From 6099f7b696d602f56ad27171b67337fc40daaf08 Mon Sep 17 00:00:00 2001 From: DMDcoin Date: Sun, 4 May 2014 17:42:34 +0100 Subject: [PATCH 001/218] Update README.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index e6e0674..7317d6e 100644 --- a/README.md +++ b/README.md @@ -1 +1,20 @@ Diamond (DMD) + +Instructions for compiling in Linux. + +Update ubuntu + sudo apt-get update +*install git to download the source code + sudo apt-get install git +*install the other necessary components + sudo apt-get install build-essential libboost1.48-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev +*navigate to the home directory + cd ~ *download the diamond source code + git clone https://github.com/DMDcoin/Diamond-Coin-2.0.1.git +*navigate to the downloaded files + cd ~ *navigate to the src file in the source code + cd diamond/src +*create obj folder + mkdir obj +*build diamondd !This will take a while! + make -f makefile.unix USE_UPNP=- From ff07d6ba4fbc005adaba17d9c904866d2ef8e796 Mon Sep 17 00:00:00 2001 From: DMDcoin Date: Sun, 4 May 2014 17:43:22 +0100 Subject: [PATCH 002/218] Update README.md --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7317d6e..6e8db4f 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,32 @@ Diamond (DMD) Instructions for compiling in Linux. Update ubuntu - sudo apt-get update + + sudo apt-get update + *install git to download the source code + sudo apt-get install git + *install the other necessary components + sudo apt-get install build-essential libboost1.48-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev + *navigate to the home directory + cd ~ *download the diamond source code + git clone https://github.com/DMDcoin/Diamond-Coin-2.0.1.git + *navigate to the downloaded files + cd ~ *navigate to the src file in the source code cd diamond/src + *create obj folder + mkdir obj + *build diamondd !This will take a while! + make -f makefile.unix USE_UPNP=- From 64b96fbb7f88f359ebb54de6ef8c5eae210d43b0 Mon Sep 17 00:00:00 2001 From: danbi Date: Tue, 6 May 2014 23:20:49 +0300 Subject: [PATCH 003/218] Implement the submit mode for getblocktemplate Add the missing processing for the "submit" mode of getblocktemplate. This is required for stratum servers that do not use submitblock for some reason. Note: I have also a version with line 400 being: strMode = "submit"; But it does not seem to be required. --- src/rpcmining.cpp | 243 ++++++++++++++++++++++++---------------------- 1 file changed, 128 insertions(+), 115 deletions(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 1565e8d..f1d438f 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -395,131 +395,144 @@ Value getblocktemplate(const Array& params, bool fHelp) if (modeval.type() == str_type) strMode = modeval.get_str(); else if (modeval.type() == null_type) - { - /* Do nothing */ - } + strMode = "template"; else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); } - if (strMode != "template") - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); - - if (vNodes.empty()) - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DiamondCoin is not connected!"); - - if (IsInitialBlockDownload()) - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "DiamondCoin is downloading blocks..."); - - static CReserveKey reservekey(pwalletMain); - - // Update block - static unsigned int nTransactionsUpdatedLast; - static CBlockIndex* pindexPrev; - static int64 nStart; - static CBlock* pblock; - if (pindexPrev != pindexBest || - (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) + if (strMode == "template") { - // Clear pindexPrev so future calls make a new block, despite any failures from here on - pindexPrev = NULL; - - // Store the pindexBest used before CreateNewBlock, to avoid races - nTransactionsUpdatedLast = nTransactionsUpdated; - CBlockIndex* pindexPrevNew = pindexBest; - nStart = GetTime(); - - // Create new block - if(pblock) - { - delete pblock; - pblock = NULL; - } - pblock = CreateNewBlock(pwalletMain); - if (!pblock) - throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); - - // Need to update only after we know CreateNewBlock succeeded - pindexPrev = pindexPrevNew; + if (vNodes.empty()) + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DiamondCoin is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "DiamondCoin is downloading blocks..."); + + static CReserveKey reservekey(pwalletMain); + + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) + { + // Clear pindexPrev so future calls make a new block, despite any failures from here on + pindexPrev = NULL; + + // Store the pindexBest used before CreateNewBlock, to avoid races + nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrevNew = pindexBest; + nStart = GetTime(); + + // Create new block + if(pblock) + { + delete pblock; + pblock = NULL; + } + pblock = CreateNewBlock(pwalletMain); + if (!pblock) + throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); + + // Need to update only after we know CreateNewBlock succeeded + pindexPrev = pindexPrevNew; + } + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + Array transactions; + map setTxIndex; + int i = 0; + CTxDB txdb("r"); + BOOST_FOREACH (CTransaction& tx, pblock->vtx) + { + uint256 txHash = tx.GetHash(); + setTxIndex[txHash] = i++; + + if (tx.IsCoinBase() || tx.IsCoinStake()) + continue; + + Object entry; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); + + entry.push_back(Pair("hash", txHash.GetHex())); + + MapPrevTx mapInputs; + map mapUnused; + bool fInvalid = false; + if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) + { + entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut()))); + + Array deps; + BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs) + { + if (setTxIndex.count(inp.first)) + deps.push_back(setTxIndex[inp.first]); + } + entry.push_back(Pair("depends", deps)); + + int64_t nSigOps = tx.GetLegacySigOpCount(); + nSigOps += tx.GetP2SHSigOpCount(mapInputs); + entry.push_back(Pair("sigops", nSigOps)); + } + + transactions.push_back(entry); + } + + Object aux; + aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + static Array aMutable; + if (aMutable.empty()) + { + aMutable.push_back("time"); + aMutable.push_back("transactions"); + aMutable.push_back("prevblock"); + } + + Object result; + result.push_back(Pair("version", pblock->nVersion)); + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); + result.push_back(Pair("transactions", transactions)); + result.push_back(Pair("coinbaseaux", aux)); + result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); + result.push_back(Pair("target", hashTarget.GetHex())); + result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); + result.push_back(Pair("mutable", aMutable)); + result.push_back(Pair("noncerange", "00000000ffffffff")); + result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); + result.push_back(Pair("curtime", (int64_t)pblock->nTime)); + result.push_back(Pair("bits", HexBits(pblock->nBits))); + result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); + + return result; } - - // Update nTime - pblock->UpdateTime(pindexPrev); - pblock->nNonce = 0; - - Array transactions; - map setTxIndex; - int i = 0; - CTxDB txdb("r"); - BOOST_FOREACH (CTransaction& tx, pblock->vtx) + else + if (strMode == "submit") { - uint256 txHash = tx.GetHash(); - setTxIndex[txHash] = i++; - - if (tx.IsCoinBase() || tx.IsCoinStake()) - continue; - - Object entry; - - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << tx; - entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); - - entry.push_back(Pair("hash", txHash.GetHex())); - - MapPrevTx mapInputs; - map mapUnused; - bool fInvalid = false; - if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) - { - entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut()))); - - Array deps; - BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs) - { - if (setTxIndex.count(inp.first)) - deps.push_back(setTxIndex[inp.first]); - } - entry.push_back(Pair("depends", deps)); - - int64_t nSigOps = tx.GetLegacySigOpCount(); - nSigOps += tx.GetP2SHSigOpCount(mapInputs); - entry.push_back(Pair("sigops", nSigOps)); - } - - transactions.push_back(entry); - } - - Object aux; - aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + // Parse parameters + const Object& oparam = params[0].get_obj(); + CDataStream ssBlock(ParseHex(find_value(oparam, "data").get_str()), SER_NETWORK, PROTOCOL_VERSION); + CBlock pblock; + ssBlock >> pblock; - uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + return ProcessBlock(NULL, &pblock); + bool fAccepted = ProcessBlock(NULL, &pblock); - static Array aMutable; - if (aMutable.empty()) - { - aMutable.push_back("time"); - aMutable.push_back("transactions"); - aMutable.push_back("prevblock"); + return fAccepted ? Value::null : "rejected"; } - - Object result; - result.push_back(Pair("version", pblock->nVersion)); - result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); - result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbaseaux", aux)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); - result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); - result.push_back(Pair("mutable", aMutable)); - result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); - result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); - result.push_back(Pair("curtime", (int64_t)pblock->nTime)); - result.push_back(Pair("bits", HexBits(pblock->nBits))); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); - - return result; + throw JSONRPCError(-8, "Invalid mode"); } Value submitblock(const Array& params, bool fHelp) From 2d05a51038274862602840ea44365cebc77d25ad Mon Sep 17 00:00:00 2001 From: danbi Date: Wed, 7 May 2014 21:03:58 +0300 Subject: [PATCH 004/218] Update rpcmining.cpp Removed extraneous return. --- src/rpcmining.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index f1d438f..e54f640 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -527,7 +527,6 @@ Value getblocktemplate(const Array& params, bool fHelp) CBlock pblock; ssBlock >> pblock; - return ProcessBlock(NULL, &pblock); bool fAccepted = ProcessBlock(NULL, &pblock); return fAccepted ? Value::null : "rejected"; From b58d06fdc16b2ebcd73ae2737a09c6f931e2925d Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 20 May 2014 17:41:34 +0300 Subject: [PATCH 005/218] Remove unused variables and extra prints --- src/main.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1e40a7e..2b29f3a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -953,8 +953,8 @@ int generateMTRandom(unsigned int s, int range) } -static const int64 nMinSubsidy = 1 * COIN; -static const int CUTOFF_HEIGHT = 100800; // Height at the end of 5 weeks +//static const int64 nMinSubsidy = 1 * COIN; +//static const int CUTOFF_HEIGHT = 100800; // Height at the end of 5 weeks // miner's coin base reward based on nBits int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) { @@ -993,7 +993,7 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) // miner's coin stake reward based on nBits and coin age spent (coin-days) // simple algorithm, not depend on the diff -const int YEARLY_BLOCKCOUNT = 525600; // 365 * 1440 +//const int YEARLY_BLOCKCOUNT = 525600; // 365 * 1440 int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight) { if(totalCoin >= VALUE_CHANGE || fTestNet) @@ -1161,8 +1161,8 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS bool CheckProofOfWork(uint256 hash, unsigned int nBits) { - if(pindexBest != NULL) - printf("pindexBest = %d", pindexBest->nMoneySupply / COIN); +// if(pindexBest != NULL) +// printf("pindexBest = %d", pindexBest->nMoneySupply / COIN); CBigNum bnTarget; bnTarget.SetCompact(nBits); @@ -2169,12 +2169,12 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const if(totalCoin >= VALUE_CHANGE) { if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) - return error("CheckBlock() : coinbase output not empty for proof-of-stake block"); + return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); } else { if (IsProofOfStake() && (vtx[0].vout.size() != 1 || !vtx[0].vout[0].IsEmpty())) - return error("CheckBlock() : coinbase output not empty for proof-of-stake block"); + return error("CheckBlock() : (OLD) coinbase output not empty for proof-of-stake block"); } // Check coinbase timestamp @@ -4102,11 +4102,11 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (txCoinStake.nTime >= max(pindexPrev->GetMedianTimePast()+1, pindexPrev->GetBlockTime() - nMaxClockDrift)) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp - pblock->vtx.push_back(txCoinStake); pblock->vtx[0].vout[0].SetEmpty(); if(totalCoin >= VALUE_CHANGE) pblock->vtx[0].vout[1].SetEmpty(); pblock->vtx[0].nTime = txCoinStake.nTime; + pblock->vtx.push_back(txCoinStake); } } nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime; @@ -4532,7 +4532,7 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) int64 nStart = GetTime(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - unsigned int max_nonce = 0xffff0000; +// unsigned int max_nonce = 0xffff0000; block_header res_header; uint256 result; @@ -4543,7 +4543,7 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) unsigned int nHashesDone = 0; uint256 thash; - char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; +// char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; if(totalCoin < VALUE_CHANGE) { From 204f836d0686605f5d3003f3928b0a129f4b7c20 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 20 May 2014 17:43:33 +0300 Subject: [PATCH 006/218] (temporary) remove reference to TxMessage --- src/main.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.h b/src/main.h index 0418f93..b181e1f 100644 --- a/src/main.h +++ b/src/main.h @@ -668,8 +668,8 @@ class CTransaction nVersion, vin.size(), vout.size(), - nLockTime, - strTxComment.substr(0,30).c_str() + nLockTime +// strTxComment.substr(0,30).c_str() ); for (unsigned int i = 0; i < vin.size(); i++) From 1221a91a038d379dc668001c1f8424f634a3afe3 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 20 May 2014 17:45:59 +0300 Subject: [PATCH 007/218] Make ebug output independent of QT --- src/kernel.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index 0b8498e..16a1470 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -354,10 +354,11 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned // Now check if proof-of-stake hash meets target protocol if (CBigNum(hashProofOfStake) > bnCoinDayWeight * bnTargetPerCoinDay) { - //qDebug() << "hashProofOfStake = " << CBigNum(hashProofOfStake).ToString().c_str(); - //qDebug() << "bnCoinDayWeight = " << bnCoinDayWeight.ToString().c_str(); - //qDebug() << "bnTargetPerCoinDay = " << bnTargetPerCoinDay.ToString().c_str(); - //printf(">>> CheckStakeKernelHash - hashProofOfStake too much\n"); +// printf("hashProofOfStake = %s\n", CBigNum(hashProofOfStake).ToString().c_str()); +// printf("bnCoinDayWeight = %s\n", bnCoinDayWeight.ToString().c_str()); +// printf("bnTargetPerCoinDay = %s\n", bnTargetPerCoinDay.ToString().c_str()); +// printf("nBits = %d\n", nBits); +// printf(">>> CheckStakeKernelHash - hashProofOfStake too much\n"); return false; } From 740edbf9332c40addd52b7d5745cf6220dc162db Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 20 May 2014 17:46:39 +0300 Subject: [PATCH 008/218] Update makefile.bsd --- src/makefile.bsd | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/makefile.bsd b/src/makefile.bsd index 10a6e66..be08f0d 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -2,8 +2,15 @@ # Distributed under the MIT/X11 software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -USE_UPNP:=0 -USE_IPV6:=1 +USE_UPNP:=- +USE_IPV6:=- +BOOST_INCLUDE_PATH=/usr/local/include +BDB_INCLUDE_PATH=/usr/local/include/db48 +BOOST_LIB_PATH=/usr/local/lib +BDB_LIB_PATH=/usr/local/lib/db48 +STATIC=1 +CC=clang +CXX=clang++ LINK:=$(CXX) @@ -52,7 +59,7 @@ endif LIBS+= \ -Wl,-B$(LMODE2) \ -l z \ - -l dl \ +# -l dl \ -l pthread @@ -94,7 +101,7 @@ DEBUGFLAGS=-g # CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only # adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work. -xCXXFLAGS=-O0 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ +xCXXFLAGS=-O2 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) # LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only @@ -102,6 +109,8 @@ xCXXFLAGS=-O0 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unus xLDFLAGS=$(LDHARDENING) $(LDFLAGS) OBJS= \ + obj/hash.o \ + obj/groestl.o \ obj/alert.o \ obj/version.o \ obj/checkpoints.o \ @@ -139,7 +148,7 @@ OBJS= \ all: diamondd test check: test_diamond FORCE - ./test_BottleCaps + ./test_diamond # auto-generated dependencies: -include obj/*.P @@ -163,6 +172,14 @@ obj/%.o: %.cpp -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ rm -f $(@:%.o=%.d) +obj/%.o: %.c + $(CC) -c $(xCXXFLAGS) -fpermissive -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + + diamondd: $(OBJS:obj/%=obj/%) $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) From 94c43bfdef344cbc2b19f96c7e576734b330a492 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 14:57:07 +0300 Subject: [PATCH 009/218] Update library dependencies --- diamond.pro | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/diamond.pro b/diamond.pro index fa29a64..21f9912 100644 --- a/diamond.pro +++ b/diamond.pro @@ -15,18 +15,23 @@ UI_DIR = build # UNCOMMENT THIS SECTION TO BUILD ON WINDOWS # Change paths if needed, these use the foocoin/deps.git repository locations +win32 { BOOST_LIB_SUFFIX=-mgw48-mt-s-1_55 BOOST_INCLUDE_PATH=C:/deps/boost_1_55_0 BOOST_LIB_PATH=C:/deps/boost_1_55_0/stage/lib BDB_INCLUDE_PATH=C:/deps/db-4.8.30.NC/build_windows BDB_LIB_PATH=C:/deps/db-4.8.30.NC/build_windows -OPENSSL_INCLUDE_PATH=C:/deps/openssl-1.0.1g/include -OPENSSL_LIB_PATH=C:/deps/openssl-1.0.1g +OPENSSL_INCLUDE_PATH=C:/deps/openssl-1.0.1h/include +OPENSSL_LIB_PATH=C:/deps/openssl-1.0.1h MINIUPNPC_INCLUDE_PATH=C:/deps -LIBPNG_INCLUDE_PATH=C:/deps/libpng-1.6.8 -LIBPNG_LIB_PATH=C:/deps/libpng-1.6.8/.libs +LIBPNG_INCLUDE_PATH=C:/deps/libpng-1.6.10 +LIBPNG_LIB_PATH=C:/deps/libpng-1.6.10/.libs MINIUPNPC_LIB_PATH=C:/deps/miniupnpc +QRENCODE_INCLUDE_PATH=C:/deps/qrencode-3.4.3 QRENCODE_LIB_PATH=C:/deps/qrencode-3.4.3/.libs +RELEASE=1 +CONFIG += static +} # use: qmake "RELEASE=1" contains(RELEASE, 1) { From 20e8c3825413ae647790aadf08024cd35d14c751 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 14:58:23 +0300 Subject: [PATCH 010/218] Update copyrights --- doc/README | 6 +++--- doc/README_windows.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/README b/doc/README index b567cb8..ff0b1a9 100644 --- a/doc/README +++ b/doc/README @@ -1,10 +1,10 @@ -Copyright (c) 2013-2014 Diamond Developers +Copyright (c) 2013-2014 Diamond Foundation -Diamond 0.3.0 BETA +Diamond 2.0.2 BETA -Copyright (c) 2013-2014 Diamond Developers +Copyright (c) 2013-2014 Diamond Foundation Copyright (c) 2013 NovaCoin Developers Copyright (c) 2011-2012 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 68f0a9e..e207127 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,10 +1,10 @@ -Copyright (c) 2013-2014 Diamond Developers +Copyright (c) 2013-2014 Diamond Foundation -Diamond 0.3.0 BETA +Diamond 2.0.2 BETA -Copyright (c) 2013-2014 Diamond Developers +Copyright (c) 2013-2014 Diamond Foundation Copyright (c) 2013 NovaCoin Developers Copyright (c) 2011-2012 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying From 0ccf2072374fc8b4aba1b864cf32f7e66699e470 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:00:16 +0300 Subject: [PATCH 011/218] Implement workaround for http://bitcoin.org/may15 --- src/db.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/db.cpp b/src/db.cpp index 221cadf..63432eb 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -85,7 +85,11 @@ bool CDBEnv::Open(boost::filesystem::path pathEnv_) dbenv.set_cachesize(nDbCache / 1024, (nDbCache % 1024)*1048576, 1); dbenv.set_lg_bsize(1048576); dbenv.set_lg_max(10485760); - dbenv.set_lk_max_locks(10000); + + // Bugfix: Bump lk_max_locks default to 537000, to safely handle reorgs with up to 5 blocks reversed + // dbenv.set_lk_max_locks(10000); + dbenv.set_lk_max_locks(537000); + dbenv.set_lk_max_objects(10000); dbenv.set_errfile(fopen(pathErrorFile.string().c_str(), "a")); /// debug dbenv.set_flags(DB_AUTO_COMMIT, 1); @@ -106,6 +110,30 @@ bool CDBEnv::Open(boost::filesystem::path pathEnv_) fDbEnvInit = true; fMockDb = false; + + // Check that the number of locks is sufficient (to prevent chain fork possibility, read http://bitcoin.org/may15 for more info) + u_int32_t nMaxLocks; + if (!dbenv.get_lk_max_locks(&nMaxLocks)) + { + int nBlocks, nDeepReorg; + std::string strMessage; + + nBlocks = nMaxLocks / 48768; + nDeepReorg = (nBlocks - 1) / 2; + + printf("Final lk_max_locks is %lu, sufficient for (worst case) %d block%s in a single transaction (up to a %d-deep reorganization)\n", (unsigned long)nMaxLocks, nBlocks, (nBlocks == 1) ? "" : "s", nDeepReorg); + if (nDeepReorg < 3) + { + if (nBlocks < 1) + strMessage = strprintf(("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a single block. If this limit is reached, Diamond may stop working."), (unsigned long)nMaxLocks); + else + strMessage = strprintf(("Warning: DB_CONFIG has set_lk_max_locks %lu, which may be too low for a common blockchain reorganization. If this limit is reached, Diamond may stop working."), (unsigned long)nMaxLocks); + + strMiscWarning = strMessage; + printf("*** %s\n", strMessage.c_str()); + } + } + return true; } From fa70bf7bf4b7303b9209eab04068db928d7b44d6 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:25:33 +0300 Subject: [PATCH 012/218] Implement proper block size for getblocktemplate. --- src/rpcmining.cpp | 228 +++++++++++++++++++++++----------------------- 1 file changed, 115 insertions(+), 113 deletions(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index e54f640..36cc268 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -250,7 +250,6 @@ Value getworkex(const Array& params, bool fHelp) Value getwork(const Array& params, bool fHelp) { - totalCoin = GetTotalCoin(); if (fHelp || params.size() > 1) throw runtime_error( "getwork [data]\n" @@ -395,134 +394,137 @@ Value getblocktemplate(const Array& params, bool fHelp) if (modeval.type() == str_type) strMode = modeval.get_str(); else if (modeval.type() == null_type) - strMode = "template"; + strMode = "template"; else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); } if (strMode == "template") { - if (vNodes.empty()) - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DiamondCoin is not connected!"); - - if (IsInitialBlockDownload()) - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "DiamondCoin is downloading blocks..."); - - static CReserveKey reservekey(pwalletMain); - - // Update block - static unsigned int nTransactionsUpdatedLast; - static CBlockIndex* pindexPrev; - static int64 nStart; - static CBlock* pblock; - if (pindexPrev != pindexBest || - (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) + if (vNodes.empty()) + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DiamondCoin is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "DiamondCoin is downloading blocks..."); + + static CReserveKey reservekey(pwalletMain); + + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 5)) + { + // Clear pindexPrev so future calls make a new block, despite any failures from here on + pindexPrev = NULL; + + // Store the pindexBest used before CreateNewBlock, to avoid races + nTransactionsUpdatedLast = nTransactionsUpdated; + CBlockIndex* pindexPrevNew = pindexBest; + nStart = GetTime(); + + // Create new block + if(pblock) { - // Clear pindexPrev so future calls make a new block, despite any failures from here on - pindexPrev = NULL; - - // Store the pindexBest used before CreateNewBlock, to avoid races - nTransactionsUpdatedLast = nTransactionsUpdated; - CBlockIndex* pindexPrevNew = pindexBest; - nStart = GetTime(); - - // Create new block - if(pblock) - { - delete pblock; - pblock = NULL; - } - pblock = CreateNewBlock(pwalletMain); - if (!pblock) - throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); - - // Need to update only after we know CreateNewBlock succeeded - pindexPrev = pindexPrevNew; + delete pblock; + pblock = NULL; } - - // Update nTime - pblock->UpdateTime(pindexPrev); - pblock->nNonce = 0; - - Array transactions; - map setTxIndex; - int i = 0; - CTxDB txdb("r"); - BOOST_FOREACH (CTransaction& tx, pblock->vtx) + pblock = CreateNewBlock(pwalletMain); + if (!pblock) + throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); + + // Need to update only after we know CreateNewBlock succeeded + pindexPrev = pindexPrevNew; + } + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + Array transactions; + map setTxIndex; + int i = 0; + CTxDB txdb("r"); + BOOST_FOREACH (CTransaction& tx, pblock->vtx) + { + uint256 txHash = tx.GetHash(); + setTxIndex[txHash] = i++; + + if (tx.IsCoinBase() || tx.IsCoinStake()) + continue; + + Object entry; + + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + ssTx << tx; + entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); + + entry.push_back(Pair("hash", txHash.GetHex())); + + MapPrevTx mapInputs; + map mapUnused; + bool fInvalid = false; + if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) { - uint256 txHash = tx.GetHash(); - setTxIndex[txHash] = i++; - - if (tx.IsCoinBase() || tx.IsCoinStake()) - continue; - - Object entry; - - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << tx; - entry.push_back(Pair("data", HexStr(ssTx.begin(), ssTx.end()))); - - entry.push_back(Pair("hash", txHash.GetHex())); - - MapPrevTx mapInputs; - map mapUnused; - bool fInvalid = false; - if (tx.FetchInputs(txdb, mapUnused, false, false, mapInputs, fInvalid)) - { - entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut()))); - - Array deps; - BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs) - { - if (setTxIndex.count(inp.first)) - deps.push_back(setTxIndex[inp.first]); - } - entry.push_back(Pair("depends", deps)); - - int64_t nSigOps = tx.GetLegacySigOpCount(); - nSigOps += tx.GetP2SHSigOpCount(mapInputs); - entry.push_back(Pair("sigops", nSigOps)); - } - - transactions.push_back(entry); + entry.push_back(Pair("fee", (int64_t)(tx.GetValueIn(mapInputs) - tx.GetValueOut()))); + + Array deps; + BOOST_FOREACH (MapPrevTx::value_type& inp, mapInputs) + { + if (setTxIndex.count(inp.first)) + deps.push_back(setTxIndex[inp.first]); + } + entry.push_back(Pair("depends", deps)); + + int64_t nSigOps = tx.GetLegacySigOpCount(); + nSigOps += tx.GetP2SHSigOpCount(mapInputs); + entry.push_back(Pair("sigops", nSigOps)); } - - Object aux; - aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); - - uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - - static Array aMutable; - if (aMutable.empty()) - { - aMutable.push_back("time"); - aMutable.push_back("transactions"); - aMutable.push_back("prevblock"); - } - - Object result; - result.push_back(Pair("version", pblock->nVersion)); - result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); - result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbaseaux", aux)); + + transactions.push_back(entry); + } + + Object aux; + aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + static Array aMutable; + if (aMutable.empty()) + { + aMutable.push_back("time"); + aMutable.push_back("transactions"); + aMutable.push_back("prevblock"); + } + + Object result; + result.push_back(Pair("version", pblock->nVersion)); + result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); + result.push_back(Pair("transactions", transactions)); + result.push_back(Pair("coinbaseaux", aux)); + if(totalCoin >= VALUE_CHANGE) + result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue + (int64_t)pblock->vtx[0].vout[1].nValue)); + else result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); - result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); - result.push_back(Pair("mutable", aMutable)); - result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); - result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); - result.push_back(Pair("curtime", (int64_t)pblock->nTime)); - result.push_back(Pair("bits", HexBits(pblock->nBits))); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); - - return result; + result.push_back(Pair("target", hashTarget.GetHex())); + result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); + result.push_back(Pair("mutable", aMutable)); + result.push_back(Pair("noncerange", "00000000ffffffff")); + result.push_back(Pair("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS)); + result.push_back(Pair("sizelimit", (int64_t)MAX_BLOCK_SIZE)); + result.push_back(Pair("curtime", (int64_t)pblock->nTime)); + result.push_back(Pair("bits", HexBits(pblock->nBits))); + result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); + + return result; } else if (strMode == "submit") { // Parse parameters - const Object& oparam = params[0].get_obj(); + const Object& oparam = params[0].get_obj(); CDataStream ssBlock(ParseHex(find_value(oparam, "data").get_str()), SER_NETWORK, PROTOCOL_VERSION); CBlock pblock; ssBlock >> pblock; From 285ae33cd0aeb258f4a23db64c4c05408efe24c1 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:25:55 +0300 Subject: [PATCH 013/218] Clean up unused variables and comments. --- diamond.pro | 1 + src/base58.h | 1 - src/bitcoinrpc.cpp | 2 +- src/db.cpp | 1 - src/init.cpp | 5 ++--- src/kernel.cpp | 9 +++++---- src/main.cpp | 33 +++++++-------------------------- src/main.h | 3 --- src/rpcblockchain.cpp | 1 - src/util.cpp | 2 -- src/util.h | 19 ------------------- src/version.h | 5 ----- src/wallet.cpp | 10 +++++----- 13 files changed, 21 insertions(+), 71 deletions(-) diff --git a/diamond.pro b/diamond.pro index 21f9912..1151343 100644 --- a/diamond.pro +++ b/diamond.pro @@ -53,6 +53,7 @@ QMAKE_LFLAGS *= -fstack-protector-all --param ssp-buffer-size=1 } # for extra security on Windows: enable ASLR and DEP via GCC linker flags win32:QMAKE_LFLAGS *= -Wl,--dynamicbase -Wl,--nxcompat +win32:QMAKE_LFLAGS *= -Wl,--large-address-aware -static lessThan(QT_MAJOR_VERSION, 5): win32: QMAKE_LFLAGS *= -static # use: qmake "USE_QRCODE=1" diff --git a/src/base58.h b/src/base58.h index 3451e7a..a35e741 100644 --- a/src/base58.h +++ b/src/base58.h @@ -280,7 +280,6 @@ class CBitcoinAddress : public CBase58Data SCRIPT_ADDRESS = 8, PUBKEY_ADDRESS_TEST = 111, SCRIPT_ADDRESS_TEST = 196, - }; bool Set(const CKeyID &id) { diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 725e127..647236b 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -208,7 +208,7 @@ static const CRPCCommand vRPCCommands[] = { "getpeerinfo", &getpeerinfo, true, false }, { "getdifficulty", &getdifficulty, true, false }, { "getgenerate", &getgenerate, true, false }, - //{ "setgenerate", &setgenerate, true, false }, + { "setgenerate", &setgenerate, true, false }, { "gethashespersec", &gethashespersec, true, false }, { "getinfo", &getinfo, true, false }, { "getmininginfo", &getmininginfo, true, false }, diff --git a/src/db.cpp b/src/db.cpp index 63432eb..809314d 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -650,7 +650,6 @@ bool CTxDB::LoadBlockIndex() // Calculate bnChainTrust vector > vSortedByHeight; - map a = mapBlockIndex; vSortedByHeight.reserve(mapBlockIndex.size()); BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) { diff --git a/src/init.cpp b/src/init.cpp index 990d191..3d69b90 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -124,7 +124,7 @@ bool AppInit(int argc, char* argv[]) // // Parameters // - // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() + // If Qt is used, parameters/diamond.conf are parsed in qt/bitcoin.cpp's main() ParseParameters(argc, argv); if (!boost::filesystem::is_directory(GetDataDir(false))) { @@ -351,7 +351,6 @@ bool AppInit2() // ********************************************************* Step 2: parameter interactions fTestNet = GetBoolArg("-testnet"); - //fTestNet = true; if (fTestNet) { SoftSetBoolArg("-irc", true); } @@ -419,7 +418,7 @@ bool AppInit2() fPrintToConsole = GetBoolArg("-printtoconsole"); fPrintToDebugger = GetBoolArg("-printtodebugger"); fLogTimestamps = GetBoolArg("-logtimestamps"); - fLogTimestamps = true; + if (mapArgs.count("-timeout")) { int nNewTimeout = GetArg("-timeout", 5000); diff --git a/src/kernel.cpp b/src/kernel.cpp index 16a1470..9cc67ae 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -3,7 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include -//#include + #include "kernel.h" #include "db.h" @@ -221,7 +221,7 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier { nStakeModifier = 0; if (!mapBlockIndex.count(hashBlockFrom)) - return false; + return error("GetKernelStakeModifier() : block not indexed"); const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom]; nStakeModifierHeight = pindexFrom->nHeight; nStakeModifierTime = pindexFrom->GetBlockTime(); @@ -279,8 +279,8 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier // bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, bool fPrintProofOfStake) { - if(totalCoin < VALUE_CHANGE && pindexBest->nHeight > 376497 && !fTestNet) - return false; +// if(totalCoin < VALUE_CHANGE && pindexBest->nHeight > 376497 && !fTestNet) +// return false; if (nTimeTx < txPrev.nTime) // Transaction timestamp violation return error("CheckStakeKernelHash() : nTime violation"); @@ -296,6 +296,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned // v0.3 protocol kernel hash weight starts from 0 at the min age // this change increases active coins participating the hash and helps // to secure the network when proof-of-stake difficulty is low +// DK changing calculations here creates a fork int64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)nStakeMaxAge) - nStakeMinAge; CBigNum bnCoinDayWeight; diff --git a/src/main.cpp b/src/main.cpp index 2b29f3a..2d455ca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,7 +11,6 @@ #include "ui_interface.h" #include "kernel.h" #include "scrypt_mine.h" -#include "scrypt.h" #include #include #include @@ -43,7 +42,7 @@ static CBigNum bnProofOfStakeLimit(~uint256(0) >> 20); static CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16); static CBigNum bnProofOfStakeLimitTestNet(~uint256(0) >> 20); uint256 nPoWBase = uint256("0x00000000ffff0000000000000000000000000000000000000000000000000000"); // difficulty-1 target -unsigned int nStakeMinAge = 60 * 60 * 24 * 7; // minimum age for coin age: 2d +unsigned int nStakeMinAge = 60 * 60 * 24 * 7; // minimum age for coin age: 7d unsigned int nStakeMaxAge = 60 * 60 * 24 * 30; // stake age of full weight: 30d int64 nStakeTargetSpacing = 60; // 1-minute block spacing int64 nWorkTargetSpacing = 60; // 1-minute block spacing @@ -953,8 +952,6 @@ int generateMTRandom(unsigned int s, int range) } -//static const int64 nMinSubsidy = 1 * COIN; -//static const int CUTOFF_HEIGHT = 100800; // Height at the end of 5 weeks // miner's coin base reward based on nBits int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) { @@ -993,7 +990,6 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) // miner's coin stake reward based on nBits and coin age spent (coin-days) // simple algorithm, not depend on the diff -//const int YEARLY_BLOCKCOUNT = 525600; // 365 * 1440 int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight) { if(totalCoin >= VALUE_CHANGE || fTestNet) @@ -1123,14 +1119,16 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS { if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); - CBigNum bnTargetLimit = !fProofOfStake ? bnProofOfWorkLimit : bnProofOfStakeLimit; + // cruft from alorithm switch time if(pindexLast->nHeight >= 386221 && pindexLast->nHeight <= 386226) return bnProofOfWorkLimit.GetCompact(); if(pindexLast->nHeight >= 386232 && pindexLast->nHeight <= 386233) return bnProofOfWorkLimit_1.GetCompact(); + CBigNum bnTargetLimit = fProofOfStake ? bnProofOfStakeLimit : bnProofOfWorkLimit; + if (pindexLast == NULL) return bnTargetLimit.GetCompact(); // genesis block @@ -1148,7 +1146,6 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS CBigNum bnNew; bnNew.SetCompact(pindexPrev->nBits); int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nWorkTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); - int64 nInterval = nTargetTimespan / nTargetSpacing; bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); @@ -1161,18 +1158,18 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS bool CheckProofOfWork(uint256 hash, unsigned int nBits) { -// if(pindexBest != NULL) -// printf("pindexBest = %d", pindexBest->nMoneySupply / COIN); CBigNum bnTarget; bnTarget.SetCompact(nBits); // Check range if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) return false; +// return error("CheckProofOfWork() : nBits below minimum work"); // Check proof of work matches claimed amount if (hash > bnTarget.getuint256()) return false; +// return error("CheckProofOfWork() : hash doesn't match nBits"); return true; } @@ -2046,17 +2043,8 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) { pindexNew->pprev = (*miPrev).second; pindexNew->nHeight = pindexNew->pprev->nHeight + 1; - - //test - if(pindexNew->pprev->nHeight >= 3) - { - int i = 1; - i++; - i++; - } } - // ppcoin: compute chain trust score pindexNew->bnChainTrust = (pindexNew->pprev ? pindexNew->pprev->bnChainTrust : 0) + pindexNew->GetBlockTrust(); @@ -2313,8 +2301,6 @@ CBigNum CBlockIndex::GetBlockTrust() const if (bnTarget <= 0) return 0; return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1); - - } bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck) @@ -2501,7 +2487,6 @@ bool CBlock::SignBlock(const CKeyStore& keystore) if (key.GetPubKey() != vchPubKey) return false; - return key.Sign(GetHashScrypt(), vchBlockSig); } } @@ -4153,7 +4138,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (!mempool.mapTx.count(txin.prevout.hash)) { printf("ERROR: mempool transaction missing input\n"); - if (fDebug) assert("mempool transaction missing input" == 0); + // if (fDebug) assert("mempool transaction missing input" == 0); fMissingInputs = true; if (porphan) vOrphan.pop_back(); @@ -4442,8 +4427,6 @@ static int nLimitProcessors = -1; void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) { - void *scratchbuf = scrypt_buffer_alloc(); - printf("CPUMiner started for proof-of-%s\n", fProofOfStake? "stake" : "work"); SetThreadPriority(THREAD_PRIORITY_LOWEST); @@ -4532,7 +4515,6 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) int64 nStart = GetTime(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); -// unsigned int max_nonce = 0xffff0000; block_header res_header; uint256 result; @@ -4691,7 +4673,6 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) } } - scrypt_buffer_free(scratchbuf); } void static ThreadBitcoinMiner(void* parg) diff --git a/src/main.h b/src/main.h index b181e1f..52d94c8 100644 --- a/src/main.h +++ b/src/main.h @@ -43,9 +43,6 @@ static const int64 VALUE_CHANGE = 369494; #define DEV_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define DEV_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" -inline int64_t PastDrift(int64 nTime) { return nTime - 15 * 60; } // up to 1 day from the past -inline int64_t FutureDrift(int64 nTime) { return nTime + 15 * 60; } // up to 1 day from the future - inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index c9f9b35..0362015 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -48,7 +48,6 @@ int64 GetTotalCoin() return pindexBest->nMoneySupply / COIN; } - Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail) { Object result; diff --git a/src/util.cpp b/src/util.cpp index d93055e..6432822 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1120,8 +1120,6 @@ boost::filesystem::path GetConfigFile() { boost::filesystem::path pathConfigFile(GetArg("-conf", "Diamond.conf")); if (!pathConfigFile.is_complete()) pathConfigFile = GetDataDir(false) / pathConfigFile; - int i = 0; - i++; return pathConfigFile; } diff --git a/src/util.h b/src/util.h index 0e88ad6..0113b18 100644 --- a/src/util.h +++ b/src/util.h @@ -133,25 +133,6 @@ inline void Sleep(int64 n) #define ATTR_WARN_PRINTF(X,Y) #endif - - -inline void MilliSleep(int64 n) -{ -// Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50 -// until fixed in 1.52. Use the deprecated sleep method for the broken case. -// See: https://svn.boost.org/trac/boost/ticket/7238 - -#if BOOST_VERSION >= 105000 && (!defined(BOOST_HAS_NANOSLEEP) || BOOST_VERSION >= 105200) - boost::this_thread::sleep_for(boost::chrono::milliseconds(n)); -#else - boost::this_thread::sleep(boost::posix_time::milliseconds(n)); -#endif -} - - - - - extern std::map mapArgs; extern std::map > mapMultiArgs; extern bool fDebug; diff --git a/src/version.h b/src/version.h index d5cb6f5..ce9c826 100644 --- a/src/version.h +++ b/src/version.h @@ -21,11 +21,6 @@ extern const std::string CLIENT_NAME; extern const std::string CLIENT_BUILD; extern const std::string CLIENT_DATE; -// -// database format versioning -// -static const int DATABASE_VERSION = 70508; - // // network protocol versioning // diff --git a/src/wallet.cpp b/src/wallet.cpp index b626af8..bdea7d6 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -351,7 +351,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str()); else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n])) { - printf("WalletUpdateSpent found spent coin %sMNT %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + printf("WalletUpdateSpent found spent coin %sDMD %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); wtx.MarkSpent(txin.prevout.n); wtx.WriteToDisk(); NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); @@ -855,7 +855,7 @@ void CWallet::ReacceptWalletTransactions() } if (fUpdated) { - printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + printf("ReacceptWalletTransactions found spent coin %sDMD %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); wtx.MarkDirty(); wtx.WriteToDisk(); } @@ -1467,7 +1467,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; - // printf(">> Wallet: CreateCoinStake: nCredit = %"PRI64d"\n", nCredit); + // printf(">> Wallet: CreateCoinStake: nCredit = %"PRI64d"\n", nCredit); vwtxPrev.push_back(pcoin.first); txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); @@ -2080,7 +2080,7 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool { if (IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull())) { - printf("FixSpentCoins found lost coin %sppc %s[%d], %s\n", + printf("FixSpentCoins found lost coin %sDMD %s[%d], %s\n", FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); nMismatchFound++; nBalanceInQuestion += pcoin->vout[n].nValue; @@ -2092,7 +2092,7 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool } else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull())) { - printf("FixSpentCoins found spent coin %sppc %s[%d], %s\n", + printf("FixSpentCoins found spent coin %sDMD %s[%d], %s\n", FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); nMismatchFound++; nBalanceInQuestion += pcoin->vout[n].nValue; From 9cbc4324c51dfdc145c927b402aaace1fa99d50a Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:32:09 +0300 Subject: [PATCH 014/218] Implement additional checks in GetHash() and CheckBlock() to account for different hash algorithms. --- src/db.cpp | 3 ++- src/kernel.cpp | 8 +++----- src/main.cpp | 40 ++++++++++++++++++++++++++-------------- src/main.h | 11 ++++++----- src/rpcblockchain.cpp | 2 +- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 809314d..056f33b 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -710,7 +710,8 @@ bool CTxDB::LoadBlockIndex() if (!block.ReadFromDisk(pindex)) return error("LoadBlockIndex() : block.ReadFromDisk failed"); // check level 1: verify block validity - if (nCheckLevel>0 && !block.CheckBlock()) + // DK properly pass totalCoin + if (nCheckLevel>0 && !block.CheckBlock(true, true, pindex->nMoneySupply / COIN)) { printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); pindexFork = pindex->pprev; diff --git a/src/kernel.cpp b/src/kernel.cpp index 9cc67ae..38b8b53 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -326,9 +326,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nStakeModifierHeight = 0; int64 nStakeModifierTime = 0; - if (!GetKernelStakeModifier(blockFrom.GetHashScrypt(), nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake) && - - !GetKernelStakeModifier(blockFrom.GetHashGroestl(), nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake)) + if (!GetKernelStakeModifier(blockFrom.GetHash(true), nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake)) { // printf(">>> CheckStakeKernelHash: GetKernelStakeModifier return false\n"); return false; @@ -343,7 +341,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned printf("CheckStakeKernelHash() : using modifier 0x%016"PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", nStakeModifier, nStakeModifierHeight, DateTimeStrFormat(nStakeModifierTime).c_str(), - mapBlockIndex[blockFrom.GetHash()]->nHeight, + mapBlockIndex[blockFrom.GetHash(true)]->nHeight, DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); printf("CheckStakeKernelHash() : check protocol=%s modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", "0.3", @@ -368,7 +366,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned printf("CheckStakeKernelHash() : using modifier 0x%016"PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", nStakeModifier, nStakeModifierHeight, DateTimeStrFormat(nStakeModifierTime).c_str(), - mapBlockIndex[blockFrom.GetHash()]->nHeight, + mapBlockIndex[blockFrom.GetHash(true)]->nHeight, DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); printf("CheckStakeKernelHash() : pass protocol=%s modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", "0.3", diff --git a/src/main.cpp b/src/main.cpp index 2d455ca..7975a18 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -420,7 +420,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) } // Update the tx's hashBlock - hashBlock = pblock->GetHash(); + hashBlock = pblock->GetHash(true); // Locate the transaction for (nIndex = 0; nIndex < (int)pblock->vtx.size(); nIndex++) @@ -4733,22 +4733,34 @@ int64 GetDevCoin(int64 totalCoin) { return 0.01 * COIN; } -uint256 CBlock::GetHash() const +uint256 CBlock::GetHash(bool existingBlock) const { - if((totalCoinDB <= VALUE_CHANGE && totalCoin == -1) || (totalCoin >= 0 && totalCoin < VALUE_CHANGE)) - { - uint256 thash; - void * scratchbuff = scrypt_buffer_alloc(); - - scrypt_hash(CVOIDBEGIN(nVersion), sizeof(block_header), UINTBEGIN(thash), scratchbuff); + // There are two distinct cases when we are called + // First case is with with a block already in the blockchain index + // Second is for a new block - scrypt_buffer_free(scratchbuff); - return thash; - } - else if((totalCoinDB > VALUE_CHANGE && totalCoin == -1) || (totalCoin >= VALUE_CHANGE)) + if (existingBlock) { - return HashGroestl(BEGIN(nVersion), END(nNonce)); + //printf("CBlock::GetHash() look up an existing block\n"); + // TODO: reverse checks when Groestl blocks become more + // calculate Scrypt first + uint256 hash_scrypt = GetHashScrypt(); + // find the index position(s) + CBlockIndex* pblockindex_scrypt = mapBlockIndex[hash_scrypt]; + if (pblockindex_scrypt) + return hash_scrypt; + + // we are here so it must be Groestl + uint256 hash_groestl = GetHashGroestl(); + CBlockIndex* pblockindex_groestl = mapBlockIndex[hash_groestl]; + if (pblockindex_groestl) + return hash_groestl; } - return HashGroestl(BEGIN(nVersion), END(nNonce)); + + // new block or not found in blockchain + if(totalCoin < VALUE_CHANGE) + return GetHashScrypt(); + + return GetHashGroestl(); } diff --git a/src/main.h b/src/main.h index 52d94c8..f10fe47 100644 --- a/src/main.h +++ b/src/main.h @@ -39,9 +39,10 @@ static const int64 CIRCULATION_MONEY = MAX_MONEY; static const double TAX_PERCENTAGE = 0.01; static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; -static const int64 VALUE_CHANGE = 369494; -#define DEV_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" -#define DEV_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" +static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl +static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS +#define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" +#define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. @@ -920,7 +921,7 @@ class CBlock return (nBits == 0); } - uint256 GetHash() const; + uint256 GetHash(bool existingBlock=false) const; uint256 GetHashScrypt() const { @@ -1117,7 +1118,7 @@ class CBlock bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew); bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos); - bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true) const; + bool CheckBlock(bool fCheckPOW=true, bool fCheckMerkleRoot=true, int64 totalCoin=0) const; bool AcceptBlock(); bool GetCoinAge(uint64& nCoinAge) const; // ppcoin: calculate total coin age spent in block bool SignBlock(const CKeyStore& keystore); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 0362015..8622ea4 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -51,7 +51,7 @@ int64 GetTotalCoin() Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail) { Object result; - result.push_back(Pair("hash", block.GetHash().GetHex())); + result.push_back(Pair("hash", block.GetHash(true).GetHex())); CMerkleTx txGen(block.vtx[0]); txGen.SetMerkleBranch(&block); result.push_back(Pair("confirmations", (int)txGen.GetDepthInMainChain())); From 9364f497da7fa74d38e42abd2208b0d9fcd6a231 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:37:46 +0300 Subject: [PATCH 015/218] More GetHash(), CheckBlock() and totalCoins fixes. --- src/db.cpp | 3 +-- src/main.cpp | 39 +++++++++++---------------------------- src/main.h | 11 ++--------- 3 files changed, 14 insertions(+), 39 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 056f33b..f2f9a3c 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -859,10 +859,9 @@ bool CTxDB::LoadBlockIndexGuts() CDiskBlockIndex diskindex; ssValue >> diskindex; - totalCoinDB = diskindex.nMoneySupply / COIN; // Construct block index object uint256 blockHash; - if(totalCoinDB <= VALUE_CHANGE) + if(diskindex.nMoneySupply / COIN <= VALUE_CHANGE) blockHash = diskindex.GetBlockHashScrypt(); else blockHash = diskindex.GetBlockHashGroest(); diff --git a/src/main.cpp b/src/main.cpp index 7975a18..89abb95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,8 +47,6 @@ unsigned int nStakeMaxAge = 60 * 60 * 24 * 30; // stake age of full weight: 30d int64 nStakeTargetSpacing = 60; // 1-minute block spacing int64 nWorkTargetSpacing = 60; // 1-minute block spacing -int64 coinMax = 0; -int64 totalCoinDB = 0; int64 totalCoin = -1; int64 nChainStartTime = 1373654826; int nCoinbaseMaturity = 30; @@ -846,7 +844,7 @@ int CTxIndex::GetDepthInMainChain() const if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false)) return 0; // Find the block in the index - map::iterator mi = mapBlockIndex.find(block.GetHash()); + map::iterator mi = mapBlockIndex.find(block.GetHash(true)); if (mi == mapBlockIndex.end()) return 0; CBlockIndex* pindex = (*mi).second; @@ -874,7 +872,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock) { CBlock block; if (block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) - hashBlock = block.GetHash(); + hashBlock = block.GetHash(true); return true; } } @@ -915,11 +913,7 @@ bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) } if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions)) return false; - totalCoinDB = 1; - uint256 hash1 = GetHashScrypt(); - totalCoinDB = coinMax; - uint256 hash2 = GetHashGroestl(); - if (hash1 != pindex->GetBlockHash() && hash2 != pindex->GetBlockHash()) + if (GetHashScrypt() != pindex->GetBlockHash() && GetHashGroestl() != pindex->GetBlockHash()) return error("CBlock::ReadFromDisk() : GetHash() doesn't match index"); return true; } @@ -1564,7 +1558,7 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) { // Check it again in case a previous version let a bad block in - if (!CheckBlock(!fJustCheck, !fJustCheck)) + if (!CheckBlock(!fJustCheck, !fJustCheck, GetTotalCoin())) return false; // Do not allow blocks that contain transactions which 'overwrite' older transactions, @@ -2104,9 +2098,10 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } -bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const +bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const { - totalCoin = GetTotalCoin(); + // Update the coin mechanics variables post algorithm change + // Changing any of these requires a fork if(totalCoin >= VALUE_CHANGE && !fTestNet) { nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins @@ -2130,10 +2125,6 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot) const if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) return DoS(100, error("CheckBlock() : size limits failed")); - totalCoinDB = 1; - uint256 hash1 = GetHashScrypt(); - totalCoinDB = coinMax; - uint256 hash2 = GetHashGroestl(); // Check proof of work matches claimed amount if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(hash1, nBits) && !CheckProofOfWork(hash2, nBits)) return DoS(50, error("CheckBlock() : proof of work failed")); @@ -2332,7 +2323,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); // Preliminary checks - if (!pblock->CheckBlock()) + if (!pblock->CheckBlock(true,true,GetTotalCoin())) return error("ProcessBlock() : CheckBlock FAILED"); // ppcoin: verify hash target and signature of coinstake tx @@ -2518,11 +2509,7 @@ bool CBlock::CheckBlockSignature() const return false; if (vchBlockSig.empty()) return false; - totalCoinDB = 1; - uint256 hash1 = GetHashScrypt(); - totalCoinDB = coinMax; - uint256 hash2 = GetHashGroestl(); - return (key.Verify(hash1, vchBlockSig) || key.Verify(hash2, vchBlockSig)); + return (key.Verify(GetHashScrypt(), vchBlockSig) || key.Verify(GetHashGroestl(), vchBlockSig)); } } else @@ -2543,11 +2530,7 @@ bool CBlock::CheckBlockSignature() const continue; if (vchBlockSig.empty()) continue; - totalCoinDB = 1; - uint256 hash1 = GetHashScrypt(); - totalCoinDB = coinMax; - uint256 hash2 = GetHashGroestl(); - if(!key.Verify(hash1, vchBlockSig) && !key.Verify(hash2, vchBlockSig)) + if(!key.Verify(GetHashScrypt(), vchBlockSig) && !key.Verify(GetHashGroestl(), vchBlockSig)) continue; return true; @@ -2775,7 +2758,7 @@ void PrintBlockTree() pindex->nHeight, pindex->nFile, pindex->nBlockPos, - block.GetHash().ToString().c_str(), + block.GetHash(true).ToString().c_str(), block.nBits, DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(), FormatMoney(pindex->nMint).c_str(), diff --git a/src/main.h b/src/main.h index f10fe47..7c76bec 100644 --- a/src/main.h +++ b/src/main.h @@ -61,8 +61,6 @@ static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours extern CScript COINBASE_FLAGS; -extern int64 coinMax; -extern int64 totalCoinDB; extern int64 totalCoin; extern CCriticalSection cs_main; extern std::map mapBlockIndex; @@ -1078,15 +1076,10 @@ class CBlock return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__); } - totalCoinDB = 1; - uint256 hash1 = GetHashScrypt(); - totalCoinDB = coinMax; - uint256 hash2 = GetHashGroestl(); // Check the header - if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(hash1, nBits) && !CheckProofOfWork(hash2, nBits)) - { + if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) return error("CBlock::ReadFromDisk() : errors in block header"); - } + return true; } From 2afec1e3ca2a7622583daf8853baacdcc58ec458 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:41:02 +0300 Subject: [PATCH 016/218] Fix coin mechanics calculations. --- src/kernel.cpp | 30 ++++++---------- src/main.cpp | 97 ++++++++++++++++++++++++++------------------------ 2 files changed, 60 insertions(+), 67 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index 38b8b53..a122d35 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -298,26 +298,16 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned // to secure the network when proof-of-stake difficulty is low // DK changing calculations here creates a fork int64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)nStakeMaxAge) - nStakeMinAge; - CBigNum bnCoinDayWeight; - - if(fTestNet) -// bnCoinDayWeight = CBigNum((nValueIn) * nTimeWeight * 10000 / COIN / (24 * 60 * 60)); - if(nValueIn < 100) - bnCoinDayWeight = CBigNum(100 * nTimeWeight * 10000 / (24 * 60 * 60)); - else - bnCoinDayWeight = CBigNum((nValueIn) * nTimeWeight * 10000 / COIN / (24 * 60 * 60)); - else - { - if(totalCoin < VALUE_CHANGE) - bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); - else - { - if(nValueIn < 100) - bnCoinDayWeight = CBigNum(100 * nTimeWeight * 10000 / (24 * 60 * 60)); - else - bnCoinDayWeight = CBigNum((nValueIn) * nTimeWeight * 10000 / COIN / (24 * 60 * 60)); - } - } + CBigNum bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); +// CBigNum bnCoinDayWeight; +// if (totalCoin < 391430) +// bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); +// else +// bnCoinDayWeight = CBigNum(max(1000 * COIN, nValueIn)) * nTimeWeight / (24 * 60 * 60); + +//printf("calculation: nValueIn=%lld, max=%lld\n", nValueIn, max(1000 * COIN, nValueIn)); +//printf("CheckStakeKernelHash(): bnCoinDayWeight old style = %s, new style = %s\n", (CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60)).ToString().c_str(), (CBigNum(max(1000 * COIN, nValueIn)) * nTimeWeight / COIN / (24 * 60 * 60)).ToString().c_str()); +//printf("CheckStakeKernelHash(): nTimeWeight=%lld\n", nTimeWeight); // printf(">>> CheckStakeKernelHash: nTimeWeight = %"PRI64d"\n", nTimeWeight); // Calculate hash diff --git a/src/main.cpp b/src/main.cpp index 89abb95..2d77f3c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -469,7 +469,7 @@ bool CTransaction::CheckTransaction() const if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake()) return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); - if(totalCoin < VALUE_CHANGE) + if(totalCoin < VALUE_CHANGE || totalCoin > POS_RESTART) { // ppcoin: enforce minimum output amount if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT) @@ -477,7 +477,7 @@ bool CTransaction::CheckTransaction() const } else { - if (txout.nValue < 0) + if ((!txout.IsEmpty()) && txout.nValue < 0) return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative")); } @@ -974,7 +974,12 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) } else { - if(totalCoin > 1000000) + // Diamond v2 coin mechanics + // 0.10 reward after 1,000,000 created + // 0.02 reward after 2,500,000 created + if(totalCoin > 2500000) + nSubsidy = 2 * CENT; + else if(totalCoin > 1000000) nSubsidy = 10 * CENT; else if(totalCoin > 2500000) nSubsidy = 2 * CENT; @@ -989,30 +994,28 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi if(totalCoin >= VALUE_CHANGE || fTestNet) { int64 nRewardCoinYear; - int nSubsidy = 0; + int64 nSubsidy = 0; nRewardCoinYear = MAX_MINT_PROOF_OF_STAKE; if(fTestNet) - nSubsidy = nCoinAge * 50 * MAX_MINT_PROOF_OF_STAKE * 33 / (365 * 33 + 8) / COIN; - if(totalCoin > VALUE_CHANGE) - { - nSubsidy = nCoinAge * 50 * MAX_MINT_PROOF_OF_STAKE * 33 / (365 * 33 + 8) / COIN; - } - else if(totalCoin > VALUE_CHANGE + 4000) - { - nSubsidy = nCoinAge / COIN * 50 * MAX_MINT_PROOF_OF_STAKE * 33 / (365 * 33 + 8); - } - else if(totalCoin > 1500000) - { - nSubsidy = nCoinAge / COIN * 25 * MAX_MINT_PROOF_OF_STAKE * 33 / (365 * 33 + 8); - } - else if(totalCoin > 2500000) - { - nSubsidy = nCoinAge / COIN * 5 * MAX_MINT_PROOF_OF_STAKE * 33 / (365 * 33 + 8); - } - else if(totalCoin > 3500000) - { - nSubsidy = nCoinAge / COIN * 1 * MAX_MINT_PROOF_OF_STAKE * 33 / (365 * 33 + 8); - } + nSubsidy = nCoinAge * 50 * CENT / 365; + else + { + // Diamond v2 PoS spec: + // 50% algorithm switch to 1,500,000 coins + // 25% from 1,500,000 to 2,500,000 coins + // 5% from 2,500,000 to 3,500,000 coins + // 1% ever since 3,500,000 coins + if (totalCoin > 3500000) + nRewardCoinYear = 1 * CENT; + else if (totalCoin > 2500000) + nRewardCoinYear = 5 * CENT; + else if (totalCoin > 1500000) + nRewardCoinYear = 25 * CENT; + else + nRewardCoinYear = 50 * CENT; + + nSubsidy = nCoinAge * nRewardCoinYear / 365; + } if (fDebug && GetBoolArg("-printcreation")) printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits); @@ -1135,6 +1138,22 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); + // fix block spacing + // DK activating this will result in a fork + if (fProofOfStake && GetTotalCoin() > POS_RESTART) + { + if(nActualSpacing < 0) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to 1.\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing); + nActualSpacing = 1; + } + else if(nActualSpacing > nTargetTimespan) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetTimespan (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetTimespan); + nActualSpacing = nTargetTimespan; + } + } + // ppcoin: target change every block // ppcoin: retarget with exponential moving toward target spacing CBigNum bnNew; @@ -1987,11 +2006,7 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const printf("coin age nValueIn=%"PRI64d" nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString().c_str()); } - CBigNum bnCoinDay; - if(totalCoin >= VALUE_CHANGE) - bnCoinDay = bnCentSecond * CENT / (24 * 60 * 60); - else - bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); + CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); if (fDebug && GetBoolArg("-printcoinage")) printf("coin age bnCoinDay=%s\n", bnCoinDay.ToString().c_str()); nCoinAge = bnCoinDay.getuint64(); @@ -2108,16 +2123,6 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks } - //just for test - if(pindexBest != NULL && pindexBest->nHeight > 50 && fTestNet) - nCoinbaseMaturity = 15; - - if(totalCoin > VALUE_CHANGE) - { - nStakeMinAge = 30 * 24 * 60 * 60; - nStakeMaxAge = -1; - } - // These are checks that are independent of context // that can be verified before saving an orphan block. @@ -2126,7 +2131,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) return DoS(100, error("CheckBlock() : size limits failed")); // Check proof of work matches claimed amount - if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(hash1, nBits) && !CheckProofOfWork(hash2, nBits)) + if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) return DoS(50, error("CheckBlock() : proof of work failed")); // Check timestamp @@ -2287,10 +2292,10 @@ bool CBlock::AcceptBlock() CBigNum CBlockIndex::GetBlockTrust() const { - CBigNum bnTarget; - bnTarget.SetCompact(nBits); - if (bnTarget <= 0) - return 0; + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + if (bnTarget <= 0) + return 0; return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1); } @@ -4423,8 +4428,6 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) while (fGenerateBitcoins || fProofOfStake) { totalCoin = GetTotalCoin(); - if(totalCoin < VALUE_CHANGE && fProofOfStake) - break; if (fShutdown) return; while (vNodes.empty() || IsInitialBlockDownload()) From 8787b4bb285f63f35734ff92996b7db5a26508fc Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:45:28 +0300 Subject: [PATCH 017/218] Borrow code from MintCoin to fix the getbalance and getbalance '*' RPC calls and peer node storage. --- src/main.cpp | 2 -- src/main.h | 6 ++++++ src/net.cpp | 5 +++++ src/rpcwallet.cpp | 41 +++++++++++++++++++++++++++++++---------- src/util.h | 23 +++++++++++++++++++++++ src/wallet.cpp | 36 ++++++++++++++++++++---------------- src/wallet.h | 2 +- 7 files changed, 86 insertions(+), 29 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2d77f3c..08bc73f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -981,8 +981,6 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) nSubsidy = 2 * CENT; else if(totalCoin > 1000000) nSubsidy = 10 * CENT; - else if(totalCoin > 2500000) - nSubsidy = 2 * CENT; } return nSubsidy + nFees; } diff --git a/src/main.h b/src/main.h index 7c76bec..c616d10 100644 --- a/src/main.h +++ b/src/main.h @@ -546,6 +546,12 @@ class CTransaction return (vin.size() > 0 && (!vin[0].prevout.IsNull()) && vout.size() >= 2 && vout[0].IsEmpty()); } + bool IsCoinBaseOrStake() const + { + return (IsCoinBase() || IsCoinStake()); + } + + /** Check for standard transaction types @return True if all outputs (scriptPubKeys) use only standard transaction forms */ diff --git a/src/net.cpp b/src/net.cpp index 03ec7ef..c8a32ab 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -586,6 +586,8 @@ bool CNode::IsBanned(CNetAddr ip) return fResult; } +extern CMedianFilter cPeerBlockCounts; + bool CNode::Misbehaving(int howmuch) { if (addr.IsLocal()) @@ -605,6 +607,9 @@ bool CNode::Misbehaving(int howmuch) setBanned[addr] = banTime; } CloseSocketDisconnect(); + + cPeerBlockCounts.removeLast(nStartingHeight); // remove this node's reported number of blocks + return true; } else printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 0813849..f24479a 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -515,12 +515,17 @@ int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinD if (!wtx.IsFinal()) continue; - int64 nGenerated, nReceived, nSent, nFee; - wtx.GetAccountAmounts(strAccount, nGenerated, nReceived, nSent, nFee); + int64 nGeneratedImmature, nGeneratedMature, nReceived, nSent, nFee; + wtx.GetAccountAmounts(strAccount, nGeneratedImmature, nGeneratedMature, nReceived, nSent, nFee); if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) nBalance += nReceived; - nBalance += nGenerated - nSent - nFee; + + if((wtx.IsCoinBaseOrStake() && wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetBlocksToMaturity() == 0) + || !wtx.IsCoinBaseOrStake()) + { + nBalance += nGeneratedMature - nSent - nFee; + } } // Tally internal accounting entries @@ -574,10 +579,15 @@ Value getbalance(const Array& params, bool fHelp) BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listReceived) nBalance += r.second; } - BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent) + + if((wtx.IsCoinBaseOrStake() && wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetBlocksToMaturity() == 0) + || !wtx.IsCoinBaseOrStake()) + { + BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& r, listSent) nBalance -= r.second; - nBalance -= allFee; - nBalance += allGeneratedMature; + nBalance -= allFee; + nBalance += allGeneratedMature; + } } return ValueFromAmount(nBalance); } @@ -1139,23 +1149,34 @@ Value listaccounts(const Array& params, bool fHelp) for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; + + if(!wtx.IsFinal()) + continue; + int64 nGeneratedImmature, nGeneratedMature, nFee; string strSentAccount; list > listReceived; list > listSent; wtx.GetAmounts(nGeneratedImmature, nGeneratedMature, listReceived, listSent, nFee, strSentAccount); - mapAccountBalances[strSentAccount] -= nFee; - BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent) - mapAccountBalances[strSentAccount] -= s.second; if (wtx.GetDepthInMainChain() >= nMinDepth) { - mapAccountBalances[""] += nGeneratedMature; BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& r, listReceived) if (pwalletMain->mapAddressBook.count(r.first)) mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second; else mapAccountBalances[""] += r.second; } + + if((wtx.IsCoinBaseOrStake() && wtx.GetDepthInMainChain() >= nMinDepth && wtx.GetBlocksToMaturity() == 0) + || !wtx.IsCoinBaseOrStake()) + { + mapAccountBalances[strSentAccount] -= nFee; + mapAccountBalances[""] += nGeneratedMature; + + BOOST_FOREACH(const PAIRTYPE(CTxDestination, int64)& s, listSent) + mapAccountBalances[strSentAccount] -= s.second; + + } } list acentries; diff --git a/src/util.h b/src/util.h index 0113b18..610b813 100644 --- a/src/util.h +++ b/src/util.h @@ -533,6 +533,7 @@ template class CMedianFilter std::vector vValues; std::vector vSorted; unsigned int nSize; + T tInitial; public: CMedianFilter(unsigned int size, T initial_value): nSize(size) @@ -540,6 +541,7 @@ template class CMedianFilter vValues.reserve(size); vValues.push_back(initial_value); vSorted = vValues; + tInitial = initial_value; } void input(T value) @@ -555,6 +557,27 @@ template class CMedianFilter std::sort(vSorted.begin(), vSorted.end()); } + // remove last instance of a value + void removeLast(T value) + { + for (int i = vValues.size()-1; i >= 0; --i) + { + if (vValues[i] == value) + { + vValues.erase(vValues.begin()+i); + break; + } + } + if (vValues.empty()) + { + vValues.push_back(tInitial); + } + + vSorted.resize(vValues.size()); + std::copy(vValues.begin(), vValues.end(), vSorted.begin()); + std::sort(vSorted.begin(), vSorted.end()); + } + T median() const { int size = vSorted.size(); diff --git a/src/wallet.cpp b/src/wallet.cpp index bdea7d6..e4e87d6 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -639,15 +639,6 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l listSent.clear(); strSentAccount = strFromAccount; - if (IsCoinBase() || IsCoinStake()) - { - if (GetBlocksToMaturity() > 0) - nGeneratedImmature = pwallet->GetCredit(*this); - else - nGeneratedMature = GetCredit(); - return; - } - // Compute fee: int64 nDebit = GetDebit(); if (nDebit > 0) // debit>0 means we signed/sent this transaction @@ -663,8 +654,12 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l vector vchPubKey; if (!ExtractDestination(txout.scriptPubKey, address)) { - printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", + if(!IsCoinBaseOrStake()) + { + printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n", this->GetHash().ToString().c_str()); + } + continue; } // Don't report 'change' txouts @@ -675,15 +670,25 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l listSent.push_back(make_pair(address, txout.nValue)); if (pwallet->IsMine(txout)) - listReceived.push_back(make_pair(address, txout.nValue)); + { + if(IsCoinBaseOrStake()) + { + if(GetBlocksToMaturity() > 0) + nGeneratedImmature += txout.nValue; + else + nGeneratedMature += txout.nValue; + } + else + listReceived.push_back(make_pair(address, txout.nValue)); + } } } -void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, +void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGeneratedImmature, int64& nGeneratedMature, int64& nReceived, int64& nSent, int64& nFee) const { - nGenerated = nReceived = nSent = nFee = 0; + nGeneratedImmature = nGeneratedMature = nReceived = nSent = nFee = 0; int64 allGeneratedImmature, allGeneratedMature, allFee; string strSentAccount; @@ -691,14 +696,13 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, i list > listSent; GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount); - if (strAccount == "") - nGenerated = allGeneratedMature; if (strAccount == strSentAccount) { BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64)& s, listSent) nSent += s.second; nFee = allFee; - nGenerated = allGeneratedMature; + nGeneratedImmature = allGeneratedImmature; + nGeneratedMature = allGeneratedMature; } { LOCK(pwallet->cs_wallet); diff --git a/src/wallet.h b/src/wallet.h index 4614325..98e8641 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -621,7 +621,7 @@ class CWalletTx : public CMerkleTx void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list >& listReceived, std::list >& listSent, int64& nFee, std::string& strSentAccount) const; - void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, + void GetAccountAmounts(const std::string& strAccount, int64& nGeneratedImmature, int64& nGeneratedMature, int64& nReceived, int64& nSent, int64& nFee) const; bool IsFromMe() const From a9086fbc1c63b5c3fb19030c596b43e92ea4411f Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:48:11 +0300 Subject: [PATCH 018/218] Fix dev/foundation and fee/contribution terminology. Reimplement damaged tx-message RPC interface. Update wallet version. --- src/main.cpp | 99 ++++++++++++----------------------------------- src/main.h | 9 ++--- src/rpcwallet.cpp | 33 ++++++++++++---- src/version.h | 2 +- src/wallet.cpp | 10 ++--- 5 files changed, 60 insertions(+), 93 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 08bc73f..042d6dc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1695,18 +1695,18 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) return false; } else - if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetDevCoin(totalCoin)) + if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) return false; if(totalCoin >= VALUE_CHANGE && IsProofOfWork()) { - CBitcoinAddress address(!fTestNet ? DEV_ADDRESS : DEV_ADDRESS_TEST); + CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); CScript scriptPubKey; scriptPubKey.SetDestination(address.Get()); if (vtx[0].vout[1].scriptPubKey != scriptPubKey) - return error("ConnectBlock() : coinbase does not pay to the dev address)"); - if (vtx[0].vout[1].nValue < GetDevCoin(totalCoin)) - return error("ConnectBlock() : coinbase does not pay enough to dev addresss"); + return error("ConnectBlock() : coinbase does not pay to the foundation address)"); + if (vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) + return error("ConnectBlock() : coinbase does not pay enough to foundation addresss"); } // Update block index on disk without changing it in memory. @@ -4018,7 +4018,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) txNew.vin[0].prevout.SetNull(); if(totalCoin >= VALUE_CHANGE) { - CBitcoinAddress address(!fTestNet ? DEV_ADDRESS : DEV_ADDRESS_TEST); + CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); txNew.vout.resize(2); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; txNew.vout[1].scriptPubKey.SetDestination(address.Get()); @@ -4283,7 +4283,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); if(totalCoin >= VALUE_CHANGE) - pblock->vtx[0].vout[1].nValue = GetDevCoin(totalCoin); + pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); } // Fill in header @@ -4506,68 +4506,17 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) { totalCoin = GetTotalCoin(); - unsigned int nHashesDone = 0; - - uint256 thash; -// char scratchpad[SCRYPT_SCRATCHPAD_SIZE]; if(totalCoin < VALUE_CHANGE) { - //scrypt_1024_1_1_256_sp(BEGIN(pblock->nVersion), BEGIN(thash), scratchpad); - - if (thash <= hashTarget) - { - // Found a solution - SetThreadPriority(THREAD_PRIORITY_NORMAL); - CheckWork(pblock.get(), *pwallet, reservekey); - SetThreadPriority(THREAD_PRIORITY_LOWEST); - break; - } - pblock->nNonce += 1; - nHashesDone += 1; - if ((pblock->nNonce & 0xFF) == 0) - break; -// unsigned int nNonceFound; - -// nNonceFound = scanhash_scrypt( -// (block_header *)&pblock->nVersion, -// scratchbuf, -// max_nonce, -// nHashesDone, -// UBEGIN(result), -// &res_header -// ); - -// // Check if something found -// if (nNonceFound != (unsigned int) -1 && totalCoin < VALUE_CHANGE) -// { -// if (result <= hashTarget && totalCoin < VALUE_CHANGE) -// { -// // Found a solution -// pblock->nNonce = nNonceFound; -// assert(result == pblock->GetHash()); -// if (!pblock->SignBlock(*pwalletMain)) -// { -// // strMintWarning = strMintMessage; -// break; -// } -// strMintWarning = ""; - -// SetThreadPriority(THREAD_PRIORITY_NORMAL); -// CheckWork(pblock.get(), *pwalletMain, reservekey); -// SetThreadPriority(THREAD_PRIORITY_LOWEST); -// break; -// } -// else -// break; -// } -// else -// break; + // No more scrypt hashing, take a nap + Sleep(1000); + break; } else { - uint256 hash; - hash = pblock->GetHash(); + // new block, use groestl + uint256 hash = pblock->GetHashGroestl(); if (hash <= hashTarget) { if (!pblock->SignBlock(*pwalletMain)) @@ -4576,7 +4525,6 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) break; } strMintWarning = ""; - // nHashesDone += pblock->nNonce; SetThreadPriority(THREAD_PRIORITY_NORMAL); printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); @@ -4597,10 +4545,7 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) } else { - if(totalCoin < VALUE_CHANGE) - nHashCounter += nHashesDone; - else - nHashCounter += 1; + nHashCounter++; } if (GetTimeMillis() - nHPSTimerStart > 4000) { @@ -4612,12 +4557,13 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart); nHPSTimerStart = GetTimeMillis(); nHashCounter = 0; -// static int64 nLogTime; -// if (GetTime() - nLogTime > 30 * 60) -// { -// nLogTime = GetTime(); + static int64 nLogTime; + // log hash rate every 30 minutes + if (GetTime() - nLogTime > 30 * 60) + { + nLogTime = GetTime(); printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0); -// } + } } } } @@ -4710,7 +4656,12 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet) } -int64 GetDevCoin(int64 totalCoin) { +// Diamond coin mechanics +// Foundation contribution +// 0.05 until 1000000 coins generated +// 0.01 afterwards +// Changing this requires a fork +int64 GetContributionAmount(int64 totalCoin) { if(totalCoin < 1000000) return 0.05 * COIN; else diff --git a/src/main.h b/src/main.h index c616d10..1a36cc0 100644 --- a/src/main.h +++ b/src/main.h @@ -98,8 +98,7 @@ class CReserveKey; class CTxDB; class CTxIndex; - -int64 GetDevCoin(int64 totalCoin); +int64 GetContributionAmount(int64 totalCoin); void RegisterWallet(CWallet* pwalletIn); void UnregisterWallet(CWallet* pwalletIn); void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false, bool fConnect = true); @@ -664,14 +663,14 @@ class CTransaction { std::string str; str += IsCoinBase()? "Coinbase" : (IsCoinStake()? "Coinstake" : "CTransaction"); - str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%d)\n", + str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%"PRIszu", vout.size=%"PRIszu", nLockTime=%d), TxComment=%s\n", GetHash().ToString().substr(0,10).c_str(), nTime, nVersion, vin.size(), vout.size(), - nLockTime -// strTxComment.substr(0,30).c_str() + nLockTime, + strTxComment.substr(0,30).c_str() ); for (unsigned int i = 0; i < vin.size(); i++) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index f24479a..c735e37 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -280,9 +280,9 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) Value sendtoaddress(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( - "sendtoaddress [comment] [comment-to]\n" + "sendtoaddress [comment] [comment-to] [tx-comment]\n" " is a real and is rounded to the nearest 0.000001" + HelpRequiringPassphrase()); @@ -303,10 +303,20 @@ Value sendtoaddress(const Array& params, bool fHelp) if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) wtx.mapValue["to"] = params[3].get_str(); + // Transaction comment + std::string txcomment; + if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty()) + { + txcomment = params[4].get_str(); + if (txcomment.length() > MAX_TX_COMMENT_LEN) + txcomment.resize(MAX_TX_COMMENT_LEN); + } + + if (pwalletMain->IsLocked()) throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); - string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx, false, txcomment); if (strError != "") throw JSONRPCError(RPC_WALLET_ERROR, strError); @@ -656,9 +666,9 @@ Value movecmd(const Array& params, bool fHelp) Value sendfrom(const Array& params, bool fHelp) { - if (fHelp || params.size() < 3 || params.size() > 6) + if (fHelp || params.size() < 3 || params.size() > 7) throw runtime_error( - "sendfrom [minconf=1] [comment] [comment-to]\n" + "sendfrom [minconf=1] [comment] [comment-to] [tx-comment]\n" " is a real and is rounded to the nearest 0.000001" + HelpRequiringPassphrase()); @@ -682,6 +692,13 @@ Value sendfrom(const Array& params, bool fHelp) if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty()) wtx.mapValue["to"] = params[5].get_str(); + std::string txcomment; + if (params.size() > 6 && params[6].type() != null_type && !params[6].get_str().empty()) + { + txcomment = params[6].get_str(); + if (txcomment.length() > MAX_TX_COMMENT_LEN) + txcomment.resize(MAX_TX_COMMENT_LEN); + } EnsureWalletIsUnlocked(); // Check funds @@ -690,7 +707,7 @@ Value sendfrom(const Array& params, bool fHelp) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send - string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); + string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx, false, txcomment); if (strError != "") throw JSONRPCError(RPC_WALLET_ERROR, strError); @@ -700,9 +717,9 @@ Value sendfrom(const Array& params, bool fHelp) Value sendmany(const Array& params, bool fHelp) { - if (fHelp || params.size() < 2 || params.size() > 4) + if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( - "sendmany {address:amount,...} [minconf=1] [comment]\n" + "sendmany {address:amount,...} [minconf=1] [comment] [tx-cmments]\n" "amounts are double-precision floating point numbers" + HelpRequiringPassphrase()); diff --git a/src/version.h b/src/version.h index ce9c826..28a13f6 100644 --- a/src/version.h +++ b/src/version.h @@ -46,7 +46,7 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 -#define DISPLAY_VERSION_REVISION 0 +#define DISPLAY_VERSION_REVISION 2 #define DISPLAY_VERSION_BUILD 0 #endif diff --git a/src/wallet.cpp b/src/wallet.cpp index e4e87d6..748c803 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1363,11 +1363,11 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int { // The following split & combine thresholds are important to security // Should not be adjusted if you don't understand the consequences - static unsigned int nStakeSplitAge = (60 * 60 * 24 * 30); - const CBlockIndex* pIndex0 = GetLastBlockIndex(pindexBest, false); - int64 nCombineThreshold = 0; - if(pIndex0->pprev) - nCombineThreshold = GetProofOfWorkReward(pIndex0->nHeight, MIN_TX_FEE, pIndex0->pprev->GetBlockHash()) / 3; + static unsigned int nStakeSplitAge = (60 * 60 * 24 * 30); // Age under which amounts are split in two + int64 nCombineThreshold = 100 * COIN; // amount to combine smaller coints into +// const CBlockIndex* pIndex0 = GetLastBlockIndex(pindexBest, false); +// if(pIndex0->pprev) +// nCombineThreshold = GetProofOfWorkReward(pIndex0->nHeight, MIN_TX_FEE, pIndex0->pprev->GetBlockHash()) / 3; CBigNum bnTargetPerCoinDay; bnTargetPerCoinDay.SetCompact(nBits); From b670db427ce94b20479b3994cbc529a1022f84a9 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:49:16 +0300 Subject: [PATCH 019/218] Update client version, mingw build environment and (temporary) remove permanent node. --- src/clientversion.h | 2 +- src/init.cpp | 2 +- src/makefile.mingw | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index 2bfa6e6..e8f708b 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -8,7 +8,7 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 1 +#define CLIENT_VERSION_REVISION 2 #define CLIENT_VERSION_BUILD 0 // Converts the parameter X to a string after macro replacement on X has been performed. diff --git a/src/init.cpp b/src/init.cpp index 3d69b90..37175fc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -646,7 +646,7 @@ bool AppInit2() BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); - AddOneShot("54.229.220.59"); +// AddOneShot("54.229.220.59"); // TODO: replace this by DNSseed // AddOneShot(string("")); diff --git a/src/makefile.mingw b/src/makefile.mingw index 3ac9843..30a3008 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -6,9 +6,9 @@ USE_UPNP:=0 USE_IPV6:=1 INCLUDEPATHS= \ - -I"C:\boost_1_53_0" \ - -I"C:\db-4.8.30.NC\build_unix" \ - -I"C:\openssl-1.0.1e\include + -I"C:\deps\boost_1_55_0" \ + -I"C:\deps\db-4.8.30.NC\build_unix" \ + -I"C:\deps\openssl-1.0.1e\include LIBPATHS= \ -L"C:\boost_1_53_0\stage/lib" \ From d7db539aa0d3544dce41b1813850ed5ffdebe8b0 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:52:20 +0300 Subject: [PATCH 020/218] QT GUI fixes, images, tooltips. --- src/makefile.mingw | 21 +++---- src/qt/bitcoin.qrc | 2 +- src/qt/bitcoingui.cpp | 5 +- src/qt/forms/addressbookpage.ui | 2 +- src/qt/forms/overviewpage.ui | 18 +++--- src/qt/forms/sendcoinsdialog.ui | 8 +-- src/qt/forms/sendcoinsentry.ui | 14 ++--- src/qt/locale/bitcoin_ru.ts | 82 +++++++++++++-------------- src/qt/res/images/diamond-splash.jpg | Bin 22628 -> 25117 bytes src/qt/res/images/wallet.png | Bin 109034 -> 110396 bytes src/qt/transactionview.cpp | 2 +- 11 files changed, 78 insertions(+), 76 deletions(-) diff --git a/src/makefile.mingw b/src/makefile.mingw index 30a3008..75696a6 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -11,15 +11,15 @@ INCLUDEPATHS= \ -I"C:\deps\openssl-1.0.1e\include LIBPATHS= \ - -L"C:\boost_1_53_0\stage/lib" \ - -L"C:\db-4.8.30.NC\build_unix" \ - -L"C:\openssl-1.0.1e" + -L"C:\deps\boost_1_55_0\stage/lib" \ + -L"C:\deps\db-4.8.30.NC\build_unix" \ + -L"C:\deps\openssl-1.0.1e" LIBS= \ - -l boost_system-mgw45-mt-d-1_53 \ - -l boost_filesystem-mgw45-mt-d-1_53 \ - -l boost_program_options-mgw45-mt-d-1_53 \ - -l boost_thread-mgw45-mt-d-1_53 \ + -l boost_system-mgw45-mt-d-1_55 \ + -l boost_filesystem-mgw45-mt-d-1_55 \ + -l boost_program_options-mgw45-mt-d-1_55 \ + -l boost_thread-mgw45-mt-d-1_55 \ -l db_cxx \ -l ssl \ -l crypto @@ -27,7 +27,8 @@ LIBS= \ DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE -D__NO_SYSTEM_INCLUDES DEBUGFLAGS=-g CFLAGS=-mthreads -O2 -msse2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) -LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat +LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat -Wl,--large-address-aware -static + TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) @@ -35,8 +36,8 @@ ifndef USE_UPNP override USE_UPNP = - endif ifneq (${USE_UPNP}, -) - INCLUDEPATHS += -I"C:\miniupnpc-1.6-mgw" - LIBPATHS += -L"C:\miniupnpc-1.6-mgw" + INCLUDEPATHS += -I"C:\deps\miniupnpc-1.6-mgw" + LIBPATHS += -L"C:\deps\miniupnpc-1.6-mgw" LIBS += -l miniupnpc -l iphlpapi DEFS += -DSTATICLIB -DUSE_UPNP=$(USE_UPNP) endif diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index d9e11c5..7f811f1 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -45,7 +45,7 @@ res/images/about.png res/images/diamond-splash.jpg res/images/background.png - res/images/wallet.png + res/images/diamond.png res/movies/update_spinner.mng diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 2a78694..f4e1e75 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -25,6 +25,7 @@ #include "notificator.h" #include "guiutil.h" #include "rpcconsole.h" +#include "version.h" #ifdef Q_OS_MAC #include "macdockiconhandler.h" @@ -75,8 +76,8 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): rpcConsole(0) { resize(850, 550); - setWindowTitle(tr("Diamond") + " - " + tr("Wallet")); - setStyleSheet("QMainWindow{border-image: url(:/images/main_backg)} QToolButton:!hover {color:white;} QToolButton:hover {background-color:rgb(59, 88, 104);color:white;} QToolTip {background-color:#1f333e; color:white;}"); + setWindowTitle(tr("Diamond") + " - " + tr("Wallet") + " " + QString::fromStdString(CLIENT_BUILD)); + setStyleSheet("QMainWindow{border-image: url(:/images/main_backg)} QToolButton:!hover {color:white; border-style: none;} QToolButton:hover {background-color:rgb(59, 88, 104);color:white; border-style: none;} QToolTip {background-color:#1f333e; color:white; border-style: none;}"); #ifndef Q_OS_MAC qApp->setWindowIcon(QIcon(":icons/bitcoin")); diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui index 69597e8..70ef9d4 100644 --- a/src/qt/forms/addressbookpage.ui +++ b/src/qt/forms/addressbookpage.ui @@ -485,7 +485,7 @@ QTableView {background-color:rgb(69, 87, 96); color:white;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} false diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 5361d26..c594df7 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -56,7 +56,7 @@ The displayed information may be out of date. Your wallet automatically synchronizes with the Diamond network after a connection is established, but this process has not completed yet. - QToolTip {background-color:#1f333e; color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} QLabel { color: red; background:transparent;} @@ -119,7 +119,7 @@ QLabel { color: red; background:transparent;} QLabel {background:transparent;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} 0 DMD @@ -155,7 +155,7 @@ QToolTip {background-color:#1f333e; color:white;} QLabel {background:transparent;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} 0 DMD @@ -191,7 +191,7 @@ QToolTip {background-color:#1f333e; color:white;} QLabel {background:transparent;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} 0 DMD @@ -224,7 +224,7 @@ QToolTip {background-color:#1f333e; color:white;} QLabel {background:transparent;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} 0 DMD @@ -251,7 +251,7 @@ QToolTip {background-color:#1f333e; color:white;} QLabel {background:transparent;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} 0 @@ -325,7 +325,7 @@ QToolTip {background-color:#1f333e; color:white;} background:transparent; - <html><head/><body><p><span style=" font-weight:600; color:#ffffff;">Recent transactions</span></p></body></html> + <b>Recent transactions</b> @@ -335,7 +335,7 @@ QToolTip {background-color:#1f333e; color:white;} The displayed information may be out of date. Your wallet automatically synchronizes with the Diamond network after a connection is established, but this process has not completed yet. - QToolTip {background-color:#1f333e; color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} QLabel { color: red; background:transparent; } @@ -365,7 +365,7 @@ QLabel { color: red; background:transparent; } QListView { background: transparent; } -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} QFrame::NoFrame diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 715d244..96896bb 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -15,7 +15,7 @@ SendCoinsDialog {background:transparent; color:white;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} @@ -115,7 +115,7 @@ background-color:rgba(255, 255, 255, 40); color: white; QPushButton {background-color:rgb(69, 87, 96); color: white;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} Add &Recipient @@ -145,7 +145,7 @@ QToolTip {background-color:#1f333e; color:white;} QPushButton {background-color:rgb(69, 87, 96); color: white;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} Clear &All @@ -215,7 +215,7 @@ QToolTip {background-color:#1f333e; color:white;} QPushButton {background-color:rgb(69, 87, 96); color: white;} -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} S&end diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 3fcb25a..259c3dd 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -16,7 +16,7 @@ background-color:rgb(69, 87, 96); QPushButton{background-color:rgba(97, 147, 174, 255);color:white;} -QToolTip {background-color:#1f333e !important; color:white !important;} +QToolTip {background-color:#1f333e !important; color:white !important; border-style: none;} QFrame::StyledPanel @@ -58,7 +58,7 @@ QToolTip {background-color:#1f333e !important; color:white !important;} color:white; -QToolTip {background-color:#1f333e; color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} @@ -76,7 +76,7 @@ QToolTip {background-color:#1f333e; color:white;} Enter a label for this address to add it to your address book - QToolTip {background-color:#1f333e; color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} @@ -106,7 +106,7 @@ QToolTip {background-color:#1f333e; color:white;} The address to send the payment to (e.g. dc8hQjs9oy9AHPCSF5aTvkcRVECojV3joC) - QToolTip {background-color:#1f333e; color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} 34 @@ -119,7 +119,7 @@ QToolTip {background-color:#1f333e; color:white;} Choose address from address book - QToolTip {background-color:#1f333e; color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} @@ -139,7 +139,7 @@ QToolTip {background-color:#1f333e; color:white;} Paste address from clipboard - QToolTip {background-color:#1f333e; color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} @@ -159,7 +159,7 @@ QToolTip {background-color:#1f333e; color:white;} Remove this recipient - QToolTip {background-color:#1f333e; color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 56abb9a..25ee548 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -226,7 +226,7 @@ This product includes software developed by the OpenSSL Project for use in the O Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>! - Внимание: еÑли вы зашифруете бумажник и потерÑете пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ Ð’ÐШИ МОÐЕТЫ</b>! + Внимание: еÑли вы зашифруете бумажник и потерÑете пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ Ð’ÐШÐ? МОÐЕТЫ</b>! @@ -337,7 +337,7 @@ This product includes software developed by the OpenSSL Project for use in the O Edit the list of stored addresses and labels - Изменить ÑпиÑок Ñохранённых адреÑов и меток к ним + Ð?зменить ÑпиÑок Ñохранённых адреÑов и меток к ним @@ -397,7 +397,7 @@ This product includes software developed by the OpenSSL Project for use in the O &Change Passphrase... - &Изменить пароль + &Ð?зменить пароль @@ -426,7 +426,7 @@ This product includes software developed by the OpenSSL Project for use in the O Modify configuration options for BottleCaps - Изменить параметры конфигурации BottleCaps + Ð?зменить параметры конфигурации BottleCaps @@ -446,7 +446,7 @@ This product includes software developed by the OpenSSL Project for use in the O Change the passphrase used for wallet encryption - Изменить пароль ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ° + Ð?зменить пароль ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ° @@ -598,7 +598,7 @@ This product includes software developed by the OpenSSL Project for use in the O Sent transaction - ИÑходÑÑ‰Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ + Ð?ÑходÑÑ‰Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ @@ -679,7 +679,7 @@ Address: %4 Edit Address - Изменить Ð°Ð´Ñ€ÐµÑ + Ð?зменить Ð°Ð´Ñ€ÐµÑ @@ -714,12 +714,12 @@ Address: %4 Edit receiving address - Изменение адреÑа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ + Ð?зменение адреÑа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Edit sending address - Изменение адреÑа Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ + Ð?зменение адреÑа Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ @@ -758,7 +758,7 @@ Address: %4 Usage: - ИÑпользование: + Ð?Ñпользование: @@ -1116,7 +1116,7 @@ Address: %4 PNG Images (*.png) - PNG Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png) + PNG Ð?Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png) @@ -1124,7 +1124,7 @@ Address: %4 Client name - Ð˜Ð¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° + Ð?Ð¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° @@ -1148,12 +1148,12 @@ Address: %4 &Information - &Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ + &Ð?Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Using OpenSSL version - ИÑпользуетÑÑ Ð²ÐµÑ€ÑÐ¸Ñ OpenSSL + Ð?ÑпользуетÑÑ Ð²ÐµÑ€ÑÐ¸Ñ OpenSSL @@ -1258,7 +1258,7 @@ Address: %4 Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. - ИÑпользуйте Ñтрелки вверх и вниз Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра иÑтории и <b>Ctrl-L</b> Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки Ñкрана. + Ð?Ñпользуйте Ñтрелки вверх и вниз Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра иÑтории и <b>Ctrl-L</b> Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки Ñкрана. @@ -1406,8 +1406,8 @@ Address: %4 - The address to send the payment to (e.g. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - ÐÐ´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶Ð° (например dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + The address to send the payment to (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + ÐÐ´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶Ð° (например 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) @@ -1436,8 +1436,8 @@ Address: %4 - Enter a BottleCaps address (e.g. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Введите BottleCaps-Ð°Ð´Ñ€ÐµÑ (например dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Enter a BottleCaps address (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Введите BottleCaps-Ð°Ð´Ñ€ÐµÑ (например 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) @@ -1460,8 +1460,8 @@ Address: %4 - The address to sign the message with (e.g. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - ÐдреÑ, которым вы хотите подпиÑать Ñообщение (напр. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + The address to sign the message with (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + ÐдреÑ, которым вы хотите подпиÑать Ñообщение (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) @@ -1524,8 +1524,8 @@ Address: %4 - The address the message was signed with (e.g. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - ÐдреÑ, которым было подпиÑано Ñообщение (напр. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + The address the message was signed with (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + ÐдреÑ, которым было подпиÑано Ñообщение (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) @@ -1540,8 +1540,8 @@ Address: %4 - Enter a BottleCaps address (e.g. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Введите Ð°Ð´Ñ€ÐµÑ BottleCaps (напр. dZo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Enter a BottleCaps address (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Введите Ð°Ð´Ñ€ÐµÑ BottleCaps (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) @@ -1673,7 +1673,7 @@ Address: %4 Source - ИÑточник + Ð?Ñточник @@ -1768,7 +1768,7 @@ Address: %4 Staked coins must wait 520 blocks before they can return to balance and be spent. When you generated this proof-of-stake block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be a valid stake. This may occasionally happen if another node generates a proof-of-stake block within a few seconds of yours. - ИÑпользованные в Proof-of-Stake монеты должны подождать 520 блоков, прежде чем они вернутÑÑ Ð½Ð° Ð±Ð°Ð»Ð°Ð½Ñ Ð¸ Ñмогут быть потрачены. Когда вы Ñгенерировали Ñтот proof-of-stake блок, он был отправлен в Ñеть Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² цепочку блоков. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° не удаетÑÑ, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑÑ Ð½Ð° \"не подтверждени\" и блок будет недейÑтвителен. Это иногда проиÑходит в Ñлучае, еÑли другой узел Ñгенерирует блок на неÑколько Ñекунд раньше ваÑ. + Ð?Ñпользованные в Proof-of-Stake монеты должны подождать 520 блоков, прежде чем они вернутÑÑ Ð½Ð° Ð±Ð°Ð»Ð°Ð½Ñ Ð¸ Ñмогут быть потрачены. Когда вы Ñгенерировали Ñтот proof-of-stake блок, он был отправлен в Ñеть Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² цепочку блоков. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° не удаетÑÑ, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑÑ Ð½Ð° \"не подтверждени\" и блок будет недейÑтвителен. Это иногда проиÑходит в Ñлучае, еÑли другой узел Ñгенерирует блок на неÑколько Ñекунд раньше ваÑ. @@ -2041,7 +2041,7 @@ Address: %4 Edit label - Изменить метку + Ð?зменить метку @@ -2132,7 +2132,7 @@ Address: %4 Usage: - ИÑпользование: + Ð?Ñпользование: @@ -2213,7 +2213,7 @@ Address: %4 Bind to given address. Use [host]:port notation for IPv6 - ПривÑзатьÑÑ (bind) к указанному адреÑу. ИÑпользуйте запиÑÑŒ вида [хоÑÑ‚]:порт Ð´Ð»Ñ IPv6 + ПривÑзатьÑÑ (bind) к указанному адреÑу. Ð?Ñпользуйте запиÑÑŒ вида [хоÑÑ‚]:порт Ð´Ð»Ñ IPv6 @@ -2273,12 +2273,12 @@ Address: %4 Importing blockchain data file. - ИмпортируетÑÑ Ñ„Ð°Ð¹Ð» цепи блоков. + Ð?мпортируетÑÑ Ñ„Ð°Ð¹Ð» цепи блоков. Importing bootstrap blockchain data file. - ИмпортируетÑÑ bootstrap-файл цепи блоков. + Ð?мпортируетÑÑ bootstrap-файл цепи блоков. @@ -2288,7 +2288,7 @@ Address: %4 Use the test network - ИÑпользовать теÑтовую Ñеть + Ð?Ñпользовать теÑтовую Ñеть @@ -2353,12 +2353,12 @@ Address: %4 Failed to listen on any port. Use -listen=0 if you want this. - Ðе удалоÑÑŒ начать проÑлушивание на порту. ИÑпользуйте -listen=0 еÑли Ð²Ð°Ñ Ñто уÑтраивает. + Ðе удалоÑÑŒ начать проÑлушивание на порту. Ð?Ñпользуйте -listen=0 еÑли Ð²Ð°Ñ Ñто уÑтраивает. Find peers using DNS lookup (default: 0 unless -connect) - ИÑкать узлы Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ DNS (по умолчанию: 0) + Ð?Ñкать узлы Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ DNS (по умолчанию: 0) @@ -2439,22 +2439,22 @@ Address: %4 Use UPnP to map the listening port (default: 0) - ИÑпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 0) + Ð?Ñпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 0) Use UPnP to map the listening port (default: 1 when listening) - ИÑпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 1, еÑли иÑпользуетÑÑ Ð¿Ñ€Ð¾Ñлушивание) + Ð?Ñпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 1, еÑли иÑпользуетÑÑ Ð¿Ñ€Ð¾Ñлушивание) Use proxy to reach tor hidden services (default: same as -proxy) - ИÑпользовать прокÑи Ð´Ð»Ñ Ñкрытых ÑервиÑов (по умолчанию: тот же, что и в -proxy) + Ð?Ñпользовать прокÑи Ð´Ð»Ñ Ñкрытых ÑервиÑов (по умолчанию: тот же, что и в -proxy) Username for JSON-RPC connections - Ð˜Ð¼Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC + Ð?Ð¼Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC @@ -2524,12 +2524,12 @@ Address: %4 Imports blocks from external blk000?.dat file - Импортировать блоки из внешнего файла blk000?.dat + Ð?мпортировать блоки из внешнего файла blk000?.dat Use OpenSSL (https) for JSON-RPC connections - ИÑпользовать OpenSSL (https) Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC + Ð?Ñпользовать OpenSSL (https) Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC diff --git a/src/qt/res/images/diamond-splash.jpg b/src/qt/res/images/diamond-splash.jpg index ff478322a9085a32f9f8dc29faf97f1b2ff42f53..584c10aa4a56c8279ea9534fd59bbaad7cf5769f 100644 GIT binary patch literal 25117 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 N002ovPDHLkV1haeX}r-8HzoyAR*J@4lHIZ_TVV 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%0D;e$MztG_56ngeha%tjS_Jwb9FV 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 P00000NkvXXu0mjf5g;setModel(transactionProxyModel); transactionView->setAlternatingRowColors(true); - transactionView->setStyleSheet("QTableView{alternate-background-color: rgb(37,59,72); background-color: rgb(60,93,112); selection-background-color: rgb(97,147,174);} QToolTip{background-color:#1f333e; color:white}"); + transactionView->setStyleSheet("QTableView{alternate-background-color: rgb(37,59,72); background-color: rgb(60,93,112); selection-background-color: rgb(97,147,174);} QToolTip{background-color:#1f333e; color:white; border-style: none;}"); transactionView->setSelectionBehavior(QAbstractItemView::SelectRows); transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection); From 677e53644f37fc4e23f99d71bb73e76d00ddb17d Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 15:53:39 +0300 Subject: [PATCH 021/218] copyright fix. --- COPYING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYING b/COPYING index 8a76dbc..506dbfa 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014 Diamond Developers +Copyright (c) 2014 Diamond Foundation Copyright (c) 2011-2012 PPCoin Developers Copyright (c) 2009-2012 Bitcoin Developers From 35499c50a41281d2b9c7b3cf9dc387141eea6960 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 16:04:17 +0300 Subject: [PATCH 022/218] Fix encoding. --- src/qt/locale/bitcoin_ru.ts | 1058 +++++++++++++++++------------------ 1 file changed, 529 insertions(+), 529 deletions(-) diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 25ee548..4a0a8a2 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -7,17 +7,17 @@ About BottleCaps - О BottleCaps + Î BottleCaps <b>BottleCaps</b> version - <b>BottleCaps</b> верÑÐ¸Ñ + <b>BottleCaps</b> âåðñèÿ - Copyright © 2009-2012 The BottleCaps developers - Ð’Ñе права защищены © 2009-2012 Разработчики BottleCaps + Copyright © 2009-2012 The BottleCaps developers + Âñå ïðàâà çàùèùåíû © 2009-2012 Ðàçðàáîò÷èêè BottleCaps @@ -28,11 +28,11 @@ Distributed under the MIT/X11 software license, see the accompanying file COPYIN This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. -Это ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð°. +Ýòî ýêñïåðèìåíòàëüíàÿ ïðîãðàììà. -РаÑпроÑтранÑетÑÑ Ð½Ð° правах лицензии MIT/X11, Ñм. файл license.txt или http://www.opensource.org/licenses/mit-license.php. +Ðàñïðîñòðàíÿåòñÿ íà ïðàâàõ ëèöåíçèè MIT/X11, ñì. ôàéë license.txt èëè http://www.opensource.org/licenses/mit-license.php. -Этот продукт включает ПО, разработанное OpenSSL Project Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² OpenSSL Toolkit (http://www.openssl.org/) и криптографичеÑкое ПО, напиÑанное Eric Young (eay@cryptsoft.com) и ПО Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ UPnP, напиÑанное Thomas Bernard. +Ýòîò ïðîäóêò âêëþ÷àåò ÏÎ, ðàçðàáîòàííîå OpenSSL Project äëÿ èñïîëüçîâàíèÿ â OpenSSL Toolkit (http://www.openssl.org/) è êðèïòîãðàôè÷åñêîå ÏÎ, íàïèñàííîå Eric Young (eay@cryptsoft.com) è ÏÎ äëÿ ðàáîòû ñ UPnP, íàïèñàííîå Thomas Bernard. @@ -40,102 +40,102 @@ This product includes software developed by the OpenSSL Project for use in the O Address Book - ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° + Àäðåñíàÿ êíèãà Double-click to edit address or label - Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы изменить Ð°Ð´Ñ€ÐµÑ Ð¸Ð»Ð¸ метку давжды кликните по изменÑемому объекту + Äëÿ òîãî, ÷òîáû èçìåíèòü àäðåñ èëè ìåòêó äàâæäû êëèêíèòå ïî èçìåíÿåìîìó îáúåêòó Create a new address - Создать новый Ð°Ð´Ñ€ÐµÑ + Ñîçäàòü íîâûé àäðåñ Copy the currently selected address to the system clipboard - Копировать текущий выделенный Ð°Ð´Ñ€ÐµÑ Ð² буфер обмена + Êîïèðîâàòü òåêóùèé âûäåëåííûé àäðåñ â áóôåð îáìåíà &New Address - &Ðовый Ð°Ð´Ñ€ÐµÑ + &Íîâûé àäðåñ These are your BottleCaps addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. - Это Ваши адреÑа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶ÐµÐ¹. Ð’Ñ‹ можете дать разные адреÑа отправителÑм, чтобы отÑлеживать, кто именно вам платит. + Ýòî Âàøè àäðåñà äëÿ ïîëó÷åíèÿ ïëàòåæåé. Âû ìîæåòå äàòü ðàçíûå àäðåñà îòïðàâèòåëÿì, ÷òîáû îòñëåæèâàòü, êòî èìåííî âàì ïëàòèò. &Copy Address - &Копировать Ð°Ð´Ñ€ÐµÑ + &Êîïèðîâàòü àäðåñ Show &QR Code - Показать &QR код + Ïîêàçàòü &QR êîä Sign a message to prove you own a BottleCaps address - ПодпиÑать Ñообщение, чтобы доказать владение адреÑом BottleCaps + Ïîäïèñàòü ñîîáùåíèå, ÷òîáû äîêàçàòü âëàäåíèå àäðåñîì BottleCaps Sign &Message - &ПодпиÑать Ñообщение + &Ïîäïèñàòü ñîîáùåíèå Delete the currently selected address from the list - Удалить выбранный Ð°Ð´Ñ€ÐµÑ Ð¸Ð· ÑпиÑка + Óäàëèòü âûáðàííûé àäðåñ èç ñïèñêà Verify a message to ensure it was signed with a specified BottleCaps address - Проверить Ñообщение, чтобы убедитьÑÑ, что оно было подпиÑано указанным адреÑом BottleCaps + Ïðîâåðèòü ñîîáùåíèå, ÷òîáû óáåäèòüñÿ, ÷òî îíî áûëî ïîäïèñàíî óêàçàííûì àäðåñîì BottleCaps &Verify Message - &Проверить Ñообщение + &Ïðîâåðèòü ñîîáùåíèå &Delete - &Удалить + &Óäàëèòü Copy &Label - Копировать &метку + Êîïèðîâàòü &ìåòêó &Edit - &Правка + &Ïðàâêà Export Address Book Data - ЭкÑпортировать адреÑную книгу + Ýêñïîðòèðîâàòü àäðåñíóþ êíèãó Comma separated file (*.csv) - ТекÑÑ‚, разделённый запÑтыми (*.csv) + Òåêñò, ðàçäåë¸ííûé çàïÿòûìè (*.csv) Error exporting - Ошибка ÑкÑпорта + Îøèáêà ýêñïîðòà Could not write to file %1. - Ðевозможно запиÑать в файл %1. + Íåâîçìîæíî çàïèñàòü â ôàéë %1. @@ -143,17 +143,17 @@ This product includes software developed by the OpenSSL Project for use in the O Label - Метка + Ìåòêà Address - ÐÐ´Ñ€ÐµÑ + Àäðåñ (no label) - [нет метки] + [íåò ìåòêè] @@ -161,99 +161,99 @@ This product includes software developed by the OpenSSL Project for use in the O Passphrase Dialog - Диалог ввода Ð¿Ð°Ñ€Ð¾Ð»Ñ + Äèàëîã ââîäà ïàðîëÿ Enter passphrase - Введите пароль + Ââåäèòå ïàðîëü New passphrase - Ðовый пароль + Íîâûé ïàðîëü Repeat new passphrase - Повторите новый пароль + Ïîâòîðèòå íîâûé ïàðîëü Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. - Введите новый пароль Ð´Ð»Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ°. <br/> ПожалуйÑта, иÑпользуйте фразы из <b>10 или более Ñлучайных Ñимволов,</b> или <b>воÑьми и более Ñлов.</b> + Ââåäèòå íîâûé ïàðîëü äëÿ áóìàæíèêà. <br/> Ïîæàëóéñòà, èñïîëüçóéòå ôðàçû èç <b>10 èëè áîëåå ñëó÷àéíûõ ñèìâîëîâ,</b> èëè <b>âîñüìè è áîëåå ñëîâ.</b> Encrypt wallet - Зашифровать бумажник + Çàøèôðîâàòü áóìàæíèê This operation needs your wallet passphrase to unlock the wallet. - Ð”Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ требуетÑÑ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ вашего бумажника. + Äëÿ âûïîëíåíèÿ îïåðàöèè òðåáóåòñÿ ïàðîëü âàøåãî áóìàæíèêà. Unlock wallet - Разблокировать бумажник + Ðàçáëîêèðîâàòü áóìàæíèê This operation needs your wallet passphrase to decrypt the wallet. - Ð”Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ требуетÑÑ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ вашего бумажника. + Äëÿ âûïîëíåíèÿ îïåðàöèè òðåáóåòñÿ ïàðîëü âàøåãî áóìàæíèêà. Decrypt wallet - РаÑшифровать бумажник + Ðàñøèôðîâàòü áóìàæíèê Change passphrase - Сменить пароль + Ñìåíèòü ïàðîëü Enter the old and new passphrase to the wallet. - Введите Ñтарый и новый пароль Ð´Ð»Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ°. + Ââåäèòå ñòàðûé è íîâûé ïàðîëü äëÿ áóìàæíèêà. Confirm wallet encryption - Подтвердите шифрование бумажника + Ïîäòâåðäèòå øèôðîâàíèå áóìàæíèêà Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>! - Внимание: еÑли вы зашифруете бумажник и потерÑете пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ Ð’ÐШÐ? МОÐЕТЫ</b>! + Âíèìàíèå: åñëè âû çàøèôðóåòå áóìàæíèê è ïîòåðÿåòå ïàðîëü, âû <b>ÏÎÒÅÐßÅÒÅ ÂÑÅ ÂÀØÈ ÌÎÍÅÒÛ</b>! Are you sure you wish to encrypt your wallet? - Ð’Ñ‹ уверены, что хотите зашифровать ваш бумажник? + Âû óâåðåíû, ÷òî õîòèòå çàøèôðîâàòü âàø áóìàæíèê? IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - Ð’ÐЖÐО: вÑе предыдущие резервные копии вашего кошелька должны быть заменены новым зашифрованным файлом. Ð’ целÑÑ… безопаÑноÑти предыдущие резервные копии нешифрованного кошелька Ñтанут беÑполезны, как только вы начнёте иÑпользовать новый шифрованный кошелёк. + ÂÀÆÍÎ: âñå ïðåäûäóùèå ðåçåðâíûå êîïèè âàøåãî êîøåëüêà äîëæíû áûòü çàìåíåíû íîâûì çàøèôðîâàííûì ôàéëîì.  öåëÿõ áåçîïàñíîñòè ïðåäûäóùèå ðåçåðâíûå êîïèè íåøèôðîâàííîãî êîøåëüêà ñòàíóò áåñïîëåçíû, êàê òîëüêî âû íà÷í¸òå èñïîëüçîâàòü íîâûé øèôðîâàííûé êîøåë¸ê. Warning: The Caps Lock key is on! - Внимание: Caps Lock включен! + Âíèìàíèå: Caps Lock âêëþ÷åí! Wallet encrypted - Бумажник зашифрован + Áóìàæíèê çàøèôðîâàí BottleCaps will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your coins from being stolen by malware infecting your computer. - Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð° закроетÑÑ Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа шифрованиÑ. Помните, что шифрование вашего бумажника не может полноÑтью защитить ваши монеты от кражи Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ð¸Ð½Ñ„Ð¸Ñ†Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ компьютера вредоноÑным ПО. + Ñåé÷àñ ïðîãðàììà çàêðîåòñÿ äëÿ çàâåðøåíèÿ ïðîöåññà øèôðîâàíèÿ. Ïîìíèòå, ÷òî øèôðîâàíèå âàøåãî áóìàæíèêà íå ìîæåò ïîëíîñòüþ çàùèòèòü âàøè ìîíåòû îò êðàæè ñ ïîìîùüþ èíôèöèðîâàíèÿ âàøåãî êîìïüþòåðà âðåäîíîñíûì ÏÎ. @@ -261,40 +261,40 @@ This product includes software developed by the OpenSSL Project for use in the O Wallet encryption failed - Ðе удалоÑÑŒ зашифровать бумажник + Íå óäàëîñü çàøèôðîâàòü áóìàæíèê Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Шифрование бумажника не удалоÑÑŒ из-за внутренней ошибки. Ваш бумажник не был зашифрован. + Øèôðîâàíèå áóìàæíèêà íå óäàëîñü èç-çà âíóòðåííåé îøèáêè. Âàø áóìàæíèê íå áûë çàøèôðîâàí. The supplied passphrases do not match. - Введённые пароли не Ñовпадают. + Ââåä¸ííûå ïàðîëè íå ñîâïàäàþò. Wallet unlock failed - Разблокировка бумажника не удалаÑÑŒ + Ðàçáëîêèðîâêà áóìàæíèêà íå óäàëàñü The passphrase entered for the wallet decryption was incorrect. - Указанный пароль не подходит. + Óêàçàííûé ïàðîëü íå ïîäõîäèò. Wallet decryption failed - РаÑшифрование бумажника не удалоÑÑŒ + Ðàñøèôðîâàíèå áóìàæíèêà íå óäàëîñü Wallet passphrase was successfully changed. - Пароль бумажника уÑпешно изменён. + Ïàðîëü áóìàæíèêà óñïåøíî èçìåí¸í. @@ -302,166 +302,166 @@ This product includes software developed by the OpenSSL Project for use in the O Sign &message... - &ПодпиÑать Ñообщение + &Ïîäïèñàòü ñîîáùåíèå Synchronizing with network... - Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ Ñетью... + Ñèíõðîíèçàöèÿ ñ ñåòüþ... &Overview - О&бзор + Î&áçîð Show general overview of wallet - Показать общий обзор дейÑтвий Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ¾Ð¼ + Ïîêàçàòü îáùèé îáçîð äåéñòâèé ñ áóìàæíèêîì &Transactions - &Транзакции + &Òðàíçàêöèè Browse transaction history - Показать иÑторию транзакций + Ïîêàçàòü èñòîðèþ òðàíçàêöèé &Address Book - &ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° + &Àäðåñíàÿ êíèãà Edit the list of stored addresses and labels - Ð?зменить ÑпиÑок Ñохранённых адреÑов и меток к ним + Èçìåíèòü ñïèñîê ñîõðàí¸ííûõ àäðåñîâ è ìåòîê ê íèì &Receive coins - &Получение монет + &Ïîëó÷åíèå ìîíåò Show the list of addresses for receiving payments - Показать ÑпиÑок адреÑов Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶ÐµÐ¹ + Ïîêàçàòü ñïèñîê àäðåñîâ äëÿ ïîëó÷åíèÿ ïëàòåæåé &Send coins - Отп&равка монет + Îòï&ðàâêà ìîíåò E&xit - Ð’&ыход + Â&ûõîä Quit application - Закрыть приложение + Çàêðûòü ïðèëîæåíèå Show information about BottleCaps - Показать информацию о BottleCaps'е + Ïîêàçàòü èíôîðìàöèþ î BottleCaps'å About &Qt - О &Qt + Î &Qt Show information about Qt - Показать информацию о Qt + Ïîêàçàòü èíôîðìàöèþ î Qt &Options... - Оп&ции... + Îï&öèè... &Encrypt Wallet... - &Зашифровать бумажник + &Çàøèôðîâàòü áóìàæíèê &Backup Wallet... - &Сделать резервную копию бумажника + &Ñäåëàòü ðåçåðâíóþ êîïèþ áóìàæíèêà &Change Passphrase... - &Ð?зменить пароль + &Èçìåíèòü ïàðîëü ~%n block(s) remaining - оÑталÑÑ ~%n блок - оÑталоÑÑŒ ~%n блоков - оÑталоÑÑŒ ~%n блоков + îñòàëñÿ ~%n áëîê + îñòàëîñü ~%n áëîêîâ + îñòàëîñü ~%n áëîêîâ Downloaded %1 of %2 blocks of transaction history (%3% done). - Загружено %1 из %2 блоков иÑтории операций (%3% завершено). + Çàãðóæåíî %1 èç %2 áëîêîâ èñòîðèè îïåðàöèé (%3% çàâåðøåíî). &Export... - &ЭкÑпорт... + &Ýêñïîðò... Send coins to a BottleCaps address - Отправить монеты на указанный Ð°Ð´Ñ€ÐµÑ BottleCaps + Îòïðàâèòü ìîíåòû íà óêàçàííûé àäðåñ BottleCaps Modify configuration options for BottleCaps - Ð?зменить параметры конфигурации BottleCaps + Èçìåíèòü ïàðàìåòðû êîíôèãóðàöèè BottleCaps Export the data in the current tab to a file - ЭкÑпортировать данные из вкладки в файл + Ýêñïîðòèðîâàòü äàííûå èç âêëàäêè â ôàéë Encrypt or decrypt wallet - Зашифровать или раÑшифровать бумажник + Çàøèôðîâàòü èëè ðàñøèôðîâàòü áóìàæíèê Backup wallet to another location - Сделать резервную копию бумажника в другом меÑте + Ñäåëàòü ðåçåðâíóþ êîïèþ áóìàæíèêà â äðóãîì ìåñòå Change the passphrase used for wallet encryption - Ð?зменить пароль ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ° + Èçìåíèòü ïàðîëü øèôðîâàíèÿ áóìàæíèêà &Debug window - &Окно отладки + &Îêíî îòëàäêè Open debugging and diagnostic console - Открыть конÑоль отладки и диагноÑтики + Îòêðûòü êîíñîëü îòëàäêè è äèàãíîñòèêè &Verify message... - &Проверить Ñообщение... + &Ïðîâåðèòü ñîîáùåíèå... @@ -471,139 +471,139 @@ This product includes software developed by the OpenSSL Project for use in the O Wallet - Бумажник + Áóìàæíèê &About BottleCaps - &О BottleCaps + &Î BottleCaps &Show / Hide - &Показать / Скрыть + &Ïîêàçàòü / Ñêðûòü &File - &Файл + &Ôàéë &Settings - &ÐаÑтройки + &Íàñòðîéêè &Help - &Помощь + &Ïîìîùü Tabs toolbar - Панель вкладок + Ïàíåëü âêëàäîê Actions toolbar - Панель дейÑтвий + Ïàíåëü äåéñòâèé [testnet] - [теÑÑ‚Ð¾Ð²Ð°Ñ Ñеть] + [òåñòîâàÿ ñåòü] BottleCaps client - BottleCaps клиент + BottleCaps êëèåíò %n active connection(s) to BottleCaps network - %n активное Ñоединение Ñ Ñетью - %n активных Ñоединений Ñ Ñетью - %n активных Ñоединений Ñ Ñетью + %n àêòèâíîå ñîåäèíåíèå ñ ñåòüþ + %n àêòèâíûõ ñîåäèíåíèé ñ ñåòüþ + %n àêòèâíûõ ñîåäèíåíèé ñ ñåòüþ Downloaded %1 blocks of transaction history. - Загружено %1 блоков иÑтории транзакций. + Çàãðóæåíî %1 áëîêîâ èñòîðèè òðàíçàêöèé. %n second(s) ago - %n Ñекунду назад - %n Ñекунды назад - %n Ñекунд назад + %n ñåêóíäó íàçàä + %n ñåêóíäû íàçàä + %n ñåêóíä íàçàä %n minute(s) ago - %n минуту назад - %n минуты назад - %n минут назад + %n ìèíóòó íàçàä + %n ìèíóòû íàçàä + %n ìèíóò íàçàä %n hour(s) ago - %n Ñ‡Ð°Ñ Ð½Ð°Ð·Ð°Ð´ - %n чаÑа назад - %n чаÑов назад + %n ÷àñ íàçàä + %n ÷àñà íàçàä + %n ÷àñîâ íàçàä %n day(s) ago - %n день назад - %n Ð´Ð½Ñ Ð½Ð°Ð·Ð°Ð´ - %n дней назад + %n äåíü íàçàä + %n äíÿ íàçàä + %n äíåé íàçàä Up to date - Синхронизированно + Ñèíõðîíèçèðîâàííî Catching up... - СинхронизируетÑÑ... + Ñèíõðîíèçèðóåòñÿ... Last received block was generated %1. - ПоÑледний полученный блок был Ñгенерирован %1. + Ïîñëåäíèé ïîëó÷åííûé áëîê áûë ñãåíåðèðîâàí %1. This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? - Ð”Ð°Ð½Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÐµÑ‚ предельно допуÑтимый размер. Ðо Ð’Ñ‹ можете вÑÑ‘ равно Ñовершить её, добавив комиÑÑию в %1, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÑÑ Ñ‚ÐµÐ¼ узлам, которые обработают Вашу транзакцию, и поможет поддержать Ñеть. Ð’Ñ‹ хотите добавить комиÑÑию? + Äàííàÿ òðàíçàêöèÿ ïðåâûøàåò ïðåäåëüíî äîïóñòèìûé ðàçìåð. Íî Âû ìîæåòå âñ¸ ðàâíî ñîâåðøèòü å¸, äîáàâèâ êîìèññèþ â %1, êîòîðàÿ îòïðàâèòñÿ òåì óçëàì, êîòîðûå îáðàáîòàþò Âàøó òðàíçàêöèþ, è ïîìîæåò ïîääåðæàòü ñåòü. Âû õîòèòå äîáàâèòü êîìèññèþ? Confirm transaction fee - Подтвердите комиÑÑию + Ïîäòâåðäèòå êîìèññèþ Sent transaction - Ð?ÑходÑÑ‰Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ + Èñõîäÿùàÿ òðàíçàêöèÿ Incoming transaction - ВходÑÑ‰Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ + Âõîäÿùàÿ òðàíçàêöèÿ @@ -612,58 +612,58 @@ Amount: %2 Type: %3 Address: %4 - Дата: %1 -КоличеÑтво: %2 -Тип: %3 -ÐдреÑ: %4 + Äàòà: %1 +Êîëè÷åñòâî: %2 +Òèï: %3 +Àäðåñ: %4 URI handling - Обработка URI + Îáðàáîòêà URI URI can not be parsed! This can be caused by an invalid BottleCaps address or malformed URI parameters. - Ðе удалоÑÑŒ обработать URI! Это может быть ÑвÑзано Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ñ‹Ð¼ адреÑом BottleCaps или неправильными параметрами URI. + Íå óäàëîñü îáðàáîòàòü URI! Ýòî ìîæåò áûòü ñâÿçàíî ñ íåâåðíûì àäðåñîì BottleCaps èëè íåïðàâèëüíûìè ïàðàìåòðàìè URI. Wallet is <b>encrypted</b> and currently <b>unlocked</b> - Бумажник <b>зашифрован</b> и в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ <b>разблокирован</b> + Áóìàæíèê <b>çàøèôðîâàí</b> è â íàñòîÿùåå âðåìÿ <b>ðàçáëîêèðîâàí</b> Wallet is <b>encrypted</b> and currently <b>locked</b> - Бумажник <b>зашифрован</b> и в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ <b>заблокирован</b> + Áóìàæíèê <b>çàøèôðîâàí</b> è â íàñòîÿùåå âðåìÿ <b>çàáëîêèðîâàí</b> Backup Wallet - Сделать резервную копию бумажника + Ñäåëàòü ðåçåðâíóþ êîïèþ áóìàæíèêà Wallet Data (*.dat) - Данные бумажника (*.dat) + Äàííûå áóìàæíèêà (*.dat) Backup Failed - Резервное копирование не удалоÑÑŒ + Ðåçåðâíîå êîïèðîâàíèå íå óäàëîñü There was an error trying to save the wallet data to the new location. - При попытке ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… бумажника в новое меÑто произошла ошибка. + Ïðè ïîïûòêå ñîõðàíåíèÿ äàííûõ áóìàæíèêà â íîâîå ìåñòî ïðîèçîøëà îøèáêà. A fatal error occurred. BottleCaps can no longer continue safely and will quit. - Произошла неиÑÐ¿Ñ€Ð°Ð²Ð¸Ð¼Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. BottleCaps не может безопаÑно продолжать работу и будет закрыт. + Ïðîèçîøëà íåèñïðàâèìàÿ îøèáêà. BottleCaps íå ìîæåò áåçîïàñíî ïðîäîëæàòü ðàáîòó è áóäåò çàêðûò. @@ -671,7 +671,7 @@ Address: %4 Network Alert - Ð¡ÐµÑ‚ÐµÐ²Ð°Ñ Ð¢Ñ€ÐµÐ²Ð¾Ð³Ð° + Ñåòåâàÿ Òðåâîãà @@ -679,67 +679,67 @@ Address: %4 Edit Address - Ð?зменить Ð°Ð´Ñ€ÐµÑ + Èçìåíèòü àäðåñ &Label - &Метка + &Ìåòêà The label associated with this address book entry - Метка, ÑвÑÐ·Ð°Ð½Ð½Ð°Ñ Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ запиÑью + Ìåòêà, ñâÿçàííàÿ ñ äàííîé çàïèñüþ &Address - &ÐÐ´Ñ€ÐµÑ + &Àäðåñ The address associated with this address book entry. This can only be modified for sending addresses. - ÐдреÑ, ÑвÑзанный Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ запиÑью. + Àäðåñ, ñâÿçàííûé ñ äàííîé çàïèñüþ. New receiving address - Ðовый Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ + Íîâûé àäðåñ äëÿ ïîëó÷åíèÿ New sending address - Ðовый Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ + Íîâûé àäðåñ äëÿ îòïðàâêè Edit receiving address - Ð?зменение адреÑа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ + Èçìåíåíèå àäðåñà äëÿ ïîëó÷åíèÿ Edit sending address - Ð?зменение адреÑа Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ + Èçìåíåíèå àäðåñà äëÿ îòïðàâêè The entered address "%1" is already in the address book. - Введённый Ð°Ð´Ñ€ÐµÑ Â«%1» уже находитÑÑ Ð² адреÑной книге. + Ââåä¸ííûé àäðåñ «%1» óæå íàõîäèòñÿ â àäðåñíîé êíèãå. The entered address "%1" is not a valid BottleCaps address. - Введённый Ð°Ð´Ñ€ÐµÑ "%1" не ÑвлÑетÑÑ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ BottleCaps-адреÑом. + Ââåä¸ííûé àäðåñ "%1" íå ÿâëÿåòñÿ ïðàâèëüíûì BottleCaps-àäðåñîì. Could not unlock wallet. - Ðе удаетÑÑ Ñ€Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ бумажник. + Íå óäàåòñÿ ðàçáëîêèðîâàòü áóìàæíèê. New key generation failed. - Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ ключа не удалаÑÑŒ. + Ãåíåðàöèÿ íîâîãî êëþ÷à íå óäàëàñü. @@ -753,37 +753,37 @@ Address: %4 version - верÑÐ¸Ñ + âåðñèÿ Usage: - Ð?Ñпользование: + Èñïîëüçîâàíèå: command-line options - параметры командной Ñтроки + ïàðàìåòðû êîìàíäíîé ñòðîêè UI options - Опции интерфейÑа + Îïöèè èíòåðôåéñà Set language, for example "de_DE" (default: system locale) - Выберите Ñзык, например "de_DE" (по умолчанию: как в ÑиÑтеме) + Âûáåðèòå ÿçûê, íàïðèìåð "de_DE" (ïî óìîë÷àíèþ: êàê â ñèñòåìå) Start minimized - ЗапуÑкать Ñвёрнутым + Çàïóñêàòü ñâ¸ðíóòûì Show splash screen on startup (default: 1) - Показывать ÑплÑш при запуÑке (по умолчанию: 1) + Ïîêàçûâàòü ñïëýø ïðè çàïóñêå (ïî óìîë÷àíèþ: 1) @@ -791,194 +791,194 @@ Address: %4 Options - Опции + Îïöèè &Main - &Ð“Ð»Ð°Ð²Ð½Ð°Ñ + &Ãëàâíàÿ Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. - ÐžÐ¿Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð¼Ð¸ÑÑÐ¸Ñ Ð·Ð° каждый КБ транзакции, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет быть уверенным, что Ваша Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ обработана быÑтро. БольшинÑтво транзакций занимают 1КБ. РекомендуетÑÑ ÐºÐ¾Ð¼Ð¸ÑÑÐ¸Ñ 0.01. + Îïöèîíàëüíàÿ êîìèññèÿ çà êàæäûé ÊÁ òðàíçàêöèè, êîòîðàÿ ïîçâîëÿåò áûòü óâåðåííûì, ÷òî Âàøà òðàíçàêöèÿ áóäåò îáðàáîòàíà áûñòðî. Áîëüøèíñòâî òðàíçàêöèé çàíèìàþò 1ÊÁ. Ðåêîìåíäóåòñÿ êîìèññèÿ 0.01. Pay transaction &fee - Заплатить ко&миÑÑию + Çàïëàòèòü êî&ìèññèþ Automatically start BottleCaps after logging in to the system. - ÐвтоматичеÑки запуÑкать BottleCaps поÑле входа в ÑиÑтему + Àâòîìàòè÷åñêè çàïóñêàòü BottleCaps ïîñëå âõîäà â ñèñòåìó &Start BottleCaps on system login - &ЗапуÑкать BottleCaps при входе в ÑиÑтему + &Çàïóñêàòü BottleCaps ïðè âõîäå â ñèñòåìó Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached. - Отключить базы данных блоков и адреÑов при выходе. Это означает, что их можно будет перемеÑтить в другой каталог данных, но завершение работы будет медленнее. Бумажник вÑегда отключаетÑÑ. + Îòêëþ÷èòü áàçû äàííûõ áëîêîâ è àäðåñîâ ïðè âûõîäå. Ýòî îçíà÷àåò, ÷òî èõ ìîæíî áóäåò ïåðåìåñòèòü â äðóãîé êàòàëîã äàííûõ, íî çàâåðøåíèå ðàáîòû áóäåò ìåäëåííåå. Áóìàæíèê âñåãäà îòêëþ÷àåòñÿ. &Detach databases at shutdown - &Отключать базы данных при выходе + &Îòêëþ÷àòü áàçû äàííûõ ïðè âûõîäå &Network - &Сеть + &Ñåòü Automatically open the BottleCaps client port on the router. This only works when your router supports UPnP and it is enabled. - ÐвтоматичеÑки открыть порт Ð´Ð»Ñ BottleCaps-клиента на роутере. Работает только еÑли Ваш роутер поддерживает UPnP, и Ð´Ð°Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°. + Àâòîìàòè÷åñêè îòêðûòü ïîðò äëÿ BottleCaps-êëèåíòà íà ðîóòåðå. Ðàáîòàåò òîëüêî åñëè Âàø ðîóòåð ïîääåðæèâàåò UPnP, è äàííàÿ ôóíêöèÿ âêëþ÷åíà. Map port using &UPnP - ПроброÑить порт через &UPnP + Ïðîáðîñèòü ïîðò ÷åðåç &UPnP Connect to the BottleCaps network through a SOCKS proxy (e.g. when connecting through Tor). - ПодключатьÑÑ Ðº Ñети BottleCaps через прокÑи SOCKS (например, при подключении через Tor). + Ïîäêëþ÷àòüñÿ ê ñåòè BottleCaps ÷åðåç ïðîêñè SOCKS (íàïðèìåð, ïðè ïîäêëþ÷åíèè ÷åðåç Tor). &Connect through SOCKS proxy: - &ПодключатьÑÑ Ñ‡ÐµÑ€ÐµÐ· SOCKS прокÑи: + &Ïîäêëþ÷àòüñÿ ÷åðåç SOCKS ïðîêñè: Proxy &IP: - &IP ПрокÑи: + &IP Ïðîêñè: IP address of the proxy (e.g. 127.0.0.1) - IP-Ð°Ð´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи (например 127.0.0.1) + IP-àäðåñ ïðîêñè (íàïðèìåð 127.0.0.1) &Port: - По&рт: + Ïî&ðò: Port of the proxy (e.g. 9050) - Порт прокÑи-Ñервера (например, 9050) + Ïîðò ïðîêñè-ñåðâåðà (íàïðèìåð, 9050) SOCKS &Version: - &ВерÑÐ¸Ñ SOCKS: + &Âåðñèÿ SOCKS: SOCKS version of the proxy (e.g. 5) - ВерÑÐ¸Ñ SOCKS-прокÑи (например, 5) + Âåðñèÿ SOCKS-ïðîêñè (íàïðèìåð, 5) &Window - &Окно + &Îêíî Show only a tray icon after minimizing the window. - Показывать только иконку в ÑиÑтемном лотке поÑле ÑÐ²Ð¾Ñ€Ð°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÐºÐ½Ð°. + Ïîêàçûâàòü òîëüêî èêîíêó â ñèñòåìíîì ëîòêå ïîñëå ñâîðà÷èâàíèÿ îêíà. &Minimize to the tray instead of the taskbar - &Cворачивать в ÑиÑтемный лоток вмеÑто панели задач + &Câîðà÷èâàòü â ñèñòåìíûé ëîòîê âìåñòî ïàíåëè çàäà÷ Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. - Сворачивать вмеÑто закрытиÑ. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¾Ð¿Ñ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ выбрана — приложение закроетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ поÑле выбора ÑоответÑтвующего пункта в меню. + Ñâîðà÷èâàòü âìåñòî çàêðûòèÿ. Åñëè äàííàÿ îïöèÿ áóäåò âûáðàíà — ïðèëîæåíèå çàêðîåòñÿ òîëüêî ïîñëå âûáîðà ñîîòâåòñòâóþùåãî ïóíêòà â ìåíþ. M&inimize on close - С&ворачивать при закрытии + Ñ&âîðà÷èâàòü ïðè çàêðûòèè &Display - О&тображение + Î&òîáðàæåíèå User Interface &language: - &Язык интерфейÑа: + &ßçûê èíòåðôåéñà: The user interface language can be set here. This setting will take effect after restarting BottleCaps. - ЗдеÑÑŒ можно выбрать Ñзык интерфейÑа. ÐаÑтройки вÑтупÑÑ‚ в Ñилу поÑле перезапуÑка BottleCaps. + Çäåñü ìîæíî âûáðàòü ÿçûê èíòåðôåéñà. Íàñòðîéêè âñòóïÿò â ñèëó ïîñëå ïåðåçàïóñêà BottleCaps. &Unit to show amounts in: - &Отображать Ñуммы в единицах: + &Îòîáðàæàòü ñóììû â åäèíèöàõ: Choose the default subdivision unit to show in the interface and when sending coins. - Выберите единицу Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð½ÐµÑ‚ при отображении и отправке. + Âûáåðèòå åäèíèöó èçìåðåíèÿ ìîíåò ïðè îòîáðàæåíèè è îòïðàâêå. Whether to show BottleCaps addresses in the transaction list or not. - Показывать ли адреÑа BottleCaps в ÑпиÑке транзакций. + Ïîêàçûâàòü ëè àäðåñà BottleCaps â ñïèñêå òðàíçàêöèé. &Display addresses in transaction list - &Показывать адреÑа в ÑпиÑке транзакций + &Ïîêàçûâàòü àäðåñà â ñïèñêå òðàíçàêöèé &OK - О&К + Î&Ê &Cancel - &Отмена + &Îòìåíà &Apply - &Применить + &Ïðèìåíèòü default - по умолчанию + ïî óìîë÷àíèþ Warning - Внимание + Âíèìàíèå This setting will take effect after restarting BottleCaps. - Эта наÑтройка вÑтупит в Ñилу поÑле перезапуÑка BottleCaps + Ýòà íàñòðîéêà âñòóïèò â ñèëó ïîñëå ïåðåçàïóñêà BottleCaps The supplied proxy address is invalid. - ÐÐ´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи неверен. + Àäðåñ ïðîêñè íåâåðåí. @@ -986,79 +986,79 @@ Address: %4 Form - Форма + Ôîðìà The displayed information may be out of date. Your wallet automatically synchronizes with the BottleCaps network after a connection is established, but this process has not completed yet. - ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть уÑтаревшей. Ваш бумажник автоматичеÑки ÑинхронизируетÑÑ Ñ Ñетью BottleCaps поÑле подключениÑ, но Ñтот процеÑÑ Ð¿Ð¾ÐºÐ° не завершён. + Îòîáðàæàåìàÿ èíôîðìàöèÿ ìîæåò áûòü óñòàðåâøåé. Âàø áóìàæíèê àâòîìàòè÷åñêè ñèíõðîíèçèðóåòñÿ ñ ñåòüþ BottleCaps ïîñëå ïîäêëþ÷åíèÿ, íî ýòîò ïðîöåññ ïîêà íå çàâåðø¸í. Balance: - БаланÑ: + Áàëàíñ: Stake: - ДолÑ: + Äîëÿ: Number of transactions: - КоличеÑтво транзакций: + Êîëè÷åñòâî òðàíçàêöèé: Unconfirmed: - Ðе подтверждено: + Íå ïîäòâåðæäåíî: Wallet - Бумажник + Áóìàæíèê Immature: - Ðезрелые: + Íåçðåëûå: Mined balance that has not yet matured - Ð‘Ð°Ð»Ð°Ð½Ñ Ð´Ð¾Ð±Ñ‹Ñ‚Ñ‹Ñ… монет, который ещё не Ñозрел + Áàëàíñ äîáûòûõ ìîíåò, êîòîðûé åù¸ íå ñîçðåë <b>Recent transactions</b> - <b>ПоÑледние транзакции</b> + <b>Ïîñëåäíèå òðàíçàêöèè</b> Your current balance - Ваш текущий Ð±Ð°Ð»Ð°Ð½Ñ + Âàø òåêóùèé áàëàíñ Total of transactions that have yet to be confirmed, and do not yet count toward the current balance - ÐžÐ±Ñ‰Ð°Ñ Ñумма вÑех транзакций, которые до Ñих пор не подтверждены, и до Ñих пор не учитываютÑÑ Ð² текущем баланÑе + Îáùàÿ ñóììà âñåõ òðàíçàêöèé, êîòîðûå äî ñèõ ïîð íå ïîäòâåðæäåíû, è äî ñèõ ïîð íå ó÷èòûâàþòñÿ â òåêóùåì áàëàíñå Total of coins that was staked, and do not yet count toward the current balance - ÐžÐ±Ñ‰Ð°Ñ Ñумма вÑех монет, иÑпользуемых Ð´Ð»Ñ Proof-of-Stake, и не учитывающихÑÑ Ð½Ð° баланÑе + Îáùàÿ ñóììà âñåõ ìîíåò, èñïîëüçóåìûõ äëÿ Proof-of-Stake, è íå ó÷èòûâàþùèõñÿ íà áàëàíñå Total number of transactions in wallet - Общее количеÑтво транзакций в Вашем бумажнике + Îáùåå êîëè÷åñòâî òðàíçàêöèé â Âàøåì áóìàæíèêå out of sync - не Ñинхронизировано + íå ñèíõðîíèçèðîâàíî @@ -1066,57 +1066,57 @@ Address: %4 QR Code Dialog - Диалог QR-кода + Äèàëîã QR-êîäà Request Payment - ЗапроÑить платёж + Çàïðîñèòü ïëàò¸æ Amount: - КоличеÑтво: + Êîëè÷åñòâî: Label: - Метка: + Ìåòêà: Message: - Сообщение: + Ñîîáùåíèå: &Save As... - &Сохранить как... + &Ñîõðàíèòü êàê... Error encoding URI into QR Code. - Ошибка ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ URI в QR-код + Îøèáêà êîäèðîâàíèÿ URI â QR-êîä The entered amount is invalid, please check. - Введено неверное количеÑтво, проверьте ещё раз. + Ââåäåíî íåâåðíîå êîëè÷åñòâî, ïðîâåðüòå åù¸ ðàç. Resulting URI too long, try to reduce the text for label / message. - ПолучившийÑÑ URI Ñлишком длинный, попробуйте Ñократить текÑÑ‚ метки / ÑообщениÑ. + Ïîëó÷èâøèéñÿ URI ñëèøêîì äëèííûé, ïîïðîáóéòå ñîêðàòèòü òåêñò ìåòêè / ñîîáùåíèÿ. Save QR Code - Сохранить QR-код + Ñîõðàíèòü QR-êîä PNG Images (*.png) - PNG Ð?Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png) + PNG Èçîáðàæåíèÿ (*.png) @@ -1124,7 +1124,7 @@ Address: %4 Client name - Ð?Ð¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° + Èìÿ êëèåíòà @@ -1138,132 +1138,132 @@ Address: %4 N/A - Ð/Д + Í/Ä Client version - ВерÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° + Âåðñèÿ êëèåíòà &Information - &Ð?Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ + &Èíôîðìàöèÿ Using OpenSSL version - Ð?ÑпользуетÑÑ Ð²ÐµÑ€ÑÐ¸Ñ OpenSSL + Èñïîëüçóåòñÿ âåðñèÿ OpenSSL Startup time - Ð’Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿ÑƒÑка + Âðåìÿ çàïóñêà Network - Сеть + Ñåòü Number of connections - ЧиÑло подключений + ×èñëî ïîäêëþ÷åíèé On testnet - Ð’ теÑтовой Ñети +  òåñòîâîé ñåòè Block chain - Цепь блоков + Öåïü áëîêîâ Current number of blocks - Текущее чиÑло блоков + Òåêóùåå ÷èñëî áëîêîâ Estimated total blocks - РаÑчётное чиÑло блоков + Ðàñ÷¸òíîå ÷èñëî áëîêîâ Last block time - Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледнего блока + Âðåìÿ ïîñëåäíåãî áëîêà &Open - &Открыть + &Îòêðûòü Command-line options - Параметры командной Ñтроки + Ïàðàìåòðû êîìàíäíîé ñòðîêè Show the BottleCaps-Qt help message to get a list with possible BottleCaps command-line options. - Показать помощь по BottleCaps-Qt, чтобы получить ÑпиÑок доÑтупных параметров командной Ñтроки. + Ïîêàçàòü ïîìîùü ïî BottleCaps-Qt, ÷òîáû ïîëó÷èòü ñïèñîê äîñòóïíûõ ïàðàìåòðîâ êîìàíäíîé ñòðîêè. &Show - &Показать + &Ïîêàçàòü &Console - КонÑоль + Êîíñîëü Build date - Дата Ñборки + Äàòà ñáîðêè BottleCaps - Debug window - BottleCaps - Окно отладки + BottleCaps - Îêíî îòëàäêè BottleCaps Core - Ядро BottleCaps + ßäðî BottleCaps Debug log file - Отладочный лог-файл + Îòëàäî÷íûé ëîã-ôàéë Open the BottleCaps debug log file from the current data directory. This can take a few seconds for large log files. - Открыть отладочный лог-файл BottleCaps из текущего каталога данных. Это может занÑть неÑколько Ñекунд Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… лог-файлов. + Îòêðûòü îòëàäî÷íûé ëîã-ôàéë BottleCaps èç òåêóùåãî êàòàëîãà äàííûõ. Ýòî ìîæåò çàíÿòü íåñêîëüêî ñåêóíä äëÿ áîëüøèõ ëîã-ôàéëîâ. Clear console - ОчиÑтить конÑоль + Î÷èñòèòü êîíñîëü Welcome to the BottleCaps RPC console. - Добро пожаловать в RPC-конÑоль BottleCaps. + Äîáðî ïîæàëîâàòü â RPC-êîíñîëü BottleCaps. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. - Ð?Ñпользуйте Ñтрелки вверх и вниз Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра иÑтории и <b>Ctrl-L</b> Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки Ñкрана. + Èñïîëüçóéòå ñòðåëêè ââåðõ è âíèç äëÿ ïðîñìîòðà èñòîðèè è <b>Ctrl-L</b> äëÿ î÷èñòêè ýêðàíà. Type <b>help</b> for an overview of available commands. - Ðапишите <b>help</b> Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра доÑтупных команд. + Íàïèøèòå <b>help</b> äëÿ ïðîñìîòðà äîñòóïíûõ êîìàíä. @@ -1278,32 +1278,32 @@ Address: %4 Send Coins - Отправка + Îòïðàâêà Send to multiple recipients at once - Отправить неÑкольким получателÑм одновременно + Îòïðàâèòü íåñêîëüêèì ïîëó÷àòåëÿì îäíîâðåìåííî Add &Recipient - &Добавить Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ + &Äîáàâèòü ïîëó÷àòåëÿ Remove all transaction fields - Удалить вÑе Ð¿Ð¾Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ + Óäàëèòü âñå ïîëÿ òðàíçàêöèè Clear &All - ОчиÑтить &вÑÑ‘ + Î÷èñòèòü &âñ¸ Balance: - БаланÑ: + Áàëàíñ: @@ -1313,67 +1313,67 @@ Address: %4 Confirm the send action - Подтвердить отправку + Ïîäòâåðäèòü îòïðàâêó S&end - &Отправить + &Îòïðàâèòü <b>%1</b> to %2 (%3) - <b>%1</b> адреÑату %2 (%3) + <b>%1</b> àäðåñàòó %2 (%3) Confirm send coins - Подтвердите отправку монет + Ïîäòâåðäèòå îòïðàâêó ìîíåò Are you sure you want to send %1? - Ð’Ñ‹ уверены, что хотите отправить %1? + Âû óâåðåíû, ÷òî õîòèòå îòïðàâèòü %1? and - и + è The recipient address is not valid, please recheck. - ÐÐ´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ñ‹Ð¹, пожалуйÑта, перепроверьте. + Àäðåñ ïîëó÷àòåëÿ íåâåðíûé, ïîæàëóéñòà, ïåðåïðîâåðüòå. The amount to pay must be larger than 0. - КоличеÑтво монет Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ должно быть больше 0. + Êîëè÷åñòâî ìîíåò äëÿ îòïðàâêè äîëæíî áûòü áîëüøå 0. The amount exceeds your balance. - КоличеÑтво отправлÑемых монет превышает Ваш Ð±Ð°Ð»Ð°Ð½Ñ + Êîëè÷åñòâî îòïðàâëÿåìûõ ìîíåò ïðåâûøàåò Âàø áàëàíñ The total exceeds your balance when the %1 transaction fee is included. - Сумма превыÑит Ваш баланÑ, еÑли комиÑÑÐ¸Ñ Ð² размере %1 будет добавлена к транзакции + Ñóììà ïðåâûñèò Âàø áàëàíñ, åñëè êîìèññèÿ â ðàçìåðå %1 áóäåò äîáàâëåíà ê òðàíçàêöèè Duplicate address found, can only send to each address once per send operation. - Обнаружен дублирующийÑÑ Ð°Ð´Ñ€ÐµÑ. Отправка на один и тот же Ð°Ð´Ñ€ÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð° только один раз за одну операцию отправки + Îáíàðóæåí äóáëèðóþùèéñÿ àäðåñ. Îòïðàâêà íà îäèí è òîò æå àäðåñ âîçìîæíà òîëüêî îäèí ðàç çà îäíó îïåðàöèþ îòïðàâêè Error: Transaction creation failed. - Ошибка: не удалоÑÑŒ Ñоздать транзакцию. + Îøèáêà: íå óäàëîñü ñîçäàòü òðàíçàêöèþ. Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Ошибка: Ð’ транзакции отказано. Такое может произойти, еÑли некоторые монеты уже были потрачены, например, еÑли Ð’Ñ‹ иÑпользуете одну копию файла wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в Ñтой. + Îøèáêà:  òðàíçàêöèè îòêàçàíî. Òàêîå ìîæåò ïðîèçîéòè, åñëè íåêîòîðûå ìîíåòû óæå áûëè ïîòðà÷åíû, íàïðèìåð, åñëè Âû èñïîëüçóåòå îäíó êîïèþ ôàéëà wallet.dat, à ìîíåòû áûëè ïîòðà÷åíû èç äðóãîé êîïèè, íî íå áûëè îòìå÷åíû êàê ïîòðà÷åííûå â ýòîé. @@ -1381,38 +1381,38 @@ Address: %4 Form - Форма + Ôîðìà A&mount: - Ко&личеÑтво: + Êî&ëè÷åñòâî: Pay &To: - Полу&чатель: + Ïîëó&÷àòåëü: Enter a label for this address to add it to your address book - Введите метку Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ адреÑа (Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² адреÑную книгу) + Ââåäèòå ìåòêó äëÿ äàííîãî àäðåñà (äëÿ äîáàâëåíèÿ â àäðåñíóþ êíèãó) &Label: - &Метка: + &Ìåòêà: The address to send the payment to (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - ÐÐ´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶Ð° (например 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Àäðåñ ïîëó÷àòåëÿ ïëàòåæà (íàïðèìåð 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Choose address from address book - Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги + Âûáåðèòå àäðåñ èç àäðåñíîé êíèãè @@ -1422,7 +1422,7 @@ Address: %4 Paste address from clipboard - Ð’Ñтавить Ð°Ð´Ñ€ÐµÑ Ð¸Ð· буфера обмена + Âñòàâèòü àäðåñ èç áóôåðà îáìåíà @@ -1432,12 +1432,12 @@ Address: %4 Remove this recipient - Удалить Ñтого Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ + Óäàëèòü ýòîãî ïîëó÷àòåëÿ Enter a BottleCaps address (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Введите BottleCaps-Ð°Ð´Ñ€ÐµÑ (например 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Ââåäèòå BottleCaps-àäðåñ (íàïðèìåð 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) @@ -1445,29 +1445,29 @@ Address: %4 Signatures - Sign / Verify a Message - ПодпиÑи - подпиÑать/проверить Ñообщение + Ïîäïèñè - ïîäïèñàòü/ïðîâåðèòü ñîîáùåíèå &Sign Message - &ПодпиÑать Ñообщение + &Ïîäïèñàòü ñîîáùåíèå You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. - Ð’Ñ‹ можете подпиÑывать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñвоими адреÑами, чтобы доказать владение ими. Будьте оÑторожны, не подпиÑывайте что-то неопределённое, так как фишинговые атаки могут обманным путём заÑтавить Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñать нежелательные ÑообщениÑ. ПодпиÑывайте только те ÑообщениÑ, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼Ð¸ вы ÑоглаÑны вплоть до мелочей. + Âû ìîæåòå ïîäïèñûâàòü ñîîáùåíèÿ ñâîèìè àäðåñàìè, ÷òîáû äîêàçàòü âëàäåíèå èìè. Áóäüòå îñòîðîæíû, íå ïîäïèñûâàéòå ÷òî-òî íåîïðåäåë¸ííîå, òàê êàê ôèøèíãîâûå àòàêè ìîãóò îáìàííûì ïóò¸ì çàñòàâèòü âàñ ïîäïèñàòü íåæåëàòåëüíûå ñîîáùåíèÿ. Ïîäïèñûâàéòå òîëüêî òå ñîîáùåíèÿ, ñ êîòîðûìè âû ñîãëàñíû âïëîòü äî ìåëî÷åé. The address to sign the message with (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - ÐдреÑ, которым вы хотите подпиÑать Ñообщение (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Àäðåñ, êîòîðûì âû õîòèòå ïîäïèñàòü ñîîáùåíèå (íàïð. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Choose an address from the address book - Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги + Âûáåðèòå àäðåñ èç àäðåñíîé êíèãè @@ -1478,7 +1478,7 @@ Address: %4 Paste address from clipboard - Ð’Ñтавить Ð°Ð´Ñ€ÐµÑ Ð¸Ð· буфера обмена + Âñòàâèòü àäðåñ èç áóôåðà îáìåíà @@ -1488,76 +1488,76 @@ Address: %4 Enter the message you want to sign here - Введите Ñообщение Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи + Ââåäèòå ñîîáùåíèå äëÿ ïîäïèñè Copy the current signature to the system clipboard - Скопировать текущую подпиÑÑŒ в ÑиÑтемный буфер обмена + Ñêîïèðîâàòü òåêóùóþ ïîäïèñü â ñèñòåìíûé áóôåð îáìåíà Sign the message to prove you own this BottleCaps address - ПодпиÑать Ñообщение, чтобы доказать владение адреÑом BottleCaps + Ïîäïèñàòü ñîîáùåíèå, ÷òîáû äîêàçàòü âëàäåíèå àäðåñîì BottleCaps Reset all sign message fields - СброÑить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð²Ñех полей подпиÑÑ‹Ð²Ð°Ð½Ð¸Ñ Ñообщений + Ñáðîñèòü çíà÷åíèÿ âñåõ ïîëåé ïîäïèñûâàíèÿ ñîîáùåíèé Clear &All - ОчиÑтить &вÑÑ‘ + Î÷èñòèòü &âñ¸ &Verify Message - &Проверить Ñообщение + &Ïðîâåðèòü ñîîáùåíèå Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. - Введите ниже Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи, Ñообщение (убедитеÑÑŒ, что переводы Ñтрок, пробелы, табы и Ñ‚.п. в точноÑти Ñкопированы) и подпиÑÑŒ, чтобы проверить Ñообщение. УбедитеÑÑŒ, что не Ñкопировали лишнего в подпиÑÑŒ, по Ñравнению Ñ Ñамим подпиÑываемым Ñообщением, чтобы не Ñтать жертвой атаки "man-in-the-middle". + Ââåäèòå íèæå àäðåñ äëÿ ïîäïèñè, ñîîáùåíèå (óáåäèòåñü, ÷òî ïåðåâîäû ñòðîê, ïðîáåëû, òàáû è ò.ï. â òî÷íîñòè ñêîïèðîâàíû) è ïîäïèñü, ÷òîáû ïðîâåðèòü ñîîáùåíèå. Óáåäèòåñü, ÷òî íå ñêîïèðîâàëè ëèøíåãî â ïîäïèñü, ïî ñðàâíåíèþ ñ ñàìèì ïîäïèñûâàåìûì ñîîáùåíèåì, ÷òîáû íå ñòàòü æåðòâîé àòàêè "man-in-the-middle". The address the message was signed with (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - ÐдреÑ, которым было подпиÑано Ñообщение (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Àäðåñ, êîòîðûì áûëî ïîäïèñàíî ñîîáùåíèå (íàïð. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Verify the message to ensure it was signed with the specified BottleCaps address - Проверить Ñообщение, чтобы убедитьÑÑ, что оно было подпиÑано указанным адреÑом BottleCaps + Ïðîâåðèòü ñîîáùåíèå, ÷òîáû óáåäèòüñÿ, ÷òî îíî áûëî ïîäïèñàíî óêàçàííûì àäðåñîì BottleCaps Reset all verify message fields - СброÑить вÑе Ð¿Ð¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ + Ñáðîñèòü âñå ïîëÿ ïðîâåðêè ñîîáùåíèÿ Enter a BottleCaps address (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Введите Ð°Ð´Ñ€ÐµÑ BottleCaps (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Ââåäèòå àäðåñ BottleCaps (íàïð. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Click "Sign Message" to generate signature - Ðажмите "ПодпиÑать Ñообщение" Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи + Íàæìèòå "Ïîäïèñàòü ñîîáùåíèå" äëÿ ñîçäàíèÿ ïîäïèñè Enter BottleCaps signature - Введите подпиÑÑŒ BottleCaps + Ââåäèòå ïîäïèñü BottleCaps The entered address is invalid. - Введённый Ð°Ð´Ñ€ÐµÑ Ð½ÐµÐ²ÐµÑ€ÐµÐ½ + Ââåä¸ííûé àäðåñ íåâåðåí @@ -1565,59 +1565,59 @@ Address: %4 Please check the address and try again. - ПожалуйÑта, проверьте Ð°Ð´Ñ€ÐµÑ Ð¸ попробуйте ещё раз. + Ïîæàëóéñòà, ïðîâåðüòå àäðåñ è ïîïðîáóéòå åù¸ ðàç. The entered address does not refer to a key. - Введённый Ð°Ð´Ñ€ÐµÑ Ð½Ðµ ÑвÑзан Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð¼ + Ââåä¸ííûé àäðåñ íå ñâÿçàí ñ êëþ÷îì Wallet unlock was cancelled. - Разблокировка бумажника была отменена. + Ðàçáëîêèðîâêà áóìàæíèêà áûëà îòìåíåíà. Private key for the entered address is not available. - Ð”Ð»Ñ Ð²Ð²ÐµÐ´Ñ‘Ð½Ð½Ð¾Ð³Ð¾ адреÑа недоÑтупен закрытый ключ + Äëÿ ââåä¸ííîãî àäðåñà íåäîñòóïåí çàêðûòûé êëþ÷ Message signing failed. - Ðе удалоÑÑŒ подпиÑать Ñообщение + Íå óäàëîñü ïîäïèñàòü ñîîáùåíèå Message signed. - Сообщение подпиÑано + Ñîîáùåíèå ïîäïèñàíî The signature could not be decoded. - ПодпиÑÑŒ не может быть раÑкодирована. + Ïîäïèñü íå ìîæåò áûòü ðàñêîäèðîâàíà. Please check the signature and try again. - ПожалуйÑта, проверьте подпиÑÑŒ и попробуйте ещё раз. + Ïîæàëóéñòà, ïðîâåðüòå ïîäïèñü è ïîïðîáóéòå åù¸ ðàç. The signature did not match the message digest. - ПодпиÑÑŒ не ÑоответÑтвует отпечатку ÑообщениÑ. + Ïîäïèñü íå ñîîòâåòñòâóåò îòïå÷àòêó ñîîáùåíèÿ. Message verification failed. - Проверка ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ðµ удалаÑÑŒ. + Ïðîâåðêà ñîîáùåíèÿ íå óäàëàñü. Message verified. - Сообщение проверено. + Ñîîáùåíèå ïðîâåðåíî. @@ -1625,84 +1625,84 @@ Address: %4 Open until %1 - Открыто до %1 + Îòêðûòî äî %1 Open for %n block(s) - Открыто Ð´Ð»Ñ %n блока - Открыто Ð´Ð»Ñ %n блоков - Открыто Ð´Ð»Ñ %n блоков + Îòêðûòî äëÿ %n áëîêà + Îòêðûòî äëÿ %n áëîêîâ + Îòêðûòî äëÿ %n áëîêîâ %1/offline - %1/отключен + %1/îòêëþ÷åí %1/unconfirmed - %1/не подтверждено + %1/íå ïîäòâåðæäåíî %1 confirmations - %1 подтверждений + %1 ïîäòâåðæäåíèé Status - Ð¡Ñ‚Ð°Ñ‚ÑƒÑ + Ñòàòóñ , broadcast through %n node(s) - , разоÑлано через %n узел - , разоÑлано через %n узла - , разоÑлано через %n узлов + , ðàçîñëàíî ÷åðåç %n óçåë + , ðàçîñëàíî ÷åðåç %n óçëà + , ðàçîñëàíî ÷åðåç %n óçëîâ Date - Дата + Äàòà Source - Ð?Ñточник + Èñòî÷íèê Generated - Сгенерированно + Ñãåíåðèðîâàííî From - От + Îò To - Ð”Ð»Ñ + Äëÿ own address - Ñвой Ð°Ð´Ñ€ÐµÑ + ñâîé àäðåñ label - метка + ìåòêà @@ -1711,21 +1711,21 @@ Address: %4 Credit - Кредит + Êðåäèò matures in %n more block(s) - будет доÑтупно через %n блок - будет доÑтупно через %n блока - будет доÑтупно через %n блоков + áóäåò äîñòóïíî ÷åðåç %n áëîê + áóäåò äîñòóïíî ÷åðåç %n áëîêà + áóäåò äîñòóïíî ÷åðåç %n áëîêîâ not accepted - не принÑто + íå ïðèíÿòî @@ -1733,82 +1733,82 @@ Address: %4 Debit - Дебет + Äåáåò Transaction fee - КомиÑÑÐ¸Ñ + Êîìèññèÿ Net amount - ЧиÑÑ‚Ð°Ñ Ñумма + ×èñòàÿ ñóììà Message - Сообщение + Ñîîáùåíèå Comment - Комментарий: + Êîììåíòàðèé: Transaction ID - ID транзакции + ID òðàíçàêöèè Generated coins must mature 520 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. - Сгенерированные монеты должны подождать 520 блоков, прежде чем они могут быть потрачены. Когда Ð’Ñ‹ Ñгенерировали Ñтот блок, он был отправлен в Ñеть Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² цепочку блоков. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° не удаÑÑ‚ÑÑ, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑÑ Ð½Ð° «не подтверждено», и монеты будут недейÑтвительны. Это иногда проиÑходит в Ñлучае, еÑли другой узел Ñгенерирует блок на неÑколько Ñекунд раньше ваÑ. + Ñãåíåðèðîâàííûå ìîíåòû äîëæíû ïîäîæäàòü 520 áëîêîâ, ïðåæäå ÷åì îíè ìîãóò áûòü ïîòðà÷åíû. Êîãäà Âû ñãåíåðèðîâàëè ýòîò áëîê, îí áûë îòïðàâëåí â ñåòü äëÿ äîáàâëåíèÿ â öåïî÷êó áëîêîâ. Åñëè äàííàÿ ïðîöåäóðà íå óäàñòñÿ, ñòàòóñ èçìåíèòñÿ íà «íå ïîäòâåðæäåíî», è ìîíåòû áóäóò íåäåéñòâèòåëüíû. Ýòî èíîãäà ïðîèñõîäèò â ñëó÷àå, åñëè äðóãîé óçåë ñãåíåðèðóåò áëîê íà íåñêîëüêî ñåêóíä ðàíüøå âàñ. Staked coins must wait 520 blocks before they can return to balance and be spent. When you generated this proof-of-stake block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be a valid stake. This may occasionally happen if another node generates a proof-of-stake block within a few seconds of yours. - Ð?Ñпользованные в Proof-of-Stake монеты должны подождать 520 блоков, прежде чем они вернутÑÑ Ð½Ð° Ð±Ð°Ð»Ð°Ð½Ñ Ð¸ Ñмогут быть потрачены. Когда вы Ñгенерировали Ñтот proof-of-stake блок, он был отправлен в Ñеть Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² цепочку блоков. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° не удаетÑÑ, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑÑ Ð½Ð° \"не подтверждени\" и блок будет недейÑтвителен. Это иногда проиÑходит в Ñлучае, еÑли другой узел Ñгенерирует блок на неÑколько Ñекунд раньше ваÑ. + Èñïîëüçîâàííûå â Proof-of-Stake ìîíåòû äîëæíû ïîäîæäàòü 520 áëîêîâ, ïðåæäå ÷åì îíè âåðíóòñÿ íà áàëàíñ è ñìîãóò áûòü ïîòðà÷åíû. Êîãäà âû ñãåíåðèðîâàëè ýòîò proof-of-stake áëîê, îí áûë îòïðàâëåí â ñåòü äëÿ äîáàâëåíèÿ â öåïî÷êó áëîêîâ. Åñëè äàííàÿ ïðîöåäóðà íå óäàåòñÿ, ñòàòóñ èçìåíèòñÿ íà \"íå ïîäòâåðæäåíè\" è áëîê áóäåò íåäåéñòâèòåëåí. Ýòî èíîãäà ïðîèñõîäèò â ñëó÷àå, åñëè äðóãîé óçåë ñãåíåðèðóåò áëîê íà íåñêîëüêî ñåêóíä ðàíüøå âàñ. Debug information - ÐžÑ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ + Îòëàäî÷íàÿ èíôîðìàöèÿ Transaction - Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ + Òðàíçàêöèÿ Inputs - Входы + Âõîäû Amount - КоличеÑтво + Êîëè÷åñòâî true - иÑтина + èñòèíà false - ложь + ëîæü , has not been successfully broadcast yet - , ещё не было уÑпешно разоÑлано + , åù¸ íå áûëî óñïåøíî ðàçîñëàíî unknown - неизвеÑтно + íåèçâåñòíî @@ -1816,12 +1816,12 @@ Address: %4 Transaction details - Детали транзакции + Äåòàëè òðàíçàêöèè This pane shows a detailed description of the transaction - Данный диалог показывает детализированную ÑтатиÑтику по выбранной транзакции + Äàííûé äèàëîã ïîêàçûâàåò äåòàëèçèðîâàííóþ ñòàòèñòèêó ïî âûáðàííîé òðàíçàêöèè @@ -1829,125 +1829,125 @@ Address: %4 Date - Дата + Äàòà Type - Тип + Òèï Address - ÐÐ´Ñ€ÐµÑ + Àäðåñ Amount - КоличеÑтво + Êîëè÷åñòâî Open for %n block(s) - Открыто Ð´Ð»Ñ %n блока - Открыто Ð´Ð»Ñ %n блоков - Открыто Ð´Ð»Ñ %n блоков + Îòêðûòî äëÿ %n áëîêà + Îòêðûòî äëÿ %n áëîêîâ + Îòêðûòî äëÿ %n áëîêîâ Open until %1 - Открыто до %1 + Îòêðûòî äî %1 Offline (%1 confirmations) - Оффлайн (%1 подтверждений) + Îôôëàéí (%1 ïîäòâåðæäåíèé) Unconfirmed (%1 of %2 confirmations) - Ðе подтверждено (%1 из %2 подтверждений) + Íå ïîäòâåðæäåíî (%1 èç %2 ïîäòâåðæäåíèé) Confirmed (%1 confirmations) - Подтверждено (%1 подтверждений) + Ïîäòâåðæäåíî (%1 ïîäòâåðæäåíèé) Mined balance will be available when it matures in %n more block(s) - Добытыми монетами можно будет воÑпользоватьÑÑ Ñ‡ÐµÑ€ÐµÐ· %n блок - Добытыми монетами можно будет воÑпользоватьÑÑ Ñ‡ÐµÑ€ÐµÐ· %n блока - Добытыми монетами можно будет воÑпользоватьÑÑ Ñ‡ÐµÑ€ÐµÐ· %n блоков + Äîáûòûìè ìîíåòàìè ìîæíî áóäåò âîñïîëüçîâàòüñÿ ÷åðåç %n áëîê + Äîáûòûìè ìîíåòàìè ìîæíî áóäåò âîñïîëüçîâàòüñÿ ÷åðåç %n áëîêà + Äîáûòûìè ìîíåòàìè ìîæíî áóäåò âîñïîëüçîâàòüñÿ ÷åðåç %n áëîêîâ This block was not received by any other nodes and will probably not be accepted! - Этот блок не был получен другими узлами и, возможно, не будет принÑÑ‚! + Ýòîò áëîê íå áûë ïîëó÷åí äðóãèìè óçëàìè è, âîçìîæíî, íå áóäåò ïðèíÿò! Generated but not accepted - Сгенерированно, но не подтверждено + Ñãåíåðèðîâàííî, íî íå ïîäòâåðæäåíî Received with - Получено + Ïîëó÷åíî Received from - Получено от + Ïîëó÷åíî îò Sent to - Отправлено + Îòïðàâëåíî Payment to yourself - Отправлено Ñебе + Îòïðàâëåíî ñåáå Mined - Добыто + Äîáûòî (n/a) - [не доÑтупно] + [íå äîñòóïíî] Transaction status. Hover over this field to show number of confirmations. - Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸. Подведите курÑор к нужному полю Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы увидеть количеÑтво подтверждений. + Ñòàòóñ òðàíçàêöèè. Ïîäâåäèòå êóðñîð ê íóæíîìó ïîëþ äëÿ òîãî, ÷òîáû óâèäåòü êîëè÷åñòâî ïîäòâåðæäåíèé. Date and time that the transaction was received. - Дата и времÑ, когда Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð±Ñ‹Ð»Ð° получена. + Äàòà è âðåìÿ, êîãäà òðàíçàêöèÿ áûëà ïîëó÷åíà. Type of transaction. - Тип транзакции. + Òèï òðàíçàêöèè. Destination address of transaction. - ÐÐ´Ñ€ÐµÑ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸. + Àäðåñ íàçíà÷åíèÿ òðàíçàêöèè. Amount removed from or added to balance. - Сумма, добавленнаÑ, или ÑнÑÑ‚Ð°Ñ Ñ Ð±Ð°Ð»Ð°Ð½Ñа. + Ñóììà, äîáàâëåííàÿ, èëè ñíÿòàÿ ñ áàëàíñà. @@ -1956,137 +1956,137 @@ Address: %4 All - Ð’Ñе + Âñå Today - Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ + Ñåãîäíÿ This week - Ðа Ñтой неделе + Íà ýòîé íåäåëå This month - Ð’ Ñтом меÑÑце +  ýòîì ìåñÿöå Last month - За поÑледний меÑÑц + Çà ïîñëåäíèé ìåñÿö This year - Ð’ Ñтом году +  ýòîì ãîäó Range... - Промежуток... + Ïðîìåæóòîê... Received with - Получено на + Ïîëó÷åíî íà Sent to - Отправлено на + Îòïðàâëåíî íà To yourself - Отправленные Ñебе + Îòïðàâëåííûå ñåáå Mined - Добытые + Äîáûòûå Other - Другое + Äðóãîå Enter address or label to search - Введите Ð°Ð´Ñ€ÐµÑ Ð¸Ð»Ð¸ метку Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка + Ââåäèòå àäðåñ èëè ìåòêó äëÿ ïîèñêà Min amount - Мин. Ñумма + Ìèí. ñóììà Copy address - Копировать Ð°Ð´Ñ€ÐµÑ + Êîïèðîâàòü àäðåñ Copy label - Копировать метку + Êîïèðîâàòü ìåòêó Copy amount - Скопировать Ñумму + Ñêîïèðîâàòü ñóììó Edit label - Ð?зменить метку + Èçìåíèòü ìåòêó Show transaction details - Показать подробноÑти транзакции + Ïîêàçàòü ïîäðîáíîñòè òðàíçàêöèè Export Transaction Data - ЭкÑпортировать данные транзакций + Ýêñïîðòèðîâàòü äàííûå òðàíçàêöèé Comma separated file (*.csv) - ТекÑÑ‚, разделённый запÑтыми (*.csv) + Òåêñò, ðàçäåë¸ííûé çàïÿòûìè (*.csv) Confirmed - Подтверждено + Ïîäòâåðæäåíî Date - Дата + Äàòà Type - Тип + Òèï Label - Метка + Ìåòêà Address - ÐÐ´Ñ€ÐµÑ + Àäðåñ Amount - КоличеÑтво + Êîëè÷åñòâî @@ -2096,22 +2096,22 @@ Address: %4 Error exporting - Ошибка ÑкÑпорта + Îøèáêà ýêñïîðòà Could not write to file %1. - Ðевозможно запиÑать в файл %1. + Íåâîçìîæíî çàïèñàòü â ôàéë %1. Range: - Промежуток от: + Ïðîìåæóòîê îò: to - до + äî @@ -2119,7 +2119,7 @@ Address: %4 Sending... - Отправка.... + Îòïðàâêà.... @@ -2127,118 +2127,118 @@ Address: %4 BottleCaps version - ВерÑÐ¸Ñ + Âåðñèÿ Usage: - Ð?Ñпользование: + Èñïîëüçîâàíèå: Send command to -server or bitcoind - Отправить команду на -server или bitcoind + Îòïðàâèòü êîìàíäó íà -server èëè bitcoind List commands - СпиÑок команд + Ñïèñîê êîìàíä Get help for a command - Получить помощь по команде + Ïîëó÷èòü ïîìîùü ïî êîìàíäå Options: - Опции: + Îïöèè: Specify configuration file (default: BottleCaps.conf) - Указать конфигурационный файл (по умолчанию: BottleCaps.conf) + Óêàçàòü êîíôèãóðàöèîííûé ôàéë (ïî óìîë÷àíèþ: BottleCaps.conf) Specify pid file (default: BottleCapsd.pid) - Указать pid-файл (по умолчанию: BottleCaps.pid) + Óêàçàòü pid-ôàéë (ïî óìîë÷àíèþ: BottleCaps.pid) Generate coins - Генерировать монеты + Ãåíåðèðîâàòü ìîíåòû Don't generate coins - Ðе генерировать монеты + Íå ãåíåðèðîâàòü ìîíåòû Specify data directory - Укажите каталог данных + Óêàæèòå êàòàëîã äàííûõ Set database cache size in megabytes (default: 25) - УÑтановить размер кÑша базы данных в мегабайтах (по умолчанию: 25) + Óñòàíîâèòü ðàçìåð êýøà áàçû äàííûõ â ìåãàáàéòàõ (ïî óìîë÷àíèþ: 25) Set database disk log size in megabytes (default: 100) - УÑтановить размер лога базы данных в мегабайтах (по умолчанию: 100) + Óñòàíîâèòü ðàçìåð ëîãà áàçû äàííûõ â ìåãàáàéòàõ (ïî óìîë÷àíèþ: 100) Listen for connections on <port> (default: 7777 or testnet: 17777) - Принимать входÑщие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ð° <port> (по умолчанию: 7777 или 17777 в теÑтовой Ñети) + Ïðèíèìàòü âõîäÿùèå ïîäêëþ÷åíèÿ íà <port> (ïî óìîë÷àíèþ: 7777 èëè 17777 â òåñòîâîé ñåòè) Maintain at most <n> connections to peers (default: 125) - Поддерживать не более <n> подключений к узлам (по умолчанию: 125) + Ïîääåðæèâàòü íå áîëåå <n> ïîäêëþ÷åíèé ê óçëàì (ïî óìîë÷àíèþ: 125) Connect to a node to retrieve peer addresses, and disconnect - ПодключитьÑÑ Ðº узлу, чтобы получить ÑпиÑок адреÑов других учаÑтников и отключитьÑÑ + Ïîäêëþ÷èòüñÿ ê óçëó, ÷òîáû ïîëó÷èòü ñïèñîê àäðåñîâ äðóãèõ ó÷àñòíèêîâ è îòêëþ÷èòüñÿ Specify your own public address - Укажите ваш ÑобÑтвенный публичный Ð°Ð´Ñ€ÐµÑ + Óêàæèòå âàø ñîáñòâåííûé ïóáëè÷íûé àäðåñ Bind to given address. Use [host]:port notation for IPv6 - ПривÑзатьÑÑ (bind) к указанному адреÑу. Ð?Ñпользуйте запиÑÑŒ вида [хоÑÑ‚]:порт Ð´Ð»Ñ IPv6 + Ïðèâÿçàòüñÿ (bind) ê óêàçàííîìó àäðåñó. Èñïîëüçóéòå çàïèñü âèäà [õîñò]:ïîðò äëÿ IPv6 Threshold for disconnecting misbehaving peers (default: 100) - Порог Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ ведущих ÑÐµÐ±Ñ ÑƒÐ·Ð»Ð¾Ð² (по умолчанию: 100) + Ïîðîã äëÿ îòêëþ÷åíèÿ íåïðàâèëüíî âåäóùèõ ñåáÿ óçëîâ (ïî óìîë÷àíèþ: 100) Number of seconds to keep misbehaving peers from reconnecting (default: 86400) - ЧиÑло Ñекунд Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ ведущих ÑÐµÐ±Ñ ÑƒÐ·Ð»Ð¾Ð² (по умолчанию: 86400) + ×èñëî ñåêóíä áëîêèðîâàíèÿ íåïðàâèëüíî âåäóùèõ ñåáÿ óçëîâ (ïî óìîë÷àíèþ: 86400) An error occurred while setting up the RPC port %u for listening on IPv4: %s - Произошла ошибка при открытии RPC-порта %u Ð´Ð»Ñ Ð¿Ñ€Ð¾ÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð½Ð° IPv4: %s + Ïðîèçîøëà îøèáêà ïðè îòêðûòèè RPC-ïîðòà %u äëÿ ïðîñëóøèâàíèÿ íà IPv4: %s An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s - Произошла ошибка при открытии на проÑлушивание IPv6 RCP-порта %u, возвращаемÑÑ Ðº IPv4: %s + Ïðîèçîøëà îøèáêà ïðè îòêðûòèè íà ïðîñëóøèâàíèå IPv6 RCP-ïîðòà %u, âîçâðàùàåìñÿ ê IPv4: %s Detach block and address databases. Increases shutdown time (default: 0) - Отключить базы данных блоков и адреÑов. Увеличивает Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ (по умолчанию: 0) + Îòêëþ÷èòü áàçû äàííûõ áëîêîâ è àäðåñîâ. Óâåëè÷èâàåò âðåìÿ çàâåðøåíèÿ ðàáîòû (ïî óìîë÷àíèþ: 0) @@ -2248,213 +2248,213 @@ Address: %4 Listen for JSON-RPC connections on <port> (default: 8344 or testnet: 18344) - ПроÑлушивать Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ JSON-RPC на <порту> (по умолчанию: 8344 или Ð´Ð»Ñ testnet: 18344) + Ïðîñëóøèâàòü ïîäêëþ÷åíèÿ JSON-RPC íà <ïîðòó> (ïî óìîë÷àíèþ: 8344 èëè äëÿ testnet: 18344) Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Внимание: ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ wallet.dat! Ð’Ñе ключи воÑÑтановлены, но запиÑи в адреÑной книге и иÑтории транзакций могут быть некорректными. + Âíèìàíèå: îøèáêà ÷òåíèÿ wallet.dat! Âñå êëþ÷è âîññòàíîâëåíû, íî çàïèñè â àäðåñíîé êíèãå è èñòîðèè òðàíçàêöèé ìîãóò áûòü íåêîððåêòíûìè. Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Внимание: wallet.dat был поврежден, данные воÑÑтановлены! Оригинальный wallet.dat Ñохранен как wallet.{timestamp}.bak в %s;, еÑли ваши транзакции или Ð±Ð°Ð»Ð°Ð½Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ÑÑ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾, Ñледует воÑÑтановить его из данной копии. + Âíèìàíèå: wallet.dat áûë ïîâðåæäåí, äàííûå âîññòàíîâëåíû! Îðèãèíàëüíûé wallet.dat ñîõðàíåí êàê wallet.{timestamp}.bak â %s;, åñëè âàøè òðàíçàêöèè èëè áàëàíñ îòîáðàæàþòñÿ íåïðàâèëüíî, ñëåäóåò âîññòàíîâèòü åãî èç äàííîé êîïèè. Accept command line and JSON-RPC commands - Принимать командную Ñтроку и команды JSON-RPC + Ïðèíèìàòü êîìàíäíóþ ñòðîêó è êîìàíäû JSON-RPC Attempt to recover private keys from a corrupt wallet.dat - Попытка воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ из поврежденного wallet.dat + Ïîïûòêà âîññòàíîâëåíèÿ êëþ÷åé èç ïîâðåæäåííîãî wallet.dat Importing blockchain data file. - Ð?мпортируетÑÑ Ñ„Ð°Ð¹Ð» цепи блоков. + Èìïîðòèðóåòñÿ ôàéë öåïè áëîêîâ. Importing bootstrap blockchain data file. - Ð?мпортируетÑÑ bootstrap-файл цепи блоков. + Èìïîðòèðóåòñÿ bootstrap-ôàéë öåïè áëîêîâ. Run in the background as a daemon and accept commands - ЗапуÑкатьÑÑ Ð² фоне как демон и принимать команды + Çàïóñêàòüñÿ â ôîíå êàê äåìîí è ïðèíèìàòü êîìàíäû Use the test network - Ð?Ñпользовать теÑтовую Ñеть + Èñïîëüçîâàòü òåñòîâóþ ñåòü Accept connections from outside (default: 1 if no -proxy or -connect) - Принимать Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·Ð²Ð½Ðµ (по умолчанию: 1, еÑли не иÑпользуетÑÑ -proxy или -connect) + Ïðèíèìàòü ïîäêëþ÷åíèÿ èçâíå (ïî óìîë÷àíèþ: 1, åñëè íå èñïîëüçóåòñÿ -proxy èëè -connect) Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Ошибка: Ð’ транзакции отказано. Такое может произойти, еÑли некоторые монеты уже были потрачены, например, еÑли Ð’Ñ‹ иÑпользуете одну копию файла wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в Ñтой. + Îøèáêà:  òðàíçàêöèè îòêàçàíî. Òàêîå ìîæåò ïðîèçîéòè, åñëè íåêîòîðûå ìîíåòû óæå áûëè ïîòðà÷åíû, íàïðèìåð, åñëè Âû èñïîëüçóåòå îäíó êîïèþ ôàéëà wallet.dat, à ìîíåòû áûëè ïîòðà÷åíû èç äðóãîé êîïèè, íî íå áûëè îòìå÷åíû êàê ïîòðà÷åííûå â ýòîé. Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds - Ошибка: Ñта Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ комиÑÑию в размере как минимум %s из-за её объёма, ÑложноÑти или иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ´Ð°Ð²Ð½Ð¾ полученных ÑредÑтв + Îøèáêà: ýòà òðàíçàêöèÿ òðåáóåò êîìèññèþ â ðàçìåðå êàê ìèíèìóì %s èç-çà å¸ îáú¸ìà, ñëîæíîñòè èëè èñïîëüçîâàíèÿ íåäàâíî ïîëó÷åííûõ ñðåäñòâ Set maximum size of high-priority/low-fee transactions in bytes (default: 27000) - МакÑимальный размер выÑокоприоритетных/низкокомиÑÑионных транзакций в байтах (по умолчанию: 27000) + Ìàêñèìàëüíûé ðàçìåð âûñîêîïðèîðèòåòíûõ/íèçêîêîìèññèîííûõ òðàíçàêöèé â áàéòàõ (ïî óìîë÷àíèþ: 27000) Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. - Внимание: уÑтановлено очень большое значение -paytxfee. Это комиÑÑиÑ, которую вы заплатите при проведении транзакции. + Âíèìàíèå: óñòàíîâëåíî î÷åíü áîëüøîå çíà÷åíèå -paytxfee. Ýòî êîìèññèÿ, êîòîðóþ âû çàïëàòèòå ïðè ïðîâåäåíèè òðàíçàêöèè. Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. - Внимание: отображаемые транзакции могут быть некорректны! Вам или другим узлам, возможно, Ñледует обновитьÑÑ. + Âíèìàíèå: îòîáðàæàåìûå òðàíçàêöèè ìîãóò áûòü íåêîððåêòíû! Âàì èëè äðóãèì óçëàì, âîçìîæíî, ñëåäóåò îáíîâèòüñÿ. Warning: Please check that your computer's date and time are correct! If your clock is wrong BottleCaps will not work properly. - Внимание: убедитеÑÑŒ, что дата и Ð²Ñ€ÐµÐ¼Ñ Ð½Ð° Вашем компьютере выÑтавлены верно. ЕÑли Ваши чаÑÑ‹ идут неправильно, BottleCaps будет работать некорректно. + Âíèìàíèå: óáåäèòåñü, ÷òî äàòà è âðåìÿ íà Âàøåì êîìïüþòåðå âûñòàâëåíû âåðíî. Åñëè Âàøè ÷àñû èäóò íåïðàâèëüíî, BottleCaps áóäåò ðàáîòàòü íåêîððåêòíî. Block creation options: - Параметры ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð²: + Ïàðàìåòðû ñîçäàíèÿ áëîêîâ: Connect only to the specified node(s) - ПодключатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ к указанному узлу(ам) + Ïîäêëþ÷àòüñÿ òîëüêî ê óêàçàííîìó óçëó(àì) Discover own IP address (default: 1 when listening and no -externalip) - Определить Ñвой IP (по умолчанию: 1 при проÑлушивании и еÑли не иÑпользуетÑÑ -externalip) + Îïðåäåëèòü ñâîé IP (ïî óìîë÷àíèþ: 1 ïðè ïðîñëóøèâàíèè è åñëè íå èñïîëüçóåòñÿ -externalip) Error: Transaction creation failed - Ошибка: Создание транзакции не удалоÑÑŒ + Îøèáêà: Ñîçäàíèå òðàíçàêöèè íå óäàëîñü Error: Wallet locked, unable to create transaction - Ошибка: бумажник заблокирован, невозможно Ñоздать транзакцию + Îøèáêà: áóìàæíèê çàáëîêèðîâàí, íåâîçìîæíî ñîçäàòü òðàíçàêöèþ Failed to listen on any port. Use -listen=0 if you want this. - Ðе удалоÑÑŒ начать проÑлушивание на порту. Ð?Ñпользуйте -listen=0 еÑли Ð²Ð°Ñ Ñто уÑтраивает. + Íå óäàëîñü íà÷àòü ïðîñëóøèâàíèå íà ïîðòó. Èñïîëüçóéòå -listen=0 åñëè âàñ ýòî óñòðàèâàåò. Find peers using DNS lookup (default: 0 unless -connect) - Ð?Ñкать узлы Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ DNS (по умолчанию: 0) + Èñêàòü óçëû ñ ïîìîùüþ DNS (ïî óìîë÷àíèþ: 0) Invalid -tor address: '%s' - Ðеверный Ð°Ð´Ñ€ÐµÑ -tor: '%s' + Íåâåðíûé àäðåñ -tor: '%s' Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000) - МакÑимальный размер буфера приёма на Ñоединение, <n>*1000 байт (по умолчанию: 5000) + Ìàêñèìàëüíûé ðàçìåð áóôåðà ïðè¸ìà íà ñîåäèíåíèå, <n>*1000 áàéò (ïî óìîë÷àíèþ: 5000) Maximum per-connection send buffer, <n>*1000 bytes (default: 1000) - МакÑимальный размер буфера отправки на Ñоединение, <n>*1000 байт (по умолчанию: 1000) + Ìàêñèìàëüíûé ðàçìåð áóôåðà îòïðàâêè íà ñîåäèíåíèå, <n>*1000 áàéò (ïî óìîë÷àíèþ: 1000) Only connect to nodes in network <net> (IPv4, IPv6 or Tor) - ПодключатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ к узлам из Ñети <net> (IPv4, IPv6 или Tor) + Ïîäêëþ÷àòüñÿ òîëüêî ê óçëàì èç ñåòè <net> (IPv4, IPv6 èëè Tor) Output extra debugging information. Implies all other -debug* options - Выводить больше отладочной информации. Включает вÑе оÑтальные опции -debug* + Âûâîäèòü áîëüøå îòëàäî÷íîé èíôîðìàöèè. Âêëþ÷àåò âñå îñòàëüíûå îïöèè -debug* Output extra network debugging information - Выводить дополнительную Ñетевую отладочную информацию + Âûâîäèòü äîïîëíèòåëüíóþ ñåòåâóþ îòëàäî÷íóþ èíôîðìàöèþ Prepend debug output with timestamp - ДопиÑывать отметки времени к отладочному выводу + Äîïèñûâàòü îòìåòêè âðåìåíè ê îòëàäî÷íîìó âûâîäó SSL options: (see the Bitcoin Wiki for SSL setup instructions) -Параметры SSL: (Ñм. Bitcoin Wiki Ð´Ð»Ñ Ð¸Ð½Ñтрукций по наÑтройке SSL) +Ïàðàìåòðû SSL: (ñì. Bitcoin Wiki äëÿ èíñòðóêöèé ïî íàñòðîéêå SSL) Select the version of socks proxy to use (4-5, default: 5) - Выберите верÑию SOCKS-прокÑи (4-5, по умолчанию: 5) + Âûáåðèòå âåðñèþ SOCKS-ïðîêñè (4-5, ïî óìîë÷àíèþ: 5) Send trace/debug info to console instead of debug.log file - Выводить информацию траÑÑировки/отладки на конÑоль вмеÑто файла debug.log + Âûâîäèòü èíôîðìàöèþ òðàññèðîâêè/îòëàäêè íà êîíñîëü âìåñòî ôàéëà debug.log Send trace/debug info to debugger - ОтправлÑть информацию траÑÑировки/отладки в отладчик + Îòïðàâëÿòü èíôîðìàöèþ òðàññèðîâêè/îòëàäêè â îòëàä÷èê Set maximum block size in bytes (default: 250000) - МакÑимальный размер блока в байтах (по умолчанию: 250000) + Ìàêñèìàëüíûé ðàçìåð áëîêà â áàéòàõ (ïî óìîë÷àíèþ: 250000) Set minimum block size in bytes (default: 0) - Минимальный размер блока в байтах (по умолчанию: 0) + Ìèíèìàëüíûé ðàçìåð áëîêà â áàéòàõ (ïî óìîë÷àíèþ: 0) Shrink debug.log file on client startup (default: 1 when no -debug) - Сжимать файл debug.log при запуÑке клиента (по умолчанию: 1, еÑли нет -debug) + Ñæèìàòü ôàéë debug.log ïðè çàïóñêå êëèåíòà (ïî óìîë÷àíèþ: 1, åñëè íåò -debug) Specify connection timeout in milliseconds (default: 5000) - Таймаут ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð² миллиÑекундах (по умолчанию: 5000) + Òàéìàóò ñîåäèíåíèÿ â ìèëëèñåêóíäàõ (ïî óìîë÷àíèþ: 5000) Use UPnP to map the listening port (default: 0) - Ð?Ñпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 0) + Èñïîëüçîâàòü UPnP äëÿ ïðîáðîñà ïîðòà (ïî óìîë÷àíèþ: 0) Use UPnP to map the listening port (default: 1 when listening) - Ð?Ñпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 1, еÑли иÑпользуетÑÑ Ð¿Ñ€Ð¾Ñлушивание) + Èñïîëüçîâàòü UPnP äëÿ ïðîáðîñà ïîðòà (ïî óìîë÷àíèþ: 1, åñëè èñïîëüçóåòñÿ ïðîñëóøèâàíèå) Use proxy to reach tor hidden services (default: same as -proxy) - Ð?Ñпользовать прокÑи Ð´Ð»Ñ Ñкрытых ÑервиÑов (по умолчанию: тот же, что и в -proxy) + Èñïîëüçîâàòü ïðîêñè äëÿ ñêðûòûõ ñåðâèñîâ (ïî óìîë÷àíèþ: òîò æå, ÷òî è â -proxy) Username for JSON-RPC connections - Ð?Ð¼Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC + Èìÿ äëÿ ïîäêëþ÷åíèé JSON-RPC @@ -2464,12 +2464,12 @@ Address: %4 Warning: Disk space is low! - Внимание: мало меÑта на диÑке! + Âíèìàíèå: ìàëî ìåñòà íà äèñêå! Warning: This version is obsolete, upgrade required! - Внимание: Ñта верÑÐ¸Ñ ÑƒÑтарела, требуетÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ! + Âíèìàíèå: ýòà âåðñèÿ óñòàðåëà, òðåáóåòñÿ îáíîâëåíèå! @@ -2479,82 +2479,82 @@ Address: %4 Password for JSON-RPC connections - Пароль Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC + Ïàðîëü äëÿ ïîäêëþ÷åíèé JSON-RPC Allow JSON-RPC connections from specified IP address - Разрешить Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ JSON-RPC Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾ IP + Ðàçðåøèòü ïîäêëþ÷åíèÿ JSON-RPC ñ óêàçàííîãî IP Send commands to node running on <ip> (default: 127.0.0.1) - ПоÑылать команды узлу, запущенному на <ip> (по умолчанию: 127.0.0.1) + Ïîñûëàòü êîìàíäû óçëó, çàïóùåííîìó íà <ip> (ïî óìîë÷àíèþ: 127.0.0.1) Execute command when the best block changes (%s in cmd is replaced by block hash) - Выполнить команду, когда поÑвлÑетÑÑ Ð½Ð¾Ð²Ñ‹Ð¹ блок (%s в команде заменÑетÑÑ Ð½Ð° Ñ…Ñш блока) + Âûïîëíèòü êîìàíäó, êîãäà ïîÿâëÿåòñÿ íîâûé áëîê (%s â êîìàíäå çàìåíÿåòñÿ íà õýø áëîêà) Upgrade wallet to latest format - Обновить бумажник до поÑледнего формата + Îáíîâèòü áóìàæíèê äî ïîñëåäíåãî ôîðìàòà Set key pool size to <n> (default: 100) - УÑтановить размер запаÑа ключей в <n> (по умолчанию: 100) + Óñòàíîâèòü ðàçìåð çàïàñà êëþ÷åé â <n> (ïî óìîë÷àíèþ: 100) Rescan the block chain for missing wallet transactions - Перепроверить цепь блоков на предмет отÑутÑтвующих в бумажнике транзакций + Ïåðåïðîâåðèòü öåïü áëîêîâ íà ïðåäìåò îòñóòñòâóþùèõ â áóìàæíèêå òðàíçàêöèé How many blocks to check at startup (default: 2500, 0 = all) - Сколько блоков проверÑть при запуÑке (по умолчанию: 2500, 0 = вÑе) + Ñêîëüêî áëîêîâ ïðîâåðÿòü ïðè çàïóñêå (ïî óìîë÷àíèþ: 2500, 0 = âñå) How thorough the block verification is (0-6, default: 1) - ÐаÑколько тщательно проверÑть блоки (0-6, по умолчанию: 1) + Íàñêîëüêî òùàòåëüíî ïðîâåðÿòü áëîêè (0-6, ïî óìîë÷àíèþ: 1) Imports blocks from external blk000?.dat file - Ð?мпортировать блоки из внешнего файла blk000?.dat + Èìïîðòèðîâàòü áëîêè èç âíåøíåãî ôàéëà blk000?.dat Use OpenSSL (https) for JSON-RPC connections - Ð?Ñпользовать OpenSSL (https) Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC + Èñïîëüçîâàòü OpenSSL (https) äëÿ ïîäêëþ÷åíèé JSON-RPC Server certificate file (default: server.cert) - Файл Ñерверного Ñертификата (по умолчанию: server.cert) + Ôàéë ñåðâåðíîãî ñåðòèôèêàòà (ïî óìîë÷àíèþ: server.cert) Server private key (default: server.pem) - Приватный ключ Ñервера (по умолчанию: server.pem) + Ïðèâàòíûé êëþ÷ ñåðâåðà (ïî óìîë÷àíèþ: server.pem) Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) - Разрешённые алгоритмы (по умолчанию: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Ðàçðåø¸ííûå àëãîðèòìû (ïî óìîë÷àíèþ: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) This help message - Эта Ñправка + Ýòà ñïðàâêà Cannot obtain a lock on data directory %s. BottleCaps is probably already running. - Ðевозможно уÑтановить блокировку на рабочую директорию %s. Возможно, бумажник уже запущен. + Íåâîçìîæíî óñòàíîâèòü áëîêèðîâêó íà ðàáî÷óþ äèðåêòîðèþ %s. Âîçìîæíî, áóìàæíèê óæå çàïóùåí. @@ -2564,157 +2564,157 @@ Address: %4 Unable to bind to %s on this computer (bind returned error %d, %s) - Ðевозможно привÑзатьÑÑ Ðº %s на Ñтом компьютере (bind вернул ошибку %d, %s) + Íåâîçìîæíî ïðèâÿçàòüñÿ ê %s íà ýòîì êîìïüþòåðå (bind âåðíóë îøèáêó %d, %s) Connect through socks proxy - ПодключатьÑÑ Ñ‡ÐµÑ€ÐµÐ· socks прокÑи + Ïîäêëþ÷àòüñÿ ÷åðåç socks ïðîêñè Allow DNS lookups for -addnode, -seednode and -connect - Разрешить поиÑк в DNS Ð´Ð»Ñ -addnode, -seednode и -connect + Ðàçðåøèòü ïîèñê â DNS äëÿ -addnode, -seednode è -connect Loading addresses... - Загрузка адреÑов... + Çàãðóçêà àäðåñîâ... Error loading blkindex.dat - Ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ blkindex.dat + Îøèáêà ÷òåíèÿ blkindex.dat Error loading wallet.dat: Wallet corrupted - Ошибка загрузки wallet.dat: Бумажник поврежден + Îøèáêà çàãðóçêè wallet.dat: Áóìàæíèê ïîâðåæäåí Error loading wallet.dat: Wallet requires newer version of BottleCaps - Ошибка загрузки wallet.dat: бумажник требует более новую верÑию BottleCaps + Îøèáêà çàãðóçêè wallet.dat: áóìàæíèê òðåáóåò áîëåå íîâóþ âåðñèþ BottleCaps Wallet needed to be rewritten: restart BottleCaps to complete - Ðеобходимо перезапиÑать бумажник, перезапуÑтите BottleCaps Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸. + Íåîáõîäèìî ïåðåçàïèñàòü áóìàæíèê, ïåðåçàïóñòèòå BottleCaps äëÿ çàâåðøåíèÿ îïåðàöèè. Error loading wallet.dat - Ошибка при загрузке wallet.dat + Îøèáêà ïðè çàãðóçêå wallet.dat Invalid -proxy address: '%s' - Ðеверный Ð°Ð´Ñ€ÐµÑ -proxy: '%s' + Íåâåðíûé àäðåñ -proxy: '%s' Unknown network specified in -onlynet: '%s' - Ð’ параметре -onlynet указана неизвеÑÑ‚Ð½Ð°Ñ Ñеть: '%s' +  ïàðàìåòðå -onlynet óêàçàíà íåèçâåñòíàÿ ñåòü: '%s' Unknown -socks proxy version requested: %i - Ð’ параметре -socks запрошена неизвеÑÑ‚Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ: %i +  ïàðàìåòðå -socks çàïðîøåíà íåèçâåñòíàÿ âåðñèÿ: %i Cannot resolve -bind address: '%s' - Ðе удаётÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð°Ð´Ñ€ÐµÑ Ð² параметре -bind: '%s' + Íå óäà¸òñÿ ðàçðåøèòü àäðåñ â ïàðàìåòðå -bind: '%s' Cannot resolve -externalip address: '%s' - Ðе удаётÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð°Ð´Ñ€ÐµÑ Ð² параметре -externalip: '%s' + Íå óäà¸òñÿ ðàçðåøèòü àäðåñ â ïàðàìåòðå -externalip: '%s' Invalid amount for -paytxfee=<amount>: '%s' - Ðеверное количеÑтво в параметре -paytxfee=<кол-во>: '%s' + Íåâåðíîå êîëè÷åñòâî â ïàðàìåòðå -paytxfee=<êîë-âî>: '%s' Error: could not start node - Ошибка: не удалоÑÑŒ запуÑтить узел + Îøèáêà: íå óäàëîñü çàïóñòèòü óçåë Sending... - Отправка... + Îòïðàâêà... Invalid amount - Ðеверное количеÑтво + Íåâåðíîå êîëè÷åñòâî Insufficient funds - ÐедоÑтаточно монет + Íåäîñòàòî÷íî ìîíåò Loading block index... - Загрузка индекÑа блоков... + Çàãðóçêà èíäåêñà áëîêîâ... Add a node to connect to and attempt to keep the connection open - Добавить узел Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ пытатьÑÑ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ‚ÑŒ Ñоединение открытым + Äîáàâèòü óçåë äëÿ ïîäêëþ÷åíèÿ è ïûòàòüñÿ ïîääåðæèâàòü ñîåäèíåíèå îòêðûòûì Unable to bind to %s on this computer. BottleCaps is probably already running. - Ðевозможно привÑзатьÑÑ Ðº %s на Ñтом компьютере. Возможно, BottleCaps уже работает. + Íåâîçìîæíî ïðèâÿçàòüñÿ ê %s íà ýòîì êîìïüþòåðå. Âîçìîæíî, BottleCaps óæå ðàáîòàåò. Find peers using internet relay chat (default: 1) - Ðайти учаÑтников через IRC (по умолчанию: 1) + Íàéòè ó÷àñòíèêîâ ÷åðåç IRC (ïî óìîë÷àíèþ: 1) Fee per KB to add to transactions you send - КомиÑÑÐ¸Ñ Ð½Ð° килобайт, добавлÑÐµÐ¼Ð°Ñ Ðº вашим транзакциÑм + Êîìèññèÿ íà êèëîáàéò, äîáàâëÿåìàÿ ê âàøèì òðàíçàêöèÿì Loading wallet... - Загрузка бумажника... + Çàãðóçêà áóìàæíèêà... Cannot downgrade wallet - Ðе удаётÑÑ Ð¿Ð¾Ð½Ð¸Ð·Ð¸Ñ‚ÑŒ верÑию бумажника + Íå óäà¸òñÿ ïîíèçèòü âåðñèþ áóìàæíèêà Cannot initialize keypool - Ðе удаётÑÑ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ маÑÑив ключей + Íå óäà¸òñÿ èíèöèàëèçèðîâàòü ìàññèâ êëþ÷åé Cannot write default address - Ðе удаётÑÑ Ð·Ð°Ð¿Ð¸Ñать Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾ умолчанию + Íå óäà¸òñÿ çàïèñàòü àäðåñ ïî óìîë÷àíèþ Rescanning... - Сканирование... + Ñêàíèðîâàíèå... Done loading - Загрузка завершена + Çàãðóçêà çàâåðøåíà To use the %s option - Чтобы иÑпользовать опцию %s + ×òîáû èñïîëüçîâàòü îïöèþ %s @@ -2726,28 +2726,28 @@ rpcpassword=%s (you do not need to remember this password) If the file does not exist, create it with owner-readable-only file permissions. - %s, вы должны уÑтановить опцию rpcpassword в конфигурационном файле: + %s, âû äîëæíû óñòàíîâèòü îïöèþ rpcpassword â êîíôèãóðàöèîííîì ôàéëå: %s -РекомендуетÑÑ Ð¸Ñпользовать Ñледующий Ñлучайный пароль: +Ðåêîìåíäóåòñÿ èñïîëüçîâàòü ñëåäóþùèé ñëó÷àéíûé ïàðîëü: rpcuser=bitcoinrpc rpcpassword=%s -(вам не нужно запоминать Ñтот пароль) -ЕÑли файл не ÑущеÑтвует, Ñоздайте его и уÑтановите права доÑтупа только Ð´Ð»Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð°. +(âàì íå íóæíî çàïîìèíàòü ýòîò ïàðîëü) +Åñëè ôàéë íå ñóùåñòâóåò, ñîçäàéòå åãî è óñòàíîâèòå ïðàâà äîñòóïà òîëüêî äëÿ âëàäåëüöà. Error - Ошибка + Îøèáêà You must set rpcpassword=<password> in the configuration file: %s If the file does not exist, create it with owner-readable-only file permissions. - Ð’Ñ‹ должны уÑтановить rpcpassword=<password> в конфигурационном файле: + Âû äîëæíû óñòàíîâèòü rpcpassword=<password> â êîíôèãóðàöèîííîì ôàéëå: %s -ЕÑли файл не ÑущеÑтвует, Ñоздайте его и уÑтановите права доÑтупа только Ð´Ð»Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð°. +Åñëè ôàéë íå ñóùåñòâóåò, ñîçäàéòå åãî è óñòàíîâèòå ïðàâà äîñòóïà òîëüêî äëÿ âëàäåëüöà. From 44fcb3171862dc3580d1007837a273d7c6ab0dc9 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 16:06:30 +0300 Subject: [PATCH 023/218] Encoding to UTF8. --- src/qt/locale/bitcoin_ru.ts | 1058 +++++++++++++++++------------------ 1 file changed, 529 insertions(+), 529 deletions(-) diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 4a0a8a2..752a5b3 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -7,17 +7,17 @@ About BottleCaps - Î BottleCaps + О BottleCaps <b>BottleCaps</b> version - <b>BottleCaps</b> âåðñèÿ + <b>BottleCaps</b> верÑÐ¸Ñ - Copyright © 2009-2012 The BottleCaps developers - Âñå ïðàâà çàùèùåíû © 2009-2012 Ðàçðàáîò÷èêè BottleCaps + Copyright © 2009-2012 The BottleCaps developers + Ð’Ñе права защищены © 2009-2012 Разработчики BottleCaps @@ -28,11 +28,11 @@ Distributed under the MIT/X11 software license, see the accompanying file COPYIN This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) and cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP software written by Thomas Bernard. -Ýòî ýêñïåðèìåíòàëüíàÿ ïðîãðàììà. +Это ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð°. -Ðàñïðîñòðàíÿåòñÿ íà ïðàâàõ ëèöåíçèè MIT/X11, ñì. ôàéë license.txt èëè http://www.opensource.org/licenses/mit-license.php. +РаÑпроÑтранÑетÑÑ Ð½Ð° правах лицензии MIT/X11, Ñм. файл license.txt или http://www.opensource.org/licenses/mit-license.php. -Ýòîò ïðîäóêò âêëþ÷àåò ÏÎ, ðàçðàáîòàííîå OpenSSL Project äëÿ èñïîëüçîâàíèÿ â OpenSSL Toolkit (http://www.openssl.org/) è êðèïòîãðàôè÷åñêîå ÏÎ, íàïèñàííîå Eric Young (eay@cryptsoft.com) è ÏÎ äëÿ ðàáîòû ñ UPnP, íàïèñàííîå Thomas Bernard. +Этот продукт включает ПО, разработанное OpenSSL Project Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² OpenSSL Toolkit (http://www.openssl.org/) и криптографичеÑкое ПО, напиÑанное Eric Young (eay@cryptsoft.com) и ПО Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ UPnP, напиÑанное Thomas Bernard. @@ -40,102 +40,102 @@ This product includes software developed by the OpenSSL Project for use in the O Address Book - Àäðåñíàÿ êíèãà + ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Double-click to edit address or label - Äëÿ òîãî, ÷òîáû èçìåíèòü àäðåñ èëè ìåòêó äàâæäû êëèêíèòå ïî èçìåíÿåìîìó îáúåêòó + Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы изменить Ð°Ð´Ñ€ÐµÑ Ð¸Ð»Ð¸ метку давжды кликните по изменÑемому объекту Create a new address - Ñîçäàòü íîâûé àäðåñ + Создать новый Ð°Ð´Ñ€ÐµÑ Copy the currently selected address to the system clipboard - Êîïèðîâàòü òåêóùèé âûäåëåííûé àäðåñ â áóôåð îáìåíà + Копировать текущий выделенный Ð°Ð´Ñ€ÐµÑ Ð² буфер обмена &New Address - &Íîâûé àäðåñ + &Ðовый Ð°Ð´Ñ€ÐµÑ These are your BottleCaps addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. - Ýòî Âàøè àäðåñà äëÿ ïîëó÷åíèÿ ïëàòåæåé. Âû ìîæåòå äàòü ðàçíûå àäðåñà îòïðàâèòåëÿì, ÷òîáû îòñëåæèâàòü, êòî èìåííî âàì ïëàòèò. + Это Ваши адреÑа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶ÐµÐ¹. Ð’Ñ‹ можете дать разные адреÑа отправителÑм, чтобы отÑлеживать, кто именно вам платит. &Copy Address - &Êîïèðîâàòü àäðåñ + &Копировать Ð°Ð´Ñ€ÐµÑ Show &QR Code - Ïîêàçàòü &QR êîä + Показать &QR код Sign a message to prove you own a BottleCaps address - Ïîäïèñàòü ñîîáùåíèå, ÷òîáû äîêàçàòü âëàäåíèå àäðåñîì BottleCaps + ПодпиÑать Ñообщение, чтобы доказать владение адреÑом BottleCaps Sign &Message - &Ïîäïèñàòü ñîîáùåíèå + &ПодпиÑать Ñообщение Delete the currently selected address from the list - Óäàëèòü âûáðàííûé àäðåñ èç ñïèñêà + Удалить выбранный Ð°Ð´Ñ€ÐµÑ Ð¸Ð· ÑпиÑка Verify a message to ensure it was signed with a specified BottleCaps address - Ïðîâåðèòü ñîîáùåíèå, ÷òîáû óáåäèòüñÿ, ÷òî îíî áûëî ïîäïèñàíî óêàçàííûì àäðåñîì BottleCaps + Проверить Ñообщение, чтобы убедитьÑÑ, что оно было подпиÑано указанным адреÑом BottleCaps &Verify Message - &Ïðîâåðèòü ñîîáùåíèå + &Проверить Ñообщение &Delete - &Óäàëèòü + &Удалить Copy &Label - Êîïèðîâàòü &ìåòêó + Копировать &метку &Edit - &Ïðàâêà + &Правка Export Address Book Data - Ýêñïîðòèðîâàòü àäðåñíóþ êíèãó + ЭкÑпортировать адреÑную книгу Comma separated file (*.csv) - Òåêñò, ðàçäåë¸ííûé çàïÿòûìè (*.csv) + ТекÑÑ‚, разделённый запÑтыми (*.csv) Error exporting - Îøèáêà ýêñïîðòà + Ошибка ÑкÑпорта Could not write to file %1. - Íåâîçìîæíî çàïèñàòü â ôàéë %1. + Ðевозможно запиÑать в файл %1. @@ -143,17 +143,17 @@ This product includes software developed by the OpenSSL Project for use in the O Label - Ìåòêà + Метка Address - Àäðåñ + ÐÐ´Ñ€ÐµÑ (no label) - [íåò ìåòêè] + [нет метки] @@ -161,99 +161,99 @@ This product includes software developed by the OpenSSL Project for use in the O Passphrase Dialog - Äèàëîã ââîäà ïàðîëÿ + Диалог ввода Ð¿Ð°Ñ€Ð¾Ð»Ñ Enter passphrase - Ââåäèòå ïàðîëü + Введите пароль New passphrase - Íîâûé ïàðîëü + Ðовый пароль Repeat new passphrase - Ïîâòîðèòå íîâûé ïàðîëü + Повторите новый пароль Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>10 or more random characters</b>, or <b>eight or more words</b>. - Ââåäèòå íîâûé ïàðîëü äëÿ áóìàæíèêà. <br/> Ïîæàëóéñòà, èñïîëüçóéòå ôðàçû èç <b>10 èëè áîëåå ñëó÷àéíûõ ñèìâîëîâ,</b> èëè <b>âîñüìè è áîëåå ñëîâ.</b> + Введите новый пароль Ð´Ð»Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ°. <br/> ПожалуйÑта, иÑпользуйте фразы из <b>10 или более Ñлучайных Ñимволов,</b> или <b>воÑьми и более Ñлов.</b> Encrypt wallet - Çàøèôðîâàòü áóìàæíèê + Зашифровать бумажник This operation needs your wallet passphrase to unlock the wallet. - Äëÿ âûïîëíåíèÿ îïåðàöèè òðåáóåòñÿ ïàðîëü âàøåãî áóìàæíèêà. + Ð”Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ требуетÑÑ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ вашего бумажника. Unlock wallet - Ðàçáëîêèðîâàòü áóìàæíèê + Разблокировать бумажник This operation needs your wallet passphrase to decrypt the wallet. - Äëÿ âûïîëíåíèÿ îïåðàöèè òðåáóåòñÿ ïàðîëü âàøåãî áóìàæíèêà. + Ð”Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ требуетÑÑ Ð¿Ð°Ñ€Ð¾Ð»ÑŒ вашего бумажника. Decrypt wallet - Ðàñøèôðîâàòü áóìàæíèê + РаÑшифровать бумажник Change passphrase - Ñìåíèòü ïàðîëü + Сменить пароль Enter the old and new passphrase to the wallet. - Ââåäèòå ñòàðûé è íîâûé ïàðîëü äëÿ áóìàæíèêà. + Введите Ñтарый и новый пароль Ð´Ð»Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ°. Confirm wallet encryption - Ïîäòâåðäèòå øèôðîâàíèå áóìàæíèêà + Подтвердите шифрование бумажника Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>! - Âíèìàíèå: åñëè âû çàøèôðóåòå áóìàæíèê è ïîòåðÿåòå ïàðîëü, âû <b>ÏÎÒÅÐßÅÒÅ ÂÑÅ ÂÀØÈ ÌÎÍÅÒÛ</b>! + Внимание: еÑли вы зашифруете бумажник и потерÑете пароль, вы <b>ПОТЕРЯЕТЕ ВСЕ Ð’ÐШИ МОÐЕТЫ</b>! Are you sure you wish to encrypt your wallet? - Âû óâåðåíû, ÷òî õîòèòå çàøèôðîâàòü âàø áóìàæíèê? + Ð’Ñ‹ уверены, что хотите зашифровать ваш бумажник? IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - ÂÀÆÍÎ: âñå ïðåäûäóùèå ðåçåðâíûå êîïèè âàøåãî êîøåëüêà äîëæíû áûòü çàìåíåíû íîâûì çàøèôðîâàííûì ôàéëîì.  öåëÿõ áåçîïàñíîñòè ïðåäûäóùèå ðåçåðâíûå êîïèè íåøèôðîâàííîãî êîøåëüêà ñòàíóò áåñïîëåçíû, êàê òîëüêî âû íà÷í¸òå èñïîëüçîâàòü íîâûé øèôðîâàííûé êîøåë¸ê. + Ð’ÐЖÐО: вÑе предыдущие резервные копии вашего кошелька должны быть заменены новым зашифрованным файлом. Ð’ целÑÑ… безопаÑноÑти предыдущие резервные копии нешифрованного кошелька Ñтанут беÑполезны, как только вы начнёте иÑпользовать новый шифрованный кошелёк. Warning: The Caps Lock key is on! - Âíèìàíèå: Caps Lock âêëþ÷åí! + Внимание: Caps Lock включен! Wallet encrypted - Áóìàæíèê çàøèôðîâàí + Бумажник зашифрован BottleCaps will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your coins from being stolen by malware infecting your computer. - Ñåé÷àñ ïðîãðàììà çàêðîåòñÿ äëÿ çàâåðøåíèÿ ïðîöåññà øèôðîâàíèÿ. Ïîìíèòå, ÷òî øèôðîâàíèå âàøåãî áóìàæíèêà íå ìîæåò ïîëíîñòüþ çàùèòèòü âàøè ìîíåòû îò êðàæè ñ ïîìîùüþ èíôèöèðîâàíèÿ âàøåãî êîìïüþòåðà âðåäîíîñíûì ÏÎ. + Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð° закроетÑÑ Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа шифрованиÑ. Помните, что шифрование вашего бумажника не может полноÑтью защитить ваши монеты от кражи Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Ð¸Ð½Ñ„Ð¸Ñ†Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ компьютера вредоноÑным ПО. @@ -261,40 +261,40 @@ This product includes software developed by the OpenSSL Project for use in the O Wallet encryption failed - Íå óäàëîñü çàøèôðîâàòü áóìàæíèê + Ðе удалоÑÑŒ зашифровать бумажник Wallet encryption failed due to an internal error. Your wallet was not encrypted. - Øèôðîâàíèå áóìàæíèêà íå óäàëîñü èç-çà âíóòðåííåé îøèáêè. Âàø áóìàæíèê íå áûë çàøèôðîâàí. + Шифрование бумажника не удалоÑÑŒ из-за внутренней ошибки. Ваш бумажник не был зашифрован. The supplied passphrases do not match. - Ââåä¸ííûå ïàðîëè íå ñîâïàäàþò. + Введённые пароли не Ñовпадают. Wallet unlock failed - Ðàçáëîêèðîâêà áóìàæíèêà íå óäàëàñü + Разблокировка бумажника не удалаÑÑŒ The passphrase entered for the wallet decryption was incorrect. - Óêàçàííûé ïàðîëü íå ïîäõîäèò. + Указанный пароль не подходит. Wallet decryption failed - Ðàñøèôðîâàíèå áóìàæíèêà íå óäàëîñü + РаÑшифрование бумажника не удалоÑÑŒ Wallet passphrase was successfully changed. - Ïàðîëü áóìàæíèêà óñïåøíî èçìåí¸í. + Пароль бумажника уÑпешно изменён. @@ -302,166 +302,166 @@ This product includes software developed by the OpenSSL Project for use in the O Sign &message... - &Ïîäïèñàòü ñîîáùåíèå + &ПодпиÑать Ñообщение Synchronizing with network... - Ñèíõðîíèçàöèÿ ñ ñåòüþ... + Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ Ñетью... &Overview - Î&áçîð + О&бзор Show general overview of wallet - Ïîêàçàòü îáùèé îáçîð äåéñòâèé ñ áóìàæíèêîì + Показать общий обзор дейÑтвий Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ¾Ð¼ &Transactions - &Òðàíçàêöèè + &Транзакции Browse transaction history - Ïîêàçàòü èñòîðèþ òðàíçàêöèé + Показать иÑторию транзакций &Address Book - &Àäðåñíàÿ êíèãà + &ÐдреÑÐ½Ð°Ñ ÐºÐ½Ð¸Ð³Ð° Edit the list of stored addresses and labels - Èçìåíèòü ñïèñîê ñîõðàí¸ííûõ àäðåñîâ è ìåòîê ê íèì + Изменить ÑпиÑок Ñохранённых адреÑов и меток к ним &Receive coins - &Ïîëó÷åíèå ìîíåò + &Получение монет Show the list of addresses for receiving payments - Ïîêàçàòü ñïèñîê àäðåñîâ äëÿ ïîëó÷åíèÿ ïëàòåæåé + Показать ÑпиÑок адреÑов Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶ÐµÐ¹ &Send coins - Îòï&ðàâêà ìîíåò + Отп&равка монет E&xit - Â&ûõîä + Ð’&ыход Quit application - Çàêðûòü ïðèëîæåíèå + Закрыть приложение Show information about BottleCaps - Ïîêàçàòü èíôîðìàöèþ î BottleCaps'å + Показать информацию о BottleCaps'е About &Qt - Î &Qt + О &Qt Show information about Qt - Ïîêàçàòü èíôîðìàöèþ î Qt + Показать информацию о Qt &Options... - Îï&öèè... + Оп&ции... &Encrypt Wallet... - &Çàøèôðîâàòü áóìàæíèê + &Зашифровать бумажник &Backup Wallet... - &Ñäåëàòü ðåçåðâíóþ êîïèþ áóìàæíèêà + &Сделать резервную копию бумажника &Change Passphrase... - &Èçìåíèòü ïàðîëü + &Изменить пароль ~%n block(s) remaining - îñòàëñÿ ~%n áëîê - îñòàëîñü ~%n áëîêîâ - îñòàëîñü ~%n áëîêîâ + оÑталÑÑ ~%n блок + оÑталоÑÑŒ ~%n блоков + оÑталоÑÑŒ ~%n блоков Downloaded %1 of %2 blocks of transaction history (%3% done). - Çàãðóæåíî %1 èç %2 áëîêîâ èñòîðèè îïåðàöèé (%3% çàâåðøåíî). + Загружено %1 из %2 блоков иÑтории операций (%3% завершено). &Export... - &Ýêñïîðò... + &ЭкÑпорт... Send coins to a BottleCaps address - Îòïðàâèòü ìîíåòû íà óêàçàííûé àäðåñ BottleCaps + Отправить монеты на указанный Ð°Ð´Ñ€ÐµÑ BottleCaps Modify configuration options for BottleCaps - Èçìåíèòü ïàðàìåòðû êîíôèãóðàöèè BottleCaps + Изменить параметры конфигурации BottleCaps Export the data in the current tab to a file - Ýêñïîðòèðîâàòü äàííûå èç âêëàäêè â ôàéë + ЭкÑпортировать данные из вкладки в файл Encrypt or decrypt wallet - Çàøèôðîâàòü èëè ðàñøèôðîâàòü áóìàæíèê + Зашифровать или раÑшифровать бумажник Backup wallet to another location - Ñäåëàòü ðåçåðâíóþ êîïèþ áóìàæíèêà â äðóãîì ìåñòå + Сделать резервную копию бумажника в другом меÑте Change the passphrase used for wallet encryption - Èçìåíèòü ïàðîëü øèôðîâàíèÿ áóìàæíèêà + Изменить пароль ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ¼Ð°Ð¶Ð½Ð¸ÐºÐ° &Debug window - &Îêíî îòëàäêè + &Окно отладки Open debugging and diagnostic console - Îòêðûòü êîíñîëü îòëàäêè è äèàãíîñòèêè + Открыть конÑоль отладки и диагноÑтики &Verify message... - &Ïðîâåðèòü ñîîáùåíèå... + &Проверить Ñообщение... @@ -471,139 +471,139 @@ This product includes software developed by the OpenSSL Project for use in the O Wallet - Áóìàæíèê + Бумажник &About BottleCaps - &Î BottleCaps + &О BottleCaps &Show / Hide - &Ïîêàçàòü / Ñêðûòü + &Показать / Скрыть &File - &Ôàéë + &Файл &Settings - &Íàñòðîéêè + &ÐаÑтройки &Help - &Ïîìîùü + &Помощь Tabs toolbar - Ïàíåëü âêëàäîê + Панель вкладок Actions toolbar - Ïàíåëü äåéñòâèé + Панель дейÑтвий [testnet] - [òåñòîâàÿ ñåòü] + [теÑÑ‚Ð¾Ð²Ð°Ñ Ñеть] BottleCaps client - BottleCaps êëèåíò + BottleCaps клиент %n active connection(s) to BottleCaps network - %n àêòèâíîå ñîåäèíåíèå ñ ñåòüþ - %n àêòèâíûõ ñîåäèíåíèé ñ ñåòüþ - %n àêòèâíûõ ñîåäèíåíèé ñ ñåòüþ + %n активное Ñоединение Ñ Ñетью + %n активных Ñоединений Ñ Ñетью + %n активных Ñоединений Ñ Ñетью Downloaded %1 blocks of transaction history. - Çàãðóæåíî %1 áëîêîâ èñòîðèè òðàíçàêöèé. + Загружено %1 блоков иÑтории транзакций. %n second(s) ago - %n ñåêóíäó íàçàä - %n ñåêóíäû íàçàä - %n ñåêóíä íàçàä + %n Ñекунду назад + %n Ñекунды назад + %n Ñекунд назад %n minute(s) ago - %n ìèíóòó íàçàä - %n ìèíóòû íàçàä - %n ìèíóò íàçàä + %n минуту назад + %n минуты назад + %n минут назад %n hour(s) ago - %n ÷àñ íàçàä - %n ÷àñà íàçàä - %n ÷àñîâ íàçàä + %n Ñ‡Ð°Ñ Ð½Ð°Ð·Ð°Ð´ + %n чаÑа назад + %n чаÑов назад %n day(s) ago - %n äåíü íàçàä - %n äíÿ íàçàä - %n äíåé íàçàä + %n день назад + %n Ð´Ð½Ñ Ð½Ð°Ð·Ð°Ð´ + %n дней назад Up to date - Ñèíõðîíèçèðîâàííî + Синхронизированно Catching up... - Ñèíõðîíèçèðóåòñÿ... + СинхронизируетÑÑ... Last received block was generated %1. - Ïîñëåäíèé ïîëó÷åííûé áëîê áûë ñãåíåðèðîâàí %1. + ПоÑледний полученный блок был Ñгенерирован %1. This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee? - Äàííàÿ òðàíçàêöèÿ ïðåâûøàåò ïðåäåëüíî äîïóñòèìûé ðàçìåð. Íî Âû ìîæåòå âñ¸ ðàâíî ñîâåðøèòü å¸, äîáàâèâ êîìèññèþ â %1, êîòîðàÿ îòïðàâèòñÿ òåì óçëàì, êîòîðûå îáðàáîòàþò Âàøó òðàíçàêöèþ, è ïîìîæåò ïîääåðæàòü ñåòü. Âû õîòèòå äîáàâèòü êîìèññèþ? + Ð”Ð°Ð½Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÐµÑ‚ предельно допуÑтимый размер. Ðо Ð’Ñ‹ можете вÑÑ‘ равно Ñовершить её, добавив комиÑÑию в %1, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÑÑ Ñ‚ÐµÐ¼ узлам, которые обработают Вашу транзакцию, и поможет поддержать Ñеть. Ð’Ñ‹ хотите добавить комиÑÑию? Confirm transaction fee - Ïîäòâåðäèòå êîìèññèþ + Подтвердите комиÑÑию Sent transaction - Èñõîäÿùàÿ òðàíçàêöèÿ + ИÑходÑÑ‰Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Incoming transaction - Âõîäÿùàÿ òðàíçàêöèÿ + ВходÑÑ‰Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ @@ -612,58 +612,58 @@ Amount: %2 Type: %3 Address: %4 - Äàòà: %1 -Êîëè÷åñòâî: %2 -Òèï: %3 -Àäðåñ: %4 + Дата: %1 +КоличеÑтво: %2 +Тип: %3 +ÐдреÑ: %4 URI handling - Îáðàáîòêà URI + Обработка URI URI can not be parsed! This can be caused by an invalid BottleCaps address or malformed URI parameters. - Íå óäàëîñü îáðàáîòàòü URI! Ýòî ìîæåò áûòü ñâÿçàíî ñ íåâåðíûì àäðåñîì BottleCaps èëè íåïðàâèëüíûìè ïàðàìåòðàìè URI. + Ðе удалоÑÑŒ обработать URI! Это может быть ÑвÑзано Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ñ‹Ð¼ адреÑом BottleCaps или неправильными параметрами URI. Wallet is <b>encrypted</b> and currently <b>unlocked</b> - Áóìàæíèê <b>çàøèôðîâàí</b> è â íàñòîÿùåå âðåìÿ <b>ðàçáëîêèðîâàí</b> + Бумажник <b>зашифрован</b> и в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ <b>разблокирован</b> Wallet is <b>encrypted</b> and currently <b>locked</b> - Áóìàæíèê <b>çàøèôðîâàí</b> è â íàñòîÿùåå âðåìÿ <b>çàáëîêèðîâàí</b> + Бумажник <b>зашифрован</b> и в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ <b>заблокирован</b> Backup Wallet - Ñäåëàòü ðåçåðâíóþ êîïèþ áóìàæíèêà + Сделать резервную копию бумажника Wallet Data (*.dat) - Äàííûå áóìàæíèêà (*.dat) + Данные бумажника (*.dat) Backup Failed - Ðåçåðâíîå êîïèðîâàíèå íå óäàëîñü + Резервное копирование не удалоÑÑŒ There was an error trying to save the wallet data to the new location. - Ïðè ïîïûòêå ñîõðàíåíèÿ äàííûõ áóìàæíèêà â íîâîå ìåñòî ïðîèçîøëà îøèáêà. + При попытке ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… бумажника в новое меÑто произошла ошибка. A fatal error occurred. BottleCaps can no longer continue safely and will quit. - Ïðîèçîøëà íåèñïðàâèìàÿ îøèáêà. BottleCaps íå ìîæåò áåçîïàñíî ïðîäîëæàòü ðàáîòó è áóäåò çàêðûò. + Произошла неиÑÐ¿Ñ€Ð°Ð²Ð¸Ð¼Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. BottleCaps не может безопаÑно продолжать работу и будет закрыт. @@ -671,7 +671,7 @@ Address: %4 Network Alert - Ñåòåâàÿ Òðåâîãà + Ð¡ÐµÑ‚ÐµÐ²Ð°Ñ Ð¢Ñ€ÐµÐ²Ð¾Ð³Ð° @@ -679,67 +679,67 @@ Address: %4 Edit Address - Èçìåíèòü àäðåñ + Изменить Ð°Ð´Ñ€ÐµÑ &Label - &Ìåòêà + &Метка The label associated with this address book entry - Ìåòêà, ñâÿçàííàÿ ñ äàííîé çàïèñüþ + Метка, ÑвÑÐ·Ð°Ð½Ð½Ð°Ñ Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ запиÑью &Address - &Àäðåñ + &ÐÐ´Ñ€ÐµÑ The address associated with this address book entry. This can only be modified for sending addresses. - Àäðåñ, ñâÿçàííûé ñ äàííîé çàïèñüþ. + ÐдреÑ, ÑвÑзанный Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ запиÑью. New receiving address - Íîâûé àäðåñ äëÿ ïîëó÷åíèÿ + Ðовый Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ New sending address - Íîâûé àäðåñ äëÿ îòïðàâêè + Ðовый Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ Edit receiving address - Èçìåíåíèå àäðåñà äëÿ ïîëó÷åíèÿ + Изменение адреÑа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Edit sending address - Èçìåíåíèå àäðåñà äëÿ îòïðàâêè + Изменение адреÑа Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ The entered address "%1" is already in the address book. - Ââåä¸ííûé àäðåñ «%1» óæå íàõîäèòñÿ â àäðåñíîé êíèãå. + Введённый Ð°Ð´Ñ€ÐµÑ Â«%1» уже находитÑÑ Ð² адреÑной книге. The entered address "%1" is not a valid BottleCaps address. - Ââåä¸ííûé àäðåñ "%1" íå ÿâëÿåòñÿ ïðàâèëüíûì BottleCaps-àäðåñîì. + Введённый Ð°Ð´Ñ€ÐµÑ "%1" не ÑвлÑетÑÑ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ BottleCaps-адреÑом. Could not unlock wallet. - Íå óäàåòñÿ ðàçáëîêèðîâàòü áóìàæíèê. + Ðе удаетÑÑ Ñ€Ð°Ð·Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ бумажник. New key generation failed. - Ãåíåðàöèÿ íîâîãî êëþ÷à íå óäàëàñü. + Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ ключа не удалаÑÑŒ. @@ -753,37 +753,37 @@ Address: %4 version - âåðñèÿ + верÑÐ¸Ñ Usage: - Èñïîëüçîâàíèå: + ИÑпользование: command-line options - ïàðàìåòðû êîìàíäíîé ñòðîêè + параметры командной Ñтроки UI options - Îïöèè èíòåðôåéñà + Опции интерфейÑа Set language, for example "de_DE" (default: system locale) - Âûáåðèòå ÿçûê, íàïðèìåð "de_DE" (ïî óìîë÷àíèþ: êàê â ñèñòåìå) + Выберите Ñзык, например "de_DE" (по умолчанию: как в ÑиÑтеме) Start minimized - Çàïóñêàòü ñâ¸ðíóòûì + ЗапуÑкать Ñвёрнутым Show splash screen on startup (default: 1) - Ïîêàçûâàòü ñïëýø ïðè çàïóñêå (ïî óìîë÷àíèþ: 1) + Показывать ÑплÑш при запуÑке (по умолчанию: 1) @@ -791,194 +791,194 @@ Address: %4 Options - Îïöèè + Опции &Main - &Ãëàâíàÿ + &Ð“Ð»Ð°Ð²Ð½Ð°Ñ Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. - Îïöèîíàëüíàÿ êîìèññèÿ çà êàæäûé ÊÁ òðàíçàêöèè, êîòîðàÿ ïîçâîëÿåò áûòü óâåðåííûì, ÷òî Âàøà òðàíçàêöèÿ áóäåò îáðàáîòàíà áûñòðî. Áîëüøèíñòâî òðàíçàêöèé çàíèìàþò 1ÊÁ. Ðåêîìåíäóåòñÿ êîìèññèÿ 0.01. + ÐžÐ¿Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð¼Ð¸ÑÑÐ¸Ñ Ð·Ð° каждый КБ транзакции, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñет быть уверенным, что Ваша Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ обработана быÑтро. БольшинÑтво транзакций занимают 1КБ. РекомендуетÑÑ ÐºÐ¾Ð¼Ð¸ÑÑÐ¸Ñ 0.01. Pay transaction &fee - Çàïëàòèòü êî&ìèññèþ + Заплатить ко&миÑÑию Automatically start BottleCaps after logging in to the system. - Àâòîìàòè÷åñêè çàïóñêàòü BottleCaps ïîñëå âõîäà â ñèñòåìó + ÐвтоматичеÑки запуÑкать BottleCaps поÑле входа в ÑиÑтему &Start BottleCaps on system login - &Çàïóñêàòü BottleCaps ïðè âõîäå â ñèñòåìó + &ЗапуÑкать BottleCaps при входе в ÑиÑтему Detach block and address databases at shutdown. This means they can be moved to another data directory, but it slows down shutdown. The wallet is always detached. - Îòêëþ÷èòü áàçû äàííûõ áëîêîâ è àäðåñîâ ïðè âûõîäå. Ýòî îçíà÷àåò, ÷òî èõ ìîæíî áóäåò ïåðåìåñòèòü â äðóãîé êàòàëîã äàííûõ, íî çàâåðøåíèå ðàáîòû áóäåò ìåäëåííåå. Áóìàæíèê âñåãäà îòêëþ÷àåòñÿ. + Отключить базы данных блоков и адреÑов при выходе. Это означает, что их можно будет перемеÑтить в другой каталог данных, но завершение работы будет медленнее. Бумажник вÑегда отключаетÑÑ. &Detach databases at shutdown - &Îòêëþ÷àòü áàçû äàííûõ ïðè âûõîäå + &Отключать базы данных при выходе &Network - &Ñåòü + &Сеть Automatically open the BottleCaps client port on the router. This only works when your router supports UPnP and it is enabled. - Àâòîìàòè÷åñêè îòêðûòü ïîðò äëÿ BottleCaps-êëèåíòà íà ðîóòåðå. Ðàáîòàåò òîëüêî åñëè Âàø ðîóòåð ïîääåðæèâàåò UPnP, è äàííàÿ ôóíêöèÿ âêëþ÷åíà. + ÐвтоматичеÑки открыть порт Ð´Ð»Ñ BottleCaps-клиента на роутере. Работает только еÑли Ваш роутер поддерживает UPnP, и Ð´Ð°Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°. Map port using &UPnP - Ïðîáðîñèòü ïîðò ÷åðåç &UPnP + ПроброÑить порт через &UPnP Connect to the BottleCaps network through a SOCKS proxy (e.g. when connecting through Tor). - Ïîäêëþ÷àòüñÿ ê ñåòè BottleCaps ÷åðåç ïðîêñè SOCKS (íàïðèìåð, ïðè ïîäêëþ÷åíèè ÷åðåç Tor). + ПодключатьÑÑ Ðº Ñети BottleCaps через прокÑи SOCKS (например, при подключении через Tor). &Connect through SOCKS proxy: - &Ïîäêëþ÷àòüñÿ ÷åðåç SOCKS ïðîêñè: + &ПодключатьÑÑ Ñ‡ÐµÑ€ÐµÐ· SOCKS прокÑи: Proxy &IP: - &IP Ïðîêñè: + &IP ПрокÑи: IP address of the proxy (e.g. 127.0.0.1) - IP-àäðåñ ïðîêñè (íàïðèìåð 127.0.0.1) + IP-Ð°Ð´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи (например 127.0.0.1) &Port: - Ïî&ðò: + По&рт: Port of the proxy (e.g. 9050) - Ïîðò ïðîêñè-ñåðâåðà (íàïðèìåð, 9050) + Порт прокÑи-Ñервера (например, 9050) SOCKS &Version: - &Âåðñèÿ SOCKS: + &ВерÑÐ¸Ñ SOCKS: SOCKS version of the proxy (e.g. 5) - Âåðñèÿ SOCKS-ïðîêñè (íàïðèìåð, 5) + ВерÑÐ¸Ñ SOCKS-прокÑи (например, 5) &Window - &Îêíî + &Окно Show only a tray icon after minimizing the window. - Ïîêàçûâàòü òîëüêî èêîíêó â ñèñòåìíîì ëîòêå ïîñëå ñâîðà÷èâàíèÿ îêíà. + Показывать только иконку в ÑиÑтемном лотке поÑле ÑÐ²Ð¾Ñ€Ð°Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¾ÐºÐ½Ð°. &Minimize to the tray instead of the taskbar - &Câîðà÷èâàòü â ñèñòåìíûé ëîòîê âìåñòî ïàíåëè çàäà÷ + &Cворачивать в ÑиÑтемный лоток вмеÑто панели задач Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. - Ñâîðà÷èâàòü âìåñòî çàêðûòèÿ. Åñëè äàííàÿ îïöèÿ áóäåò âûáðàíà — ïðèëîæåíèå çàêðîåòñÿ òîëüêî ïîñëå âûáîðà ñîîòâåòñòâóþùåãî ïóíêòà â ìåíþ. + Сворачивать вмеÑто закрытиÑ. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¾Ð¿Ñ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ выбрана — приложение закроетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ поÑле выбора ÑоответÑтвующего пункта в меню. M&inimize on close - Ñ&âîðà÷èâàòü ïðè çàêðûòèè + С&ворачивать при закрытии &Display - Î&òîáðàæåíèå + О&тображение User Interface &language: - &ßçûê èíòåðôåéñà: + &Язык интерфейÑа: The user interface language can be set here. This setting will take effect after restarting BottleCaps. - Çäåñü ìîæíî âûáðàòü ÿçûê èíòåðôåéñà. Íàñòðîéêè âñòóïÿò â ñèëó ïîñëå ïåðåçàïóñêà BottleCaps. + ЗдеÑÑŒ можно выбрать Ñзык интерфейÑа. ÐаÑтройки вÑтупÑÑ‚ в Ñилу поÑле перезапуÑка BottleCaps. &Unit to show amounts in: - &Îòîáðàæàòü ñóììû â åäèíèöàõ: + &Отображать Ñуммы в единицах: Choose the default subdivision unit to show in the interface and when sending coins. - Âûáåðèòå åäèíèöó èçìåðåíèÿ ìîíåò ïðè îòîáðàæåíèè è îòïðàâêå. + Выберите единицу Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð½ÐµÑ‚ при отображении и отправке. Whether to show BottleCaps addresses in the transaction list or not. - Ïîêàçûâàòü ëè àäðåñà BottleCaps â ñïèñêå òðàíçàêöèé. + Показывать ли адреÑа BottleCaps в ÑпиÑке транзакций. &Display addresses in transaction list - &Ïîêàçûâàòü àäðåñà â ñïèñêå òðàíçàêöèé + &Показывать адреÑа в ÑпиÑке транзакций &OK - Î&Ê + О&К &Cancel - &Îòìåíà + &Отмена &Apply - &Ïðèìåíèòü + &Применить default - ïî óìîë÷àíèþ + по умолчанию Warning - Âíèìàíèå + Внимание This setting will take effect after restarting BottleCaps. - Ýòà íàñòðîéêà âñòóïèò â ñèëó ïîñëå ïåðåçàïóñêà BottleCaps + Эта наÑтройка вÑтупит в Ñилу поÑле перезапуÑка BottleCaps The supplied proxy address is invalid. - Àäðåñ ïðîêñè íåâåðåí. + ÐÐ´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи неверен. @@ -986,79 +986,79 @@ Address: %4 Form - Ôîðìà + Форма The displayed information may be out of date. Your wallet automatically synchronizes with the BottleCaps network after a connection is established, but this process has not completed yet. - Îòîáðàæàåìàÿ èíôîðìàöèÿ ìîæåò áûòü óñòàðåâøåé. Âàø áóìàæíèê àâòîìàòè÷åñêè ñèíõðîíèçèðóåòñÿ ñ ñåòüþ BottleCaps ïîñëå ïîäêëþ÷åíèÿ, íî ýòîò ïðîöåññ ïîêà íå çàâåðø¸í. + ÐžÑ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÐµÐ¼Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть уÑтаревшей. Ваш бумажник автоматичеÑки ÑинхронизируетÑÑ Ñ Ñетью BottleCaps поÑле подключениÑ, но Ñтот процеÑÑ Ð¿Ð¾ÐºÐ° не завершён. Balance: - Áàëàíñ: + БаланÑ: Stake: - Äîëÿ: + ДолÑ: Number of transactions: - Êîëè÷åñòâî òðàíçàêöèé: + КоличеÑтво транзакций: Unconfirmed: - Íå ïîäòâåðæäåíî: + Ðе подтверждено: Wallet - Áóìàæíèê + Бумажник Immature: - Íåçðåëûå: + Ðезрелые: Mined balance that has not yet matured - Áàëàíñ äîáûòûõ ìîíåò, êîòîðûé åù¸ íå ñîçðåë + Ð‘Ð°Ð»Ð°Ð½Ñ Ð´Ð¾Ð±Ñ‹Ñ‚Ñ‹Ñ… монет, который ещё не Ñозрел <b>Recent transactions</b> - <b>Ïîñëåäíèå òðàíçàêöèè</b> + <b>ПоÑледние транзакции</b> Your current balance - Âàø òåêóùèé áàëàíñ + Ваш текущий Ð±Ð°Ð»Ð°Ð½Ñ Total of transactions that have yet to be confirmed, and do not yet count toward the current balance - Îáùàÿ ñóììà âñåõ òðàíçàêöèé, êîòîðûå äî ñèõ ïîð íå ïîäòâåðæäåíû, è äî ñèõ ïîð íå ó÷èòûâàþòñÿ â òåêóùåì áàëàíñå + ÐžÐ±Ñ‰Ð°Ñ Ñумма вÑех транзакций, которые до Ñих пор не подтверждены, и до Ñих пор не учитываютÑÑ Ð² текущем баланÑе Total of coins that was staked, and do not yet count toward the current balance - Îáùàÿ ñóììà âñåõ ìîíåò, èñïîëüçóåìûõ äëÿ Proof-of-Stake, è íå ó÷èòûâàþùèõñÿ íà áàëàíñå + ÐžÐ±Ñ‰Ð°Ñ Ñумма вÑех монет, иÑпользуемых Ð´Ð»Ñ Proof-of-Stake, и не учитывающихÑÑ Ð½Ð° баланÑе Total number of transactions in wallet - Îáùåå êîëè÷åñòâî òðàíçàêöèé â Âàøåì áóìàæíèêå + Общее количеÑтво транзакций в Вашем бумажнике out of sync - íå ñèíõðîíèçèðîâàíî + не Ñинхронизировано @@ -1066,57 +1066,57 @@ Address: %4 QR Code Dialog - Äèàëîã QR-êîäà + Диалог QR-кода Request Payment - Çàïðîñèòü ïëàò¸æ + ЗапроÑить платёж Amount: - Êîëè÷åñòâî: + КоличеÑтво: Label: - Ìåòêà: + Метка: Message: - Ñîîáùåíèå: + Сообщение: &Save As... - &Ñîõðàíèòü êàê... + &Сохранить как... Error encoding URI into QR Code. - Îøèáêà êîäèðîâàíèÿ URI â QR-êîä + Ошибка ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ URI в QR-код The entered amount is invalid, please check. - Ââåäåíî íåâåðíîå êîëè÷åñòâî, ïðîâåðüòå åù¸ ðàç. + Введено неверное количеÑтво, проверьте ещё раз. Resulting URI too long, try to reduce the text for label / message. - Ïîëó÷èâøèéñÿ URI ñëèøêîì äëèííûé, ïîïðîáóéòå ñîêðàòèòü òåêñò ìåòêè / ñîîáùåíèÿ. + ПолучившийÑÑ URI Ñлишком длинный, попробуйте Ñократить текÑÑ‚ метки / ÑообщениÑ. Save QR Code - Ñîõðàíèòü QR-êîä + Сохранить QR-код PNG Images (*.png) - PNG Èçîáðàæåíèÿ (*.png) + PNG Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (*.png) @@ -1124,7 +1124,7 @@ Address: %4 Client name - Èìÿ êëèåíòà + Ð˜Ð¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° @@ -1138,132 +1138,132 @@ Address: %4 N/A - Í/Ä + Ð/Д Client version - Âåðñèÿ êëèåíòà + ВерÑÐ¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° &Information - &Èíôîðìàöèÿ + &Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Using OpenSSL version - Èñïîëüçóåòñÿ âåðñèÿ OpenSSL + ИÑпользуетÑÑ Ð²ÐµÑ€ÑÐ¸Ñ OpenSSL Startup time - Âðåìÿ çàïóñêà + Ð’Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿ÑƒÑка Network - Ñåòü + Сеть Number of connections - ×èñëî ïîäêëþ÷åíèé + ЧиÑло подключений On testnet -  òåñòîâîé ñåòè + Ð’ теÑтовой Ñети Block chain - Öåïü áëîêîâ + Цепь блоков Current number of blocks - Òåêóùåå ÷èñëî áëîêîâ + Текущее чиÑло блоков Estimated total blocks - Ðàñ÷¸òíîå ÷èñëî áëîêîâ + РаÑчётное чиÑло блоков Last block time - Âðåìÿ ïîñëåäíåãî áëîêà + Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледнего блока &Open - &Îòêðûòü + &Открыть Command-line options - Ïàðàìåòðû êîìàíäíîé ñòðîêè + Параметры командной Ñтроки Show the BottleCaps-Qt help message to get a list with possible BottleCaps command-line options. - Ïîêàçàòü ïîìîùü ïî BottleCaps-Qt, ÷òîáû ïîëó÷èòü ñïèñîê äîñòóïíûõ ïàðàìåòðîâ êîìàíäíîé ñòðîêè. + Показать помощь по BottleCaps-Qt, чтобы получить ÑпиÑок доÑтупных параметров командной Ñтроки. &Show - &Ïîêàçàòü + &Показать &Console - Êîíñîëü + КонÑоль Build date - Äàòà ñáîðêè + Дата Ñборки BottleCaps - Debug window - BottleCaps - Îêíî îòëàäêè + BottleCaps - Окно отладки BottleCaps Core - ßäðî BottleCaps + Ядро BottleCaps Debug log file - Îòëàäî÷íûé ëîã-ôàéë + Отладочный лог-файл Open the BottleCaps debug log file from the current data directory. This can take a few seconds for large log files. - Îòêðûòü îòëàäî÷íûé ëîã-ôàéë BottleCaps èç òåêóùåãî êàòàëîãà äàííûõ. Ýòî ìîæåò çàíÿòü íåñêîëüêî ñåêóíä äëÿ áîëüøèõ ëîã-ôàéëîâ. + Открыть отладочный лог-файл BottleCaps из текущего каталога данных. Это может занÑть неÑколько Ñекунд Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… лог-файлов. Clear console - Î÷èñòèòü êîíñîëü + ОчиÑтить конÑоль Welcome to the BottleCaps RPC console. - Äîáðî ïîæàëîâàòü â RPC-êîíñîëü BottleCaps. + Добро пожаловать в RPC-конÑоль BottleCaps. Use up and down arrows to navigate history, and <b>Ctrl-L</b> to clear screen. - Èñïîëüçóéòå ñòðåëêè ââåðõ è âíèç äëÿ ïðîñìîòðà èñòîðèè è <b>Ctrl-L</b> äëÿ î÷èñòêè ýêðàíà. + ИÑпользуйте Ñтрелки вверх и вниз Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра иÑтории и <b>Ctrl-L</b> Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки Ñкрана. Type <b>help</b> for an overview of available commands. - Íàïèøèòå <b>help</b> äëÿ ïðîñìîòðà äîñòóïíûõ êîìàíä. + Ðапишите <b>help</b> Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра доÑтупных команд. @@ -1278,32 +1278,32 @@ Address: %4 Send Coins - Îòïðàâêà + Отправка Send to multiple recipients at once - Îòïðàâèòü íåñêîëüêèì ïîëó÷àòåëÿì îäíîâðåìåííî + Отправить неÑкольким получателÑм одновременно Add &Recipient - &Äîáàâèòü ïîëó÷àòåëÿ + &Добавить Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Remove all transaction fields - Óäàëèòü âñå ïîëÿ òðàíçàêöèè + Удалить вÑе Ð¿Ð¾Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ Clear &All - Î÷èñòèòü &âñ¸ + ОчиÑтить &вÑÑ‘ Balance: - Áàëàíñ: + БаланÑ: @@ -1313,67 +1313,67 @@ Address: %4 Confirm the send action - Ïîäòâåðäèòü îòïðàâêó + Подтвердить отправку S&end - &Îòïðàâèòü + &Отправить <b>%1</b> to %2 (%3) - <b>%1</b> àäðåñàòó %2 (%3) + <b>%1</b> адреÑату %2 (%3) Confirm send coins - Ïîäòâåðäèòå îòïðàâêó ìîíåò + Подтвердите отправку монет Are you sure you want to send %1? - Âû óâåðåíû, ÷òî õîòèòå îòïðàâèòü %1? + Ð’Ñ‹ уверены, что хотите отправить %1? and - è + и The recipient address is not valid, please recheck. - Àäðåñ ïîëó÷àòåëÿ íåâåðíûé, ïîæàëóéñòà, ïåðåïðîâåðüòå. + ÐÐ´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ñ‹Ð¹, пожалуйÑта, перепроверьте. The amount to pay must be larger than 0. - Êîëè÷åñòâî ìîíåò äëÿ îòïðàâêè äîëæíî áûòü áîëüøå 0. + КоличеÑтво монет Ð´Ð»Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ должно быть больше 0. The amount exceeds your balance. - Êîëè÷åñòâî îòïðàâëÿåìûõ ìîíåò ïðåâûøàåò Âàø áàëàíñ + КоличеÑтво отправлÑемых монет превышает Ваш Ð±Ð°Ð»Ð°Ð½Ñ The total exceeds your balance when the %1 transaction fee is included. - Ñóììà ïðåâûñèò Âàø áàëàíñ, åñëè êîìèññèÿ â ðàçìåðå %1 áóäåò äîáàâëåíà ê òðàíçàêöèè + Сумма превыÑит Ваш баланÑ, еÑли комиÑÑÐ¸Ñ Ð² размере %1 будет добавлена к транзакции Duplicate address found, can only send to each address once per send operation. - Îáíàðóæåí äóáëèðóþùèéñÿ àäðåñ. Îòïðàâêà íà îäèí è òîò æå àäðåñ âîçìîæíà òîëüêî îäèí ðàç çà îäíó îïåðàöèþ îòïðàâêè + Обнаружен дублирующийÑÑ Ð°Ð´Ñ€ÐµÑ. Отправка на один и тот же Ð°Ð´Ñ€ÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð° только один раз за одну операцию отправки Error: Transaction creation failed. - Îøèáêà: íå óäàëîñü ñîçäàòü òðàíçàêöèþ. + Ошибка: не удалоÑÑŒ Ñоздать транзакцию. Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Îøèáêà:  òðàíçàêöèè îòêàçàíî. Òàêîå ìîæåò ïðîèçîéòè, åñëè íåêîòîðûå ìîíåòû óæå áûëè ïîòðà÷åíû, íàïðèìåð, åñëè Âû èñïîëüçóåòå îäíó êîïèþ ôàéëà wallet.dat, à ìîíåòû áûëè ïîòðà÷åíû èç äðóãîé êîïèè, íî íå áûëè îòìå÷åíû êàê ïîòðà÷åííûå â ýòîé. + Ошибка: Ð’ транзакции отказано. Такое может произойти, еÑли некоторые монеты уже были потрачены, например, еÑли Ð’Ñ‹ иÑпользуете одну копию файла wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в Ñтой. @@ -1381,38 +1381,38 @@ Address: %4 Form - Ôîðìà + Форма A&mount: - Êî&ëè÷åñòâî: + Ко&личеÑтво: Pay &To: - Ïîëó&÷àòåëü: + Полу&чатель: Enter a label for this address to add it to your address book - Ââåäèòå ìåòêó äëÿ äàííîãî àäðåñà (äëÿ äîáàâëåíèÿ â àäðåñíóþ êíèãó) + Введите метку Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ адреÑа (Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² адреÑную книгу) &Label: - &Ìåòêà: + &Метка: The address to send the payment to (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Àäðåñ ïîëó÷àòåëÿ ïëàòåæà (íàïðèìåð 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + ÐÐ´Ñ€ÐµÑ Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ð¿Ð»Ð°Ñ‚ÐµÐ¶Ð° (например 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Choose address from address book - Âûáåðèòå àäðåñ èç àäðåñíîé êíèãè + Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги @@ -1422,7 +1422,7 @@ Address: %4 Paste address from clipboard - Âñòàâèòü àäðåñ èç áóôåðà îáìåíà + Ð’Ñтавить Ð°Ð´Ñ€ÐµÑ Ð¸Ð· буфера обмена @@ -1432,12 +1432,12 @@ Address: %4 Remove this recipient - Óäàëèòü ýòîãî ïîëó÷àòåëÿ + Удалить Ñтого Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Enter a BottleCaps address (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Ââåäèòå BottleCaps-àäðåñ (íàïðèìåð 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Введите BottleCaps-Ð°Ð´Ñ€ÐµÑ (например 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) @@ -1445,29 +1445,29 @@ Address: %4 Signatures - Sign / Verify a Message - Ïîäïèñè - ïîäïèñàòü/ïðîâåðèòü ñîîáùåíèå + ПодпиÑи - подпиÑать/проверить Ñообщение &Sign Message - &Ïîäïèñàòü ñîîáùåíèå + &ПодпиÑать Ñообщение You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. - Âû ìîæåòå ïîäïèñûâàòü ñîîáùåíèÿ ñâîèìè àäðåñàìè, ÷òîáû äîêàçàòü âëàäåíèå èìè. Áóäüòå îñòîðîæíû, íå ïîäïèñûâàéòå ÷òî-òî íåîïðåäåë¸ííîå, òàê êàê ôèøèíãîâûå àòàêè ìîãóò îáìàííûì ïóò¸ì çàñòàâèòü âàñ ïîäïèñàòü íåæåëàòåëüíûå ñîîáùåíèÿ. Ïîäïèñûâàéòå òîëüêî òå ñîîáùåíèÿ, ñ êîòîðûìè âû ñîãëàñíû âïëîòü äî ìåëî÷åé. + Ð’Ñ‹ можете подпиÑывать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñвоими адреÑами, чтобы доказать владение ими. Будьте оÑторожны, не подпиÑывайте что-то неопределённое, так как фишинговые атаки могут обманным путём заÑтавить Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñать нежелательные ÑообщениÑ. ПодпиÑывайте только те ÑообщениÑ, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼Ð¸ вы ÑоглаÑны вплоть до мелочей. The address to sign the message with (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Àäðåñ, êîòîðûì âû õîòèòå ïîäïèñàòü ñîîáùåíèå (íàïð. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + ÐдреÑ, которым вы хотите подпиÑать Ñообщение (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Choose an address from the address book - Âûáåðèòå àäðåñ èç àäðåñíîé êíèãè + Выберите Ð°Ð´Ñ€ÐµÑ Ð¸Ð· адреÑной книги @@ -1478,7 +1478,7 @@ Address: %4 Paste address from clipboard - Âñòàâèòü àäðåñ èç áóôåðà îáìåíà + Ð’Ñтавить Ð°Ð´Ñ€ÐµÑ Ð¸Ð· буфера обмена @@ -1488,76 +1488,76 @@ Address: %4 Enter the message you want to sign here - Ââåäèòå ñîîáùåíèå äëÿ ïîäïèñè + Введите Ñообщение Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи Copy the current signature to the system clipboard - Ñêîïèðîâàòü òåêóùóþ ïîäïèñü â ñèñòåìíûé áóôåð îáìåíà + Скопировать текущую подпиÑÑŒ в ÑиÑтемный буфер обмена Sign the message to prove you own this BottleCaps address - Ïîäïèñàòü ñîîáùåíèå, ÷òîáû äîêàçàòü âëàäåíèå àäðåñîì BottleCaps + ПодпиÑать Ñообщение, чтобы доказать владение адреÑом BottleCaps Reset all sign message fields - Ñáðîñèòü çíà÷åíèÿ âñåõ ïîëåé ïîäïèñûâàíèÿ ñîîáùåíèé + СброÑить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð²Ñех полей подпиÑÑ‹Ð²Ð°Ð½Ð¸Ñ Ñообщений Clear &All - Î÷èñòèòü &âñ¸ + ОчиÑтить &вÑÑ‘ &Verify Message - &Ïðîâåðèòü ñîîáùåíèå + &Проверить Ñообщение Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. - Ââåäèòå íèæå àäðåñ äëÿ ïîäïèñè, ñîîáùåíèå (óáåäèòåñü, ÷òî ïåðåâîäû ñòðîê, ïðîáåëû, òàáû è ò.ï. â òî÷íîñòè ñêîïèðîâàíû) è ïîäïèñü, ÷òîáû ïðîâåðèòü ñîîáùåíèå. Óáåäèòåñü, ÷òî íå ñêîïèðîâàëè ëèøíåãî â ïîäïèñü, ïî ñðàâíåíèþ ñ ñàìèì ïîäïèñûâàåìûì ñîîáùåíèåì, ÷òîáû íå ñòàòü æåðòâîé àòàêè "man-in-the-middle". + Введите ниже Ð°Ð´Ñ€ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи, Ñообщение (убедитеÑÑŒ, что переводы Ñтрок, пробелы, табы и Ñ‚.п. в точноÑти Ñкопированы) и подпиÑÑŒ, чтобы проверить Ñообщение. УбедитеÑÑŒ, что не Ñкопировали лишнего в подпиÑÑŒ, по Ñравнению Ñ Ñамим подпиÑываемым Ñообщением, чтобы не Ñтать жертвой атаки "man-in-the-middle". The address the message was signed with (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Àäðåñ, êîòîðûì áûëî ïîäïèñàíî ñîîáùåíèå (íàïð. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + ÐдреÑ, которым было подпиÑано Ñообщение (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Verify the message to ensure it was signed with the specified BottleCaps address - Ïðîâåðèòü ñîîáùåíèå, ÷òîáû óáåäèòüñÿ, ÷òî îíî áûëî ïîäïèñàíî óêàçàííûì àäðåñîì BottleCaps + Проверить Ñообщение, чтобы убедитьÑÑ, что оно было подпиÑано указанным адреÑом BottleCaps Reset all verify message fields - Ñáðîñèòü âñå ïîëÿ ïðîâåðêè ñîîáùåíèÿ + СброÑить вÑе Ð¿Ð¾Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Enter a BottleCaps address (e.g. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) - Ââåäèòå àäðåñ BottleCaps (íàïð. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) + Введите Ð°Ð´Ñ€ÐµÑ BottleCaps (напр. 4Zo1ga6xuKuQ7JV7M9rGDoxdbYwV5zgQJ5) Click "Sign Message" to generate signature - Íàæìèòå "Ïîäïèñàòü ñîîáùåíèå" äëÿ ñîçäàíèÿ ïîäïèñè + Ðажмите "ПодпиÑать Ñообщение" Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи Enter BottleCaps signature - Ââåäèòå ïîäïèñü BottleCaps + Введите подпиÑÑŒ BottleCaps The entered address is invalid. - Ââåä¸ííûé àäðåñ íåâåðåí + Введённый Ð°Ð´Ñ€ÐµÑ Ð½ÐµÐ²ÐµÑ€ÐµÐ½ @@ -1565,59 +1565,59 @@ Address: %4 Please check the address and try again. - Ïîæàëóéñòà, ïðîâåðüòå àäðåñ è ïîïðîáóéòå åù¸ ðàç. + ПожалуйÑта, проверьте Ð°Ð´Ñ€ÐµÑ Ð¸ попробуйте ещё раз. The entered address does not refer to a key. - Ââåä¸ííûé àäðåñ íå ñâÿçàí ñ êëþ÷îì + Введённый Ð°Ð´Ñ€ÐµÑ Ð½Ðµ ÑвÑзан Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð¼ Wallet unlock was cancelled. - Ðàçáëîêèðîâêà áóìàæíèêà áûëà îòìåíåíà. + Разблокировка бумажника была отменена. Private key for the entered address is not available. - Äëÿ ââåä¸ííîãî àäðåñà íåäîñòóïåí çàêðûòûé êëþ÷ + Ð”Ð»Ñ Ð²Ð²ÐµÐ´Ñ‘Ð½Ð½Ð¾Ð³Ð¾ адреÑа недоÑтупен закрытый ключ Message signing failed. - Íå óäàëîñü ïîäïèñàòü ñîîáùåíèå + Ðе удалоÑÑŒ подпиÑать Ñообщение Message signed. - Ñîîáùåíèå ïîäïèñàíî + Сообщение подпиÑано The signature could not be decoded. - Ïîäïèñü íå ìîæåò áûòü ðàñêîäèðîâàíà. + ПодпиÑÑŒ не может быть раÑкодирована. Please check the signature and try again. - Ïîæàëóéñòà, ïðîâåðüòå ïîäïèñü è ïîïðîáóéòå åù¸ ðàç. + ПожалуйÑта, проверьте подпиÑÑŒ и попробуйте ещё раз. The signature did not match the message digest. - Ïîäïèñü íå ñîîòâåòñòâóåò îòïå÷àòêó ñîîáùåíèÿ. + ПодпиÑÑŒ не ÑоответÑтвует отпечатку ÑообщениÑ. Message verification failed. - Ïðîâåðêà ñîîáùåíèÿ íå óäàëàñü. + Проверка ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ðµ удалаÑÑŒ. Message verified. - Ñîîáùåíèå ïðîâåðåíî. + Сообщение проверено. @@ -1625,84 +1625,84 @@ Address: %4 Open until %1 - Îòêðûòî äî %1 + Открыто до %1 Open for %n block(s) - Îòêðûòî äëÿ %n áëîêà - Îòêðûòî äëÿ %n áëîêîâ - Îòêðûòî äëÿ %n áëîêîâ + Открыто Ð´Ð»Ñ %n блока + Открыто Ð´Ð»Ñ %n блоков + Открыто Ð´Ð»Ñ %n блоков %1/offline - %1/îòêëþ÷åí + %1/отключен %1/unconfirmed - %1/íå ïîäòâåðæäåíî + %1/не подтверждено %1 confirmations - %1 ïîäòâåðæäåíèé + %1 подтверждений Status - Ñòàòóñ + Ð¡Ñ‚Ð°Ñ‚ÑƒÑ , broadcast through %n node(s) - , ðàçîñëàíî ÷åðåç %n óçåë - , ðàçîñëàíî ÷åðåç %n óçëà - , ðàçîñëàíî ÷åðåç %n óçëîâ + , разоÑлано через %n узел + , разоÑлано через %n узла + , разоÑлано через %n узлов Date - Äàòà + Дата Source - Èñòî÷íèê + ИÑточник Generated - Ñãåíåðèðîâàííî + Сгенерированно From - Îò + От To - Äëÿ + Ð”Ð»Ñ own address - ñâîé àäðåñ + Ñвой Ð°Ð´Ñ€ÐµÑ label - ìåòêà + метка @@ -1711,21 +1711,21 @@ Address: %4 Credit - Êðåäèò + Кредит matures in %n more block(s) - áóäåò äîñòóïíî ÷åðåç %n áëîê - áóäåò äîñòóïíî ÷åðåç %n áëîêà - áóäåò äîñòóïíî ÷åðåç %n áëîêîâ + будет доÑтупно через %n блок + будет доÑтупно через %n блока + будет доÑтупно через %n блоков not accepted - íå ïðèíÿòî + не принÑто @@ -1733,82 +1733,82 @@ Address: %4 Debit - Äåáåò + Дебет Transaction fee - Êîìèññèÿ + КомиÑÑÐ¸Ñ Net amount - ×èñòàÿ ñóììà + ЧиÑÑ‚Ð°Ñ Ñумма Message - Ñîîáùåíèå + Сообщение Comment - Êîììåíòàðèé: + Комментарий: Transaction ID - ID òðàíçàêöèè + ID транзакции Generated coins must mature 520 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. - Ñãåíåðèðîâàííûå ìîíåòû äîëæíû ïîäîæäàòü 520 áëîêîâ, ïðåæäå ÷åì îíè ìîãóò áûòü ïîòðà÷åíû. Êîãäà Âû ñãåíåðèðîâàëè ýòîò áëîê, îí áûë îòïðàâëåí â ñåòü äëÿ äîáàâëåíèÿ â öåïî÷êó áëîêîâ. Åñëè äàííàÿ ïðîöåäóðà íå óäàñòñÿ, ñòàòóñ èçìåíèòñÿ íà «íå ïîäòâåðæäåíî», è ìîíåòû áóäóò íåäåéñòâèòåëüíû. Ýòî èíîãäà ïðîèñõîäèò â ñëó÷àå, åñëè äðóãîé óçåë ñãåíåðèðóåò áëîê íà íåñêîëüêî ñåêóíä ðàíüøå âàñ. + Сгенерированные монеты должны подождать 520 блоков, прежде чем они могут быть потрачены. Когда Ð’Ñ‹ Ñгенерировали Ñтот блок, он был отправлен в Ñеть Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² цепочку блоков. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° не удаÑÑ‚ÑÑ, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑÑ Ð½Ð° «не подтверждено», и монеты будут недейÑтвительны. Это иногда проиÑходит в Ñлучае, еÑли другой узел Ñгенерирует блок на неÑколько Ñекунд раньше ваÑ. Staked coins must wait 520 blocks before they can return to balance and be spent. When you generated this proof-of-stake block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, it will change to \"not accepted\" and not be a valid stake. This may occasionally happen if another node generates a proof-of-stake block within a few seconds of yours. - Èñïîëüçîâàííûå â Proof-of-Stake ìîíåòû äîëæíû ïîäîæäàòü 520 áëîêîâ, ïðåæäå ÷åì îíè âåðíóòñÿ íà áàëàíñ è ñìîãóò áûòü ïîòðà÷åíû. Êîãäà âû ñãåíåðèðîâàëè ýòîò proof-of-stake áëîê, îí áûë îòïðàâëåí â ñåòü äëÿ äîáàâëåíèÿ â öåïî÷êó áëîêîâ. Åñëè äàííàÿ ïðîöåäóðà íå óäàåòñÿ, ñòàòóñ èçìåíèòñÿ íà \"íå ïîäòâåðæäåíè\" è áëîê áóäåò íåäåéñòâèòåëåí. Ýòî èíîãäà ïðîèñõîäèò â ñëó÷àå, åñëè äðóãîé óçåë ñãåíåðèðóåò áëîê íà íåñêîëüêî ñåêóíä ðàíüøå âàñ. + ИÑпользованные в Proof-of-Stake монеты должны подождать 520 блоков, прежде чем они вернутÑÑ Ð½Ð° Ð±Ð°Ð»Ð°Ð½Ñ Ð¸ Ñмогут быть потрачены. Когда вы Ñгенерировали Ñтот proof-of-stake блок, он был отправлен в Ñеть Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² цепочку блоков. ЕÑли Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° не удаетÑÑ, ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑÑ Ð½Ð° \"не подтверждени\" и блок будет недейÑтвителен. Это иногда проиÑходит в Ñлучае, еÑли другой узел Ñгенерирует блок на неÑколько Ñекунд раньше ваÑ. Debug information - Îòëàäî÷íàÿ èíôîðìàöèÿ + ÐžÑ‚Ð»Ð°Ð´Ð¾Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Transaction - Òðàíçàêöèÿ + Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Inputs - Âõîäû + Входы Amount - Êîëè÷åñòâî + КоличеÑтво true - èñòèíà + иÑтина false - ëîæü + ложь , has not been successfully broadcast yet - , åù¸ íå áûëî óñïåøíî ðàçîñëàíî + , ещё не было уÑпешно разоÑлано unknown - íåèçâåñòíî + неизвеÑтно @@ -1816,12 +1816,12 @@ Address: %4 Transaction details - Äåòàëè òðàíçàêöèè + Детали транзакции This pane shows a detailed description of the transaction - Äàííûé äèàëîã ïîêàçûâàåò äåòàëèçèðîâàííóþ ñòàòèñòèêó ïî âûáðàííîé òðàíçàêöèè + Данный диалог показывает детализированную ÑтатиÑтику по выбранной транзакции @@ -1829,125 +1829,125 @@ Address: %4 Date - Äàòà + Дата Type - Òèï + Тип Address - Àäðåñ + ÐÐ´Ñ€ÐµÑ Amount - Êîëè÷åñòâî + КоличеÑтво Open for %n block(s) - Îòêðûòî äëÿ %n áëîêà - Îòêðûòî äëÿ %n áëîêîâ - Îòêðûòî äëÿ %n áëîêîâ + Открыто Ð´Ð»Ñ %n блока + Открыто Ð´Ð»Ñ %n блоков + Открыто Ð´Ð»Ñ %n блоков Open until %1 - Îòêðûòî äî %1 + Открыто до %1 Offline (%1 confirmations) - Îôôëàéí (%1 ïîäòâåðæäåíèé) + Оффлайн (%1 подтверждений) Unconfirmed (%1 of %2 confirmations) - Íå ïîäòâåðæäåíî (%1 èç %2 ïîäòâåðæäåíèé) + Ðе подтверждено (%1 из %2 подтверждений) Confirmed (%1 confirmations) - Ïîäòâåðæäåíî (%1 ïîäòâåðæäåíèé) + Подтверждено (%1 подтверждений) Mined balance will be available when it matures in %n more block(s) - Äîáûòûìè ìîíåòàìè ìîæíî áóäåò âîñïîëüçîâàòüñÿ ÷åðåç %n áëîê - Äîáûòûìè ìîíåòàìè ìîæíî áóäåò âîñïîëüçîâàòüñÿ ÷åðåç %n áëîêà - Äîáûòûìè ìîíåòàìè ìîæíî áóäåò âîñïîëüçîâàòüñÿ ÷åðåç %n áëîêîâ + Добытыми монетами можно будет воÑпользоватьÑÑ Ñ‡ÐµÑ€ÐµÐ· %n блок + Добытыми монетами можно будет воÑпользоватьÑÑ Ñ‡ÐµÑ€ÐµÐ· %n блока + Добытыми монетами можно будет воÑпользоватьÑÑ Ñ‡ÐµÑ€ÐµÐ· %n блоков This block was not received by any other nodes and will probably not be accepted! - Ýòîò áëîê íå áûë ïîëó÷åí äðóãèìè óçëàìè è, âîçìîæíî, íå áóäåò ïðèíÿò! + Этот блок не был получен другими узлами и, возможно, не будет принÑÑ‚! Generated but not accepted - Ñãåíåðèðîâàííî, íî íå ïîäòâåðæäåíî + Сгенерированно, но не подтверждено Received with - Ïîëó÷åíî + Получено Received from - Ïîëó÷åíî îò + Получено от Sent to - Îòïðàâëåíî + Отправлено Payment to yourself - Îòïðàâëåíî ñåáå + Отправлено Ñебе Mined - Äîáûòî + Добыто (n/a) - [íå äîñòóïíî] + [не доÑтупно] Transaction status. Hover over this field to show number of confirmations. - Ñòàòóñ òðàíçàêöèè. Ïîäâåäèòå êóðñîð ê íóæíîìó ïîëþ äëÿ òîãî, ÷òîáû óâèäåòü êîëè÷åñòâî ïîäòâåðæäåíèé. + Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸. Подведите курÑор к нужному полю Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы увидеть количеÑтво подтверждений. Date and time that the transaction was received. - Äàòà è âðåìÿ, êîãäà òðàíçàêöèÿ áûëà ïîëó÷åíà. + Дата и времÑ, когда Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð±Ñ‹Ð»Ð° получена. Type of transaction. - Òèï òðàíçàêöèè. + Тип транзакции. Destination address of transaction. - Àäðåñ íàçíà÷åíèÿ òðàíçàêöèè. + ÐÐ´Ñ€ÐµÑ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸. Amount removed from or added to balance. - Ñóììà, äîáàâëåííàÿ, èëè ñíÿòàÿ ñ áàëàíñà. + Сумма, добавленнаÑ, или ÑнÑÑ‚Ð°Ñ Ñ Ð±Ð°Ð»Ð°Ð½Ñа. @@ -1956,137 +1956,137 @@ Address: %4 All - Âñå + Ð’Ñе Today - Ñåãîäíÿ + Ð¡ÐµÐ³Ð¾Ð´Ð½Ñ This week - Íà ýòîé íåäåëå + Ðа Ñтой неделе This month -  ýòîì ìåñÿöå + Ð’ Ñтом меÑÑце Last month - Çà ïîñëåäíèé ìåñÿö + За поÑледний меÑÑц This year -  ýòîì ãîäó + Ð’ Ñтом году Range... - Ïðîìåæóòîê... + Промежуток... Received with - Ïîëó÷åíî íà + Получено на Sent to - Îòïðàâëåíî íà + Отправлено на To yourself - Îòïðàâëåííûå ñåáå + Отправленные Ñебе Mined - Äîáûòûå + Добытые Other - Äðóãîå + Другое Enter address or label to search - Ââåäèòå àäðåñ èëè ìåòêó äëÿ ïîèñêà + Введите Ð°Ð´Ñ€ÐµÑ Ð¸Ð»Ð¸ метку Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка Min amount - Ìèí. ñóììà + Мин. Ñумма Copy address - Êîïèðîâàòü àäðåñ + Копировать Ð°Ð´Ñ€ÐµÑ Copy label - Êîïèðîâàòü ìåòêó + Копировать метку Copy amount - Ñêîïèðîâàòü ñóììó + Скопировать Ñумму Edit label - Èçìåíèòü ìåòêó + Изменить метку Show transaction details - Ïîêàçàòü ïîäðîáíîñòè òðàíçàêöèè + Показать подробноÑти транзакции Export Transaction Data - Ýêñïîðòèðîâàòü äàííûå òðàíçàêöèé + ЭкÑпортировать данные транзакций Comma separated file (*.csv) - Òåêñò, ðàçäåë¸ííûé çàïÿòûìè (*.csv) + ТекÑÑ‚, разделённый запÑтыми (*.csv) Confirmed - Ïîäòâåðæäåíî + Подтверждено Date - Äàòà + Дата Type - Òèï + Тип Label - Ìåòêà + Метка Address - Àäðåñ + ÐÐ´Ñ€ÐµÑ Amount - Êîëè÷åñòâî + КоличеÑтво @@ -2096,22 +2096,22 @@ Address: %4 Error exporting - Îøèáêà ýêñïîðòà + Ошибка ÑкÑпорта Could not write to file %1. - Íåâîçìîæíî çàïèñàòü â ôàéë %1. + Ðевозможно запиÑать в файл %1. Range: - Ïðîìåæóòîê îò: + Промежуток от: to - äî + до @@ -2119,7 +2119,7 @@ Address: %4 Sending... - Îòïðàâêà.... + Отправка.... @@ -2127,118 +2127,118 @@ Address: %4 BottleCaps version - Âåðñèÿ + ВерÑÐ¸Ñ Usage: - Èñïîëüçîâàíèå: + ИÑпользование: Send command to -server or bitcoind - Îòïðàâèòü êîìàíäó íà -server èëè bitcoind + Отправить команду на -server или bitcoind List commands - Ñïèñîê êîìàíä + СпиÑок команд Get help for a command - Ïîëó÷èòü ïîìîùü ïî êîìàíäå + Получить помощь по команде Options: - Îïöèè: + Опции: Specify configuration file (default: BottleCaps.conf) - Óêàçàòü êîíôèãóðàöèîííûé ôàéë (ïî óìîë÷àíèþ: BottleCaps.conf) + Указать конфигурационный файл (по умолчанию: BottleCaps.conf) Specify pid file (default: BottleCapsd.pid) - Óêàçàòü pid-ôàéë (ïî óìîë÷àíèþ: BottleCaps.pid) + Указать pid-файл (по умолчанию: BottleCaps.pid) Generate coins - Ãåíåðèðîâàòü ìîíåòû + Генерировать монеты Don't generate coins - Íå ãåíåðèðîâàòü ìîíåòû + Ðе генерировать монеты Specify data directory - Óêàæèòå êàòàëîã äàííûõ + Укажите каталог данных Set database cache size in megabytes (default: 25) - Óñòàíîâèòü ðàçìåð êýøà áàçû äàííûõ â ìåãàáàéòàõ (ïî óìîë÷àíèþ: 25) + УÑтановить размер кÑша базы данных в мегабайтах (по умолчанию: 25) Set database disk log size in megabytes (default: 100) - Óñòàíîâèòü ðàçìåð ëîãà áàçû äàííûõ â ìåãàáàéòàõ (ïî óìîë÷àíèþ: 100) + УÑтановить размер лога базы данных в мегабайтах (по умолчанию: 100) Listen for connections on <port> (default: 7777 or testnet: 17777) - Ïðèíèìàòü âõîäÿùèå ïîäêëþ÷åíèÿ íà <port> (ïî óìîë÷àíèþ: 7777 èëè 17777 â òåñòîâîé ñåòè) + Принимать входÑщие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ð° <port> (по умолчанию: 7777 или 17777 в теÑтовой Ñети) Maintain at most <n> connections to peers (default: 125) - Ïîääåðæèâàòü íå áîëåå <n> ïîäêëþ÷åíèé ê óçëàì (ïî óìîë÷àíèþ: 125) + Поддерживать не более <n> подключений к узлам (по умолчанию: 125) Connect to a node to retrieve peer addresses, and disconnect - Ïîäêëþ÷èòüñÿ ê óçëó, ÷òîáû ïîëó÷èòü ñïèñîê àäðåñîâ äðóãèõ ó÷àñòíèêîâ è îòêëþ÷èòüñÿ + ПодключитьÑÑ Ðº узлу, чтобы получить ÑпиÑок адреÑов других учаÑтников и отключитьÑÑ Specify your own public address - Óêàæèòå âàø ñîáñòâåííûé ïóáëè÷íûé àäðåñ + Укажите ваш ÑобÑтвенный публичный Ð°Ð´Ñ€ÐµÑ Bind to given address. Use [host]:port notation for IPv6 - Ïðèâÿçàòüñÿ (bind) ê óêàçàííîìó àäðåñó. Èñïîëüçóéòå çàïèñü âèäà [õîñò]:ïîðò äëÿ IPv6 + ПривÑзатьÑÑ (bind) к указанному адреÑу. ИÑпользуйте запиÑÑŒ вида [хоÑÑ‚]:порт Ð´Ð»Ñ IPv6 Threshold for disconnecting misbehaving peers (default: 100) - Ïîðîã äëÿ îòêëþ÷åíèÿ íåïðàâèëüíî âåäóùèõ ñåáÿ óçëîâ (ïî óìîë÷àíèþ: 100) + Порог Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ ведущих ÑÐµÐ±Ñ ÑƒÐ·Ð»Ð¾Ð² (по умолчанию: 100) Number of seconds to keep misbehaving peers from reconnecting (default: 86400) - ×èñëî ñåêóíä áëîêèðîâàíèÿ íåïðàâèëüíî âåäóùèõ ñåáÿ óçëîâ (ïî óìîë÷àíèþ: 86400) + ЧиÑло Ñекунд Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ ведущих ÑÐµÐ±Ñ ÑƒÐ·Ð»Ð¾Ð² (по умолчанию: 86400) An error occurred while setting up the RPC port %u for listening on IPv4: %s - Ïðîèçîøëà îøèáêà ïðè îòêðûòèè RPC-ïîðòà %u äëÿ ïðîñëóøèâàíèÿ íà IPv4: %s + Произошла ошибка при открытии RPC-порта %u Ð´Ð»Ñ Ð¿Ñ€Ð¾ÑÐ»ÑƒÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð½Ð° IPv4: %s An error occurred while setting up the RPC port %u for listening on IPv6, falling back to IPv4: %s - Ïðîèçîøëà îøèáêà ïðè îòêðûòèè íà ïðîñëóøèâàíèå IPv6 RCP-ïîðòà %u, âîçâðàùàåìñÿ ê IPv4: %s + Произошла ошибка при открытии на проÑлушивание IPv6 RCP-порта %u, возвращаемÑÑ Ðº IPv4: %s Detach block and address databases. Increases shutdown time (default: 0) - Îòêëþ÷èòü áàçû äàííûõ áëîêîâ è àäðåñîâ. Óâåëè÷èâàåò âðåìÿ çàâåðøåíèÿ ðàáîòû (ïî óìîë÷àíèþ: 0) + Отключить базы данных блоков и адреÑов. Увеличивает Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ (по умолчанию: 0) @@ -2248,213 +2248,213 @@ Address: %4 Listen for JSON-RPC connections on <port> (default: 8344 or testnet: 18344) - Ïðîñëóøèâàòü ïîäêëþ÷åíèÿ JSON-RPC íà <ïîðòó> (ïî óìîë÷àíèþ: 8344 èëè äëÿ testnet: 18344) + ПроÑлушивать Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ JSON-RPC на <порту> (по умолчанию: 8344 или Ð´Ð»Ñ testnet: 18344) Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. - Âíèìàíèå: îøèáêà ÷òåíèÿ wallet.dat! Âñå êëþ÷è âîññòàíîâëåíû, íî çàïèñè â àäðåñíîé êíèãå è èñòîðèè òðàíçàêöèé ìîãóò áûòü íåêîððåêòíûìè. + Внимание: ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ wallet.dat! Ð’Ñе ключи воÑÑтановлены, но запиÑи в адреÑной книге и иÑтории транзакций могут быть некорректными. Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. - Âíèìàíèå: wallet.dat áûë ïîâðåæäåí, äàííûå âîññòàíîâëåíû! Îðèãèíàëüíûé wallet.dat ñîõðàíåí êàê wallet.{timestamp}.bak â %s;, åñëè âàøè òðàíçàêöèè èëè áàëàíñ îòîáðàæàþòñÿ íåïðàâèëüíî, ñëåäóåò âîññòàíîâèòü åãî èç äàííîé êîïèè. + Внимание: wallet.dat был поврежден, данные воÑÑтановлены! Оригинальный wallet.dat Ñохранен как wallet.{timestamp}.bak в %s;, еÑли ваши транзакции или Ð±Ð°Ð»Ð°Ð½Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶Ð°ÑŽÑ‚ÑÑ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾, Ñледует воÑÑтановить его из данной копии. Accept command line and JSON-RPC commands - Ïðèíèìàòü êîìàíäíóþ ñòðîêó è êîìàíäû JSON-RPC + Принимать командную Ñтроку и команды JSON-RPC Attempt to recover private keys from a corrupt wallet.dat - Ïîïûòêà âîññòàíîâëåíèÿ êëþ÷åé èç ïîâðåæäåííîãî wallet.dat + Попытка воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ из поврежденного wallet.dat Importing blockchain data file. - Èìïîðòèðóåòñÿ ôàéë öåïè áëîêîâ. + ИмпортируетÑÑ Ñ„Ð°Ð¹Ð» цепи блоков. Importing bootstrap blockchain data file. - Èìïîðòèðóåòñÿ bootstrap-ôàéë öåïè áëîêîâ. + ИмпортируетÑÑ bootstrap-файл цепи блоков. Run in the background as a daemon and accept commands - Çàïóñêàòüñÿ â ôîíå êàê äåìîí è ïðèíèìàòü êîìàíäû + ЗапуÑкатьÑÑ Ð² фоне как демон и принимать команды Use the test network - Èñïîëüçîâàòü òåñòîâóþ ñåòü + ИÑпользовать теÑтовую Ñеть Accept connections from outside (default: 1 if no -proxy or -connect) - Ïðèíèìàòü ïîäêëþ÷åíèÿ èçâíå (ïî óìîë÷àíèþ: 1, åñëè íå èñïîëüçóåòñÿ -proxy èëè -connect) + Принимать Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·Ð²Ð½Ðµ (по умолчанию: 1, еÑли не иÑпользуетÑÑ -proxy или -connect) Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. - Îøèáêà:  òðàíçàêöèè îòêàçàíî. Òàêîå ìîæåò ïðîèçîéòè, åñëè íåêîòîðûå ìîíåòû óæå áûëè ïîòðà÷åíû, íàïðèìåð, åñëè Âû èñïîëüçóåòå îäíó êîïèþ ôàéëà wallet.dat, à ìîíåòû áûëè ïîòðà÷åíû èç äðóãîé êîïèè, íî íå áûëè îòìå÷åíû êàê ïîòðà÷åííûå â ýòîé. + Ошибка: Ð’ транзакции отказано. Такое может произойти, еÑли некоторые монеты уже были потрачены, например, еÑли Ð’Ñ‹ иÑпользуете одну копию файла wallet.dat, а монеты были потрачены из другой копии, но не были отмечены как потраченные в Ñтой. Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds - Îøèáêà: ýòà òðàíçàêöèÿ òðåáóåò êîìèññèþ â ðàçìåðå êàê ìèíèìóì %s èç-çà å¸ îáú¸ìà, ñëîæíîñòè èëè èñïîëüçîâàíèÿ íåäàâíî ïîëó÷åííûõ ñðåäñòâ + Ошибка: Ñта Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ комиÑÑию в размере как минимум %s из-за её объёма, ÑложноÑти или иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ´Ð°Ð²Ð½Ð¾ полученных ÑредÑтв Set maximum size of high-priority/low-fee transactions in bytes (default: 27000) - Ìàêñèìàëüíûé ðàçìåð âûñîêîïðèîðèòåòíûõ/íèçêîêîìèññèîííûõ òðàíçàêöèé â áàéòàõ (ïî óìîë÷àíèþ: 27000) + МакÑимальный размер выÑокоприоритетных/низкокомиÑÑионных транзакций в байтах (по умолчанию: 27000) Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. - Âíèìàíèå: óñòàíîâëåíî î÷åíü áîëüøîå çíà÷åíèå -paytxfee. Ýòî êîìèññèÿ, êîòîðóþ âû çàïëàòèòå ïðè ïðîâåäåíèè òðàíçàêöèè. + Внимание: уÑтановлено очень большое значение -paytxfee. Это комиÑÑиÑ, которую вы заплатите при проведении транзакции. Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. - Âíèìàíèå: îòîáðàæàåìûå òðàíçàêöèè ìîãóò áûòü íåêîððåêòíû! Âàì èëè äðóãèì óçëàì, âîçìîæíî, ñëåäóåò îáíîâèòüñÿ. + Внимание: отображаемые транзакции могут быть некорректны! Вам или другим узлам, возможно, Ñледует обновитьÑÑ. Warning: Please check that your computer's date and time are correct! If your clock is wrong BottleCaps will not work properly. - Âíèìàíèå: óáåäèòåñü, ÷òî äàòà è âðåìÿ íà Âàøåì êîìïüþòåðå âûñòàâëåíû âåðíî. Åñëè Âàøè ÷àñû èäóò íåïðàâèëüíî, BottleCaps áóäåò ðàáîòàòü íåêîððåêòíî. + Внимание: убедитеÑÑŒ, что дата и Ð²Ñ€ÐµÐ¼Ñ Ð½Ð° Вашем компьютере выÑтавлены верно. ЕÑли Ваши чаÑÑ‹ идут неправильно, BottleCaps будет работать некорректно. Block creation options: - Ïàðàìåòðû ñîçäàíèÿ áëîêîâ: + Параметры ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¾Ð²: Connect only to the specified node(s) - Ïîäêëþ÷àòüñÿ òîëüêî ê óêàçàííîìó óçëó(àì) + ПодключатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ к указанному узлу(ам) Discover own IP address (default: 1 when listening and no -externalip) - Îïðåäåëèòü ñâîé IP (ïî óìîë÷àíèþ: 1 ïðè ïðîñëóøèâàíèè è åñëè íå èñïîëüçóåòñÿ -externalip) + Определить Ñвой IP (по умолчанию: 1 при проÑлушивании и еÑли не иÑпользуетÑÑ -externalip) Error: Transaction creation failed - Îøèáêà: Ñîçäàíèå òðàíçàêöèè íå óäàëîñü + Ошибка: Создание транзакции не удалоÑÑŒ Error: Wallet locked, unable to create transaction - Îøèáêà: áóìàæíèê çàáëîêèðîâàí, íåâîçìîæíî ñîçäàòü òðàíçàêöèþ + Ошибка: бумажник заблокирован, невозможно Ñоздать транзакцию Failed to listen on any port. Use -listen=0 if you want this. - Íå óäàëîñü íà÷àòü ïðîñëóøèâàíèå íà ïîðòó. Èñïîëüçóéòå -listen=0 åñëè âàñ ýòî óñòðàèâàåò. + Ðе удалоÑÑŒ начать проÑлушивание на порту. ИÑпользуйте -listen=0 еÑли Ð²Ð°Ñ Ñто уÑтраивает. Find peers using DNS lookup (default: 0 unless -connect) - Èñêàòü óçëû ñ ïîìîùüþ DNS (ïî óìîë÷àíèþ: 0) + ИÑкать узлы Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ DNS (по умолчанию: 0) Invalid -tor address: '%s' - Íåâåðíûé àäðåñ -tor: '%s' + Ðеверный Ð°Ð´Ñ€ÐµÑ -tor: '%s' Maximum per-connection receive buffer, <n>*1000 bytes (default: 5000) - Ìàêñèìàëüíûé ðàçìåð áóôåðà ïðè¸ìà íà ñîåäèíåíèå, <n>*1000 áàéò (ïî óìîë÷àíèþ: 5000) + МакÑимальный размер буфера приёма на Ñоединение, <n>*1000 байт (по умолчанию: 5000) Maximum per-connection send buffer, <n>*1000 bytes (default: 1000) - Ìàêñèìàëüíûé ðàçìåð áóôåðà îòïðàâêè íà ñîåäèíåíèå, <n>*1000 áàéò (ïî óìîë÷àíèþ: 1000) + МакÑимальный размер буфера отправки на Ñоединение, <n>*1000 байт (по умолчанию: 1000) Only connect to nodes in network <net> (IPv4, IPv6 or Tor) - Ïîäêëþ÷àòüñÿ òîëüêî ê óçëàì èç ñåòè <net> (IPv4, IPv6 èëè Tor) + ПодключатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ к узлам из Ñети <net> (IPv4, IPv6 или Tor) Output extra debugging information. Implies all other -debug* options - Âûâîäèòü áîëüøå îòëàäî÷íîé èíôîðìàöèè. Âêëþ÷àåò âñå îñòàëüíûå îïöèè -debug* + Выводить больше отладочной информации. Включает вÑе оÑтальные опции -debug* Output extra network debugging information - Âûâîäèòü äîïîëíèòåëüíóþ ñåòåâóþ îòëàäî÷íóþ èíôîðìàöèþ + Выводить дополнительную Ñетевую отладочную информацию Prepend debug output with timestamp - Äîïèñûâàòü îòìåòêè âðåìåíè ê îòëàäî÷íîìó âûâîäó + ДопиÑывать отметки времени к отладочному выводу SSL options: (see the Bitcoin Wiki for SSL setup instructions) -Ïàðàìåòðû SSL: (ñì. Bitcoin Wiki äëÿ èíñòðóêöèé ïî íàñòðîéêå SSL) +Параметры SSL: (Ñм. Bitcoin Wiki Ð´Ð»Ñ Ð¸Ð½Ñтрукций по наÑтройке SSL) Select the version of socks proxy to use (4-5, default: 5) - Âûáåðèòå âåðñèþ SOCKS-ïðîêñè (4-5, ïî óìîë÷àíèþ: 5) + Выберите верÑию SOCKS-прокÑи (4-5, по умолчанию: 5) Send trace/debug info to console instead of debug.log file - Âûâîäèòü èíôîðìàöèþ òðàññèðîâêè/îòëàäêè íà êîíñîëü âìåñòî ôàéëà debug.log + Выводить информацию траÑÑировки/отладки на конÑоль вмеÑто файла debug.log Send trace/debug info to debugger - Îòïðàâëÿòü èíôîðìàöèþ òðàññèðîâêè/îòëàäêè â îòëàä÷èê + ОтправлÑть информацию траÑÑировки/отладки в отладчик Set maximum block size in bytes (default: 250000) - Ìàêñèìàëüíûé ðàçìåð áëîêà â áàéòàõ (ïî óìîë÷àíèþ: 250000) + МакÑимальный размер блока в байтах (по умолчанию: 250000) Set minimum block size in bytes (default: 0) - Ìèíèìàëüíûé ðàçìåð áëîêà â áàéòàõ (ïî óìîë÷àíèþ: 0) + Минимальный размер блока в байтах (по умолчанию: 0) Shrink debug.log file on client startup (default: 1 when no -debug) - Ñæèìàòü ôàéë debug.log ïðè çàïóñêå êëèåíòà (ïî óìîë÷àíèþ: 1, åñëè íåò -debug) + Сжимать файл debug.log при запуÑке клиента (по умолчанию: 1, еÑли нет -debug) Specify connection timeout in milliseconds (default: 5000) - Òàéìàóò ñîåäèíåíèÿ â ìèëëèñåêóíäàõ (ïî óìîë÷àíèþ: 5000) + Таймаут ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð² миллиÑекундах (по умолчанию: 5000) Use UPnP to map the listening port (default: 0) - Èñïîëüçîâàòü UPnP äëÿ ïðîáðîñà ïîðòà (ïî óìîë÷àíèþ: 0) + ИÑпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 0) Use UPnP to map the listening port (default: 1 when listening) - Èñïîëüçîâàòü UPnP äëÿ ïðîáðîñà ïîðòà (ïî óìîë÷àíèþ: 1, åñëè èñïîëüçóåòñÿ ïðîñëóøèâàíèå) + ИÑпользовать UPnP Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð±Ñ€Ð¾Ñа порта (по умолчанию: 1, еÑли иÑпользуетÑÑ Ð¿Ñ€Ð¾Ñлушивание) Use proxy to reach tor hidden services (default: same as -proxy) - Èñïîëüçîâàòü ïðîêñè äëÿ ñêðûòûõ ñåðâèñîâ (ïî óìîë÷àíèþ: òîò æå, ÷òî è â -proxy) + ИÑпользовать прокÑи Ð´Ð»Ñ Ñкрытых ÑервиÑов (по умолчанию: тот же, что и в -proxy) Username for JSON-RPC connections - Èìÿ äëÿ ïîäêëþ÷åíèé JSON-RPC + Ð˜Ð¼Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC @@ -2464,12 +2464,12 @@ Address: %4 Warning: Disk space is low! - Âíèìàíèå: ìàëî ìåñòà íà äèñêå! + Внимание: мало меÑта на диÑке! Warning: This version is obsolete, upgrade required! - Âíèìàíèå: ýòà âåðñèÿ óñòàðåëà, òðåáóåòñÿ îáíîâëåíèå! + Внимание: Ñта верÑÐ¸Ñ ÑƒÑтарела, требуетÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ðµ! @@ -2479,82 +2479,82 @@ Address: %4 Password for JSON-RPC connections - Ïàðîëü äëÿ ïîäêëþ÷åíèé JSON-RPC + Пароль Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC Allow JSON-RPC connections from specified IP address - Ðàçðåøèòü ïîäêëþ÷åíèÿ JSON-RPC ñ óêàçàííîãî IP + Разрешить Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ JSON-RPC Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð¾Ð³Ð¾ IP Send commands to node running on <ip> (default: 127.0.0.1) - Ïîñûëàòü êîìàíäû óçëó, çàïóùåííîìó íà <ip> (ïî óìîë÷àíèþ: 127.0.0.1) + ПоÑылать команды узлу, запущенному на <ip> (по умолчанию: 127.0.0.1) Execute command when the best block changes (%s in cmd is replaced by block hash) - Âûïîëíèòü êîìàíäó, êîãäà ïîÿâëÿåòñÿ íîâûé áëîê (%s â êîìàíäå çàìåíÿåòñÿ íà õýø áëîêà) + Выполнить команду, когда поÑвлÑетÑÑ Ð½Ð¾Ð²Ñ‹Ð¹ блок (%s в команде заменÑетÑÑ Ð½Ð° Ñ…Ñш блока) Upgrade wallet to latest format - Îáíîâèòü áóìàæíèê äî ïîñëåäíåãî ôîðìàòà + Обновить бумажник до поÑледнего формата Set key pool size to <n> (default: 100) - Óñòàíîâèòü ðàçìåð çàïàñà êëþ÷åé â <n> (ïî óìîë÷àíèþ: 100) + УÑтановить размер запаÑа ключей в <n> (по умолчанию: 100) Rescan the block chain for missing wallet transactions - Ïåðåïðîâåðèòü öåïü áëîêîâ íà ïðåäìåò îòñóòñòâóþùèõ â áóìàæíèêå òðàíçàêöèé + Перепроверить цепь блоков на предмет отÑутÑтвующих в бумажнике транзакций How many blocks to check at startup (default: 2500, 0 = all) - Ñêîëüêî áëîêîâ ïðîâåðÿòü ïðè çàïóñêå (ïî óìîë÷àíèþ: 2500, 0 = âñå) + Сколько блоков проверÑть при запуÑке (по умолчанию: 2500, 0 = вÑе) How thorough the block verification is (0-6, default: 1) - Íàñêîëüêî òùàòåëüíî ïðîâåðÿòü áëîêè (0-6, ïî óìîë÷àíèþ: 1) + ÐаÑколько тщательно проверÑть блоки (0-6, по умолчанию: 1) Imports blocks from external blk000?.dat file - Èìïîðòèðîâàòü áëîêè èç âíåøíåãî ôàéëà blk000?.dat + Импортировать блоки из внешнего файла blk000?.dat Use OpenSSL (https) for JSON-RPC connections - Èñïîëüçîâàòü OpenSSL (https) äëÿ ïîäêëþ÷åíèé JSON-RPC + ИÑпользовать OpenSSL (https) Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ JSON-RPC Server certificate file (default: server.cert) - Ôàéë ñåðâåðíîãî ñåðòèôèêàòà (ïî óìîë÷àíèþ: server.cert) + Файл Ñерверного Ñертификата (по умолчанию: server.cert) Server private key (default: server.pem) - Ïðèâàòíûé êëþ÷ ñåðâåðà (ïî óìîë÷àíèþ: server.pem) + Приватный ключ Ñервера (по умолчанию: server.pem) Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) - Ðàçðåø¸ííûå àëãîðèòìû (ïî óìîë÷àíèþ: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) + Разрешённые алгоритмы (по умолчанию: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH) This help message - Ýòà ñïðàâêà + Эта Ñправка Cannot obtain a lock on data directory %s. BottleCaps is probably already running. - Íåâîçìîæíî óñòàíîâèòü áëîêèðîâêó íà ðàáî÷óþ äèðåêòîðèþ %s. Âîçìîæíî, áóìàæíèê óæå çàïóùåí. + Ðевозможно уÑтановить блокировку на рабочую директорию %s. Возможно, бумажник уже запущен. @@ -2564,157 +2564,157 @@ Address: %4 Unable to bind to %s on this computer (bind returned error %d, %s) - Íåâîçìîæíî ïðèâÿçàòüñÿ ê %s íà ýòîì êîìïüþòåðå (bind âåðíóë îøèáêó %d, %s) + Ðевозможно привÑзатьÑÑ Ðº %s на Ñтом компьютере (bind вернул ошибку %d, %s) Connect through socks proxy - Ïîäêëþ÷àòüñÿ ÷åðåç socks ïðîêñè + ПодключатьÑÑ Ñ‡ÐµÑ€ÐµÐ· socks прокÑи Allow DNS lookups for -addnode, -seednode and -connect - Ðàçðåøèòü ïîèñê â DNS äëÿ -addnode, -seednode è -connect + Разрешить поиÑк в DNS Ð´Ð»Ñ -addnode, -seednode и -connect Loading addresses... - Çàãðóçêà àäðåñîâ... + Загрузка адреÑов... Error loading blkindex.dat - Îøèáêà ÷òåíèÿ blkindex.dat + Ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ blkindex.dat Error loading wallet.dat: Wallet corrupted - Îøèáêà çàãðóçêè wallet.dat: Áóìàæíèê ïîâðåæäåí + Ошибка загрузки wallet.dat: Бумажник поврежден Error loading wallet.dat: Wallet requires newer version of BottleCaps - Îøèáêà çàãðóçêè wallet.dat: áóìàæíèê òðåáóåò áîëåå íîâóþ âåðñèþ BottleCaps + Ошибка загрузки wallet.dat: бумажник требует более новую верÑию BottleCaps Wallet needed to be rewritten: restart BottleCaps to complete - Íåîáõîäèìî ïåðåçàïèñàòü áóìàæíèê, ïåðåçàïóñòèòå BottleCaps äëÿ çàâåðøåíèÿ îïåðàöèè. + Ðеобходимо перезапиÑать бумажник, перезапуÑтите BottleCaps Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸. Error loading wallet.dat - Îøèáêà ïðè çàãðóçêå wallet.dat + Ошибка при загрузке wallet.dat Invalid -proxy address: '%s' - Íåâåðíûé àäðåñ -proxy: '%s' + Ðеверный Ð°Ð´Ñ€ÐµÑ -proxy: '%s' Unknown network specified in -onlynet: '%s' -  ïàðàìåòðå -onlynet óêàçàíà íåèçâåñòíàÿ ñåòü: '%s' + Ð’ параметре -onlynet указана неизвеÑÑ‚Ð½Ð°Ñ Ñеть: '%s' Unknown -socks proxy version requested: %i -  ïàðàìåòðå -socks çàïðîøåíà íåèçâåñòíàÿ âåðñèÿ: %i + Ð’ параметре -socks запрошена неизвеÑÑ‚Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ: %i Cannot resolve -bind address: '%s' - Íå óäà¸òñÿ ðàçðåøèòü àäðåñ â ïàðàìåòðå -bind: '%s' + Ðе удаётÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð°Ð´Ñ€ÐµÑ Ð² параметре -bind: '%s' Cannot resolve -externalip address: '%s' - Íå óäà¸òñÿ ðàçðåøèòü àäðåñ â ïàðàìåòðå -externalip: '%s' + Ðе удаётÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐ¸Ñ‚ÑŒ Ð°Ð´Ñ€ÐµÑ Ð² параметре -externalip: '%s' Invalid amount for -paytxfee=<amount>: '%s' - Íåâåðíîå êîëè÷åñòâî â ïàðàìåòðå -paytxfee=<êîë-âî>: '%s' + Ðеверное количеÑтво в параметре -paytxfee=<кол-во>: '%s' Error: could not start node - Îøèáêà: íå óäàëîñü çàïóñòèòü óçåë + Ошибка: не удалоÑÑŒ запуÑтить узел Sending... - Îòïðàâêà... + Отправка... Invalid amount - Íåâåðíîå êîëè÷åñòâî + Ðеверное количеÑтво Insufficient funds - Íåäîñòàòî÷íî ìîíåò + ÐедоÑтаточно монет Loading block index... - Çàãðóçêà èíäåêñà áëîêîâ... + Загрузка индекÑа блоков... Add a node to connect to and attempt to keep the connection open - Äîáàâèòü óçåë äëÿ ïîäêëþ÷åíèÿ è ïûòàòüñÿ ïîääåðæèâàòü ñîåäèíåíèå îòêðûòûì + Добавить узел Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ пытатьÑÑ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ‚ÑŒ Ñоединение открытым Unable to bind to %s on this computer. BottleCaps is probably already running. - Íåâîçìîæíî ïðèâÿçàòüñÿ ê %s íà ýòîì êîìïüþòåðå. Âîçìîæíî, BottleCaps óæå ðàáîòàåò. + Ðевозможно привÑзатьÑÑ Ðº %s на Ñтом компьютере. Возможно, BottleCaps уже работает. Find peers using internet relay chat (default: 1) - Íàéòè ó÷àñòíèêîâ ÷åðåç IRC (ïî óìîë÷àíèþ: 1) + Ðайти учаÑтников через IRC (по умолчанию: 1) Fee per KB to add to transactions you send - Êîìèññèÿ íà êèëîáàéò, äîáàâëÿåìàÿ ê âàøèì òðàíçàêöèÿì + КомиÑÑÐ¸Ñ Ð½Ð° килобайт, добавлÑÐµÐ¼Ð°Ñ Ðº вашим транзакциÑм Loading wallet... - Çàãðóçêà áóìàæíèêà... + Загрузка бумажника... Cannot downgrade wallet - Íå óäà¸òñÿ ïîíèçèòü âåðñèþ áóìàæíèêà + Ðе удаётÑÑ Ð¿Ð¾Ð½Ð¸Ð·Ð¸Ñ‚ÑŒ верÑию бумажника Cannot initialize keypool - Íå óäà¸òñÿ èíèöèàëèçèðîâàòü ìàññèâ êëþ÷åé + Ðе удаётÑÑ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ маÑÑив ключей Cannot write default address - Íå óäà¸òñÿ çàïèñàòü àäðåñ ïî óìîë÷àíèþ + Ðе удаётÑÑ Ð·Ð°Ð¿Ð¸Ñать Ð°Ð´Ñ€ÐµÑ Ð¿Ð¾ умолчанию Rescanning... - Ñêàíèðîâàíèå... + Сканирование... Done loading - Çàãðóçêà çàâåðøåíà + Загрузка завершена To use the %s option - ×òîáû èñïîëüçîâàòü îïöèþ %s + Чтобы иÑпользовать опцию %s @@ -2726,28 +2726,28 @@ rpcpassword=%s (you do not need to remember this password) If the file does not exist, create it with owner-readable-only file permissions. - %s, âû äîëæíû óñòàíîâèòü îïöèþ rpcpassword â êîíôèãóðàöèîííîì ôàéëå: + %s, вы должны уÑтановить опцию rpcpassword в конфигурационном файле: %s -Ðåêîìåíäóåòñÿ èñïîëüçîâàòü ñëåäóþùèé ñëó÷àéíûé ïàðîëü: +РекомендуетÑÑ Ð¸Ñпользовать Ñледующий Ñлучайный пароль: rpcuser=bitcoinrpc rpcpassword=%s -(âàì íå íóæíî çàïîìèíàòü ýòîò ïàðîëü) -Åñëè ôàéë íå ñóùåñòâóåò, ñîçäàéòå åãî è óñòàíîâèòå ïðàâà äîñòóïà òîëüêî äëÿ âëàäåëüöà. +(вам не нужно запоминать Ñтот пароль) +ЕÑли файл не ÑущеÑтвует, Ñоздайте его и уÑтановите права доÑтупа только Ð´Ð»Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð°. Error - Îøèáêà + Ошибка You must set rpcpassword=<password> in the configuration file: %s If the file does not exist, create it with owner-readable-only file permissions. - Âû äîëæíû óñòàíîâèòü rpcpassword=<password> â êîíôèãóðàöèîííîì ôàéëå: + Ð’Ñ‹ должны уÑтановить rpcpassword=<password> в конфигурационном файле: %s -Åñëè ôàéë íå ñóùåñòâóåò, ñîçäàéòå åãî è óñòàíîâèòå ïðàâà äîñòóïà òîëüêî äëÿ âëàäåëüöà. +ЕÑли файл не ÑущеÑтвует, Ñоздайте его и уÑтановите права доÑтупа только Ð´Ð»Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð°. From ddeade94c2a76780ad0123355f4dd5f07df75360 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 16:10:38 +0300 Subject: [PATCH 024/218] Update version number. --- src/clientversion.h | 2 +- src/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index e8f708b..1725bce 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 2 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_BUILD 1 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/version.h b/src/version.h index 28a13f6..60a0650 100644 --- a/src/version.h +++ b/src/version.h @@ -47,6 +47,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 2 -#define DISPLAY_VERSION_BUILD 0 +#define DISPLAY_VERSION_BUILD 1 #endif From a03b92e819c387e4db4bc52ddb80e641265298e3 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 17:29:05 +0300 Subject: [PATCH 025/218] Properly calculate totalCoin in LoadBlockIndex() --- src/db.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/db.cpp b/src/db.cpp index f2f9a3c..ed9ffdb 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -704,6 +704,8 @@ bool CTxDB::LoadBlockIndex() map, CBlockIndex*> mapBlockPos; for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) { + // calculate totalCoin for other routines that get called + totalCoin = pindex->nMoneySupply / COIN; if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; @@ -711,7 +713,7 @@ bool CTxDB::LoadBlockIndex() return error("LoadBlockIndex() : block.ReadFromDisk failed"); // check level 1: verify block validity // DK properly pass totalCoin - if (nCheckLevel>0 && !block.CheckBlock(true, true, pindex->nMoneySupply / COIN)) + if (nCheckLevel>0 && !block.CheckBlock(true, true, totalCoin)) { printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str()); pindexFork = pindex->pprev; From a3e0f3efa3dc7f8c782e49ee3781abb4ab267fc1 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 12 Jun 2014 18:54:14 +0300 Subject: [PATCH 026/218] Wallet background image. --- src/qt/res/images/diamond.png | Bin 0 -> 110396 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/qt/res/images/diamond.png diff --git a/src/qt/res/images/diamond.png b/src/qt/res/images/diamond.png new file mode 100644 index 0000000000000000000000000000000000000000..882d645a3aa1ed38e63e611f1903edccf3db3338 GIT binary patch literal 110396 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 N002ovPDHLkV1haeX} Date: Thu, 12 Jun 2014 23:45:09 +0300 Subject: [PATCH 027/218] Add new checkpoint and update splash screen with new url. --- src/checkpoints.cpp | 1 + src/qt/res/images/diamond-splash.jpg | Bin 25117 -> 70938 bytes 2 files changed, 1 insertion(+) diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index fa9d3c1..3111c0e 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -36,6 +36,7 @@ namespace Checkpoints (317997, uint256("0x000000007458dc82830320e592b9e0585efa68d01c3de479c14843af4942528e")) (386222, uint256("0x000006a8c97fcba6e69278f2c5e21c2266ed12ecea07045e9214cb23f3d5eeaa")) (386232, uint256("0x000004bf5ce28d4bf81a7f993de4443d5a5b2bd3290e7935f3096e5b7c40fe36")) + (443923, uint256("0x0000000001f9b10759fa67418e4c20a772ec39c3eff33742cb5899c7b50d7348")) ; diff --git a/src/qt/res/images/diamond-splash.jpg b/src/qt/res/images/diamond-splash.jpg index 584c10aa4a56c8279ea9534fd59bbaad7cf5769f..6d02745872d13290dde18c886fc50039ddc0824d 100644 GIT binary patch literal 70938 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 Date: Tue, 17 Jun 2014 16:10:15 +0300 Subject: [PATCH 028/218] File rename, cruft removal. --- .../{bitcoin_testnet.png => Diamond_testnet.png} | Bin src/qt/res/icons/New folder/mining.png | Bin 2435 -> 0 bytes src/qt/res/icons/New folder/mining_active.png | Bin 1240 -> 0 bytes src/qt/res/icons/New folder/mining_inactive.png | Bin 1241 -> 0 bytes 4 files changed, 0 insertions(+), 0 deletions(-) rename src/qt/res/icons/{bitcoin_testnet.png => Diamond_testnet.png} (100%) delete mode 100644 src/qt/res/icons/New folder/mining.png delete mode 100644 src/qt/res/icons/New folder/mining_active.png delete mode 100644 src/qt/res/icons/New folder/mining_inactive.png diff --git a/src/qt/res/icons/bitcoin_testnet.png b/src/qt/res/icons/Diamond_testnet.png similarity index 100% rename from src/qt/res/icons/bitcoin_testnet.png rename to src/qt/res/icons/Diamond_testnet.png diff --git a/src/qt/res/icons/New folder/mining.png b/src/qt/res/icons/New folder/mining.png deleted file mode 100644 index e1c4ebc8a687aacfdd3c81f6927754d2a833e902..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2435 zcmbVOdpK0<8lT)^Xm3Rm+G$KFiJ3KbGnr&&+>PX}i;S7Y3})7tSs0g!t#XOv5sFhp zB~Q{l*|JU4j$NVTk{umUl87X_IL=I^bN=Y;KhAodwZ8BDzW4Wg@6WT+Jw2QjAx)47 z1Y(hkGuunKqE)Z9mhvl$kAJ6JjA4fW*c%FkW4TfgVb6y`K(vd98wPrTTz*_sGiZxI zsD}!D0^k6SJDmrKuw0c6RxXk#(FlaCom|4@MSw6m1Pl|38JIV<^%%5}&%pSTIRHn( z0tG_ncq!-|@8QFXkKobx7`u&VTRB}xAOc}7S}uwd%jj|j<_j-fxmO+IFz7ETa0CPM z)u{lECz=IGK{Oc)Sn~i1fTrNFcp`~PrCOm003N^r1RS1Vji=Iy1UdkqzdabGH7P%o z?!|WeW=knCFaj8s&~dof*jQ{V5erGfaCjPxrs5zFtd$zpvN$o!m0OEttL7Qlpo}LK zN?;)*MynXPAy72Tz$iWa8iGi|;e00+%f2N_nKGQ5E5YHh08S)Q#q~v7277`3apQ;D zGM_jJi1PwvP_&e%tVigod9X5fe{V>osPu-uSt?W(g&WC+c+nzI47;!y808I?FXYn! znhk)*Q%L}o08ni3cpBB7%x1EPOfrE)Bv6R+96!R6Sa`sJ|wEGQ9{#z`aB?Y-KB=v!y$oUTN6hJT}6F?F)%bSem zaCt(pN>-KUYqV@oDvSa7j#5a3{*qt1@CWwUOh={-mB}I#{#V>zvHbrhXE>!ZI8}4} zSF_9?DLYWL{oeXY;rsA_V&%k0m7`(3)EtFCXkK<<+xy6S2K`4NZ(pOisoCg}zdow1 z*tdvcq+Vceh;ndl6RtMH-#jvtbt^k@Ja+=;$#d6xaA^Ggkt1hxFamc&ohU2Uy*cBQ z;LQB!q8&RsAM{mK*NNUt(aLe~>zJbCriGiO(w>CYxZ_VhFzSbBL*a%F$y?h6BzX_# zegUfWIzxu|=!c^R#f#T3N<9PZLhk;fqWF|)AS(Rob@}w7U&{J(`(_iYVv0Yd*Xd3e zj%95}4G(>4KG5}hz+wc=?nYJp(7l7Kg>7SRJiV7#o^l;I^6F}vpumaZhOU|&U%td3 zhpQIlLDm@D?$kKc%SsVU#+Nj?-CTD`PyIvR$Y}Ucb80)W>9E_~O+dmu>;fD6JqcTd z!3hb92vP(N)McXj!b~+8zDR{5+kt@q} z1G}#{>di1;#>jJi)=s;{n~|Ai)YX2Jyt?W8%lLG#qBs4d#U_iT`psT_<)w#~fmNFASaah7EwlAm0p6*0WqNO8ISaa3O2uBh>eic)wt2`~nb9C-M7*ia0F=Z1qq86kZnR2a^)OWe1@NQ)4 z(>s1s3*0BLN(Q{*ss-@zn_dCoRwr`t~haDKK)Pb@3qY}#)r?$xVLc1+}|`#1a`Zl zG#EiM=XUFjKG7`i_^G(@wkXk7ij_)MJ+x&f_t=~_1b`%@y zX^n+gB`%{@1u3HGRQUDd`Ui+`#Fff-g_$;#L=Bo{&Dz#uf82U)NRfYD?W#^^Yzz_@ z9lEsLocVc(}axhAu@o77_+Qz`R@HrrP(qg+149lP__9^X-6r(cG{i!0a$WL~hJ4%And!Wj(; zTEIG?-&xyq^sMWyonijGC`^uGHa)?1?wsHH&&h}v`}D$mD)5TeTimXx0oaodLn#v>O3D-GUQHKAfzMDe&=|`CweN8-^FpIjS;ZlxGCdJhV6fQg z)k`Dl%ee8|nMsL`&bh@d9d7H0?5>IIUuPLB;Wx&W`Mez02<*?o9IUC2&g1kumPO2i zk9(%rHJ|`Yy5r8luKL4|5El%dM?kSJ z)53WAlxl-DXODW^a`on%N9LUe`#XH0hS%2`=?j^)q3@9m80n<0v*T&J9r=?v&93Kj z#WlT6?WxThNH<(|QKzcb&R7M**<0rF|53dA^R|oTNpqzYy%}?RR+i6c0|+bgcgtvA{Pe_b`>-D*M9@SS?#v~ diff --git a/src/qt/res/icons/New folder/mining_active.png b/src/qt/res/icons/New folder/mining_active.png deleted file mode 100644 index 8be87663f040d19e7df5c9e711f9a66f4ef4585e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1240 zcmbVMO=uid9Dkdb77ShZ0Ja1O*R0luD3l5h@534=sX+5+xcGK`F*JNj7?jJvcD) z-v7P-@AvTETM{SCWxPJ+$5l` zC5RJTmde^`RMm%P95gmFT2N=kRY4<;4#0k2!~_QN6zCfhrYrghVw+dQ`{0-);I@i4 zo*;IdDrR#qZ8->XF)FH3JrwMrV|1M5dHx7wD4HTEhNPJ&&5LnHq$s%i5ZIcdmBqX~ zv}+4X38LzGwn&n-S}j(K$1JBp(t;oa91Ii18c}!J^b|j8x`!JKGICW%w>{l5VZf-A ztSK)+U{7~KFzjr0kJxl~6NOVo`if1`F^V*dAg*m~*UO`S+}Ky!Elk^p%p=#Da#UQ8 z^5F&;=kD=_0!8eN_==7>rC3hlS)QSKdTCnVB~DJI z<0+0|<4jMy!Lc8fVkAD!a*V|CgET!DPYFZ3z_A>~u#_B^*akLZx}IXHs9{&fc6YJ# zW3gh|L5gQN1_jUgM?a0UA;&V{c78>DANw*p zl$2R~7wPj?f z;D1;8}+zr?ZO>&i#3!<;#2XCs(=`{+KNSp-Wm^9RB6AV?R)r+SYCk-+k15?a7V# zJIU+ewb5K%&S-ahmpBwv_q5hEvWZ@g8y5=y=q Y0_PqITLaYkQt+?I435elrB2QL4M5(NvH$=8 diff --git a/src/qt/res/icons/New folder/mining_inactive.png b/src/qt/res/icons/New folder/mining_inactive.png deleted file mode 100644 index cee171fc42e9729b9725bc038ef25a31b263af79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1241 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+nA0*tB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsdd8d(^a zm^zx9m>U_GSr{5xnmd}hI5`_TnHrfG8<`oy%)qACz{t_u*u>P#(Zt-<(9qS`$47>X1ny~G| h;4)XH+u;q23>(U=rdvLZcmyhJJYD@<);T3K0RWReqF?|3 From ea5ff91c402e6c624900dca8105dd5a8ef221667 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 17 Jun 2014 16:10:57 +0300 Subject: [PATCH 029/218] Changes required to make Diamond compile on OS X Mavericks. --- diamond.pro | 10 ++++++++-- doc/readme-qt.rst | 10 +++++----- src/makefile.osx | 29 ++++++++++++++++++++--------- src/net.cpp | 2 +- src/qt/bitcoin.qrc | 2 +- src/qt/bitcoingui.cpp | 6 +++--- src/qt/macdockiconhandler.h | 5 ++++- src/qt/macdockiconhandler.mm | 12 +++++++++++- src/qt/notificator.cpp | 4 ++++ src/qt/res/icons/Diamond.icns | Bin 154369 -> 295464 bytes src/scrypt-x86.S | 6 +++--- src/scrypt-x86_64.S | 14 +++++++------- src/serialize.h | 13 ------------- 13 files changed, 67 insertions(+), 46 deletions(-) diff --git a/diamond.pro b/diamond.pro index 1151343..b96c0e2 100644 --- a/diamond.pro +++ b/diamond.pro @@ -33,10 +33,16 @@ RELEASE=1 CONFIG += static } +# OS X Mavericks 10.9 build +macx:QMAKE_MAC_SDK = macosx10.9 +macx:QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9 +macx:USE_QRCODE=1 + # use: qmake "RELEASE=1" contains(RELEASE, 1) { # Mac: compile for maximum compatibility (10.5, 32-bit) - macx:QMAKE_CXXFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk +# macx:QMAKE_CXXFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk + !windows:!macx { # Linux: static link @@ -378,7 +384,7 @@ macx:HEADERS += src/qt/macdockiconhandler.h macx:OBJECTIVE_SOURCES += src/qt/macdockiconhandler.mm macx:LIBS += -framework Foundation -framework ApplicationServices -framework AppKit macx:DEFINES += MAC_OSX MSG_NOSIGNAL=0 -macx:ICON = src/qt/res/icons/bitcoin.icns +macx:ICON = src/qt/res/icons/Diamond.icns macx:TARGET = "diamond-qt" macx:QMAKE_CFLAGS_THREAD += -pthread macx:QMAKE_LFLAGS_THREAD += -pthread diff --git a/doc/readme-qt.rst b/doc/readme-qt.rst index 294f31a..71adaf5 100644 --- a/doc/readme-qt.rst +++ b/doc/readme-qt.rst @@ -1,4 +1,4 @@ -Bitcoin-qt: Qt4 GUI for Bitcoin +Diamond-qt: Qt5 GUI for Diamond =============================== Build instructions @@ -23,9 +23,9 @@ then execute the following: qmake make -Alternatively, install Qt Creator and open the `bitcoin-qt.pro` file. +Alternatively, install Qt Creator and open the `diamond-qt.pro` file. -An executable named `bitcoin-qt` will be built. +An executable named `diamond-qt` will be built. Windows @@ -59,7 +59,7 @@ Mac OS X :: sudo port selfupdate - sudo port install boost db48 miniupnpc + sudo port install boost db48 miniupnpc qrencode - Open the .pro file in Qt Creator and build as normal (cmd-B) @@ -138,7 +138,7 @@ Ubuntu 11.10 warning ==================== Ubuntu 11.10 has a package called 'qt-at-spi' installed by default. At the time of writing, having that package -installed causes bitcoin-qt to crash intermittently. The issue has been reported as `launchpad bug 857790`_, but +installed causes Diamond-qt to crash intermittently. The issue has been reported as `launchpad bug 857790`_, but isn't yet fixed. Until the bug is fixed, you can remove the qt-at-spi package to work around the problem, though this will presumably diff --git a/src/makefile.osx b/src/makefile.osx index 7e66fec..31458d8 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -6,7 +6,7 @@ # Mac OS X makefile for bitcoin # Originally by Laszlo Hanyecz (solar@heliacal.net) -CXX=llvm-g++ +CXX=clang++ DEPSDIR=/opt/local INCLUDEPATHS= \ @@ -59,14 +59,15 @@ DEFS=-DMAC_OSX -DMSG_NOSIGNAL=0 -DBOOST_SPIRIT_THREADSAFE ifdef RELEASE # Compile for maximum compatibility and smallest size. # This requires that dependencies are compiled -# the same way. -CFLAGS = -mmacosx-version-min=10.5 -arch x86_64 -O3 -msse2 +# the same way. Use this if you build on pre-Mavericks system +#xCXXFLAGS = -mmacosx-version-min=10.5 -arch x86_64 -O3 -msse2 +xCXXFLAGS = -O3 -msse2 else -CFLAGS = -g -msse2 +xCXXFLAGS = -g -msse2 endif # ppc doesn't work because we don't support big-endian -CFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ +xCXXFLAGS += -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) OBJS= \ @@ -98,6 +99,8 @@ OBJS= \ obj/walletdb.o \ obj/noui.o \ obj/pbkdf2.o \ + obj/hash.o \ + obj/groestl.o \ obj/kernel.o \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ @@ -134,12 +137,20 @@ version.cpp: obj/build.h DEFS += -DHAVE_BUILD_INFO obj/%.o: %.cpp - $(CXX) -c $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< @cp $(@:%.o=%.d) $(@:%.o=%.P); \ sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ rm -f $(@:%.o=%.d) +obj/%.o: %.c + $(CC) -c $(xCXXFLAGS) -fpermissive -MMD -MF $(@:%.o=%.d) -o $@ $< + @cp $(@:%.o=%.d) $(@:%.o=%.P); \ + sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ + -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ + rm -f $(@:%.o=%.d) + + obj/scrypt-x86.o: scrypt-x86.S $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< @@ -147,19 +158,19 @@ obj/scrypt-x86_64.o: scrypt-x86_64.S $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< diamondd: $(OBJS:obj/%=obj/%) - $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) obj-test/%.o: test/%.cpp - $(CXX) -c $(TESTDEFS) $(CFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< + $(CXX) -c $(TESTDEFS) $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< @cp $(@:%.o=%.d) $(@:%.o=%.P); \ sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ rm -f $(@:%.o=%.d) test_diamond: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS) + $(CXX) $(xCXXFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) $(TESTLIBS) clean: -rm -f diamondd test_diamond diff --git a/src/net.cpp b/src/net.cpp index c8a32ab..1cd181f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -57,7 +57,7 @@ static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; CAddress addrSeenByPeer(CService("0.0.0.0", 0), nLocalServices); uint64 nLocalHostNonce = 0; -array vnThreadsRunning; +boost::array vnThreadsRunning; static std::vector vhListenSocket; CAddrMan addrman; diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 7f811f1..523c770 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -22,7 +22,7 @@ res/icons/editpaste.png res/icons/editcopy.png res/icons/add.png - res/icons/Diamond-128.png + res/icons/Diamond-128.png res/icons/Diamond-16.png res/icons/edit.png res/icons/history.png diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index f4e1e75..5b5911b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -344,10 +344,10 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) { setWindowTitle(windowTitle() + QString(" ") + tr("[testnet]")); #ifndef Q_OS_MAC - qApp->setWindowIcon(QIcon(":icons/bitcoin_testnet")); - setWindowIcon(QIcon(":icons/bitcoin_testnet")); + qApp->setWindowIcon(QIcon(":icons/Diamond_testnet")); + setWindowIcon(QIcon(":icons/Diamond_testnet")); #else - MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet")); + MacDockIconHandler::instance()->setIcon(QIcon(":icons/Diamond_testnet")); #endif if(trayIcon) { diff --git a/src/qt/macdockiconhandler.h b/src/qt/macdockiconhandler.h index 2092fb2..08a8110 100644 --- a/src/qt/macdockiconhandler.h +++ b/src/qt/macdockiconhandler.h @@ -1,7 +1,8 @@ #ifndef MACDOCKICONHANDLER_H #define MACDOCKICONHANDLER_H -#include +#include +#include class QMenu; class QIcon; @@ -24,6 +25,7 @@ class MacDockIconHandler : public QObject QMenu *dockMenu(); void setIcon(const QIcon &icon); + void setMainWindow(QMainWindow *window); static MacDockIconHandler *instance(); void handleDockIconClickEvent(); @@ -39,6 +41,7 @@ public slots: DockIconClickEventHandler *m_dockIconClickEventHandler; QWidget *m_dummyWidget; QMenu *m_dockMenu; + QMainWindow *mainWindow; }; #endif // MACDOCKICONCLICKHANDLER_H diff --git a/src/qt/macdockiconhandler.mm b/src/qt/macdockiconhandler.mm index 6d1cd64..0c3ee5f 100644 --- a/src/qt/macdockiconhandler.mm +++ b/src/qt/macdockiconhandler.mm @@ -4,7 +4,6 @@ #include #include -//extern void qt_mac_set_dock_menu(QMenu*); #include #include @@ -53,13 +52,19 @@ - (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAp this->m_dummyWidget = new QWidget(); this->m_dockMenu = new QMenu(this->m_dummyWidget); + this->setMainWindow(NULL); [pool release]; } +void MacDockIconHandler::setMainWindow(QMainWindow *window) { + this->mainWindow = window; +} + MacDockIconHandler::~MacDockIconHandler() { [this->m_dockIconClickEventHandler release]; delete this->m_dummyWidget; + this->setMainWindow(NULL); } QMenu *MacDockIconHandler::dockMenu() @@ -109,5 +114,10 @@ - (void)handleDockClickEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAp void MacDockIconHandler::handleDockIconClickEvent() { + if (this->mainWindow) + { + this->mainWindow->activateWindow(); + this->mainWindow->show(); + } emit this->dockIconClicked(); } diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 8028190..3a92be0 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -18,8 +18,10 @@ #ifdef Q_OS_MAC #include +#if QT_VERSION < 0x050000 extern bool qt_mac_execute_apple_script(const QString &script, AEDesc *ret); #endif +#endif // https://wiki.ubuntu.com/NotificationDevelopmentGuidelines recommends at least 128 const int FREEDESKTOP_NOTIFICATION_ICON_SIZE = 128; @@ -269,7 +271,9 @@ void Notificator::notifyGrowl(Class cls, const QString &title, const QString &te quotedTitle.replace("\\", "\\\\").replace("\"", "\\"); quotedText.replace("\\", "\\\\").replace("\"", "\\"); QString growlApp(this->mode == Notificator::Growl13 ? "Growl" : "GrowlHelperApp"); +#if QT_VERSION < 0x050000 qt_mac_execute_apple_script(script.arg(notificationApp, quotedTitle, quotedText, notificationIcon, growlApp), 0); +#endif } #endif diff --git a/src/qt/res/icons/Diamond.icns b/src/qt/res/icons/Diamond.icns index 83a5c43105f7b66d26ee9953ef11a097d48fe39e..71d5376f2a432d6a81e6f9059ff9c6107462f369 100644 GIT binary patch literal 295464 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 z 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 literal 154369 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

Xwk}K81 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 nNRXs?L$|XHCAS9= 0); - if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) - { - // special case for inserting at the front when there's room - nReadPos -= (last - first); - memcpy(&vch[nReadPos], &first[0], last - first); - } - else - vch.insert(it, first, last); - } - void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) { assert(last - first >= 0); From 527a1d0b64687f0517aa20484d80a4d3ac2a9de2 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 30 Jun 2014 13:05:52 +0300 Subject: [PATCH 030/218] Disconnect old versions that do not properly support PoS and coin mechanics. --- src/main.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 042d6dc..4ab18f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3025,6 +3025,21 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } + + // Diamond: disconnect any known version prior 2.0.2.1 + // as these have PoS not working and could serve us garbage + if (fDebug) printf("connected subver %s\n", pfrom->strSubVer.c_str()); + if (!strcmp(pfrom->strSubVer.c_str(),"/Diamond:2.0.1/") + || !strcmp(pfrom->strSubVer.c_str(),"/Diamond:0.7.2/") + || !strcmp(pfrom->strSubVer.c_str(),"/Satoshi:0.7.2/") + || !strcmp(pfrom->strSubVer.c_str(),"") + ) + { + printf("partner %s using obsolete client %s\n", pfrom->addr.ToString().c_str(), pfrom->strSubVer.c_str()); + pfrom->fDisconnect = true; + return false; + } + // ppcoin: record my external IP reported by peer if (addrFrom.IsRoutable() && addrMe.IsRoutable()) addrSeenByPeer = addrMe; From 5118adadf17818ae62a703bdcd7a890ee9ec2e5b Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 30 Jun 2014 13:06:22 +0300 Subject: [PATCH 031/218] New checkpoint post-PoS activation. --- src/checkpoints.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 3111c0e..3e5c5f4 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -37,6 +37,7 @@ namespace Checkpoints (386222, uint256("0x000006a8c97fcba6e69278f2c5e21c2266ed12ecea07045e9214cb23f3d5eeaa")) (386232, uint256("0x000004bf5ce28d4bf81a7f993de4443d5a5b2bd3290e7935f3096e5b7c40fe36")) (443923, uint256("0x0000000001f9b10759fa67418e4c20a772ec39c3eff33742cb5899c7b50d7348")) + (468356, uint256("0x000000000543a19eaf97aa0ad933cb6423dedacb09786f4891126ac02bd8b7d4")) ; From 13e35601d308cb81c9a4b624ad57409329e384f5 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 30 Jun 2014 13:06:39 +0300 Subject: [PATCH 032/218] Version bump to 2.0.2.2 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 60a0650..d3a5437 100644 --- a/src/version.h +++ b/src/version.h @@ -47,6 +47,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 2 -#define DISPLAY_VERSION_BUILD 1 +#define DISPLAY_VERSION_BUILD 2 #endif From 40fb83924464ebc6927c11efcbf1cb3b6d21bd40 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 2 Jul 2014 13:42:20 +0300 Subject: [PATCH 033/218] Fix more Diamond/DiamondCoin and diamond/bitcoin references. --- src/bitcoinrpc.cpp | 2 +- src/init.cpp | 36 ++++++++++++++++++------------------ src/main.cpp | 21 ++++++++++----------- src/main.h | 2 +- src/qt/bitcoinstrings.cpp | 4 ++-- src/qt/forms/aboutdialog.ui | 4 ++-- src/qt/locale/bitcoin_en.ts | 4 ++-- src/qt/locale/bitcoin_ru.ts | 4 ++-- src/rpcmining.cpp | 12 ++++++------ 9 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 647236b..6db70f1 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -742,7 +742,7 @@ void ThreadRPCServer2(void* parg) uiInterface.ThreadSafeMessageBox(strprintf( _("%s, you must set a rpcpassword in the configuration file:\n %s\n" "It is recommended you use the following random password:\n" - "rpcuser=bitcoinrpc\n" + "rpcuser=diamondrpc\n" "rpcpassword=%s\n" "(you do not need to remember this password)\n" "If the file does not exist, create it with owner-readable-only file permissions.\n"), diff --git a/src/init.cpp b/src/init.cpp index 37175fc..e035739 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -81,7 +81,7 @@ void Shutdown(void* parg) delete pwalletMain; NewThread(ExitTimeout, NULL); Sleep(50); - printf("DiamondCoin exited\n\n"); + printf("Diamond exited\n\n"); fExit = true; #ifndef QT_GUI // ensure non-UI client gets exited here, but let Bitcoin-Qt reach 'return 0;' in bitcoin.cpp @@ -136,12 +136,12 @@ bool AppInit(int argc, char* argv[]) if (mapArgs.count("-?") || mapArgs.count("--help")) { // First part of help message is specific to bitcoind / RPC client - std::string strUsage = _("DiamondCoin version") + " " + FormatFullVersion() + "\n\n" + + std::string strUsage = _("Diamond version") + " " + FormatFullVersion() + "\n\n" + _("Usage:") + "\n" + - " DiamondCoind [options] " + "\n" + - " DiamondCoind [options] [params] " + _("Send command to -server or DiamondCoind") + "\n" + - " DiamondCoind [options] help " + _("List commands") + "\n" + - " DiamondCoind [options] help " + _("Get help for a command") + "\n"; + " Diamondd [options] " + "\n" + + " Diamondd [options] [params] " + _("Send command to -server or Diamondd") + "\n" + + " Diamondd [options] help " + _("List commands") + "\n" + + " Diamondd [options] help " + _("Get help for a command") + "\n"; strUsage += "\n" + HelpMessage(); @@ -151,7 +151,7 @@ bool AppInit(int argc, char* argv[]) // Command-line RPC for (int i = 1; i < argc; i++) - if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "DiamondCoin:")) + if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "Diamond:")) fCommandLine = true; if (fCommandLine) @@ -191,13 +191,13 @@ int main(int argc, char* argv[]) bool static InitError(const std::string &str) { - uiInterface.ThreadSafeMessageBox(str, _("DiamondCoin"), CClientUIInterface::OK | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(str, _("Diamond"), CClientUIInterface::OK | CClientUIInterface::MODAL); return false; } bool static InitWarning(const std::string &str) { - uiInterface.ThreadSafeMessageBox(str, _("DiamondCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(str, _("Diamond"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); return true; } @@ -219,8 +219,8 @@ std::string HelpMessage() { string strUsage = _("Options:") + "\n" + " -? " + _("This help message") + "\n" + - " -conf= " + _("Specify configuration file (default: DiamondCoin.conf)") + "\n" + - " -pid= " + _("Specify pid file (default: DiamondCoind.pid)") + "\n" + + " -conf= " + _("Specify configuration file (default: Diamond.conf)") + "\n" + + " -pid= " + _("Specify pid file (default: Diamondd.pid)") + "\n" + " -gen " + _("Generate coins") + "\n" + " -gen=0 " + _("Don't generate coins") + "\n" + " -datadir= " + _("Specify data directory") + "\n" + @@ -451,7 +451,7 @@ bool AppInit2() if (file) fclose(file); static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); if (!lock.try_lock()) - return InitError(strprintf(_("Cannot obtain a lock on data directory %s. DiamondCoin is probably already running."), strDataDir.c_str())); + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Diamond is probably already running."), strDataDir.c_str())); #if !defined(WIN32) && !defined(QT_GUI) if (fDaemon) @@ -478,7 +478,7 @@ bool AppInit2() if (GetBoolArg("-shrinkdebugfile", !fDebug)) ShrinkDebugFile(); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); - printf("DiamondCoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); + printf("Diamond version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str()); printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); if (!fLogTimestamps) printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); @@ -487,7 +487,7 @@ bool AppInit2() std::ostringstream strErrors; if (fDaemon) - fprintf(stdout, "DiamondCoin server starting\n"); + fprintf(stdout, "Diamond server starting\n"); int64 nStart; @@ -519,7 +519,7 @@ bool AppInit2() " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" " your balance or transactions are incorrect you should" " restore from a backup."), strDataDir.c_str()); - uiInterface.ThreadSafeMessageBox(msg, _("DiamondCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(msg, _("Diamond"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); } if (r == CDBEnv::RECOVER_FAIL) return InitError(_("wallet.dat corrupt, salvage failed")); @@ -730,13 +730,13 @@ bool AppInit2() { string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect.")); - uiInterface.ThreadSafeMessageBox(msg, _("DiamondCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + uiInterface.ThreadSafeMessageBox(msg, _("Diamond"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); } else if (nLoadWalletRet == DB_TOO_NEW) - strErrors << _("Error loading wallet.dat: Wallet requires newer version of DiamondCoin") << "\n"; + strErrors << _("Error loading wallet.dat: Wallet requires newer version of Diamond") << "\n"; else if (nLoadWalletRet == DB_NEED_REWRITE) { - strErrors << _("Wallet needed to be rewritten: restart DiamondCoin to complete") << "\n"; + strErrors << _("Wallet needed to be rewritten: restart Diamond to complete") << "\n"; printf("%s", strErrors.str().c_str()); return InitError(strErrors.str()); } diff --git a/src/main.cpp b/src/main.cpp index 4ab18f1..c92f67c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3028,7 +3028,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Diamond: disconnect any known version prior 2.0.2.1 // as these have PoS not working and could serve us garbage - if (fDebug) printf("connected subver %s\n", pfrom->strSubVer.c_str()); + printf("connected subver %s\n", pfrom->strSubVer.c_str()); if (!strcmp(pfrom->strSubVer.c_str(),"/Diamond:2.0.1/") || !strcmp(pfrom->strSubVer.c_str(),"/Diamond:0.7.2/") || !strcmp(pfrom->strSubVer.c_str(),"/Satoshi:0.7.2/") @@ -4686,31 +4686,30 @@ int64 GetContributionAmount(int64 totalCoin) { uint256 CBlock::GetHash(bool existingBlock) const { // There are two distinct cases when we are called - // First case is with with a block already in the blockchain index + // First case is with with a block already in the blockchain index // Second is for a new block - if (existingBlock) { //printf("CBlock::GetHash() look up an existing block\n"); // TODO: reverse checks when Groestl blocks become more - // calculate Scrypt first + // calculate Scrypt first uint256 hash_scrypt = GetHashScrypt(); // find the index position(s) - CBlockIndex* pblockindex_scrypt = mapBlockIndex[hash_scrypt]; + CBlockIndex* pblockindex_scrypt = mapBlockIndex[hash_scrypt]; if (pblockindex_scrypt) - return hash_scrypt; + return hash_scrypt; - // we are here so it must be Groestl + // we are here so it must be Groestl uint256 hash_groestl = GetHashGroestl(); - CBlockIndex* pblockindex_groestl = mapBlockIndex[hash_groestl]; - if (pblockindex_groestl) - return hash_groestl; + CBlockIndex* pblockindex_groestl = mapBlockIndex[hash_groestl]; + if (pblockindex_groestl) + return hash_groestl; } // new block or not found in blockchain if(totalCoin < VALUE_CHANGE) - return GetHashScrypt(); + return GetHashScrypt(); return GetHashGroestl(); } diff --git a/src/main.h b/src/main.h index 1a36cc0..1717d82 100644 --- a/src/main.h +++ b/src/main.h @@ -1444,7 +1444,7 @@ class CDiskBlockIndex : public CBlockIndex return block.GetHashScrypt(); } - uint256 GetBlockHashGroest() const + uint256 GetBlockHashGroestl() const { CBlock block; block.nVersion = nVersion; diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 469e1ee..50f2430 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -10,7 +10,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "%s, you must set a rpcpassword in the configuration file:\n" " %s\n" "It is recommended you use the following random password:\n" -"rpcuser=bitcoinrpc\n" +"rpcuser=diamondrpc\n" "rpcpassword=%s\n" "(you do not need to remember this password)\n" "If the file does not exist, create it with owner-readable-only file " @@ -174,4 +174,4 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Diamon QT_TRANSLATE_NOOP("bitcoin-core", "Warning: Disk space is low!"), QT_TRANSLATE_NOOP("bitcoin-core", "Warning: This version is obsolete, upgrade required!"), QT_TRANSLATE_NOOP("bitcoin-core", "wallet.dat corrupt, salvage failed"), -}; \ No newline at end of file +}; diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index ad188b9..6aa264b 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -11,7 +11,7 @@ - About DiamondCoin + About Diamond @@ -94,7 +94,7 @@ Copyright © 2009-2014 Bitcoin Developers Copyright © 2012-2014 PPCoin Developers -Copyright © 2014 DiamondCoin Developers +Copyright © 2014 Diamond Foundation diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index a4eb463..6f12bd5 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -2708,7 +2708,7 @@ Address: %4 %s, you must set a rpcpassword in the configuration file: %s It is recommended you use the following random password: -rpcuser=bitcoinrpc +rpcuser=diamondrpc rpcpassword=%s (you do not need to remember this password) If the file does not exist, create it with owner-readable-only file permissions. @@ -2716,7 +2716,7 @@ If the file does not exist, create it with owner-readable-only file permissions. %s, you must set a rpcpassword in the configuration file: %s It is recommended you use the following random password: -rpcuser=bitcoinrpc +rpcuser=diamondrpc rpcpassword=%s (you do not need to remember this password) If the file does not exist, create it with owner-readable-only file permissions. diff --git a/src/qt/locale/bitcoin_ru.ts b/src/qt/locale/bitcoin_ru.ts index 752a5b3..f75445e 100644 --- a/src/qt/locale/bitcoin_ru.ts +++ b/src/qt/locale/bitcoin_ru.ts @@ -2721,7 +2721,7 @@ Address: %4 %s, you must set a rpcpassword in the configuration file: %s It is recommended you use the following random password: -rpcuser=bitcoinrpc +rpcuser=diamondrpc rpcpassword=%s (you do not need to remember this password) If the file does not exist, create it with owner-readable-only file permissions. @@ -2729,7 +2729,7 @@ If the file does not exist, create it with owner-readable-only file permissions. %s, вы должны уÑтановить опцию rpcpassword в конфигурационном файле: %s РекомендуетÑÑ Ð¸Ñпользовать Ñледующий Ñлучайный пароль: -rpcuser=bitcoinrpc +rpcuser=diamondrpc rpcpassword=%s (вам не нужно запоминать Ñтот пароль) ЕÑли файл не ÑущеÑтвует, Ñоздайте его и уÑтановите права доÑтупа только Ð´Ð»Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð°. diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 36cc268..f4742e3 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -127,10 +127,10 @@ Value getworkex(const Array& params, bool fHelp) ); if (vNodes.empty()) - throw JSONRPCError(-9, "DiamondCoin is not connected!"); + throw JSONRPCError(-9, "Diamond is not connected!"); if (IsInitialBlockDownload()) - throw JSONRPCError(-10, "DiamondCoin is downloading blocks..."); + throw JSONRPCError(-10, "Diamond is downloading blocks..."); typedef map > mapNewBlock_t; static mapNewBlock_t mapNewBlock; @@ -261,10 +261,10 @@ Value getwork(const Array& params, bool fHelp) "If [data] is specified, tries to solve the block and returns true if it was successful."); if (vNodes.empty()) - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DiamondCoin is not connected!"); + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Diamond is not connected!"); if (IsInitialBlockDownload()) - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "DiamondCoin is downloading blocks..."); + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Diamond is downloading blocks..."); typedef map > mapNewBlock_t; static mapNewBlock_t mapNewBlock; // FIXME: thread safety @@ -402,10 +402,10 @@ Value getblocktemplate(const Array& params, bool fHelp) if (strMode == "template") { if (vNodes.empty()) - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "DiamondCoin is not connected!"); + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Diamond is not connected!"); if (IsInitialBlockDownload()) - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "DiamondCoin is downloading blocks..."); + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Diamond is downloading blocks..."); static CReserveKey reservekey(pwalletMain); From e9bf51df0a5f3469984d81dba5cc810289dc25b6 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 3 Jul 2014 12:47:17 +0300 Subject: [PATCH 034/218] Clean some more cruft. --- src/kernel.cpp | 3 --- src/main.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index a122d35..95c571a 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -279,9 +279,6 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier // bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, bool fPrintProofOfStake) { -// if(totalCoin < VALUE_CHANGE && pindexBest->nHeight > 376497 && !fTestNet) -// return false; - if (nTimeTx < txPrev.nTime) // Transaction timestamp violation return error("CheckStakeKernelHash() : nTime violation"); diff --git a/src/main.h b/src/main.h index 1717d82..8ccdc90 100644 --- a/src/main.h +++ b/src/main.h @@ -1355,7 +1355,7 @@ class CBlockIndex hashProofOfStake.ToString().c_str(), prevoutStake.ToString().c_str(), nStakeTime, hashMerkleRoot.ToString().c_str(), - GetBlockHash().ToString().c_str()); + phashBlock ? GetBlockHash().ToString().c_str() : "*not initialized*"); } void print() const From c6412d37d76d8822425104b1f0eb591c86ca17d7 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 3 Jul 2014 12:57:57 +0300 Subject: [PATCH 035/218] Implement -fastindex, based on the implementation by MintCoin. Using the client past this change requires rebuilding the block chain index, either via load block loading or from the network. --- src/init.cpp | 4 ++++ src/main.h | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index e035739..b657b2c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -27,6 +27,8 @@ using namespace boost; CWallet* pwalletMain; CClientUIInterface uiInterface; +bool fUseFastIndex; + ////////////////////////////////////////////////////////////////////////////// // // Shutdown @@ -426,6 +428,8 @@ bool AppInit2() nConnectTimeout = nNewTimeout; } + fUseFastIndex = GetBoolArg("-fastindex", true); + // Continue to put "/P2SH/" in the coinbase to monitor // BIP16 support. // This can be removed eventually... diff --git a/src/main.h b/src/main.h index 8ccdc90..eda4249 100644 --- a/src/main.h +++ b/src/main.h @@ -89,6 +89,7 @@ extern std::map mapOrphanBlocks; // Settings extern int64 nTransactionFee; +extern bool fUseFastIndex; // Minimum disk space required - used in CheckDiskSpace() static const uint64 nMinDiskSpace = 52428800; @@ -1369,12 +1370,16 @@ class CBlockIndex /** Used to marshal pointers into hashes for db storage. */ class CDiskBlockIndex : public CBlockIndex { +private: + uint256 blockHash; + public: uint256 hashPrev; uint256 hashNext; CDiskBlockIndex() { + blockHash = 0; hashPrev = 0; hashNext = 0; } @@ -1418,10 +1423,14 @@ class CDiskBlockIndex : public CBlockIndex READWRITE(nTime); READWRITE(nBits); READWRITE(nNonce); + READWRITE(blockHash); ) uint256 GetBlockHash() const { + if (fUseFastIndex && (nTime < GetAdjustedTime() - 24 * 60 * 60) && blockHash != 0) + return blockHash; + CBlock block; block.nVersion = nVersion; block.hashPrevBlock = hashPrev; @@ -1429,7 +1438,8 @@ class CDiskBlockIndex : public CBlockIndex block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; - return block.GetHash(); + const_cast(this)->blockHash = block.GetHash(); + return blockHash; } uint256 GetBlockHashScrypt() const From f9b9b08728b005d4d166cf5a2c257116322b4bad Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 3 Jul 2014 15:42:53 +0300 Subject: [PATCH 036/218] Hash functions cleanup. --- src/db.cpp | 8 +++----- src/main.cpp | 2 +- src/main.h | 24 ------------------------ 3 files changed, 4 insertions(+), 30 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index ed9ffdb..05929c5 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -863,10 +863,8 @@ bool CTxDB::LoadBlockIndexGuts() // Construct block index object uint256 blockHash; - if(diskindex.nMoneySupply / COIN <= VALUE_CHANGE) - blockHash = diskindex.GetBlockHashScrypt(); - else - blockHash = diskindex.GetBlockHashGroest(); + totalCoin = diskindex.nMoneySupply / COIN; + blockHash = diskindex.GetBlockHash(); // Construct block index object CBlockIndex* pindexNew = InsertBlockIndex(blockHash); @@ -898,7 +896,7 @@ bool CTxDB::LoadBlockIndexGuts() } // Watch for genesis block - if (pindexGenesisBlock == NULL && diskindex.GetBlockHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) + if (pindexGenesisBlock == NULL && blockHash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) pindexGenesisBlock = pindexNew; if (!pindexNew->CheckIndex()) diff --git a/src/main.cpp b/src/main.cpp index c92f67c..c34cbbe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4709,7 +4709,7 @@ uint256 CBlock::GetHash(bool existingBlock) const // new block or not found in blockchain if(totalCoin < VALUE_CHANGE) - return GetHashScrypt(); + return GetHashScrypt(); return GetHashGroestl(); } diff --git a/src/main.h b/src/main.h index eda4249..e5d1fb7 100644 --- a/src/main.h +++ b/src/main.h @@ -1442,30 +1442,6 @@ class CDiskBlockIndex : public CBlockIndex return blockHash; } - uint256 GetBlockHashScrypt() const - { - CBlock block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrev; - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block.GetHashScrypt(); - } - - uint256 GetBlockHashGroestl() const - { - CBlock block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrev; - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block.GetHashGroestl(); - } - std::string ToString() const { std::string str = "CDiskBlockIndex("; From 52f10349f5b829063a59d65a7b714bfa60d15ee2 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 3 Jul 2014 17:54:42 +0300 Subject: [PATCH 037/218] Implemented the getnetworkhashps RPC call. --- src/bitcoinrpc.cpp | 1 + src/rpcmining.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 6db70f1..5080c1c 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -210,6 +210,7 @@ static const CRPCCommand vRPCCommands[] = { "getgenerate", &getgenerate, true, false }, { "setgenerate", &setgenerate, true, false }, { "gethashespersec", &gethashespersec, true, false }, + { "getnetworkhashps", &getnetworkhashps, true, false }, { "getinfo", &getinfo, true, false }, { "getmininginfo", &getmininginfo, true, false }, { "getnewaddress", &getnewaddress, true, false }, diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index f4742e3..dbea5a7 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -77,7 +77,7 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("generate", GetBoolArg("-gen"))); obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); obj.push_back(Pair("hashespersec", gethashespersec(params, false))); - obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); + obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); obj.push_back(Pair("testnet", fTestNet)); return obj; From 2f4e9b98180acfd12f4f251cb3c73070cf5d7b23 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 7 Jul 2014 16:54:37 +0300 Subject: [PATCH 038/218] Small documentation fixes. --- contrib/macdeploy/fancy.plist | 2 +- contrib/macdeploy/notes.txt | 2 +- diamond.pro | 2 +- doc/README | 2 +- doc/README_windows.txt | 2 +- doc/readme-qt.rst | 10 +++++++++- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/contrib/macdeploy/fancy.plist b/contrib/macdeploy/fancy.plist index 08c2a06..f7668b2 100644 --- a/contrib/macdeploy/fancy.plist +++ b/contrib/macdeploy/fancy.plist @@ -22,7 +22,7 @@ 370 156 - NovaCoin-Qt.app + Diamond-Qt.app 128 156 diff --git a/contrib/macdeploy/notes.txt b/contrib/macdeploy/notes.txt index 9b592fc..7f22a43 100644 --- a/contrib/macdeploy/notes.txt +++ b/contrib/macdeploy/notes.txt @@ -6,7 +6,7 @@ You will need the appscript package for the fancy disk image creation to work. Install it by invoking "sudo easy_install appscript". Ths script should be invoked in the target directory like this: -$source_dir/contrib/macdeploy/macdeployqtplus NovaCoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist -verbose 2 +$source_dir/contrib/macdeploy/macdeployqtplus Diamond-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy $source_dir/contrib/macdeploy/fancy.plist -verbose 2 During the process, the disk image window will pop up briefly where the fancy settings are applied. This is normal, please do not interfere. diff --git a/diamond.pro b/diamond.pro index b96c0e2..398ebf8 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 0.1.0.2 +VERSION = 2.0.3.0 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES diff --git a/doc/README b/doc/README index ff0b1a9..69e0e29 100644 --- a/doc/README +++ b/doc/README @@ -2,7 +2,7 @@ Copyright (c) 2013-2014 Diamond Foundation -Diamond 2.0.2 BETA +Diamond 2.0.3 Copyright (c) 2013-2014 Diamond Foundation Copyright (c) 2013 NovaCoin Developers diff --git a/doc/README_windows.txt b/doc/README_windows.txt index e207127..51967a5 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -2,7 +2,7 @@ Copyright (c) 2013-2014 Diamond Foundation -Diamond 2.0.2 BETA +Diamond 2.0.3 Copyright (c) 2013-2014 Diamond Foundation Copyright (c) 2013 NovaCoin Developers diff --git a/doc/readme-qt.rst b/doc/readme-qt.rst index 71adaf5..3b0076e 100644 --- a/doc/readme-qt.rst +++ b/doc/readme-qt.rst @@ -8,7 +8,15 @@ Debian ------- First, make sure that the required packages for Qt4 development of your -distribution are installed, for Debian and Ubuntu these are: +distribution are installed. + +On recent Ubuntu releases, the `libdb4.8++-dev` package is not in the default +repositories. However it's in the bitcoin repository, which we can add +with: + + apt-add-repository ppa:bitcoin/bitcoin + +Then we need to make sure our build environment is up to date. For Debian and Ubuntu: :: From 22ba8e6f8f87b13d373c9cfda24e8abf16076153 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 7 Jul 2014 17:56:08 +0300 Subject: [PATCH 039/218] Fix more name clashes. --- contrib/macdeploy/notes.txt | 2 +- doc/README | 2 +- doc/README_windows.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/macdeploy/notes.txt b/contrib/macdeploy/notes.txt index 7f22a43..ee0d073 100644 --- a/contrib/macdeploy/notes.txt +++ b/contrib/macdeploy/notes.txt @@ -19,7 +19,7 @@ Fill in the following. Enable custom process step: [x] Command: %{sourceDir}/contrib/macdeploy/macdeployqtplus Working directory: %{buildDir} -Command arguments: NovaCoin-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist -verbose 2 +Command arguments: Diamond-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist -verbose 2 After that you can start the deployment process through the menu with Build -> Deploy Project "novacoin-qt" diff --git a/doc/README b/doc/README index 69e0e29..4dc6524 100644 --- a/doc/README +++ b/doc/README @@ -45,6 +45,6 @@ Start up the new diamondd. See the documentation/wiki at the Diamond site: - http://diamond.cc/ + http://bit.diamonds/ for help and more information. diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 51967a5..9b74594 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -47,6 +47,6 @@ Start up the new diamondd. See the documentation/wiki at the Diamond site: - http://diamond.cc/ + http://bit.diamonds/ for help and more information. From e7c01e95986fb5383167a2c455916429a0034888 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 7 Jul 2014 17:58:37 +0300 Subject: [PATCH 040/218] Get rid of erroneous orphans created during algorithm switch moment. --- src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index c34cbbe..b9ec575 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4695,6 +4695,10 @@ uint256 CBlock::GetHash(bool existingBlock) const // TODO: reverse checks when Groestl blocks become more // calculate Scrypt first uint256 hash_scrypt = GetHashScrypt(); + if (hash_scrypt == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) { + printf("GetHash(): hash fixed up (scrypt)\n"); + return uint256("0x00000d652b612a94e1c830bf4e05106438ea6b53372b29206f0b820d91a9b67b"); + } // find the index position(s) CBlockIndex* pblockindex_scrypt = mapBlockIndex[hash_scrypt]; if (pblockindex_scrypt) From 53650676bdf7643c84a51fcac46b1f2c37bb76e1 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 7 Jul 2014 17:59:25 +0300 Subject: [PATCH 041/218] Implement the 'stakepower' element in 'getmininginfo' RPC call. --- src/rpcmining.cpp | 1 + src/wallet.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/wallet.h | 1 + 3 files changed, 51 insertions(+) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index dbea5a7..75b2a49 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -79,6 +79,7 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("hashespersec", gethashespersec(params, false))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); + obj.push_back(Pair("stakepower", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain))); obj.push_back(Pair("testnet", fTestNet)); return obj; } diff --git a/src/wallet.cpp b/src/wallet.cpp index 748c803..d47b41e 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1358,6 +1358,55 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strTxComment); } +// Diamond: get current stake generation power +// This function should closely match the logic and values in CTransaction::GetCoinAge() +uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) +{ + // Choose coins to use + int64 nBalance = GetBalance(); + int64 nReserveBalance = 0; + uint64 nCoinAge = 0; + CBigNum bnCentSecond = 0; // coin age in the unit of cent-seconds + + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + { + error("CreateCoinStake : invalid reserve balance amount"); + return 0; + } + + if (nBalance <= nReserveBalance) + return 0; + + set > setCoins; + vector vwtxPrev; + int64 nValueIn = 0; + if (!SelectCoins(nBalance - nReserveBalance, GetTime(), setCoins, nValueIn)) + return 0; + if (setCoins.empty()) + return 0; + + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxDB txdb("r"); + CTxIndex txindex; + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + + // Do not count input that is still too young + if (pcoin.first->nTime + nStakeMinAge > GetTime()) + continue; + + bnCentSecond += CBigNum(pcoin.first->vout[pcoin.second].nValue) * (GetTime() - pcoin.first->nTime) / CENT; + } + CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); + nCoinAge = bnCoinDay.getuint64(); + + if (fDebug && GetBoolArg("-printcoinage")) + printf("StakePower bnCoinDay=%"PRI64d"\n", nCoinAge); + + return nCoinAge; +} + // ppcoin: create coin stake transaction bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew) { diff --git a/src/wallet.h b/src/wallet.h index 98e8641..e6b0761 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -177,6 +177,7 @@ class CWallet : public CCryptoKeyStore bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); + uint64 GetStakeMintPower(const CKeyStore& keystore); bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); From 0c3d868c911c2188a1c70928b23cbe3e92143897 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 7 Jul 2014 18:00:35 +0300 Subject: [PATCH 042/218] Properly name the wallet in the About dialog. --- src/qt/forms/aboutdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 6aa264b..088223b 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -50,7 +50,7 @@ IBeamCursor - <b>DMDCoin</b> version + <b>Diamond</b> version Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse From 3f103ec7a23c7a9ac83abef52d4592f365b9ee3a Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 9 Jul 2014 10:30:46 +0300 Subject: [PATCH 043/218] Some more cleanup, formatting, style, typos. --- contrib/macdeploy/notes.txt | 2 +- doc/readme-qt.rst | 4 +-- src/db.cpp | 1 - src/kernel.cpp | 11 +------ src/main.cpp | 23 +++++++------ src/qt/bitcoingui.cpp | 56 ++++++++++++++++---------------- src/qt/transactiondesc.cpp | 2 +- src/qt/transactiontablemodel.cpp | 2 +- src/qt/transactionview.cpp | 2 +- src/rpcblockchain.cpp | 1 - src/wallet.cpp | 3 -- 11 files changed, 46 insertions(+), 61 deletions(-) diff --git a/contrib/macdeploy/notes.txt b/contrib/macdeploy/notes.txt index ee0d073..fd50d23 100644 --- a/contrib/macdeploy/notes.txt +++ b/contrib/macdeploy/notes.txt @@ -22,5 +22,5 @@ Working directory: %{buildDir} Command arguments: Diamond-Qt.app -add-qt-tr da,de,es,hu,ru,uk,zh_CN,zh_TW -dmg -fancy %{sourceDir}/contrib/macdeploy/fancy.plist -verbose 2 After that you can start the deployment process through the menu with -Build -> Deploy Project "novacoin-qt" +Build -> Deploy Project "diamond-qt" diff --git a/doc/readme-qt.rst b/doc/readme-qt.rst index 3b0076e..45100bb 100644 --- a/doc/readme-qt.rst +++ b/doc/readme-qt.rst @@ -22,7 +22,7 @@ Then we need to make sure our build environment is up to date. For Debian and Ub apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev \ libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ - libssl-dev libdb4.8++-dev + libssl-dev libdb4.8++-dev libminiupnpc-dev libminiupnpc8 then execute the following: @@ -31,7 +31,7 @@ then execute the following: qmake make -Alternatively, install Qt Creator and open the `diamond-qt.pro` file. +Alternatively, install Qt Creator and open the `diamond.pro` file. An executable named `diamond-qt` will be built. diff --git a/src/db.cpp b/src/db.cpp index 05929c5..c45cd24 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -679,7 +679,6 @@ bool CTxDB::LoadBlockIndex() pindexBest = mapBlockIndex[hashBestChain]; nBestHeight = pindexBest->nHeight; bnBestChainTrust = pindexBest->bnChainTrust; - printf("LoadBlockIndex(): hashBestChain=%s height=%d trust=%s date=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); diff --git a/src/kernel.cpp b/src/kernel.cpp index 95c571a..5369b77 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -239,7 +239,7 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier else { // printf(">> nStakeModifierTime = %"PRI64d", pindexFrom->GetBlockTime() = %"PRI64d", nStakeModifierSelectionInterval = %"PRI64d"\n", - // nStakeModifierTime, pindexFrom->GetBlockTime(), nStakeModifierSelectionInterval); + // nStakeModifierTime, pindexFrom->GetBlockTime(), nStakeModifierSelectionInterval); return false; } } @@ -296,15 +296,6 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned // DK changing calculations here creates a fork int64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)nStakeMaxAge) - nStakeMinAge; CBigNum bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); -// CBigNum bnCoinDayWeight; -// if (totalCoin < 391430) -// bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); -// else -// bnCoinDayWeight = CBigNum(max(1000 * COIN, nValueIn)) * nTimeWeight / (24 * 60 * 60); - -//printf("calculation: nValueIn=%lld, max=%lld\n", nValueIn, max(1000 * COIN, nValueIn)); -//printf("CheckStakeKernelHash(): bnCoinDayWeight old style = %s, new style = %s\n", (CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60)).ToString().c_str(), (CBigNum(max(1000 * COIN, nValueIn)) * nTimeWeight / COIN / (24 * 60 * 60)).ToString().c_str()); -//printf("CheckStakeKernelHash(): nTimeWeight=%lld\n", nTimeWeight); // printf(">>> CheckStakeKernelHash: nTimeWeight = %"PRI64d"\n", nTimeWeight); // Calculate hash diff --git a/src/main.cpp b/src/main.cpp index b9ec575..22f730c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1140,16 +1140,16 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS // DK activating this will result in a fork if (fProofOfStake && GetTotalCoin() > POS_RESTART) { - if(nActualSpacing < 0) - { - if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to 1.\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing); - nActualSpacing = 1; - } - else if(nActualSpacing > nTargetTimespan) - { - if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetTimespan (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetTimespan); - nActualSpacing = nTargetTimespan; - } + if(nActualSpacing < 0) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to 1.\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing); + nActualSpacing = 1; + } + else if(nActualSpacing > nTargetTimespan) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetTimespan (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetTimespan); + nActualSpacing = nTargetTimespan; + } } // ppcoin: target change every block @@ -2110,7 +2110,6 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) return true; } - bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const { // Update the coin mechanics variables post algorithm change @@ -2148,6 +2147,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) if (vtx[i].IsCoinStake()) return DoS(100, error("CheckBlock() : coinstake in wrong position")); + // ppcoin: coinbase output should be empty if proof-of-stake block if(totalCoin >= VALUE_CHANGE) { if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) @@ -4670,7 +4670,6 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet) } } - // Diamond coin mechanics // Foundation contribution // 0.05 until 1000000 coins generated diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 5b5911b..7d0c3e2 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -169,7 +169,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): statusBar()->addPermanentWidget(frameBlocks); syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this); - // this->setStyleSheet("background-color: #effbef;"); + // this->setStyleSheet("background-color: #effbef;"); // Clicking on a transaction on the overview page simply sends you to transaction history page connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage())); @@ -315,7 +315,7 @@ void BitcoinGUI::createMenuBar() help->addAction(aboutAction); help->addAction(aboutQtAction); - // QString ss("QMenuBar::item { background-color: #effbef; color: black }"); + // QString ss("QMenuBar::item { background-color: #effbef; color: black }"); // appMenuBar->setStyleSheet(ss); } @@ -397,7 +397,7 @@ void BitcoinGUI::setWalletModel(WalletModel *walletModel) // Balloon pop-up for new transaction connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), - this, SLOT(incomingTransaction(QModelIndex,int,int))); + this, SLOT(incomingTransaction(QModelIndex,int,int))); // Ask for passphrase if needed connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet())); @@ -414,13 +414,13 @@ void BitcoinGUI::createTrayIcon() trayIcon->setToolTip(tr("Diamond client")); trayIcon->setIcon(QIcon(":/icons/toolbar")); connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); trayIcon->show(); #else // Note: On Mac, the dock icon is used to provide the tray's functionality. MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); trayIconMenu = dockIconHandler->dockMenu(); - dockIconHandler->setMainWindow((QMainWindow*)this); + dockIconHandler->setMainWindow((QMainWindow*)this); #endif // Configuration of the tray icon (or dock icon) icon menu @@ -532,7 +532,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) progressBar->setVisible(false); } - tooltip = tr("Current difficulty is %1.").arg(clientModel->GetDifficulty()) + QString("
") + tooltip; + tooltip = tr("Current difficulty is %1.").arg(clientModel->GetDifficulty()) + QString("
") + tooltip; QDateTime lastBlockDate = clientModel->getLastBlockDate(); int secs = lastBlockDate.secsTo(QDateTime::currentDateTime()); @@ -640,12 +640,12 @@ void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee) { QString strMessage = tr("This transaction is over the size limit. You can still send it for a fee of %1, " - "which goes to the nodes that process your transaction and helps to support the network. " - "Do you want to pay the fee?").arg( - BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired)); + "which goes to the nodes that process your transaction and helps to support the network. " + "Do you want to pay the fee?").arg( + BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, nFeeRequired)); QMessageBox::StandardButton retval = QMessageBox::question( - this, tr("Confirm transaction fee"), strMessage, - QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes); + this, tr("Confirm transaction fee"), strMessage, + QMessageBox::Yes|QMessageBox::Cancel, QMessageBox::Yes); *payFee = (retval == QMessageBox::Yes); } @@ -655,32 +655,32 @@ void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int return; TransactionTableModel *ttm = walletModel->getTransactionTableModel(); qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent) - .data(Qt::EditRole).toULongLong(); + .data(Qt::EditRole).toULongLong(); if(!clientModel->inInitialBlockDownload()) { // On new transaction, make an info balloon // Unless the initial block download is in progress, to prevent balloon-spam QString date = ttm->index(start, TransactionTableModel::Date, parent) - .data().toString(); + .data().toString(); QString type = ttm->index(start, TransactionTableModel::Type, parent) - .data().toString(); + .data().toString(); QString address = ttm->index(start, TransactionTableModel::ToAddress, parent) - .data().toString(); + .data().toString(); QIcon icon = qvariant_cast(ttm->index(start, - TransactionTableModel::ToAddress, parent) - .data(Qt::DecorationRole)); + TransactionTableModel::ToAddress, parent) + .data(Qt::DecorationRole)); notificator->notify(Notificator::Information, - (amount)<0 ? tr("Sent transaction") : - tr("Incoming transaction"), - tr("Date: %1\n" - "Amount: %2\n" - "Type: %3\n" - "Address: %4\n") - .arg(date) - .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true)) - .arg(type) - .arg(address), icon); + (amount)<0 ? tr("Sent transaction") : + tr("Incoming transaction"), + tr("Date: %1\n" + "Amount: %2\n" + "Type: %3\n" + "Address: %4\n") + .arg(date) + .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true)) + .arg(type) + .arg(address), icon); } } @@ -825,7 +825,7 @@ void BitcoinGUI::encryptWallet(bool status) if(!walletModel) return; AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt: - AskPassphraseDialog::Decrypt, this); + AskPassphraseDialog::Decrypt, this); dlg.setModel(walletModel); dlg.exec(); diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 361e691..ae10db6 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -220,7 +220,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx) strHTML += "" + tr("Transaction ID") + ": " + wtx.GetHash().ToString().c_str() + "
"; if (wtx.IsCoinBase() || wtx.IsCoinStake()) - strHTML += "
" + tr("Generated coins must mature 50 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
"; + strHTML += "
" + tr("Generated coins must mature 200 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.") + "
"; // // Debug view diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 0638a8b..2a187db 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -360,7 +360,7 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const case TransactionRecord::SendToSelf: return tr("Payment to yourself"); case TransactionRecord::StakeMint: - return tr("Mint"); + return tr("Minted"); case TransactionRecord::Generated: return tr("Mined"); default: diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index f28fe02..faea192 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -76,7 +76,7 @@ TransactionView::TransactionView(QWidget *parent) : typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) | TransactionFilterProxy::TYPE(TransactionRecord::SendToOther)); typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf)); - typeWidget->addItem(tr("Mint"), TransactionFilterProxy::TYPE(TransactionRecord::StakeMint)); + typeWidget->addItem(tr("Minted"), TransactionFilterProxy::TYPE(TransactionRecord::StakeMint)); typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated)); typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other)); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 8622ea4..1ecea9f 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -42,7 +42,6 @@ double GetDifficulty(const CBlockIndex* blockindex) return dDiff; } - int64 GetTotalCoin() { return pindexBest->nMoneySupply / COIN; diff --git a/src/wallet.cpp b/src/wallet.cpp index d47b41e..cbf0191 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1414,9 +1414,6 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // Should not be adjusted if you don't understand the consequences static unsigned int nStakeSplitAge = (60 * 60 * 24 * 30); // Age under which amounts are split in two int64 nCombineThreshold = 100 * COIN; // amount to combine smaller coints into -// const CBlockIndex* pIndex0 = GetLastBlockIndex(pindexBest, false); -// if(pIndex0->pprev) -// nCombineThreshold = GetProofOfWorkReward(pIndex0->nHeight, MIN_TX_FEE, pIndex0->pprev->GetBlockHash()) / 3; CBigNum bnTargetPerCoinDay; bnTargetPerCoinDay.SetCompact(nBits); From cc749e9dfd9ebaabf1dcbb6917ea48d069d83d47 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 9 Jul 2014 10:45:41 +0300 Subject: [PATCH 044/218] Implement minting icon and mini-stat tooltip. Idea borrowed from MintCoin. --- src/bitcoinrpc.h | 3 ++ src/kernel.cpp | 10 ++++ src/kernel.h | 2 + src/qt/bitcoin.qrc | 1 + src/qt/bitcoingui.cpp | 93 +++++++++++++++++++++++++++++++++++++- src/qt/bitcoingui.h | 12 +++++ src/qt/transactionview.cpp | 2 +- src/rpcblockchain.cpp | 25 ++++++++++ src/wallet.cpp | 57 +++++++++++++++++++++++ src/wallet.h | 1 + 10 files changed, 203 insertions(+), 3 deletions(-) diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 09472eb..87b7e87 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -127,6 +127,9 @@ extern int64 nWalletUnlockTime; extern int64 AmountFromValue(const json_spirit::Value& value); extern json_spirit::Value ValueFromAmount(int64 amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); + +extern double GetPoSKernelPS(); + extern std::string HexBits(unsigned int nBits); extern std::string HelpRequiringPassphrase(); extern void EnsureWalletIsUnlocked(); diff --git a/src/kernel.cpp b/src/kernel.cpp index 5369b77..db42aa8 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -32,6 +32,16 @@ static std::map mapStakeModifierCheckpoints = ( 317997, 0xfd318368u ) ; +// Get time weight +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd) +{ + // Kernel hash weight starts from 0 at the min age + // this change increases active coins participating the hash and helps + // to secure the network when proof-of-stake difficulty is low + + return min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, (int64)nStakeMaxAge); +} + // Get the last stake modifier and its generation time from a given block static bool GetLastStakeModifier(const CBlockIndex* pindex, uint64& nStakeModifier, int64& nModifierTime) { diff --git a/src/kernel.h b/src/kernel.h index 9241173..608ff8b 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -34,4 +34,6 @@ unsigned int GetStakeModifierChecksum(const CBlockIndex* pindex); // Check stake modifier hard checkpoints bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierChecksum); +// Get time weight using supplied timestamps +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd); #endif // PPCOIN_KERNEL_H diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 523c770..6a2ea8c 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -36,6 +36,7 @@ res/icons/tx_inout.png res/icons/lock_closed.png res/icons/lock_open.png + res/icons/mining.png res/icons/key.png res/icons/filesave.png res/icons/qrcode.png diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 7d0c3e2..893b8a4 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -25,6 +25,8 @@ #include "notificator.h" #include "guiutil.h" #include "rpcconsole.h" +#include "wallet.h" +#include "bitcoinrpc.h" #include "version.h" #ifdef Q_OS_MAC @@ -64,6 +66,9 @@ #include +extern CWallet *pwalletMain; +extern int64 nLastCoinStakeSearchInterval; +extern unsigned int nStakeTargetSpacing; BitcoinGUI::BitcoinGUI(QWidget *parent): QMainWindow(parent), clientModel(0), @@ -132,22 +137,38 @@ BitcoinGUI::BitcoinGUI(QWidget *parent): // Status bar notification icons QFrame *frameBlocks = new QFrame(); frameBlocks->setContentsMargins(0,0,0,0); - frameBlocks->setMinimumWidth(56); - frameBlocks->setMaximumWidth(56); + frameBlocks->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); QHBoxLayout *frameBlocksLayout = new QHBoxLayout(frameBlocks); frameBlocksLayout->setContentsMargins(3,0,3,0); frameBlocksLayout->setSpacing(3); labelEncryptionIcon = new QLabel(); + labelMintingIcon = new QLabel(); labelConnectionsIcon = new QLabel(); labelBlocksIcon = new QLabel(); frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelEncryptionIcon); frameBlocksLayout->addStretch(); + frameBlocksLayout->addWidget(labelMintingIcon); + frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelConnectionsIcon); frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelBlocksIcon); frameBlocksLayout->addStretch(); + // Set minting pixmap + labelMintingIcon->setPixmap(QIcon(":/icons/minting").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelMintingIcon->setEnabled(false); + // Add timer to update minting icon + QTimer *timerMintingIcon = new QTimer(labelMintingIcon); + timerMintingIcon->start(MODEL_UPDATE_DELAY); + connect(timerMintingIcon, SIGNAL(timeout()), this, SLOT(updateMintingIcon())); + // Add timer to update minting weights + QTimer *timerMintingWeights = new QTimer(labelMintingIcon); + timerMintingWeights->start(30 * 1000); + connect(timerMintingWeights, SIGNAL(timeout()), this, SLOT(updateMintingWeights())); + // Set initial values for user and network weights + nWeight, nNetworkWeight = 0; + // Progress bar and label for blocks download progressBarLabel = new QLabel(); progressBarLabel->setVisible(false); @@ -893,3 +914,71 @@ void BitcoinGUI::toggleHidden() { showNormalIfMinimized(true); } + +void BitcoinGUI::updateMintingIcon() +{ + if (pwalletMain && pwalletMain->IsLocked()) + { + labelMintingIcon->setToolTip(tr("Not minting because wallet is locked.")); + labelMintingIcon->setEnabled(false); + } + else if (vNodes.empty()) + { + labelMintingIcon->setToolTip(tr("Not minting because wallet is offline.")); + labelMintingIcon->setEnabled(false); + } + else if (IsInitialBlockDownload()) + { + labelMintingIcon->setToolTip(tr("Not minting because wallet is syncing.")); + labelMintingIcon->setEnabled(false); + } + else if (!nWeight) + { + labelMintingIcon->setToolTip(tr("Not minting because you don't have mature coins.")); + labelMintingIcon->setEnabled(false); + } + else if (nLastCoinStakeSearchInterval) + { + uint64 nEstimateTime = nStakeTargetSpacing * nNetworkWeight / nWeight; + + QString text; + if (nEstimateTime < 60) + { + text = tr("%n second(s)", "", nEstimateTime); + } + else if (nEstimateTime < 60*60) + { + text = tr("%n minute(s)", "", nEstimateTime/60); + } + else if (nEstimateTime < 24*60*60) + { + text = tr("%n hour(s)", "", nEstimateTime/(60*60)); + } + else + { + text = tr("%n day(s)", "", nEstimateTime/(60*60*24)); + } + + labelMintingIcon->setEnabled(true); + labelMintingIcon->setToolTip(tr("Minting.
Your weight is %1.
Network weight is %2.
Expected time to earn reward is %3.").arg(nWeight).arg(nNetworkWeight).arg(text)); + } + else + { + labelMintingIcon->setToolTip(tr("Not minting.")); + labelMintingIcon->setEnabled(false); + } +} + +void BitcoinGUI::updateMintingWeights() +{ + // Only update if we have the network's current number of blocks, or weight(s) are zero (fixes lagging GUI) + if ((clientModel && clientModel->getNumBlocks() == clientModel->getNumBlocksOfPeers()) || !nWeight || !nNetworkWeight) + { + nWeight = 0; + + if (pwalletMain) + pwalletMain->GetStakeWeight(*pwalletMain, nMinMax, nMinMax, nWeight); + + nNetworkWeight = GetPoSKernelPS(); + } +} diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index c67e887..b68b02f 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -4,6 +4,8 @@ #include #include +#include "util.h" // for uint64 + class TransactionTableModel; class ClientModel; class WalletModel; @@ -67,6 +69,7 @@ class BitcoinGUI : public QMainWindow SignVerifyMessageDialog *signVerifyMessageDialog; QLabel *labelEncryptionIcon; + QLabel *labelMintingIcon; QLabel *labelConnectionsIcon; QLabel *labelBlocksIcon; QLabel *progressBarLabel; @@ -98,6 +101,10 @@ class BitcoinGUI : public QMainWindow QMovie *syncIconMovie; + uint64 nMinMax; + uint64 nWeight; + uint64 nNetworkWeight; + /** Create the main UI actions. */ void createActions(); /** Create the menu bar and sub-menus. */ @@ -174,6 +181,11 @@ private slots: void showNormalIfMinimized(bool fToggleHidden = false); /** simply calls showNormalIfMinimized(true) for use in SLOT() macro */ void toggleHidden(); + + /** Update info about minting */ + void updateMintingIcon(); + /** Update minting weight info */ + void updateMintingWeights(); }; #endif diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index faea192..b7b025a 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -175,7 +175,7 @@ void TransactionView::setModel(WalletModel *model) transactionView->setSelectionBehavior(QAbstractItemView::SelectRows); transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection); transactionView->setSortingEnabled(true); - transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder); + transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder); transactionView->verticalHeader()->hide(); transactionView->horizontalHeader()->resizeSection( diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 1ecea9f..761180f 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -47,6 +47,31 @@ int64 GetTotalCoin() return pindexBest->nMoneySupply / COIN; } +double GetPoSKernelPS() +{ + int nPoSInterval = 72; + double dStakeKernelsTriedAvg = 0; + int nStakesHandled = 0, nStakesTime = 0; + + CBlockIndex* pindex = pindexBest;; + CBlockIndex* pindexPrevStake = NULL; + + while (pindex && nStakesHandled < nPoSInterval) + { + if (pindex->IsProofOfStake()) + { + dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0; + nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0; + pindexPrevStake = pindex; + nStakesHandled++; + } + + pindex = pindex->pprev; + } + + return nStakesTime ? dStakeKernelsTriedAvg / nStakesTime : 0; +} + Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPrintTransactionDetail) { Object result; diff --git a/src/wallet.cpp b/src/wallet.cpp index cbf0191..2132e0d 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1407,6 +1407,63 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) return nCoinAge; } +// NovaCoin: get current stake weight + bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight) + { + // Choose coins to use + int64 nBalance = GetBalance(); + + int64 nReserveBalance = 0; + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + return error("CreateCoinStake : invalid reserve balance amount"); + if (nBalance <= nReserveBalance) + return false; + + set > setCoins; + vector vwtxPrev; + int64 nValueIn = 0; + + if (!SelectCoins(nBalance - nReserveBalance, GetTime(), setCoins, nValueIn)) + return false; + + if (setCoins.empty()) + return false; + + CTxDB txdb("r"); + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxIndex txindex; + { + LOCK2(cs_main, cs_wallet); + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + } + + int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime()); + CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); + + // Weight is greater than zero + if (nTimeWeight > 0) + { + nWeight += bnCoinDayWeight.getuint64(); + } + + // Weight is greater than zero, but the maximum value isn't reached yet + if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge) + { + nMinWeight += bnCoinDayWeight.getuint64(); + } + + // Maximum weight was reached + if (nTimeWeight == nStakeMaxAge) + { + nMaxWeight += bnCoinDayWeight.getuint64(); + } + } + + return true; + } + // ppcoin: create coin stake transaction bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew) { diff --git a/src/wallet.h b/src/wallet.h index e6b0761..7ac9133 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -178,6 +178,7 @@ class CWallet : public CCryptoKeyStore bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); uint64 GetStakeMintPower(const CKeyStore& keystore); + bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight); bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); From 48255001bda14dcdc7aa30cad0980d707c83df14 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 9 Jul 2014 10:55:43 +0300 Subject: [PATCH 045/218] Implement 'Unlock for minting only' in the GUI. Please note, this is a very weak protection, it only disables the GUI sending of coins! Idea borrowed from MintCoin. Got rid of the useless lock button in the overview page. Minor other fixes. --- src/qt/askpassphrasedialog.cpp | 9 +++++ src/qt/askpassphrasedialog.h | 1 + src/qt/bitcoingui.cpp | 50 ++++++++++++++++++++++++---- src/qt/bitcoingui.h | 3 ++ src/qt/forms/askpassphrasedialog.ui | 16 +++++++++ src/qt/forms/overviewpage.ui | 28 +++++----------- src/qt/locale/bitcoin_en.qm | Bin 74726 -> 0 bytes src/qt/locale/bitcoin_ru.qm | Bin 84243 -> 0 bytes src/qt/overviewpage.cpp | 28 +--------------- src/qt/overviewpage.h | 1 - src/qt/walletmodel.cpp | 10 ++++++ 11 files changed, 93 insertions(+), 53 deletions(-) delete mode 100644 src/qt/locale/bitcoin_en.qm delete mode 100644 src/qt/locale/bitcoin_ru.qm diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 5ad1e78..e3f448f 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -8,6 +8,8 @@ #include #include +extern bool fWalletUnlockMintOnly; + AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : QDialog(parent), ui(new Ui::AskPassphraseDialog), @@ -33,6 +35,10 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words.")); setWindowTitle(tr("Encrypt wallet")); break; + case UnlockMinting: + ui->mintingCheckBox->setChecked(true); + ui->mintingCheckBox->show(); + // fallthru case Unlock: // Ask passphrase ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet.")); ui->passLabel2->hide(); @@ -138,6 +144,7 @@ void AskPassphraseDialog::accept() QDialog::reject(); // Cancelled } } break; + case UnlockMinting: case Unlock: if(!model->setWalletLocked(false, oldpass)) { @@ -146,6 +153,7 @@ void AskPassphraseDialog::accept() } else { + fWalletUnlockMintOnly = ui->mintingCheckBox->isChecked(); QDialog::accept(); // Success } break; @@ -193,6 +201,7 @@ void AskPassphraseDialog::textChanged() case Encrypt: // New passphrase x2 acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); break; + case UnlockMinting: case Unlock: // Old passphrase x1 case Decrypt: acceptable = !ui->passEdit1->text().isEmpty(); diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index b500ff4..ca01274 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -18,6 +18,7 @@ class AskPassphraseDialog : public QDialog public: enum Mode { Encrypt, /**< Ask passphrase twice and encrypt */ + UnlockMinting, /**< Ask passphrase and unlock for minting only */ Unlock, /**< Ask passphrase and unlock */ ChangePass, /**< Ask old passphrase + new passphrase twice */ Decrypt /**< Ask passphrase and decrypt wallet */ diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 893b8a4..ff86f76 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -69,12 +69,15 @@ extern CWallet *pwalletMain; extern int64 nLastCoinStakeSearchInterval; extern unsigned int nStakeTargetSpacing; +extern bool fWalletUnlockMintOnly; + BitcoinGUI::BitcoinGUI(QWidget *parent): QMainWindow(parent), clientModel(0), walletModel(0), encryptWalletAction(0), changePassphraseAction(0), + lockWalletToggleAction(0), aboutQtAction(0), trayIcon(0), notificator(0), @@ -285,6 +288,7 @@ void BitcoinGUI::createActions() backupWalletAction->setToolTip(tr("Backup wallet to another location")); changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this); changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption")); + lockWalletToggleAction = new QAction(this); signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this); verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this); @@ -301,6 +305,7 @@ void BitcoinGUI::createActions() connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool))); connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet())); connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase())); + connect(lockWalletToggleAction, SIGNAL(triggered()), this, SLOT(lockWalletToggle())); connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); } @@ -327,6 +332,7 @@ void BitcoinGUI::createMenuBar() QMenu *settings = appMenuBar->addMenu(tr("&Settings")); settings->addAction(encryptWalletAction); settings->addAction(changePassphraseAction); + settings->addAction(lockWalletToggleAction); settings->addSeparator(); settings->addAction(optionsAction); @@ -352,6 +358,7 @@ void BitcoinGUI::createToolBars() QToolBar *toolbar2 = addToolBar(tr("Actions toolbar")); toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + toolbar2->addAction(lockWalletToggleAction); toolbar2->addAction(exportAction); } @@ -819,24 +826,33 @@ void BitcoinGUI::setEncryptionStatus(int status) case WalletModel::Unencrypted: labelEncryptionIcon->hide(); encryptWalletAction->setChecked(false); - changePassphraseAction->setEnabled(false); encryptWalletAction->setEnabled(true); + changePassphraseAction->setEnabled(false); + lockWalletToggleAction->setVisible(false); break; case WalletModel::Unlocked: labelEncryptionIcon->show(); labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); - labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked")); + labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked.")); encryptWalletAction->setChecked(true); - changePassphraseAction->setEnabled(true); encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + changePassphraseAction->setEnabled(true); + lockWalletToggleAction->setVisible(true); + lockWalletToggleAction->setIcon(QIcon(":/icons/lock_closed")); + lockWalletToggleAction->setText(tr("&Lock Wallet")); + lockWalletToggleAction->setToolTip(tr("Lock wallet")); break; case WalletModel::Locked: labelEncryptionIcon->show(); labelEncryptionIcon->setPixmap(QIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); - labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked")); + labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked.")); encryptWalletAction->setChecked(true); - changePassphraseAction->setEnabled(true); encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported + changePassphraseAction->setEnabled(true); + lockWalletToggleAction->setVisible(true); + lockWalletToggleAction->setIcon(QIcon(":/icons/lock_open")); + lockWalletToggleAction->setText(tr("&Unlock Wallet...")); + lockWalletToggleAction->setToolTip(tr("Unlock wallet")); break; } } @@ -879,13 +895,35 @@ void BitcoinGUI::unlockWallet() { if(!walletModel) return; + + // Unlock wallet when requested by wallet model + if(walletModel->getEncryptionStatus() == WalletModel::Locked || fWalletUnlockMintOnly) + { + AskPassphraseDialog::Mode mode = AskPassphraseDialog::Unlock; + AskPassphraseDialog dlg(mode, this); + dlg.setModel(walletModel); + dlg.exec(); + } +} + +void BitcoinGUI::lockWalletToggle() +{ + if(!walletModel) + return; + // Unlock wallet when requested by wallet model if(walletModel->getEncryptionStatus() == WalletModel::Locked) { - AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); + AskPassphraseDialog::Mode mode = AskPassphraseDialog::UnlockMinting; + AskPassphraseDialog dlg(mode, this); dlg.setModel(walletModel); dlg.exec(); } + else if(walletModel->getEncryptionStatus() == WalletModel::Unlocked) + { + walletModel->setWalletLocked(true); + fWalletUnlockMintOnly = false; + } } void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index b68b02f..202de9e 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -91,6 +91,7 @@ class BitcoinGUI : public QMainWindow QAction *encryptWalletAction; QAction *backupWalletAction; QAction *changePassphraseAction; + QAction *lockWalletToggleAction; QAction *aboutQtAction; QAction *openRPCConsoleAction; @@ -176,6 +177,8 @@ private slots: void changePassphrase(); /** Ask for passphrase to unlock wallet temporarily */ void unlockWallet(); + /** Toggle unlocking wallet */ + void lockWalletToggle(); /** Show window if hidden, unminimize when minimized, rise when obscured or show if hidden and fToggleHidden is true */ void showNormalIfMinimized(bool fToggleHidden = false); diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui index 2516904..204d282 100644 --- a/src/qt/forms/askpassphrasedialog.ui +++ b/src/qt/forms/askpassphrasedialog.ui @@ -99,6 +99,22 @@
+ + + + true + + + Serves to disable trivial use of sendmoney when the OS account is compromised. Provides no real security. + + + For minting only + + + false + + +
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index c594df7..02e933f 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -381,31 +381,21 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - false + + + Qt::Vertical - - Unlock wallet + + + 20 + 40 + - + diff --git a/src/qt/locale/bitcoin_en.qm b/src/qt/locale/bitcoin_en.qm deleted file mode 100644 index 78bebd450d8772143d65fa02fa8dc926aac121e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74726 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 diff --git a/src/qt/locale/bitcoin_ru.qm b/src/qt/locale/bitcoin_ru.qm deleted file mode 100644 index afb610b5bd586f181e20a72cd43f92a7857ce432..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84243 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
    tx1;a_^#_%?K1n9L<$WUb`a2wZY^ebA&WQO+* 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::system().toString(count)); } -void OverviewPage::unlockWallet() -{ - if(model->getEncryptionStatus() == WalletModel::Locked) - { - AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); - dlg.setModel(model); - if(dlg.exec() == QDialog::Accepted) - { - ui->unlockWalletButton->setText(QString("Lock wallet")); - } - } - else - { - model->setWalletLocked(true); - ui->unlockWalletButton->setText(QString("Unlock wallet")); - } -} - void OverviewPage::setModel(WalletModel *model) { this->model = model; @@ -183,7 +165,7 @@ void OverviewPage::setModel(WalletModel *model) filter->setLimit(NUM_ITEMS); filter->setDynamicSortFilter(true); filter->setSortRole(Qt::EditRole); - filter->sort(TransactionTableModel::Status, Qt::DescendingOrder); + filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); ui->listTransactions->setModel(filter); ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); @@ -196,14 +178,6 @@ void OverviewPage::setModel(WalletModel *model) connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int))); connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); - - // Unlock wallet button - WalletModel::EncryptionStatus status = model->getEncryptionStatus(); - if(status == WalletModel::Unencrypted) - { - ui->unlockWalletButton->setDisabled(true); - } - connect(ui->unlockWalletButton, SIGNAL(clicked()), this, SLOT(unlockWallet())); } // update the display unit, to not use the default ("DMD") diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 2ed43b7..59fbb1d 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -29,7 +29,6 @@ class OverviewPage : public QWidget public slots: void setBalance(qint64 balance, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance); void setNumTransactions(int count); - void unlockWallet(); signals: void transactionClicked(const QModelIndex &index); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 34850d8..d43a739 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -12,6 +12,8 @@ #include #include +extern bool fWalletUnlockMintOnly; + WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), transactionTableModel(0), @@ -357,6 +359,14 @@ WalletModel::UnlockContext WalletModel::requestUnlock() // Request UI to unlock wallet emit requireUnlock(); } + else if(fWalletUnlockMintOnly) + { + // Relock so the user must give the right passphrase to continue + setWalletLocked(true); + + // Request UI to unlock wallet + emit requireUnlock(); + } // If wallet is still locked, unlock was failed or cancelled, mark context as invalid bool valid = getEncryptionStatus() != Locked; From 4f2bb1e479db7fca55ab081a21976018ec86fd01 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 10 Jul 2014 20:17:57 +0300 Subject: [PATCH 046/218] Some code cleanup --- src/db.cpp | 4 +-- src/kernel.h | 1 + src/main.cpp | 75 ++++++++++++++++++++++++++-------------------------- 3 files changed, 39 insertions(+), 41 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index c45cd24..c44965e 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -860,10 +860,8 @@ bool CTxDB::LoadBlockIndexGuts() CDiskBlockIndex diskindex; ssValue >> diskindex; - // Construct block index object - uint256 blockHash; totalCoin = diskindex.nMoneySupply / COIN; - blockHash = diskindex.GetBlockHash(); + uint256 blockHash = diskindex.GetBlockHash(); // Construct block index object CBlockIndex* pindexNew = InsertBlockIndex(blockHash); diff --git a/src/kernel.h b/src/kernel.h index 608ff8b..412deb3 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -36,4 +36,5 @@ bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierCheck // Get time weight using supplied timestamps int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd); + #endif // PPCOIN_KERNEL_H diff --git a/src/main.cpp b/src/main.cpp index 22f730c..7093004 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -989,10 +989,10 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) // simple algorithm, not depend on the diff int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight) { + int64 nRewardCoinYear; + int64 nSubsidy = 0; if(totalCoin >= VALUE_CHANGE || fTestNet) { - int64 nRewardCoinYear; - int64 nSubsidy = 0; nRewardCoinYear = MAX_MINT_PROOF_OF_STAKE; if(fTestNet) nSubsidy = nCoinAge * 50 * CENT / 365; @@ -1021,39 +1021,37 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi } else { - int64 nRewardCoinYear; + CBigNum bnRewardCoinYearLimit = MAX_MINT_PROOF_OF_STAKE; // Base stake mint rate, 100% year interest + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + CBigNum bnTargetLimit = bnProofOfStakeLimit; + bnTargetLimit.SetCompact(bnTargetLimit.GetCompact()); - CBigNum bnRewardCoinYearLimit = MAX_MINT_PROOF_OF_STAKE; // Base stake mint rate, 100% year interest - CBigNum bnTarget; - bnTarget.SetCompact(nBits); - CBigNum bnTargetLimit = bnProofOfStakeLimit; - bnTargetLimit.SetCompact(bnTargetLimit.GetCompact()); - - // Diamond: reward for coin-year is cut in half every 64x multiply of PoS difficulty - // A reasonably continuous curve is used to avoid shock to market - // (nRewardCoinYearLimit / nRewardCoinYear) ** 4 == bnProofOfStakeLimit / bnTarget - // - // Human readable form: - // - // nRewardCoinYear = 1 / (posdiff ^ 1/4) + // Diamond: reward for coin-year is cut in half every 64x multiply of PoS difficulty + // A reasonably continuous curve is used to avoid shock to market + // (nRewardCoinYearLimit / nRewardCoinYear) ** 4 == bnProofOfStakeLimit / bnTarget + // + // Human readable form: + // + // nRewardCoinYear = 1 / (posdiff ^ 1/4) - CBigNum bnLowerBound = 1 * CENT; // Lower interest bound is 1% per year - CBigNum bnUpperBound = bnRewardCoinYearLimit; - while (bnLowerBound + CENT <= bnUpperBound) - { - CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2; - if (fDebug && GetBoolArg("-printcreation")) - printf("GetProofOfStakeReward() : lower=%"PRI64d" upper=%"PRI64d" mid=%"PRI64d"\n", bnLowerBound.getuint64(), bnUpperBound.getuint64(), bnMidValue.getuint64()); - if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnTarget) - bnUpperBound = bnMidValue; - else - bnLowerBound = bnMidValue; - } + CBigNum bnLowerBound = 1 * CENT; // Lower interest bound is 1% per year + CBigNum bnUpperBound = bnRewardCoinYearLimit; + while (bnLowerBound + CENT <= bnUpperBound) + { + CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2; + if (fDebug && GetBoolArg("-printcreation")) + printf("GetProofOfStakeReward() : lower=%"PRI64d" upper=%"PRI64d" mid=%"PRI64d"\n", bnLowerBound.getuint64(), bnUpperBound.getuint64(), bnMidValue.getuint64()); + if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnRewardCoinYearLimit * bnTarget) + bnUpperBound = bnMidValue; + else + bnLowerBound = bnMidValue; + } - nRewardCoinYear = bnUpperBound.getuint64(); - nRewardCoinYear = min((nRewardCoinYear / CENT) * CENT, MAX_MINT_PROOF_OF_STAKE); + nRewardCoinYear = bnUpperBound.getuint64(); + nRewardCoinYear = min((nRewardCoinYear / CENT) * CENT, MAX_MINT_PROOF_OF_STAKE); - int64 nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear; + nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear; if (fDebug && GetBoolArg("-printcreation")) printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits); return nSubsidy; @@ -3025,7 +3023,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - // Diamond: disconnect any known version prior 2.0.2.1 // as these have PoS not working and could serve us garbage printf("connected subver %s\n", pfrom->strSubVer.c_str()); @@ -4437,18 +4434,20 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) // Each thread has its own key and counter CReserveKey reservekey(pwallet); unsigned int nExtraNonce = 0; - totalCoin = GetTotalCoin(); + while (fGenerateBitcoins || fProofOfStake) { totalCoin = GetTotalCoin(); if (fShutdown) return; - while (vNodes.empty() || IsInitialBlockDownload()) + + while (vNodes.empty() || IsInitialBlockDownload() || pwallet->IsLocked()) { + nLastCoinStakeSearchInterval = 0; Sleep(1000); if (fShutdown) return; - if ((!fGenerateBitcoins) && !fProofOfStake) + if (!fGenerateBitcoins && !fProofOfStake) return; } @@ -4492,8 +4491,8 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) continue; } -// printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), -// ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); + //printf("Running BitcoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(), + // ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); // // Pre-build hash buffers @@ -4536,7 +4535,7 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) { if (!pblock->SignBlock(*pwalletMain)) { -// strMintWarning = strMintMessage; + strMintWarning = strMintMessage; break; } strMintWarning = ""; From d9fd6832cf54eb4fbe9879e6ce9e4e6c875b6938 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 11 Jul 2014 12:37:55 +0300 Subject: [PATCH 047/218] Enable dnsseed, add one node. --- src/net.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 1cd181f..419a80c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1154,6 +1154,7 @@ void MapPort() // The first name is used as information source for addrman. // The second name should resolve to a list of seed addresses. static const char *strDNSSeed[][2] = { + {"dmdseed.danbo.bg", "dmdseed.danbo.bg"}, {"", ""}, }; @@ -1850,18 +1851,12 @@ void StartNode(void* parg) // Start threads // - if (!GetBoolArg("-dnsseed", true)) printf("DNS seeding disabled\n"); else if (!NewThread(ThreadDNSAddressSeed, NULL)) printf("Error: NewThread(ThreadDNSAddressSeed) failed\n"); - if (!GetBoolArg("-dnsseed", false)) - printf("DNS seeding disabled\n"); - if (GetBoolArg("-dnsseed", false)) - printf("DNS seeding NYI\n"); - // Map ports with UPnP if (fUseUPnP) MapPort(); From df39bb6b76c14445b4222a5a22b128db7e947934 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 11 Jul 2014 12:42:15 +0300 Subject: [PATCH 048/218] Fix minting icon status. Add minting icon for transactions. --- src/qt/bitcoin.qrc | 3 ++- src/qt/res/icons/mining.png | Bin 0 -> 269 bytes src/qt/res/icons/mining_active.png | Bin 0 -> 668 bytes src/qt/res/icons/minting.png | Bin 0 -> 6797 bytes src/qt/res/icons/tx_minted.png | Bin 0 -> 3043 bytes src/qt/transactiontablemodel.cpp | 13 ++++++++----- 6 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 src/qt/res/icons/mining.png create mode 100644 src/qt/res/icons/mining_active.png create mode 100644 src/qt/res/icons/minting.png create mode 100644 src/qt/res/icons/tx_minted.png diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 6a2ea8c..c7c2dcd 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -31,12 +31,13 @@ res/icons/synced.png res/icons/remove.png res/icons/tx_mined.png + res/icons/tx_minted.png res/icons/tx_input.png res/icons/tx_output.png res/icons/tx_inout.png res/icons/lock_closed.png res/icons/lock_open.png - res/icons/mining.png + res/icons/minting.png res/icons/key.png res/icons/filesave.png res/icons/qrcode.png diff --git a/src/qt/res/icons/mining.png b/src/qt/res/icons/mining.png new file mode 100644 index 0000000000000000000000000000000000000000..8217870db9935f560ead54cd4978ba5b9e9e7b5b GIT binary patch literal 269 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85p>QK$!8;-MT+OLG}_)Usv{f>>R>YEbA|*cmjpQN?apKg7ec# z$`gxH8440J^GfvcQcDy}^bD+De9Z)^$n|t_46*QEdhQ_C0R%Z=p=-75F zLX@B1WZ6+6!SI}lB#x}L=X=T)?oK&+bGGh>JD2!!c_)|cXMJb5*!x}mfoAQkTb%zh z#zel)mEXnvVnSLLhr{$UZ3o*99L$l(@mQU>;UTB=yY5d+Z{h^%tIC_Zffh4(y85}S Ib4q9e0Kz3*6#xJL literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/mining_active.png b/src/qt/res/icons/mining_active.png new file mode 100644 index 0000000000000000000000000000000000000000..4726ebb9ae8760caeb6e065d8d99834e3b37b34f GIT binary patch literal 668 zcmV;N0%QG&P)NotxI}z*ga{w`NFYV zEV+^vrz$4Hf$Fu&3rSy%yd$aP044k3CEYb8-z2RBr@gn5mg==i zQ_>enKP1fy$OBJXVblqdY#+Gq$7!#fje6~D)M;lU{5U-T-uQ8fAEy8hf$PAWfQ?od z5hNKv!;jPbb~fT%jQu$60^5F^a?~4ifP26-$B$FIVp*$YuNj>7nr^YA|E}KyXU|F zuM7;Z0aO4_zzyK>49Pz5ZmPtp-mg|z99i{!P@vtu& ztdEjD&G=<#6Iu|k09*mqfK{Mic{fP1&P>f7PzGF6JqNfBP&9Km=82rCS&($Wawh3S z(l2wRV$w0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02*{fSaefwW^{L9 za%BKeVQFr3E>1;MAa*k@H7+qQF!XYv0000XbVXQnLvm$dbZKvHAXI5>WdJfTF*7EhN(-9Rc12!eyFk zlU~{MrsQyB2`7Ag^pdlaw2zK|>+-#&SFOON?c2~eFbtzE9UE(V@ynNA#d))4J;%?# zOU;q5JVW_=aKJUoR$P-C)@YDjS`KBJ0!;%$xO2rKYC*Jp9NbKUF9c{k*n% z^p>%U;-ll=s@QXKa$PUHz6os#4N9ygyj9nPXiEp~T6GOxI@SjNa34}!#|lLl_pV!u zL8tRp-uKMt?WdQ&^$1vT^QxOMzPucTRx6@Opl|;N$SBOmNv|KPW=?`qtwrUOiKt2G z@S81f$9SlMdS7)`caPUkQsMdCBo($9|Yfr4DkO4r)ps@l)jUOo0W|Db$y!E^*?o zkaS9T%Uf^ZlKJzIOr?;LB!pv0^mu%b7`ItkHMD9qG+GThLJ_#b5$rnJfRHbUa3q2f zV;Y|S>A&JgO$`!>gob0rM~D9WWev4^`HGd&k01CKDVOz{@1LSxBtAS#xoz>1C6YfB zmcsFb6s7*9#1cta#rZ@sB^~#Nq@yms^j5c1`b~4E^y3d|q-{q}NC%D_mnti(ggs@W z!~ReCYa`(Pn^)g*-@W(!E6jEW^s3PTH@*5ty#C6|c;mHK!+iS_>VHrNsbiInw$83% zyTbuzAdJpoA4VAd=5z%r3vyx6X`x~@NK>Ri!3T=y7!F3Uz14*St&JE7crYo;ipfae z+GSTE91iO_rm*F6m5Y`vy;O2WB&j|iNlnzwkR?aI=*ikiAdjEbB9zsZk$+! zXQ?ygJ3m`0=FOWY1tL-D5BqAQW$V5#U4PGd>F!6Kly*0?O1&d~$s3MH;aFT^YDhiQ zIHN)Qo=BvmJ>3J+L;H_P8}}WOHaz;cc| zUJ*136-vt{pg7Bh{%8bELoxW$)My`yK%rB@#xS_&_gi7g&4ecwMQx`OCw6Yf@x8mz z+S2kpj@dmr^#7E!B$T1Pbd44rAfyGqXAVm z4V3O4?ArVq?!I%K7-K(m1N9a0hO#yzBlEGnbtmx5i!Z`Ht{f9eOOdWpV;~eqTUQ6P zBt!*S+3*B>n3P)pN0A-bbbu=o!xJyPhTf(+0;3koS1iX5uD%@oeSM;PJS8ZLbvqle z6YR7pqOg~>`Te7{*n8|a23Tymscx!{j+kj+Jm)%a?9I)1a@Cc%W7TzduBij#uUn1I zXbOjq*UtX(;>CaDc)iqhN~Q9#U3(8e!*#j(vdd6Xl#ic1{X493OcQ4q8VRes`o6?!7yZH?;!hj9ipg&xA>@CE(hT zVKdQAvib-Gl)6IydVi@Xn!(=xi%VtJiP6l$y3XxJ7;Pr=5*VBjp zY-q=frI+C+>wkoE#ucLD*kQc42k{5-N=vH?3HP-#_~_0$vZ=+S=}+ zSv|7FpCM=CfY%=T&5P(I`gbv`gVZ6`O63^euNSa&--yvIyuRWZjeBAQ>E zmxbwOGjeq4$Y5g=P9@=C%{OUP>;TOuEy{)|&xVvfopd*d&JiD;{O~Yp@+V;ZoA2RI zdk&yFF9*ZDJ;atUw!HQlhK7cOStGJ>r;#&tz^c3M`L5hsYIvuKD}L1FMW#}TLY0E4 zAi;TP2a=p*%o}2OBq8}?h!1f^)0If$`5srl42bM#k;`Z}m-%W-PiJ&!VW*ZEO_)I* zZ_}pp8ENbzgYTq? zjM3A}nWn(6HvIe-_6(~TDu$|XL|CcCQnH?MHY#CG@UWN1p3zxs8oSPMV_oCO$iG>6Ag|#5tFH{_+28KR52p7dLzqT5O$W) z`MDYL1d^O;G4V%Y^sKq%CXR%q!q~CMnUq0|TCI+Hn6skvk;q|$AT~q}T*REnqt*pe zcrVDZ7)!uA+|9gJBcI`KP)e|FPDzN;P&G$jBS!M0K!6h&J=$CxWegd z9MZV*N~(e@D>ga#LX3kR;^g=#BuPOhDCjI+!)I}hBwXaQe4d@hG(N{p9N}Zp?g}6t zh_L;&BUec*vg(+7pvT50V*Ihn8}IDgb;ZROUkutNKU_$HtI2uD=^)M#v|(bsAEX2N zk_u!p&rOU|vFa)*2`!x8JrN4RuTav- zDfkI^Nk)VBaIH*+s@OA3nNWpuGnB|S$Wt2gyvBSXMGDeDJtsqZWP`<|#Q@?ca#2h~ z7%h%Mh=E+`(cguLUpZ&_`0;g&+&^D0LO;gAm`NDoy{*w0_IG(vM^e?j>m5WGQA~7< zG}mMD>`U=&Iysv zf287ip?v*Wh$FHJ`OEP>7IDfMm!!^^B=u73!;*CQ15ZmuQ_hiYd~>I?%axQizPU~K z?d4IE$0lQ4zi%(U_F8$KC9UN*2pB3_OZ3{dgD1LrY&7N};2p83vXBuI@$tHs{^PJei78N6nVXGl9@De%9-PC;^mPxaO`py)Vk7K#ybw8>ZL{nouu3l2j z@Q<)!u)>5wXgY8N{yvf^IyEgY0x96dl&eV5ejoO{y8|sdcOVvwLZMDVk>D{EC!15V0hpDg#ru=bqBpu7f zDLmxHv>BB+vgu{i96Bhr;7`a89D|Gn111+1k0Y63t~2bLS(p!y@oe9_7ahN4>)F`@ zU510*SPwdOy^GHJ26Q*Kp|iIWUH#o~vz-kF0-RU??|8j<#hF%-z#*;J)i zGU*Y%a!ILovgV8Qnrk#5GUCSmH{O6+XMn+Ig^F#nD4~*Il>UEUMolLV4LXIr zXY&2SX&vz8Yp=VW6n69t(U-uM#L2@45F7ErQhgrG1R>kh>1q8M4)G|qCqU@GV`lDzfU`7*3a{f4a<1y0exV#}MNK!qip^nyFb;A|# zw$_sZvnOD5iDQD~Kj39k#Cv0LQZc5FmfF|XC(M*v!LiEe9PsViZvCd5yMp1>i+1GPWrRC6N=R;}G!j>~0S;cwCBo1Wem101l#-71p>~ngUYiZ={Y3O7< zuXP5|+`)xXC(y&*VqZfaI)|f-ggA*%5)L*;b$%av4dCj`Oc=7V(YW<(8M5QiIHK$m z!a+Y$jDoOhfL)4ctbnc#@jWQyt>Cc=Z~IIU^;<4?`&eA+y1U@&??;T?nv%^)imTh% z*@1Y?VK^p~W6`X+DASAFR$yEIAWru6($FX}vaKj{Skc2(4~u4sU0xc?iP>yIewGfC z^?H`kFuYuOf%XPsLOMU!sI-{PYO>uMz_%)M#p^6SyEWiuTbLLw4JlI&1yuEqj>KEpiv&D2@Q zXWe%5V?TdF2BR*9fSz5Qigmqp?|Z0yb0eDH-HPhjbMWe|E3qy|i5FZc-1fw)cxLT4 zSegQ`j~|cVhz~(ugj~RY{_bu$l|rEanvWjCv~#9l!MI#_$oC(wZN}ciC%^@V*`j2P zPomlB!w`v0O<2SqaK+lSaJRR@S$_g4Vt|rPNb`Hi$|CFzC8z~5o`rmt1MXXW`x-b| z@Wpq1MvE1#+qSYj3*)NquE%}1--g>AX*du{;eubiiC@m2iiY3*1cs7w*d|S5`IBgH zCpr$+peLGyh0$YTK1Yb~=g&V63yO>6CTh!x7PK>pj3zU}Vd4O}e>56}XV`^-5kC%e zpF}ThSdf#AoZ0g*c=!Xk6ODfDdQRQVztlk{`>kCD>uJG37I?G0FX z!%e7QMc{(VOz`@S0N%TN4ks0X#%4#xv{}$)=0j^RGt83=)hIG2O~h4;7oxfUBvhPo zHuJuK(KO`upwsV1fVdDO;Kf)0M1;gy62)FXf)g}lLL2()Gx%nn6 z)&UM0`A1?x(bTEfG$Rixf}y#%1Ue#r)aOR9zXO5(PQ(LY81nN8fOhuuY8bUv_U)5l zF=gQcqV)+@2Y(;}0zUIsMQn&6><=JBX9T@21YI7udkLbxFdEw1@m^TM%~lnrE?b46 zBm2n*RM2GDpp;@Tnl0#QZ4!3Z$kv~MoXP?BUiGy*(anlFfh)dpLZ-ZxUBgCw-kQ5{ z$CMJNiQKu7~pirry&nv|E1q+bR)i+uka@#t|=75(ZYRmik81e(G z25|)F0G}_!xDd6UIZP1HFnSW?{&8Z%a0gRp-#!F-UD(?(1L4?rH=Z4?#z^ zneaN1k!eAD{c&OUA=&yf5c>a9WmpmRU|Kdn0G5Rf9@gEy7NLL#)xUieBU~|6Q5n)r z8IX=2N01~$W3sSxDdjIZtOX?`H4+lxfZP#QlHn!D_A;|``MHEpWCVS!9Z+kPi~^dW zP(h_hM}!dot%X49A;D20?Ce0Sw*xu?WJlg2%+xD!{$2ls4b?ZQozVrfO-XY?K0xNG`g?BgpL3|thB+Y3R z6Bw(U3Iz2AgCSVk5WoqNs~8uk!_Q7k;X|Y(8;7=SM&QT+7#vwJJF*cKUrMlaB}ju4 zsRW|r`$~-t8ncxV5JqsI2U@coDT0=Xcw!%42&2^o1A%jxJw#;Khrp0i#sP`fh|JWm zp-Q6@(oJ@ZG{<9AD7;8E54*x;5*O#9yJ^Og|yp%7vJ53)$=bz&EZ26c(WV| zW0g}mK#2HW{l1ImeTg-@5|b-tqwJEe;+4(@#Mz{HJx-{H2B9K#^&YQ9jGdBxd^u7| zEfSnWjGbPJDIiu_K~xXATu4P?GJlt3ys*QNmx*+12AM3!8|sI@p^?}4p=7V1Wa^|b zyj5xG@bomxJII!aGf=v6CDvC@N57~-=gvTHOEcbSY{r!{E8%vz#Mj}U_GdSzl+SX& z$0ELGo=&}xx;i^27ZWB;!q;!P4JrcLc#@&xq{l5}ilUYA3=hFQIEVy8GsrTiG8mvr z*FoayrV%(5JkKBG*b;)nP8m0hRx80zkC13){2>Ap9T1Hm)Z4;T>X#iF8W}<1!b@?< zUH4*|S&xf|2_G_8Zl7L;ok#0Xnd=~^2E=x_NZ2vUSRC+45r2&$X!19y;xDu>%gA)7 z=UlP?C6zNVZNVZ8G77o}hcHMoGeT!XNpQlPfW#G53ZT^Mzq;HQV!W3R!9iSsXJSkJBw6 zfE3J`zW~!`%|^+E^P$elgNv!)9U6v{>L&q;xZENT*f|mS zhK2|_dO1pTT-_v@pdk0^f&$FG^l~KGd>z`o9j(830%ddNplaGQtXTSGjMFG(LMBoz zUHp04S zShSvqyPR|Y!=I@XWHpG9I+tF19TqKK0(Vm*-gx9;eD&(DqH;zhDoP5V=fwS?Fsuf> z*b)7xXpdd~w;b?kA`n`n&*jv)Dz*Be(((zIx9H0#tE$EYmtRSa!4k-B&)MGxug`}A zX=%gci4$v&Hlw%hAm(0h{&tSBi28RecIsm4dg@Mc5z*sHcir<{>5)f&E^Xg;RBH7mr4~<8 zYH%l|TYmJY^!lE9$t1RufhE-ccf$5d{-*av>V4GrsnYBV=1BK`f4$W0O-WBZ`+}JK vqtt&W5&xI)W9r9~7w^B2FXRh3Qvv=9+y1=xNI?3700000NkvXXu0mjfaMbOa literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/tx_minted.png b/src/qt/res/icons/tx_minted.png new file mode 100644 index 0000000000000000000000000000000000000000..6fd6afed2ee4d36ac6b74feb616795d06fde8643 GIT binary patch literal 3043 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 { case TransactionRecord::Generated: + { + QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); + return QIcon(":/icons/tx_mined"); + } case TransactionRecord::StakeMint: - { - QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); - float dd = str.toFloat(); - return QIcon(":/icons/tx_mined"); - } + { + QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); + return QIcon(":/icons/tx_minted"); + } case TransactionRecord::RecvWithAddress: case TransactionRecord::RecvFromOther: return QIcon(":/icons/tx_input"); From e59f0a89c5cf363ba2e0fff1806dc7c28444cead Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 11 Jul 2014 12:54:59 +0300 Subject: [PATCH 049/218] Implement coin control feature. --- src/qt/forms/optionsdialog.ui | 10 + src/qt/forms/sendcoinsdialog.ui | 574 ++++++++++++++++++++++++++++++++ src/qt/optionsdialog.cpp | 1 + src/qt/optionsmodel.cpp | 15 + src/qt/optionsmodel.h | 5 + src/qt/sendcoinsdialog.cpp | 208 +++++++++++- src/qt/sendcoinsdialog.h | 14 + src/qt/sendcoinsentry.cpp | 1 + src/qt/sendcoinsentry.h | 1 + src/qt/walletmodel.cpp | 83 ++++- src/qt/walletmodel.h | 20 +- src/wallet.cpp | 65 ++-- src/wallet.h | 9 +- 13 files changed, 969 insertions(+), 37 deletions(-) diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 6402c2c..2bb9956 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -343,6 +343,16 @@ + + + + Whether to show coin control features or not. + + + Display coin &control features (experts only!) + + + diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index 96896bb..af82d57 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -19,6 +19,580 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} + + 8 + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + 6 + + + 0 + + + 0 + + + 0 + + + 6 + + + + + 0 + + + 10 + + + 10 + + + + + 15 + + + + + + 0 + 0 + + + + + 75 + true + + + + Coin Control Features + + + + + + + + + 8 + + + 10 + + + + + Inputs... + + + + + + + automatically selected + + + 5 + + + + + + + + 75 + true + + + + Insufficient funds! + + + 5 + + + + + + + Qt::Horizontal + + + + 40 + 1 + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 20 + + + 0 + + + 10 + + + + + 10 + + + 14 + + + 10 + + + 4 + + + 6 + + + + + Quantity: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Bytes: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 14 + + + 6 + + + 4 + + + 6 + + + + + Amount: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Priority: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + medium + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 14 + + + 6 + + + 4 + + + 6 + + + + + Fee: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Low Output: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + no + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 14 + + + 6 + + + 4 + + + 6 + + + + + After Fee: + + + 0 + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Change + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + + 12 + + + QLayout::SetDefaultConstraint + + + 5 + + + 5 + + + + + custom change address + + + + + + + false + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + + + 3 + + + + + + + + + Qt::Vertical + + + + 800 + 1 + + + + + + + + + diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 1a438cb..e13bc24 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -148,6 +148,7 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->lang, OptionsModel::Language); mapper->addMapping(ui->unit, OptionsModel::DisplayUnit); mapper->addMapping(ui->displayAddresses, OptionsModel::DisplayAddresses); + mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures); } void OptionsDialog::enableApplyButton() diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 756fe61..abc09a0 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -45,6 +45,7 @@ void OptionsModel::Init() bDisplayAddresses = settings.value("bDisplayAddresses", false).toBool(); fMinimizeToTray = settings.value("fMinimizeToTray", false).toBool(); fMinimizeOnClose = settings.value("fMinimizeOnClose", false).toBool(); + fCoinControlFeatures = settings.value("fCoinControlFeatures", false).toBool(); nTransactionFee = settings.value("nTransactionFee").toLongLong(); language = settings.value("language", "").toString(); @@ -170,6 +171,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const return QVariant(bitdb.GetDetach()); case Language: return settings.value("language", ""); + case CoinControlFeatures: + return QVariant(fCoinControlFeatures); default: return QVariant(); } @@ -239,6 +242,7 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in case Fee: nTransactionFee = value.toLongLong(); settings.setValue("nTransactionFee", nTransactionFee); + emit transactionFeeChanged(nTransactionFee); break; case DisplayUnit: nDisplayUnit = value.toInt(); @@ -258,6 +262,12 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in case Language: settings.setValue("language", value); break; + case CoinControlFeatures: { + fCoinControlFeatures = value.toBool(); + settings.setValue("fCoinControlFeatures", fCoinControlFeatures); + emit coinControlFeaturesChanged(fCoinControlFeatures); + } + break; default: break; } @@ -272,6 +282,11 @@ qint64 OptionsModel::getTransactionFee() return nTransactionFee; } +bool OptionsModel::getCoinControlFeatures() +{ + return fCoinControlFeatures; +} + bool OptionsModel::getMinimizeToTray() { return fMinimizeToTray; diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 34724ad..263b95e 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -30,6 +30,7 @@ class OptionsModel : public QAbstractListModel DisplayAddresses, // bool DetachDatabases, // bool Language, // QString + CoinControlFeatures, // bool OptionIDRowCount, }; @@ -48,6 +49,7 @@ class OptionsModel : public QAbstractListModel bool getMinimizeOnClose(); int getDisplayUnit(); bool getDisplayAddresses(); + bool getCoinControlFeatures(); QString getLanguage() { return language; } private: @@ -55,10 +57,13 @@ class OptionsModel : public QAbstractListModel bool bDisplayAddresses; bool fMinimizeToTray; bool fMinimizeOnClose; + bool fCoinControlFeatures; QString language; signals: void displayUnitChanged(int unit); + void transactionFeeChanged(qint64); + void coinControlFeaturesChanged(bool); }; #endif // OPTIONSMODEL_H diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index efbaed4..dfce5b3 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -1,18 +1,23 @@ #include "sendcoinsdialog.h" #include "ui_sendcoinsdialog.h" +#include "init.h" #include "walletmodel.h" +#include "addresstablemodel.h" +#include "addressbookpage.h" #include "bitcoinunits.h" #include "addressbookpage.h" #include "optionsmodel.h" #include "sendcoinsentry.h" #include "guiutil.h" #include "askpassphrasedialog.h" -#include "base58.h" +#include "coincontrol.h" +#include "coincontroldialog.h" #include #include #include #include +#include SendCoinsDialog::SendCoinsDialog(QWidget *parent) : QDialog(parent), @@ -31,7 +36,39 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) : connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addEntry())); connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); - + + // Coin Control + ui->lineEditCoinControlChange->setFont(GUIUtil::bitcoinAddressFont()); + connect(ui->pushButtonCoinControl, SIGNAL(clicked()), this, SLOT(coinControlButtonClicked())); + connect(ui->checkBoxCoinControlChange, SIGNAL(stateChanged(int)), this, SLOT(coinControlChangeChecked(int))); + connect(ui->lineEditCoinControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(coinControlChangeEdited(const QString &))); + + // Coin Control: clipboard actions + QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this); + QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this); + QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this); + QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this); + QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this); + QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this); + QAction *clipboardLowOutputAction = new QAction(tr("Copy low output"), this); + QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); + connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity())); + connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAmount())); + connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardFee())); + connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAfterFee())); + connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardBytes())); + connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardPriority())); + connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardLowOutput())); + connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardChange())); + ui->labelCoinControlQuantity->addAction(clipboardQuantityAction); + ui->labelCoinControlAmount->addAction(clipboardAmountAction); + ui->labelCoinControlFee->addAction(clipboardFeeAction); + ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction); + ui->labelCoinControlBytes->addAction(clipboardBytesAction); + ui->labelCoinControlPriority->addAction(clipboardPriorityAction); + ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction); + ui->labelCoinControlChange->addAction(clipboardChangeAction); + fNewRecipientAllowed = true; } @@ -52,6 +89,12 @@ void SendCoinsDialog::setModel(WalletModel *model) setBalance(model->getBalance(), model->getStake(), model->getUnconfirmedBalance(), model->getImmatureBalance()); connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64))); connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + // Coin Control + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels())); + connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool))); + connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(qint64)), this, SLOT(coinControlUpdateLabels())); + ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures()); + coinControlUpdateLabels(); } } @@ -124,7 +167,13 @@ void SendCoinsDialog::on_sendButton_clicked() return; } - WalletModel::SendCoinsReturn sendstatus = model->sendCoins(txcomment, recipients); + WalletModel::SendCoinsReturn sendstatus; + + if (!model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures()) + sendstatus = model->sendCoins(txcomment,recipients); + else + sendstatus = model->sendCoins(txcomment,recipients, CoinControlDialog::coinControl); + switch(sendstatus.status) { case WalletModel::InvalidAddress: @@ -167,6 +216,8 @@ void SendCoinsDialog::on_sendButton_clicked() break; case WalletModel::OK: accept(); + CoinControlDialog::coinControl->UnSelectAll(); + coinControlUpdateLabels(); break; } fNewRecipientAllowed = true; @@ -202,6 +253,7 @@ SendCoinsEntry *SendCoinsDialog::addEntry() entry->setModel(model); ui->entries->addWidget(entry); connect(entry, SIGNAL(removeEntry(SendCoinsEntry*)), this, SLOT(removeEntry(SendCoinsEntry*))); + connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels())); updateRemoveEnabled(); @@ -229,6 +281,7 @@ void SendCoinsDialog::updateRemoveEnabled() } } setupTabChain(0); + coinControlUpdateLabels(); } void SendCoinsDialog::removeEntry(SendCoinsEntry* entry) @@ -311,3 +364,152 @@ void SendCoinsDialog::updateDisplayUnit() ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), model->getBalance())); } } + + // Coin Control: copy label "Quantity" to clipboard + void SendCoinsDialog::coinControlClipboardQuantity() + { + QApplication::clipboard()->setText(ui->labelCoinControlQuantity->text()); + } + + // Coin Control: copy label "Amount" to clipboard + void SendCoinsDialog::coinControlClipboardAmount() + { + QApplication::clipboard()->setText(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" "))); + } + + // Coin Control: copy label "Fee" to clipboard + void SendCoinsDialog::coinControlClipboardFee() + { + QApplication::clipboard()->setText(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" "))); + } + + // Coin Control: copy label "After fee" to clipboard + void SendCoinsDialog::coinControlClipboardAfterFee() + { + QApplication::clipboard()->setText(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" "))); + } + + // Coin Control: copy label "Bytes" to clipboard + void SendCoinsDialog::coinControlClipboardBytes() + { + QApplication::clipboard()->setText(ui->labelCoinControlBytes->text()); + } + + // Coin Control: copy label "Priority" to clipboard + void SendCoinsDialog::coinControlClipboardPriority() + { + QApplication::clipboard()->setText(ui->labelCoinControlPriority->text()); + } + + // Coin Control: copy label "Low output" to clipboard + void SendCoinsDialog::coinControlClipboardLowOutput() + { + QApplication::clipboard()->setText(ui->labelCoinControlLowOutput->text()); + } + + // Coin Control: copy label "Change" to clipboard + void SendCoinsDialog::coinControlClipboardChange() + { + QApplication::clipboard()->setText(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" "))); + } + + // Coin Control: settings menu - coin control enabled/disabled by user + void SendCoinsDialog::coinControlFeatureChanged(bool checked) + { + ui->frameCoinControl->setVisible(checked); + + if (!checked && model) // coin control features disabled + CoinControlDialog::coinControl->SetNull(); + } + + // Coin Control: button inputs -> show actual coin control dialog + void SendCoinsDialog::coinControlButtonClicked() + { + CoinControlDialog dlg; + dlg.setModel(model); + dlg.exec(); + coinControlUpdateLabels(); + } + + // Coin Control: checkbox custom change address + void SendCoinsDialog::coinControlChangeChecked(int state) + { + if (model) + { + if (state == Qt::Checked) + CoinControlDialog::coinControl->destChange = CBitcoinAddress(ui->lineEditCoinControlChange->text().toStdString()).Get(); + else + CoinControlDialog::coinControl->destChange = CNoDestination(); + } + + ui->lineEditCoinControlChange->setEnabled((state == Qt::Checked)); + ui->labelCoinControlChangeLabel->setEnabled((state == Qt::Checked)); + } + + // Coin Control: custom change address changed + void SendCoinsDialog::coinControlChangeEdited(const QString & text) + { + if (model) + { + CoinControlDialog::coinControl->destChange = CBitcoinAddress(text.toStdString()).Get(); + + // label for the change address + ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:black;}"); + if (text.isEmpty()) + ui->labelCoinControlChangeLabel->setText(""); + else if (!CBitcoinAddress(text.toStdString()).IsValid()) + { + ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}"); + ui->labelCoinControlChangeLabel->setText(tr("WARNING: Invalid Bitcoin address")); + } + else + { + QString associatedLabel = model->getAddressTableModel()->labelForAddress(text); + if (!associatedLabel.isEmpty()) + ui->labelCoinControlChangeLabel->setText(associatedLabel); + else + { + CPubKey pubkey; + CKeyID keyid; + CBitcoinAddress(text.toStdString()).GetKeyID(keyid); + if (model->getPubKey(keyid, pubkey)) + ui->labelCoinControlChangeLabel->setText(tr("(no label)")); + else + { + ui->labelCoinControlChangeLabel->setStyleSheet("QLabel{color:red;}"); + ui->labelCoinControlChangeLabel->setText(tr("WARNING: unknown change address")); + } + } + } + } + } + + // Coin Control: update labels + void SendCoinsDialog::coinControlUpdateLabels() + { + if (!model || !model->getOptionsModel() || !model->getOptionsModel()->getCoinControlFeatures()) + return; + // set pay amounts + CoinControlDialog::payAmounts.clear(); + for(int i = 0; i < ui->entries->count(); ++i) + { + SendCoinsEntry *entry = qobject_cast(ui->entries->itemAt(i)->widget()); + if(entry) + CoinControlDialog::payAmounts.append(entry->getValue().amount); + } + if (CoinControlDialog::coinControl->HasSelected()) + { + // actual coin control calculation + CoinControlDialog::updateLabels(model, this); + // show coin control stats + ui->labelCoinControlAutomaticallySelected->hide(); + ui->widgetCoinControl->show(); + } + else + { + // hide coin control stats + ui->labelCoinControlAutomaticallySelected->show(); + ui->widgetCoinControl->hide(); + ui->labelCoinControlInsuffFunds->hide(); + } +} diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 32bb61a..68424bb 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -2,6 +2,7 @@ #define SENDCOINSDIALOG_H #include +#include namespace Ui { class SendCoinsDialog; @@ -49,6 +50,19 @@ private slots: void on_sendButton_clicked(); void removeEntry(SendCoinsEntry* entry); void updateDisplayUnit(); + void coinControlFeatureChanged(bool); + void coinControlButtonClicked(); + void coinControlChangeChecked(int); + void coinControlChangeEdited(const QString &); + void coinControlUpdateLabels(); + void coinControlClipboardQuantity(); + void coinControlClipboardAmount(); + void coinControlClipboardFee(); + void coinControlClipboardAfterFee(); + void coinControlClipboardBytes(); + void coinControlClipboardPriority(); + void coinControlClipboardLowOutput(); + void coinControlClipboardChange(); }; #endif // SENDCOINSDIALOG_H diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index f00cf1b..2869df4 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -72,6 +72,7 @@ void SendCoinsEntry::setModel(WalletModel *model) if(model && model->getOptionsModel()) connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(ui->payAmount, SIGNAL(textChanged()), this, SIGNAL(payAmountChanged())); clear(); } diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h index 0ac14c1..4148128 100644 --- a/src/qt/sendcoinsentry.h +++ b/src/qt/sendcoinsentry.h @@ -39,6 +39,7 @@ public slots: signals: void removeEntry(SendCoinsEntry *entry); + void payAmountChanged(); private slots: void on_deleteButton_clicked(); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index d43a739..320a300 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -131,7 +131,7 @@ bool WalletModel::validateAddress(const QString &address) return addressParsed.IsValid(); } -WalletModel::SendCoinsReturn WalletModel::sendCoins(const QString &txcomment, const QList &recipients) +WalletModel::SendCoinsReturn WalletModel::sendCoins(const QString &txcomment, const QList &recipients, const CCoinControl *coinControl) { qint64 total = 0; QSet setAddress; @@ -163,12 +163,18 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QString &txcomment, co return DuplicateAddress; } - if(total > getBalance()) + int64 nBalance = 0; + std::vector vCoins; + wallet->AvailableCoins(vCoins, true, coinControl); + + BOOST_FOREACH(const COutput& out, vCoins) + nBalance += out.tx->vout[out.i].nValue; + if(total > nBalance) { return AmountExceedsBalance; } - if((total + nTransactionFee) > getBalance()) + if((total + nTransactionFee) > nBalance) { return SendCoinsReturn(AmountWithFeeExceedsBalance, nTransactionFee); } @@ -191,11 +197,11 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(const QString &txcomment, co std::string strTxComment = txcomment.toStdString(); if (!strTxComment.empty()) strTxComment = "text:" + strTxComment; - bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strTxComment); + bool fCreated = wallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strTxComment, coinControl); if(!fCreated) { - if((total + nFeeRequired) > wallet->GetBalance()) + if((total + nFeeRequired) > nBalance) // FIXME: could cause collisions in the future { return SendCoinsReturn(AmountWithFeeExceedsBalance, nFeeRequired); } @@ -394,3 +400,70 @@ void WalletModel::UnlockContext::CopyFrom(const UnlockContext& rhs) *this = rhs; rhs.relock = false; } + + bool WalletModel::getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const + { + return wallet->GetPubKey(address, vchPubKeyOut); + } + + // returns a list of COutputs from COutPoints + void WalletModel::getOutputs(const std::vector& vOutpoints, std::vector& vOutputs) + { + BOOST_FOREACH(const COutPoint& outpoint, vOutpoints) + { + if (!wallet->mapWallet.count(outpoint.hash)) continue; + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain()); + vOutputs.push_back(out); + } + } + + // AvailableCoins + LockedCoins grouped by wallet address (put change in one group with wallet address) + void WalletModel::listCoins(std::map >& mapCoins) const + { + std::vector vCoins; + wallet->AvailableCoins(vCoins); + std::vector vLockedCoins; + + // add locked coins + BOOST_FOREACH(const COutPoint& outpoint, vLockedCoins) + { + if (!wallet->mapWallet.count(outpoint.hash)) continue; + COutput out(&wallet->mapWallet[outpoint.hash], outpoint.n, wallet->mapWallet[outpoint.hash].GetDepthInMainChain()); + vCoins.push_back(out); + } + + BOOST_FOREACH(const COutput& out, vCoins) + { + COutput cout = out; + + while (wallet->IsChange(cout.tx->vout[cout.i]) && cout.tx->vin.size() > 0 && wallet->IsMine(cout.tx->vin[0])) + { + if (!wallet->mapWallet.count(cout.tx->vin[0].prevout.hash)) break; + cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0); + } + + CTxDestination address; + if(!ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address)) continue; + mapCoins[CBitcoinAddress(address).ToString().c_str()].push_back(out); + } + } + + bool WalletModel::isLockedCoin(uint256 hash, unsigned int n) const + { + return false; + } + + void WalletModel::lockCoin(COutPoint& output) + { + return; + } + + void WalletModel::unlockCoin(COutPoint& output) + { + return; + } + + void WalletModel::listLockedCoins(std::vector& vOutpts) + { + return; + } diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 5890b42..fc71da9 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -2,6 +2,8 @@ #define WALLETMODEL_H #include +#include +#include #include "allocators.h" /* for SecureString */ @@ -9,6 +11,12 @@ class OptionsModel; class AddressTableModel; class TransactionTableModel; class CWallet; +class CKeyID; +class CPubKey; +class COutput; +class COutPoint; +class uint256; +class CCoinControl; QT_BEGIN_NAMESPACE class QTimer; @@ -68,7 +76,7 @@ class WalletModel : public QObject // Return status record for SendCoins, contains error id + information struct SendCoinsReturn { - SendCoinsReturn(StatusCode status, + SendCoinsReturn(StatusCode status=Aborted, qint64 fee=0, QString hex=QString()): status(status), fee(fee), hex(hex) {} @@ -78,7 +86,7 @@ class WalletModel : public QObject }; // Send coins to a list of recipients - SendCoinsReturn sendCoins(const QString &txcomment, const QList &recipients); + SendCoinsReturn sendCoins(const QString &txcomment, const QList &recipients, const CCoinControl *coinControl=NULL); // Wallet encryption bool setWalletEncrypted(bool encrypted, const SecureString &passphrase); @@ -109,6 +117,14 @@ class WalletModel : public QObject }; UnlockContext requestUnlock(); + + bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; + void getOutputs(const std::vector& vOutpoints, std::vector& vOutputs); + void listCoins(std::map >& mapCoins) const; + bool isLockedCoin(uint256 hash, unsigned int n) const; + void lockCoin(COutPoint& output); + void unlockCoin(COutPoint& output); + void listLockedCoins(std::vector& vOutpts); private: CWallet *wallet; diff --git a/src/wallet.cpp b/src/wallet.cpp index 2132e0d..e6dd002 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -10,6 +10,8 @@ #include "ui_interface.h" #include "base58.h" #include "kernel.h" +#include "coincontrol.h" + #include using namespace std; @@ -1010,7 +1012,7 @@ int64 CWallet::GetImmatureBalance() const } // populate vCoins with vector of spendable COutputs -void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed) const +void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const { vCoins.clear(); @@ -1033,7 +1035,8 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed) const continue; for (unsigned int i = 0; i < pcoin->vout.size(); i++) - if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue > 0) + if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue > 0 && + (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); } } @@ -1209,20 +1212,28 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in return true; } -bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64& nValueRet) const +bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64& nValueRet, const CCoinControl* coinControl) const { vector vCoins; - AvailableCoins(vCoins); + AvailableCoins(vCoins, true, coinControl); + + // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) + if (coinControl && coinControl->HasSelected()) + { + BOOST_FOREACH(const COutput& out, vCoins) + { + nValueRet += out.tx->vout[out.i].nValue; + setCoinsRet.insert(make_pair(out.tx, out.i)); + } + return (nValueRet >= nTargetValue); + } return (SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 6, vCoins, setCoinsRet, nValueRet) || SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 1, vCoins, setCoinsRet, nValueRet) || SelectCoinsMinConf(nTargetValue, nSpendTime, 0, 1, vCoins, setCoinsRet, nValueRet)); } - - - -bool CWallet::CreateTransaction(const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment) +bool CWallet::CreateTransaction(const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment, const CCoinControl* coinControl) { int64 nValue = 0; BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend) @@ -1262,7 +1273,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // Choose coins to use set > setCoins; int64 nValueIn = 0; - if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn)) + if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn, coinControl)) return false; BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { @@ -1290,23 +1301,31 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW if (nChange > 0) { - // Note: We use a new key here to keep it from being obvious which side is the change. - // The drawback is that by not reusing a previous key, the change may be lost if a - // backup is restored, if the backup doesn't have the new private key for the change. - // If we reused the old key, it would be possible to add code to look for and - // rediscover unknown transactions that were written with keys of ours to recover - // post-backup change. - - // Reserve a new key pair from key pool - CPubKey vchPubKey = reservekey.GetReservedKey(); - // assert(mapKeys.count(vchPubKey)); - // Fill a vout to ourself // TODO: pass in scriptChange instead of reservekey so // change transaction isn't always pay-to-bitcoin-address CScript scriptChange; - scriptChange.SetDestination(vchPubKey.GetID()); + // coin control: send change to custom address + if (coinControl && !boost::get(&coinControl->destChange)) + scriptChange.SetDestination(coinControl->destChange); + + // no coin control: send change to newly generated address + else + { + // Note: We use a new key here to keep it from being obvious which side is the change. + // The drawback is that by not reusing a previous key, the change may be lost if a + // backup is restored, if the backup doesn't have the new private key for the change. + // If we reused the old key, it would be possible to add code to look for and + // rediscover unknown transactions that were written with keys of ours to recover + // post-backup change. + + // Reserve a new key pair from key pool + CPubKey vchPubKey = reservekey.GetReservedKey(); + + scriptChange.SetDestination(vchPubKey.GetID()); + } + // Insert change txn at random position: vector::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); wtxNew.vout.insert(position, CTxOut(nChange, scriptChange)); @@ -1351,11 +1370,11 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW return true; } -bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment) +bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment, const CCoinControl* coinControl) { vector< pair > vecSend; vecSend.push_back(make_pair(scriptPubKey, nValue)); - return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strTxComment); + return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strTxComment, coinControl); } // Diamond: get current stake generation power diff --git a/src/wallet.h b/src/wallet.h index 7ac9133..41dd767 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -23,6 +23,7 @@ class CAccountingEntry; class CWalletTx; class CReserveKey; class COutput; +class CCoinControl; /** (client) version numbers for particular wallet features */ enum WalletFeature @@ -69,7 +70,7 @@ class CKeyPool class CWallet : public CCryptoKeyStore { private: - bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64& nValueRet) const; + bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64& nValueRet, const CCoinControl *coinControl=NULL) const; CWalletDB *pwalletdbEncryption; @@ -123,7 +124,7 @@ class CWallet : public CCryptoKeyStore // check whether we are allowed to upgrade (or already support) to the named feature bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; } - void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true) const; + void AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL) const; bool SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64& nValueRet) const; // keystore implementation // Generate a new key @@ -174,8 +175,8 @@ class CWallet : public CCryptoKeyStore int64 GetImmatureBalance() const; int64 GetStake() const; int64 GetNewMint() const; - bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment); - bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment); + bool CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment, const CCoinControl *coinControl=NULL); + bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, std::string strTxComment, const CCoinControl *coinControl=NULL); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); uint64 GetStakeMintPower(const CKeyStore& keystore); bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight); From 190f52be41369b285a93de09589d5076071b20d8 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 11 Jul 2014 12:59:55 +0300 Subject: [PATCH 050/218] Typos and Qt styling fixes. --- src/json/json_spirit_writer_template.h | 2 +- src/qt/bitcoinstrings.cpp | 4 +- src/qt/forms/addressbookpage.ui | 32 +++------------ src/qt/forms/editaddressdialog.ui | 2 +- src/qt/forms/optionsdialog.ui | 2 +- src/qt/forms/overviewpage.ui | 4 +- src/qt/forms/sendcoinsdialog.ui | 54 ++++++++++++-------------- src/qt/forms/sendcoinsentry.ui | 31 +++++---------- src/qt/forms/transactiondescdialog.ui | 5 +-- src/qt/guiutil.cpp | 1 + src/qt/rpcconsole.cpp | 2 +- src/qt/sendcoinsentry.cpp | 3 ++ src/qt/transactionview.cpp | 4 +- 13 files changed, 55 insertions(+), 91 deletions(-) diff --git a/src/json/json_spirit_writer_template.h b/src/json/json_spirit_writer_template.h index 28c49dd..3cd8eb0 100644 --- a/src/json/json_spirit_writer_template.h +++ b/src/json/json_spirit_writer_template.h @@ -28,7 +28,7 @@ namespace json_spirit template< class String_type > String_type non_printable_to_string( unsigned int c ) { - typedef typename String_type::value_type Char_type; + //typedef typename String_type::value_type Char_type; String_type result( 6, '\\' ); diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 50f2430..c386c83 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -44,7 +44,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Execute command when the best block changes (%s in cmd is replaced by block " "hash)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Listen for JSON-RPC connections on (default: 8344 or testnet: 18344)"), +"Listen for JSON-RPC connections on (default: 17772 or testnet: 27772)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Number of seconds to keep misbehaving peers from reconnecting (default: " "86400)"), @@ -116,7 +116,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=: '%s'") QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -reservebalance="), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"), QT_TRANSLATE_NOOP("bitcoin-core", "List commands"), -QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on (default: 27772 or testnet: 17772)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on (default: 17771 or testnet: 27771)"), QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading block index..."), QT_TRANSLATE_NOOP("bitcoin-core", "Loading wallet..."), diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui index 70ef9d4..8dacba1 100644 --- a/src/qt/forms/addressbookpage.ui +++ b/src/qt/forms/addressbookpage.ui @@ -14,14 +14,16 @@ Address Book - AddressBookPage{background:transparent; color: white;} + + AddressBookPage{background:transparent; color: white;} + QTableView {background-color:rgb(69, 87, 96); color:white;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} + QPushButton {background-color:rgb(69, 87, 96); color: white;} + - - color:white; - These are your Diamond addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you. @@ -483,10 +485,6 @@ Double-click to edit address or label - - QTableView {background-color:rgb(69, 87, 96); color:white;} -QToolTip {background-color:#1f333e; color:white; border-style: none;} - false @@ -514,9 +512,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Create a new address - - background-color:rgb(69, 87, 96); color: white; - &New Address @@ -531,9 +526,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Copy the currently selected address to the system clipboard - - background-color:rgb(69, 87, 96); color: white; - &Copy Address @@ -545,9 +537,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} - - background-color:rgb(69, 87, 96); color: white; - Show &QR Code @@ -562,9 +551,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Sign a message to prove you own a Diamond address - - background-color:rgb(69, 87, 96); color: white; - Sign &Message @@ -579,9 +565,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Verify a message to ensure it was signed with a specified Diamond address - - background-color:rgb(69, 87, 96); color: white; - &Verify Message @@ -596,9 +579,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Delete the currently selected address from the list - - background-color:rgb(69, 87, 96); color: white; - &Delete diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui index 10577f4..d6ec6bb 100644 --- a/src/qt/forms/editaddressdialog.ui +++ b/src/qt/forms/editaddressdialog.ui @@ -38,7 +38,7 @@ The label associated with this address book entry - + background-color:#1f333e; color:white; border: none; diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 2bb9956..6bca13e 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -33,7 +33,7 @@ - Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.01 recommended. + Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB. Fee 0.001 recommended. Qt::PlainText diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 02e933f..756d570 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -22,7 +22,7 @@ - background-color:rgba(255, 255, 255, 40); color: white; + background-color:transparent; color:white; QFrame::StyledPanel @@ -308,7 +308,7 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} - background-color:rgba(255, 255, 255, 40); color: white; + background-color:transparent; color:white; QFrame::StyledPanel diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui index af82d57..6cb282d 100644 --- a/src/qt/forms/sendcoinsdialog.ui +++ b/src/qt/forms/sendcoinsdialog.ui @@ -6,17 +6,23 @@ 0 0 - 686 - 234 + 831 + 390 Send Coins - SendCoinsDialog {background:transparent; color:white;} -QToolTip {background-color:#1f333e; color:white; border-style: none;} - + + SendCoinsDialog {background:transparent; color:white;} + QPushButton {background-color:rgb(69, 87, 96); color:white;} + QLabel {background-color:transparent; color:white;} + QFrame {background-color:transparent; color:white;} + QCheckBox {background-color:transparent; color:white;} + QLineEdit {background-color:#1f333e; color:white; border: none;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} + @@ -595,9 +601,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} - - background-color:rgb(69, 87, 96) - QFrame::StyledPanel @@ -608,15 +611,12 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} - <html><head/><body><p><span style=" color:#ffffff;">Transaction comment:</span></p></body></html> + Transaction comment: - - color:white; - @@ -624,10 +624,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} - - -background-color:rgba(255, 255, 255, 40); color: white; - true @@ -641,7 +637,7 @@ background-color:rgba(255, 255, 255, 40); color: white; - background:transparent; + background-color:rgb(59, 88, 104); @@ -687,10 +683,6 @@ background-color:rgba(255, 255, 255, 40); color: white; Send to multiple recipients at once - - QPushButton {background-color:rgb(69, 87, 96); color: white;} -QToolTip {background-color:#1f333e; color:white; border-style: none;} - Add &Recipient @@ -717,10 +709,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Remove all transaction fields - - QPushButton {background-color:rgb(69, 87, 96); color: white;} -QToolTip {background-color:#1f333e; color:white; border-style: none;} - Clear &All @@ -743,6 +731,12 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} + + + 0 + 0 + + Balance: @@ -750,6 +744,12 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} + + + 0 + 0 + + IBeamCursor @@ -787,10 +787,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Confirm the send action - - QPushButton {background-color:rgb(69, 87, 96); color: white;} -QToolTip {background-color:#1f333e; color:white; border-style: none;} - S&end diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 259c3dd..516fe4f 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -14,9 +14,10 @@ Form - background-color:rgb(69, 87, 96); -QPushButton{background-color:rgba(97, 147, 174, 255);color:white;} -QToolTip {background-color:#1f333e !important; color:white !important; border-style: none;} + background-color:transparent; + QLabel {background-color:transparent; color:white;} + QToolTip {background-color:#1f333e !important; color:white !important; border-style: none;} + QFrame::StyledPanel @@ -31,7 +32,7 @@ QToolTip {background-color:#1f333e !important; color:white !important; border-st - <html><head/><body><p><span style=" color:#ffffff;">A&amp;mount:</span></p></body></html> + A&mount: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -44,7 +45,7 @@ QToolTip {background-color:#1f333e !important; color:white !important; border-st - <html><head/><body><p><span style=" color:#ffffff;">Pay &amp;To:</span></p></body></html> + Pay &To: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -58,7 +59,8 @@ QToolTip {background-color:#1f333e !important; color:white !important; border-st color:white; -QToolTip {background-color:#1f333e; color:white; border-style: none;} + QToolTip {background-color:#1f333e; color:white; border-style: none;} + @@ -75,9 +77,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Enter a label for this address to add it to your address book - - QToolTip {background-color:#1f333e; color:white; border-style: none;} - @@ -85,7 +84,7 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} - <html><head/><body><p><span style=" color:#ffffff;">&amp;Label:</span></p></body></html> + &Label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -105,9 +104,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} The address to send the payment to (e.g. dc8hQjs9oy9AHPCSF5aTvkcRVECojV3joC) - - QToolTip {background-color:#1f333e; color:white; border-style: none;} - 34 @@ -118,9 +114,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Choose address from address book - - QToolTip {background-color:#1f333e; color:white; border-style: none;} - @@ -138,9 +131,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Paste address from clipboard - - QToolTip {background-color:#1f333e; color:white; border-style: none;} - @@ -158,9 +148,6 @@ QToolTip {background-color:#1f333e; color:white; border-style: none;} Remove this recipient - - QToolTip {background-color:#1f333e; color:white; border-style: none;} - diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui index 2203e6a..f3300c1 100644 --- a/src/qt/forms/transactiondescdialog.ui +++ b/src/qt/forms/transactiondescdialog.ui @@ -14,7 +14,7 @@ Transaction details - TransactionDescDialog{background: transparent;} + TransactionDescDialog{background: transparent; color:white;} @@ -22,9 +22,6 @@ This pane shows a detailed description of the transaction - - - true diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index e5494de..add7991 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -22,6 +22,7 @@ #include #include #include + #include #include diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 0aa82d1..aebe43e 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -20,7 +20,7 @@ // TODO: make it possible to filter out categories (esp debug messages when implemented) // TODO: receive errors and debug messages through ClientModel -const int CONSOLE_SCROLLBACK = 50; +//const int CONSOLE_SCROLLBACK = 50; const int CONSOLE_HISTORY = 50; const QSize ICON_SIZE(24, 24); diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 2869df4..2bed6cb 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -23,7 +23,10 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) : #if QT_VERSION >= 0x040700 /* Do not move this to the XML file, Qt before 4.7 will choke on it */ ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book")); + ui->addAsLabel->setStyleSheet("background-color:#1f333e; color:white; border:none;"); ui->payTo->setPlaceholderText(tr("Enter a valid Diamond address")); + ui->payTo->setStyleSheet("background-color:#1f333e; color:white; border:none;"); + ui->payAmount->setStyleSheet("background-color:#1f333e; color:white; border:none;"); #endif setFocusPolicy(Qt::TabFocus); setFocusProxy(ui->payTo); diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index b7b025a..427fdb0 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -35,8 +35,7 @@ TransactionView::TransactionView(QWidget *parent) : { // Build filter row setContentsMargins(0,0,0,0); - setStyleSheet("background-color:rgba(255, 255, 255, 40); color: white;"); - + setStyleSheet("background-color:#1f333e; color: white;"); QHBoxLayout *hlayout = new QHBoxLayout(); hlayout->setContentsMargins(0,0,0,0); @@ -86,6 +85,7 @@ TransactionView::TransactionView(QWidget *parent) : #if QT_VERSION >= 0x040700 /* Do not move this to the XML file, Qt before 4.7 will choke on it */ addressWidget->setPlaceholderText(tr("Enter address or label to search")); + addressWidget->setStyleSheet("background-color:#1f333e; color:white; border:none;"); #endif hlayout->addWidget(addressWidget); From 92a1cfa3433bd09438375588a5888fbe91f8ecb3 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 11 Jul 2014 13:00:19 +0300 Subject: [PATCH 051/218] Commit some missing pieces of coin control. --- src/coincontrol.h | 57 +++ src/qt/coincontroldialog.cpp | 742 ++++++++++++++++++++++++++++++ src/qt/coincontroldialog.h | 92 ++++ src/qt/coincontroltreewidget.cpp | 28 ++ src/qt/coincontroltreewidget.h | 17 + src/qt/forms/coincontroldialog.ui | 554 ++++++++++++++++++++++ 6 files changed, 1490 insertions(+) create mode 100644 src/coincontrol.h create mode 100644 src/qt/coincontroldialog.cpp create mode 100644 src/qt/coincontroldialog.h create mode 100644 src/qt/coincontroltreewidget.cpp create mode 100644 src/qt/coincontroltreewidget.h create mode 100644 src/qt/forms/coincontroldialog.ui diff --git a/src/coincontrol.h b/src/coincontrol.h new file mode 100644 index 0000000..236b586 --- /dev/null +++ b/src/coincontrol.h @@ -0,0 +1,57 @@ +#ifndef COINCONTROL_H +#define COINCONTROL_H + +/** Coin Control Features. */ +class CCoinControl +{ +public: + CTxDestination destChange; + + CCoinControl() + { + SetNull(); + } + + void SetNull() + { + destChange = CNoDestination(); + setSelected.clear(); + } + + bool HasSelected() const + { + return (setSelected.size() > 0); + } + + bool IsSelected(const uint256& hash, unsigned int n) const + { + COutPoint outpt(hash, n); + return (setSelected.count(outpt) > 0); + } + + void Select(COutPoint& output) + { + setSelected.insert(output); + } + + void UnSelect(COutPoint& output) + { + setSelected.erase(output); + } + + void UnSelectAll() + { + setSelected.clear(); + } + + void ListSelected(std::vector& vOutpoints) + { + vOutpoints.assign(setSelected.begin(), setSelected.end()); + } + +private: + std::set setSelected; + +}; + +#endif // COINCONTROL_H diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp new file mode 100644 index 0000000..b2aadeb --- /dev/null +++ b/src/qt/coincontroldialog.cpp @@ -0,0 +1,742 @@ +#include "coincontroldialog.h" +#include "ui_coincontroldialog.h" + +#include "init.h" +#include "bitcoinunits.h" +#include "walletmodel.h" +#include "addresstablemodel.h" +#include "optionsmodel.h" +#include "coincontrol.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +QList CoinControlDialog::payAmounts; +CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); + +CoinControlDialog::CoinControlDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CoinControlDialog), + model(0) +{ + ui->setupUi(this); + + // context menu actions + QAction *copyAddressAction = new QAction(tr("Copy address"), this); + QAction *copyLabelAction = new QAction(tr("Copy label"), this); + QAction *copyAmountAction = new QAction(tr("Copy amount"), this); + copyTransactionHashAction = new QAction(tr("Copy transaction ID"), this); // we need to enable/disable this + //lockAction = new QAction(tr("Lock unspent"), this); // we need to enable/disable this + //unlockAction = new QAction(tr("Unlock unspent"), this); // we need to enable/disable this + + // context menu + contextMenu = new QMenu(); + contextMenu->addAction(copyAddressAction); + contextMenu->addAction(copyLabelAction); + contextMenu->addAction(copyAmountAction); + contextMenu->addAction(copyTransactionHashAction); + //contextMenu->addSeparator(); + //contextMenu->addAction(lockAction); + //contextMenu->addAction(unlockAction); + + // context menu signals + connect(ui->treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint))); + connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress())); + connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel())); + connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); + connect(copyTransactionHashAction, SIGNAL(triggered()), this, SLOT(copyTransactionHash())); + //connect(lockAction, SIGNAL(triggered()), this, SLOT(lockCoin())); + //connect(unlockAction, SIGNAL(triggered()), this, SLOT(unlockCoin())); + + // clipboard actions + QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this); + QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this); + QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this); + QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this); + QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this); + QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this); + QAction *clipboardLowOutputAction = new QAction(tr("Copy low output"), this); + QAction *clipboardChangeAction = new QAction(tr("Copy change"), this); + + connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(clipboardQuantity())); + connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(clipboardAmount())); + connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(clipboardFee())); + connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(clipboardAfterFee())); + connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(clipboardBytes())); + connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(clipboardPriority())); + connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(clipboardLowOutput())); + connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(clipboardChange())); + + ui->labelCoinControlQuantity->addAction(clipboardQuantityAction); + ui->labelCoinControlAmount->addAction(clipboardAmountAction); + ui->labelCoinControlFee->addAction(clipboardFeeAction); + ui->labelCoinControlAfterFee->addAction(clipboardAfterFeeAction); + ui->labelCoinControlBytes->addAction(clipboardBytesAction); + ui->labelCoinControlPriority->addAction(clipboardPriorityAction); + ui->labelCoinControlLowOutput->addAction(clipboardLowOutputAction); + ui->labelCoinControlChange->addAction(clipboardChangeAction); + + // toggle tree/list mode + connect(ui->radioTreeMode, SIGNAL(toggled(bool)), this, SLOT(radioTreeMode(bool))); + connect(ui->radioListMode, SIGNAL(toggled(bool)), this, SLOT(radioListMode(bool))); + + // click on checkbox + connect(ui->treeWidget, SIGNAL(itemChanged( QTreeWidgetItem*, int)), this, SLOT(viewItemChanged( QTreeWidgetItem*, int))); + + // click on header +#if QT_VERSION < 0x050000 + ui->treeWidget->header()->setClickable(true); +#else + ui->treeWidget->header()->setSectionsClickable(true); +#endif + connect(ui->treeWidget->header(), SIGNAL(sectionClicked(int)), this, SLOT(headerSectionClicked(int))); + + // ok button + connect(ui->buttonBox, SIGNAL(clicked( QAbstractButton*)), this, SLOT(buttonBoxClicked(QAbstractButton*))); + + // (un)select all + connect(ui->pushButtonSelectAll, SIGNAL(clicked()), this, SLOT(buttonSelectAllClicked())); + + ui->treeWidget->setColumnWidth(COLUMN_CHECKBOX, 84); + ui->treeWidget->setColumnWidth(COLUMN_AMOUNT, 100); + ui->treeWidget->setColumnWidth(COLUMN_LABEL, 170); + ui->treeWidget->setColumnWidth(COLUMN_ADDRESS, 290); + ui->treeWidget->setColumnWidth(COLUMN_DATE, 110); + ui->treeWidget->setColumnWidth(COLUMN_CONFIRMATIONS, 100); + ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); + ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transacton hash in this column, but dont show it + ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but dont show it + ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but dont show it + ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but dont show it + + // default view is sorted by amount desc + sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder); +} + +CoinControlDialog::~CoinControlDialog() +{ + delete ui; +} + +void CoinControlDialog::setModel(WalletModel *model) +{ + this->model = model; + + if(model && model->getOptionsModel() && model->getAddressTableModel()) + { + updateView(); + //updateLabelLocked(); + CoinControlDialog::updateLabels(model, this); + } +} + +// helper function str_pad +QString CoinControlDialog::strPad(QString s, int nPadLength, QString sPadding) +{ + while (s.length() < nPadLength) + s = sPadding + s; + + return s; +} + +// ok button +void CoinControlDialog::buttonBoxClicked(QAbstractButton* button) +{ + if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) + done(QDialog::Accepted); // closes the dialog +} + +// (un)select all +void CoinControlDialog::buttonSelectAllClicked() +{ + Qt::CheckState state = Qt::Checked; + for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) + { + if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != Qt::Unchecked) + { + state = Qt::Unchecked; + break; + } + } + ui->treeWidget->setEnabled(false); + for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) + if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) != state) + ui->treeWidget->topLevelItem(i)->setCheckState(COLUMN_CHECKBOX, state); + ui->treeWidget->setEnabled(true); + CoinControlDialog::updateLabels(model, this); +} + +// context menu +void CoinControlDialog::showMenu(const QPoint &point) +{ + QTreeWidgetItem *item = ui->treeWidget->itemAt(point); + if(item) + { + contextMenuItem = item; + + // disable some items (like Copy Transaction ID, lock, unlock) for tree roots in context menu + if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) + { + copyTransactionHashAction->setEnabled(true); + //if (model->isLockedCoin(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt())) + //{ + // lockAction->setEnabled(false); + // unlockAction->setEnabled(true); + //} + //else + //{ + // lockAction->setEnabled(true); + // unlockAction->setEnabled(false); + //} + } + else // this means click on parent node in tree mode -> disable all + { + copyTransactionHashAction->setEnabled(false); + //lockAction->setEnabled(false); + //unlockAction->setEnabled(false); + } + + // show context menu + contextMenu->exec(QCursor::pos()); + } +} + +// context menu action: copy amount +void CoinControlDialog::copyAmount() +{ + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_AMOUNT)); +} + +// context menu action: copy label +void CoinControlDialog::copyLabel() +{ + if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_LABEL).length() == 0 && contextMenuItem->parent()) + QApplication::clipboard()->setText(contextMenuItem->parent()->text(COLUMN_LABEL)); + else + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_LABEL)); +} + +// context menu action: copy address +void CoinControlDialog::copyAddress() +{ + if (ui->radioTreeMode->isChecked() && contextMenuItem->text(COLUMN_ADDRESS).length() == 0 && contextMenuItem->parent()) + QApplication::clipboard()->setText(contextMenuItem->parent()->text(COLUMN_ADDRESS)); + else + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_ADDRESS)); +} + +// context menu action: copy transaction id +void CoinControlDialog::copyTransactionHash() +{ + QApplication::clipboard()->setText(contextMenuItem->text(COLUMN_TXHASH)); +} + +// context menu action: lock coin +/*void CoinControlDialog::lockCoin() +{ + if (contextMenuItem->checkState(COLUMN_CHECKBOX) == Qt::Checked) + contextMenuItem->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); + + COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + model->lockCoin(outpt); + contextMenuItem->setDisabled(true); + contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + updateLabelLocked(); +}*/ + +// context menu action: unlock coin +/*void CoinControlDialog::unlockCoin() +{ + COutPoint outpt(uint256(contextMenuItem->text(COLUMN_TXHASH).toStdString()), contextMenuItem->text(COLUMN_VOUT_INDEX).toUInt()); + model->unlockCoin(outpt); + contextMenuItem->setDisabled(false); + contextMenuItem->setIcon(COLUMN_CHECKBOX, QIcon()); + updateLabelLocked(); +}*/ + +// copy label "Quantity" to clipboard +void CoinControlDialog::clipboardQuantity() +{ + QApplication::clipboard()->setText(ui->labelCoinControlQuantity->text()); +} + +// copy label "Amount" to clipboard +void CoinControlDialog::clipboardAmount() +{ + QApplication::clipboard()->setText(ui->labelCoinControlAmount->text().left(ui->labelCoinControlAmount->text().indexOf(" "))); +} + +// copy label "Fee" to clipboard +void CoinControlDialog::clipboardFee() +{ + QApplication::clipboard()->setText(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" "))); +} + +// copy label "After fee" to clipboard +void CoinControlDialog::clipboardAfterFee() +{ + QApplication::clipboard()->setText(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" "))); +} + +// copy label "Bytes" to clipboard +void CoinControlDialog::clipboardBytes() +{ + QApplication::clipboard()->setText(ui->labelCoinControlBytes->text()); +} + +// copy label "Priority" to clipboard +void CoinControlDialog::clipboardPriority() +{ + QApplication::clipboard()->setText(ui->labelCoinControlPriority->text()); +} + +// copy label "Low output" to clipboard +void CoinControlDialog::clipboardLowOutput() +{ + QApplication::clipboard()->setText(ui->labelCoinControlLowOutput->text()); +} + +// copy label "Change" to clipboard +void CoinControlDialog::clipboardChange() +{ + QApplication::clipboard()->setText(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" "))); +} + +// treeview: sort +void CoinControlDialog::sortView(int column, Qt::SortOrder order) +{ + sortColumn = column; + sortOrder = order; + ui->treeWidget->sortItems(column, order); + ui->treeWidget->header()->setSortIndicator((sortColumn == COLUMN_AMOUNT_INT64 ? COLUMN_AMOUNT : (sortColumn == COLUMN_PRIORITY_INT64 ? COLUMN_PRIORITY : sortColumn)), sortOrder); +} + +// treeview: clicked on header +void CoinControlDialog::headerSectionClicked(int logicalIndex) +{ + if (logicalIndex == COLUMN_CHECKBOX) // click on most left column -> do nothing + { + ui->treeWidget->header()->setSortIndicator((sortColumn == COLUMN_AMOUNT_INT64 ? COLUMN_AMOUNT : (sortColumn == COLUMN_PRIORITY_INT64 ? COLUMN_PRIORITY : sortColumn)), sortOrder); + } + else + { + if (logicalIndex == COLUMN_AMOUNT) // sort by amount + logicalIndex = COLUMN_AMOUNT_INT64; + + if (logicalIndex == COLUMN_PRIORITY) // sort by priority + logicalIndex = COLUMN_PRIORITY_INT64; + + if (sortColumn == logicalIndex) + sortOrder = ((sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder); + else + { + sortColumn = logicalIndex; + sortOrder = ((sortColumn == COLUMN_AMOUNT_INT64 || sortColumn == COLUMN_PRIORITY_INT64 || sortColumn == COLUMN_DATE || sortColumn == COLUMN_CONFIRMATIONS) ? Qt::DescendingOrder : Qt::AscendingOrder); // if amount,date,conf,priority then default => desc, else default => asc + } + + sortView(sortColumn, sortOrder); + } +} + +// toggle tree mode +void CoinControlDialog::radioTreeMode(bool checked) +{ + if (checked && model) + updateView(); +} + +// toggle list mode +void CoinControlDialog::radioListMode(bool checked) +{ + if (checked && model) + updateView(); +} + +// checkbox clicked by user +void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) +{ + if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode) + { + COutPoint outpt(uint256(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()); + + if (item->checkState(COLUMN_CHECKBOX) == Qt::Unchecked) + coinControl->UnSelect(outpt); + else if (item->isDisabled()) // locked (this happens if "check all" through parent node) + item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); + else + coinControl->Select(outpt); + + // selection changed -> update labels + if (ui->treeWidget->isEnabled()) // do not update on every click for (un)select all + CoinControlDialog::updateLabels(model, this); + } +} + +// helper function, return human readable label for priority number +QString CoinControlDialog::getPriorityLabel(double dPriority) +{ + if (dPriority > 576000ULL) // at least medium, this number is from AllowFree(), the other thresholds are kinda random + { + if (dPriority > 5760000000ULL) return tr("highest"); + else if (dPriority > 576000000ULL) return tr("high"); + else if (dPriority > 57600000ULL) return tr("medium-high"); + else return tr("medium"); + } + else + { + if (dPriority > 5760ULL) return tr("low-medium"); + else if (dPriority > 58ULL) return tr("low"); + else return tr("lowest"); + } +} + +// shows count of locked unspent outputs +/*void CoinControlDialog::updateLabelLocked() +{ + vector vOutpts; + model->listLockedCoins(vOutpts); + if (vOutpts.size() > 0) + { + ui->labelLocked->setText(tr("(%1 locked)").arg(vOutpts.size())); + ui->labelLocked->setVisible(true); + } + else ui->labelLocked->setVisible(false); +}*/ + +void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) +{ + if (!model) return; + + // nPayAmount + qint64 nPayAmount = 0; + bool fLowOutput = false; + bool fDust = false; + CTransaction txDummy; + foreach(const qint64 &amount, CoinControlDialog::payAmounts) + { + nPayAmount += amount; + + if (amount > 0) + { + if (amount < CENT) + fLowOutput = true; + + CTxOut txout(amount, (CScript)vector(24, 0)); + txDummy.vout.push_back(txout); + } + } + + QString sPriorityLabel = ""; + int64 nAmount = 0; + int64 nPayFee = 0; + int64 nAfterFee = 0; + int64 nChange = 0; + unsigned int nBytes = 0; + unsigned int nBytesInputs = 0; + double dPriority = 0; + double dPriorityInputs = 0; + unsigned int nQuantity = 0; + + vector vCoinControl; + vector vOutputs; + coinControl->ListSelected(vCoinControl); + model->getOutputs(vCoinControl, vOutputs); + + BOOST_FOREACH(const COutput& out, vOutputs) + { + // Quantity + nQuantity++; + + // Amount + nAmount += out.tx->vout[out.i].nValue; + + // Priority + dPriorityInputs += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); + + // Bytes + CTxDestination address; + if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) + { + CPubKey pubkey; + CKeyID *keyid = boost::get< CKeyID >(&address); + if (keyid && model->getPubKey(*keyid, pubkey)) + nBytesInputs += (pubkey.IsCompressed() ? 148 : 180); + else + nBytesInputs += 148; // in all error cases, simply assume 148 here + } + else nBytesInputs += 148; + } + + // calculation + if (nQuantity > 0) + { + // Bytes + nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here + + // Priority + dPriority = dPriorityInputs / nBytes; + sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority); + + // Fee + int64 nFee = nTransactionFee * (1 + (int64)nBytes / 1000); + + // Min Fee + int64 nMinFee = txDummy.GetMinFee(1, false, GMF_SEND); + + nPayFee = max(nFee, nMinFee); + + if (nPayAmount > 0) + { + nChange = nAmount - nPayFee - nPayAmount; + + // if sub-cent change is required, the fee must be raised to at least CTransaction::nMinTxFee + if (nPayFee < CENT && nChange > 0 && nChange < CENT) + { + if (nChange < CENT) // change < 0.01 => simply move all change to fees + { + nPayFee = nChange; + nChange = 0; + } + else + { + nChange = nChange + nPayFee - CENT; + nPayFee = CENT; + } + } + + if (nChange == 0) + nBytes -= 34; + } + + // after fee + nAfterFee = nAmount - nPayFee; + if (nAfterFee < 0) + nAfterFee = 0; + } + + // actually update labels + int nDisplayUnit = BitcoinUnits::BTC; + if (model && model->getOptionsModel()) + nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); + + QLabel *l1 = dialog->findChild("labelCoinControlQuantity"); + QLabel *l2 = dialog->findChild("labelCoinControlAmount"); + QLabel *l3 = dialog->findChild("labelCoinControlFee"); + QLabel *l4 = dialog->findChild("labelCoinControlAfterFee"); + QLabel *l5 = dialog->findChild("labelCoinControlBytes"); + QLabel *l6 = dialog->findChild("labelCoinControlPriority"); + QLabel *l7 = dialog->findChild("labelCoinControlLowOutput"); + QLabel *l8 = dialog->findChild("labelCoinControlChange"); + + // enable/disable "low output" and "change" + dialog->findChild("labelCoinControlLowOutputText")->setEnabled(nPayAmount > 0); + dialog->findChild("labelCoinControlLowOutput") ->setEnabled(nPayAmount > 0); + dialog->findChild("labelCoinControlChangeText") ->setEnabled(nPayAmount > 0); + dialog->findChild("labelCoinControlChange") ->setEnabled(nPayAmount > 0); + + // stats + l1->setText(QString::number(nQuantity)); // Quantity + l2->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAmount)); // Amount + l3->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nPayFee)); // Fee + l4->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nAfterFee)); // After Fee + l5->setText(((nBytes > 0) ? "~" : "") + QString::number(nBytes)); // Bytes + l6->setText(sPriorityLabel); // Priority + l7->setText((fLowOutput ? (fDust ? tr("DUST") : tr("yes")) : tr("no"))); // Low Output / Dust + l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change + + // turn labels "red" + l5->setStyleSheet((nBytes >= 10000) ? "color:red;" : ""); // Bytes >= 10000 + l6->setStyleSheet((dPriority <= 576000) ? "color:red;" : ""); // Priority < "medium" + l7->setStyleSheet((fLowOutput) ? "color:red;" : ""); // Low Output = "yes" + l8->setStyleSheet((nChange > 0 && nChange < CENT) ? "color:red;" : ""); // Change < 0.01BTC + + // tool tips + l5->setToolTip(tr("This label turns red, if the transaction size is bigger than 10000 bytes.\n\n This means a fee of at least %1 per kb is required.\n\n Can vary +/- 1 Byte per input.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + l6->setToolTip(tr("Transactions with higher priority get more likely into a block.\n\nThis label turns red, if the priority is smaller than \"medium\".\n\n This means a fee of at least %1 per kb is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + l7->setToolTip(tr("This label turns red, if any recipient receives an amount smaller than %1.\n\n This means a fee of at least %2 is required. \n\n Amounts below 0.546 times the minimum relay fee are shown as DUST.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT)).arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + l8->setToolTip(tr("This label turns red, if the change is smaller than %1.\n\n This means a fee of at least %2 is required.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT)).arg(BitcoinUnits::formatWithUnit(nDisplayUnit, CENT))); + dialog->findChild("labelCoinControlBytesText") ->setToolTip(l5->toolTip()); + dialog->findChild("labelCoinControlPriorityText") ->setToolTip(l6->toolTip()); + dialog->findChild("labelCoinControlLowOutputText")->setToolTip(l7->toolTip()); + dialog->findChild("labelCoinControlChangeText") ->setToolTip(l8->toolTip()); + + // Insufficient funds + QLabel *label = dialog->findChild("labelCoinControlInsuffFunds"); + if (label) + label->setVisible(nChange < 0); +} + +void CoinControlDialog::updateView() +{ + bool treeMode = ui->radioTreeMode->isChecked(); + + ui->treeWidget->clear(); + ui->treeWidget->setEnabled(false); // performance, otherwise updateLabels would be called for every checked checkbox + ui->treeWidget->setAlternatingRowColors(!treeMode); + QFlags flgCheckbox=Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; + QFlags flgTristate=Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; + + int nDisplayUnit = BitcoinUnits::BTC; + if (model && model->getOptionsModel()) + nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); + + map > mapCoins; + model->listCoins(mapCoins); + + BOOST_FOREACH(PAIRTYPE(QString, vector) coins, mapCoins) + { + QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); + QString sWalletAddress = coins.first; + QString sWalletLabel = ""; + if (model->getAddressTableModel()) + sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress); + if (sWalletLabel.length() == 0) + sWalletLabel = tr("(no label)"); + + if (treeMode) + { + // wallet address + ui->treeWidget->addTopLevelItem(itemWalletAddress); + + itemWalletAddress->setFlags(flgTristate); + itemWalletAddress->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); + + for (int i = 0; i < ui->treeWidget->columnCount(); i++) + itemWalletAddress->setBackground(i, QColor(248, 247, 246)); + + // label + itemWalletAddress->setText(COLUMN_LABEL, sWalletLabel); + + // address + itemWalletAddress->setText(COLUMN_ADDRESS, sWalletAddress); + } + + int64 nSum = 0; + double dPrioritySum = 0; + int nChildren = 0; + int nInputSum = 0; + BOOST_FOREACH(const COutput& out, coins.second) + { + int nInputSize = 148; // 180 if uncompressed public key + nSum += out.tx->vout[out.i].nValue; + nChildren++; + + QTreeWidgetItem *itemOutput; + if (treeMode) itemOutput = new QTreeWidgetItem(itemWalletAddress); + else itemOutput = new QTreeWidgetItem(ui->treeWidget); + itemOutput->setFlags(flgCheckbox); + itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); + + // address + CTxDestination outputAddress; + QString sAddress = ""; + if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress)) + { + sAddress = CBitcoinAddress(outputAddress).ToString().c_str(); + + // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs + if (!treeMode || (!(sAddress == sWalletAddress))) + itemOutput->setText(COLUMN_ADDRESS, sAddress); + + CPubKey pubkey; + CKeyID *keyid = boost::get< CKeyID >(&outputAddress); + if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed()) + nInputSize = 180; + } + + // label + if (!(sAddress == sWalletAddress)) // change + { + // tooltip from where the change comes from + itemOutput->setToolTip(COLUMN_LABEL, tr("change from %1 (%2)").arg(sWalletLabel).arg(sWalletAddress)); + itemOutput->setText(COLUMN_LABEL, tr("(change)")); + } + else if (!treeMode) + { + QString sLabel = ""; + if (model->getAddressTableModel()) + sLabel = model->getAddressTableModel()->labelForAddress(sAddress); + if (sLabel.length() == 0) + sLabel = tr("(no label)"); + itemOutput->setText(COLUMN_LABEL, sLabel); + } + + // amount + itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue)); + itemOutput->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(out.tx->vout[out.i].nValue), 15, " ")); // padding so that sorting works correctly + + // date + itemOutput->setText(COLUMN_DATE, QDateTime::fromTime_t(out.tx->GetTxTime()).toUTC().toString("yy-MM-dd hh:mm")); + + // immature PoS reward + if (out.tx->IsCoinStake() && out.tx->GetBlocksToMaturity() > 0 && out.tx->GetDepthInMainChain() > 0) { + itemOutput->setBackground(COLUMN_CONFIRMATIONS, Qt::red); + itemOutput->setDisabled(true); + } + + // confirmations + itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); + + // priority + double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 + itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority)); + itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64)dPriority), 20, " ")); + dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); + nInputSum += nInputSize; + + // transaction hash + uint256 txhash = out.tx->GetHash(); + itemOutput->setText(COLUMN_TXHASH, txhash.GetHex().c_str()); + + // vout index + itemOutput->setText(COLUMN_VOUT_INDEX, QString::number(out.i)); + + // disable locked coins + /*if (model->isLockedCoin(txhash, out.i)) + { + COutPoint outpt(txhash, out.i); + coinControl->UnSelect(outpt); // just to be sure + itemOutput->setDisabled(true); + itemOutput->setIcon(COLUMN_CHECKBOX, QIcon(":/icons/lock_closed")); + }*/ + + // set checkbox + if (coinControl->IsSelected(txhash, out.i)) + itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Checked); + } + + // amount + if (treeMode) + { + dPrioritySum = dPrioritySum / (nInputSum + 78); + itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); + itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); + itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); + itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum)); + itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64)dPrioritySum), 20, " ")); + } + } + + // expand all partially selected + if (treeMode) + { + for (int i = 0; i < ui->treeWidget->topLevelItemCount(); i++) + if (ui->treeWidget->topLevelItem(i)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked) + ui->treeWidget->topLevelItem(i)->setExpanded(true); + } + + // sort view + sortView(sortColumn, sortOrder); + ui->treeWidget->setEnabled(true); +} diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h new file mode 100644 index 0000000..5d0a90b --- /dev/null +++ b/src/qt/coincontroldialog.h @@ -0,0 +1,92 @@ +#ifndef COINCONTROLDIALOG_H +#define COINCONTROLDIALOG_H + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Ui { + class CoinControlDialog; +} +class WalletModel; +class CCoinControl; + +class CoinControlDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CoinControlDialog(QWidget *parent = 0); + ~CoinControlDialog(); + + void setModel(WalletModel *model); + + // static because also called from sendcoinsdialog + static void updateLabels(WalletModel*, QDialog*); + static QString getPriorityLabel(double); + + static QList payAmounts; + static CCoinControl *coinControl; + +private: + Ui::CoinControlDialog *ui; + WalletModel *model; + int sortColumn; + Qt::SortOrder sortOrder; + + QMenu *contextMenu; + QTreeWidgetItem *contextMenuItem; + QAction *copyTransactionHashAction; + //QAction *lockAction; + //QAction *unlockAction; + + QString strPad(QString, int, QString); + void sortView(int, Qt::SortOrder); + void updateView(); + + enum + { + COLUMN_CHECKBOX, + COLUMN_AMOUNT, + COLUMN_LABEL, + COLUMN_ADDRESS, + COLUMN_DATE, + COLUMN_CONFIRMATIONS, + COLUMN_PRIORITY, + COLUMN_TXHASH, + COLUMN_VOUT_INDEX, + COLUMN_AMOUNT_INT64, + COLUMN_PRIORITY_INT64 + }; + +private slots: + void showMenu(const QPoint &); + void copyAmount(); + void copyLabel(); + void copyAddress(); + void copyTransactionHash(); + //void lockCoin(); + //void unlockCoin(); + void clipboardQuantity(); + void clipboardAmount(); + void clipboardFee(); + void clipboardAfterFee(); + void clipboardBytes(); + void clipboardPriority(); + void clipboardLowOutput(); + void clipboardChange(); + void radioTreeMode(bool); + void radioListMode(bool); + void viewItemChanged(QTreeWidgetItem*, int); + void headerSectionClicked(int); + void buttonBoxClicked(QAbstractButton*); + void buttonSelectAllClicked(); + //void updateLabelLocked(); +}; + +#endif // COINCONTROLDIALOG_H diff --git a/src/qt/coincontroltreewidget.cpp b/src/qt/coincontroltreewidget.cpp new file mode 100644 index 0000000..0c1b514 --- /dev/null +++ b/src/qt/coincontroltreewidget.cpp @@ -0,0 +1,28 @@ +#include "coincontroltreewidget.h" +#include "coincontroldialog.h" + +CoinControlTreeWidget::CoinControlTreeWidget(QWidget *parent) : + QTreeWidget(parent) +{ + +} + +void CoinControlTreeWidget::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Space) // press spacebar -> select checkbox + { + event->ignore(); + int COLUMN_CHECKBOX = 0; + this->currentItem()->setCheckState(COLUMN_CHECKBOX, ((this->currentItem()->checkState(COLUMN_CHECKBOX) == Qt::Checked) ? Qt::Unchecked : Qt::Checked)); + } + else if (event->key() == Qt::Key_Escape) // press esc -> close dialog + { + event->ignore(); + CoinControlDialog *coinControlDialog = (CoinControlDialog*)this->parentWidget(); + coinControlDialog->done(QDialog::Accepted); + } + else + { + this->QTreeWidget::keyPressEvent(event); + } +} diff --git a/src/qt/coincontroltreewidget.h b/src/qt/coincontroltreewidget.h new file mode 100644 index 0000000..d981f72 --- /dev/null +++ b/src/qt/coincontroltreewidget.h @@ -0,0 +1,17 @@ +#ifndef COINCONTROLTREEWIDGET_H +#define COINCONTROLTREEWIDGET_H + +#include +#include + +class CoinControlTreeWidget : public QTreeWidget { +Q_OBJECT + +public: + explicit CoinControlTreeWidget(QWidget *parent = 0); + +protected: + virtual void keyPressEvent(QKeyEvent *event); +}; + +#endif // COINCONTROLTREEWIDGET_H \ No newline at end of file diff --git a/src/qt/forms/coincontroldialog.ui b/src/qt/forms/coincontroldialog.ui new file mode 100644 index 0000000..29ff1fd --- /dev/null +++ b/src/qt/forms/coincontroldialog.ui @@ -0,0 +1,554 @@ + + + CoinControlDialog + + + + 0 + 0 + 1000 + 500 + + + + Coin Control + + + QTableView {background-color:rgb(69, 87, 96); color:white;} +QToolTip {background-color:#1f333e; color:white; border-style: none;} + + + + + + + 0 + + + 10 + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + Quantity: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Bytes: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0 + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + Amount: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + font-weight:bold; + + + Priority: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + Fee: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + false + + + font-weight:bold; + + + Low Output: + + + + + + + false + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + no + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + 10 + + + 10 + + + 6 + + + 6 + + + + + font-weight:bold; + + + After Fee: + + + + + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + false + + + font-weight:bold; + + + Change: + + + + + + + false + + + + Monospace + 10 + + + + IBeamCursor + + + Qt::ActionsContextMenu + + + 0.00 DMD + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + 0 + 40 + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + 10 + 0 + 781 + 41 + + + + + 14 + + + + + + 0 + 0 + + + + (un)select all + + + + + + + + 0 + 0 + + + + Tree mode + + + true + + + + + + + + 0 + 0 + + + + List mode + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Qt::CustomContextMenu + + + false + + + 11 + + + true + + + false + + + + + + + + + Amount + + + + + Label + + + + + Address + + + + + Date + + + + + Confirmations + + + Confirmed + + + + + Priority + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + CoinControlTreeWidget + QTreeWidget +
    coincontroltreewidget.h
    +
    +
    + + +
    From 9760de7a9f4bd082148c66e4042e482d984cab71 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 11 Jul 2014 13:10:23 +0300 Subject: [PATCH 052/218] More coin control fixes. --- diamond.pro | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/diamond.pro b/diamond.pro index 398ebf8..677562d 100644 --- a/diamond.pro +++ b/diamond.pro @@ -133,6 +133,8 @@ HEADERS += src/qt/bitcoingui.h \ src/qt/transactiontablemodel.h \ src/qt/addresstablemodel.h \ src/qt/optionsdialog.h \ + src/qt/coincontroldialog.h \ + src/qt/coincontroltreewidget.h \ src/qt/sendcoinsdialog.h \ src/qt/addressbookpage.h \ src/qt/signverifymessagedialog.h \ @@ -145,6 +147,7 @@ HEADERS += src/qt/bitcoingui.h \ src/bignum.h \ src/checkpoints.h \ src/compat.h \ + src/coincontrol.h \ src/sync.h \ src/util.h \ src/uint256.h \ @@ -213,6 +216,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/addresstablemodel.cpp \ src/qt/optionsdialog.cpp \ src/qt/sendcoinsdialog.cpp \ + src/qt/coincontroldialog.cpp \ + src/qt/coincontroltreewidget.cpp \ src/qt/addressbookpage.cpp \ src/qt/signverifymessagedialog.cpp \ src/qt/aboutdialog.cpp \ @@ -280,6 +285,7 @@ RESOURCES += \ src/qt/bitcoin.qrc FORMS += \ + src/qt/forms/coincontroldialog.ui \ src/qt/forms/sendcoinsdialog.ui \ src/qt/forms/addressbookpage.ui \ src/qt/forms/signverifymessagedialog.ui \ From 3798c764ad20648094824a22312e8a932cd66e90 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 11 Jul 2014 13:11:23 +0300 Subject: [PATCH 053/218] Update version to 2.0.3 --- src/clientversion.h | 4 ++-- src/qt/forms/aboutdialog.ui | 2 +- src/qt/res/icons/mining_active.png | Bin 668 -> 0 bytes src/version.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 src/qt/res/icons/mining_active.png diff --git a/src/clientversion.h b/src/clientversion.h index 1725bce..13e1ea5 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -8,8 +8,8 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 2 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_REVISION 3 +#define CLIENT_VERSION_BUILD 0 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 088223b..307b268 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.1 + 2.0.3 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/qt/res/icons/mining_active.png b/src/qt/res/icons/mining_active.png deleted file mode 100644 index 4726ebb9ae8760caeb6e065d8d99834e3b37b34f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 668 zcmV;N0%QG&P)NotxI}z*ga{w`NFYV zEV+^vrz$4Hf$Fu&3rSy%yd$aP044k3CEYb8-z2RBr@gn5mg==i zQ_>enKP1fy$OBJXVblqdY#+Gq$7!#fje6~D)M;lU{5U-T-uQ8fAEy8hf$PAWfQ?od z5hNKv!;jPbb~fT%jQu$60^5F^a?~4ifP26-$B$FIVp*$YuNj>7nr^YA|E}KyXU|F zuM7;Z0aO4_zzyK>49Pz5ZmPtp-mg|z99i{!P@vtu& ztdEjD&G=<#6Iu|k09*mqfK{Mic{fP1&P>f7PzGF6JqNfBP&9Km=82rCS&($Wawh3S z(l2wRV$w0000 Date: Thu, 14 Aug 2014 09:53:56 +0300 Subject: [PATCH 054/218] Dead code removal, eliminate extra hash calculations and clean up style. --- src/kernel.cpp | 37 +++++++---------- src/main.cpp | 107 ++++++++++++++++--------------------------------- src/main.h | 3 -- 3 files changed, 49 insertions(+), 98 deletions(-) diff --git a/src/kernel.cpp b/src/kernel.cpp index db42aa8..6857c39 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -69,9 +69,7 @@ static int64 GetStakeModifierSelectionInterval() { int64 nSelectionInterval = 0; for (int nSection=0; nSection<64; nSection++) - { nSelectionInterval += GetStakeModifierSelectionIntervalSection(nSection); - } return nSelectionInterval; } @@ -153,10 +151,16 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64& nStakeModif return error("ComputeNextStakeModifier: unable to get last modifier"); if (fDebug) { - printf("ComputeNextStakeModifier: prev modifier=0x%016"PRI64x" time=%s\n", nStakeModifier, DateTimeStrFormat(nModifierTime).c_str()); + printf("ComputeNextStakeModifier: prev modifier=0x%016"PRI64x" time=%s epoch=%u\n", nStakeModifier, DateTimeStrFormat(nModifierTime).c_str(), (unsigned int)nModifierTime); } if (nModifierTime / nModifierInterval >= pindexPrev->GetBlockTime() / nModifierInterval) + { + if (fDebug) + { + printf("ComputeNextStakeModifier: no new interval keep current modifier: pindexPrev nHeight=%d nTime=%u\n", pindexPrev->nHeight, (unsigned int)pindexPrev->GetBlockTime()); + } return true; + } // Sort candidate blocks by timestamp vector > vSortedByTimestamp; @@ -237,7 +241,6 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier nStakeModifierTime = pindexFrom->GetBlockTime(); int64 nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval(); const CBlockIndex* pindex = pindexFrom; - // loop to find the stake modifier later by a selection interval while (nStakeModifierTime < pindexFrom->GetBlockTime() + nStakeModifierSelectionInterval) { @@ -247,11 +250,7 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s", pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, hashBlockFrom.ToString().c_str()); else - { - // printf(">> nStakeModifierTime = %"PRI64d", pindexFrom->GetBlockTime() = %"PRI64d", nStakeModifierSelectionInterval = %"PRI64d"\n", - // nStakeModifierTime, pindexFrom->GetBlockTime(), nStakeModifierSelectionInterval); return false; - } } pindex = pindex->pnext; if (pindex->GeneratedStakeModifier()) @@ -300,26 +299,22 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned bnTargetPerCoinDay.SetCompact(nBits); int64 nValueIn = txPrev.vout[prevout.n].nValue; + uint256 hashBlockFrom = blockFrom.GetHash(true); + // v0.3 protocol kernel hash weight starts from 0 at the min age // this change increases active coins participating the hash and helps // to secure the network when proof-of-stake difficulty is low // DK changing calculations here creates a fork int64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)nStakeMaxAge) - nStakeMinAge; CBigNum bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); - - // printf(">>> CheckStakeKernelHash: nTimeWeight = %"PRI64d"\n", nTimeWeight); // Calculate hash CDataStream ss(SER_GETHASH, 0); uint64 nStakeModifier = 0; int nStakeModifierHeight = 0; int64 nStakeModifierTime = 0; - if (!GetKernelStakeModifier(blockFrom.GetHash(true), nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake)) - { - // printf(">>> CheckStakeKernelHash: GetKernelStakeModifier return false\n"); + if (!GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake)) return false; - } - // printf(">>> CheckStakeKernelHash: passed GetKernelStakeModifier\n"); ss << nStakeModifier; ss << nTimeBlockFrom << nTxPrevOffset << txPrev.nTime << prevout.n << nTimeTx; @@ -329,10 +324,9 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned printf("CheckStakeKernelHash() : using modifier 0x%016"PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", nStakeModifier, nStakeModifierHeight, DateTimeStrFormat(nStakeModifierTime).c_str(), - mapBlockIndex[blockFrom.GetHash(true)]->nHeight, + mapBlockIndex[hashBlockFrom]->nHeight, DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); - printf("CheckStakeKernelHash() : check protocol=%s modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", - "0.3", + printf("CheckStakeKernelHash() : check modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", nStakeModifier, nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx, hashProofOfStake.ToString().c_str()); @@ -354,10 +348,9 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned printf("CheckStakeKernelHash() : using modifier 0x%016"PRI64x" at height=%d timestamp=%s for block from height=%d timestamp=%s\n", nStakeModifier, nStakeModifierHeight, DateTimeStrFormat(nStakeModifierTime).c_str(), - mapBlockIndex[blockFrom.GetHash(true)]->nHeight, + mapBlockIndex[hashBlockFrom]->nHeight, DateTimeStrFormat(blockFrom.GetBlockTime()).c_str()); - printf("CheckStakeKernelHash() : pass protocol=%s modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", - "0.3", + printf("CheckStakeKernelHash() : pass modifier=0x%016"PRI64x" nTimeBlockFrom=%u nTxPrevOffset=%u nTimeTxPrev=%u nPrevout=%u nTimeTx=%u hashProof=%s\n", nStakeModifier, nTimeBlockFrom, nTxPrevOffset, txPrev.nTime, prevout.n, nTimeTx, hashProofOfStake.ToString().c_str()); @@ -423,8 +416,6 @@ bool CheckStakeModifierCheckpoints(int nHeight, unsigned int nStakeModifierCheck { if (fTestNet) return true; // Testnet has no checkpoints if (mapStakeModifierCheckpoints.count(nHeight)) - { return nStakeModifierChecksum == mapStakeModifierCheckpoints[nHeight]; - } return true; } diff --git a/src/main.cpp b/src/main.cpp index 7093004..6bf118a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,7 +25,7 @@ using namespace boost; // CCriticalSection cs_setpwalletRegistered; -set setpwalletRegistered; +set setpwalletRegistered; CCriticalSection cs_main; @@ -829,14 +829,12 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) return false; } - bool CWalletTx::AcceptWalletTransaction() { CTxDB txdb("r"); return AcceptWalletTransaction(txdb); } - int CTxIndex::GetDepthInMainChain() const { // Read block header @@ -918,7 +916,6 @@ bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) return true; } - uint256 static GetOrphanRoot(const CBlock* pblock) { // Work back to the first block in the orphan chain @@ -927,7 +924,6 @@ uint256 static GetOrphanRoot(const CBlock* pblock) return pblock->GetHash(); } - // ppcoin: find block wanted by given orphan block uint256 WantedByOrphan(const CBlock* pblockOrphan) { @@ -1339,7 +1335,6 @@ bool CTransaction::FetchInputs(CTxDB& txdb, const map& mapTes return true; } - const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& inputs) const { MapPrevTx::const_iterator mi = inputs.find(input.prevout.hash); @@ -1353,7 +1348,6 @@ const CTxOut& CTransaction::GetOutputFor(const CTxIn& input, const MapPrevTx& in return txPrev.vout[input.prevout.n]; } - int64 CTransaction::GetValueIn(const MapPrevTx& inputs) const { if (IsCoinBase()) @@ -1368,7 +1362,6 @@ int64 CTransaction::GetValueIn(const MapPrevTx& inputs) const } - unsigned int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const { if (IsCoinBase()) @@ -1384,7 +1377,6 @@ unsigned int CTransaction::GetP2SHSigOpCount(const MapPrevTx& inputs) const return nSigOps; } - bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, map& mapTestPool, const CDiskTxPos& posThisTx, const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash) @@ -1714,7 +1706,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) CDiskBlockIndex blockindexPrev(pindex->pprev); blockindexPrev.hashNext = pindex->GetBlockHash(); if (!txdb.WriteBlockIndex(blockindexPrev)) - return error("ConnectBlock() : WriteBlockIndex failed"); + return error("ConnectBlock() : WriteBlockIndex for blockindexPrev failed"); } // Watch for transactions paying to me @@ -1846,7 +1838,6 @@ bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew) return true; } - bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) { uint256 hash = GetHash(); @@ -2205,7 +2196,6 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) return true; } - bool CBlock::AcceptBlock() { // Check for duplicate @@ -2973,10 +2963,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - - - - if (strCommand == "version") { // Each connection can only send one version message @@ -3196,7 +3182,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fDisconnect = true; } - else if (strCommand == "inv") { vector vInv; @@ -3480,11 +3465,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { CBlock block; vRecv >> block; + uint256 hashBlock = block.GetHash(); - printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str()); + printf("received block %s\n", hashBlock.ToString().substr(0,20).c_str()); // block.print(); - CInv inv(MSG_BLOCK, block.GetHash()); + CInv inv(MSG_BLOCK, hashBlock); pfrom->AddInventoryKnown(inv); if (ProcessBlock(pfrom, &block)) @@ -4079,10 +4065,9 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) int64 nSearchTime = txCoinStake.nTime; // search to current time if (nSearchTime > nLastCoinStakeSearchTime) { - // printf(">>> OK1\n"); if (pwallet->CreateCoinStake(*pwallet, pblock->nBits, nSearchTime-nLastCoinStakeSearchTime, txCoinStake)) { - if (txCoinStake.nTime >= max(pindexPrev->GetMedianTimePast()+1, pindexPrev->GetBlockTime() - nMaxClockDrift)) + if (txCoinStake.nTime >= max(pindexPrev->GetMedianTimePast()+1, pindexPrev->GetBlockTime() - nMaxClockDrift)) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp pblock->vtx[0].vout[0].SetEmpty(); @@ -4389,10 +4374,13 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) printf("BitcoinMiner:\n"); printf("new block found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); pblock->print(); - if(totalCoin >= VALUE_CHANGE) - printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue + pblock->vtx[0].vout[1].nValue).c_str()); - else - printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); + if (pblock->IsProofOfWork()) + { + if(totalCoin >= VALUE_CHANGE) + printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue + pblock->vtx[0].vout[1].nValue).c_str()); + else + printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); + } // Found a solution { @@ -4406,7 +4394,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) // Track how many getdata requests this block gets { LOCK(wallet.cs_wallet); - wallet.mapRequestCount[pblock->GetHash()] = 0; + wallet.mapRequestCount[hash] = 0; } // Process this block the same as if we had received it from another node @@ -4504,7 +4492,7 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1); unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); - unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); +// unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); // @@ -4513,43 +4501,31 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) int64 nStart = GetTime(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - block_header res_header; - uint256 result; - while (true) { - - totalCoin = GetTotalCoin(); - - if(totalCoin < VALUE_CHANGE) - { - // No more scrypt hashing, take a nap - Sleep(1000); - break; - } - else + // always calculate totalCoins + totalCoins = GetTotalCoins(); + // new block, use groestl + uint256 hash = pblock->GetHashGroestl(); + if (hash <= hashTarget) { - // new block, use groestl - uint256 hash = pblock->GetHashGroestl(); - if (hash <= hashTarget) + if (!pblock->SignBlock(*pwalletMain)) { - if (!pblock->SignBlock(*pwalletMain)) - { - strMintWarning = strMintMessage; - break; - } - strMintWarning = ""; - SetThreadPriority(THREAD_PRIORITY_NORMAL); - - printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); - pblock->print(); - - CheckWork(pblock.get(), *pwalletMain, reservekey); - SetThreadPriority(THREAD_PRIORITY_LOWEST); + strMintWarning = strMintMessage; break; } - ++pblock->nNonce; + strMintWarning = ""; + SetThreadPriority(THREAD_PRIORITY_NORMAL); + + printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + pblock->print(); + + CheckWork(pblock.get(), *pwalletMain, reservekey); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + break; } + ++pblock->nNonce; + // Meter hashes/sec static int64 nHashCounter; if (nHPSTimerStart == 0) @@ -4558,9 +4534,7 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) nHashCounter = 0; } else - { nHashCounter++; - } if (GetTimeMillis() - nHPSTimerStart > 4000) { static CCriticalSection cs; @@ -4572,7 +4546,6 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) nHPSTimerStart = GetTimeMillis(); nHashCounter = 0; static int64 nLogTime; - // log hash rate every 30 minutes if (GetTime() - nLogTime > 30 * 60) { nLogTime = GetTime(); @@ -4591,16 +4564,8 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) return; if (vNodes.empty()) break; - if(totalCoin < VALUE_CHANGE) - { - if (nBlockNonce >= 0xffff0000) - break; - } - else - { - if (++pblock->nNonce >= 0xffff0000) - break; - } + if (pblock->nNonce >= 0xffff0000) + break; if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60) break; if (pindexPrev != pindexBest) @@ -4611,12 +4576,10 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift); pblock->UpdateTime(pindexPrev); nBlockTime = ByteReverse(pblock->nTime); - if (pblock->GetBlockTime() >= (int64)pblock->vtx[0].nTime + nMaxClockDrift) break; // need to update coinbase timestamp } } - } void static ThreadBitcoinMiner(void* parg) diff --git a/src/main.h b/src/main.h index e5d1fb7..d51d202 100644 --- a/src/main.h +++ b/src/main.h @@ -94,7 +94,6 @@ extern bool fUseFastIndex; // Minimum disk space required - used in CheckDiskSpace() static const uint64 nMinDiskSpace = 52428800; - class CReserveKey; class CTxDB; class CTxIndex; @@ -139,8 +138,6 @@ void ResendWalletTransactions(); - - bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); /** Position on disk for a particular transaction. */ From a75862994afb01d8ea4d4a316ee0ca355a6db549 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 14 Aug 2014 09:56:25 +0300 Subject: [PATCH 055/218] Fix 'not enough work' misbehaving and ban behaviour. --- src/main.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6bf118a..da501d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2347,8 +2347,19 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) if (bnNewBlock > bnRequired) { if (pfrom) - pfrom->Misbehaving(100); - return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); + pfrom->Misbehaving(10); // danbi: was 100, but that's way too heavy handed + if (fDebug) + { + printf("ProcessBlock(): "); + pblock->print(); + printf("\n"); + } + // danbi: Only refuse this block if time distance between the last sync checkpoint + // and the block's time is less than the checkpoints max span + if (deltaTime < CHECKPOINT_MAX_SPAN) + return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); + else + return printf("ProcessBlock(CHECKPOINT_MAX_SPAN) : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); } } From 5bc8863310dad834d8c9d1fc9f52e8fe723406e5 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 14 Aug 2014 09:57:19 +0300 Subject: [PATCH 056/218] Disconnect version 2.0.2.1 clients. --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index da501d3..138b64c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3020,10 +3020,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - // Diamond: disconnect any known version prior 2.0.2.1 + // Diamond: disconnect any known version prior 2.0.3 // as these have PoS not working and could serve us garbage printf("connected subver %s\n", pfrom->strSubVer.c_str()); if (!strcmp(pfrom->strSubVer.c_str(),"/Diamond:2.0.1/") + || !strcmp(pfrom->strSubVer.c_str(),"/Diamond:2.0.2.1/") || !strcmp(pfrom->strSubVer.c_str(),"/Diamond:0.7.2/") || !strcmp(pfrom->strSubVer.c_str(),"/Satoshi:0.7.2/") || !strcmp(pfrom->strSubVer.c_str(),"") From 5a704df1facc0ea09f12dd0bfd1b90a2462d5fb6 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 14 Aug 2014 09:58:55 +0300 Subject: [PATCH 057/218] Increase receive and send buffers and getblocks limits. --- src/main.cpp | 12 ++++++++---- src/net.h | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 138b64c..8a73d21 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3329,13 +3329,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Send the rest of the chain if (pindex) pindex = pindex->pnext; - int nLimit = 500; + int nLimit = 500 + locator.GetDistanceBack(); + unsigned int nBytes = 0; printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit); for (; pindex; pindex = pindex->pnext) { if (pindex->GetBlockHash() == hashStop) { - printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str()); + printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); // ppcoin: tell downloading node about the latest block if it's // without risk being rejected due to stake connection check if (hashStop != hashBestChain && pindex->GetBlockTime() + nStakeMinAge > pindexBest->GetBlockTime()) @@ -3343,11 +3344,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) break; } pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash())); - if (--nLimit <= 0) + CBlock block; + block.ReadFromDisk(pindex, true); + nBytes += block.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION); + if (--nLimit <= 0 || nBytes >= SendBufferSize()/2) { // When this block is requested, we'll send an inv that'll make them // getblocks the next batch of inventory. - printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str()); + printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); pfrom->hashContinue = pindex->GetBlockHash(); break; } diff --git a/src/net.h b/src/net.h index 16cd95f..b44eb32 100644 --- a/src/net.h +++ b/src/net.h @@ -26,8 +26,8 @@ extern int nBestHeight; -inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } -inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } +inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); } +inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); } void AddOneShot(std::string strDest); bool RecvLine(SOCKET hSocket, std::string& strLine); From 9fdc729cf8b76932197c3529a774529e09dc32c7 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 14 Aug 2014 10:00:21 +0300 Subject: [PATCH 058/218] Bump version number to 2.0.3.1. --- src/clientversion.h | 2 +- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index 13e1ea5..560a940 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 3 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_BUILD 1 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 307b268..448885d 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.3 + 2.0.3.1 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index db20eab..7f3f0b7 100644 --- a/src/version.h +++ b/src/version.h @@ -47,6 +47,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 3 -#define DISPLAY_VERSION_BUILD 0 +#define DISPLAY_VERSION_BUILD 1 #endif From 1b8d7befcda84d73358e747a0dfb2733315b2e7c Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 14 Aug 2014 10:06:07 +0300 Subject: [PATCH 059/218] Fix a typo. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8a73d21..2ac15f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4519,8 +4519,8 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) while (true) { - // always calculate totalCoins - totalCoins = GetTotalCoins(); + // always calculate totalCoin + totalCoin = GetTotalCoin(); // new block, use groestl uint256 hash = pblock->GetHashGroestl(); if (hash <= hashTarget) From d39c2df8f047e2099b230668922fad0a3589abe4 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 21 Aug 2014 17:14:04 +0300 Subject: [PATCH 060/218] Fix some log messages --- src/main.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2ac15f1..1addd40 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -500,7 +500,7 @@ bool CTransaction::CheckTransaction() const if (IsCoinBase()) { if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100) - return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size")); + return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size is invalid")); } else { @@ -620,7 +620,7 @@ bool CTxMemPool::accept(CTxDB& txdb, CTransaction &tx, bool fCheckInputs, return error("CTxMemPool::accept() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str()); if (pfMissingInputs) *pfMissingInputs = true; - return false; + return error("CTxMemPool::accept() : FetchInputs failed %s", hash.ToString().substr(0,10).c_str()); } // Check for non-standard pay-to-script-hash in inputs @@ -1104,7 +1104,7 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta return pindex; } -unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) +unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); @@ -1166,6 +1166,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) CBigNum bnTarget; bnTarget.SetCompact(nBits); + // danbi: substitute false for error as we call it with both algorithms for now // Check range if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) return false; @@ -1919,8 +1920,9 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) bnBestChainTrust = pindexNew->bnChainTrust; nTimeBestReceived = GetTime(); nTransactionsUpdated++; - printf("SetBestChain: new best=%s height=%d trust=%s date=%s\n", + printf("SetBestChain: new best=%s height=%d trust=%s moneysupply=%s date=%s\n", hashBestChain.ToString().c_str(), nBestHeight, bnBestChainTrust.ToString().c_str(), + FormatMoney(pindexBest->nMoneySupply).c_str(), DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str()); printf("Stake checkpoint: %x\n", pindexBest->nStakeModifierChecksum); @@ -3336,7 +3338,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { if (pindex->GetBlockHash() == hashStop) { - printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); + printf(" getblocks (hashStop) stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); // ppcoin: tell downloading node about the latest block if it's // without risk being rejected due to stake connection check if (hashStop != hashBestChain && pindex->GetBlockTime() + nStakeMinAge > pindexBest->GetBlockTime()) @@ -3351,7 +3353,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { // When this block is requested, we'll send an inv that'll make them // getblocks the next batch of inventory. - printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); + printf(" getblocks (nLimit) stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); pfrom->hashContinue = pindex->GetBlockHash(); break; } From 42454151729fa497cba4be3076bdce6b9ceeff84 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 21 Aug 2014 17:18:45 +0300 Subject: [PATCH 061/218] Update scrypt/groestl switch comparisons. Do more processing in the GetHash() routine, eliminating certain bogus hashes (if so happens). Set totalCoin in the message processing routine as well. --- src/main.cpp | 65 +++++++++++++++++++++++++++++++---------------- src/rpcmining.cpp | 2 +- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1addd40..18c3ed3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -469,7 +469,7 @@ bool CTransaction::CheckTransaction() const if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake()) return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); - if(totalCoin < VALUE_CHANGE || totalCoin > POS_RESTART) + if(totalCoin <= VALUE_CHANGE || totalCoin > POS_RESTART) { // ppcoin: enforce minimum output amount if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT) @@ -947,7 +947,7 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) { int64 nSubsidy = COIN; - if(totalCoin < VALUE_CHANGE) + if(totalCoin <= VALUE_CHANGE) { std::string cseed_str = prevHash.ToString().substr(6,7); const char* cseed = cseed_str.c_str(); @@ -987,7 +987,7 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi { int64 nRewardCoinYear; int64 nSubsidy = 0; - if(totalCoin >= VALUE_CHANGE || fTestNet) + if(totalCoin > VALUE_CHANGE || fTestNet) { nRewardCoinYear = MAX_MINT_PROOF_OF_STAKE; if(fTestNet) @@ -1680,7 +1680,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // printf("==> Got prevHash = %s\n", prevHash.ToString().c_str()); } - if(totalCoin < VALUE_CHANGE) + if(totalCoin <= VALUE_CHANGE) { if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) return false; @@ -1689,7 +1689,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) return false; - if(totalCoin >= VALUE_CHANGE && IsProofOfWork()) + if(totalCoin > VALUE_CHANGE && IsProofOfWork()) { CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); CScript scriptPubKey; @@ -2105,7 +2105,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) { // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork - if(totalCoin >= VALUE_CHANGE && !fTestNet) + if(totalCoin > VALUE_CHANGE && !fTestNet) { nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks @@ -2139,7 +2139,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) return DoS(100, error("CheckBlock() : coinstake in wrong position")); // ppcoin: coinbase output should be empty if proof-of-stake block - if(totalCoin >= VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) { if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); @@ -2975,6 +2975,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) printf("dropmessagestest DROPPING RECV MESSAGE\n"); return true; } + // make sure we have current totalCoin + totalCoin = GetTotalCoin(); if (strCommand == "version") { @@ -4032,7 +4034,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - if(totalCoin >= VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) { CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); txNew.vout.resize(2); @@ -4089,7 +4091,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp pblock->vtx[0].vout[0].SetEmpty(); - if(totalCoin >= VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) pblock->vtx[0].vout[1].SetEmpty(); pblock->vtx[0].nTime = txCoinStake.nTime; pblock->vtx.push_back(txCoinStake); @@ -4297,7 +4299,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfWork()) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); - if(totalCoin >= VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); } @@ -4394,7 +4396,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) pblock->print(); if (pblock->IsProofOfWork()) { - if(totalCoin >= VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue + pblock->vtx[0].vout[1].nValue).c_str()); else printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); @@ -4671,11 +4673,21 @@ uint256 CBlock::GetHash(bool existingBlock) const if (existingBlock) { //printf("CBlock::GetHash() look up an existing block\n"); - // TODO: reverse checks when Groestl blocks become more - // calculate Scrypt first + // We first check Groestl hash as that's less expensive and + // there are enough groestl blocks now + uint256 hash_groestl = GetHashGroestl(); + if (hash_groestl == uint256("0xe12ddb2c35d84403b0a045574ecce223f7e2f0db4506e76ed3d43bc464ace40c")) { + printf("GetHash(true): hash fixed up (groestl)\n"); + return uint256("0x000009d32c4f8ec5d66a65e88c8099da31452de0daec3b0b68926659b50b4e8f"); + } + CBlockIndex* pblockindex_groestl = mapBlockIndex[hash_groestl]; + if (pblockindex_groestl) + return hash_groestl; + + // we are here so it must be Scrypt uint256 hash_scrypt = GetHashScrypt(); if (hash_scrypt == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) { - printf("GetHash(): hash fixed up (scrypt)\n"); + printf("GetHash(true): hash fixed up (scrypt)\n"); return uint256("0x00000d652b612a94e1c830bf4e05106438ea6b53372b29206f0b820d91a9b67b"); } // find the index position(s) @@ -4683,16 +4695,25 @@ uint256 CBlock::GetHash(bool existingBlock) const if (pblockindex_scrypt) return hash_scrypt; - // we are here so it must be Groestl - uint256 hash_groestl = GetHashGroestl(); - CBlockIndex* pblockindex_groestl = mapBlockIndex[hash_groestl]; - if (pblockindex_groestl) - return hash_groestl; + // XXX: We are here, asked for an existing hash but did not find it! + printf("CBlock::GetHash(true): neither scrypt nor groestl hash found in the block index! Failing back..\n"); } // new block or not found in blockchain - if(totalCoin < VALUE_CHANGE) - return GetHashScrypt(); + if(totalCoin <= VALUE_CHANGE) + { + uint256 hash_scrypt = GetHashScrypt(); + if (hash_scrypt == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) { + printf("GetHash(): hash fixed up (scrypt)\n"); + return uint256("0x00000d652b612a94e1c830bf4e05106438ea6b53372b29206f0b820d91a9b67b"); + } + return hash_scrypt; + } - return GetHashGroestl(); + uint256 hash_groestl = GetHashGroestl(); + if (hash_groestl == uint256("0xe12ddb2c35d84403b0a045574ecce223f7e2f0db4506e76ed3d43bc464ace40c")) { + printf("GetHash(): hash fixed up (groestl)\n"); + return uint256("0x000009d32c4f8ec5d66a65e88c8099da31452de0daec3b0b68926659b50b4e8f"); + } + return hash_groestl; } diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 75b2a49..9ca8c30 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -505,7 +505,7 @@ Value getblocktemplate(const Array& params, bool fHelp) result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); - if(totalCoin >= VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue + (int64_t)pblock->vtx[0].vout[1].nValue)); else result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); From 6d14f8f305e0c8704adc36b468362664715100c4 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 21 Aug 2014 17:21:09 +0300 Subject: [PATCH 062/218] Use already computed totalCoin. --- src/db.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index c44965e..f76ce9f 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -883,11 +883,11 @@ bool CTxDB::LoadBlockIndexGuts() pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; - if(pindexNew->nMoneySupply / COIN == VALUE_CHANGE) + if(totalCoin == VALUE_CHANGE) { pindexSave = pindexNew; } - if(pindexNew->nMoneySupply / COIN == VALUE_CHANGE + 1) + if(totalCoin == VALUE_CHANGE + 1) { pindexSaveNext = pindexNew; } From c6242236944849b787c80168d2ed69403c5d8ca1 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 2 Sep 2014 15:58:47 +0300 Subject: [PATCH 063/218] Calculate totalCoin in a missing place and produce error messages. --- src/main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 18c3ed3..e6e59a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1680,14 +1680,17 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // printf("==> Got prevHash = %s\n", prevHash.ToString().c_str()); } + // danbi: update totalCoin as we are one behind here + // XXX: this might backfire in case of error... + totalCoin = pindex->nMoneySupply / COIN; if(totalCoin <= VALUE_CHANGE) { if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) - return false; + return error("ConnectBlock() : claiming to have created too much (old)"); } else if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) - return false; + return error("ConnectBlock() : claiming to have created too much (new)"); if(totalCoin > VALUE_CHANGE && IsProofOfWork()) { From 9b2df27327659a0e0ac1bc58f812aab90c7cc34d Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 5 Sep 2014 12:45:46 +0300 Subject: [PATCH 064/218] Fix README a bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6e8db4f..add9662 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ Update ubuntu *install the other necessary components - sudo apt-get install build-essential libboost1.48-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev + sudo apt-get install build-essential libboost1.55-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev *navigate to the home directory cd ~ *download the diamond source code - git clone https://github.com/DMDcoin/Diamond-Coin-2.0.1.git + git clone https://github.com/DMDcoin/Diamond.git *navigate to the downloaded files From a758ba644bf62ebe37cbd6fd69da3a6713ea7423 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 5 Sep 2014 12:47:41 +0300 Subject: [PATCH 065/218] Update version to 2.0.3.2 --- src/clientversion.h | 2 +- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index 560a940..bbb53d3 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 3 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_BUILD 2 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 448885d..eea87c7 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.3.1 + 2.0.3.2 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index 7f3f0b7..25e20af 100644 --- a/src/version.h +++ b/src/version.h @@ -47,6 +47,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 3 -#define DISPLAY_VERSION_BUILD 1 +#define DISPLAY_VERSION_BUILD 2 #endif From 9d294f0dfd55a0c34ef7248a0d8a134cd063253e Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 5 Sep 2014 14:15:15 +0300 Subject: [PATCH 066/218] Filter junk from the block index and add debug prints to find out more. --- src/db.cpp | 146 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 96 insertions(+), 50 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index f76ce9f..16428e1 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -853,70 +853,116 @@ bool CTxDB::LoadBlockIndexGuts() // Unserialize try { - string strType; - ssKey >> strType; - if (strType == "blockindex" && !fRequestShutdown) - { - CDiskBlockIndex diskindex; - ssValue >> diskindex; - - totalCoin = diskindex.nMoneySupply / COIN; - uint256 blockHash = diskindex.GetBlockHash(); - - // Construct block index object - CBlockIndex* pindexNew = InsertBlockIndex(blockHash); - pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); - pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); - pindexNew->nFile = diskindex.nFile; - pindexNew->nBlockPos = diskindex.nBlockPos; - pindexNew->nHeight = diskindex.nHeight; - pindexNew->nMint = diskindex.nMint; - pindexNew->nMoneySupply = diskindex.nMoneySupply; - pindexNew->nFlags = diskindex.nFlags; - pindexNew->nStakeModifier = diskindex.nStakeModifier; - pindexNew->prevoutStake = diskindex.prevoutStake; - pindexNew->nStakeTime = diskindex.nStakeTime; - pindexNew->hashProofOfStake = diskindex.hashProofOfStake; - pindexNew->nVersion = diskindex.nVersion; - pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; - pindexNew->nTime = diskindex.nTime; - pindexNew->nBits = diskindex.nBits; - pindexNew->nNonce = diskindex.nNonce; - - if(totalCoin == VALUE_CHANGE) + string strType; + ssKey >> strType; + if (strType == "blockindex" && !fRequestShutdown) { - pindexSave = pindexNew; + CDiskBlockIndex diskindex; + ssValue >> diskindex; + + totalCoin = diskindex.nMoneySupply / COIN; + uint256 blockHash = diskindex.GetBlockHash(); + + // clean up junk from the block index + if (totalCoin == 0) { + printf("money supply = 0\n"); + diskindex.print(); + if (blockHash != (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) + { + // not the genesis block, garbage anyway + printf("deleted\n"); + continue; + } + } + if (totalCoin == VALUE_CHANGE) { + printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); + diskindex.print(); + if (diskindex.hashNext == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) + { + // assign proper hash value + printf("changed\n"); + diskindex.hashNext = uint256("0x00000d652b612a94e1c830bf4e05106438ea6b53372b29206f0b820d91a9b67b"); + } + if (diskindex.GetBlockHash() == uint256("0xe12ddb2c35d84403b0a045574ecce223f7e2f0db4506e76ed3d43bc464ace40c")) + { + // this hash version should not be here, delete + printf("deleted\n"); + continue; + } + } + if (totalCoin == VALUE_CHANGE+1) { + // for information + printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); + diskindex.print(); + } + // end cleanup + + // Construct block index object + CBlockIndex* pindexNew = InsertBlockIndex(blockHash); + pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); + pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); + pindexNew->nFile = diskindex.nFile; + pindexNew->nBlockPos = diskindex.nBlockPos; + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nMint = diskindex.nMint; + pindexNew->nMoneySupply = diskindex.nMoneySupply; + pindexNew->nFlags = diskindex.nFlags; + pindexNew->nStakeModifier = diskindex.nStakeModifier; + pindexNew->prevoutStake = diskindex.prevoutStake; + pindexNew->nStakeTime = diskindex.nStakeTime; + pindexNew->hashProofOfStake = diskindex.hashProofOfStake; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + + if(totalCoin == VALUE_CHANGE) + pindexSave = pindexNew; + if(totalCoin == VALUE_CHANGE + 1) + pindexSaveNext = pindexNew; + + // Watch for genesis block + if (pindexGenesisBlock == NULL && blockHash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) + pindexGenesisBlock = pindexNew; + + if (!pindexNew->CheckIndex()) + return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); + + // ppcoin: build setStakeSeen + if (pindexNew->IsProofOfStake()) + setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); } - if(totalCoin == VALUE_CHANGE + 1) + else { - pindexSaveNext = pindexNew; + break; // if shutdown requested or finished loading block index } - - // Watch for genesis block - if (pindexGenesisBlock == NULL && blockHash == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) - pindexGenesisBlock = pindexNew; - - if (!pindexNew->CheckIndex()) - return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight); - - // ppcoin: build setStakeSeen - if (pindexNew->IsProofOfStake()) - setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); - } - else - { - break; // if shutdown requested or finished loading block index - } } // try catch (std::exception &e) { return error("%s() : deserialize error", __PRETTY_FUNCTION__); } } if(pindexSaveNext != NULL && pindexSave != NULL && pindexSave->pnext == NULL) + { + printf("linked pnext at switch block\n"); pindexSave->pnext = pindexSaveNext; + } pcursor->close(); + printf ("verify mapBlockIndex\n"); + count=0; + BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) + { + CBlockIndex* pindex = item.second; + if (pindex->nHeight == 0) { + printf("nHeight=0 count=%d\n", count); + pindex->print(); + } + count++; + } + printf("end verify\n"); + return true; } From 7e5ce2cbb221ff89e922ee115fff6e409a3a270a Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 5 Sep 2014 14:51:19 +0300 Subject: [PATCH 067/218] Add missing counter. --- src/db.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/db.cpp b/src/db.cpp index 16428e1..0471aca 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -834,10 +834,12 @@ bool CTxDB::LoadBlockIndexGuts() if (!pcursor) return false; + int count=0; // Load mapBlockIndex unsigned int fFlags = DB_SET_RANGE; while (true) { + count++; // Read next record CDataStream ssKey(SER_DISK, CLIENT_VERSION); if (fFlags == DB_SET_RANGE) @@ -942,6 +944,9 @@ bool CTxDB::LoadBlockIndexGuts() return error("%s() : deserialize error", __PRETTY_FUNCTION__); } } + + printf("loaded %d in block index\n", count); + if(pindexSaveNext != NULL && pindexSave != NULL && pindexSave->pnext == NULL) { printf("linked pnext at switch block\n"); From 22f7eb608906d064cef043b45a2b5b17eb23f170 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 19 Sep 2014 19:01:27 +0300 Subject: [PATCH 068/218] Implement -changeaddres command line/config parameter and getchangeaddress/setchangeaddress RPC calls. Let's specific address for sending all change to be set. This would prevent wallet bloat, as by default new address (public/private keypair) is created each time there is change -- virtually at every 'send'. --- src/bitcoinrpc.cpp | 2 ++ src/bitcoinrpc.h | 2 ++ src/init.cpp | 8 ++++++++ src/main.h | 2 ++ src/rpcwallet.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/wallet.cpp | 10 +++++++++- 6 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 5080c1c..c733b19 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -268,6 +268,8 @@ static const CRPCCommand vRPCCommands[] = { "resendtx", &resendtx, false, true}, { "makekeypair", &makekeypair, false, true}, { "sendalert", &sendalert, false, false}, + { "setchangeaddress", &setchangeaddress, true, false }, + { "getchangeaddress", &getchangeaddress, true, false }, }; CRPCTable::CRPCTable() diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 87b7e87..91934dd 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -204,5 +204,7 @@ extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fH extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblockbynumber(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getcheckpoint(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value setchangeaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getchangeaddress(const json_spirit::Array& params, bool fHelp); #endif diff --git a/src/init.cpp b/src/init.cpp index b657b2c..70c6512 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -430,6 +430,14 @@ bool AppInit2() fUseFastIndex = GetBoolArg("-fastindex", true); + if (mapArgs.count("-changeaddress")) + { + CBitcoinAddress address(GetArg("-changeaddress", "")); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Diamond address"); + changeAddress = address.Get(); + } + // Continue to put "/P2SH/" in the coinbase to monitor // BIP16 support. // This can be removed eventually... diff --git a/src/main.h b/src/main.h index d51d202..4f1dd61 100644 --- a/src/main.h +++ b/src/main.h @@ -90,6 +90,8 @@ extern std::map mapOrphanBlocks; // Settings extern int64 nTransactionFee; extern bool fUseFastIndex; +// where to deposit change +extern CTxDestination changeAddress; // Minimum disk space required - used in CheckDiskSpace() static const uint64 nMinDiskSpace = 52428800; diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index c735e37..571028d 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -15,6 +15,9 @@ using namespace std; int64 nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; +// were to deposit change +CTxDestination changeAddress = CNoDestination(); + extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, json_spirit::Object& entry); std::string HelpRequiringPassphrase() @@ -1783,3 +1786,44 @@ Value makekeypair(const Array& params, bool fHelp) result.push_back(Pair("PublicKey", HexStr(key.GetPubKey().Raw()))); return result; } + +// danbi: set address for change +Value setchangeaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "setchangeaddress \n" + "Sets the change deposit address."); + + if (params[0].get_str() == "") + { + changeAddress = CNoDestination(); + } + else + { + CBitcoinAddress address(params[0].get_str()); + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Diamond address"); + changeAddress = address.Get(); + } + + return Value::null; +} + + +Value getchangeaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getchangeaddress\n" + "Returns the change deposit address."); + + Value ret; + + if (!CBitcoinAddress(changeAddress).IsValid()) + ret = ""; + else + ret = CBitcoinAddress(changeAddress).ToString(); + + return ret; +} diff --git a/src/wallet.cpp b/src/wallet.cpp index e6dd002..c684867 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1306,6 +1306,13 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // change transaction isn't always pay-to-bitcoin-address CScript scriptChange; + // danbi: send change to defined address, if set + // eventually overriden by coin control + if (CBitcoinAddress(changeAddress).IsValid()) + scriptChange.SetDestination(changeAddress); + + else + { // coin control: send change to custom address if (coinControl && !boost::get(&coinControl->destChange)) scriptChange.SetDestination(coinControl->destChange); @@ -1325,7 +1332,8 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW scriptChange.SetDestination(vchPubKey.GetID()); } - + } + // Insert change txn at random position: vector::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); wtxNew.vout.insert(position, CTxOut(nChange, scriptChange)); From ecc3af2bea41ab0e74c22084a6f9b81cf0e5754b Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 19 Sep 2014 19:28:02 +0300 Subject: [PATCH 069/218] Unstuck PoW by preventing negative value of the expected difficulty (bnTarget and bnNew) and introducing block time pacing for PoW as well. Should handle the time warp attacks. --- src/init.cpp | 5 +++++ src/main.cpp | 31 +++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 70c6512..873ecb6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -174,9 +174,14 @@ bool AppInit(int argc, char* argv[]) return fRet; } +extern CBigNum bnSign; + extern void noui_connect(); int main(int argc, char* argv[]) { + // init pseudo constants first + bnSign.SetHex("0x80000000000000000000000000000000000000000000000000000000"); + bool fRet = false; // Connect bitcoind signal handlers diff --git a/src/main.cpp b/src/main.cpp index e6e59a8..8fe7a2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,6 +47,9 @@ unsigned int nStakeMaxAge = 60 * 60 * 24 * 30; // stake age of full weight: 30d int64 nStakeTargetSpacing = 60; // 1-minute block spacing int64 nWorkTargetSpacing = 60; // 1-minute block spacing +CBigNum bnSign = 0; // initialized in init.cpp, fix signed BigNum math +static const int64 POW_RESTART = 576898; // When (block) to unstuck PoW + int64 totalCoin = -1; int64 nChainStartTime = 1373654826; int nCoinbaseMaturity = 30; @@ -1131,7 +1134,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); // fix block spacing - // DK activating this will result in a fork + // danbi: activating this will result in a fork if (fProofOfStake && GetTotalCoin() > POS_RESTART) { if(nActualSpacing < 0) @@ -1152,10 +1155,15 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS bnNew.SetCompact(pindexPrev->nBits); int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nWorkTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); int64 nInterval = nTargetTimespan / nTargetSpacing; + + // danbi: implement new pacing algorithm for PoW + if (nActualSpacing < 0 && nBestHeight > POW_RESTART+100 ) + nActualSpacing=nTargetSpacing; + bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); - if (bnNew > bnTargetLimit) + if (bnNew <= 0 || bnNew > bnTargetLimit) bnNew = bnTargetLimit; return bnNew.GetCompact(); @@ -1168,6 +1176,13 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) // danbi: substitute false for error as we call it with both algorithms for now // Check range + // Fix negative number + if (bnTarget <= 0 && nBestHeight > POW_RESTART) + { + printf("CheckProofOfWork(): bnTarget <= 0, fixing\n"); + bnTarget = bnSign - bnTarget; + } + if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) return false; // return error("CheckProofOfWork() : nBits below minimum work"); @@ -2122,7 +2137,8 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) return DoS(100, error("CheckBlock() : size limits failed")); // Check proof of work matches claimed amount - if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) +// if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) + if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits)) return DoS(50, error("CheckBlock() : proof of work failed")); // Check timestamp @@ -2285,9 +2301,16 @@ CBigNum CBlockIndex::GetBlockTrust() const { CBigNum bnTarget; bnTarget.SetCompact(nBits); + // Fix negative number + if (bnTarget <= 0 && nBestHeight > POW_RESTART) + { + printf("GetBlockTrust(): bnTarget <= 0, fixing\n"); + bnTarget = bnSign - bnTarget; + } + if (bnTarget <= 0) return 0; - return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1); + return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1); } bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck) From 5e60c0de1a8fc3cccbcc7880c01ceb1347ed204c Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 19 Sep 2014 19:29:24 +0300 Subject: [PATCH 070/218] Update version to 2.1 --- src/clientversion.h | 6 +++--- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index bbb53d3..1a1ef8b 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -7,9 +7,9 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 -#define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 3 -#define CLIENT_VERSION_BUILD 2 +#define CLIENT_VERSION_MINOR 1 +#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_BUILD 0 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index eea87c7..591b8ec 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.3.2 + 2.1 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index 25e20af..43e51b6 100644 --- a/src/version.h +++ b/src/version.h @@ -45,8 +45,8 @@ static const int BIP0031_VERSION = 60000; static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 -#define DISPLAY_VERSION_MINOR 0 -#define DISPLAY_VERSION_REVISION 3 -#define DISPLAY_VERSION_BUILD 2 +#define DISPLAY_VERSION_MINOR 1 +#define DISPLAY_VERSION_REVISION 0 +#define DISPLAY_VERSION_BUILD 0 #endif From f7114ace9ba85842d06cf168eab4696664d6dd42 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 19 Sep 2014 22:55:37 +0300 Subject: [PATCH 071/218] Set the PoW restart block. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 8fe7a2b..a473205 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,7 +48,7 @@ int64 nStakeTargetSpacing = 60; // 1-minute block spacing int64 nWorkTargetSpacing = 60; // 1-minute block spacing CBigNum bnSign = 0; // initialized in init.cpp, fix signed BigNum math -static const int64 POW_RESTART = 576898; // When (block) to unstuck PoW +static const int64 POW_RESTART = 577850; // When (block) to unstuck PoW int64 totalCoin = -1; int64 nChainStartTime = 1373654826; From a9243f1629169d341e80ae02bdbb59ad3aa3b4eb Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Sat, 20 Sep 2014 22:48:16 +0300 Subject: [PATCH 072/218] Adjust PoW unstuck logic. Implement unified pacing for both PoW and PoS. Set version to 2.0.4. --- src/clientversion.h | 4 +-- src/init.cpp | 5 ---- src/main.cpp | 50 ++++++++++++++++--------------------- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 4 +-- 5 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index 1a1ef8b..7e8397f 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -7,8 +7,8 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 -#define CLIENT_VERSION_MINOR 1 -#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_MINOR 0 +#define CLIENT_VERSION_REVISION 4 #define CLIENT_VERSION_BUILD 0 // Converts the parameter X to a string after macro replacement on X has been performed. diff --git a/src/init.cpp b/src/init.cpp index 873ecb6..70c6512 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -174,14 +174,9 @@ bool AppInit(int argc, char* argv[]) return fRet; } -extern CBigNum bnSign; - extern void noui_connect(); int main(int argc, char* argv[]) { - // init pseudo constants first - bnSign.SetHex("0x80000000000000000000000000000000000000000000000000000000"); - bool fRet = false; // Connect bitcoind signal handlers diff --git a/src/main.cpp b/src/main.cpp index a473205..1c83a98 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,7 +47,6 @@ unsigned int nStakeMaxAge = 60 * 60 * 24 * 30; // stake age of full weight: 30d int64 nStakeTargetSpacing = 60; // 1-minute block spacing int64 nWorkTargetSpacing = 60; // 1-minute block spacing -CBigNum bnSign = 0; // initialized in init.cpp, fix signed BigNum math static const int64 POW_RESTART = 577850; // When (block) to unstuck PoW int64 totalCoin = -1; @@ -1131,12 +1130,30 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if (pindexPrevPrev->pprev == NULL) return bnTargetLimit.GetCompact(); // second block + // ppcoin: target change every block + // ppcoin: retarget with exponential moving toward target spacing + CBigNum bnNew; + bnNew.SetCompact(pindexPrev->nBits); + int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nWorkTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); + int64 nInterval = nTargetTimespan / nTargetSpacing; int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); // fix block spacing - // danbi: activating this will result in a fork - if (fProofOfStake && GetTotalCoin() > POS_RESTART) + // danbi: implement new pacing algorithm for PoW & PoS + if (nActualSpacing < 0 && nBestHeight > POW_RESTART) { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetSpacing (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetSpacing); + nActualSpacing=nTargetSpacing; + } + else if (nActualSpacing > nTargetTimespan && nBestHeight > POW_RESTART) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetTimespan (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetTimespan); + nActualSpacing=nTargetTimespan; + } + + // danbi: old PoS pacing algorithm + if (fProofOfStake && GetTotalCoin() > POS_RESTART && nBestHeight <= POW_RESTART) + { if(nActualSpacing < 0) { if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to 1.\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing); @@ -1149,21 +1166,12 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS } } - // ppcoin: target change every block - // ppcoin: retarget with exponential moving toward target spacing - CBigNum bnNew; - bnNew.SetCompact(pindexPrev->nBits); - int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nWorkTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); - int64 nInterval = nTargetTimespan / nTargetSpacing; - - // danbi: implement new pacing algorithm for PoW - if (nActualSpacing < 0 && nBestHeight > POW_RESTART+100 ) - nActualSpacing=nTargetSpacing; bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); - if (bnNew <= 0 || bnNew > bnTargetLimit) + // danbi: make sure we don't emit negative numbers even if we miscalculated + if ((bnNew <= 0 && nBestHeight > POW_RESTART) || bnNew > bnTargetLimit) bnNew = bnTargetLimit; return bnNew.GetCompact(); @@ -1176,13 +1184,6 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) // danbi: substitute false for error as we call it with both algorithms for now // Check range - // Fix negative number - if (bnTarget <= 0 && nBestHeight > POW_RESTART) - { - printf("CheckProofOfWork(): bnTarget <= 0, fixing\n"); - bnTarget = bnSign - bnTarget; - } - if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) return false; // return error("CheckProofOfWork() : nBits below minimum work"); @@ -2301,13 +2302,6 @@ CBigNum CBlockIndex::GetBlockTrust() const { CBigNum bnTarget; bnTarget.SetCompact(nBits); - // Fix negative number - if (bnTarget <= 0 && nBestHeight > POW_RESTART) - { - printf("GetBlockTrust(): bnTarget <= 0, fixing\n"); - bnTarget = bnSign - bnTarget; - } - if (bnTarget <= 0) return 0; return (IsProofOfStake()? (CBigNum(1)<<256) / (bnTarget+1) : 1); diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 591b8ec..ccb845a 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.1 + 2.0.4 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index 43e51b6..bdbe42e 100644 --- a/src/version.h +++ b/src/version.h @@ -45,8 +45,8 @@ static const int BIP0031_VERSION = 60000; static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 -#define DISPLAY_VERSION_MINOR 1 -#define DISPLAY_VERSION_REVISION 0 +#define DISPLAY_VERSION_MINOR 0 +#define DISPLAY_VERSION_REVISION 4 #define DISPLAY_VERSION_BUILD 0 #endif From 14cc45836f89983de5e34025e3678f274400002a Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Sat, 20 Sep 2014 23:02:58 +0300 Subject: [PATCH 073/218] Rearange pacing code. --- src/main.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1c83a98..98c943a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1139,20 +1139,22 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); // fix block spacing - // danbi: implement new pacing algorithm for PoW & PoS - if (nActualSpacing < 0 && nBestHeight > POW_RESTART) + // danbi: post 2.0.4 implement new pacing algorithm for PoW & PoS + if (nBestHeight > POW_RESTART) { - if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetSpacing (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetSpacing); - nActualSpacing=nTargetSpacing; - } - else if (nActualSpacing > nTargetTimespan && nBestHeight > POW_RESTART) - { - if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetTimespan (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetTimespan); - nActualSpacing=nTargetTimespan; + if (nActualSpacing < 0) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetSpacing (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetSpacing); + nActualSpacing=nTargetSpacing; + } + else if (nActualSpacing > nTargetTimespan) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to nTargetTimespan (%"PRI64d").\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing, nTargetTimespan); + nActualSpacing=nTargetTimespan; + } } - - // danbi: old PoS pacing algorithm - if (fProofOfStake && GetTotalCoin() > POS_RESTART && nBestHeight <= POW_RESTART) + // danbi: old pre 2.0.4 PoS pacing algorithm + else if (fProofOfStake && GetTotalCoin() > POS_RESTART) { if(nActualSpacing < 0) { From 01046753bf3e566d000854a41a2417493bd8db7c Mon Sep 17 00:00:00 2001 From: Robert Zimmerman Date: Sat, 21 Feb 2015 06:26:06 -0800 Subject: [PATCH 074/218] Adding support for armv7 builds --- diamond.pro | 18 +- src/makefile.unix | 17 +- src/scrypt-arm.S | 569 ++++++++++++++++++++++++++++++++++++++++++++ src/scrypt_mine.cpp | 22 +- 4 files changed, 620 insertions(+), 6 deletions(-) create mode 100644 src/scrypt-arm.S diff --git a/diamond.pro b/diamond.pro index 677562d..e7ce84c 100644 --- a/diamond.pro +++ b/diamond.pro @@ -123,8 +123,21 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) { DEFINES += HAVE_BUILD_INFO } -QMAKE_CXXFLAGS += -msse2 -QMAKE_CFLAGS += -msse2 +# If we have an arm device, we can't use sse2, so define as thumb +# Because of scrypt_mine.cpp, we also have to add a compile +# flag that states we *really* don't have SSE +# Otherwise, assume sse2 exists +!equals($$QMAKE_HOST.arch, armv7l) { + message(FOUND host = $$QMAKE_HOST.arch) + QMAKE_CXXFLAGS += -mthumb -DNOSSE + QMAKE_CFLAGS += -mthumb -DNOSSE +} +else { + QMAKE_CXXFLAGS += -msse2 + QMAKE_CFLAGS += -msse2 +} +#endif + QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter -Wstack-protector # Input @@ -275,6 +288,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/kernel.cpp \ src/scrypt-x86.S \ src/scrypt-x86_64.S \ + src/scrypt-arm.S \ src/scrypt_mine.cpp \ src/pbkdf2.cpp \ src/hash.cpp \ diff --git a/src/makefile.unix b/src/makefile.unix index 6d878e0..34495f0 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -94,9 +94,18 @@ DEBUGFLAGS=-g # CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only # adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work. -xCXXFLAGS=-O2 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ +xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) +# If we have an arm device, we can't use sse2, so define as thumb +# Otherwise, assume sse2 exists +# xCPUARCH is passed in as a define (xCPUARCH=armv7l) +ifeq ($(xCPUARCH),armv7l) + xCXXFLAGS+=-mthumb -DNOSSE +else + xCXXFLAGS+=-msse2 +endif + # LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only # adds some defaults in front. Unfortunately, LDFLAGS=... $(LDFLAGS) does not work. xLDFLAGS=$(LDHARDENING) $(LDFLAGS) @@ -135,7 +144,8 @@ OBJS= \ obj/pbkdf2.o \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ - obj/scrypt-x86_64.o + obj/scrypt-x86_64.o \ + obj/scrypt-arm.o all: diamondd @@ -158,6 +168,9 @@ obj/scrypt-x86.o: scrypt-x86.S obj/scrypt-x86_64.o: scrypt-x86_64.S $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< +obj/scrypt-arm.o: scrypt-arm.S + $(CXX) -c $(xCXXFLAGS) -MMD -o $@ $< + obj/%.o: %.cpp $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< @cp $(@:%.o=%.d) $(@:%.o=%.P); \ diff --git a/src/scrypt-arm.S b/src/scrypt-arm.S new file mode 100644 index 0000000..eacb015 --- /dev/null +++ b/src/scrypt-arm.S @@ -0,0 +1,569 @@ +/* + * Copyright 2012 pooler@litecoinpool.org + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#if defined(__arm__) + +#define __ARM_ARCH_5E_OR_6_OR_7__ + +#ifdef __ARM_ARCH_5E_OR_6__ + +.macro scrypt_shuffle + add lr, r0, #9*4 + ldmia r0, {r2-r7} + ldmia lr, {r2, r8-r12, lr} + str r3, [r0, #5*4] + str r5, [r0, #15*4] + str r6, [r0, #12*4] + str r7, [r0, #1*4] + ldr r5, [r0, #7*4] + str r2, [r0, #13*4] + str r8, [r0, #2*4] + strd r4, [r0, #10*4] + str r9, [r0, #7*4] + str r10, [r0, #4*4] + str r11, [r0, #9*4] + str lr, [r0, #3*4] + + add r2, r0, #64+0*4 + add lr, r0, #64+9*4 + ldmia r2, {r2-r7} + ldmia lr, {r2, r8-r12, lr} + str r3, [r0, #64+5*4] + str r5, [r0, #64+15*4] + str r6, [r0, #64+12*4] + str r7, [r0, #64+1*4] + ldr r5, [r0, #64+7*4] + str r2, [r0, #64+13*4] + str r8, [r0, #64+2*4] + strd r4, [r0, #64+10*4] + str r9, [r0, #64+7*4] + str r10, [r0, #64+4*4] + str r11, [r0, #64+9*4] + str lr, [r0, #64+3*4] +.endm + +.macro salsa8_core_doubleround_body + add r6, r2, r6 + add r7, r3, r7 + eor r10, r10, r6, ror #25 + add r6, r0, r4 + eor r11, r11, r7, ror #25 + add r7, r1, r5 + strd r10, [sp, #14*4] + eor r12, r12, r6, ror #25 + eor lr, lr, r7, ror #25 + + ldrd r6, [sp, #10*4] + add r2, r10, r2 + add r3, r11, r3 + eor r6, r6, r2, ror #23 + add r2, r12, r0 + eor r7, r7, r3, ror #23 + add r3, lr, r1 + strd r6, [sp, #10*4] + eor r8, r8, r2, ror #23 + eor r9, r9, r3, ror #23 + + ldrd r2, [sp, #6*4] + add r10, r6, r10 + add r11, r7, r11 + eor r2, r2, r10, ror #19 + add r10, r8, r12 + eor r3, r3, r11, ror #19 + add r11, r9, lr + eor r4, r4, r10, ror #19 + eor r5, r5, r11, ror #19 + + ldrd r10, [sp, #2*4] + add r6, r2, r6 + add r7, r3, r7 + eor r10, r10, r6, ror #14 + add r6, r4, r8 + eor r11, r11, r7, ror #14 + add r7, r5, r9 + eor r0, r0, r6, ror #14 + eor r1, r1, r7, ror #14 + + + ldrd r6, [sp, #14*4] + strd r2, [sp, #6*4] + strd r10, [sp, #2*4] + add r6, r11, r6 + add r7, r0, r7 + eor r4, r4, r6, ror #25 + add r6, r1, r12 + eor r5, r5, r7, ror #25 + add r7, r10, lr + eor r2, r2, r6, ror #25 + eor r3, r3, r7, ror #25 + strd r2, [sp, #6*4] + + add r10, r3, r10 + ldrd r6, [sp, #10*4] + add r11, r4, r11 + eor r8, r8, r10, ror #23 + add r10, r5, r0 + eor r9, r9, r11, ror #23 + add r11, r2, r1 + eor r6, r6, r10, ror #23 + eor r7, r7, r11, ror #23 + strd r6, [sp, #10*4] + + add r2, r7, r2 + ldrd r10, [sp, #14*4] + add r3, r8, r3 + eor r12, r12, r2, ror #19 + add r2, r9, r4 + eor lr, lr, r3, ror #19 + add r3, r6, r5 + eor r10, r10, r2, ror #19 + eor r11, r11, r3, ror #19 + + ldrd r2, [sp, #2*4] + add r6, r11, r6 + add r7, r12, r7 + eor r0, r0, r6, ror #14 + add r6, lr, r8 + eor r1, r1, r7, ror #14 + add r7, r10, r9 + eor r2, r2, r6, ror #14 + eor r3, r3, r7, ror #14 +.endm + +.macro salsa8_core + ldmia sp, {r0-r12, lr} + + ldrd r10, [sp, #14*4] + salsa8_core_doubleround_body + ldrd r6, [sp, #6*4] + strd r2, [sp, #2*4] + strd r10, [sp, #14*4] + salsa8_core_doubleround_body + ldrd r6, [sp, #6*4] + strd r2, [sp, #2*4] + strd r10, [sp, #14*4] + salsa8_core_doubleround_body + ldrd r6, [sp, #6*4] + strd r2, [sp, #2*4] + strd r10, [sp, #14*4] + salsa8_core_doubleround_body + + stmia sp, {r0-r5} + strd r8, [sp, #8*4] + str r12, [sp, #12*4] + str lr, [sp, #13*4] + strd r10, [sp, #14*4] +.endm + +#else + +.macro scrypt_shuffle +.endm + +.macro salsa8_core_doubleround_body + ldr r8, [sp, #8*4] + add r11, r11, r10 + ldr lr, [sp, #13*4] + add r12, r12, r3 + eor r2, r2, r11, ror #23 + add r11, r4, r0 + eor r7, r7, r12, ror #23 + add r12, r9, r5 + str r9, [sp, #9*4] + eor r8, r8, r11, ror #23 + str r10, [sp, #14*4] + eor lr, lr, r12, ror #23 + + ldr r11, [sp, #11*4] + add r9, lr, r9 + ldr r12, [sp, #12*4] + add r10, r2, r10 + eor r1, r1, r9, ror #19 + add r9, r7, r3 + eor r6, r6, r10, ror #19 + add r10, r8, r4 + str r8, [sp, #8*4] + eor r11, r11, r9, ror #19 + str lr, [sp, #13*4] + eor r12, r12, r10, ror #19 + + ldr r9, [sp, #10*4] + add r8, r12, r8 + ldr r10, [sp, #15*4] + add lr, r1, lr + eor r0, r0, r8, ror #14 + add r8, r6, r2 + eor r5, r5, lr, ror #14 + add lr, r11, r7 + eor r9, r9, r8, ror #14 + ldr r8, [sp, #9*4] + eor r10, r10, lr, ror #14 + ldr lr, [sp, #14*4] + + + add r8, r9, r8 + str r9, [sp, #10*4] + add lr, r10, lr + str r10, [sp, #15*4] + eor r11, r11, r8, ror #25 + add r8, r0, r3 + eor r12, r12, lr, ror #25 + add lr, r5, r4 + eor r1, r1, r8, ror #25 + ldr r8, [sp, #8*4] + eor r6, r6, lr, ror #25 + + add r9, r11, r9 + ldr lr, [sp, #13*4] + add r10, r12, r10 + eor r8, r8, r9, ror #23 + add r9, r1, r0 + eor lr, lr, r10, ror #23 + add r10, r6, r5 + str r11, [sp, #11*4] + eor r2, r2, r9, ror #23 + str r12, [sp, #12*4] + eor r7, r7, r10, ror #23 + + ldr r9, [sp, #9*4] + add r11, r8, r11 + ldr r10, [sp, #14*4] + add r12, lr, r12 + eor r9, r9, r11, ror #19 + add r11, r2, r1 + eor r10, r10, r12, ror #19 + add r12, r7, r6 + str r8, [sp, #8*4] + eor r3, r3, r11, ror #19 + str lr, [sp, #13*4] + eor r4, r4, r12, ror #19 +.endm + +.macro salsa8_core + ldmia sp, {r0-r7} + + ldr r12, [sp, #15*4] + ldr r8, [sp, #11*4] + ldr lr, [sp, #12*4] + + ldr r9, [sp, #9*4] + add r8, r8, r12 + ldr r11, [sp, #10*4] + add lr, lr, r0 + eor r3, r3, r8, ror #25 + add r8, r5, r1 + ldr r10, [sp, #14*4] + eor r4, r4, lr, ror #25 + add lr, r11, r6 + eor r9, r9, r8, ror #25 + eor r10, r10, lr, ror #25 + + salsa8_core_doubleround_body + + ldr r11, [sp, #10*4] + add r8, r9, r8 + ldr r12, [sp, #15*4] + add lr, r10, lr + eor r11, r11, r8, ror #14 + add r8, r3, r2 + eor r12, r12, lr, ror #14 + add lr, r4, r7 + eor r0, r0, r8, ror #14 + ldr r8, [sp, #11*4] + eor r5, r5, lr, ror #14 + ldr lr, [sp, #12*4] + + add r8, r8, r12 + str r11, [sp, #10*4] + add lr, lr, r0 + str r12, [sp, #15*4] + eor r3, r3, r8, ror #25 + add r8, r5, r1 + eor r4, r4, lr, ror #25 + add lr, r11, r6 + str r9, [sp, #9*4] + eor r9, r9, r8, ror #25 + str r10, [sp, #14*4] + eor r10, r10, lr, ror #25 + + salsa8_core_doubleround_body + + ldr r11, [sp, #10*4] + add r8, r9, r8 + ldr r12, [sp, #15*4] + add lr, r10, lr + eor r11, r11, r8, ror #14 + add r8, r3, r2 + eor r12, r12, lr, ror #14 + add lr, r4, r7 + eor r0, r0, r8, ror #14 + ldr r8, [sp, #11*4] + eor r5, r5, lr, ror #14 + ldr lr, [sp, #12*4] + + add r8, r8, r12 + str r11, [sp, #10*4] + add lr, lr, r0 + str r12, [sp, #15*4] + eor r3, r3, r8, ror #25 + add r8, r5, r1 + eor r4, r4, lr, ror #25 + add lr, r11, r6 + str r9, [sp, #9*4] + eor r9, r9, r8, ror #25 + str r10, [sp, #14*4] + eor r10, r10, lr, ror #25 + + salsa8_core_doubleround_body + + ldr r11, [sp, #10*4] + add r8, r9, r8 + ldr r12, [sp, #15*4] + add lr, r10, lr + eor r11, r11, r8, ror #14 + add r8, r3, r2 + eor r12, r12, lr, ror #14 + add lr, r4, r7 + eor r0, r0, r8, ror #14 + ldr r8, [sp, #11*4] + eor r5, r5, lr, ror #14 + ldr lr, [sp, #12*4] + + add r8, r8, r12 + str r11, [sp, #10*4] + add lr, lr, r0 + str r12, [sp, #15*4] + eor r3, r3, r8, ror #25 + add r8, r5, r1 + eor r4, r4, lr, ror #25 + add lr, r11, r6 + str r9, [sp, #9*4] + eor r9, r9, r8, ror #25 + str r10, [sp, #14*4] + eor r10, r10, lr, ror #25 + + salsa8_core_doubleround_body + + ldr r11, [sp, #10*4] + add r8, r9, r8 + ldr r12, [sp, #15*4] + add lr, r10, lr + str r9, [sp, #9*4] + eor r11, r11, r8, ror #14 + eor r12, r12, lr, ror #14 + add r8, r3, r2 + str r10, [sp, #14*4] + add lr, r4, r7 + str r11, [sp, #10*4] + eor r0, r0, r8, ror #14 + str r12, [sp, #15*4] + eor r5, r5, lr, ror #14 + + stmia sp, {r0-r7} +.endm + +#endif + + +.macro scrypt_core_macro1a_x4 + ldmia r0, {r4-r7} + ldmia lr!, {r8-r11} + stmia r1!, {r4-r7} + stmia r3!, {r8-r11} + eor r4, r4, r8 + eor r5, r5, r9 + eor r6, r6, r10 + eor r7, r7, r11 + stmia r0!, {r4-r7} + stmia r12!, {r4-r7} +.endm + +.macro scrypt_core_macro1b_x4 + ldmia r3!, {r8-r11} + ldmia r2, {r4-r7} + eor r8, r8, r4 + eor r9, r9, r5 + eor r10, r10, r6 + eor r11, r11, r7 + ldmia r0, {r4-r7} + stmia r2!, {r8-r11} + eor r4, r4, r8 + eor r5, r5, r9 + eor r6, r6, r10 + eor r7, r7, r11 + ldmia r1!, {r8-r11} + eor r4, r4, r8 + eor r5, r5, r9 + eor r6, r6, r10 + eor r7, r7, r11 + stmia r0!, {r4-r7} + stmia r12!, {r4-r7} +.endm + +.macro scrypt_core_macro2_x4 + ldmia r12, {r4-r7} + ldmia r0, {r8-r11} + add r4, r4, r8 + add r5, r5, r9 + add r6, r6, r10 + add r7, r7, r11 + stmia r0!, {r4-r7} + ldmia r2, {r8-r11} + eor r4, r4, r8 + eor r5, r5, r9 + eor r6, r6, r10 + eor r7, r7, r11 + stmia r2!, {r4-r7} + stmia r12!, {r4-r7} +.endm + +.macro scrypt_core_macro3_x4 + ldmia r1!, {r4-r7} + ldmia r0, {r8-r11} + add r4, r4, r8 + add r5, r5, r9 + add r6, r6, r10 + add r7, r7, r11 + stmia r0!, {r4-r7} +.endm + +.macro scrypt_core_macro3_x6 + ldmia r1!, {r2-r7} + ldmia r0, {r8-r12, lr} + add r2, r2, r8 + add r3, r3, r9 + add r4, r4, r10 + add r5, r5, r11 + add r6, r6, r12 + add r7, r7, lr + stmia r0!, {r2-r7} +.endm + + + .text + .code 32 + .align 2 + .globl scrypt_core + .globl _scrypt_core +#ifdef __ELF__ + .type scrypt_core, %function +#endif +scrypt_core: +_scrypt_core: + stmfd sp!, {r4-r11, lr} + mov r12, sp + sub sp, sp, #21*4 + bic sp, sp, #63 + str r12, [sp, #20*4] + + scrypt_shuffle + + str r0, [sp, #16*4] + add r12, r1, #1024*32*4 + str r12, [sp, #18*4] +scrypt_core_loop1: + add lr, r0, #16*4 + add r3, r1, #16*4 + mov r12, sp + scrypt_core_macro1a_x4 + scrypt_core_macro1a_x4 + scrypt_core_macro1a_x4 + scrypt_core_macro1a_x4 + str r1, [sp, #17*4] + + salsa8_core + + ldr r0, [sp, #16*4] + mov r12, sp + add r2, r0, #16*4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + + salsa8_core + + ldr r0, [sp, #16*4] + mov r1, sp + add r0, r0, #16*4 + scrypt_core_macro3_x6 + scrypt_core_macro3_x6 + ldr r3, [sp, #17*4] + ldr r12, [sp, #18*4] + scrypt_core_macro3_x4 + + add r1, r3, #16*4 + sub r0, r0, #32*4 + cmp r1, r12 + bne scrypt_core_loop1 + + ldr r4, [r0, #16*4] + sub r1, r1, #1024*32*4 + str r1, [sp, #17*4] + mov r4, r4, lsl #32-10 + mov r12, #1024 + add r1, r1, r4, lsr #32-10-7 +scrypt_core_loop2: + add r2, r0, #16*4 + add r3, r1, #16*4 + str r12, [sp, #18*4] + mov r12, sp +#ifdef __ARM_ARCH_5E_OR_6_OR_7__ + pld [r1, #24*4] + pld [r1, #8*4] +#endif + scrypt_core_macro1b_x4 + scrypt_core_macro1b_x4 + scrypt_core_macro1b_x4 + scrypt_core_macro1b_x4 + + salsa8_core + + ldr r0, [sp, #16*4] + mov r12, sp + add r2, r0, #16*4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + scrypt_core_macro2_x4 + + salsa8_core + + ldr r0, [sp, #16*4] + mov r1, sp + ldr r3, [sp, #17*4] + add r0, r0, #16*4 + scrypt_core_macro3_x4 + mov r4, r4, lsl #32-10 + add r3, r3, r4, lsr #32-10-7 + str r3, [sp, #19*4] +#ifdef __ARM_ARCH_5E_OR_6_OR_7__ + pld [r3, #16*4] + pld [r3] +#endif + scrypt_core_macro3_x6 + scrypt_core_macro3_x6 + + ldr r12, [sp, #18*4] + sub r0, r0, #32*4 + ldr r1, [sp, #19*4] + subs r12, r12, #1 + bne scrypt_core_loop2 + + scrypt_shuffle + + ldr sp, [sp, #20*4] +#ifdef __thumb__ + ldmfd sp!, {r4-r11, lr} + bx lr +#else + ldmfd sp!, {r4-r11, pc} +#endif + +#endif \ No newline at end of file diff --git a/src/scrypt_mine.cpp b/src/scrypt_mine.cpp index afca59d..246ea43 100644 --- a/src/scrypt_mine.cpp +++ b/src/scrypt_mine.cpp @@ -29,7 +29,16 @@ #include #include + +// Here, we need to check if we're compiling for an ARM processor. If we are, we +// need to make sure we don't try to use SSE instructions +extern "C" { +#ifndef NOSSE +#ifndef NO_ASM #include +#endif +#endif +} #include "scrypt_mine.h" #include "pbkdf2.h" @@ -43,7 +52,16 @@ extern bool fGenerateBitcoins; extern CBlockIndex* pindexBest; extern uint32_t nTransactionsUpdated; - +// Here, we need to check to see what type of processor we're using +// because x86 and x64 have different buffer size requirements. +// We're assuming ARM processors fall in with i386 processors +// because I can't think of a good reason to automatically go with a +// larger buffer, given the lower RAM and swap file sizes for ARM boards +// compared to x86 boards. +// In case this is an issue, see the following URL for help determining +// a good buffer size: +// https://github.com/pooler/cpuminer/blob/4611186cb88eec76f22a88565675473b2eeade28/scrypt.c#L502-510 +// It basically recommends SCRYPT_BUFFER_SIZE = (sizeof(int) * SCRYPT_MAX_WAYS * 128 + 63) #if defined(__x86_64__) #define SCRYPT_3WAY @@ -54,7 +72,7 @@ extern "C" void scrypt_core(uint32_t *X, uint32_t *V); extern "C" void scrypt_core_2way(uint32_t *X, uint32_t *Y, uint32_t *V); extern "C" void scrypt_core_3way(uint32_t *X, uint32_t *Y, uint32_t *Z, uint32_t *V); -#elif defined(__i386__) +#elif ( defined(__i386__)||defined(__arm__) ) #define SCRYPT_BUFFER_SIZE (131072 + 63) From 8584b48066b3d03c04161a91d825b6b92aea20ac Mon Sep 17 00:00:00 2001 From: Robert Zimmerman Date: Sat, 21 Feb 2015 06:26:49 -0800 Subject: [PATCH 075/218] Updating documentation for armv7 --- README.md | 65 +++++++++++------ doc/build-unix-arm.txt | 159 +++++++++++++++++++++++++++++++++++++++++ doc/readme-qt-arm.rst | 114 +++++++++++++++++++++++++++++ 3 files changed, 316 insertions(+), 22 deletions(-) create mode 100644 doc/build-unix-arm.txt create mode 100644 doc/readme-qt-arm.rst diff --git a/README.md b/README.md index add9662..22a6a7b 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,55 @@ Diamond (DMD) +=== -Instructions for compiling in Linux. +Fork Information +=== -Update ubuntu - - sudo apt-get update +This branch is an unofficial offshoot that allows building for armv7l +architecture CPUs. It was made for the convenience of people that either +use an ARM desktop or run an ARM server and who want to keep their +wallet open to mint coins via POS or want to run an energy-efficient +node for solo mining. -*install git to download the source code +This fork really only adds a few lines of changes to the Makefile and +Qt's version of a makefile. It might even be a drop-in solution for the +future, if neither have significant changes made to them. (Either that +or the Diamond team will merge it.) - sudo apt-get install git +Information for building is located in: +[doc/build-unix-arm.txt](doc/build-unix-arm.txt) for headless and +[doc/readme-qt-arm.rst](doc/readme-qt-arm.rst) for the Qt GUI. -*install the other necessary components - sudo apt-get install build-essential libboost1.55-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev +Instructions for compiling in Linux for armv7l. +--- +Update ubuntu +``` +sudo apt-get update +``` +*install git to download the source code +``` +sudo apt-get install git +``` +*install the other necessary components +``` +sudo apt-get install build-essential libboost1.55-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev +``` *navigate to the home directory - - cd ~ *download the diamond source code - - git clone https://github.com/DMDcoin/Diamond.git - +``` +cd ~ *download the diamond source code +git clone https://github.com/DMDcoin/Diamond.git +``` *navigate to the downloaded files - - cd ~ *navigate to the src file in the source code - cd diamond/src - +``` +cd ~ *navigate to the src file in the source code +cd diamond/src +``` *create obj folder - - mkdir obj - +``` +mkdir obj +``` *build diamondd !This will take a while! - - make -f makefile.unix USE_UPNP=- +``` +make -f makefile.unix xCPUARCH=armv7l +``` \ No newline at end of file diff --git a/doc/build-unix-arm.txt b/doc/build-unix-arm.txt new file mode 100644 index 0000000..5d469ed --- /dev/null +++ b/doc/build-unix-arm.txt @@ -0,0 +1,159 @@ +Copyright (c) 2009-2012 Bitcoin Developers +Distributed under the MIT/X11 software license, see the accompanying +file license.txt or http://www.opensource.org/licenses/mit-license.php. +This product includes software developed by the OpenSSL Project for use in +the OpenSSL Toolkit (http://www.openssl.org/). This product includes +cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP +software written by Thomas Bernard. + + +UNIX BUILD NOTES +================ + +To Build +-------- + +cd src/ +make -f makefile.unix xCPUARCH=armv7l # Headless bitcoin + +See readme-qt.rst for instructions on building Bitcoin QT, +the graphical bitcoin. + +Dependencies +------------ + + Library Purpose Description + ------- ------- ----------- + libssl SSL Support Secure communications + libdb4.8 Berkeley DB Blockchain & wallet storage + libboost Boost C++ Library + miniupnpc UPnP Support Optional firewall-jumping support + libqrencode QRCode generation Optional QRCode generation + +Note that libexecinfo should be installed, if you building under *BSD systems. +This library provides backtrace facility. + +miniupnpc may be used for UPnP port mapping. It can be downloaded from +http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and +turned off by default. Set USE_UPNP to a different value to control this: + USE_UPNP=- No UPnP support - miniupnp not required + USE_UPNP=0 (the default) UPnP support turned off by default at runtime + USE_UPNP=1 UPnP support turned on by default at runtime + +libqrencode may be used for QRCode image generation. It can be downloaded +from http://fukuchi.org/works/qrencode/index.html.en, or installed via +your package manager. Set USE_QRCODE to control this: + USE_QRCODE=0 (the default) No QRCode support - libqrcode not required + USE_QRCODE=1 QRCode support enabled + +Licenses of statically linked libraries: + Berkeley DB New BSD license with additional requirement that linked + software must be free open source + Boost MIT-like license + miniupnpc New (3-clause) BSD license + +Versions used in this release: + GCC 4.3.3 + OpenSSL 0.9.8g + Berkeley DB 4.8.30.NC + Boost 1.37 + miniupnpc 1.6 + +Dependency Build Instructions: Ubuntu & Debian +---------------------------------------------- +sudo apt-get install build-essential +sudo apt-get install libssl-dev +sudo apt-get install libdb4.8-dev +sudo apt-get install libdb4.8++-dev + Boost 1.40+: sudo apt-get install libboost-all-dev + or Boost 1.37: sudo apt-get install libboost1.37-dev +sudo apt-get install libqrencode-dev + +If using Boost 1.37, append -mt to the boost libraries in the makefile. + + +Dependency Build Instructions: Gentoo +------------------------------------- + +Note: If you just want to install bitcoind on Gentoo, you can add the Bitcoin + overlay and use your package manager: + layman -a bitcoin && emerge bitcoind + +emerge -av1 --noreplace boost glib openssl sys-libs/db:4.8 + +Take the following steps to build (no UPnP support): + cd ${BITCOIN_DIR}/src + make -f makefile.unix USE_UPNP= BDB_INCLUDE_PATH='/usr/include/db4.8' + strip bitcoind + + +Notes +----- +The release is built with GCC and then "strip bitcoind" to strip the debug +symbols, which reduces the executable size by about 90%. + + +miniupnpc +--------- +tar -xzvf miniupnpc-1.6.tar.gz +cd miniupnpc-1.6 +make +sudo su +make install + + +Berkeley DB +----------- +You need Berkeley DB 4.8. If you have to build Berkeley DB yourself: +../dist/configure --enable-cxx +make + + +Boost +----- +If you need to build Boost yourself: +sudo su +./bootstrap.sh +./bjam install + + +Security +-------- +To help make your bitcoin installation more secure by making certain attacks impossible to +exploit even if a vulnerability is found, you can take the following measures: + +* Position Independent Executable + Build position independent code to take advantage of Address Space Layout Randomization + offered by some kernels. An attacker who is able to cause execution of code at an arbitrary + memory location is thwarted if he doesn't know where anything useful is located. + The stack and heap are randomly located by default but this allows the code section to be + randomly located as well. + + On an Amd64 processor where a library was not compiled with -fPIC, this will cause an error + such as: "relocation R_X86_64_32 against `......' can not be used when making a shared object;" + + To build with PIE, use: + make -f makefile.unix ... -e PIE=1 + + To test that you have built PIE executable, install scanelf, part of paxutils, and use: + scanelf -e ./bitcoin + + The output should contain: + TYPE + ET_DYN + +* Non-executable Stack + If the stack is executable then trivial stack based buffer overflow exploits are possible if + vulnerable buffers are found. By default, bitcoin should be built with a non-executable stack + but if one of the libraries it uses asks for an executable stack or someone makes a mistake + and uses a compiler extension which requires an executable stack, it will silently build an + executable without the non-executable stack protection. + + To verify that the stack is non-executable after compiling use: + scanelf -e ./bitcoin + + the output should contain: + STK/REL/PTL + RW- R-- RW- + + The STK RW- means that the stack is readable and writeable but not executable. diff --git a/doc/readme-qt-arm.rst b/doc/readme-qt-arm.rst new file mode 100644 index 0000000..399b354 --- /dev/null +++ b/doc/readme-qt-arm.rst @@ -0,0 +1,114 @@ +Diamond-qt+armv7l: Qt4 GUI for Diamond +=============================== + +Build instructions +=================== + +Debian+armv7l +------- + +First, make sure that the required packages for Qt4 development of your +distribution are installed. + +Then we need to make sure our build environment is up to date. For Debian and Ubuntu: + +:: + + apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev \ + libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ + libssl-dev libdb5.1++-dev libminiupnpc-dev libminiupnpc8 + +then execute the following: + +:: + + qmake + make + +Alternatively, install Qt Creator and open the `diamond.pro` file. + +An executable named `diamond-qt` will be built. + + +Build configuration options +============================ + +UPNnP port forwarding +--------------------- + +To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable bitcoin experience), pass the following argument to qmake: + +:: + + qmake "USE_UPNP=1" + +(in **Qt Creator**, you can find the setting for additional qmake arguments under "Projects" -> "Build Settings" -> "Build Steps", then click "Details" next to **qmake**) + +This requires miniupnpc for UPnP port mapping. It can be downloaded from +http://miniupnp.tuxfamily.org/files/. UPnP support is not compiled in by default. + +Set USE_UPNP to a different value to control this: + ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=- | no UPnP support, miniupnpc not required; | ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=0 | (the default) built with UPnP, support turned off by default at runtime; | ++------------+--------------------------------------------------------------------------+ +| USE_UPNP=1 | build with UPnP support turned on by default at runtime. | ++------------+--------------------------------------------------------------------------+ + +Notification support for recent (k)ubuntu versions +--------------------------------------------------- + +To see desktop notifications on (k)ubuntu versions starting from 10.04, enable usage of the +FreeDesktop notification interface through DBUS using the following qmake option: + +:: + + qmake "USE_DBUS=1" + +Generation of QR codes +----------------------- + +libqrencode may be used to generate QRCode images for payment requests. +It can be downloaded from http://fukuchi.org/works/qrencode/index.html.en, or installed via your package manager. Pass the USE_QRCODE +flag to qmake to control this: + ++--------------+--------------------------------------------------------------------------+ +| USE_QRCODE=0 | (the default) No QRCode support - libarcode not required | ++--------------+--------------------------------------------------------------------------+ +| USE_QRCODE=1 | QRCode support enabled | ++--------------+--------------------------------------------------------------------------+ + + +Berkely DB version warning +========================== + +A warning for people using the *static binary* version of Bitcoin on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**). + +The static binary version of Bitcoin is linked against libdb4.8 (see also `this Debian issue`_). + +Now the nasty thing is that databases from 5.X are not compatible with 4.X. + +If the globally installed development package of Berkely DB installed on your system is 5.X, any source you +build yourself will be linked against that. The first time you run with a 5.X version the database will be upgraded, +and 4.X cannot open the new format. This means that you cannot go back to the old statically linked version without +significant hassle! + +.. _`this Debian issue`: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=621425 + +Ubuntu 11.10 warning +==================== + +Ubuntu 11.10 has a package called 'qt-at-spi' installed by default. At the time of writing, having that package +installed causes Diamond-qt to crash intermittently. The issue has been reported as `launchpad bug 857790`_, but +isn't yet fixed. + +Until the bug is fixed, you can remove the qt-at-spi package to work around the problem, though this will presumably +disable screen reader functionality for Qt apps: + +:: + + sudo apt-get remove qt-at-spi + +.. _`launchpad bug 857790`: https://bugs.launchpad.net/ubuntu/+source/qt-at-spi/+bug/857790 From 4e38f525491173428895a71cf64eb0454476eea6 Mon Sep 17 00:00:00 2001 From: Robert Zimmerman Date: Mon, 9 Mar 2015 21:54:00 -0700 Subject: [PATCH 076/218] Removed thumb instruction mode from GCC flags for RPi2 compatibility --- diamond.pro | 4 ++-- src/makefile.unix | 2 +- src/scrypt_mine.cpp | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/diamond.pro b/diamond.pro index e7ce84c..583f9d0 100644 --- a/diamond.pro +++ b/diamond.pro @@ -129,8 +129,8 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) { # Otherwise, assume sse2 exists !equals($$QMAKE_HOST.arch, armv7l) { message(FOUND host = $$QMAKE_HOST.arch) - QMAKE_CXXFLAGS += -mthumb -DNOSSE - QMAKE_CFLAGS += -mthumb -DNOSSE + QMAKE_CXXFLAGS += -DNOSSE + QMAKE_CFLAGS += -DNOSSE } else { QMAKE_CXXFLAGS += -msse2 diff --git a/src/makefile.unix b/src/makefile.unix index 34495f0..ac0ccd8 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -101,7 +101,7 @@ xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-para # Otherwise, assume sse2 exists # xCPUARCH is passed in as a define (xCPUARCH=armv7l) ifeq ($(xCPUARCH),armv7l) - xCXXFLAGS+=-mthumb -DNOSSE + xCXXFLAGS+= -DNOSSE else xCXXFLAGS+=-msse2 endif diff --git a/src/scrypt_mine.cpp b/src/scrypt_mine.cpp index 246ea43..2697abf 100644 --- a/src/scrypt_mine.cpp +++ b/src/scrypt_mine.cpp @@ -34,10 +34,8 @@ // need to make sure we don't try to use SSE instructions extern "C" { #ifndef NOSSE -#ifndef NO_ASM #include #endif -#endif } #include "scrypt_mine.h" From c25c5ce696b7530089d734f1342a8cfde4448c6a Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 18 Mar 2015 12:36:51 +0200 Subject: [PATCH 077/218] Address processing cleanup, whitespaces. --- src/base58.h | 12 +++++++++--- src/bignum.h | 1 - src/main.cpp | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/base58.h b/src/base58.h index a35e741..2c616a9 100644 --- a/src/base58.h +++ b/src/base58.h @@ -402,10 +402,16 @@ bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { class CBitcoinSecret : public CBase58Data { public: + enum + { + PRIVKEY_ADDRESS = CBitcoinAddress::PUBKEY_ADDRESS + 128, + PRIVKEY_ADDRESS_TEST = CBitcoinAddress::PUBKEY_ADDRESS_TEST + 128, + }; + void SetSecret(const CSecret& vchSecret, bool fCompressed) { assert(vchSecret.size() == 32); - SetData(128 + (fTestNet ? CBitcoinAddress::PUBKEY_ADDRESS_TEST : CBitcoinAddress::PUBKEY_ADDRESS), &vchSecret[0], vchSecret.size()); + SetData(fTestNet ? PRIVKEY_ADDRESS_TEST : PRIVKEY_ADDRESS, &vchSecret[0], vchSecret.size()); if (fCompressed) vchData.push_back(1); } @@ -424,10 +430,10 @@ class CBitcoinSecret : public CBase58Data bool fExpectTestNet = false; switch(nVersion) { - case (128 + CBitcoinAddress::PUBKEY_ADDRESS): + case PRIVKEY_ADDRESS: break; - case (128 + CBitcoinAddress::PUBKEY_ADDRESS_TEST): + case PRIVKEY_ADDRESS_TEST: fExpectTestNet = true; break; diff --git a/src/bignum.h b/src/bignum.h index c214275..c04fb0b 100644 --- a/src/bignum.h +++ b/src/bignum.h @@ -250,7 +250,6 @@ class CBigNum : public BIGNUM return n; } - void setvch(const std::vector& vch) { std::vector vch2(vch.size() + 4); diff --git a/src/main.cpp b/src/main.cpp index 98c943a..4ea5f2b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1155,7 +1155,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS } // danbi: old pre 2.0.4 PoS pacing algorithm else if (fProofOfStake && GetTotalCoin() > POS_RESTART) - { + { if(nActualSpacing < 0) { if (fDebug && GetBoolArg("-printjunk")) printf(">> %s nActualSpacing = %"PRI64d" corrected to 1.\n", fProofOfStake ? "PoS" : "PoW", nActualSpacing); From 21ff1ef6e1aaab0839767d0b2bd62c14b9fc9c00 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 18 Mar 2015 12:39:31 +0200 Subject: [PATCH 078/218] Fix to build on FreeBSD 10 --- src/makefile.bsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/makefile.bsd b/src/makefile.bsd index be08f0d..6ee0e4b 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -42,7 +42,7 @@ LIBS += \ -l db_cxx$(BDB_LIB_SUFFIX) \ -l ssl \ -l crypto \ - -l execinfo + -l execinfo -l elf ifndef USE_UPNP override USE_UPNP = - From 7f881123cd93037cff5761f8b1182d350e9f45a7 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 18 Mar 2015 12:43:03 +0200 Subject: [PATCH 079/218] Fix slow initial loading of pre-switch blocks --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4ea5f2b..96611c9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2140,8 +2140,8 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) return DoS(100, error("CheckBlock() : size limits failed")); // Check proof of work matches claimed amount -// if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) - if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits)) + // XXX: danbi - need to check both algos or we make it hard for initial sync + if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) return DoS(50, error("CheckBlock() : proof of work failed")); // Check timestamp From 32a47ceae22cd2f3e651d3480f83abae63dc1d2f Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 18 Mar 2015 12:46:15 +0200 Subject: [PATCH 080/218] Update version number to 2.0.4.1 --- src/clientversion.h | 2 +- src/qt/forms/aboutdialog.ui | 2 +- src/version.cpp | 2 +- src/version.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index 7e8397f..4c0a131 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 4 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_BUILD 1 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index ccb845a..8a8fd15 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.4 + 2.0.4.1 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.cpp b/src/version.cpp index 64900a6..a1f59f9 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -8,7 +8,7 @@ // Name of client reported in the 'version' message. Report the same name // for both bitcoind and bitcoin-qt, to make it harder for attackers to // target servers or GUI users specifically. -const std::string CLIENT_NAME("Diamond"); +const std::string CLIENT_NAME = "Diamond"; // Client version number #define CLIENT_VERSION_SUFFIX "" diff --git a/src/version.h b/src/version.h index bdbe42e..84c91eb 100644 --- a/src/version.h +++ b/src/version.h @@ -47,6 +47,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 4 -#define DISPLAY_VERSION_BUILD 0 +#define DISPLAY_VERSION_BUILD 1 #endif From 52be4f0c8b88a346f137be51e1f6019042e25383 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 18 Mar 2015 13:00:39 +0200 Subject: [PATCH 081/218] Contribution to makefile.unix by MitchellMint to make it compile on Raspberry Pi --- src/makefile.unix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/makefile.unix b/src/makefile.unix index 6d878e0..747fd1a 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -94,6 +94,9 @@ DEBUGFLAGS=-g # CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only # adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work. +# If you are compiling on Raspberry Pi use the following, see +# raspberry pi website. http://www.raspberrypi.org/forums/viewtopic.php?f=33&t=27674 +#xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ xCXXFLAGS=-O2 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) From 0207a83a610bcce59667ba5b6037268f7332e767 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 18 Mar 2015 16:01:16 +0200 Subject: [PATCH 082/218] Revert back the pre-fork version of the text --- README.md | 65 +++++++++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 22a6a7b..add9662 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,34 @@ Diamond (DMD) -=== -Fork Information -=== +Instructions for compiling in Linux. -This branch is an unofficial offshoot that allows building for armv7l -architecture CPUs. It was made for the convenience of people that either -use an ARM desktop or run an ARM server and who want to keep their -wallet open to mint coins via POS or want to run an energy-efficient -node for solo mining. +Update ubuntu + + sudo apt-get update -This fork really only adds a few lines of changes to the Makefile and -Qt's version of a makefile. It might even be a drop-in solution for the -future, if neither have significant changes made to them. (Either that -or the Diamond team will merge it.) +*install git to download the source code -Information for building is located in: -[doc/build-unix-arm.txt](doc/build-unix-arm.txt) for headless and -[doc/readme-qt-arm.rst](doc/readme-qt-arm.rst) for the Qt GUI. + sudo apt-get install git +*install the other necessary components -Instructions for compiling in Linux for armv7l. ---- + sudo apt-get install build-essential libboost1.55-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev -Update ubuntu -``` -sudo apt-get update -``` -*install git to download the source code -``` -sudo apt-get install git -``` -*install the other necessary components -``` -sudo apt-get install build-essential libboost1.55-all-dev libcurl4-openssl-dev libdb5.1-dev libdb5.1++-dev -``` *navigate to the home directory -``` -cd ~ *download the diamond source code -git clone https://github.com/DMDcoin/Diamond.git -``` + + cd ~ *download the diamond source code + + git clone https://github.com/DMDcoin/Diamond.git + *navigate to the downloaded files -``` -cd ~ *navigate to the src file in the source code -cd diamond/src -``` + + cd ~ *navigate to the src file in the source code + cd diamond/src + *create obj folder -``` -mkdir obj -``` + + mkdir obj + *build diamondd !This will take a while! -``` -make -f makefile.unix xCPUARCH=armv7l -``` \ No newline at end of file + + make -f makefile.unix USE_UPNP=- From 33f31dd74eda936bc33011c356f6836c0e17a946 Mon Sep 17 00:00:00 2001 From: Robert Zimmerman Date: Sun, 22 Mar 2015 04:04:13 -0700 Subject: [PATCH 083/218] Fixing support for SSE2 on x86/x64, adding support for armv6l Previously, compilation worked for all architectures at the expense of the use of SSE2 instructions. The offending line (where $$QMAKE_HOST.arch is checked) always returned true. This is because $$QMAKE_HOST.arch was not read properly before the equals() check, making the check return false. It was then not-ed and returned true. Thus support for ARM was achieved because of two errors cancelling eachother out, but negatively impacting non-ARM processor performance. This is previously addressed in https://github.com/DMDcoin/Diamond/commit/52be4f0c8b88a346f137be51e1f6019042e25383 because it added back in the -msse2 flag, but it added it for all compiles instead of using it selectively for non-ARM compiles. This patch explicitly defines QMAKE_XCPUARCH = $$QMAKE_HOST.arch before the equals check, removes the not on the equals() check, and adds in a check for armv6l architecture CPUs as well. It also adds support for armv6l (original Raspberry Pi) headless wallet builds by adding in the appropriate check for xCPUARCH in the Unix makefile. All previously ARM-ified readmes have been merged into the main readmes for cleanliness. --- diamond.pro | 16 +++++++++++----- doc/build-unix.txt | 29 ++++++++++++++++++++++++++--- doc/readme-qt.rst | 31 +++++++++++++++++++++---------- src/makefile.unix | 12 +++++------- 4 files changed, 63 insertions(+), 25 deletions(-) diff --git a/diamond.pro b/diamond.pro index 583f9d0..60d6802 100644 --- a/diamond.pro +++ b/diamond.pro @@ -123,16 +123,22 @@ contains(BITCOIN_NEED_QT_PLUGINS, 1) { DEFINES += HAVE_BUILD_INFO } -# If we have an arm device, we can't use sse2, so define as thumb +# If we have an ARM device, we can't use SSE2 instructions, so don't try to use them # Because of scrypt_mine.cpp, we also have to add a compile # flag that states we *really* don't have SSE -# Otherwise, assume sse2 exists -!equals($$QMAKE_HOST.arch, armv7l) { - message(FOUND host = $$QMAKE_HOST.arch) - QMAKE_CXXFLAGS += -DNOSSE +QMAKE_XCPUARCH = $$QMAKE_HOST.arch +equals(QMAKE_XCPUARCH, armv7l) { + message(Building without SSE2 support) + QMAKE_CXXFLAGS += -DNOSSE + QMAKE_CFLAGS += -DNOSSE +} +else:equals(QMAKE_XCPUARCH, armv6l) { + message(Building without SSE2 support) + QMAKE_CXXFLAGS += -DNOSSE QMAKE_CFLAGS += -DNOSSE } else { + message(Building with SSE2 support) QMAKE_CXXFLAGS += -msse2 QMAKE_CFLAGS += -msse2 } diff --git a/doc/build-unix.txt b/doc/build-unix.txt index 3dffb22..3388063 100644 --- a/doc/build-unix.txt +++ b/doc/build-unix.txt @@ -10,16 +10,26 @@ software written by Thomas Bernard. UNIX BUILD NOTES ================ -To Build +To Build On i386, amd64 -------- cd src/ -make -f makefile.unix # Headless bitcoin +make -f makefile.unix # Headless diamond + +To Build On armv6l +-------- +cd src/ +make -f makefile.unix xCPUARCH=armv6l # Headless diamond + +To Build On armv7l +-------- +cd src/ +make -f makefile.unix xCPUARCH=armv7l # Headless diamond See readme-qt.rst for instructions on building Bitcoin QT, the graphical bitcoin. -Dependencies +Dependencies for i386, amd64 ------------ Library Purpose Description @@ -29,6 +39,19 @@ Dependencies libboost Boost C++ Library miniupnpc UPnP Support Optional firewall-jumping support libqrencode QRCode generation Optional QRCode generation + libgmp3 GMP Multiple precision arithmetic library + +Dependencies for armv6l, armv7l +------------ + + Library Purpose Description + ------- ------- ----------- + libssl SSL Support Secure communications + libdb5.1 Berkeley DB Blockchain & wallet storage + libboost Boost C++ Library + miniupnpc UPnP Support Optional firewall-jumping support + libqrencode QRCode generation Optional QRCode generation + libgmp3 GMP Multiple precision arithmetic library Note that libexecinfo should be installed, if you building under *BSD systems. This library provides backtrace facility. diff --git a/doc/readme-qt.rst b/doc/readme-qt.rst index 45100bb..faa28ea 100644 --- a/doc/readme-qt.rst +++ b/doc/readme-qt.rst @@ -4,25 +4,36 @@ Diamond-qt: Qt5 GUI for Diamond Build instructions =================== -Debian +Debian (i386, amd64) ------- -First, make sure that the required packages for Qt4 development of your -distribution are installed. +First, make sure that the required packages for Qt5 development of your +distribution are installed, for Debian and Ubuntu (i386, amd64) these are: -On recent Ubuntu releases, the `libdb4.8++-dev` package is not in the default -repositories. However it's in the bitcoin repository, which we can add -with: +:: - apt-add-repository ppa:bitcoin/bitcoin + apt-get install qt5-qmake libqt5-dev build-essential libboost-dev libboost-system-dev \ + libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ + libssl-dev libdb4.8++-dev libminiupnpc-dev libminiupnpc8 -Then we need to make sure our build environment is up to date. For Debian and Ubuntu: +then execute the following: :: - apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev \ + qmake + make + +Debian (armv6l, armv7l) +------- + +First, make sure that the required packages for Qt5 development of your +distribution are installed, for Debian and Ubuntu (i386, amd64) these are: + +:: + + apt-get install qt5-qmake libqt5-dev build-essential libboost-dev libboost-system-dev \ libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ - libssl-dev libdb4.8++-dev libminiupnpc-dev libminiupnpc8 + libssl-dev libdb5.1++-dev libminiupnpc-dev libminiupnpc8 then execute the following: diff --git a/src/makefile.unix b/src/makefile.unix index fb2735b..3df072e 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -94,17 +94,15 @@ DEBUGFLAGS=-g # CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only # adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work. -# If you are compiling on Raspberry Pi use the following, see -# raspberry pi website. http://www.raspberrypi.org/forums/viewtopic.php?f=33&t=27674 -#xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ -xCXXFLAGS=-O2 -msse2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ +xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) -# If we have an arm device, we can't use sse2, so define as thumb -# Otherwise, assume sse2 exists -# xCPUARCH is passed in as a define (xCPUARCH=armv7l) +# If we have an ARM device, we can't use SSE2 instructions, so don't try to use them +# xCPUARCH is passed in as a define (xCPUARCH=armv7l, xCPUARCH=armv6l) ifeq ($(xCPUARCH),armv7l) xCXXFLAGS+= -DNOSSE +else ifeq ($(xCPUARCH),armv6l) + xCXXFLAGS+= -DNOSSE else xCXXFLAGS+=-msse2 endif From fa89f448c80853782e0018186675caf764548e14 Mon Sep 17 00:00:00 2001 From: Robert Zimmerman Date: Sun, 22 Mar 2015 14:53:33 -0700 Subject: [PATCH 084/218] Removing obsolete documentation --- doc/build-unix-arm.txt | 159 ----------------------------------------- doc/readme-qt-arm.rst | 114 ----------------------------- 2 files changed, 273 deletions(-) delete mode 100644 doc/build-unix-arm.txt delete mode 100644 doc/readme-qt-arm.rst diff --git a/doc/build-unix-arm.txt b/doc/build-unix-arm.txt deleted file mode 100644 index 5d469ed..0000000 --- a/doc/build-unix-arm.txt +++ /dev/null @@ -1,159 +0,0 @@ -Copyright (c) 2009-2012 Bitcoin Developers -Distributed under the MIT/X11 software license, see the accompanying -file license.txt or http://www.opensource.org/licenses/mit-license.php. -This product includes software developed by the OpenSSL Project for use in -the OpenSSL Toolkit (http://www.openssl.org/). This product includes -cryptographic software written by Eric Young (eay@cryptsoft.com) and UPnP -software written by Thomas Bernard. - - -UNIX BUILD NOTES -================ - -To Build --------- - -cd src/ -make -f makefile.unix xCPUARCH=armv7l # Headless bitcoin - -See readme-qt.rst for instructions on building Bitcoin QT, -the graphical bitcoin. - -Dependencies ------------- - - Library Purpose Description - ------- ------- ----------- - libssl SSL Support Secure communications - libdb4.8 Berkeley DB Blockchain & wallet storage - libboost Boost C++ Library - miniupnpc UPnP Support Optional firewall-jumping support - libqrencode QRCode generation Optional QRCode generation - -Note that libexecinfo should be installed, if you building under *BSD systems. -This library provides backtrace facility. - -miniupnpc may be used for UPnP port mapping. It can be downloaded from -http://miniupnp.tuxfamily.org/files/. UPnP support is compiled in and -turned off by default. Set USE_UPNP to a different value to control this: - USE_UPNP=- No UPnP support - miniupnp not required - USE_UPNP=0 (the default) UPnP support turned off by default at runtime - USE_UPNP=1 UPnP support turned on by default at runtime - -libqrencode may be used for QRCode image generation. It can be downloaded -from http://fukuchi.org/works/qrencode/index.html.en, or installed via -your package manager. Set USE_QRCODE to control this: - USE_QRCODE=0 (the default) No QRCode support - libqrcode not required - USE_QRCODE=1 QRCode support enabled - -Licenses of statically linked libraries: - Berkeley DB New BSD license with additional requirement that linked - software must be free open source - Boost MIT-like license - miniupnpc New (3-clause) BSD license - -Versions used in this release: - GCC 4.3.3 - OpenSSL 0.9.8g - Berkeley DB 4.8.30.NC - Boost 1.37 - miniupnpc 1.6 - -Dependency Build Instructions: Ubuntu & Debian ----------------------------------------------- -sudo apt-get install build-essential -sudo apt-get install libssl-dev -sudo apt-get install libdb4.8-dev -sudo apt-get install libdb4.8++-dev - Boost 1.40+: sudo apt-get install libboost-all-dev - or Boost 1.37: sudo apt-get install libboost1.37-dev -sudo apt-get install libqrencode-dev - -If using Boost 1.37, append -mt to the boost libraries in the makefile. - - -Dependency Build Instructions: Gentoo -------------------------------------- - -Note: If you just want to install bitcoind on Gentoo, you can add the Bitcoin - overlay and use your package manager: - layman -a bitcoin && emerge bitcoind - -emerge -av1 --noreplace boost glib openssl sys-libs/db:4.8 - -Take the following steps to build (no UPnP support): - cd ${BITCOIN_DIR}/src - make -f makefile.unix USE_UPNP= BDB_INCLUDE_PATH='/usr/include/db4.8' - strip bitcoind - - -Notes ------ -The release is built with GCC and then "strip bitcoind" to strip the debug -symbols, which reduces the executable size by about 90%. - - -miniupnpc ---------- -tar -xzvf miniupnpc-1.6.tar.gz -cd miniupnpc-1.6 -make -sudo su -make install - - -Berkeley DB ------------ -You need Berkeley DB 4.8. If you have to build Berkeley DB yourself: -../dist/configure --enable-cxx -make - - -Boost ------ -If you need to build Boost yourself: -sudo su -./bootstrap.sh -./bjam install - - -Security --------- -To help make your bitcoin installation more secure by making certain attacks impossible to -exploit even if a vulnerability is found, you can take the following measures: - -* Position Independent Executable - Build position independent code to take advantage of Address Space Layout Randomization - offered by some kernels. An attacker who is able to cause execution of code at an arbitrary - memory location is thwarted if he doesn't know where anything useful is located. - The stack and heap are randomly located by default but this allows the code section to be - randomly located as well. - - On an Amd64 processor where a library was not compiled with -fPIC, this will cause an error - such as: "relocation R_X86_64_32 against `......' can not be used when making a shared object;" - - To build with PIE, use: - make -f makefile.unix ... -e PIE=1 - - To test that you have built PIE executable, install scanelf, part of paxutils, and use: - scanelf -e ./bitcoin - - The output should contain: - TYPE - ET_DYN - -* Non-executable Stack - If the stack is executable then trivial stack based buffer overflow exploits are possible if - vulnerable buffers are found. By default, bitcoin should be built with a non-executable stack - but if one of the libraries it uses asks for an executable stack or someone makes a mistake - and uses a compiler extension which requires an executable stack, it will silently build an - executable without the non-executable stack protection. - - To verify that the stack is non-executable after compiling use: - scanelf -e ./bitcoin - - the output should contain: - STK/REL/PTL - RW- R-- RW- - - The STK RW- means that the stack is readable and writeable but not executable. diff --git a/doc/readme-qt-arm.rst b/doc/readme-qt-arm.rst deleted file mode 100644 index 399b354..0000000 --- a/doc/readme-qt-arm.rst +++ /dev/null @@ -1,114 +0,0 @@ -Diamond-qt+armv7l: Qt4 GUI for Diamond -=============================== - -Build instructions -=================== - -Debian+armv7l -------- - -First, make sure that the required packages for Qt4 development of your -distribution are installed. - -Then we need to make sure our build environment is up to date. For Debian and Ubuntu: - -:: - - apt-get install qt4-qmake libqt4-dev build-essential libboost-dev libboost-system-dev \ - libboost-filesystem-dev libboost-program-options-dev libboost-thread-dev \ - libssl-dev libdb5.1++-dev libminiupnpc-dev libminiupnpc8 - -then execute the following: - -:: - - qmake - make - -Alternatively, install Qt Creator and open the `diamond.pro` file. - -An executable named `diamond-qt` will be built. - - -Build configuration options -============================ - -UPNnP port forwarding ---------------------- - -To use UPnP for port forwarding behind a NAT router (recommended, as more connections overall allow for a faster and more stable bitcoin experience), pass the following argument to qmake: - -:: - - qmake "USE_UPNP=1" - -(in **Qt Creator**, you can find the setting for additional qmake arguments under "Projects" -> "Build Settings" -> "Build Steps", then click "Details" next to **qmake**) - -This requires miniupnpc for UPnP port mapping. It can be downloaded from -http://miniupnp.tuxfamily.org/files/. UPnP support is not compiled in by default. - -Set USE_UPNP to a different value to control this: - -+------------+--------------------------------------------------------------------------+ -| USE_UPNP=- | no UPnP support, miniupnpc not required; | -+------------+--------------------------------------------------------------------------+ -| USE_UPNP=0 | (the default) built with UPnP, support turned off by default at runtime; | -+------------+--------------------------------------------------------------------------+ -| USE_UPNP=1 | build with UPnP support turned on by default at runtime. | -+------------+--------------------------------------------------------------------------+ - -Notification support for recent (k)ubuntu versions ---------------------------------------------------- - -To see desktop notifications on (k)ubuntu versions starting from 10.04, enable usage of the -FreeDesktop notification interface through DBUS using the following qmake option: - -:: - - qmake "USE_DBUS=1" - -Generation of QR codes ------------------------ - -libqrencode may be used to generate QRCode images for payment requests. -It can be downloaded from http://fukuchi.org/works/qrencode/index.html.en, or installed via your package manager. Pass the USE_QRCODE -flag to qmake to control this: - -+--------------+--------------------------------------------------------------------------+ -| USE_QRCODE=0 | (the default) No QRCode support - libarcode not required | -+--------------+--------------------------------------------------------------------------+ -| USE_QRCODE=1 | QRCode support enabled | -+--------------+--------------------------------------------------------------------------+ - - -Berkely DB version warning -========================== - -A warning for people using the *static binary* version of Bitcoin on a Linux/UNIX-ish system (tl;dr: **Berkely DB databases are not forward compatible**). - -The static binary version of Bitcoin is linked against libdb4.8 (see also `this Debian issue`_). - -Now the nasty thing is that databases from 5.X are not compatible with 4.X. - -If the globally installed development package of Berkely DB installed on your system is 5.X, any source you -build yourself will be linked against that. The first time you run with a 5.X version the database will be upgraded, -and 4.X cannot open the new format. This means that you cannot go back to the old statically linked version without -significant hassle! - -.. _`this Debian issue`: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=621425 - -Ubuntu 11.10 warning -==================== - -Ubuntu 11.10 has a package called 'qt-at-spi' installed by default. At the time of writing, having that package -installed causes Diamond-qt to crash intermittently. The issue has been reported as `launchpad bug 857790`_, but -isn't yet fixed. - -Until the bug is fixed, you can remove the qt-at-spi package to work around the problem, though this will presumably -disable screen reader functionality for Qt apps: - -:: - - sudo apt-get remove qt-at-spi - -.. _`launchpad bug 857790`: https://bugs.launchpad.net/ubuntu/+source/qt-at-spi/+bug/857790 From 08ea53a6fe774ae4c91dc650348379f417194faa Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 09:43:32 +0100 Subject: [PATCH 085/218] Defining reward lowering points. --- src/main.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.h b/src/main.h index 4f1dd61..6712818 100644 --- a/src/main.h +++ b/src/main.h @@ -41,6 +41,8 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS +static const int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; // when total supply == 1 000 000 +static const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" From 6e68c02a8468440988fe613ae009abef1ebed709 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 10:05:36 +0100 Subject: [PATCH 086/218] Added isRewardDecreased --- src/main.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 96611c9..6dcc1b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -81,6 +81,39 @@ int64 nHPSTimerStart; // Settings int64 nTransactionFee = MIN_TX_FEE; +// Eagle test settings +int64 blockBeforeFirstDecrease = 0; +int64 blocbBeforeSecondDecrease = 0; + + + + + +unsigned int isRewardDecreased() { + if (totalCoin > SECOND_REWARD_DECREASE_AT_COIN) { + if ((blocbBeforeSecondDecrease > 0) && (blocbBeforeSecondDecrease != nBestHeight)) { + printf("EAGLE: isRewardDecreased RETURNING 2\n"); + return 2; + } else if (blocbBeforeSecondDecrease == 0) { + blocbBeforeSecondDecrease = nBestHeight; + printf("EAGLE: isRewardDecreased setting blocbBeforeSecondDecrease=%d RETURNING 0\n", nBestHeight); + return 0; + } + } else if (totalCoin > FIRST_REWARD_DECREASE_AT_COIN) { + if ((blockBeforeFirstDecrease > 0) && (blockBeforeFirstDecrease != nBestHeight)) { + printf("EAGLE: isRewardDecreased RETURNING 1\n"); + return 1; + } else if (blockBeforeFirstDecrease == 0) { + blockBeforeFirstDecrease = nBestHeight; + printf("EAGLE: isRewardDecreased setting blockBeforeFirstDecrease=%d RETURNING 0\n", nBestHeight); + return 0; + } + } + + return 0; +} + + ////////////////////////////////////////////////////////////////////////////// // From e589bc4b5ff5b1589aa1ad23c7d2ac433cb5e854 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 10:43:56 +0100 Subject: [PATCH 087/218] Bumping up version --- src/version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/version.h b/src/version.h index 84c91eb..1dfd5ae 100644 --- a/src/version.h +++ b/src/version.h @@ -25,7 +25,7 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60006; +static const int PROTOCOL_VERSION = 60009; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; @@ -46,7 +46,7 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 -#define DISPLAY_VERSION_REVISION 4 -#define DISPLAY_VERSION_BUILD 1 +#define DISPLAY_VERSION_REVISION 5 +#define DISPLAY_VERSION_BUILD 0 #endif From 2d07725b9fe3d0557091b41afab0eac1358947b3 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 11:23:40 +0100 Subject: [PATCH 088/218] Added dropping connections to old clients after first reward decrease --- src/main.cpp | 22 +++++++++++++++++++++- src/main.h | 2 +- src/version.h | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6dcc1b8..9cae411 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -84,12 +84,13 @@ int64 nTransactionFee = MIN_TX_FEE; // Eagle test settings int64 blockBeforeFirstDecrease = 0; int64 blocbBeforeSecondDecrease = 0; - +bool eagleoldclients = false; unsigned int isRewardDecreased() { +// should we calculate totalCoin here to be absolutely sure it is up to date? if (totalCoin > SECOND_REWARD_DECREASE_AT_COIN) { if ((blocbBeforeSecondDecrease > 0) && (blocbBeforeSecondDecrease != nBestHeight)) { printf("EAGLE: isRewardDecreased RETURNING 2\n"); @@ -3033,6 +3034,19 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // make sure we have current totalCoin totalCoin = GetTotalCoin(); + if ((fDebug) && (!eagleoldclients)) + if (isRewardDecreased()) { + printf("EAGLE INFO: SWITCH! Beginning to disconnect old clients\n"); + eagleoldclients = true; + } + + if (isRewardDecreased() && (pfrom->nVersion) && + (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { + printf("(EAGLE1) ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + pfrom->fDisconnect = true; + return false; + } + if (strCommand == "version") { // Each connection can only send one version message @@ -3056,6 +3070,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return false; } + if (isRewardDecreased() && (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { + printf("(EAGLE2) ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + pfrom->fDisconnect = true; + return false; + } + if (pfrom->nVersion == 10300) pfrom->nVersion = 300; if (!vRecv.empty()) diff --git a/src/main.h b/src/main.h index 6712818..80c5025 100644 --- a/src/main.h +++ b/src/main.h @@ -41,7 +41,7 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -static const int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; // when total supply == 1 000 000 +static const int64 FIRST_REWARD_DECREASE_AT_COIN = 958762; // when total supply == 1 000 000 static const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" diff --git a/src/version.h b/src/version.h index 1dfd5ae..4ef6911 100644 --- a/src/version.h +++ b/src/version.h @@ -26,6 +26,7 @@ extern const std::string CLIENT_DATE; // static const int PROTOCOL_VERSION = 60009; +static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60009; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; From f5e7ed0c7e1887ec9d176aaf3d0405c2d0dcdf4f Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 11:40:58 +0100 Subject: [PATCH 089/218] - Modified PoW reward - Modified isRewardDecreased() to check for >= condition --- src/main.cpp | 16 ++++++++-------- src/main.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9cae411..6885c8f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -91,7 +91,7 @@ bool eagleoldclients = false; unsigned int isRewardDecreased() { // should we calculate totalCoin here to be absolutely sure it is up to date? - if (totalCoin > SECOND_REWARD_DECREASE_AT_COIN) { + if (totalCoin >= SECOND_REWARD_DECREASE_AT_COIN) { if ((blocbBeforeSecondDecrease > 0) && (blocbBeforeSecondDecrease != nBestHeight)) { printf("EAGLE: isRewardDecreased RETURNING 2\n"); return 2; @@ -100,7 +100,7 @@ unsigned int isRewardDecreased() { printf("EAGLE: isRewardDecreased setting blocbBeforeSecondDecrease=%d RETURNING 0\n", nBestHeight); return 0; } - } else if (totalCoin > FIRST_REWARD_DECREASE_AT_COIN) { + } else if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { if ((blockBeforeFirstDecrease > 0) && (blockBeforeFirstDecrease != nBestHeight)) { printf("EAGLE: isRewardDecreased RETURNING 1\n"); return 1; @@ -1007,12 +1007,12 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) else { // Diamond v2 coin mechanics - // 0.10 reward after 1,000,000 created - // 0.02 reward after 2,500,000 created - if(totalCoin > 2500000) - nSubsidy = 2 * CENT; - else if(totalCoin > 1000000) - nSubsidy = 10 * CENT; + // 0.20 reward after 1,000,000 created + // 0.04 reward after 2,500,000 created + if(isRewardDecreased() == 2) + nSubsidy = 4 * CENT; + else if(isRewardDecreased() == 1) + nSubsidy = 20 * CENT; } return nSubsidy + nFees; } diff --git a/src/main.h b/src/main.h index 80c5025..bfe26ca 100644 --- a/src/main.h +++ b/src/main.h @@ -41,7 +41,7 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -static const int64 FIRST_REWARD_DECREASE_AT_COIN = 958762; // when total supply == 1 000 000 +static const int64 FIRST_REWARD_DECREASE_AT_COIN = 958780; // when total supply == 1 000 000 static const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" From a3961a15ef54c407f0c1f9d1508994ad70a94322 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 12:34:57 +0100 Subject: [PATCH 090/218] Changing the way return value of isRewardDecreased is checked --- src/main.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6885c8f..321fd3f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,11 +85,12 @@ int64 nTransactionFee = MIN_TX_FEE; int64 blockBeforeFirstDecrease = 0; int64 blocbBeforeSecondDecrease = 0; bool eagleoldclients = false; +int64 eaglesubsidy = 0; +int eagledecreased = 0; - -unsigned int isRewardDecreased() { +int isRewardDecreased() { // should we calculate totalCoin here to be absolutely sure it is up to date? if (totalCoin >= SECOND_REWARD_DECREASE_AT_COIN) { if ((blocbBeforeSecondDecrease > 0) && (blocbBeforeSecondDecrease != nBestHeight)) { @@ -1009,10 +1010,22 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) // Diamond v2 coin mechanics // 0.20 reward after 1,000,000 created // 0.04 reward after 2,500,000 created - if(isRewardDecreased() == 2) + eagledecreased = isRewardDecreased(); + if(eagledecreased > 1) { nSubsidy = 4 * CENT; - else if(isRewardDecreased() == 1) + printf("EAGLE: subsidy SET TO 4 isRewardDecreased=%d\n", eagledecreased); + if (fDebug && (eaglesubsidy == 1)) { + printf("EAGLE INFO: SECOND REWARD DROP! CHANGING subsidy to 4 CENT\n"); + eaglesubsidy = 2; + } + } else if(eagledecreased > 0) { nSubsidy = 20 * CENT; + printf("EAGLE: subsidy SET TO 20 isRewardDecreased=%d\n", eagledecreased); + if (fDebug && !eaglesubsidy) { + printf("EAGLE INFO: FIRST REWARD DROP! CHANGING subsidy to 20 CENT\n"); + eaglesubsidy = 1; + } + } } return nSubsidy + nFees; } From 3d3bab77ceb87e6a1c488d785f06874f98d493f7 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 13:17:48 +0100 Subject: [PATCH 091/218] Changing PoW/PoS block spacing --- src/main.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 321fd3f..b66500a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -87,7 +87,7 @@ int64 blocbBeforeSecondDecrease = 0; bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; - +int eaglespacing = 0; int isRewardDecreased() { @@ -2171,9 +2171,17 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const { + if (isRewardDecreased()) { + nStakeTargetSpacing = 2 * 60; // pos block spacing set to 2 minutes after first reward reduction + nWorkTargetSpacing = 2 * 60; // pow block spacing set to 2 minutes after first reward reduction + nCoinbaseMaturity = 180; // coinbase maturity does not change + if (fDebug && !eaglespacing) { + printf("EAGLE (checkblock): spacing for both PoW/PoS to 120/120"); + eaglespacing = 1; + } // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork - if(totalCoin > VALUE_CHANGE && !fTestNet) + } else if(totalCoin > VALUE_CHANGE && !fTestNet) { nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks From ee845d329cc348b9fb3b4b64eb371425de3e18a4 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 23 Mar 2015 17:58:35 +0100 Subject: [PATCH 092/218] Setting FIRST_REWARD_DECREASE_AT_COIN to 1 mil --- src/main.cpp | 2 +- src/main.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b66500a..0f9280a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2176,7 +2176,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nWorkTargetSpacing = 2 * 60; // pow block spacing set to 2 minutes after first reward reduction nCoinbaseMaturity = 180; // coinbase maturity does not change if (fDebug && !eaglespacing) { - printf("EAGLE (checkblock): spacing for both PoW/PoS to 120/120"); + printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120"); eaglespacing = 1; } // Update the coin mechanics variables post algorithm change diff --git a/src/main.h b/src/main.h index bfe26ca..6712818 100644 --- a/src/main.h +++ b/src/main.h @@ -41,7 +41,7 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -static const int64 FIRST_REWARD_DECREASE_AT_COIN = 958780; // when total supply == 1 000 000 +static const int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; // when total supply == 1 000 000 static const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" From 3158e76677d6e0905848addccab233f036989ae6 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Tue, 24 Mar 2015 12:43:36 +0100 Subject: [PATCH 093/218] Updating aboutdialog.ui to show version 2.0.5 --- src/qt/forms/aboutdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 8a8fd15..7d9d91e 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.4.1 + 2.0.5 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse From 6dec876d2c411a77ec879f731450621d90e084c3 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Tue, 24 Mar 2015 14:32:21 +0100 Subject: [PATCH 094/218] Removing payment to foundation after first trigger --- src/main.cpp | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0f9280a..2ecd1ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,11 +103,11 @@ int isRewardDecreased() { } } else if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { if ((blockBeforeFirstDecrease > 0) && (blockBeforeFirstDecrease != nBestHeight)) { - printf("EAGLE: isRewardDecreased RETURNING 1\n"); +// printf("EAGLE: isRewardDecreased RETURNING 1\n"); return 1; } else if (blockBeforeFirstDecrease == 0) { blockBeforeFirstDecrease = nBestHeight; - printf("EAGLE: isRewardDecreased setting blockBeforeFirstDecrease=%d RETURNING 0\n", nBestHeight); +// printf("EAGLE: isRewardDecreased setting blockBeforeFirstDecrease=%d RETURNING 0\n", nBestHeight); return 0; } } @@ -1748,8 +1748,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // danbi: update totalCoin as we are one behind here // XXX: this might backfire in case of error... totalCoin = pindex->nMoneySupply / COIN; - if(totalCoin <= VALUE_CHANGE) + if ((totalCoin <= VALUE_CHANGE) || (isRewardDecreased())) { + if (fDebug && isRewardDecreased()) + printf("EAGLE5: isRewardDecreased==TRUE: testing old ValueOut\n"); if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) return error("ConnectBlock() : claiming to have created too much (old)"); } @@ -1757,8 +1759,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) return error("ConnectBlock() : claiming to have created too much (new)"); - if(totalCoin > VALUE_CHANGE && IsProofOfWork()) + if ((totalCoin > VALUE_CHANGE && IsProofOfWork()) && (!isRewardDecreased())) { + if (fDebug) + printf("EAGLE6: payment to FOUNDATION ADDRESS\n"); CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); CScript scriptPubKey; scriptPubKey.SetDestination(address.Get()); @@ -4130,8 +4134,10 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - if(totalCoin > VALUE_CHANGE) + if ((totalCoin > VALUE_CHANGE) && (!isRewardDecreased())) { + if (fDebug) + printf("EAGLE7: CreateNewBlock() - payment to foundation\n"); CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); txNew.vout.resize(2); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; @@ -4139,6 +4145,8 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) } else { + if (fDebug) + printf("EAGLE8: CreateNewBlock - no payment to foundation\n"); txNew.vout.resize(1); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; } @@ -4395,8 +4403,11 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfWork()) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); - if(totalCoin > VALUE_CHANGE) + if ((totalCoin > VALUE_CHANGE) && (!isRewardDecreased())) { + if (fDebug) + printf("EAGLE9: Create new block - payment to foundation\n"); pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); + } } // Fill in header @@ -4751,13 +4762,17 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet) // Diamond coin mechanics // Foundation contribution // 0.05 until 1000000 coins generated -// 0.01 afterwards +// 0 afterwards // Changing this requires a fork int64 GetContributionAmount(int64 totalCoin) { - if(totalCoin < 1000000) + if(!isRewardDecreased()) return 0.05 * COIN; else - return 0.01 * COIN; + { + if (fDebug) + printf("EAGLE10: GetContributionAmount - RETURNING 0 since we have passed trigger\n"); + return 0; + } } uint256 CBlock::GetHash(bool existingBlock) const From 29cf3025f576660856fa03627dc5a33d58fd971b Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Tue, 24 Mar 2015 14:37:06 +0100 Subject: [PATCH 095/218] Coin age is being lowered to 3 days after first reward reduction --- src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2ecd1ee..2a705f4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2176,9 +2176,10 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const { if (isRewardDecreased()) { - nStakeTargetSpacing = 2 * 60; // pos block spacing set to 2 minutes after first reward reduction - nWorkTargetSpacing = 2 * 60; // pow block spacing set to 2 minutes after first reward reduction - nCoinbaseMaturity = 180; // coinbase maturity does not change + nStakeTargetSpacing = 2 * 60; // pos block spacing set to 2 minutes after first reward reduction + nWorkTargetSpacing = 2 * 60; // pow block spacing set to 2 minutes after first reward reduction + nCoinbaseMaturity = 180; // coinbase maturity does not change + nStakeMinAge = 60 * 60 * 24 * 3 // min age is lowered from 7 to 3 after first reward reduction if (fDebug && !eaglespacing) { printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120"); eaglespacing = 1; From 1b4586ea468aa3a63ff9c5bd975c11f3b3665f35 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Tue, 24 Mar 2015 14:49:46 +0100 Subject: [PATCH 096/218] Fixing missing comma --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2a705f4..a685778 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2179,9 +2179,9 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nStakeTargetSpacing = 2 * 60; // pos block spacing set to 2 minutes after first reward reduction nWorkTargetSpacing = 2 * 60; // pow block spacing set to 2 minutes after first reward reduction nCoinbaseMaturity = 180; // coinbase maturity does not change - nStakeMinAge = 60 * 60 * 24 * 3 // min age is lowered from 7 to 3 after first reward reduction + nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 after first reward reduction if (fDebug && !eaglespacing) { - printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120"); + printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days"); eaglespacing = 1; } // Update the coin mechanics variables post algorithm change From ef8d159e1a2c9c4e1f88d66125e9ba5564db69b7 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Tue, 24 Mar 2015 17:43:51 +0100 Subject: [PATCH 097/218] testing --- src/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.h b/src/main.h index 6712818..8083230 100644 --- a/src/main.h +++ b/src/main.h @@ -41,7 +41,7 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -static const int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; // when total supply == 1 000 000 +static const int64 FIRST_REWARD_DECREASE_AT_COIN = 961741; // when total supply == 1 000 000 static const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" From 6e04769273c3c1f7fe372f2f5e98c16d24b7f473 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Wed, 25 Mar 2015 08:45:15 +0100 Subject: [PATCH 098/218] Testing - lowering diff at moment of switch --- src/main.cpp | 9 ++++++++- src/main.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index a685778..f40c105 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -107,7 +107,7 @@ int isRewardDecreased() { return 1; } else if (blockBeforeFirstDecrease == 0) { blockBeforeFirstDecrease = nBestHeight; -// printf("EAGLE: isRewardDecreased setting blockBeforeFirstDecrease=%d RETURNING 0\n", nBestHeight); + printf("EAGLE: isRewardDecreased setting blockBeforeFirstDecrease=%d RETURNING 0\n", nBestHeight); return 0; } } @@ -1158,6 +1158,13 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); + if (blockBeforeFirstDecrease && pindexLast->nHeight == blockBeforeFirstDecrease) + { + if (fDebug) + printf("EAGLE11: SWITCH! Lowering diff"); + return bnProofOfWorkLimit.GetCompact(); + } + // cruft from alorithm switch time if(pindexLast->nHeight >= 386221 && pindexLast->nHeight <= 386226) return bnProofOfWorkLimit.GetCompact(); diff --git a/src/main.h b/src/main.h index 8083230..25eb48b 100644 --- a/src/main.h +++ b/src/main.h @@ -41,7 +41,7 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -static const int64 FIRST_REWARD_DECREASE_AT_COIN = 961741; // when total supply == 1 000 000 +static const int64 FIRST_REWARD_DECREASE_AT_COIN = 961930; // when total supply == 1 000 000 static const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" From 2a28c23d03d97b7f225b1d5b2c6ebd0c7848ba7d Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Wed, 25 Mar 2015 11:42:42 +0100 Subject: [PATCH 099/218] Few changes for testing --- src/db.cpp | 6 ++++++ src/main.cpp | 8 ++++++-- src/main.h | 10 ++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 0471aca..10814af 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -705,6 +705,12 @@ bool CTxDB::LoadBlockIndex() { // calculate totalCoin for other routines that get called totalCoin = pindex->nMoneySupply / COIN; + if (totalCoin == FIRST_REWARD_DECREASE_AT_COIN) { + blockBeforeFirstDecrease = 999; + if (fDebug) + printf("EAGLE12: Setting blockBeforeFirstDecrease during initial block verification\n"); + } + if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; diff --git a/src/main.cpp b/src/main.cpp index f40c105..658db05 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,6 +88,8 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; +int64 FIRST_REWARD_DECREASE_AT_COIN = 963008; +int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; int isRewardDecreased() { @@ -1158,10 +1160,12 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); - if (blockBeforeFirstDecrease && pindexLast->nHeight == blockBeforeFirstDecrease) + if (fDebug) + printf("EAGLE13: GetNextTargetRequired nHeight==%d\n", pindexLast->nHeight); + if (blockBeforeFirstDecrease && pindexLast->nHeight == blockBeforeFirstDecrease + 1) { if (fDebug) - printf("EAGLE11: SWITCH! Lowering diff"); + printf("*** EAGLE11: SWITCH! Lowering diff nHeight==%d\n", pindexLast->nHeight); return bnProofOfWorkLimit.GetCompact(); } diff --git a/src/main.h b/src/main.h index 25eb48b..aa0b592 100644 --- a/src/main.h +++ b/src/main.h @@ -41,8 +41,12 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -static const int64 FIRST_REWARD_DECREASE_AT_COIN = 961930; // when total supply == 1 000 000 -static const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 +extern int64 FIRST_REWARD_DECREASE_AT_COIN; +extern int64 SECOND_REWARD_DECREASE_AT_COIN; +//extern const int64 FIRST_REWARD_DECREASE_AT_COIN = 961930; // when total supply == 1 000 000 +//extern const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 +//extern const int64 FIRST_REWARD_DECREASE_AT_COIN; // when total supply == 1 000 000 +//extern const int64 SECOND_REWARD_DECREASE_AT_COIN; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" @@ -64,6 +68,8 @@ static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours extern CScript COINBASE_FLAGS; extern int64 totalCoin; +extern int64 blockBeforeFirstDecrease; +extern int64 blocbBeforeSecondDecrease; extern CCriticalSection cs_main; extern std::map mapBlockIndex; extern std::set > setStakeSeen; From 261d56fe33001118a3e0ac48d67a19aa84c82789 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Wed, 25 Mar 2015 18:18:57 +0100 Subject: [PATCH 100/218] - Removing check related to checkpoint server. We do not have it on test network. - Removing two test messages. --- src/main.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 658db05..972704c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1015,14 +1015,12 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) eagledecreased = isRewardDecreased(); if(eagledecreased > 1) { nSubsidy = 4 * CENT; - printf("EAGLE: subsidy SET TO 4 isRewardDecreased=%d\n", eagledecreased); if (fDebug && (eaglesubsidy == 1)) { printf("EAGLE INFO: SECOND REWARD DROP! CHANGING subsidy to 4 CENT\n"); eaglesubsidy = 2; } } else if(eagledecreased > 0) { nSubsidy = 20 * CENT; - printf("EAGLE: subsidy SET TO 20 isRewardDecreased=%d\n", eagledecreased); if (fDebug && !eaglesubsidy) { printf("EAGLE INFO: FIRST REWARD DROP! CHANGING subsidy to 20 CENT\n"); eaglesubsidy = 1; @@ -2451,10 +2449,11 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) } // danbi: Only refuse this block if time distance between the last sync checkpoint // and the block's time is less than the checkpoints max span - if (deltaTime < CHECKPOINT_MAX_SPAN) - return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); - else - return printf("ProcessBlock(CHECKPOINT_MAX_SPAN) : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); +// EAGLE - commenting out for duration of tests +// if (deltaTime < CHECKPOINT_MAX_SPAN) +// return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); +// else +// return printf("ProcessBlock(CHECKPOINT_MAX_SPAN) : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); } } From 32d9c879c12625b9466c8a777ee90cbe4d41b9bd Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Wed, 25 Mar 2015 18:58:37 +0100 Subject: [PATCH 101/218] Test version 2015032502 - Switch happens after coin 963970 - Setting min age back to 7 days --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 972704c..428cc5a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 963008; +int64 FIRST_REWARD_DECREASE_AT_COIN = 963970; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; @@ -2188,7 +2188,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nStakeTargetSpacing = 2 * 60; // pos block spacing set to 2 minutes after first reward reduction nWorkTargetSpacing = 2 * 60; // pow block spacing set to 2 minutes after first reward reduction nCoinbaseMaturity = 180; // coinbase maturity does not change - nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 after first reward reduction +// nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 after first reward reduction if (fDebug && !eaglespacing) { printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days"); eaglespacing = 1; From 2fc49f77538618cefff3a8178a3e4d4ca7fc51c4 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 26 Mar 2015 11:55:19 +0100 Subject: [PATCH 102/218] Disabling check for 'coinbase output not empty' for testing --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 428cc5a..5af1862 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2233,7 +2233,8 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) if(totalCoin > VALUE_CHANGE) { if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) - return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); +// return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); + printf("EAGLE20 ERROR:: coinbase check is being hit!"); } else { From 080f62d8f525f8c470b3512e0c3384d98d6252b3 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 26 Mar 2015 12:15:56 +0100 Subject: [PATCH 103/218] - Lowering both PoW and PoS diffs for 100 blocks after first trigger - Removing some debug print messages --- src/main.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5af1862..70a60c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1158,13 +1158,24 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); - if (fDebug) - printf("EAGLE13: GetNextTargetRequired nHeight==%d\n", pindexLast->nHeight); - if (blockBeforeFirstDecrease && pindexLast->nHeight == blockBeforeFirstDecrease + 1) - { - if (fDebug) - printf("*** EAGLE11: SWITCH! Lowering diff nHeight==%d\n", pindexLast->nHeight); - return bnProofOfWorkLimit.GetCompact(); +// if (blockBeforeFirstDecrease && pindexLast->nHeight == blockBeforeFirstDecrease + 1) +// { +// if (fDebug) +// printf("*** EAGLE11: SWITCH! Lowering diff nHeight==%d\n", pindexLast->nHeight); +// return bnProofOfWorkLimit.GetCompact(); +// } + // Diff will be lowered for 100 blocks after first trigger. + if (blockBeforeFirstDecrease && pindexLast->nHeight <= blockBeforeFirstDecrease + 100) { + if (fProofOfStake) { + if (fDebug) + printf("EAGLE21: Lowering diff for PoS"); + return bnProofOfStakeLimit.GetCompact(); + } else { + if (fDebug) + printf("EAGLE22: Lowering diff for PoW"); + return bnProofOfWorkLimit.GetCompact(); + } + } // cruft from alorithm switch time @@ -1770,8 +1781,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if ((totalCoin > VALUE_CHANGE && IsProofOfWork()) && (!isRewardDecreased())) { - if (fDebug) - printf("EAGLE6: payment to FOUNDATION ADDRESS\n"); +// if (fDebug) +// printf("EAGLE6: payment to FOUNDATION ADDRESS\n"); CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); CScript scriptPubKey; scriptPubKey.SetDestination(address.Get()); @@ -4157,8 +4168,8 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) } else { - if (fDebug) - printf("EAGLE8: CreateNewBlock - no payment to foundation\n"); +// if (fDebug) +// printf("EAGLE8: CreateNewBlock - no payment to foundation\n"); txNew.vout.resize(1); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; } From 666447b8537bfb32cae8dfbe4075555ec9146d66 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 26 Mar 2015 12:22:30 +0100 Subject: [PATCH 104/218] Test version 2015032601 - switch at 965400 coins - bumping version --- src/main.cpp | 2 +- src/version.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 70a60c6..7649886 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 963970; +int64 FIRST_REWARD_DECREASE_AT_COIN = 965400; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; diff --git a/src/version.h b/src/version.h index 4ef6911..fd75515 100644 --- a/src/version.h +++ b/src/version.h @@ -25,8 +25,8 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60009; -static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60009; +static const int PROTOCOL_VERSION = 60010; +static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60010; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; @@ -48,6 +48,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 5 -#define DISPLAY_VERSION_BUILD 0 +#define DISPLAY_VERSION_BUILD 1 #endif From 76807dc39ec72a07ba309c03c33a934ff522aa60 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 27 Mar 2015 09:16:38 +0100 Subject: [PATCH 105/218] Testing --- src/main.cpp | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7649886..2bb25ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1158,21 +1158,15 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); -// if (blockBeforeFirstDecrease && pindexLast->nHeight == blockBeforeFirstDecrease + 1) -// { -// if (fDebug) -// printf("*** EAGLE11: SWITCH! Lowering diff nHeight==%d\n", pindexLast->nHeight); -// return bnProofOfWorkLimit.GetCompact(); -// } // Diff will be lowered for 100 blocks after first trigger. if (blockBeforeFirstDecrease && pindexLast->nHeight <= blockBeforeFirstDecrease + 100) { if (fProofOfStake) { - if (fDebug) - printf("EAGLE21: Lowering diff for PoS"); +// if (fDebug) +// printf("EAGLE21: Lowering diff for PoS"); return bnProofOfStakeLimit.GetCompact(); } else { - if (fDebug) - printf("EAGLE22: Lowering diff for PoW"); +// if (fDebug) +// printf("EAGLE22: Lowering diff for PoW"); return bnProofOfWorkLimit.GetCompact(); } @@ -1768,10 +1762,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // danbi: update totalCoin as we are one behind here // XXX: this might backfire in case of error... totalCoin = pindex->nMoneySupply / COIN; - if ((totalCoin <= VALUE_CHANGE) || (isRewardDecreased())) + if (totalCoin <= VALUE_CHANGE) { - if (fDebug && isRewardDecreased()) - printf("EAGLE5: isRewardDecreased==TRUE: testing old ValueOut\n"); if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) return error("ConnectBlock() : claiming to have created too much (old)"); } @@ -1779,10 +1771,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) return error("ConnectBlock() : claiming to have created too much (new)"); - if ((totalCoin > VALUE_CHANGE && IsProofOfWork()) && (!isRewardDecreased())) + if (totalCoin > VALUE_CHANGE && IsProofOfWork()) { -// if (fDebug) -// printf("EAGLE6: payment to FOUNDATION ADDRESS\n"); CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); CScript scriptPubKey; scriptPubKey.SetDestination(address.Get()); @@ -2462,7 +2452,8 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // danbi: Only refuse this block if time distance between the last sync checkpoint // and the block's time is less than the checkpoints max span // EAGLE - commenting out for duration of tests -// if (deltaTime < CHECKPOINT_MAX_SPAN) + if (deltaTime < CHECKPOINT_MAX_SPAN) + printf("EAGLE30: CHECKPOINT_MAX_SPAN confition hit"); // return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); // else // return printf("ProcessBlock(CHECKPOINT_MAX_SPAN) : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); @@ -4157,10 +4148,8 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - if ((totalCoin > VALUE_CHANGE) && (!isRewardDecreased())) + if (totalCoin > VALUE_CHANGE) { - if (fDebug) - printf("EAGLE7: CreateNewBlock() - payment to foundation\n"); CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); txNew.vout.resize(2); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; @@ -4168,8 +4157,6 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) } else { -// if (fDebug) -// printf("EAGLE8: CreateNewBlock - no payment to foundation\n"); txNew.vout.resize(1); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; } @@ -4426,11 +4413,8 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfWork()) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); - if ((totalCoin > VALUE_CHANGE) && (!isRewardDecreased())) { - if (fDebug) - printf("EAGLE9: Create new block - payment to foundation\n"); + if (totalCoin > VALUE_CHANGE) pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); - } } // Fill in header @@ -4785,17 +4769,13 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet) // Diamond coin mechanics // Foundation contribution // 0.05 until 1000000 coins generated -// 0 afterwards +// 0.01 afterwards // Changing this requires a fork int64 GetContributionAmount(int64 totalCoin) { if(!isRewardDecreased()) return 0.05 * COIN; else - { - if (fDebug) - printf("EAGLE10: GetContributionAmount - RETURNING 0 since we have passed trigger\n"); - return 0; - } + return 0.01 * COIN; } uint256 CBlock::GetHash(bool existingBlock) const From 029778190df16f323a5f8ed0ad63a0370f884b17 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 27 Mar 2015 09:25:37 +0100 Subject: [PATCH 106/218] Testing --- src/main.cpp | 2 +- src/version.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2bb25ff..262760f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 965400; +int64 FIRST_REWARD_DECREASE_AT_COIN = 967060; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; diff --git a/src/version.h b/src/version.h index fd75515..f3e5f32 100644 --- a/src/version.h +++ b/src/version.h @@ -25,8 +25,8 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60010; -static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60010; +static const int PROTOCOL_VERSION = 60011; +static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60011; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; From 22b5412dcbf66f668159ea3fefb3ab82dfeb54af Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 27 Mar 2015 11:40:38 +0100 Subject: [PATCH 107/218] Fixing the way blockBeforeFirstDecrease is set during reading data from disk --- src/db.cpp | 9 ++++----- src/db.h | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 10814af..af19515 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -705,11 +705,10 @@ bool CTxDB::LoadBlockIndex() { // calculate totalCoin for other routines that get called totalCoin = pindex->nMoneySupply / COIN; - if (totalCoin == FIRST_REWARD_DECREASE_AT_COIN) { - blockBeforeFirstDecrease = 999; - if (fDebug) - printf("EAGLE12: Setting blockBeforeFirstDecrease during initial block verification\n"); - } + if (!isRewardDecreased()) + if (blockBeforeFirstDecrease) + if (fDebug) + printf("EAGLE12: Setting blockBeforeFirstDecrease during initial block verification\n"); if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; diff --git a/src/db.h b/src/db.h index eeb3a0b..c4c8f1b 100644 --- a/src/db.h +++ b/src/db.h @@ -29,6 +29,8 @@ extern unsigned int nWalletDBUpdated; void ThreadFlushWalletDB(void* parg); bool BackupWallet(const CWallet& wallet, const std::string& strDest); +extern int isRewardDecreased(); + class CDBEnv { From 611b47ffe9c5d3edbd65f5dfaf80af5f57560f7a Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 27 Mar 2015 11:41:00 +0100 Subject: [PATCH 108/218] Testing --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 262760f..253096f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,10 +88,11 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 967060; +int64 FIRST_REWARD_DECREASE_AT_COIN = 967310; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; +// Returns 0 if before first trigger, then 1 before 2nd trigger and 2 afterwards int isRewardDecreased() { // should we calculate totalCoin here to be absolutely sure it is up to date? if (totalCoin >= SECOND_REWARD_DECREASE_AT_COIN) { From 30a4aa0ac7f05ca79fd176d580ba8dbffea472ca Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 27 Mar 2015 12:42:16 +0100 Subject: [PATCH 109/218] Added test message --- src/db.cpp | 15 ++++++++++++--- src/main.cpp | 6 ++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index af19515..24c4bb4 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -705,10 +705,19 @@ bool CTxDB::LoadBlockIndex() { // calculate totalCoin for other routines that get called totalCoin = pindex->nMoneySupply / COIN; - if (!isRewardDecreased()) - if (blockBeforeFirstDecrease) + if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { + if (!blockBeforeFirstDecrease) { + blockBeforeFirstDecrease = pindex->nHeight; + } else if (blockBeforeFirstDecrease > pindex->nHeight) { + blockBeforeFirstDecrease = pindex->nHeight; if (fDebug) - printf("EAGLE12: Setting blockBeforeFirstDecrease during initial block verification\n"); + printf("EAGLE12: Setting blockBeforeFirstDecrease=%d during initial block verification\n", blockBeforeFirstDecrease); + } + } +// if (!isRewardDecreased()) +// if (blockBeforeFirstDecrease) +// if (fDebug) +// printf("EAGLE12: Setting blockBeforeFirstDecrease during initial block verification=%d\n", blockBeforeFirstDecrease); if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; diff --git a/src/main.cpp b/src/main.cpp index 253096f..caecba2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,7 @@ static const int64 POW_RESTART = 577850; // When (block) to unstuck PoW int64 totalCoin = -1; int64 nChainStartTime = 1373654826; -int nCoinbaseMaturity = 30; +int nCoinbaseMaturity = 31; CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; CBigNum bnBestChainTrust = 0; @@ -1779,8 +1779,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) scriptPubKey.SetDestination(address.Get()); if (vtx[0].vout[1].scriptPubKey != scriptPubKey) return error("ConnectBlock() : coinbase does not pay to the foundation address)"); - if (vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) + if (vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) { + printf("EAGLE31: contribution=%d", GetContributionAmount(totalCoin)); return error("ConnectBlock() : coinbase does not pay enough to foundation addresss"); + } } // Update block index on disk without changing it in memory. From 273155b6e21ce69e99b6e463319a312d967268d8 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 27 Mar 2015 13:19:34 +0100 Subject: [PATCH 110/218] Testing --- src/db.cpp | 4 ++-- src/main.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 24c4bb4..71be1ac 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -707,9 +707,9 @@ bool CTxDB::LoadBlockIndex() totalCoin = pindex->nMoneySupply / COIN; if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { if (!blockBeforeFirstDecrease) { - blockBeforeFirstDecrease = pindex->nHeight; + blockBeforeFirstDecrease = pindex->nHeight - 1; } else if (blockBeforeFirstDecrease > pindex->nHeight) { - blockBeforeFirstDecrease = pindex->nHeight; + blockBeforeFirstDecrease = pindex->nHeight - 1; if (fDebug) printf("EAGLE12: Setting blockBeforeFirstDecrease=%d during initial block verification\n", blockBeforeFirstDecrease); } diff --git a/src/main.cpp b/src/main.cpp index caecba2..967f81e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1160,6 +1160,8 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS return bnProofOfWorkLimit.GetCompact(); // Diff will be lowered for 100 blocks after first trigger. +// EAGLE - this has to be removed for prod release as this breaks things during reading from disk +// in db.cpp if (blockBeforeFirstDecrease && pindexLast->nHeight <= blockBeforeFirstDecrease + 100) { if (fProofOfStake) { // if (fDebug) From 335f960a1ba68c0c48d76ffea506dde28a257cca Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 27 Mar 2015 14:32:17 +0100 Subject: [PATCH 111/218] Test version 2015032701 --- src/db.cpp | 1 + src/main.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/db.cpp b/src/db.cpp index 71be1ac..064f749 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -707,6 +707,7 @@ bool CTxDB::LoadBlockIndex() totalCoin = pindex->nMoneySupply / COIN; if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { if (!blockBeforeFirstDecrease) { + printf("EAGLE122: Initially setting blockBeforeFirstDecrease=%d during initial block verification\n", blockBeforeFirstDecrease); blockBeforeFirstDecrease = pindex->nHeight - 1; } else if (blockBeforeFirstDecrease > pindex->nHeight) { blockBeforeFirstDecrease = pindex->nHeight - 1; diff --git a/src/main.cpp b/src/main.cpp index 967f81e..c547803 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 967310; +int64 FIRST_REWARD_DECREASE_AT_COIN = 967580; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; From b4ed0fae94d33c20550324f2c4b16685f1c4fba9 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Sun, 29 Mar 2015 12:00:42 +0200 Subject: [PATCH 112/218] Test release 2015032901 --- src/main.cpp | 48 +++++++++--------------------------------------- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c547803..50d1af5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -97,20 +97,16 @@ int isRewardDecreased() { // should we calculate totalCoin here to be absolutely sure it is up to date? if (totalCoin >= SECOND_REWARD_DECREASE_AT_COIN) { if ((blocbBeforeSecondDecrease > 0) && (blocbBeforeSecondDecrease != nBestHeight)) { - printf("EAGLE: isRewardDecreased RETURNING 2\n"); return 2; } else if (blocbBeforeSecondDecrease == 0) { blocbBeforeSecondDecrease = nBestHeight; - printf("EAGLE: isRewardDecreased setting blocbBeforeSecondDecrease=%d RETURNING 0\n", nBestHeight); return 0; } } else if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { if ((blockBeforeFirstDecrease > 0) && (blockBeforeFirstDecrease != nBestHeight)) { -// printf("EAGLE: isRewardDecreased RETURNING 1\n"); return 1; } else if (blockBeforeFirstDecrease == 0) { blockBeforeFirstDecrease = nBestHeight; - printf("EAGLE: isRewardDecreased setting blockBeforeFirstDecrease=%d RETURNING 0\n", nBestHeight); return 0; } } @@ -1159,22 +1155,6 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); - // Diff will be lowered for 100 blocks after first trigger. -// EAGLE - this has to be removed for prod release as this breaks things during reading from disk -// in db.cpp - if (blockBeforeFirstDecrease && pindexLast->nHeight <= blockBeforeFirstDecrease + 100) { - if (fProofOfStake) { -// if (fDebug) -// printf("EAGLE21: Lowering diff for PoS"); - return bnProofOfStakeLimit.GetCompact(); - } else { -// if (fDebug) -// printf("EAGLE22: Lowering diff for PoW"); - return bnProofOfWorkLimit.GetCompact(); - } - - } - // cruft from alorithm switch time if(pindexLast->nHeight >= 386221 && pindexLast->nHeight <= 386226) return bnProofOfWorkLimit.GetCompact(); @@ -1782,7 +1762,6 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (vtx[0].vout[1].scriptPubKey != scriptPubKey) return error("ConnectBlock() : coinbase does not pay to the foundation address)"); if (vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) { - printf("EAGLE31: contribution=%d", GetContributionAmount(totalCoin)); return error("ConnectBlock() : coinbase does not pay enough to foundation addresss"); } } @@ -2191,10 +2170,10 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const { if (isRewardDecreased()) { - nStakeTargetSpacing = 2 * 60; // pos block spacing set to 2 minutes after first reward reduction - nWorkTargetSpacing = 2 * 60; // pow block spacing set to 2 minutes after first reward reduction + nStakeTargetSpacing = 100; // pos block spacing set to 100 seconds after first reward reduction + nWorkTargetSpacing = 100; // pow block spacing set to 100 seconds after first reward reduction nCoinbaseMaturity = 180; // coinbase maturity does not change -// nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 after first reward reduction + nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 after first reward reduction if (fDebug && !eaglespacing) { printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days"); eaglespacing = 1; @@ -2239,8 +2218,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) if(totalCoin > VALUE_CHANGE) { if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) -// return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); - printf("EAGLE20 ERROR:: coinbase check is being hit!"); + return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); } else { @@ -2456,12 +2434,10 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) } // danbi: Only refuse this block if time distance between the last sync checkpoint // and the block's time is less than the checkpoints max span -// EAGLE - commenting out for duration of tests if (deltaTime < CHECKPOINT_MAX_SPAN) - printf("EAGLE30: CHECKPOINT_MAX_SPAN confition hit"); -// return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); -// else -// return printf("ProcessBlock(CHECKPOINT_MAX_SPAN) : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); + return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); + else + return printf("ProcessBlock(CHECKPOINT_MAX_SPAN) : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); } } @@ -3078,15 +3054,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // make sure we have current totalCoin totalCoin = GetTotalCoin(); - if ((fDebug) && (!eagleoldclients)) - if (isRewardDecreased()) { - printf("EAGLE INFO: SWITCH! Beginning to disconnect old clients\n"); - eagleoldclients = true; - } - if (isRewardDecreased() && (pfrom->nVersion) && (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { - printf("(EAGLE1) ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + printf("ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); pfrom->fDisconnect = true; return false; } @@ -3115,7 +3085,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } if (isRewardDecreased() && (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { - printf("(EAGLE2) ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + printf("ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); pfrom->fDisconnect = true; return false; } From b50ce46d2ca2636cdff3d5377863fb7febfde048 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Sun, 29 Mar 2015 12:05:26 +0200 Subject: [PATCH 113/218] Test release 20150329 - setting switch to happen after 971510 coins --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 50d1af5..12e707a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 967580; +int64 FIRST_REWARD_DECREASE_AT_COIN = 971510; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; From 46627e7c0d688af2a1e9a07c09c4d5c9c00948da Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 30 Mar 2015 20:53:54 +0200 Subject: [PATCH 114/218] Testing - setting switch to 1000000 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 12e707a..0d2877e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 971510; +int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; From ba026557f0fc76273c03a8fd6d7559cf27817d32 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Mon, 30 Mar 2015 21:14:07 +0200 Subject: [PATCH 115/218] Testing switch to happen on independent network: port 37771. 45 blocks in the future --- src/main.cpp | 2 +- src/protocol.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 0d2877e..c452e4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; +int64 FIRST_REWARD_DECREASE_AT_COIN = 974125; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; diff --git a/src/protocol.h b/src/protocol.h index 7a75bda..357c298 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -18,7 +18,7 @@ extern bool fTestNet; static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) { - return testnet ? 27771 : 17771; + return testnet ? 27771 : 37771; } From 5b6c6b6f793fcf0325bf5436a6b66be1eab1d003 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Tue, 31 Mar 2015 20:07:03 +0200 Subject: [PATCH 116/218] Test release 20150331 - minAge 2 hours, switch at 976150 coins --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c452e4f..dea6e3d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,7 +88,7 @@ bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 974125; +int64 FIRST_REWARD_DECREASE_AT_COIN = 976150; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; @@ -2173,7 +2173,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nStakeTargetSpacing = 100; // pos block spacing set to 100 seconds after first reward reduction nWorkTargetSpacing = 100; // pow block spacing set to 100 seconds after first reward reduction nCoinbaseMaturity = 180; // coinbase maturity does not change - nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 after first reward reduction + nStakeMinAge = 60 * 60 * 2; // min age is lowered from 7 to 3 after first reward reduction if (fDebug && !eaglespacing) { printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days"); eaglespacing = 1; From 9246b8e789bf5f9be29331cd024b3b3f83018afd Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 11:54:24 +0200 Subject: [PATCH 117/218] Analysing an issue with diff engine --- src/db.cpp | 4 ++-- src/main.cpp | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 064f749..96c5652 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -707,12 +707,12 @@ bool CTxDB::LoadBlockIndex() totalCoin = pindex->nMoneySupply / COIN; if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { if (!blockBeforeFirstDecrease) { - printf("EAGLE122: Initially setting blockBeforeFirstDecrease=%d during initial block verification\n", blockBeforeFirstDecrease); + printf("EAGLE122: Initially setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); blockBeforeFirstDecrease = pindex->nHeight - 1; } else if (blockBeforeFirstDecrease > pindex->nHeight) { blockBeforeFirstDecrease = pindex->nHeight - 1; if (fDebug) - printf("EAGLE12: Setting blockBeforeFirstDecrease=%d during initial block verification\n", blockBeforeFirstDecrease); + printf("EAGLE12: Setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); } } // if (!isRewardDecreased()) diff --git a/src/main.cpp b/src/main.cpp index dea6e3d..6d8a69c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1153,7 +1153,10 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) + { + if (fDebug && GetBoolArg("-printjunk")) printf(">> EAGLE1 PoW returning bnProofOfWorkLimit nHeight = %d\n", pindexLast->nHeight); return bnProofOfWorkLimit.GetCompact(); + } // cruft from alorithm switch time if(pindexLast->nHeight >= 386221 && pindexLast->nHeight <= 386226) @@ -1163,6 +1166,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS return bnProofOfWorkLimit_1.GetCompact(); CBigNum bnTargetLimit = fProofOfStake ? bnProofOfStakeLimit : bnProofOfWorkLimit; +// if (fDebug && GetBoolArg("-printjunk")) printf("EAGLE2: bnTargetLimit = %llu", bnTargetLimit); if (pindexLast == NULL) return bnTargetLimit.GetCompact(); // genesis block @@ -1174,6 +1178,11 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if (pindexPrevPrev->pprev == NULL) return bnTargetLimit.GetCompact(); // second block + if (fDebug && GetBoolArg("-printjunk")) + { + printf("EAGLE3: pindexLast->nHeight=%d, pindexPrev->nHeight=%d, pindexPrevPrev->nHeight=%d", pindexLast->nHeight, pindexPrev->nHeight, pindexPrevPrev->nHeight); + } + // ppcoin: target change every block // ppcoin: retarget with exponential moving toward target spacing CBigNum bnNew; @@ -1181,6 +1190,11 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nWorkTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); int64 nInterval = nTargetTimespan / nTargetSpacing; int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); + if (fDebug && GetBoolArg("-printjunk")) + { + printf("EAGLE4: nTargetSpacing=%"PRI64d", nInterval=%"PRI64d", nActualSpacing=%"PRI64d", nTargetTimespan=%"PRI64d", nStakeTargetSpacing=%"PRI64d"", nTargetSpacing, nInterval, nActualSpacing, nTargetTimespan, nStakeTargetSpacing); + } + // fix block spacing // danbi: post 2.0.4 implement new pacing algorithm for PoW & PoS @@ -1218,7 +1232,14 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS // danbi: make sure we don't emit negative numbers even if we miscalculated if ((bnNew <= 0 && nBestHeight > POW_RESTART) || bnNew > bnTargetLimit) + { + if (fDebug && GetBoolArg("-printjunk")) + { + if (bnNew <= 0) printf("EAGLE98: Correction by danby bnNew <= 0\n"); + else printf("EAGLE99 Correction by danbi bnNew>bnTargetLimit\n"); + } bnNew = bnTargetLimit; + } return bnNew.GetCompact(); } From d3cd66dc62ba35521ab2cb9e449ac9d2e022749d Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 12:02:04 +0200 Subject: [PATCH 118/218] . --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6d8a69c..d5db5ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1180,7 +1180,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if (fDebug && GetBoolArg("-printjunk")) { - printf("EAGLE3: pindexLast->nHeight=%d, pindexPrev->nHeight=%d, pindexPrevPrev->nHeight=%d", pindexLast->nHeight, pindexPrev->nHeight, pindexPrevPrev->nHeight); + printf("EAGLE3: pindexLast->nHeight=%d, pindexPrev->nHeight=%d, pindexPrevPrev->nHeight=%d\n", pindexLast->nHeight, pindexPrev->nHeight, pindexPrevPrev->nHeight); } // ppcoin: target change every block @@ -1192,7 +1192,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); if (fDebug && GetBoolArg("-printjunk")) { - printf("EAGLE4: nTargetSpacing=%"PRI64d", nInterval=%"PRI64d", nActualSpacing=%"PRI64d", nTargetTimespan=%"PRI64d", nStakeTargetSpacing=%"PRI64d"", nTargetSpacing, nInterval, nActualSpacing, nTargetTimespan, nStakeTargetSpacing); + printf("EAGLE4: nTargetSpacing=%"PRI64d", nInterval=%"PRI64d", nActualSpacing=%"PRI64d", nTargetTimespan=%"PRI64d", nStakeTargetSpacing=%"PRI64d"\n", nTargetSpacing, nInterval, nActualSpacing, nTargetTimespan, nStakeTargetSpacing); } From c18ba8c70f4be041698dd12de4aa7a74048a7752 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 12:08:06 +0200 Subject: [PATCH 119/218] . --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index d5db5ab..c9496a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1180,7 +1180,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS if (fDebug && GetBoolArg("-printjunk")) { - printf("EAGLE3: pindexLast->nHeight=%d, pindexPrev->nHeight=%d, pindexPrevPrev->nHeight=%d\n", pindexLast->nHeight, pindexPrev->nHeight, pindexPrevPrev->nHeight); + printf("%s block, EAGLE3: pindexLast->nHeight=%d, pindexPrev->nHeight=%d, pindexPrevPrev->nHeight=%d\n", fProofOfStake ? "PoS" : "PoW", pindexLast->nHeight, pindexPrev->nHeight, pindexPrevPrev->nHeight); } // ppcoin: target change every block From 70ebb7aaf2ba5281edfd750e8a52eb87034c37d7 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 13:04:20 +0200 Subject: [PATCH 120/218] Bugfix - fixing if condition --- src/main.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index c9496a4..f58a5cb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1192,7 +1192,7 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); if (fDebug && GetBoolArg("-printjunk")) { - printf("EAGLE4: nTargetSpacing=%"PRI64d", nInterval=%"PRI64d", nActualSpacing=%"PRI64d", nTargetTimespan=%"PRI64d", nStakeTargetSpacing=%"PRI64d"\n", nTargetSpacing, nInterval, nActualSpacing, nTargetTimespan, nStakeTargetSpacing); + printf("EAGLE4: nTargetSpacing=%"PRI64d", nInterval=%"PRI64d", nActualSpacing=%"PRI64d", nTargetTimespan=%"PRI64d", nStakeTargetSpacing=%"PRI64d", nStakeMinAge=%d\n", nTargetSpacing, nInterval, nActualSpacing, nTargetTimespan, nStakeTargetSpacing, nStakeMinAge); } @@ -2201,8 +2201,11 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) } // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork - } else if(totalCoin > VALUE_CHANGE && !fTestNet) + } + + if ((!isRewardDecreased) && (totalCoin > VALUE_CHANGE && !fTestNet)) { + if (fDebug && GetBoolArg("-printjunk")) printf("EAGLE11: old code - nStakeTargetSpacing = 600"); nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks } From 2ff3563afcdffb868bf3e826141dd4bb7980499d Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 15:58:13 +0200 Subject: [PATCH 121/218] Adding GetNextTargetRequired_v2 which comes from Noblecoin/Magi. --- src/main.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index f58a5cb..f9fcbe1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1150,7 +1150,7 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta return pindex; } -unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) +unsigned int GetNextTargetRequired_v1(const CBlockIndex* pindexLast, bool fProofOfStake) { if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) { @@ -1244,6 +1244,71 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS return bnNew.GetCompact(); } + +unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProofOfStake) +{ + CBigNum bnTargetLimit = bnProofOfWorkLimit; + + if(fProofOfStake) + { + // Proof-of-Stake blocks has own target limit since nVersion=3 supermajority on mainNet and always on testNet + bnTargetLimit = bnProofOfStakeLimit; + } + + if (pindexLast == NULL) + return bnTargetLimit.GetCompact(); // genesis block + + const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); + if (pindexPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // first block + const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); + if (pindexPrevPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // second block + + int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); + if(nActualSpacing < 0) + { + // printf(">> nActualSpacing = %"PRI64d" corrected to 1.\n", nActualSpacing); + nActualSpacing = 1; + } + else if(nActualSpacing > nTargetTimespan) + { + // printf(">> nActualSpacing = %"PRI64d" corrected to nTargetTimespan (900).\n", nActualSpacing); + nActualSpacing = nTargetTimespan; + } + + // ppcoin: target change every block + // ppcoin: retarget with exponential moving toward target spacing + CBigNum bnNew; + bnNew.SetCompact(pindexPrev->nBits); + + int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : nWorkTargetSpacing; + int64 nInterval = nTargetTimespan / nTargetSpacing; + bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); + bnNew /= ((nInterval + 1) * nTargetSpacing); + + /* + printf(">> Height = %d, fProofOfStake = %d, nInterval = %"PRI64d", nTargetSpacing = %"PRI64d", nActualSpacing = %"PRI64d"\n", + pindexPrev->nHeight, fProofOfStake, nInterval, nTargetSpacing, nActualSpacing); + printf(">> pindexPrev->GetBlockTime() = %"PRI64d", pindexPrev->nHeight = %d, pindexPrevPrev->GetBlockTime() = %"PRI64d", pindexPrevPrev->nHeight = %d\n", + pindexPrev->GetBlockTime(), pindexPrev->nHeight, pindexPrevPrev->GetBlockTime(), pindexPrevPrev->nHeight); + */ + + if (bnNew > bnTargetLimit) + bnNew = bnTargetLimit; + + return bnNew.GetCompact(); +} + + +unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) +{ + if (!isRewardDecreased()) + return GetNextTargetRequired_v1(pindexLast, fProofOfStake); + else return GetNextTargetRequired_v2(pindexLast, fProofOfStake); +} + + bool CheckProofOfWork(uint256 hash, unsigned int nBits) { CBigNum bnTarget; From 8cc0473e62c5fbde0b30cc6e90ba12d021acfa4f Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 16:23:45 +0200 Subject: [PATCH 122/218] Missing brackets --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index f9fcbe1..f3e8320 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2268,7 +2268,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) // Changing any of these requires a fork } - if ((!isRewardDecreased) && (totalCoin > VALUE_CHANGE && !fTestNet)) + if ((!isRewardDecreased()) && (totalCoin > VALUE_CHANGE && !fTestNet)) { if (fDebug && GetBoolArg("-printjunk")) printf("EAGLE11: old code - nStakeTargetSpacing = 600"); nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins From a34afecf4c4c1058c3c804ccfa1b79ac2ebe45a5 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 18:08:13 +0200 Subject: [PATCH 123/218] Changing port to 47771 --- src/main.cpp | 2 +- src/protocol.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f3e8320..f61c80d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,7 @@ #include "checkpoints.h" #include "db.h" #include "net.h" -#include "init.h" +#include "init.h" #include "ui_interface.h" #include "kernel.h" #include "scrypt_mine.h" diff --git a/src/protocol.h b/src/protocol.h index 357c298..69d3103 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -18,7 +18,7 @@ extern bool fTestNet; static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) { - return testnet ? 27771 : 37771; + return testnet ? 27771 : 47771; } From f091468e26fd290d04538e8114b9a77585ccb2e2 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Thu, 2 Apr 2015 18:18:30 +0200 Subject: [PATCH 124/218] . --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f61c80d..14cb674 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2261,7 +2261,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nCoinbaseMaturity = 180; // coinbase maturity does not change nStakeMinAge = 60 * 60 * 2; // min age is lowered from 7 to 3 after first reward reduction if (fDebug && !eaglespacing) { - printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days"); + printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days totalCoin=%"PRI64d"\n", totalCoin); eaglespacing = 1; } // Update the coin mechanics variables post algorithm change @@ -2270,7 +2270,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) if ((!isRewardDecreased()) && (totalCoin > VALUE_CHANGE && !fTestNet)) { - if (fDebug && GetBoolArg("-printjunk")) printf("EAGLE11: old code - nStakeTargetSpacing = 600"); + if (fDebug && GetBoolArg("-printjunk")) printf("EAGLE11: old code - nStakeTargetSpacing = 600, totalcoin=%"PRI64d"\n", totalCoin); nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks } From 01a1eb82d75536523ec4a40152d9964efee4a003 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 3 Apr 2015 11:43:18 +0200 Subject: [PATCH 125/218] minor --- src/db.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db.cpp b/src/db.cpp index 96c5652..a4fcdf0 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -707,8 +707,8 @@ bool CTxDB::LoadBlockIndex() totalCoin = pindex->nMoneySupply / COIN; if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { if (!blockBeforeFirstDecrease) { - printf("EAGLE122: Initially setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); blockBeforeFirstDecrease = pindex->nHeight - 1; + printf("EAGLE122: Initially setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); } else if (blockBeforeFirstDecrease > pindex->nHeight) { blockBeforeFirstDecrease = pindex->nHeight - 1; if (fDebug) From ad5c258c6e8b4ba8da6b13d8ebcfc844d2e1a162 Mon Sep 17 00:00:00 2001 From: Eagle Flies Date: Fri, 3 Apr 2015 13:18:15 +0200 Subject: [PATCH 126/218] Prod wallet release version 2.0.5.2 Changing what happens after triggers (1 mil coins and 2,5 mil coins): - PoW reward drops to 0,2 coin after 1 mil coins - PoW reward drops to 0,04 coin after 2,5 mil coins - Foundation share is lowered from 0,05 to 0,01 coin after 1st trigger - PoS block spacing is changed from 600 to 100 seconds (6 times more PoS blocks) - PoW block spacing is changed from 60 to 100 seconds - GetNextTargetRequired is split onto GetNextTargetRequired_v1 which is same code as now and is going to be used up to 1 mil coins, afterwards we are switching to GetNextTargetRequired_v2 which is coming from Noblecoin/Magi - PoS min_age drops from 7 days to 1 day after 1 mil coins - Version is bumped to 2.0.5.2/60012 and all previous versions will be disconnected after 1st trigger --- src/db.cpp | 4 ---- src/main.cpp | 21 ++++----------------- src/protocol.h | 2 +- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 6 +++--- 5 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index a4fcdf0..6c3d2a2 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -715,10 +715,6 @@ bool CTxDB::LoadBlockIndex() printf("EAGLE12: Setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); } } -// if (!isRewardDecreased()) -// if (blockBeforeFirstDecrease) -// if (fDebug) -// printf("EAGLE12: Setting blockBeforeFirstDecrease during initial block verification=%d\n", blockBeforeFirstDecrease); if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; diff --git a/src/main.cpp b/src/main.cpp index 14cb674..8ddbb71 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,7 @@ static const int64 POW_RESTART = 577850; // When (block) to unstuck PoW int64 totalCoin = -1; int64 nChainStartTime = 1373654826; -int nCoinbaseMaturity = 31; +int nCoinbaseMaturity = 30; CBlockIndex* pindexGenesisBlock = NULL; int nBestHeight = -1; CBigNum bnBestChainTrust = 0; @@ -84,15 +84,14 @@ int64 nTransactionFee = MIN_TX_FEE; // Eagle test settings int64 blockBeforeFirstDecrease = 0; int64 blocbBeforeSecondDecrease = 0; -bool eagleoldclients = false; int64 eaglesubsidy = 0; int eagledecreased = 0; int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 976150; +int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; -// Returns 0 if before first trigger, then 1 before 2nd trigger and 2 afterwards +// Returns 0 before first trigger, then 1 before 2nd trigger and 2 afterwards int isRewardDecreased() { // should we calculate totalCoin here to be absolutely sure it is up to date? if (totalCoin >= SECOND_REWARD_DECREASE_AT_COIN) { @@ -1250,10 +1249,7 @@ unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProof CBigNum bnTargetLimit = bnProofOfWorkLimit; if(fProofOfStake) - { - // Proof-of-Stake blocks has own target limit since nVersion=3 supermajority on mainNet and always on testNet bnTargetLimit = bnProofOfStakeLimit; - } if (pindexLast == NULL) return bnTargetLimit.GetCompact(); // genesis block @@ -1268,12 +1264,10 @@ unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProof int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); if(nActualSpacing < 0) { - // printf(">> nActualSpacing = %"PRI64d" corrected to 1.\n", nActualSpacing); nActualSpacing = 1; } else if(nActualSpacing > nTargetTimespan) { - // printf(">> nActualSpacing = %"PRI64d" corrected to nTargetTimespan (900).\n", nActualSpacing); nActualSpacing = nTargetTimespan; } @@ -1287,13 +1281,6 @@ unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProof bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); - /* - printf(">> Height = %d, fProofOfStake = %d, nInterval = %"PRI64d", nTargetSpacing = %"PRI64d", nActualSpacing = %"PRI64d"\n", - pindexPrev->nHeight, fProofOfStake, nInterval, nTargetSpacing, nActualSpacing); - printf(">> pindexPrev->GetBlockTime() = %"PRI64d", pindexPrev->nHeight = %d, pindexPrevPrev->GetBlockTime() = %"PRI64d", pindexPrevPrev->nHeight = %d\n", - pindexPrev->GetBlockTime(), pindexPrev->nHeight, pindexPrevPrev->GetBlockTime(), pindexPrevPrev->nHeight); - */ - if (bnNew > bnTargetLimit) bnNew = bnTargetLimit; @@ -2259,7 +2246,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nStakeTargetSpacing = 100; // pos block spacing set to 100 seconds after first reward reduction nWorkTargetSpacing = 100; // pow block spacing set to 100 seconds after first reward reduction nCoinbaseMaturity = 180; // coinbase maturity does not change - nStakeMinAge = 60 * 60 * 2; // min age is lowered from 7 to 3 after first reward reduction + nStakeMinAge = 60 * 60 * 24; // min age is lowered from 7 to 1 day after first reward reduction if (fDebug && !eaglespacing) { printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days totalCoin=%"PRI64d"\n", totalCoin); eaglespacing = 1; diff --git a/src/protocol.h b/src/protocol.h index 69d3103..7a75bda 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -18,7 +18,7 @@ extern bool fTestNet; static inline unsigned short GetDefaultPort(const bool testnet = fTestNet) { - return testnet ? 27771 : 47771; + return testnet ? 27771 : 17771; } diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 7d9d91e..ccc0537 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.5 + 2.0.5.2 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index f3e5f32..f0b58ca 100644 --- a/src/version.h +++ b/src/version.h @@ -25,8 +25,8 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60011; -static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60011; +static const int PROTOCOL_VERSION = 60012; +static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60012; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; @@ -48,6 +48,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 5 -#define DISPLAY_VERSION_BUILD 1 +#define DISPLAY_VERSION_BUILD 2 #endif From 8cb2b442a9aeb2beea910bf0a90feb43ce8985b3 Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 22:18:34 +0300 Subject: [PATCH 127/218] Implement new coin mechanic Adjust rewards and PoW/PoS pacing after 1000000 DMD are reached. --- src/main.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 96611c9..36962fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -973,12 +973,12 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) else { // Diamond v2 coin mechanics - // 0.10 reward after 1,000,000 created - // 0.02 reward after 2,500,000 created - if(totalCoin > 2500000) - nSubsidy = 2 * CENT; - else if(totalCoin > 1000000) - nSubsidy = 10 * CENT; + // 0.20 reward after 1,000,000 created + // 0.04 reward after 2,500,000 created + if(totalCoin >= 2500000) + nSubsidy = 4 * CENT; + else if(totalCoin >= 1000000) + nSubsidy = 20 * CENT; } return nSubsidy + nFees; } @@ -1106,7 +1106,7 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta return pindex; } -unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) +unsigned int GetNextTargetRequired_v1(const CBlockIndex* pindexLast, bool fProofOfStake) { if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) return bnProofOfWorkLimit.GetCompact(); @@ -1179,6 +1179,58 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS return bnNew.GetCompact(); } +unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProofOfStake) +{ + CBigNum bnTargetLimit = bnProofOfWorkLimit; + + if(fProofOfStake) + bnTargetLimit = bnProofOfStakeLimit; + + if (pindexLast == NULL) + return bnTargetLimit.GetCompact(); // genesis block + + const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); + if (pindexPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // first block + const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); + if (pindexPrevPrev->pprev == NULL) + return bnTargetLimit.GetCompact(); // second block + + int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); + if(nActualSpacing < 0) + { + nActualSpacing = 1; + } + else if(nActualSpacing > nTargetTimespan) + { + nActualSpacing = nTargetTimespan; + } + + // ppcoin: target change every block + // ppcoin: retarget with exponential moving toward target spacing + CBigNum bnNew; + bnNew.SetCompact(pindexPrev->nBits); + + int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : nWorkTargetSpacing; + int64 nInterval = nTargetTimespan / nTargetSpacing; + bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); + bnNew /= ((nInterval + 1) * nTargetSpacing); + + if (bnNew > bnTargetLimit) + bnNew = bnTargetLimit; + + return bnNew.GetCompact(); +} + + +unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) +{ + if (totalCoin < 1000000) + return GetNextTargetRequired_v1(pindexLast, fProofOfStake); + else return GetNextTargetRequired_v2(pindexLast, fProofOfStake); +} + + bool CheckProofOfWork(uint256 hash, unsigned int nBits) { CBigNum bnTarget; @@ -2126,7 +2178,13 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) { // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork - if(totalCoin > VALUE_CHANGE && !fTestNet) + if (totalCoin >= 1000000) { + nStakeTargetSpacing = 100; // pos block spacing set to 100 seconds after first reward reduction + nWorkTargetSpacing = 100; // pow block spacing set to 100 seconds after first reward reduction + nCoinbaseMaturity = 180; // coinbase maturity does not change + nStakeMinAge = 60 * 60 * 24; // min age is lowered from 7 to 1 day after first reward reduction + } + else if(totalCoin > VALUE_CHANGE && !fTestNet) { nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks @@ -3023,6 +3081,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return false; } + if (totalCoin >= 1000000 && (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { + printf("ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + pfrom->fDisconnect = true; + return false; + } + if (pfrom->nVersion == 10300) pfrom->nVersion = 300; if (!vRecv.empty()) From a3b0187bcbbb237f8c42733b3a838d3b57be42a3 Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 22:19:39 +0300 Subject: [PATCH 128/218] Update version to 2.0.5.2 --- src/qt/forms/aboutdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 8a8fd15..ccc0537 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.4.1 + 2.0.5.2 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse From 7f41f6bf1c3dcd08854e37a0a55796eabb9dbb58 Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 22:20:21 +0300 Subject: [PATCH 129/218] Update version to 2.0.5.2 --- src/clientversion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index 4c0a131..0b2aac6 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -8,8 +8,8 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 4 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_REVISION 5 +#define CLIENT_VERSION_BUILD 2 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! From a278520f4a6692dc962ed3fb1c241277a0fc506e Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 22:24:17 +0300 Subject: [PATCH 130/218] Update version to 2.0.5.2 --- src/version.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/version.h b/src/version.h index 84c91eb..f0b58ca 100644 --- a/src/version.h +++ b/src/version.h @@ -25,7 +25,8 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60006; +static const int PROTOCOL_VERSION = 60012; +static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60012; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; @@ -46,7 +47,7 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 -#define DISPLAY_VERSION_REVISION 4 -#define DISPLAY_VERSION_BUILD 1 +#define DISPLAY_VERSION_REVISION 5 +#define DISPLAY_VERSION_BUILD 2 #endif From 7c2f3b327c84b21169057272ce60531353b73f3a Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 23:20:05 +0300 Subject: [PATCH 131/218] Check for bnNew <= 0 in the new difficulty code The new difficulty code was missing the check for bnNew <= 0 that could cause the block chain to stop --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 36962fb..30aab4f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1216,7 +1216,8 @@ unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProof bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); - if (bnNew > bnTargetLimit) + // danbi: make sure we don't emit negative numbers even if we miscalculated + if (bnNew <= 0 || bnNew > bnTargetLimit) bnNew = bnTargetLimit; return bnNew.GetCompact(); From 98f388a3c76f030cf951a22071200b0914278d9d Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 23:23:20 +0300 Subject: [PATCH 132/218] Update version to 2.0.5.3 --- src/qt/forms/aboutdialog.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index ccc0537..a56fc6e 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.5.2 + 2.0.5.3 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse From 18957680e59e586a5ddbd6b8b69064cc283e4bed Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 23:23:53 +0300 Subject: [PATCH 133/218] Update version to 2.0.5.3 --- src/clientversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clientversion.h b/src/clientversion.h index 0b2aac6..8d0b95a 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 5 -#define CLIENT_VERSION_BUILD 2 +#define CLIENT_VERSION_BUILD 3 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! From a18470d13d3633d4f2c2f9b97a121716f592febe Mon Sep 17 00:00:00 2001 From: danbi Date: Mon, 6 Apr 2015 23:24:23 +0300 Subject: [PATCH 134/218] Update version to 2.0.5.3 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index f0b58ca..deb341d 100644 --- a/src/version.h +++ b/src/version.h @@ -48,6 +48,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 5 -#define DISPLAY_VERSION_BUILD 2 +#define DISPLAY_VERSION_BUILD 3 #endif From 206028f9385f7f680a4866daf18a9d864c1fda35 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 7 Apr 2015 11:03:30 +0300 Subject: [PATCH 135/218] Implement change of Foundation address every 500000 coin to avoid bloat --- src/main.cpp | 23 +++++++++++++++++++++-- src/main.h | 2 -- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 30aab4f..1609afa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1765,7 +1765,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if(totalCoin > VALUE_CHANGE && IsProofOfWork()) { - CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); + CBitcoinAddress address = GetFoundationAddress(totalCoin); CScript scriptPubKey; scriptPubKey.SetDestination(address.Get()); if (vtx[0].vout[1].scriptPubKey != scriptPubKey) @@ -4123,7 +4123,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) txNew.vin[0].prevout.SetNull(); if(totalCoin > VALUE_CHANGE) { - CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); + CBitcoinAddress address = GetFoundationAddress(totalCoin); txNew.vout.resize(2); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; txNew.vout[1].scriptPubKey.SetDestination(address.Get()); @@ -4751,6 +4751,25 @@ int64 GetContributionAmount(int64 totalCoin) { return 0.01 * COIN; } +// Return Foundation to send contributions to +// address changes every 500000 coin in order to keep it small +// +CBitcoinAddress GetFoundationAddress(int64 totalCoin) { + if (fTestNet) + return address("mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA"); // test Foundation address + + if (totalCoin < 1000000) + return address("dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz"); + else if (totalCoin < 1500000) + return address("dTZMqKTYGUwF3aLFx31anxsNKrtaWn6U3x"); + else if (totalCoin < 2000000) + return address("dPbhK6rPtaBeGepU1nqghZRy4NWot5T7dG"); + else if (totalCoin < 2500000) + return address("dbXsr1iVzF6KDRxDspAbvtCpdscF28bD8J"); + else + return address ("dSDEptc8gJzbEe3Kfta8McvnBmapk6fcrR"); +} + uint256 CBlock::GetHash(bool existingBlock) const { // There are two distinct cases when we are called diff --git a/src/main.h b/src/main.h index 4f1dd61..62a8e4a 100644 --- a/src/main.h +++ b/src/main.h @@ -41,8 +41,6 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -#define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" -#define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. From 47788d8d272613c77e13720e49879a404810a243 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 8 Apr 2015 11:10:27 +0300 Subject: [PATCH 136/218] Change PoS minimum time to 3 days --- src/main.cpp | 21 +++++++++++---------- src/main.h | 2 ++ src/obj-test/.gitignore | 2 -- 3 files changed, 13 insertions(+), 12 deletions(-) delete mode 100644 src/obj-test/.gitignore diff --git a/src/main.cpp b/src/main.cpp index 1609afa..e19ab01 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2180,10 +2180,11 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork if (totalCoin >= 1000000) { - nStakeTargetSpacing = 100; // pos block spacing set to 100 seconds after first reward reduction - nWorkTargetSpacing = 100; // pow block spacing set to 100 seconds after first reward reduction - nCoinbaseMaturity = 180; // coinbase maturity does not change - nStakeMinAge = 60 * 60 * 24; // min age is lowered from 7 to 1 day after first reward reduction + // after first reward reduction + nStakeTargetSpacing = 100; // PoS block spacing set to 100 seconds + nWorkTargetSpacing = 100; // PoW block spacing set to 100 seconds + nCoinbaseMaturity = 180; // coinbase maturity does not change + nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 days } else if(totalCoin > VALUE_CHANGE && !fTestNet) { @@ -4756,18 +4757,18 @@ int64 GetContributionAmount(int64 totalCoin) { // CBitcoinAddress GetFoundationAddress(int64 totalCoin) { if (fTestNet) - return address("mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA"); // test Foundation address + return CBitcoinAddress("mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA"); // test Foundation address if (totalCoin < 1000000) - return address("dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz"); + return CBitcoinAddress("dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz"); else if (totalCoin < 1500000) - return address("dTZMqKTYGUwF3aLFx31anxsNKrtaWn6U3x"); + return CBitcoinAddress("dTZMqKTYGUwF3aLFx31anxsNKrtaWn6U3x"); else if (totalCoin < 2000000) - return address("dPbhK6rPtaBeGepU1nqghZRy4NWot5T7dG"); + return CBitcoinAddress("dPbhK6rPtaBeGepU1nqghZRy4NWot5T7dG"); else if (totalCoin < 2500000) - return address("dbXsr1iVzF6KDRxDspAbvtCpdscF28bD8J"); + return CBitcoinAddress("dbXsr1iVzF6KDRxDspAbvtCpdscF28bD8J"); else - return address ("dSDEptc8gJzbEe3Kfta8McvnBmapk6fcrR"); + return CBitcoinAddress ("dSDEptc8gJzbEe3Kfta8McvnBmapk6fcrR"); } uint256 CBlock::GetHash(bool existingBlock) const diff --git a/src/main.h b/src/main.h index 62a8e4a..536f7e0 100644 --- a/src/main.h +++ b/src/main.h @@ -13,6 +13,7 @@ #include "bitcoinrpc.h" #include #include "hash.h" +#include "base58.h" class CWallet; class CBlock; @@ -99,6 +100,7 @@ class CTxDB; class CTxIndex; int64 GetContributionAmount(int64 totalCoin); +CBitcoinAddress GetFoundationAddress(int64 totalCoin); void RegisterWallet(CWallet* pwalletIn); void UnregisterWallet(CWallet* pwalletIn); void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false, bool fConnect = true); diff --git a/src/obj-test/.gitignore b/src/obj-test/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/src/obj-test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore From 771ffed4c69aecd8e22f45a43ca1446374eed0d2 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 8 Apr 2015 11:18:33 +0300 Subject: [PATCH 137/218] Update version to 2.0.5.5 --- src/clientversion.h | 2 +- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/clientversion.h b/src/clientversion.h index 8d0b95a..a08f3c4 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 5 -#define CLIENT_VERSION_BUILD 3 +#define CLIENT_VERSION_BUILD 5 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index a56fc6e..86f6336 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.5.3 + 2.0.5.5 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index deb341d..47e125d 100644 --- a/src/version.h +++ b/src/version.h @@ -48,6 +48,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 5 -#define DISPLAY_VERSION_BUILD 3 +#define DISPLAY_VERSION_BUILD 5 #endif From f918e19c751a7b2b2cf81a948fe67e5d92d7e0c1 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 8 Apr 2015 11:33:52 +0300 Subject: [PATCH 138/218] Fix comments and whitespace --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e19ab01..e6a07d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4752,8 +4752,8 @@ int64 GetContributionAmount(int64 totalCoin) { return 0.01 * COIN; } -// Return Foundation to send contributions to -// address changes every 500000 coin in order to keep it small +// Return Foundation Address to send contributions to +// address changes every 500000 coin in order to reduce wallet bloat // CBitcoinAddress GetFoundationAddress(int64 totalCoin) { if (fTestNet) From b19301b46ff6b885309ee1f5232078162de34d90 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Wed, 8 Apr 2015 12:16:07 +0300 Subject: [PATCH 139/218] Update copyrights --- COPYING | 2 +- doc/README | 8 ++------ doc/README_windows.txt | 8 ++------ src/main.cpp | 30 +++++++++++++++--------------- src/qt/forms/aboutdialog.ui | 2 +- src/qt/res/bitcoin-qt.rc | 2 +- 6 files changed, 22 insertions(+), 30 deletions(-) diff --git a/COPYING b/COPYING index 506dbfa..0f96bda 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2014 Diamond Foundation +Copyright (c) 2013-2015 Diamond Foundation Copyright (c) 2011-2012 PPCoin Developers Copyright (c) 2009-2012 Bitcoin Developers diff --git a/doc/README b/doc/README index 4dc6524..8b46b43 100644 --- a/doc/README +++ b/doc/README @@ -1,10 +1,6 @@ +Diamond 2.0.5.5 -Copyright (c) 2013-2014 Diamond Foundation - - -Diamond 2.0.3 - -Copyright (c) 2013-2014 Diamond Foundation +Copyright (c) 2013-2015 Diamond Foundation Copyright (c) 2013 NovaCoin Developers Copyright (c) 2011-2012 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 9b74594..a8788d5 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,10 +1,6 @@ +Diamond 2.0.5.5 -Copyright (c) 2013-2014 Diamond Foundation - - -Diamond 2.0.3 - -Copyright (c) 2013-2014 Diamond Foundation +Copyright (c) 2013-2015 Diamond Foundation Copyright (c) 2013 NovaCoin Developers Copyright (c) 2011-2012 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying diff --git a/src/main.cpp b/src/main.cpp index e6a07d4..27e8a2a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -471,7 +471,7 @@ bool CTransaction::CheckTransaction() const if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake()) return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); - if(totalCoin <= VALUE_CHANGE || totalCoin > POS_RESTART) + if (totalCoin <= VALUE_CHANGE || totalCoin > POS_RESTART) { // ppcoin: enforce minimum output amount if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT) @@ -949,7 +949,7 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) { int64 nSubsidy = COIN; - if(totalCoin <= VALUE_CHANGE) + if (totalCoin <= VALUE_CHANGE) { std::string cseed_str = prevHash.ToString().substr(6,7); const char* cseed = cseed_str.c_str(); @@ -975,9 +975,9 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) // Diamond v2 coin mechanics // 0.20 reward after 1,000,000 created // 0.04 reward after 2,500,000 created - if(totalCoin >= 2500000) + if (totalCoin >= 2500000) nSubsidy = 4 * CENT; - else if(totalCoin >= 1000000) + else if (totalCoin >= 1000000) nSubsidy = 20 * CENT; } return nSubsidy + nFees; @@ -989,7 +989,7 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi { int64 nRewardCoinYear; int64 nSubsidy = 0; - if(totalCoin > VALUE_CHANGE || fTestNet) + if (totalCoin > VALUE_CHANGE || fTestNet) { nRewardCoinYear = MAX_MINT_PROOF_OF_STAKE; if(fTestNet) @@ -1754,7 +1754,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // danbi: update totalCoin as we are one behind here // XXX: this might backfire in case of error... totalCoin = pindex->nMoneySupply / COIN; - if(totalCoin <= VALUE_CHANGE) + if (totalCoin <= VALUE_CHANGE) { if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) return error("ConnectBlock() : claiming to have created too much (old)"); @@ -1763,7 +1763,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) return error("ConnectBlock() : claiming to have created too much (new)"); - if(totalCoin > VALUE_CHANGE && IsProofOfWork()) + if (totalCoin > VALUE_CHANGE && IsProofOfWork()) { CBitcoinAddress address = GetFoundationAddress(totalCoin); CScript scriptPubKey; @@ -2186,7 +2186,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nCoinbaseMaturity = 180; // coinbase maturity does not change nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 days } - else if(totalCoin > VALUE_CHANGE && !fTestNet) + else if (totalCoin > VALUE_CHANGE && !fTestNet) { nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks @@ -2221,7 +2221,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) return DoS(100, error("CheckBlock() : coinstake in wrong position")); // ppcoin: coinbase output should be empty if proof-of-stake block - if(totalCoin > VALUE_CHANGE) + if (totalCoin > VALUE_CHANGE) { if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); @@ -4122,7 +4122,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - if(totalCoin > VALUE_CHANGE) + if (totalCoin > VALUE_CHANGE) { CBitcoinAddress address = GetFoundationAddress(totalCoin); txNew.vout.resize(2); @@ -4179,7 +4179,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp pblock->vtx[0].vout[0].SetEmpty(); - if(totalCoin > VALUE_CHANGE) + if (totalCoin > VALUE_CHANGE) pblock->vtx[0].vout[1].SetEmpty(); pblock->vtx[0].nTime = txCoinStake.nTime; pblock->vtx.push_back(txCoinStake); @@ -4387,7 +4387,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfWork()) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); - if(totalCoin > VALUE_CHANGE) + if (totalCoin > VALUE_CHANGE) pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); } @@ -4484,7 +4484,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) pblock->print(); if (pblock->IsProofOfWork()) { - if(totalCoin > VALUE_CHANGE) + if (totalCoin > VALUE_CHANGE) printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue + pblock->vtx[0].vout[1].nValue).c_str()); else printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); @@ -4746,7 +4746,7 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet) // 0.01 afterwards // Changing this requires a fork int64 GetContributionAmount(int64 totalCoin) { - if(totalCoin < 1000000) + if (totalCoin < 1000000) return 0.05 * COIN; else return 0.01 * COIN; @@ -4807,7 +4807,7 @@ uint256 CBlock::GetHash(bool existingBlock) const } // new block or not found in blockchain - if(totalCoin <= VALUE_CHANGE) + if (totalCoin <= VALUE_CHANGE) { uint256 hash_scrypt = GetHashScrypt(); if (hash_scrypt == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) { diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 86f6336..eb5c70e 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -94,7 +94,7 @@ Copyright © 2009-2014 Bitcoin Developers Copyright © 2012-2014 PPCoin Developers -Copyright © 2014 Diamond Foundation +Copyright © 2013-2015 Diamond Foundation diff --git a/src/qt/res/bitcoin-qt.rc b/src/qt/res/bitcoin-qt.rc index b0ea7a9..26d5d1c 100644 --- a/src/qt/res/bitcoin-qt.rc +++ b/src/qt/res/bitcoin-qt.rc @@ -22,7 +22,7 @@ BEGIN VALUE "FileDescription", "Diamond-Qt (OSS GUI client for Diamond)" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "Diamond-qt" - VALUE "LegalCopyright", "2009-2014 The Bitcoin developers, 2012-2014 The Diamond & PPCoin developers" + VALUE "LegalCopyright", "2009-2014 The Bitcoin developers, 2012-2013 PPCoin developers, 2013-2015 Diamond Foundation" VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php." VALUE "OriginalFilename", "Diamond-qt.exe" VALUE "ProductName", "Diamond-Qt" From 4c2e3cc0d48be1a4a9e3964c7c556a487c2c8a63 Mon Sep 17 00:00:00 2001 From: Robert Zimmerman Date: Wed, 8 Apr 2015 02:37:59 -0700 Subject: [PATCH 140/218] Rebasing db.h,db.cpp,main.h to danbi/Diamond --- src/db.cpp | 11 ----------- src/db.h | 2 -- src/main.h | 8 -------- 3 files changed, 21 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 6c3d2a2..0471aca 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -705,17 +705,6 @@ bool CTxDB::LoadBlockIndex() { // calculate totalCoin for other routines that get called totalCoin = pindex->nMoneySupply / COIN; - if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { - if (!blockBeforeFirstDecrease) { - blockBeforeFirstDecrease = pindex->nHeight - 1; - printf("EAGLE122: Initially setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); - } else if (blockBeforeFirstDecrease > pindex->nHeight) { - blockBeforeFirstDecrease = pindex->nHeight - 1; - if (fDebug) - printf("EAGLE12: Setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); - } - } - if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; diff --git a/src/db.h b/src/db.h index c4c8f1b..eeb3a0b 100644 --- a/src/db.h +++ b/src/db.h @@ -29,8 +29,6 @@ extern unsigned int nWalletDBUpdated; void ThreadFlushWalletDB(void* parg); bool BackupWallet(const CWallet& wallet, const std::string& strDest); -extern int isRewardDecreased(); - class CDBEnv { diff --git a/src/main.h b/src/main.h index f57fe79..536f7e0 100644 --- a/src/main.h +++ b/src/main.h @@ -42,12 +42,6 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -extern int64 FIRST_REWARD_DECREASE_AT_COIN; -extern int64 SECOND_REWARD_DECREASE_AT_COIN; -//extern const int64 FIRST_REWARD_DECREASE_AT_COIN = 961930; // when total supply == 1 000 000 -//extern const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 -//extern const int64 FIRST_REWARD_DECREASE_AT_COIN; // when total supply == 1 000 000 -//extern const int64 SECOND_REWARD_DECREASE_AT_COIN; // when total supply == 2 500 000 inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. @@ -67,8 +61,6 @@ static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours extern CScript COINBASE_FLAGS; extern int64 totalCoin; -extern int64 blockBeforeFirstDecrease; -extern int64 blocbBeforeSecondDecrease; extern CCriticalSection cs_main; extern std::map mapBlockIndex; extern std::set > setStakeSeen; From 85ba455a2b86e17df15f75b32800713cbb40f1a2 Mon Sep 17 00:00:00 2001 From: danbi Date: Wed, 8 Apr 2015 14:10:57 +0300 Subject: [PATCH 141/218] Revert "Prod version 2.0.5.2" --- src/db.cpp | 11 --- src/db.h | 2 - src/main.cpp | 173 ++++-------------------------------- src/main.h | 8 -- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 7 +- 6 files changed, 19 insertions(+), 184 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 6c3d2a2..0471aca 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -705,17 +705,6 @@ bool CTxDB::LoadBlockIndex() { // calculate totalCoin for other routines that get called totalCoin = pindex->nMoneySupply / COIN; - if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { - if (!blockBeforeFirstDecrease) { - blockBeforeFirstDecrease = pindex->nHeight - 1; - printf("EAGLE122: Initially setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); - } else if (blockBeforeFirstDecrease > pindex->nHeight) { - blockBeforeFirstDecrease = pindex->nHeight - 1; - if (fDebug) - printf("EAGLE12: Setting blockBeforeFirstDecrease=%"PRI64d" during initial block verification\n", blockBeforeFirstDecrease); - } - } - if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; diff --git a/src/db.h b/src/db.h index c4c8f1b..eeb3a0b 100644 --- a/src/db.h +++ b/src/db.h @@ -29,8 +29,6 @@ extern unsigned int nWalletDBUpdated; void ThreadFlushWalletDB(void* parg); bool BackupWallet(const CWallet& wallet, const std::string& strDest); -extern int isRewardDecreased(); - class CDBEnv { diff --git a/src/main.cpp b/src/main.cpp index 8ddbb71..96611c9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,7 @@ #include "checkpoints.h" #include "db.h" #include "net.h" -#include "init.h" +#include "init.h" #include "ui_interface.h" #include "kernel.h" #include "scrypt_mine.h" @@ -81,39 +81,6 @@ int64 nHPSTimerStart; // Settings int64 nTransactionFee = MIN_TX_FEE; -// Eagle test settings -int64 blockBeforeFirstDecrease = 0; -int64 blocbBeforeSecondDecrease = 0; -int64 eaglesubsidy = 0; -int eagledecreased = 0; -int eaglespacing = 0; -int64 FIRST_REWARD_DECREASE_AT_COIN = 1000000; -int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; - - -// Returns 0 before first trigger, then 1 before 2nd trigger and 2 afterwards -int isRewardDecreased() { -// should we calculate totalCoin here to be absolutely sure it is up to date? - if (totalCoin >= SECOND_REWARD_DECREASE_AT_COIN) { - if ((blocbBeforeSecondDecrease > 0) && (blocbBeforeSecondDecrease != nBestHeight)) { - return 2; - } else if (blocbBeforeSecondDecrease == 0) { - blocbBeforeSecondDecrease = nBestHeight; - return 0; - } - } else if (totalCoin >= FIRST_REWARD_DECREASE_AT_COIN) { - if ((blockBeforeFirstDecrease > 0) && (blockBeforeFirstDecrease != nBestHeight)) { - return 1; - } else if (blockBeforeFirstDecrease == 0) { - blockBeforeFirstDecrease = nBestHeight; - return 0; - } - } - - return 0; -} - - ////////////////////////////////////////////////////////////////////////////// // @@ -1006,22 +973,12 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) else { // Diamond v2 coin mechanics - // 0.20 reward after 1,000,000 created - // 0.04 reward after 2,500,000 created - eagledecreased = isRewardDecreased(); - if(eagledecreased > 1) { - nSubsidy = 4 * CENT; - if (fDebug && (eaglesubsidy == 1)) { - printf("EAGLE INFO: SECOND REWARD DROP! CHANGING subsidy to 4 CENT\n"); - eaglesubsidy = 2; - } - } else if(eagledecreased > 0) { - nSubsidy = 20 * CENT; - if (fDebug && !eaglesubsidy) { - printf("EAGLE INFO: FIRST REWARD DROP! CHANGING subsidy to 20 CENT\n"); - eaglesubsidy = 1; - } - } + // 0.10 reward after 1,000,000 created + // 0.02 reward after 2,500,000 created + if(totalCoin > 2500000) + nSubsidy = 2 * CENT; + else if(totalCoin > 1000000) + nSubsidy = 10 * CENT; } return nSubsidy + nFees; } @@ -1149,13 +1106,10 @@ const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfSta return pindex; } -unsigned int GetNextTargetRequired_v1(const CBlockIndex* pindexLast, bool fProofOfStake) +unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { if(fTestNet && !fProofOfStake && pindexLast->nHeight <= 100) - { - if (fDebug && GetBoolArg("-printjunk")) printf(">> EAGLE1 PoW returning bnProofOfWorkLimit nHeight = %d\n", pindexLast->nHeight); return bnProofOfWorkLimit.GetCompact(); - } // cruft from alorithm switch time if(pindexLast->nHeight >= 386221 && pindexLast->nHeight <= 386226) @@ -1165,7 +1119,6 @@ unsigned int GetNextTargetRequired_v1(const CBlockIndex* pindexLast, bool fProof return bnProofOfWorkLimit_1.GetCompact(); CBigNum bnTargetLimit = fProofOfStake ? bnProofOfStakeLimit : bnProofOfWorkLimit; -// if (fDebug && GetBoolArg("-printjunk")) printf("EAGLE2: bnTargetLimit = %llu", bnTargetLimit); if (pindexLast == NULL) return bnTargetLimit.GetCompact(); // genesis block @@ -1177,11 +1130,6 @@ unsigned int GetNextTargetRequired_v1(const CBlockIndex* pindexLast, bool fProof if (pindexPrevPrev->pprev == NULL) return bnTargetLimit.GetCompact(); // second block - if (fDebug && GetBoolArg("-printjunk")) - { - printf("%s block, EAGLE3: pindexLast->nHeight=%d, pindexPrev->nHeight=%d, pindexPrevPrev->nHeight=%d\n", fProofOfStake ? "PoS" : "PoW", pindexLast->nHeight, pindexPrev->nHeight, pindexPrevPrev->nHeight); - } - // ppcoin: target change every block // ppcoin: retarget with exponential moving toward target spacing CBigNum bnNew; @@ -1189,11 +1137,6 @@ unsigned int GetNextTargetRequired_v1(const CBlockIndex* pindexLast, bool fProof int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : min(nTargetSpacingWorkMax, (int64) nWorkTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); int64 nInterval = nTargetTimespan / nTargetSpacing; int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); - if (fDebug && GetBoolArg("-printjunk")) - { - printf("EAGLE4: nTargetSpacing=%"PRI64d", nInterval=%"PRI64d", nActualSpacing=%"PRI64d", nTargetTimespan=%"PRI64d", nStakeTargetSpacing=%"PRI64d", nStakeMinAge=%d\n", nTargetSpacing, nInterval, nActualSpacing, nTargetTimespan, nStakeTargetSpacing, nStakeMinAge); - } - // fix block spacing // danbi: post 2.0.4 implement new pacing algorithm for PoW & PoS @@ -1231,71 +1174,11 @@ unsigned int GetNextTargetRequired_v1(const CBlockIndex* pindexLast, bool fProof // danbi: make sure we don't emit negative numbers even if we miscalculated if ((bnNew <= 0 && nBestHeight > POW_RESTART) || bnNew > bnTargetLimit) - { - if (fDebug && GetBoolArg("-printjunk")) - { - if (bnNew <= 0) printf("EAGLE98: Correction by danby bnNew <= 0\n"); - else printf("EAGLE99 Correction by danbi bnNew>bnTargetLimit\n"); - } - bnNew = bnTargetLimit; - } - - return bnNew.GetCompact(); -} - - -unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProofOfStake) -{ - CBigNum bnTargetLimit = bnProofOfWorkLimit; - - if(fProofOfStake) - bnTargetLimit = bnProofOfStakeLimit; - - if (pindexLast == NULL) - return bnTargetLimit.GetCompact(); // genesis block - - const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); - if (pindexPrev->pprev == NULL) - return bnTargetLimit.GetCompact(); // first block - const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); - if (pindexPrevPrev->pprev == NULL) - return bnTargetLimit.GetCompact(); // second block - - int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); - if(nActualSpacing < 0) - { - nActualSpacing = 1; - } - else if(nActualSpacing > nTargetTimespan) - { - nActualSpacing = nTargetTimespan; - } - - // ppcoin: target change every block - // ppcoin: retarget with exponential moving toward target spacing - CBigNum bnNew; - bnNew.SetCompact(pindexPrev->nBits); - - int64 nTargetSpacing = fProofOfStake? nStakeTargetSpacing : nWorkTargetSpacing; - int64 nInterval = nTargetTimespan / nTargetSpacing; - bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); - bnNew /= ((nInterval + 1) * nTargetSpacing); - - if (bnNew > bnTargetLimit) bnNew = bnTargetLimit; return bnNew.GetCompact(); } - -unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) -{ - if (!isRewardDecreased()) - return GetNextTargetRequired_v1(pindexLast, fProofOfStake); - else return GetNextTargetRequired_v2(pindexLast, fProofOfStake); -} - - bool CheckProofOfWork(uint256 hash, unsigned int nBits) { CBigNum bnTarget; @@ -1818,7 +1701,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // danbi: update totalCoin as we are one behind here // XXX: this might backfire in case of error... totalCoin = pindex->nMoneySupply / COIN; - if (totalCoin <= VALUE_CHANGE) + if(totalCoin <= VALUE_CHANGE) { if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) return error("ConnectBlock() : claiming to have created too much (old)"); @@ -1827,16 +1710,15 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) return error("ConnectBlock() : claiming to have created too much (new)"); - if (totalCoin > VALUE_CHANGE && IsProofOfWork()) + if(totalCoin > VALUE_CHANGE && IsProofOfWork()) { CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); CScript scriptPubKey; scriptPubKey.SetDestination(address.Get()); if (vtx[0].vout[1].scriptPubKey != scriptPubKey) return error("ConnectBlock() : coinbase does not pay to the foundation address)"); - if (vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) { + if (vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) return error("ConnectBlock() : coinbase does not pay enough to foundation addresss"); - } } // Update block index on disk without changing it in memory. @@ -2242,22 +2124,10 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const { - if (isRewardDecreased()) { - nStakeTargetSpacing = 100; // pos block spacing set to 100 seconds after first reward reduction - nWorkTargetSpacing = 100; // pow block spacing set to 100 seconds after first reward reduction - nCoinbaseMaturity = 180; // coinbase maturity does not change - nStakeMinAge = 60 * 60 * 24; // min age is lowered from 7 to 1 day after first reward reduction - if (fDebug && !eaglespacing) { - printf("EAGLE (checkblock): setting spacing for both PoW/PoS to 120/120 and lowering coin age to 3 days totalCoin=%"PRI64d"\n", totalCoin); - eaglespacing = 1; - } // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork - } - - if ((!isRewardDecreased()) && (totalCoin > VALUE_CHANGE && !fTestNet)) + if(totalCoin > VALUE_CHANGE && !fTestNet) { - if (fDebug && GetBoolArg("-printjunk")) printf("EAGLE11: old code - nStakeTargetSpacing = 600, totalcoin=%"PRI64d"\n", totalCoin); nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks } @@ -3130,13 +3000,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // make sure we have current totalCoin totalCoin = GetTotalCoin(); - if (isRewardDecreased() && (pfrom->nVersion) && - (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { - printf("ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); - pfrom->fDisconnect = true; - return false; - } - if (strCommand == "version") { // Each connection can only send one version message @@ -3160,12 +3023,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return false; } - if (isRewardDecreased() && (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { - printf("ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); - pfrom->fDisconnect = true; - return false; - } - if (pfrom->nVersion == 10300) pfrom->nVersion = 300; if (!vRecv.empty()) @@ -4199,7 +4056,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - if (totalCoin > VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) { CBitcoinAddress address(!fTestNet ? FOUNDATION_ADDRESS : FOUNDATION_ADDRESS_TEST); txNew.vout.resize(2); @@ -4464,7 +4321,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfWork()) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); - if (totalCoin > VALUE_CHANGE) + if(totalCoin > VALUE_CHANGE) pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); } @@ -4823,7 +4680,7 @@ void GenerateBitcoins(bool fGenerate, CWallet* pwallet) // 0.01 afterwards // Changing this requires a fork int64 GetContributionAmount(int64 totalCoin) { - if(!isRewardDecreased()) + if(totalCoin < 1000000) return 0.05 * COIN; else return 0.01 * COIN; diff --git a/src/main.h b/src/main.h index aa0b592..4f1dd61 100644 --- a/src/main.h +++ b/src/main.h @@ -41,12 +41,6 @@ static const int64 MAX_MINT_PROOF_OF_STAKE = 1 * CENT; static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS -extern int64 FIRST_REWARD_DECREASE_AT_COIN; -extern int64 SECOND_REWARD_DECREASE_AT_COIN; -//extern const int64 FIRST_REWARD_DECREASE_AT_COIN = 961930; // when total supply == 1 000 000 -//extern const int64 SECOND_REWARD_DECREASE_AT_COIN = 2500000; // when total supply == 2 500 000 -//extern const int64 FIRST_REWARD_DECREASE_AT_COIN; // when total supply == 1 000 000 -//extern const int64 SECOND_REWARD_DECREASE_AT_COIN; // when total supply == 2 500 000 #define FOUNDATION_ADDRESS "dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz" #define FOUNDATION_ADDRESS_TEST "mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA" @@ -68,8 +62,6 @@ static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours extern CScript COINBASE_FLAGS; extern int64 totalCoin; -extern int64 blockBeforeFirstDecrease; -extern int64 blocbBeforeSecondDecrease; extern CCriticalSection cs_main; extern std::map mapBlockIndex; extern std::set > setStakeSeen; diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index ccc0537..8a8fd15 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.5.2 + 2.0.4.1 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index f0b58ca..84c91eb 100644 --- a/src/version.h +++ b/src/version.h @@ -25,8 +25,7 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60012; -static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60012; +static const int PROTOCOL_VERSION = 60006; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; @@ -47,7 +46,7 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 -#define DISPLAY_VERSION_REVISION 5 -#define DISPLAY_VERSION_BUILD 2 +#define DISPLAY_VERSION_REVISION 4 +#define DISPLAY_VERSION_BUILD 1 #endif From 42047488c7b78518c3f97f53de63b86c1770c7ad Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:22:05 +0300 Subject: [PATCH 142/218] Optimize debug prints for less output, format code --- src/bitcoinrpc.cpp | 3 ++- src/db.cpp | 6 +++--- src/init.cpp | 5 ++++- src/main.cpp | 10 +++++++--- src/net.cpp | 4 ---- src/wallet.cpp | 27 +++++++++++++-------------- 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index c733b19..ab3d4e8 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -514,7 +514,8 @@ bool ClientAllowed(const boost::asio::ip::address& address) || address.to_v6().is_v4_mapped())) return ClientAllowed(address.to_v6().to_v4()); - std::string ipv4addr = address.to_string(); + // danbi: not used + // std::string ipv4addr = address.to_string(); if (address == asio::ip::address_v4::loopback() || address == asio::ip::address_v6::loopback() diff --git a/src/db.cpp b/src/db.cpp index 0471aca..70ff001 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -867,12 +867,12 @@ bool CTxDB::LoadBlockIndexGuts() // clean up junk from the block index if (totalCoin == 0) { - printf("money supply = 0\n"); - diskindex.print(); + // printf("money supply = 0\n"); + // diskindex.print(); if (blockHash != (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) { // not the genesis block, garbage anyway - printf("deleted\n"); + // printf("deleted\n"); continue; } } diff --git a/src/init.cpp b/src/init.cpp index 70c6512..54074ee 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -280,7 +280,7 @@ std::string HelpMessage() " -rpcallowip= " + _("Allow JSON-RPC connections from specified IP address") + "\n" + " -rpcconnect= " + _("Send commands to node running on (default: 127.0.0.1)") + "\n" + " -blocknotify= " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" + - " -walletnotify= " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n" + + " -walletnotify= " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n" + " -upgradewallet " + _("Upgrade wallet to latest format") + "\n" + " -keypool= " + _("Set key pool size to (default: 100)") + "\n" + " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" + @@ -506,6 +506,7 @@ bool AppInit2() // ********************************************************* Step 5: verify database integrity uiInterface.InitMessage(_("Verifying database integrity...")); + printf("Verifying database integrity...\n"); if (!bitdb.Open(GetDataDir())) { @@ -814,6 +815,7 @@ bool AppInit2() if (mapArgs.count("-loadblock")) { uiInterface.InitMessage(_("Importing blockchain data file.")); + printf("Importing blockchain data file.\n"); BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) { @@ -826,6 +828,7 @@ bool AppInit2() filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat"; if (filesystem::exists(pathBootstrap)) { uiInterface.InitMessage(_("Importing bootstrap blockchain data file.")); + printf("Importing bootstrap blockchain data file.\n"); FILE *file = fopen(pathBootstrap.string().c_str(), "rb"); if (file) { diff --git a/src/main.cpp b/src/main.cpp index 27e8a2a..461a138 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3057,6 +3057,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) printf("dropmessagestest DROPPING RECV MESSAGE\n"); return true; } + + // print what we got + if (fDebug) printf("%s from %s\n", strCommand.c_str(), pfrom->addr.ToString().c_str()); + // make sure we have current totalCoin totalCoin = GetTotalCoin(); @@ -3423,12 +3427,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pindex = pindex->pnext; int nLimit = 500 + locator.GetDistanceBack(); unsigned int nBytes = 0; - printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit); + if (fDebug) printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit); for (; pindex; pindex = pindex->pnext) { if (pindex->GetBlockHash() == hashStop) { - printf(" getblocks (hashStop) stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); + if (fDebug) printf(" getblocks (hashStop) stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); // ppcoin: tell downloading node about the latest block if it's // without risk being rejected due to stake connection check if (hashStop != hashBestChain && pindex->GetBlockTime() + nStakeMinAge > pindexBest->GetBlockTime()) @@ -3443,7 +3447,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) { // When this block is requested, we'll send an inv that'll make them // getblocks the next batch of inventory. - printf(" getblocks (nLimit) stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); + if (fDebug) printf(" getblocks (nLimit) stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); pfrom->hashContinue = pindex->GetBlockHash(); break; } diff --git a/src/net.cpp b/src/net.cpp index 419a80c..e9dc8ec 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -558,10 +558,6 @@ void CNode::PushVersion() nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()), nBestHeight); } - - - - std::map CNode::setBanned; CCriticalSection CNode::cs_setBanned; diff --git a/src/wallet.cpp b/src/wallet.cpp index c684867..d9be390 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1397,7 +1397,7 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) { - error("CreateCoinStake : invalid reserve balance amount"); + error("GetStakeMintPower : invalid reserve balance amount"); return 0; } @@ -1442,7 +1442,7 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) int64 nReserveBalance = 0; if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) - return error("CreateCoinStake : invalid reserve balance amount"); + return error("GetStakeWeight : invalid reserve balance amount"); if (nBalance <= nReserveBalance) return false; @@ -1531,30 +1531,29 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int { CTxDB txdb("r"); CTxIndex txindex; - { - LOCK2(cs_main, cs_wallet); - if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) - continue; - } + { + LOCK2(cs_main, cs_wallet); + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + } // Read block header CBlock block; - { - LOCK2(cs_main, cs_wallet); - if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) - continue; - } + { + LOCK2(cs_main, cs_wallet); + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + continue; + } static int nMaxStakeSearchInterval = 60; - // printf(">> block.GetBlockTime() = %"PRI64d", nStakeMinAge = %d, txNew.nTime = %d\n", block.GetBlockTime(), nStakeMinAge,txNew.nTime); if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval) continue; // only count coins meeting min age requirement bool fKernelFound = false; for (unsigned int n=0; n> In.....\n"); + // printf(">> In.....\n"); // Search backward in time from the given txNew timestamp // Search nSearchInterval seconds back up to nMaxStakeSearchInterval uint256 hashProofOfStake = 0; From 47a39deed7d44307a004d7606af7a68dcf618060 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:22:42 +0300 Subject: [PATCH 143/218] Add a new checkpoint --- src/checkpoints.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 3e5c5f4..024fe26 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -38,6 +38,7 @@ namespace Checkpoints (386232, uint256("0x000004bf5ce28d4bf81a7f993de4443d5a5b2bd3290e7935f3096e5b7c40fe36")) (443923, uint256("0x0000000001f9b10759fa67418e4c20a772ec39c3eff33742cb5899c7b50d7348")) (468356, uint256("0x000000000543a19eaf97aa0ad933cb6423dedacb09786f4891126ac02bd8b7d4")) + (895493, uint256("0x0000000003140f322a3913d0d67b77b462b0bcdd2a4a0ec0cd791de743cf9202")) ; From 8995965ef39a0beb5e35c9e9cab615feb9272c50 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:24:18 +0300 Subject: [PATCH 144/218] Optimize Groestl hashing a bit by improving buffer alignment --- src/hash.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/hash.h b/src/hash.h index d46a463..97e366f 100644 --- a/src/hash.h +++ b/src/hash.h @@ -13,12 +13,19 @@ #include #include +// danbi: try to improve Groestl hashing +#if defined(__GNUC__) + #define DATA_ALIGN16(x) x __attribute__ ((aligned(16))) +#else + #define DATA_ALIGN16(x) __declspec(align(16)) x +#endif + template inline uint256 HashGroestl(const T1 pbegin, const T1 pend) { sph_groestl512_context ctx_gr[2]; - static unsigned char pblank[1]; - uint512 hash[2]; + DATA_ALIGN16(static unsigned char pblank[1]); + DATA_ALIGN16(uint512 hash[2]); sph_groestl512_init(&ctx_gr[0]); sph_groestl512 (&ctx_gr[0], (pbegin == pend ? pblank : static_cast(&pbegin[0])), (pend - pbegin) * sizeof(pbegin[0])); From b70a59a8cf710a87890bfa7f0b4639d853554b8e Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:29:04 +0300 Subject: [PATCH 145/218] Implement -zapwallettxes --- src/init.cpp | 51 +++++++++++++++++++++++++++++ src/wallet.cpp | 22 +++++++++++++ src/wallet.h | 1 + src/walletdb.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ src/walletdb.h | 2 ++ 5 files changed, 159 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 54074ee..649560c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -285,6 +285,8 @@ std::string HelpMessage() " -keypool= " + _("Set key pool size to (default: 100)") + "\n" + " -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" + " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\n" + + " -zapwallettxes= " + _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup\n") + + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)\n") + " -checkblocks= " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" + " -checklevel= " + _("How thorough the block verification is (0-6, default: 1)") + "\n" + " -loadblock= " + _("Imports blocks from external blk000?.dat file") + "\n" + @@ -390,6 +392,11 @@ bool AppInit2() SoftSetBoolArg("-rescan", true); } + if (GetBoolArg("-zapwallettxes", false)) { + // -zapwallettx implies a rescan + SoftSetBoolArg("-rescan", true); + } + // ********************************************************* Step 3: parameter-to-internal-flags fDebug = GetBoolArg("-debug"); @@ -729,6 +736,25 @@ bool AppInit2() // ********************************************************* Step 8: load wallet + // needed to restore wallet transaction meta data after -zapwallettxes + std::vector vWtx; + + if (GetBoolArg("-zapwallettxes", false)) { + uiInterface.InitMessage(_("Zapping all transactions from wallet...")); + printf("Zapping all transactions from wallet...\n"); + + pwalletMain = new CWallet("wallet.dat"); + DBErrors nZapWalletRet = pwalletMain->ZapWalletTx(vWtx); + if (nZapWalletRet != DB_LOAD_OK) { + uiInterface.InitMessage(_("Error loading wallet.dat: Wallet corrupted")); + printf("Error loading wallet.dat: Wallet corrupted\n"); + return false; + } + + delete pwalletMain; + pwalletMain = NULL; + } + uiInterface.InitMessage(_("Loading wallet...")); printf("Loading wallet...\n"); nStart = GetTimeMillis(); @@ -808,6 +834,31 @@ bool AppInit2() nStart = GetTimeMillis(); pwalletMain->ScanForWalletTransactions(pindexRescan, true); printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + nWalletDBUpdated++; + + // Restore wallet transaction metadata after -zapwallettxes=1 + if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2") + { + BOOST_FOREACH(const CWalletTx& wtxOld, vWtx) + { + uint256 hash = wtxOld.GetHash(); + std::map::iterator mi = pwalletMain->mapWallet.find(hash); + if (mi != pwalletMain->mapWallet.end()) + { + const CWalletTx* copyFrom = &wtxOld; + CWalletTx* copyTo = &mi->second; + copyTo->mapValue = copyFrom->mapValue; + copyTo->vOrderForm = copyFrom->vOrderForm; + copyTo->nTimeReceived = copyFrom->nTimeReceived; + copyTo->nTimeSmart = copyFrom->nTimeSmart; + copyTo->fFromMe = copyFrom->fFromMe; + copyTo->strFromAccount = copyFrom->strFromAccount; + copyTo->nOrderPos = copyFrom->nOrderPos; + copyTo->WriteToDisk(); + } + } + } } // ********************************************************* Step 9: import blocks diff --git a/src/wallet.cpp b/src/wallet.cpp index d9be390..0910347 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1838,6 +1838,28 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet) return DB_LOAD_OK; } +DBErrors CWallet::ZapWalletTx(std::vector& vWtx) +{ + if (!fFileBacked) + return DB_LOAD_OK; + DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx); + if (nZapWalletTxRet == DB_NEED_REWRITE) + { + if (CDB::Rewrite(strWalletFile, "\x04pool")) + { + LOCK(cs_wallet); + setKeyPool.clear(); + // Note: can't top-up keypool here, because wallet is locked. + // User will be prompted to unlock wallet the next operation + // that requires a new key. + } + } + + if (nZapWalletTxRet != DB_LOAD_OK) + return nZapWalletTxRet; + + return DB_LOAD_OK; +} bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName) { diff --git a/src/wallet.h b/src/wallet.h index 41dd767..b94337c 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -263,6 +263,7 @@ class CWallet : public CCryptoKeyStore void SetBestChain(const CBlockLocator& loc); DBErrors LoadWallet(bool& fFirstRunRet); + DBErrors ZapWalletTx(std::vector& vWtx); bool SetAddressBookName(const CTxDestination& address, const std::string& strName); diff --git a/src/walletdb.cpp b/src/walletdb.cpp index bb3c11a..50e1296 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -482,6 +482,89 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) return result; } +DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector& vTxHash, vector& vWtx) +{ + pwallet->vchDefaultKey = CPubKey(); + bool fNoncriticalErrors = false; + DBErrors result = DB_LOAD_OK; + + try { + LOCK(pwallet->cs_wallet); + int nMinVersion = 0; + if (Read((string)"minversion", nMinVersion)) + { + if (nMinVersion > CLIENT_VERSION) + return DB_TOO_NEW; + pwallet->LoadMinVersion(nMinVersion); + } + + // Get cursor + Dbc* pcursor = GetCursor(); + if (!pcursor) + { + printf("Error getting wallet database cursor\n"); + return DB_CORRUPT; + } + + while (true) + { + // Read next record + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue); + if (ret == DB_NOTFOUND) + break; + else if (ret != 0) + { + printf("Error reading next record from wallet database\n"); + return DB_CORRUPT; + } + + string strType; + ssKey >> strType; + if (strType == "tx") { + uint256 hash; + ssKey >> hash; + + CWalletTx wtx; + ssValue >> wtx; + + vTxHash.push_back(hash); + vWtx.push_back(wtx); + } + } + pcursor->close(); + } + catch (const boost::thread_interrupted&) { + throw; + } + catch (...) { + result = DB_CORRUPT; + } + + if (fNoncriticalErrors && result == DB_LOAD_OK) + result = DB_NONCRITICAL_ERROR; + + return result; +} + +DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, vector& vWtx) +{ + // build list of wallet TXs + vector vTxHash; + DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); + if (err != DB_LOAD_OK) + return err; + + // erase each wallet TX + BOOST_FOREACH (uint256& hash, vTxHash) { + if (!EraseTx(hash)) + return DB_CORRUPT; + } + + return DB_LOAD_OK; +} + void ThreadFlushWalletDB(void* parg) { // Make this thread recognisable as the wallet flushing thread diff --git a/src/walletdb.h b/src/walletdb.h index a3e779a..2f33eb0 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -156,6 +156,8 @@ class CWalletDB : public CDB DBErrors ReorderTransactions(CWallet*); DBErrors LoadWallet(CWallet* pwallet); + DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); + DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, std::string filename); }; From 2ad2213e5991cb8bdd242b7a44630c642b91922b Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:32:01 +0300 Subject: [PATCH 146/218] Make CBlock::GetHash totalCoin aware (optimizes processing of non-current blocks) --- src/main.cpp | 23 ++++++++++++++++++----- src/main.h | 2 +- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 461a138..668e3b6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4775,11 +4775,25 @@ CBitcoinAddress GetFoundationAddress(int64 totalCoin) { return CBitcoinAddress ("dSDEptc8gJzbEe3Kfta8McvnBmapk6fcrR"); } -uint256 CBlock::GetHash(bool existingBlock) const +uint256 CBlock::GetHash(bool existingBlock, int64 coins) const { + // existingBlock is set by default to false + // coins is set by default to (global) totalCoin + // // There are two distinct cases when we are called - // First case is with with a block already in the blockchain index - // Second is for a new block + // existingBlock=true - a block already in the blockchain index + // both coins and totalCoin are ignored + // existingBlock=false - for a new block or when totalCoins is known + // in the context. The parameter coins is used in this case + +if (fDebug && GetBoolArg("-printjunk") && coins != totalCoin) { + printf("COMP: coins(%"PRI64d") != totalCoin(%"PRI64d")\n", coins, totalCoin); +} +// special case +if (coins == 0 && !(totalCoin == 0)) { + printf("CBlock::GetHash: coins is 0, totalCoin is %"PRI64d"\n", totalCoin); + coins=totalCoin; +} if (existingBlock) { @@ -4810,8 +4824,7 @@ uint256 CBlock::GetHash(bool existingBlock) const printf("CBlock::GetHash(true): neither scrypt nor groestl hash found in the block index! Failing back..\n"); } - // new block or not found in blockchain - if (totalCoin <= VALUE_CHANGE) + if (coins <= VALUE_CHANGE) { uint256 hash_scrypt = GetHashScrypt(); if (hash_scrypt == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) { diff --git a/src/main.h b/src/main.h index 536f7e0..2bcae82 100644 --- a/src/main.h +++ b/src/main.h @@ -924,7 +924,7 @@ class CBlock return (nBits == 0); } - uint256 GetHash(bool existingBlock=false) const; + uint256 GetHash(bool existingBlock=false, int64 coins=totalCoin) const; uint256 GetHashScrypt() const { From d53756102bfaf97903d2024ee6a29957d26a96d6 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:35:03 +0300 Subject: [PATCH 147/218] Use the totalCoin aware CBlock::GetHash function to reduce calls to hash functions (scrypt/groestl) Eliminate repeated calls to GetHash --- src/main.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 668e3b6..2a483bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -913,7 +913,9 @@ bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) } if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions)) return false; - if (GetHashScrypt() != pindex->GetBlockHash() && GetHashGroestl() != pindex->GetBlockHash()) +// if (GetHashScrypt() != pindex->GetBlockHash() && GetHashGroestl() != pindex->GetBlockHash()) + // send totalCoins to speed up GetHash() + if (GetHash(false, pindex->nMoneySupply / COIN ) != pindex->GetBlockHash()) return error("CBlock::ReadFromDisk() : GetHash() doesn't match index"); return true; } @@ -2201,8 +2203,12 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) // Check proof of work matches claimed amount // XXX: danbi - need to check both algos or we make it hard for initial sync - if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) - return DoS(50, error("CheckBlock() : proof of work failed")); + // can't use GetHash() optimization, because we are also called when + // new block comes during initial sync and that might come from "future" + // compromise: use optimization, but decrease penalty (was 50) +// if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) + if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(false, totalCoin), nBits)) + return DoS(10, error("CheckBlock() : proof of work failed")); // Check timestamp if (GetBlockTime() > GetAdjustedTime() + nMaxClockDrift) @@ -2496,9 +2502,10 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) ++mi) { CBlock* pblockOrphan = (*mi).second; + uint256 ohash = pblockOrphan->GetHash(); if (pblockOrphan->AcceptBlock()) - vWorkQueue.push_back(pblockOrphan->GetHash()); - mapOrphanBlocks.erase(pblockOrphan->GetHash()); + vWorkQueue.push_back(ohash); + mapOrphanBlocks.erase(ohash); setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake()); delete pblockOrphan; } @@ -2840,6 +2847,7 @@ void PrintBlockTree() // print item CBlock block; block.ReadFromDisk(pindex); +// danbi: optimization for GetHash() possible here printf("%d (%u,%u) %s %08x %s mint %7s tx %"PRIszu"", pindex->nHeight, pindex->nFile, From 4825400b83c7a37962feac7ddaee19ed56957291 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:38:34 +0300 Subject: [PATCH 148/218] Change IsBanned to return number of seconds remaining for the ban, to be recorded in long file --- src/net.cpp | 17 ++++++++++------- src/net.h | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index e9dc8ec..eb03de0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -566,20 +566,22 @@ void CNode::ClearBanned() setBanned.clear(); } -bool CNode::IsBanned(CNetAddr ip) +// return how many seconds left, if banned +int64 CNode::IsBanned(CNetAddr ip) { - bool fResult = false; { LOCK(cs_setBanned); std::map::iterator i = setBanned.find(ip); if (i != setBanned.end()) { int64 t = (*i).second; - if (GetTime() < t) - fResult = true; + int64 left = t - GetTime(); + if (left < 0) + left=0; + return left; } } - return fResult; + return 0; } extern CMedianFilter cPeerBlockCounts; @@ -813,6 +815,7 @@ void ThreadSocketHandler2(void* parg) SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); CAddress addr; int nInbound = 0; + int bsec = 0; // how many seconds left in a ban if (hSocket != INVALID_SOCKET) if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr)) @@ -839,9 +842,9 @@ void ThreadSocketHandler2(void* parg) closesocket(hSocket); } } - else if (CNode::IsBanned(addr)) + else if ((bsec = CNode::IsBanned(addr))) { - printf("connection from %s dropped (banned)\n", addr.ToString().c_str()); + printf("connection from %s dropped (banned %d sec)\n", addr.ToString().c_str(), bsec); closesocket(hSocket); } else diff --git a/src/net.h b/src/net.h index b44eb32..d7d7c67 100644 --- a/src/net.h +++ b/src/net.h @@ -637,7 +637,7 @@ class CNode // between nodes running old code and nodes running // new code. static void ClearBanned(); // needed for unit testing - static bool IsBanned(CNetAddr ip); + static int64 IsBanned(CNetAddr ip); bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot void copyStats(CNodeStats &stats); }; From d5f4dab6556733b28bbf431b4096097d6bea702a Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:40:03 +0300 Subject: [PATCH 149/218] After disconnecting a node due to old version/protocol also ban it. --- src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 2a483bf..811886b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3097,6 +3097,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (totalCoin >= 1000000 && (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { printf("ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); + // immediate ban + pfrom->Misbehaving(100); pfrom->fDisconnect = true; return false; } @@ -3135,6 +3137,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) ) { printf("partner %s using obsolete client %s\n", pfrom->addr.ToString().c_str(), pfrom->strSubVer.c_str()); + // immediate ban + pfrom->Misbehaving(100); pfrom->fDisconnect = true; return false; } From 5468133b1986d7432cea5ce05d299a1f1c622112 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:41:47 +0300 Subject: [PATCH 150/218] Implement -connectallowedip, an ACL for inter-node connections --- src/net.cpp | 18 ++++++++++++++++++ src/net.h | 1 + 2 files changed, 19 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index eb03de0..ede46b4 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -584,6 +584,19 @@ int64 CNode::IsBanned(CNetAddr ip) return 0; } +bool CNode::ConnectAllowed(CNetAddr ip) +{ + const string strAddress = ip.ToString(); + const vector& vAllow = mapMultiArgs["-connectallowip"]; + // no ACL specified, everyone plays + if (vAllow.empty()) + return true; + BOOST_FOREACH(string strAllow, vAllow) + if (WildcardMatch(strAddress, strAllow)) + return true; + return false; +} + extern CMedianFilter cPeerBlockCounts; bool CNode::Misbehaving(int howmuch) @@ -842,6 +855,11 @@ void ThreadSocketHandler2(void* parg) closesocket(hSocket); } } + else if (!CNode::ConnectAllowed(addr)) + { + printf("connection from %s dropped (forbidden)\n", addr.ToString().c_str()); + closesocket(hSocket); + } else if ((bsec = CNode::IsBanned(addr))) { printf("connection from %s dropped (banned %d sec)\n", addr.ToString().c_str(), bsec); diff --git a/src/net.h b/src/net.h index d7d7c67..e8cdc7c 100644 --- a/src/net.h +++ b/src/net.h @@ -638,6 +638,7 @@ class CNode // new code. static void ClearBanned(); // needed for unit testing static int64 IsBanned(CNetAddr ip); + static bool ConnectAllowed(CNetAddr ip); bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot void copyStats(CNodeStats &stats); }; From 6364e1fe07aad273d6b182b1e043a34ee5f8e7b1 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:46:07 +0300 Subject: [PATCH 151/218] Add default seednode --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 649560c..6fd5b6b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -666,7 +666,7 @@ bool AppInit2() BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); -// AddOneShot("54.229.220.59"); + AddOneShot("193.68.21.19"); // TODO: replace this by DNSseed // AddOneShot(string("")); From 13ce3306aba168a0e76e0f0fca0615f54ebf5299 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:47:15 +0300 Subject: [PATCH 152/218] Update version to 2.0.5.6 --- doc/README | 2 +- doc/README_windows.txt | 2 +- src/clientversion.h | 2 +- src/qt/forms/aboutdialog.ui | 2 +- src/version.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/README b/doc/README index 8b46b43..c4bfd08 100644 --- a/doc/README +++ b/doc/README @@ -1,4 +1,4 @@ -Diamond 2.0.5.5 +Diamond 2.0.5.6 Copyright (c) 2013-2015 Diamond Foundation Copyright (c) 2013 NovaCoin Developers diff --git a/doc/README_windows.txt b/doc/README_windows.txt index a8788d5..0f8d58f 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Diamond 2.0.5.5 +Diamond 2.0.5.6 Copyright (c) 2013-2015 Diamond Foundation Copyright (c) 2013 NovaCoin Developers diff --git a/src/clientversion.h b/src/clientversion.h index a08f3c4..36dc445 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 5 -#define CLIENT_VERSION_BUILD 5 +#define CLIENT_VERSION_BUILD 6 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index eb5c70e..30f2a97 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.5.5 + 2.0.5.6 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/version.h b/src/version.h index 47e125d..f968d72 100644 --- a/src/version.h +++ b/src/version.h @@ -48,6 +48,6 @@ static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 #define DISPLAY_VERSION_MINOR 0 #define DISPLAY_VERSION_REVISION 5 -#define DISPLAY_VERSION_BUILD 5 +#define DISPLAY_VERSION_BUILD 6 #endif From 7323a7b6885dfa4ef9ff979707fb23a6c55ef515 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Fri, 24 Apr 2015 12:51:31 +0300 Subject: [PATCH 153/218] Update version of project too --- diamond.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diamond.pro b/diamond.pro index 60d6802..e236993 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 2.0.3.0 +VERSION = 2.0.5.6 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES From 318f74176893b165fd2e39bb3159b0f322f1d93b Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 27 Apr 2015 11:31:54 +0300 Subject: [PATCH 154/218] More seednode fixes --- src/main.cpp | 3 ++- src/net.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 811886b..9ba9b59 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3292,7 +3292,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } } // Do not store addresses outside our network - if (fReachable) + // danbi: ignore reachable if we do OneShot + if (fReachable || pfrom->fOneShot) vAddrOk.push_back(addr); } addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); diff --git a/src/net.cpp b/src/net.cpp index ede46b4..560797d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1218,6 +1218,7 @@ void ThreadDNSAddressSeed2(void* parg) int nOneDay = 24*3600; CAddress addr = CAddress(CService(ip, GetDefaultPort())); addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old + SetReachable(addr.GetNetwork()); vAdd.push_back(addr); found++; } @@ -1403,6 +1404,7 @@ void ThreadOpenConnections2(void* parg) memcpy(&ip, &pnSeed[i], sizeof(ip)); CAddress addr(CService(ip, GetDefaultPort())); addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek; + SetReachable(addr.GetNetwork()); vAdd.push_back(addr); } addrman.Add(vAdd, CNetAddr("127.0.0.1")); From 5d99907e7eed1a149537fc30c1510df0a339aa81 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 27 Apr 2015 11:50:09 +0300 Subject: [PATCH 155/218] Update seed nodes --- src/init.cpp | 1 - src/net.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 6fd5b6b..2f994e7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -666,7 +666,6 @@ bool AppInit2() BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); - AddOneShot("193.68.21.19"); // TODO: replace this by DNSseed // AddOneShot(string("")); diff --git a/src/net.cpp b/src/net.cpp index 560797d..c802eec 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1171,6 +1171,7 @@ void MapPort() // The first name is used as information source for addrman. // The second name should resolve to a list of seed addresses. static const char *strDNSSeed[][2] = { + {"seed.bit.diamond", "seed.bit.diamond"}, {"dmdseed.danbo.bg", "dmdseed.danbo.bg"}, {"", ""}, }; @@ -1244,6 +1245,7 @@ void ThreadDNSAddressSeed2(void* parg) unsigned int pnSeed[] = { + 0x131544c1 }; void DumpAddresses() From 5987b055afcc8c7155ad78ed9b99e518cc7a52bd Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 27 Apr 2015 11:51:41 +0300 Subject: [PATCH 156/218] Reduce debug output during block chain load --- src/db.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 70ff001..a5bc107 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -877,25 +877,25 @@ bool CTxDB::LoadBlockIndexGuts() } } if (totalCoin == VALUE_CHANGE) { - printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); - diskindex.print(); +// printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); +// diskindex.print(); if (diskindex.hashNext == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) { // assign proper hash value - printf("changed\n"); +// printf("changed\n"); diskindex.hashNext = uint256("0x00000d652b612a94e1c830bf4e05106438ea6b53372b29206f0b820d91a9b67b"); } if (diskindex.GetBlockHash() == uint256("0xe12ddb2c35d84403b0a045574ecce223f7e2f0db4506e76ed3d43bc464ace40c")) { // this hash version should not be here, delete - printf("deleted\n"); +// printf("deleted\n"); continue; } } if (totalCoin == VALUE_CHANGE+1) { // for information - printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); - diskindex.print(); +// printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); +// diskindex.print(); } // end cleanup @@ -945,28 +945,30 @@ bool CTxDB::LoadBlockIndexGuts() } } - printf("loaded %d in block index\n", count); +// printf("loaded %d in block index\n", count); if(pindexSaveNext != NULL && pindexSave != NULL && pindexSave->pnext == NULL) { - printf("linked pnext at switch block\n"); +// printf("linked pnext at switch block\n"); pindexSave->pnext = pindexSaveNext; } pcursor->close(); +#if 0 printf ("verify mapBlockIndex\n"); count=0; BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex) { CBlockIndex* pindex = item.second; if (pindex->nHeight == 0) { - printf("nHeight=0 count=%d\n", count); + printf("nHeight=0 count=%d\n", count); pindex->print(); } count++; } printf("end verify\n"); +#endif return true; } From 5412776a14d3e7053e30539fb14cacc8cb3a210c Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 27 Apr 2015 12:10:28 +0300 Subject: [PATCH 157/218] Turn off IRC by default --- src/init.cpp | 2 +- src/irc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 2f994e7..4cf60cd 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -241,7 +241,7 @@ std::string HelpMessage() " -externalip= " + _("Specify your own public address") + "\n" + " -onlynet= " + _("Only connect to nodes in network (IPv4, IPv6 or Tor)") + "\n" + " -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" + - " -irc " + _("Find peers using internet relay chat (default: 1)") + "\n" + + " -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" + " -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" + " -bind= " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" + " -dnsseed " + _("Find peers using DNS lookup (default: 0)") + "\n" + diff --git a/src/irc.cpp b/src/irc.cpp index 157a031..4132ba8 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -214,7 +214,7 @@ void ThreadIRCSeed2(void* parg) return; // ... or if IRC is not enabled. - if (!GetBoolArg("-irc", true)) + if (!GetBoolArg("-irc", false)) return; printf("ThreadIRCSeed started\n"); From c841d79e2cd340ee27089078d8b0ee31824480d0 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Mon, 27 Apr 2015 13:58:39 +0300 Subject: [PATCH 158/218] Increase the number of outgoing connections to 16 --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index c802eec..e1ee17b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -25,7 +25,7 @@ using namespace std; using namespace boost; -static const int MAX_OUTBOUND_CONNECTIONS = 12; +static const int MAX_OUTBOUND_CONNECTIONS = 16; void ThreadMessageHandler2(void* parg); void ThreadSocketHandler2(void* parg); From 0e196a57591edc04f5b5b06b0b8a13b91d70ac2d Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Thu, 30 Apr 2015 13:44:12 +0300 Subject: [PATCH 159/218] Update version to 2.0.5.7 --- diamond.pro | 2 +- doc/README | 2 +- doc/README_windows.txt | 2 +- src/clientversion.h | 2 +- src/qt/forms/aboutdialog.ui | 2 +- src/qt/res/images/wallet.png | Bin 110396 -> 0 bytes src/version.h | 2 +- 7 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 src/qt/res/images/wallet.png diff --git a/diamond.pro b/diamond.pro index e236993..0424a9c 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 2.0.5.6 +VERSION = 2.0.5.7 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES diff --git a/doc/README b/doc/README index c4bfd08..902345c 100644 --- a/doc/README +++ b/doc/README @@ -1,4 +1,4 @@ -Diamond 2.0.5.6 +Diamond 2.0.5.7 Copyright (c) 2013-2015 Diamond Foundation Copyright (c) 2013 NovaCoin Developers diff --git a/doc/README_windows.txt b/doc/README_windows.txt index 0f8d58f..12aaa1c 100644 --- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Diamond 2.0.5.6 +Diamond 2.0.5.7 Copyright (c) 2013-2015 Diamond Foundation Copyright (c) 2013 NovaCoin Developers diff --git a/src/clientversion.h b/src/clientversion.h index 36dc445..af44bc4 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 0 #define CLIENT_VERSION_REVISION 5 -#define CLIENT_VERSION_BUILD 6 +#define CLIENT_VERSION_BUILD 7 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 30f2a97..9f86741 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.5.6 + 2.0.5.7 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/src/qt/res/images/wallet.png b/src/qt/res/images/wallet.png deleted file mode 100644 index 882d645a3aa1ed38e63e611f1903edccf3db3338..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110396 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
    6zV6E}LO=bOf-m44uoayo#fT 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 N002ovPDHLkV1haeX} Date: Wed, 30 Dec 2015 14:02:40 -0600 Subject: [PATCH 160/218] Add some .gitignore files Create src/obj dir during source clone to avoid confusion Ignore some binary and autogenerated files --- .gitignore | 19 +++++++++++++++++++ src/obj/.gitignore | 3 +++ 2 files changed, 22 insertions(+) create mode 100644 .gitignore create mode 100644 src/obj/.gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..912eeb9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +src/diamondd +src/test_diamond + +# Ignore build dir +build/ + +# Compilation and Qt preprocessor part +*.qm +Makefile +paycoin-qt + +# Resources cpp +qrc_*.cpp + +# Qt creator +*.pro.user + +# Mac specific +.DS_Store diff --git a/src/obj/.gitignore b/src/obj/.gitignore new file mode 100644 index 0000000..dd3727e --- /dev/null +++ b/src/obj/.gitignore @@ -0,0 +1,3 @@ +#Ignore all files except the .gitignore +* +!.gitignore From 8167e1bb463e73d6a455d3c8de2be3fc40bfe62f Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Wed, 30 Dec 2015 14:18:08 -0600 Subject: [PATCH 161/218] Add compatibility for miniupnpc api 14 --- src/net.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index e1ee17b..849a50a 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1053,10 +1053,14 @@ void ThreadMapPort2(void* parg) #ifndef UPNPDISCOVER_SUCCESS /* miniupnpc 1.5 */ devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#else +#elif MINIUPNPC_API_VERSION < 14 /* miniupnpc 1.6 */ int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); +#else + /* miniupnpc 1.9 */ + int error = 0; + devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); #endif struct UPNPUrls urls; From e90eb5d513fb1f907a0994318c1c883316f43096 Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Wed, 30 Dec 2015 14:19:44 -0600 Subject: [PATCH 162/218] Add .gitignore for src/obj-test also --- src/obj-test/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/obj-test/.gitignore diff --git a/src/obj-test/.gitignore b/src/obj-test/.gitignore new file mode 100644 index 0000000..dd3727e --- /dev/null +++ b/src/obj-test/.gitignore @@ -0,0 +1,3 @@ +#Ignore all files except the .gitignore +* +!.gitignore From 3eb77ba74efdb9a612dcb872f3507e466884aa55 Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Wed, 30 Dec 2015 14:29:26 -0600 Subject: [PATCH 163/218] Make tests build Files that failed to build have been renamed .bak to be left out Add a default value to test_bitcoin.cpp High number of failing tests, not addressed in this commit --- src/test/{Checkpoints_tests.cpp => Checkpoints_tests.cpp.bak} | 0 src/test/{miner_tests.cpp => miner_tests.cpp.bak} | 0 src/test/test_bitcoin.cpp | 2 ++ src/test/{wallet_tests.cpp => wallet_tests.cpp.bak} | 0 4 files changed, 2 insertions(+) rename src/test/{Checkpoints_tests.cpp => Checkpoints_tests.cpp.bak} (100%) rename src/test/{miner_tests.cpp => miner_tests.cpp.bak} (100%) rename src/test/{wallet_tests.cpp => wallet_tests.cpp.bak} (100%) diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp.bak similarity index 100% rename from src/test/Checkpoints_tests.cpp rename to src/test/Checkpoints_tests.cpp.bak diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp.bak similarity index 100% rename from src/test/miner_tests.cpp rename to src/test/miner_tests.cpp.bak diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index bcf0907..5f50e9a 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -11,6 +11,8 @@ CClientUIInterface uiInterface; extern bool fPrintToConsole; extern void noui_connect(); +bool fUseFastIndex = true; + struct TestingSetup { TestingSetup() { fPrintToDebugger = true; // don't want to write to debug.log file diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp.bak similarity index 100% rename from src/test/wallet_tests.cpp rename to src/test/wallet_tests.cpp.bak From 790cf713a61e185dd1dc441430f2df61b73668df Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Mon, 4 Jan 2016 11:54:42 -0600 Subject: [PATCH 164/218] Implement core scrape address functionality --- src/bitcoinrpc.cpp | 20 +++-- src/bitcoinrpc.h | 8 ++ src/rpcwallet.cpp | 128 ++++++++++++++++++++++++++++- src/test/rpc_tests.cpp | 177 +++++++++++++++++++++++++++++++++++++++++ src/wallet.cpp | 63 ++++++++++----- src/wallet.h | 28 ++++++- src/walletdb.cpp | 62 ++++++++++++++- src/walletdb.h | 8 ++ 8 files changed, 464 insertions(+), 30 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index ab3d4e8..120205a 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -262,14 +262,18 @@ static const CRPCCommand vRPCCommands[] = { "signrawtransaction", &signrawtransaction, false, false }, { "sendrawtransaction", &sendrawtransaction, false, false }, { "getcheckpoint", &getcheckpoint, true, false }, - { "reservebalance", &reservebalance, false, true}, - { "checkwallet", &checkwallet, false, true}, - { "repairwallet", &repairwallet, false, true}, - { "resendtx", &resendtx, false, true}, - { "makekeypair", &makekeypair, false, true}, - { "sendalert", &sendalert, false, false}, - { "setchangeaddress", &setchangeaddress, true, false }, - { "getchangeaddress", &getchangeaddress, true, false }, + { "reservebalance", &reservebalance, false, true }, + { "checkwallet", &checkwallet, false, true }, + { "repairwallet", &repairwallet, false, true }, + { "resendtx", &resendtx, false, true }, + { "makekeypair", &makekeypair, false, true }, + { "sendalert", &sendalert, false, false }, + { "setchangeaddress", &setchangeaddress, true, false }, + { "getchangeaddress", &getchangeaddress, true, false }, + { "getscrapeaddress", &getscrapeaddress, true, false }, + { "listscrapeaddresses", &listscrapeaddresses, true, false }, + { "setscrapeaddress", &setscrapeaddress, true, true }, + { "deletescrapeaddress", &deletescrapeaddress, true, true } }; CRPCTable::CRPCTable() diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 91934dd..0532a98 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -74,6 +74,9 @@ int CommandLineRPC(int argc, char *argv[]); /** Convert parameter values for RPC call from strings to command-specific JSON objects. */ json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams); +/** Call the RPC service directly (placed here to allow for more in depth tests). */ +json_spirit::Object CallRPC(const std::string &strMethod, const json_spirit::Array ¶ms); + /* Type-check arguments; throws JSONRPCError if wrong type given. Does not check that the right number of arguments are passed, just that any passed are the correct type. @@ -207,4 +210,9 @@ extern json_spirit::Value getcheckpoint(const json_spirit::Array& params, bool f extern json_spirit::Value setchangeaddress(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getchangeaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value setscrapeaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getscrapeaddress(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listscrapeaddresses(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value deletescrapeaddress(const json_spirit::Array& params, bool fHelp); + #endif diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 571028d..774222e 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1776,7 +1777,7 @@ Value makekeypair(const Array& params, bool fHelp) string strPrefix = ""; if (params.size() > 0) strPrefix = params[0].get_str(); - + CKey key; key.MakeNewKey(false); @@ -1827,3 +1828,128 @@ Value getchangeaddress(const Array& params, bool fHelp) return ret; } + +Value setscrapeaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) { + string ret = "setscrapeaddress ,
    \nSet an auto scrape address to send stake rewards to from a given address."; + if (pwalletMain->IsCrypted()) + ret += "requires wallet passphrase to be set with walletpassphrase first"; + + throw runtime_error(ret); + } + + EnsureWalletIsUnlocked(); + + string strAddress = params[0].get_str(); + CBitcoinAddress address(strAddress); + string strScrapeAddress = params[1].get_str(); + CBitcoinAddress scrapeAddress(strScrapeAddress); + + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address."); + + if (address.Get() == scrapeAddress.Get()) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot set scrape address to the same as staking address."); + + if (!IsMine(*pwalletMain, address.Get())) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Staking address must be in wallet."); + + if (!scrapeAddress.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid scrape address."); + + string oldScrapeAddress; + bool warn = false; + if (pwalletMain->ReadScrapeAddress(strAddress, oldScrapeAddress)) { + if (strScrapeAddress == oldScrapeAddress) + throw runtime_error(strprintf("Scrape address is already set to %s", oldScrapeAddress.c_str())); + + warn = true; + } + + if (pwalletMain->WriteScrapeAddress(strAddress, strScrapeAddress)) { + if (warn) + return strprintf("Warning overwriting %s with %s", oldScrapeAddress.c_str(), strScrapeAddress.c_str()); + + Object obj; + obj.push_back(Pair(strAddress, strScrapeAddress)); + return obj; + } + + // This should never happen. + throw JSONRPCError(-1, "setscrapeaddress: unknown error"); +} + +Value getscrapeaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "getscrapeaddress \n" + "Get the auto scrape address for a given address." + ); + + string strAddress = params[0].get_str(); + CBitcoinAddress address(strAddress); + + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address."); + + if (!IsMine(*pwalletMain, address.Get())) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Staking address must be in wallet."); + + string strScrapeAddress; + if (!pwalletMain->ReadScrapeAddress(strAddress, strScrapeAddress)) { + string ret = "No scrape address set for address "; + ret += strAddress; + throw JSONRPCError(RPC_WALLET_ERROR, ret); + } + + Object obj; + obj.push_back(Pair(strAddress, strScrapeAddress)); + return obj; +} + +Value listscrapeaddresses(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "listscrapeaddresses\n" + "List all the defined scrape addresses." + ); + + Object obj; + LOCK(pwalletMain->cs_wallet); + CWalletDB(pwalletMain->strWalletFile).DumpScrapeAddresses(obj); + + return obj; +} + +Value deletescrapeaddress(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) { + string ret = "deletescrapeaddress \nDelete the auto scrape address for a given address."; + if (pwalletMain->IsCrypted()) + ret += "requires wallet passphrase to be set with walletpassphrase first"; + + throw runtime_error(ret); + } + + EnsureWalletIsUnlocked(); + + string strAddress = params[0].get_str(); + CBitcoinAddress address(strAddress); + + if (!address.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address."); + + if (!IsMine(*pwalletMain, address.Get())) + throw JSONRPCError(RPC_INVALID_PARAMETER, "Staking address must be in wallet."); + + if (!pwalletMain->HasScrapeAddress(strAddress)) { + string ret = "No scrape address set for address "; + ret += strAddress; + throw JSONRPCError(RPC_WALLET_ERROR, ret); + } + + return pwalletMain->EraseScrapeAddress(strAddress); +} diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 505ec8f..88334f5 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -4,6 +4,7 @@ #include "base58.h" #include "util.h" #include "bitcoinrpc.h" +#include "wallet.h" using namespace std; using namespace json_spirit; @@ -59,4 +60,180 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); } +// Actually run some of the RPC tests over RPC +struct RPCServerFixture +{ + RPCServerFixture() { + SoftSetArg("-rpcuser", "diamondrpc"); + SoftSetArg("-rpcpassword", "dbrxGK62DXSJ6Cm3zgurPs3ML9uKxfwv5Z"); + NewThread(ThreadRPCServer, NULL); + } + + ~RPCServerFixture() { } +}; + +// Read a response object and return false if there is an error found +bool readResponse(Object obj, int &error_code) { + // Initialize our error code as 0 because otherwise it may not have a value. + error_code = 0; + + const Value &error = find_value(obj, "error"); + + if (error.type() != null_type) + { + error_code = find_value(error.get_obj(), "code").get_int(); + return false; + } + + return true; +} + +Object callRPC(string strMethod, vector strParams) { + Array params = RPCConvertValues(strMethod, strParams); + return CallRPC(strMethod, params); +} + +BOOST_FIXTURE_TEST_CASE(rpc_scrapes, RPCServerFixture) +{ + // Wait a little bit to try to make sure the thread is fully started + Sleep(100); + + /* This is a valid private key and address, do NOT use this key in a real + * wallet, your coins will not be secure! */ + string strValidAddress = "dNsgxYgHwfWexm64z3E8ZRzKembpcKmG7v"; + string strValidPrivKey = "ZHbcuy4b9z7R3FAwvsmNfHoG3LtrfoCPtoYWhUG4thypZySos2ti"; + string strValidAddress2 = "dbrxGK62DXSJ6Cm3zgurPs3ML9uKxfwv5Z"; + + // error: {"code":-8,"message":"Staking address must be in wallet."} + string strMethod = "setscrapeaddress"; + vector strParams; + strParams.push_back(strValidAddress); + strParams.push_back(strValidAddress2); + + Object obj = callRPC(strMethod, strParams); + + int error_code; + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_PARAMETER); + + strMethod = "getscrapeaddress"; + strParams.clear(); + strParams.push_back(strValidAddress); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_PARAMETER); + + strMethod = "deletescrapeaddress"; + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_PARAMETER); + + // Import a valid private key for testing on. + strMethod = "importprivkey"; + strParams.clear(); + strParams.push_back(strValidPrivKey); + strParams.push_back("test"); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(readResponse(obj, error_code)); + + // // error: {"code":-5,"message":"Invalid address."} + strMethod = "setscrapeaddress"; + strParams.clear(); + strParams.push_back("dNsgxYgHwfWe"); + strParams.push_back("dbrxGK62DXSJ"); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_ADDRESS_OR_KEY); + + strMethod = "getscrapeaddress"; + strParams.clear(); + strParams.push_back("dNsgxYgHwfWe"); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_ADDRESS_OR_KEY); + + strMethod = "deletescrapeaddress"; + strParams.clear(); + strParams.push_back("dNsgxYgHwfWe"); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_ADDRESS_OR_KEY); + + // error: {"code":-5,"message":"Invalid scrape address."} + strMethod = "setscrapeaddress"; + strParams.clear(); + strParams.push_back(strValidAddress); + strParams.push_back("dbrxGK62DXSJ"); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_ADDRESS_OR_KEY); + + // error: {"code":-8,"message":"Cannot set scrape address to the same as staking address."} + strParams.clear(); + strParams.push_back(strValidAddress); + strParams.push_back(strValidAddress); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_INVALID_PARAMETER); + + // error: ("code":-1,"message":"No scrape address set for address ") + strMethod = "getscrapeaddress"; + strParams.clear(); + strParams.push_back(strValidAddress); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_WALLET_ERROR); + + strMethod = "deletescrapeaddress"; + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(!readResponse(obj, error_code)); + BOOST_CHECK_EQUAL(error_code, RPC_WALLET_ERROR); + + // Valid setscrapeaddress + strMethod = "setscrapeaddress"; + strParams.clear(); + strParams.push_back(strValidAddress); + strParams.push_back(strValidAddress2); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(readResponse(obj, error_code)); + + // Valid getscrapeaddress + strMethod = "getscrapeaddress"; + strParams.clear(); + strParams.push_back(strValidAddress); + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(readResponse(obj, error_code)); + + // Valid deletescrapeaddress + strMethod = "deletescrapeaddress"; + + obj = callRPC(strMethod, strParams); + + BOOST_CHECK(readResponse(obj, error_code)); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet.cpp b/src/wallet.cpp index 0910347..114ea7c 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -1246,7 +1247,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW return false; wtxNew.BindWallet(this); - + // transaction comment wtxNew.strTxComment = strTxComment; if (wtxNew.strTxComment.length() > MAX_TX_COMMENT_LEN) @@ -1316,7 +1317,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // coin control: send change to custom address if (coinControl && !boost::get(&coinControl->destChange)) scriptChange.SetDestination(coinControl->destChange); - + // no coin control: send change to newly generated address else { @@ -1326,10 +1327,10 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // If we reused the old key, it would be possible to add code to look for and // rediscover unknown transactions that were written with keys of ours to recover // post-backup change. - + // Reserve a new key pair from key pool CPubKey vchPubKey = reservekey.GetReservedKey(); - + scriptChange.SetDestination(vchPubKey.GetID()); } } @@ -1439,23 +1440,23 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) { // Choose coins to use int64 nBalance = GetBalance(); - + int64 nReserveBalance = 0; if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) return error("GetStakeWeight : invalid reserve balance amount"); if (nBalance <= nReserveBalance) return false; - + set > setCoins; vector vwtxPrev; int64 nValueIn = 0; - + if (!SelectCoins(nBalance - nReserveBalance, GetTime(), setCoins, nValueIn)) return false; - + if (setCoins.empty()) return false; - + CTxDB txdb("r"); BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { @@ -1465,29 +1466,29 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) continue; } - + int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime()); CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); - + // Weight is greater than zero if (nTimeWeight > 0) { nWeight += bnCoinDayWeight.getuint64(); } - + // Weight is greater than zero, but the maximum value isn't reached yet if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge) { nMinWeight += bnCoinDayWeight.getuint64(); } - + // Maximum weight was reached if (nTimeWeight == nStakeMaxAge) { nMaxWeight += bnCoinDayWeight.getuint64(); } } - + return true; } @@ -1546,7 +1547,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int } static int nMaxStakeSearchInterval = 60; - + if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval) continue; // only count coins meeting min age requirement @@ -1554,7 +1555,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int for (unsigned int n=0; n> In.....\n"); - // Search backward in time from the given txNew timestamp + // Search backward in time from the given txNew timestamp // Search nSearchInterval seconds back up to nMaxStakeSearchInterval uint256 hashProofOfStake = 0; COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second); @@ -1596,7 +1597,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int else scriptPubKeyOut = scriptPubKeyKernel; - txNew.nTime -= n; + txNew.nTime -= n; txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; @@ -1649,6 +1650,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int vwtxPrev.push_back(pcoin.first); } } + + bool scrapedstake = false; // Calculate coin age reward { uint64 nCoinAge; @@ -1657,14 +1660,36 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (!txNew.GetCoinAge(txdb, nCoinAge)) return error("CreateCoinStake : failed to calculate coin age"); - nCredit += GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime, pIndex0->nHeight); + int64 nReward = GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime, pIndex0->nHeight); + + /* Check the staking address against the scrape addresses in the + * walletdb and see if it has a scrape address for it, if it does + * send the reward to the scrape address. */ + CTxDestination address; + ExtractDestination(txNew.vout[1].scriptPubKey, address); + CBitcoinAddress addr(address); + + string strScrapeAddress; + if (HasScrapeAddress(addr.ToString()) && ReadScrapeAddress(addr.ToString(), strScrapeAddress)) { + CScript stakescript; + CBitcoinAddress scrapeaddr(strScrapeAddress); + CTxDestination scrape = scrapeaddr.Get(); + if (fDebug && GetBoolArg("-printcoinstake")) + strprintf("CreateCoinStake : a scrape address has been set for %s to %s, sending reward there.\n", addr.ToString().c_str(), scrapeaddr.ToString().c_str()); + + stakescript.SetDestination(scrape); + txNew.vout.push_back(CTxOut(nReward, stakescript)); + scrapedstake = true; + } else { + nCredit += nReward; + } } int64 nMinFee = 0; while (true) { // Set output amount - if (txNew.vout.size() == 3) + if ((!scrapedstake && txNew.vout.size() == 3) || txNew.vout.size() == 4) { txNew.vout[1].nValue = ((nCredit - nMinFee) / 2 / CENT) * CENT; txNew.vout[2].nValue = nCredit - nMinFee - txNew.vout[1].nValue; diff --git a/src/wallet.h b/src/wallet.h index b94337c..a4d6700 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_WALLET_H @@ -32,8 +33,9 @@ enum WalletFeature FEATURE_WALLETCRYPT = 40000, // wallet encryption FEATURE_COMPRPUBKEY = 60000, // compressed public keys + FEATURE_SCRAPEADDRESS = 60001, // scrape addresses for staking wallets - FEATURE_LATEST = 60000 + FEATURE_LATEST = 60001 }; @@ -313,6 +315,30 @@ class CWallet : public CCryptoKeyStore * @note called with lock cs_wallet held. */ boost::signals2::signal NotifyTransactionChanged; + + bool WriteScrapeAddress(const std::string strAddress, const std::string strScrapeAddress) + { + LOCK(cs_wallet); + return CWalletDB(strWalletFile).WriteScrapeAddress(strAddress, strScrapeAddress); + } + + bool EraseScrapeAddress(const std::string strAddress) + { + LOCK(cs_wallet); + return CWalletDB(strWalletFile).EraseScrapeAddress(strAddress); + } + + bool ReadScrapeAddress(const std::string strAddress, std::string &strScrapeAddress) + { + LOCK(cs_wallet); + return CWalletDB(strWalletFile).ReadScrapeAddress(strAddress, strScrapeAddress); + } + + bool HasScrapeAddress(const std::string strAddress) + { + LOCK(cs_wallet); + return CWalletDB(strWalletFile).HasScrapeAddress(strAddress); + } }; /** A key allocated from the key pool. */ diff --git a/src/walletdb.cpp b/src/walletdb.cpp index 50e1296..e24ed50 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,7 +10,7 @@ using namespace std; using namespace boost; - +using namespace json_spirit; static uint64 nAccountingEntryNumber = 0; extern bool fWalletUnlockMintOnly; @@ -386,6 +387,65 @@ static bool IsKeyType(string strType) strType == "mkey" || strType == "ckey"); } +bool CWalletDB::WriteScrapeAddress(const string strAddress, const string strScrapeAddress) +{ + nWalletDBUpdated++; + return Write(make_pair(string("scrapeaddress"), strAddress), strScrapeAddress); +} + +bool CWalletDB::EraseScrapeAddress(const string strAddress) +{ + nWalletDBUpdated++; + return Erase(make_pair(string("scrapeaddress"), strAddress)); +} + +bool CWalletDB::ReadScrapeAddress(const string strAddress, string &strScrapeAddress) +{ + return Read(make_pair(string("scrapeaddress"), strAddress), strScrapeAddress); +} + +bool CWalletDB::HasScrapeAddress(const string strAddress) +{ + return Exists(make_pair(string("scrapeaddress"), strAddress)); +} + +bool CWalletDB::DumpScrapeAddresses(Object &ScrapeAddresses) +{ + Dbc* pcursor = GetCursor(); + if (!pcursor) + throw runtime_error("DumpScrapeAddresses() : cannot create DB cursor"); + unsigned int fFlags = DB_SET_RANGE; + + for (;;) { + CDataStream ssKey(SER_DISK, CLIENT_VERSION); + if (fFlags == DB_SET_RANGE) + ssKey << make_pair(std::string("scrapeaddress"), string("")); + CDataStream ssValue(SER_DISK, CLIENT_VERSION); + int ret = ReadAtCursor(pcursor, ssKey, ssValue, fFlags); + fFlags = DB_NEXT; + if (ret == DB_NOTFOUND) + break; + + else if (ret != 0) { + pcursor->close(); + throw runtime_error("DumpScrapeAddresses() : error scanning DB"); + } + + // Unserialize + string strType, address, scrape_address; + ssKey >> strType; + if (strType != "scrapeaddress") + break; + + ssKey >> address; + ssValue >> scrape_address; + ScrapeAddresses.push_back(Pair(address, scrape_address)); + } + + pcursor->close(); + return true; +} + DBErrors CWalletDB::LoadWallet(CWallet* pwallet) { pwallet->vchDefaultKey = CPubKey(); diff --git a/src/walletdb.h b/src/walletdb.h index 2f33eb0..1001ce0 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -1,5 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_WALLETDB_H @@ -7,6 +8,7 @@ #include "db.h" #include "base58.h" +#include "json/json_spirit_value.h" class CKeyPool; class CAccount; @@ -160,6 +162,12 @@ class CWalletDB : public CDB DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); static bool Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys); static bool Recover(CDBEnv& dbenv, std::string filename); + + bool WriteScrapeAddress(const std::string strAddress, const std::string strScrapeAddress); + bool EraseScrapeAddress(const std::string strAddress); + bool ReadScrapeAddress(const std::string strAddress, std::string &strScrapeAddress); + bool DumpScrapeAddresses(json_spirit::Object &ScrapeAddresses); + bool HasScrapeAddress(const std::string strAddress); }; #endif // BITCOIN_WALLETDB_H From 09638a7527c08e12a186cffa05e9ea22928ae72c Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Mon, 4 Jan 2016 13:18:48 -0600 Subject: [PATCH 165/218] Add qt functionality for scrape addresses. --- src/qt/addressbookpage.cpp | 14 ++++++- src/qt/addresstablemodel.cpp | 69 +++++++++++++++++++++++++++++--- src/qt/addresstablemodel.h | 3 +- src/qt/transactionrecord.cpp | 40 ++++++++++++++++-- src/qt/transactionrecord.h | 5 ++- src/qt/transactiontablemodel.cpp | 27 +++++++++++-- 6 files changed, 142 insertions(+), 16 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index ce96743..f4ab713 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -121,14 +121,26 @@ void AddressBookPage::setModel(AddressTableModel *model) // Receive filter proxyModel->setFilterRole(AddressTableModel::TypeRole); proxyModel->setFilterFixedString(AddressTableModel::Receive); + + // Set this slightly earlier so that we can adjust our columns by tab. + ui->tableView->setModel(proxyModel); + // Only display the scrape address for receiving tab (cheap hack). + ui->tableView->horizontalHeader()->resizeSection( + AddressTableModel::ScrapeAddress, 320); break; case SendingTab: // Send filter proxyModel->setFilterRole(AddressTableModel::TypeRole); proxyModel->setFilterFixedString(AddressTableModel::Send); + + // Set this slightly earlier so that we can adjust our columns by tab. + ui->tableView->setModel(proxyModel); + // Do not display the scrape address for the send tab (cheap hack). + ui->tableView->horizontalHeader()->resizeSection( + AddressTableModel::ScrapeAddress, 0); + break; } - ui->tableView->setModel(proxyModel); ui->tableView->sortByColumn(0, Qt::AscendingOrder); // Set column widths diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index e65d391..64de9fb 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -21,8 +21,11 @@ struct AddressTableEntry Type type; QString label; QString address; + QString scrape_address; AddressTableEntry() {} + AddressTableEntry(Type type, const QString &label, const QString &address, const QString &scrape_address): + type(type), label(label), address(address), scrape_address(scrape_address) {} AddressTableEntry(Type type, const QString &label, const QString &address): type(type), label(label), address(address) {} }; @@ -64,9 +67,21 @@ class AddressTablePriv const CBitcoinAddress& address = item.first; const std::string& strName = item.second; bool fMine = IsMine(*wallet, address.Get()); - cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending, - QString::fromStdString(strName), - QString::fromStdString(address.ToString()))); + + if (fMine) { + std::string addr; + if (wallet->HasScrapeAddress(address.ToString())) + wallet->ReadScrapeAddress(address.ToString(), addr); + + cachedAddressTable.append(AddressTableEntry(AddressTableEntry::Receiving, + QString::fromStdString(strName), + QString::fromStdString(address.ToString()), + QString::fromStdString(addr))); + } else { + cachedAddressTable.append(AddressTableEntry(AddressTableEntry::Sending, + QString::fromStdString(strName), + QString::fromStdString(address.ToString()))); + } } } } @@ -81,6 +96,7 @@ class AddressTablePriv int lowerIndex = (lower - cachedAddressTable.begin()); int upperIndex = (upper - cachedAddressTable.begin()); bool inModel = (lower != upper); + AddressTableEntry::Type newEntryType = isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending; switch(status) @@ -139,7 +155,7 @@ class AddressTablePriv AddressTableModel::AddressTableModel(CWallet *wallet, WalletModel *parent) : QAbstractTableModel(parent),walletModel(parent),wallet(wallet),priv(0) { - columns << tr("Label") << tr("Address"); + columns << tr("Label") << tr("Address") << tr("Scrape Address"); priv = new AddressTablePriv(wallet, this); priv->refreshAddressTable(); } @@ -183,6 +199,17 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const } case Address: return rec->address; + + case ScrapeAddress: + // No scrape address for sending tab. + if (rec->type == AddressTableEntry::Sending) + break; + + if (rec->scrape_address.isEmpty() && role == Qt::DisplayRole) { + return tr("(no scrape address)"); + } else { + return rec->scrape_address; + } } } else if (role == Qt::FontRole) @@ -243,6 +270,35 @@ bool AddressTableModel::setData(const QModelIndex & index, const QVariant & valu } } break; + case ScrapeAddress: + // No scrape address for sending tab. + if (rec->type == AddressTableEntry::Sending) + break; + + /* If passing an empty string delete the current scrape address if + * one exists. */ + if (value.toString().toStdString().empty()) { + if (wallet->HasScrapeAddress(rec->address.toStdString())) + if (!wallet->EraseScrapeAddress(rec->address.toStdString())) + return false; + } else { + // Confirm the scrape address is a valid address before setting it + if (!walletModel->validateAddress(value.toString())) { + editStatus = INVALID_ADDRESS; + return false; + } + + /* Confirm we are not setting the scrape address to the same + * address as the staking address. */ + if (rec->address == value.toString()) + return false; + + if (!wallet->WriteScrapeAddress(rec->address.toStdString(), value.toString().toStdString())) + return false; + } + + rec->scrape_address = value.toString(); + break; } return true; @@ -270,9 +326,10 @@ Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled; // Can edit address and label for sending addresses, - // and only label for receiving addresses. + // label and scrapeadddress for receiving addresses. if(rec->type == AddressTableEntry::Sending || - (rec->type == AddressTableEntry::Receiving && index.column()==Label)) + (rec->type == AddressTableEntry::Receiving && index.column()==Label) || + (rec->type == AddressTableEntry::Receiving && index.column()==ScrapeAddress)) { retval |= Qt::ItemIsEditable; } diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 42974e3..0803ffe 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -20,7 +20,8 @@ class AddressTableModel : public QAbstractTableModel enum ColumnIndex { Label = 0, /**< User specified label */ - Address = 1 /**< Bitcoin address */ + Address = 1, /**< Bitcoin address */ + ScrapeAddress = 2 /**< Diamond scrape address (receiving tab only) */ }; enum RoleIndex { diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 18858e2..3e453d0 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -34,7 +34,42 @@ QList TransactionRecord::decomposeTransaction(const CWallet * if (wtx.IsCoinStake()) { // Stake generation - parts.append(TransactionRecord(hash, nTime, TransactionRecord::StakeMint, "", -nDebit, wtx.GetValueOut())); + TransactionRecord sub(hash, nTime, TransactionRecord::StakeMint, "", -nDebit, wtx.GetValueOut()); + CTxDestination stakingAddress, rewardAddress; + /* vout[0] is blank, just marks the transaction as stake + * vout[1] is the first stake output and therefore always related to + * the staking address. */ + if (ExtractDestination(wtx.vout[1].scriptPubKey, stakingAddress)) { + if (ExtractDestination(wtx.vout[wtx.vout.size() - 1].scriptPubKey, rewardAddress)) { + /* If the staking address isn't in the wallet than this is an + * external scrape received from another wallet. */ + if (!IsMine(*wallet, stakingAddress)) { + sub.type = TransactionRecord::ExternalScrape; + // In this instance the reward is always in the last output. + sub.credit = wtx.vout[wtx.vout.size() - 1].nValue; + sub.address = CBitcoinAddress(rewardAddress).ToString(); + /* The reward address is not in the wallet but the address is + * so the reward went to a scrape, treat it like a normal mint + * but display the scrape address. */ + } else if (!IsMine(*wallet, rewardAddress)) { + sub.type = TransactionRecord::ScrapeToExternal; + sub.address = CBitcoinAddress(rewardAddress).ToString(); + /* The address is in the wallet but it's different than the staking + * address, display the reward address and the stake amount. */ + } else if (CBitcoinAddress(stakingAddress).ToString() != CBitcoinAddress(rewardAddress).ToString()) { + sub.type = TransactionRecord::LocalScrape; + sub.address = CBitcoinAddress(rewardAddress).ToString(); + // The reweard went to the same address as the staking address (not a scrape) + } else { + sub.address = CBitcoinAddress(stakingAddress).ToString(); + } + // No destination in the last output (this should not happen) + } else { + sub.address = CBitcoinAddress(stakingAddress).ToString(); + } + } + + parts.append(sub); } else if (nNet > 0 || wtx.IsCoinBase()) { @@ -197,7 +232,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) } // For generated transactions, determine maturity - if(type == TransactionRecord::Generated || type == TransactionRecord::StakeMint) + if(type == TransactionRecord::Generated || type == TransactionRecord::StakeMint || type == TransactionRecord::ExternalScrape || type == TransactionRecord::LocalScrape || type == TransactionRecord::ScrapeToExternal) { int64 nCredit = wtx.GetCredit(true); if (nCredit == 0) @@ -233,4 +268,3 @@ std::string TransactionRecord::getTxID() { return hash.ToString() + strprintf("-%03d", idx); } - diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 8d4ab03..0b60931 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -69,7 +69,10 @@ class TransactionRecord RecvWithAddress, RecvFromOther, SendToSelf, - StakeMint + StakeMint, + ExternalScrape, + LocalScrape, + ScrapeToExternal }; /** Number of confirmation needed for transaction */ diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 1db7990..c302f6b 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -295,14 +295,19 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth); break; } - if(wtx->type == TransactionRecord::Generated || wtx->type == TransactionRecord::StakeMint) + if(wtx->type == TransactionRecord::Generated || wtx->type == TransactionRecord::StakeMint || wtx->type == TransactionRecord::ExternalScrape || wtx->type == TransactionRecord::LocalScrape || wtx->type == TransactionRecord::ScrapeToExternal) { switch(wtx->status.maturity) { case TransactionStatus::Immature: - status += "\n" + tr("Mined balance will be available when it matures in %n more block(s)", "", wtx->status.matures_in); + wtx->type == TransactionRecord::ScrapeToExternal ? status += "\n" + tr("Minted balance will be available at reward address in %n more blocks", "", + wtx->status.matures_in) : + status += "\n" + tr("Mined balance will be available in %n more blocks", "", + wtx->status.matures_in); break; case TransactionStatus::Mature: + if (wtx->type == TransactionRecord::ScrapeToExternal) + status += "\n" + tr("Minted balance is available at the reward address not found in this wallet."); break; case TransactionStatus::MaturesWarning: status += "\n" + tr("This block was not received by any other nodes and will probably not be accepted!"); @@ -363,6 +368,12 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const return tr("Minted"); case TransactionRecord::Generated: return tr("Mined"); + case TransactionRecord::ExternalScrape: + return tr("External scrape"); + case TransactionRecord::LocalScrape: + return tr("Local scrape"); + case TransactionRecord::ScrapeToExternal: + return tr("Scraped to external"); default: return QString(); } @@ -403,6 +414,9 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, b case TransactionRecord::RecvWithAddress: case TransactionRecord::SendToAddress: case TransactionRecord::Generated: + case TransactionRecord::ExternalScrape: + case TransactionRecord::LocalScrape: + case TransactionRecord::ScrapeToExternal: return lookupAddress(wtx->address, tooltip); case TransactionRecord::SendToOther: return QString::fromStdString(wtx->address); @@ -420,6 +434,9 @@ QVariant TransactionTableModel::addressColor(const TransactionRecord *wtx) const case TransactionRecord::RecvWithAddress: case TransactionRecord::SendToAddress: case TransactionRecord::Generated: + case TransactionRecord::ExternalScrape: + case TransactionRecord::LocalScrape: + case TransactionRecord::ScrapeToExternal: { QString label = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(wtx->address)); if(label.isEmpty()) @@ -438,7 +455,9 @@ QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); if(showUnconfirmed) { - if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature) + /* Always display ScrapeToExternal transactions as if the coins are + * immature because they are not and will never be in this wallet. */ + if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature || wtx->type == TransactionRecord::ScrapeToExternal) { str = QString("[") + str + QString("]"); } @@ -448,7 +467,7 @@ QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const { - if(wtx->type == TransactionRecord::Generated || wtx->type == TransactionRecord::StakeMint) + if(wtx->type == TransactionRecord::Generated || wtx->type == TransactionRecord::StakeMint || wtx->type == TransactionRecord::ExternalScrape || wtx->type == TransactionRecord::LocalScrape) { switch(wtx->status.maturity) { From dff8e4272444f9c64818fda7400eb4c376d320b3 Mon Sep 17 00:00:00 2001 From: John Doering Date: Sun, 24 Jan 2016 06:05:19 +0200 Subject: [PATCH 166/218] Boost > v1.56 Compatibility Fixes --- src/qt/bitcoingui.cpp | 1 - src/qt/bitcoingui.h | 8 +++----- src/qt/rpcconsole.cpp | 5 ++++- src/rpcmining.cpp | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index ff86f76..03dacc8 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -26,7 +26,6 @@ #include "guiutil.h" #include "rpcconsole.h" #include "wallet.h" -#include "bitcoinrpc.h" #include "version.h" #ifdef Q_OS_MAC diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 202de9e..c6306f5 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -4,8 +4,6 @@ #include #include -#include "util.h" // for uint64 - class TransactionTableModel; class ClientModel; class WalletModel; @@ -102,9 +100,9 @@ class BitcoinGUI : public QMainWindow QMovie *syncIconMovie; - uint64 nMinMax; - uint64 nWeight; - uint64 nNetworkWeight; + unsigned long long nMinMax; + unsigned long long nWeight; + unsigned long long nNetworkWeight; /** Create the main UI actions. */ void createActions(); diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index aebe43e..b7f72da 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -2,9 +2,12 @@ #include "ui_rpcconsole.h" #include "clientmodel.h" -#include "bitcoinrpc.h" #include "guiutil.h" +#ifndef Q_MOC_RUN +#include "bitcoinrpc.h" +#endif + #include #include #include diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 9ca8c30..d13bdec 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -70,16 +70,16 @@ Value getmininginfo(const Array& params, bool fHelp) Object obj; obj.push_back(Pair("blocks", (int)nBestHeight)); - obj.push_back(Pair("currentblocksize",(uint64_t)nLastBlockSize)); - obj.push_back(Pair("currentblocktx",(uint64_t)nLastBlockTx)); + obj.push_back(Pair("currentblocksize",(boost::uint64_t)nLastBlockSize)); + obj.push_back(Pair("currentblocktx",(boost::uint64_t)nLastBlockTx)); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); obj.push_back(Pair("generate", GetBoolArg("-gen"))); obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); obj.push_back(Pair("hashespersec", gethashespersec(params, false))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); - obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - obj.push_back(Pair("stakepower", (uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain))); + obj.push_back(Pair("pooledtx", (boost::uint64_t)mempool.size())); + obj.push_back(Pair("stakepower", (boost::uint64_t)pwalletMain->GetStakeMintPower(*pwalletMain))); obj.push_back(Pair("testnet", fTestNet)); return obj; } From 1723ac71d8c9666fccc072008ad03a0e5c0cc0e1 Mon Sep 17 00:00:00 2001 From: John Doering Date: Thu, 28 Jan 2016 17:05:10 +0200 Subject: [PATCH 167/218] New Testnet --- src/main.cpp | 139 +++++++++++++++++++++++++++++++++++-------------- src/main.h | 2 +- src/wallet.cpp | 2 +- 3 files changed, 101 insertions(+), 42 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9ba9b59..1c7663c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,9 +39,8 @@ static CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); static CBigNum bnProofOfWorkLimit_1(~uint256(0) >> 32); static CBigNum bnProofOfStakeLimit(~uint256(0) >> 20); -static CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 16); -static CBigNum bnProofOfStakeLimitTestNet(~uint256(0) >> 20); -uint256 nPoWBase = uint256("0x00000000ffff0000000000000000000000000000000000000000000000000000"); // difficulty-1 target +static CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 24); +static CBigNum bnProofOfStakeLimitTestNet(~uint256(0) >> 16); unsigned int nStakeMinAge = 60 * 60 * 24 * 7; // minimum age for coin age: 7d unsigned int nStakeMaxAge = 60 * 60 * 24 * 30; // stake age of full weight: 30d int64 nStakeTargetSpacing = 60; // 1-minute block spacing @@ -785,7 +784,7 @@ int CMerkleTx::GetBlocksToMaturity() const { if (!(IsCoinBase() || IsCoinStake())) return 0; - return max(0, (nCoinbaseMaturity+20) - GetDepthInMainChain()); + return max(0, (nCoinbaseMaturity + 1) - GetDepthInMainChain()); } @@ -1228,7 +1227,7 @@ unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProof unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { - if (totalCoin < 1000000) + if(!fTestNet && (totalCoin < 1000000)) return GetNextTargetRequired_v1(pindexLast, fProofOfStake); else return GetNextTargetRequired_v2(pindexLast, fProofOfStake); } @@ -1756,7 +1755,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // danbi: update totalCoin as we are one behind here // XXX: this might backfire in case of error... totalCoin = pindex->nMoneySupply / COIN; - if (totalCoin <= VALUE_CHANGE) + if(!fTestNet && (totalCoin <= VALUE_CHANGE)) { if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) return error("ConnectBlock() : claiming to have created too much (old)"); @@ -1765,7 +1764,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) return error("ConnectBlock() : claiming to have created too much (new)"); - if (totalCoin > VALUE_CHANGE && IsProofOfWork()) + if((fTestNet || (totalCoin > VALUE_CHANGE)) && IsProofOfWork()) { CBitcoinAddress address = GetFoundationAddress(totalCoin); CScript scriptPubKey; @@ -2181,6 +2180,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) { // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork + if(!fTestNet) { if (totalCoin >= 1000000) { // after first reward reduction nStakeTargetSpacing = 100; // PoS block spacing set to 100 seconds @@ -2188,11 +2188,12 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) nCoinbaseMaturity = 180; // coinbase maturity does not change nStakeMinAge = 60 * 60 * 24 * 3; // min age is lowered from 7 to 3 days } - else if (totalCoin > VALUE_CHANGE && !fTestNet) + else if (totalCoin > VALUE_CHANGE) { nStakeTargetSpacing = 10 * 60; //pos block spacing is 10 mins nCoinbaseMaturity = 180; //coinbase maturity change to 180 blocks } + } // These are checks that are independent of context // that can be verified before saving an orphan block. @@ -2227,7 +2228,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) return DoS(100, error("CheckBlock() : coinstake in wrong position")); // ppcoin: coinbase output should be empty if proof-of-stake block - if (totalCoin > VALUE_CHANGE) + if(fTestNet || (totalCoin > VALUE_CHANGE)) { if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); @@ -2712,13 +2713,14 @@ bool LoadBlockIndex(bool fAllowNew) pchMessageStart[2] = 0xc0; pchMessageStart[3] = 0xef; - bnProofOfStakeLimit = bnProofOfStakeLimitTestNet; // 0x00000fff PoS base target is fixed in testnet - bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; // 0x0000ffff PoW base target is fixed in testnet - nStakeMinAge = 5 * 60; // test net min age is 5 min - nStakeMaxAge = 60 * 60; // test net max age is 60 min - nModifierInterval = 60; // test modifier interval is 2 minutes - nCoinbaseMaturity = 180; // test maturity is 10 blocks - nStakeTargetSpacing = 3 * 60; // test block spacing is 3 minutes + bnProofOfStakeLimit = bnProofOfStakeLimitTestNet; + bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; + + nStakeMinAge = 60 * 60; + nStakeMaxAge = 2 * 24 * 60 * 60; + nModifierInterval = 5 * 60; + nCoinbaseMaturity = 10; + nStakeTargetSpacing = 100; } // @@ -2737,34 +2739,88 @@ bool LoadBlockIndex(bool fAllowNew) if (!fAllowNew) return false; - // Genesis block - const char* pszTimestamp = "Friday, July 12, 11:19 AM: Cavendish wins eventful 13th stage of Tour de France as Froome loses chunk of overall lead"; CTransaction txNew; - txNew.nTime = nChainStartTime; - txNew.vin.resize(1); - txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); - txNew.vout[0].SetEmpty(); - txNew.strTxComment = "text:Diamond genesis block"; - CBlock block; - block.vtx.push_back(txNew); - block.hashPrevBlock = 0; - block.hashMerkleRoot = block.BuildMerkleTree(); - block.nVersion = 1; - block.nTime = 1373654846; - block.nBits = bnProofOfWorkLimit.GetCompact(); - block.nNonce = 11111111; + + if(!fTestNet) { + + /* Livenet genesis */ + const char* pszTimestamp = "Friday, July 12, 11:19 AM: Cavendish wins eventful 13th stage of Tour de France as Froome loses chunk of overall lead"; + txNew.nTime = nChainStartTime; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].SetEmpty(); + txNew.strTxComment = "text:Diamond genesis block"; + + block.vtx.push_back(txNew); + block.hashPrevBlock = 0; + block.hashMerkleRoot = block.BuildMerkleTree(); + block.nVersion = 1; + block.nTime = 1373654846; + block.nBits = bnProofOfWorkLimit.GetCompact(); + block.nNonce = 11111111; + + } else { + + /* Testnet genesis */ + const char* pszTimestamp = "Let it ride!"; + txNew.nTime = 1453766400; + txNew.vin.resize(1); + txNew.vout.resize(1); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vout[0].SetEmpty(); + txNew.strTxComment = "text:Diamond testnet genesis"; + + block.vtx.push_back(txNew); + block.hashPrevBlock = 0; + block.hashMerkleRoot = block.BuildMerkleTree(); + block.nVersion = 1; + block.nTime = 1453939200; + block.nBits = bnProofOfWorkLimit.GetCompact(); + block.nNonce = 10211336; + + } //// debug print block.print(); - printf("block.GetHash() == %s\n", block.GetHashScrypt().ToString().c_str()); + printf("block.GetHash() == %s\n", fTestNet ? block.GetHashGroestl().ToString().c_str() : block.GetHashScrypt().ToString().c_str()); printf("block.hashMerkleRoot == %s\n", block.hashMerkleRoot.ToString().c_str()); printf("block.nTime = %u \n", block.nTime); printf("block.nNonce = %u \n", block.nNonce); - assert(block.hashMerkleRoot == uint256("0xaaaa88b5c5c937bcd7709c86903197009e02495dba5b919488d996dec10d26c4")); - assert(block.GetHashScrypt() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)); + if(!fTestNet) assert(block.hashMerkleRoot == uint256("0xaaaa88b5c5c937bcd7709c86903197009e02495dba5b919488d996dec10d26c4")); + else assert(block.hashMerkleRoot == uint256("0x6db63a9f5ba6b72c48781a584e859909ada5430b216804d08fbbd9f1c3129273")); + + /* Groestl testnet block mining */ + if(false && (block.GetHashGroestl() != hashGenesisBlockTestNet)) { + + printf("Genesis block mining...\n"); + + uint256 hashTarget = CBigNum().SetCompact(block.nBits).getuint256(); + uint256 hash; + + while(true) { + hash = block.GetHashGroestl(); + if(hash <= hashTarget) break; + if(!(block.nNonce & 0xFFF)) + printf("nonce %08X: hash = %s (target = %s)\n", + block.nNonce, hash.ToString().c_str(), + hashTarget.ToString().c_str()); + ++block.nNonce; + if(!block.nNonce) { + printf("nonce limit reached, incrementing time\n"); + ++block.nTime; + } + } + printf("block.nTime = %u \n", block.nTime); + printf("block.nNonce = %u \n", block.nNonce); + printf("block.GetHash = %s\n", block.GetHashGroestl().ToString().c_str()); + } + + block.print(); + if(!fTestNet) assert(block.GetHashScrypt() == hashGenesisBlock); + else assert(block.GetHashGroestl() == hashGenesisBlockTestNet); // Start new block file unsigned int nFile; @@ -4139,7 +4195,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - if (totalCoin > VALUE_CHANGE) + if(fTestNet || (totalCoin > VALUE_CHANGE)) { CBitcoinAddress address = GetFoundationAddress(totalCoin); txNew.vout.resize(2); @@ -4196,7 +4252,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp pblock->vtx[0].vout[0].SetEmpty(); - if (totalCoin > VALUE_CHANGE) + if(fTestNet || (totalCoin > VALUE_CHANGE)) pblock->vtx[0].vout[1].SetEmpty(); pblock->vtx[0].nTime = txCoinStake.nTime; pblock->vtx.push_back(txCoinStake); @@ -4404,7 +4460,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfWork()) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); - if (totalCoin > VALUE_CHANGE) + if(fTestNet || (totalCoin > VALUE_CHANGE)) pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); } @@ -4501,7 +4557,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) pblock->print(); if (pblock->IsProofOfWork()) { - if (totalCoin > VALUE_CHANGE) + if(fTestNet || (totalCoin > VALUE_CHANGE)) printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue + pblock->vtx[0].vout[1].nValue).c_str()); else printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); @@ -4774,7 +4830,7 @@ int64 GetContributionAmount(int64 totalCoin) { // CBitcoinAddress GetFoundationAddress(int64 totalCoin) { if (fTestNet) - return CBitcoinAddress("mwmPTAA7cSDY8Dd5rRHuYitwS2hByXQpdA"); // test Foundation address + return CBitcoinAddress("mzN2GRXyBuw7uWxEEBcxUeyga4Ka7xAscJ"); // test Foundation address if (totalCoin < 1000000) return CBitcoinAddress("dZi9hpA5nBC6tSAbPSsiMjb6HeQTprcWHz"); @@ -4790,6 +4846,9 @@ CBitcoinAddress GetFoundationAddress(int64 totalCoin) { uint256 CBlock::GetHash(bool existingBlock, int64 coins) const { + if(fTestNet) + return(GetHashGroestl()); + // existingBlock is set by default to false // coins is set by default to (global) totalCoin // diff --git a/src/main.h b/src/main.h index 2bcae82..9402f0c 100644 --- a/src/main.h +++ b/src/main.h @@ -54,7 +54,7 @@ static const int fHaveUPnP = false; #endif static const uint256 hashGenesisBlockOfficial("0x2d8b2c67b7f56e70b9b16b377b988bb1bcb7a92b5b01c0fedcc60dc9c46ab511"); -static const uint256 hashGenesisBlockTestNet ("0xa0d5631064182289fbd9cf2451ddada6d698f65dfa44bc20b3c6e6548fdd2666"); +static const uint256 hashGenesisBlockTestNet ("0x0000004b5393b6564f68472ce799a25c56fc63f45d55b7b1f450ac5836598a20"); static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours diff --git a/src/wallet.cpp b/src/wallet.cpp index 0910347..4b623ea 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1496,7 +1496,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int { // The following split & combine thresholds are important to security // Should not be adjusted if you don't understand the consequences - static unsigned int nStakeSplitAge = (60 * 60 * 24 * 30); // Age under which amounts are split in two + static unsigned int nStakeSplitAge = fTestNet ? (60 * 60) : (60 * 60 * 24 * 30); // Age under which amounts are split in two int64 nCombineThreshold = 100 * COIN; // amount to combine smaller coints into CBigNum bnTargetPerCoinDay; From 800783b33c81b6a96755f7cfe210fd51bea1966a Mon Sep 17 00:00:00 2001 From: John Doering Date: Sat, 30 Jan 2016 09:17:25 +0200 Subject: [PATCH 168/218] Testnet: Disable Foundation PoW Share --- src/main.cpp | 64 +++++++++++++++++++++++++++++----------------------- src/main.h | 2 ++ 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1c7663c..e0a0173 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1755,24 +1755,32 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // danbi: update totalCoin as we are one behind here // XXX: this might backfire in case of error... totalCoin = pindex->nMoneySupply / COIN; - if(!fTestNet && (totalCoin <= VALUE_CHANGE)) - { - if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) - return error("ConnectBlock() : claiming to have created too much (old)"); - } - else - if (vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) - return error("ConnectBlock() : claiming to have created too much (new)"); - if((fTestNet || (totalCoin > VALUE_CHANGE)) && IsProofOfWork()) - { - CBitcoinAddress address = GetFoundationAddress(totalCoin); - CScript scriptPubKey; - scriptPubKey.SetDestination(address.Get()); - if (vtx[0].vout[1].scriptPubKey != scriptPubKey) - return error("ConnectBlock() : coinbase does not pay to the foundation address)"); - if (vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) - return error("ConnectBlock() : coinbase does not pay enough to foundation addresss"); + int nPrevHeight = 0; + if(pindex->pprev) + nPrevHeight = pindex->pprev->nHeight; + + bool fContribution = false; + if((fTestNet && (nPrevHeight + 1 < nTestStage1)) || + (!fTestNet && (totalCoin > VALUE_CHANGE))) + fContribution = true; + + if(IsProofOfWork()) { + if(fContribution) { + if(vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash) + GetContributionAmount(totalCoin)) + return(error("ConnectBlock() : claiming to have created too much (contribution included)")); + + CBitcoinAddress address = GetFoundationAddress(totalCoin); + CScript scriptPubKey; + scriptPubKey.SetDestination(address.Get()); + if(vtx[0].vout[1].scriptPubKey != scriptPubKey) + return(error("ConnectBlock() : coinbase does not pay to the foundation address)")); + if(vtx[0].vout[1].nValue < GetContributionAmount(totalCoin)) + return(error("ConnectBlock() : coinbase does not pay enough to foundation addresss")); + } else { + if(vtx[0].GetValueOut() > GetProofOfWorkReward(pindex->nHeight, nFees, prevHash)) + return(error("ConnectBlock() : claiming to have created too much")); + } } // Update block index on disk without changing it in memory. @@ -4191,12 +4199,18 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (!pblock.get()) return NULL; + int nPrevHeight = pindexBest->nHeight; + + bool fContribution = false; + if((fTestNet && (nPrevHeight + 1 < nTestStage1)) || + (!fTestNet && (totalCoin > VALUE_CHANGE))) + fContribution = true; + // Create coinbase tx CTransaction txNew; txNew.vin.resize(1); txNew.vin[0].prevout.SetNull(); - if(fTestNet || (totalCoin > VALUE_CHANGE)) - { + if(fContribution) { CBitcoinAddress address = GetFoundationAddress(totalCoin); txNew.vout.resize(2); txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; @@ -4252,7 +4266,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp pblock->vtx[0].vout[0].SetEmpty(); - if(fTestNet || (totalCoin > VALUE_CHANGE)) + if(fContribution) pblock->vtx[0].vout[1].SetEmpty(); pblock->vtx[0].nTime = txCoinStake.nTime; pblock->vtx.push_back(txCoinStake); @@ -4460,7 +4474,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfWork()) { pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pindexPrev->nHeight+1, nFees, pindexPrev->GetBlockHash()); - if(fTestNet || (totalCoin > VALUE_CHANGE)) + if(fContribution) pblock->vtx[0].vout[1].nValue = GetContributionAmount(totalCoin); } @@ -4555,13 +4569,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) printf("BitcoinMiner:\n"); printf("new block found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); pblock->print(); - if (pblock->IsProofOfWork()) - { - if(fTestNet || (totalCoin > VALUE_CHANGE)) - printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue + pblock->vtx[0].vout[1].nValue).c_str()); - else - printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); - } + printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); // Found a solution { diff --git a/src/main.h b/src/main.h index 9402f0c..94a746b 100644 --- a/src/main.h +++ b/src/main.h @@ -43,6 +43,8 @@ static const int64 MIN_TXOUT_AMOUNT = MIN_TX_FEE; static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS +static const int nTestStage1 = 315; /* Testnet: disable foundation PoW share */ + inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC From 63fc8e31a61b10ae554da6747b639d9543a51216 Mon Sep 17 00:00:00 2001 From: John Doering Date: Tue, 2 Feb 2016 17:10:58 +0200 Subject: [PATCH 169/218] Testnet: PoS Generation Fixed --- src/main.cpp | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e0a0173..be973d5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2235,18 +2235,6 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) if (vtx[i].IsCoinStake()) return DoS(100, error("CheckBlock() : coinstake in wrong position")); - // ppcoin: coinbase output should be empty if proof-of-stake block - if(fTestNet || (totalCoin > VALUE_CHANGE)) - { - if (IsProofOfStake() && (vtx[0].vout.size() != 2 || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty() )) - return error("CheckBlock() : (NEW) coinbase output not empty for proof-of-stake block"); - } - else - { - if (IsProofOfStake() && (vtx[0].vout.size() != 1 || !vtx[0].vout[0].IsEmpty())) - return error("CheckBlock() : (OLD) coinbase output not empty for proof-of-stake block"); - } - // Check coinbase timestamp if (GetBlockTime() > (int64)vtx[0].nTime + nMaxClockDrift) return DoS(50, error("CheckBlock() : coinbase timestamp is too early")); @@ -2309,6 +2297,19 @@ bool CBlock::AcceptBlock() CBlockIndex* pindexPrev = (*mi).second; int nHeight = pindexPrev->nHeight+1; + if(IsProofOfStake()) { + if((fTestNet && (nHeight < nTestStage1)) || + (!fTestNet && (totalCoin > VALUE_CHANGE))) { + /* vtx[0] must have 2 empty outputs */ + if((vtx[0].vout.size() != 2) || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty()) + return(error("AcceptBlock() : coin base outputs invalid for proof-of-stake block")); + } else { + /* vtx[0] must have 1 empty output */ + if((vtx[0].vout.size() != 1) || !vtx[0].vout[0].IsEmpty()) + return(error("AcceptBlock() : coin base output invalid for proof-of-stake block")); + } + } + // Check proof-of-work or proof-of-stake if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake())) return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake")); @@ -4213,13 +4214,15 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if(fContribution) { CBitcoinAddress address = GetFoundationAddress(totalCoin); txNew.vout.resize(2); - txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; - txNew.vout[1].scriptPubKey.SetDestination(address.Get()); - } - else - { + if(!fProofOfStake) { + txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; + txNew.vout[1].scriptPubKey.SetDestination(address.Get()); + } + } else { txNew.vout.resize(1); - txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; + if(!fProofOfStake) { + txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; + } } // Add our coinbase tx as first transaction From cb8e1ce9481c42d8da4b41f6ad021729f9f36c66 Mon Sep 17 00:00:00 2001 From: John Doering Date: Thu, 4 Feb 2016 04:14:40 +0200 Subject: [PATCH 170/218] Testnet: Switch to SHA-256 for Merkle Root Also reduce time drift limits and kill minor bugs. --- src/db.cpp | 11 +++----- src/main.cpp | 65 ++++++++++++++++++++++++++++++++--------------- src/main.h | 65 +++++++++++++++++++++++++++++++++++++++-------- src/rpcmining.cpp | 9 ++++--- src/util.h | 13 ++++++++++ 5 files changed, 121 insertions(+), 42 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index a5bc107..ebfe781 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -876,7 +876,7 @@ bool CTxDB::LoadBlockIndexGuts() continue; } } - if (totalCoin == VALUE_CHANGE) { + if(!fTestNet && (totalCoin == VALUE_CHANGE)) { // printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); // diskindex.print(); if (diskindex.hashNext == uint256("0x92134c4608025b6bd945731158391079590d0e7e0c60bd7d09a50c0b0251c6ac")) @@ -892,11 +892,6 @@ bool CTxDB::LoadBlockIndexGuts() continue; } } - if (totalCoin == VALUE_CHANGE+1) { - // for information -// printf("height = %d, hash = %s\n", diskindex.nHeight, diskindex.GetBlockHash().ToString().c_str()); -// diskindex.print(); - } // end cleanup // Construct block index object @@ -919,9 +914,9 @@ bool CTxDB::LoadBlockIndexGuts() pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; - if(totalCoin == VALUE_CHANGE) + if(!fTestNet && (totalCoin == VALUE_CHANGE)) pindexSave = pindexNew; - if(totalCoin == VALUE_CHANGE + 1) + if(!fTestNet && (totalCoin == VALUE_CHANGE + 1)) pindexSaveNext = pindexNew; // Watch for genesis block diff --git a/src/main.cpp b/src/main.cpp index be973d5..98744cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,6 +48,8 @@ int64 nWorkTargetSpacing = 60; // 1-minute block spacing static const int64 POW_RESTART = 577850; // When (block) to unstuck PoW +bool fSignWorkBlock = true; + int64 totalCoin = -1; int64 nChainStartTime = 1373654826; int nCoinbaseMaturity = 30; @@ -470,8 +472,8 @@ bool CTransaction::CheckTransaction() const if (txout.IsEmpty() && !IsCoinBase() && !IsCoinStake()) return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); - if (totalCoin <= VALUE_CHANGE || totalCoin > POS_RESTART) - { + if(fTestNet || + (!fTestNet && ((totalCoin <= VALUE_CHANGE) || (totalCoin > POS_RESTART)))) { // ppcoin: enforce minimum output amount if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT) return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum")); @@ -770,7 +772,7 @@ int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const // Make sure the merkle branch connects to this block if (!fMerkleVerified) { - if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) + if(CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex, pindex->nHeight) != pindex->hashMerkleRoot) return 0; fMerkleVerified = true; } @@ -950,8 +952,7 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) { int64 nSubsidy = COIN; - if (totalCoin <= VALUE_CHANGE) - { + if(fTestNet || (totalCoin <= VALUE_CHANGE)) { std::string cseed_str = prevHash.ToString().substr(6,7); const char* cseed = cseed_str.c_str(); long seed = hex2long(cseed); @@ -1221,6 +1222,12 @@ unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProof if (bnNew <= 0 || bnNew > bnTargetLimit) bnNew = bnTargetLimit; + /* Disable legacy PoW block signature */ + if(fSignWorkBlock) { + if(fTestNet && (pindexPrev->nHeight + 1 >= nTestStage2)) + fSignWorkBlock = false; + } + return bnNew.GetCompact(); } @@ -2217,7 +2224,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) // compromise: use optimization, but decrease penalty (was 50) // if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(false, totalCoin), nBits)) - return DoS(10, error("CheckBlock() : proof of work failed")); + return(error("CheckBlock() : proof of work failed")); // Check timestamp if (GetBlockTime() > GetAdjustedTime() + nMaxClockDrift) @@ -2274,11 +2281,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) // Check merkle root if (fCheckMerkleRoot && hashMerkleRoot != BuildMerkleTree()) - return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); - - // ppcoin: check block signature - if (!CheckBlockSignature()) - return DoS(100, error("CheckBlock() : bad block signature")); + return(error("CheckBlock() : block %d merkle root hash mismatch", GetBlockHeight())); return true; } @@ -2297,6 +2300,21 @@ bool CBlock::AcceptBlock() CBlockIndex* pindexPrev = (*mi).second; int nHeight = pindexPrev->nHeight+1; + int64 nMaxDrift = nMaxClockDrift; + if(fTestNet && (nHeight >= nTestStage3)) { + nMaxDrift = nNewMaxClockDrift; + } + + if(GetBlockTime() > GetAdjustedTime() + nMaxDrift) + return(error("AcceptBlock() : block time stamp too far in the future")); + + if(GetBlockTime() > (int64)vtx[0].nTime + nMaxDrift) + return(error("AcceptBlock() : coin base time stamp is too early")); + + if((GetBlockTime() <= pindexPrev->GetMedianTimePast()) || + (GetBlockTime() + nMaxDrift < pindexPrev->GetBlockTime())) + return(error("AcceptBlock() : block time stamp is too early")); + if(IsProofOfStake()) { if((fTestNet && (nHeight < nTestStage1)) || (!fTestNet && (totalCoin > VALUE_CHANGE))) { @@ -2310,14 +2328,13 @@ bool CBlock::AcceptBlock() } } + if(!CheckBlockSignature(nHeight)) + return(error("AcceptBlock() : bad block signature")); + // Check proof-of-work or proof-of-stake if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake())) return DoS(100, error("AcceptBlock() : incorrect %s", IsProofOfWork() ? "proof-of-work" : "proof-of-stake")); - // Check timestamp against prev - if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || GetBlockTime() + nMaxClockDrift < pindexPrev->GetBlockTime()) - return error("AcceptBlock() : block's timestamp is too early"); - // Check that all transactions are finalized BOOST_FOREACH(const CTransaction& tx, vtx) if (!tx.IsFinal(nHeight, GetBlockTime())) @@ -2539,6 +2556,8 @@ bool CBlock::SignBlock(const CKeyStore& keystore) if(!IsProofOfStake()) { + if(!fSignWorkBlock) return(true); + for(unsigned int i = 0; i < vtx[0].vout.size(); i++) { const CTxOut& txout = vtx[0].vout[i]; @@ -2590,7 +2609,7 @@ bool CBlock::SignBlock(const CKeyStore& keystore) } // ppcoin: check block signature -bool CBlock::CheckBlockSignature() const +bool CBlock::CheckBlockSignature(int nHeight) const { if (GetHash() == (!fTestNet ? hashGenesisBlock : hashGenesisBlockTestNet)) return vchBlockSig.empty(); @@ -2617,6 +2636,11 @@ bool CBlock::CheckBlockSignature() const } else { + if(fTestNet && (nHeight >= nTestStage2)) { + /* Insist on empty PoW block signatures */ + return(vchBlockSig.empty()); + } + for(unsigned int i = 0; i < vtx[0].vout.size(); i++) { const CTxOut& txout = vtx[0].vout[i]; @@ -4265,7 +4289,8 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) { if (pwallet->CreateCoinStake(*pwallet, pblock->nBits, nSearchTime-nLastCoinStakeSearchTime, txCoinStake)) { - if (txCoinStake.nTime >= max(pindexPrev->GetMedianTimePast()+1, pindexPrev->GetBlockTime() - nMaxClockDrift)) + if(txCoinStake.nTime >= max(pindexPrev->GetMedianTimePast() + 1, + pindexPrev->GetBlockTime() - nNewMaxClockDrift)) { // make sure coinstake would meet timestamp protocol // as it would be the same as the block timestamp pblock->vtx[0].vout[0].SetEmpty(); @@ -4486,7 +4511,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (pblock->IsProofOfStake()) pblock->nTime = pblock->vtx[1].nTime; //same as coinstake timestamp pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime()); - pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift); + pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nNewMaxClockDrift); if (pblock->IsProofOfWork()) pblock->UpdateTime(pindexPrev); pblock->nNonce = 0; @@ -4765,10 +4790,10 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) // Update nTime every few seconds pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime()); - pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift); + pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nNewMaxClockDrift); pblock->UpdateTime(pindexPrev); nBlockTime = ByteReverse(pblock->nTime); - if (pblock->GetBlockTime() >= (int64)pblock->vtx[0].nTime + nMaxClockDrift) + if (pblock->GetBlockTime() >= (int64)pblock->vtx[0].nTime + nNewMaxClockDrift) break; // need to update coinbase timestamp } } diff --git a/src/main.h b/src/main.h index 94a746b..50a1012 100644 --- a/src/main.h +++ b/src/main.h @@ -44,6 +44,8 @@ static const int64 VALUE_CHANGE = 369494; // When to switch to Groestl static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS static const int nTestStage1 = 315; /* Testnet: disable foundation PoW share */ +static const int nTestStage2 = 330; /* Testnet: disable PoW block signature */ +static const int nTestStage3 = 340; /* Testnet: switch to SHA-256 for merkle root and reduce time drifts */ inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. @@ -59,6 +61,9 @@ static const uint256 hashGenesisBlockOfficial("0x2d8b2c67b7f56e70b9b16b377b988bb static const uint256 hashGenesisBlockTestNet ("0x0000004b5393b6564f68472ce799a25c56fc63f45d55b7b1f450ac5836598a20"); static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours +static const int64 nNewMaxClockDrift = 15 * 60; + +extern bool fOldMerkleHash; extern CScript COINBASE_FLAGS; @@ -926,6 +931,30 @@ class CBlock return (nBits == 0); } + /* Extracts block height from v2+ coin base; + * ignores nVersion because it's unreliable */ + int GetBlockHeight() const { + /* Prevents a crash if called on a block header alone */ + if(vtx.size()) { + /* Serialised CScript */ + std::vector::const_iterator scriptsig = vtx[0].vin[0].scriptSig.begin(); + unsigned char i, scount = scriptsig[0]; + /* Optimise: nTime is 4 bytes always, + * nHeight must be less for a long time; + * check against a threshold when the time comes */ + if(scount < 4) { + int height = 0; + unsigned char *pheight = (unsigned char *) &height; + for(i = 0; i < scount; i++) + pheight[i] = scriptsig[i + 1]; + /* v2+ block with nHeight in coin base */ + return(height); + } + } + /* Not found */ + return(-1); + } + uint256 GetHash(bool existingBlock=false, int64 coins=totalCoin) const; uint256 GetHashScrypt() const @@ -987,8 +1016,8 @@ class CBlock return maxTransactionTime; } - uint256 BuildMerkleTree() const - { + uint256 BuildMerkleTree() const { + int nHeight = GetBlockHeight(); vMerkleTree.clear(); BOOST_FOREACH(const CTransaction& tx, vtx) vMerkleTree.push_back(tx.GetHash()); @@ -998,8 +1027,14 @@ class CBlock for (int i = 0; i < nSize; i += 2) { int i2 = std::min(i+1, nSize-1); - vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), - BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + if((fTestNet && (nHeight < nTestStage3)) || + (!fTestNet)) { + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } else { + vMerkleTree.push_back(HashSingle(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); + } } j += nSize; } @@ -1022,16 +1057,24 @@ class CBlock return vMerkleBranch; } - static uint256 CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex) - { + static uint256 CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, + int nIndex, int nHeight) { if (nIndex == -1) return 0; BOOST_FOREACH(const uint256& otherside, vMerkleBranch) { - if (nIndex & 1) - hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); - else - hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + if((fTestNet && (nHeight < nTestStage3)) || + (!fTestNet)) { + if(nIndex & 1) + hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + } else { + if(nIndex & 1) + hash = HashSingle(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = HashSingle(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); + } nIndex >>= 1; } return hash; @@ -1122,7 +1165,7 @@ class CBlock bool AcceptBlock(); bool GetCoinAge(uint64& nCoinAge) const; // ppcoin: calculate total coin age spent in block bool SignBlock(const CKeyStore& keystore); - bool CheckBlockSignature() const; + bool CheckBlockSignature(int nHeight) const; private: bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index d13bdec..d2f7d74 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -505,10 +505,13 @@ Value getblocktemplate(const Array& params, bool fHelp) result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); - if(totalCoin > VALUE_CHANGE) - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue + (int64_t)pblock->vtx[0].vout[1].nValue)); - else + if((fTestNet && (pindexPrev->nHeight + 1 < nTestStage1)) || + (!fTestNet && (totalCoin > VALUE_CHANGE))) { + result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue + + (int64_t)pblock->vtx[0].vout[1].nValue)); + } else { result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); + } result.push_back(Pair("target", hashTarget.GetHex())); result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("mutable", aMutable)); diff --git a/src/util.h b/src/util.h index 610b813..2dff789 100644 --- a/src/util.h +++ b/src/util.h @@ -488,6 +488,19 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end, return hash2; } +template +inline uint256 HashSingle(const T1 p1begin, const T1 p1end, + const T2 p2begin, const T2 p2end) { + static unsigned char pblank[1]; + uint256 hash1; + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0])); + SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0])); + SHA256_Final((unsigned char*)&hash1, &ctx); + return(hash1); +} + template inline uint256 Hash(const T1 p1begin, const T1 p1end, const T2 p2begin, const T2 p2end, From 042f532bbcb0c15a27617f11d51017e1c13c8731 Mon Sep 17 00:00:00 2001 From: John Doering Date: Thu, 4 Feb 2016 04:31:02 +0200 Subject: [PATCH 171/218] RPC getworkex Removed --- src/bitcoinrpc.cpp | 1 - src/bitcoinrpc.h | 1 - src/rpcmining.cpp | 130 --------------------------------------------- 3 files changed, 132 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index ab3d4e8..bd98b9f 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -247,7 +247,6 @@ static const CRPCCommand vRPCCommands[] = { "signmessage", &signmessage, false, false }, { "verifymessage", &verifymessage, false, false }, { "getwork", &getwork, true, false }, - { "getworkex", &getworkex, true, false }, { "listaccounts", &listaccounts, false, false }, { "settxfee", &settxfee, false, false }, { "getblocktemplate", &getblocktemplate, true, false }, diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 91934dd..0e317ae 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -146,7 +146,6 @@ extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHe extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getworkex(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index d2f7d74..2abc301 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -119,136 +119,6 @@ Value getnetworkhashps(const Array& params, bool fHelp) } -Value getworkex(const Array& params, bool fHelp) -{ - if (fHelp || params.size() > 2) - throw runtime_error( - "getworkex [data, coinbase]\n" - "If [data, coinbase] is not specified, returns extended work data.\n" - ); - - if (vNodes.empty()) - throw JSONRPCError(-9, "Diamond is not connected!"); - - if (IsInitialBlockDownload()) - throw JSONRPCError(-10, "Diamond is downloading blocks..."); - - typedef map > mapNewBlock_t; - static mapNewBlock_t mapNewBlock; - static vector vNewBlock; - static CReserveKey reservekey(pwalletMain); - - if (params.size() == 0) - { - // Update block - static unsigned int nTransactionsUpdatedLast; - static CBlockIndex* pindexPrev; - static int64 nStart; - static CBlock* pblock; - if (pindexPrev != pindexBest || - (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) - { - if (pindexPrev != pindexBest) - { - // Deallocate old blocks since they're obsolete now - mapNewBlock.clear(); - BOOST_FOREACH(CBlock* pblock, vNewBlock) - delete pblock; - vNewBlock.clear(); - } - nTransactionsUpdatedLast = nTransactionsUpdated; - pindexPrev = pindexBest; - nStart = GetTime(); - - // Create new block - pblock = CreateNewBlock(pwalletMain); - if (!pblock) - throw JSONRPCError(-7, "Out of memory"); - vNewBlock.push_back(pblock); - } - - // Update nTime - pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - pblock->nNonce = 0; - - // Update nExtraNonce - static unsigned int nExtraNonce = 0; - IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); - - // Save - mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig); - - // Prebuild hash buffers - char pmidstate[32]; - char pdata[128]; - char phash1[64]; - FormatHashBuffers(pblock, pmidstate, pdata, phash1); - - uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - - CTransaction coinbaseTx = pblock->vtx[0]; - std::vector merkle = pblock->GetMerkleBranch(0); - - Object result; - result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); - result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); - - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); - ssTx << coinbaseTx; - result.push_back(Pair("coinbase", HexStr(ssTx.begin(), ssTx.end()))); - - Array merkle_arr; - - BOOST_FOREACH(uint256 merkleh, merkle) { - merkle_arr.push_back(HexStr(BEGIN(merkleh), END(merkleh))); - } - - result.push_back(Pair("merkle", merkle_arr)); - - - return result; - } - else - { - // Parse parameters - vector vchData = ParseHex(params[0].get_str()); - vector coinbase; - - if(params.size() == 2) - coinbase = ParseHex(params[1].get_str()); - - if (vchData.size() != 128) - throw JSONRPCError(-8, "Invalid parameter"); - - CBlock* pdata = (CBlock*)&vchData[0]; - - // Byte reverse - for (int i = 0; i < 128/4; i++) - ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); - - // Get saved block - if (!mapNewBlock.count(pdata->hashMerkleRoot)) - return false; - CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; - - pblock->nTime = pdata->nTime; - pblock->nNonce = pdata->nNonce; - - if(coinbase.size() == 0) - pblock->vtx[0].vin[0].scriptSig = mapNewBlock[pdata->hashMerkleRoot].second; - else - CDataStream(coinbase, SER_NETWORK, PROTOCOL_VERSION) >> pblock->vtx[0]; // FIXME - HACK! - - pblock->hashMerkleRoot = pblock->BuildMerkleTree(); - - if (!pblock->SignBlock(*pwalletMain)) - throw JSONRPCError(-100, "Unable to sign block, wallet locked?"); - - return CheckWork(pblock, *pwalletMain, reservekey); - } -} - - Value getwork(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) From 85ff2a9a8c13a4ebbdd3aa0a05a72e184cb87df5 Mon Sep 17 00:00:00 2001 From: John Doering Date: Mon, 8 Feb 2016 17:18:51 +0200 Subject: [PATCH 172/218] Testnet: Another Attempt --- src/checkpoints.h | 2 +- src/main.h | 56 ++++++++++++++++++++++------------------------- src/util.h | 42 +++++++++++++++++------------------ 3 files changed, 48 insertions(+), 52 deletions(-) diff --git a/src/checkpoints.h b/src/checkpoints.h index 4f5db11..46147fb 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -118,7 +118,7 @@ class CSyncCheckpoint : public CUnsignedSyncCheckpoint uint256 GetHash() const { - return SerializeHash(*this); + return(SerializeHash2(*this)); } bool RelayTo(CNode* pnode) const diff --git a/src/main.h b/src/main.h index 50a1012..0f57d71 100644 --- a/src/main.h +++ b/src/main.h @@ -45,7 +45,10 @@ static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS static const int nTestStage1 = 315; /* Testnet: disable foundation PoW share */ static const int nTestStage2 = 330; /* Testnet: disable PoW block signature */ -static const int nTestStage3 = 340; /* Testnet: switch to SHA-256 for merkle root and reduce time drifts */ +static const int nTestStage3 = 340; /* Testnet: reduce time drifts */ + +/* Testnet: SHA-256 transaction hashing after 8-Feb-2016 15:00 UTC */ +static const unsigned int nTestTxSwitch = 1454943600; inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. @@ -392,7 +395,7 @@ class CTxOut uint256 GetHash() const { - return SerializeHash(*this); + return(SerializeHash2(*this)); } friend bool operator==(const CTxOut& a, const CTxOut& b) @@ -443,8 +446,7 @@ typedef std::map > MapPrevTx; class CTransaction { public: - static const int LEGACY_VERSION_1=1; - static const int CURRENT_VERSION = 2; + static const int CURRENT_VERSION = 3; int nVersion; unsigned int nTime; @@ -470,14 +472,19 @@ class CTransaction READWRITE(vin); READWRITE(vout); READWRITE(nLockTime); - if(this->nVersion > LEGACY_VERSION_1) { + if(this->nVersion > 1) { READWRITE(strTxComment); } ) void SetNull() { - nVersion = CTransaction::CURRENT_VERSION; nTime = GetAdjustedTime(); + if((fTestNet && (nTime < nTestTxSwitch)) || + (!fTestNet)) { + nVersion = 2; + } else { + nVersion = CTransaction::CURRENT_VERSION; + } vin.clear(); vout.clear(); nLockTime = 0; @@ -490,9 +497,13 @@ class CTransaction return (vin.empty() && vout.empty()); } - uint256 GetHash() const - { - return SerializeHash(*this); + uint256 GetHash() const { + if((fTestNet && (nTime < nTestTxSwitch)) || + (!fTestNet)) { + return(SerializeHash2(*this)); + } else { + return(SerializeHash1(*this)); + } } bool IsFinal(int nBlockHeight=0, int64 nBlockTime=0) const @@ -1017,7 +1028,6 @@ class CBlock } uint256 BuildMerkleTree() const { - int nHeight = GetBlockHeight(); vMerkleTree.clear(); BOOST_FOREACH(const CTransaction& tx, vtx) vMerkleTree.push_back(tx.GetHash()); @@ -1027,14 +1037,8 @@ class CBlock for (int i = 0; i < nSize; i += 2) { int i2 = std::min(i+1, nSize-1); - if((fTestNet && (nHeight < nTestStage3)) || - (!fTestNet)) { - vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), - BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); - } else { - vMerkleTree.push_back(HashSingle(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), - BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); - } + vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), + BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); } j += nSize; } @@ -1063,18 +1067,10 @@ class CBlock return 0; BOOST_FOREACH(const uint256& otherside, vMerkleBranch) { - if((fTestNet && (nHeight < nTestStage3)) || - (!fTestNet)) { - if(nIndex & 1) - hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); - else - hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); - } else { - if(nIndex & 1) - hash = HashSingle(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); - else - hash = HashSingle(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); - } + if(nIndex & 1) + hash = Hash(BEGIN(otherside), END(otherside), BEGIN(hash), END(hash)); + else + hash = Hash(BEGIN(hash), END(hash), BEGIN(otherside), END(otherside)); nIndex >>= 1; } return hash; diff --git a/src/util.h b/src/util.h index 2dff789..260f6a5 100644 --- a/src/util.h +++ b/src/util.h @@ -454,13 +454,20 @@ class CHashWriter return (*this); } - // invalidates the object - uint256 GetHash() { + /* SHA-256 */ + uint256 GetHash1() { uint256 hash1; - SHA256_Final((unsigned char*)&hash1, &ctx); + SHA256_Final((unsigned char *) &hash1, &ctx); + return(hash1); + } + + /* SHA-256d */ + uint256 GetHash2() { + uint256 hash1; + SHA256_Final((unsigned char *) &hash1, &ctx); uint256 hash2; - SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); - return hash2; + SHA256((unsigned char *) &hash1, sizeof(hash1), (unsigned char *) &hash2); + return(hash2); } template @@ -488,19 +495,6 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end, return hash2; } -template -inline uint256 HashSingle(const T1 p1begin, const T1 p1end, - const T2 p2begin, const T2 p2end) { - static unsigned char pblank[1]; - uint256 hash1; - SHA256_CTX ctx; - SHA256_Init(&ctx); - SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0])); - SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0])); - SHA256_Final((unsigned char*)&hash1, &ctx); - return(hash1); -} - template inline uint256 Hash(const T1 p1begin, const T1 p1end, const T2 p2begin, const T2 p2end, @@ -520,11 +514,17 @@ inline uint256 Hash(const T1 p1begin, const T1 p1end, } template -uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION) -{ +uint256 SerializeHash1(const T& obj, int nType = SER_GETHASH, int nVersion = PROTOCOL_VERSION) { + CHashWriter ss(nType, nVersion); + ss << obj; + return(ss.GetHash1()); +} + +template +uint256 SerializeHash2(const T& obj, int nType = SER_GETHASH, int nVersion = PROTOCOL_VERSION) { CHashWriter ss(nType, nVersion); ss << obj; - return ss.GetHash(); + return(ss.GetHash2()); } inline uint160 Hash160(const std::vector& vch) From 18db9a2bec5fc57282ed22a35aaa7e7aaf853234 Mon Sep 17 00:00:00 2001 From: John Doering Date: Wed, 10 Feb 2016 13:21:38 +0200 Subject: [PATCH 173/218] Genesis Block Calculation Fixed --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 98744cd..1fe5715 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2779,6 +2779,7 @@ bool LoadBlockIndex(bool fAllowNew) /* Livenet genesis */ const char* pszTimestamp = "Friday, July 12, 11:19 AM: Cavendish wins eventful 13th stage of Tour de France as Froome loses chunk of overall lead"; + txNew.nVersion = 2; txNew.nTime = nChainStartTime; txNew.vin.resize(1); txNew.vout.resize(1); @@ -2798,6 +2799,7 @@ bool LoadBlockIndex(bool fAllowNew) /* Testnet genesis */ const char* pszTimestamp = "Let it ride!"; + txNew.nVersion = 2; txNew.nTime = 1453766400; txNew.vin.resize(1); txNew.vout.resize(1); From d5fb1badff04cdca4d7f8e76ca2aa1b6dc002208 Mon Sep 17 00:00:00 2001 From: John Doering Date: Mon, 15 Feb 2016 23:25:31 +0200 Subject: [PATCH 174/218] Testnet: Merged Mining --- diamond.pro | 6 +- src/auxpow.cpp | 129 +++++++++++++++++++ src/auxpow.h | 86 +++++++++++++ src/bitcoinrpc.cpp | 2 + src/bitcoinrpc.h | 2 + src/db.cpp | 2 + src/kernel.cpp | 1 + src/main.cpp | 140 +++++++++++++++----- src/main.h | 55 +++++++- src/makefile.bsd | 3 +- src/makefile.linux-mingw | 3 +- src/makefile.mingw | 3 +- src/makefile.osx | 3 +- src/makefile.unix | 3 +- src/rpcblockchain.cpp | 1 + src/rpcmining.cpp | 268 +++++++++++++++++++++++++++++++++++++++ src/wallet.cpp | 1 + 17 files changed, 662 insertions(+), 46 deletions(-) create mode 100644 src/auxpow.cpp create mode 100644 src/auxpow.h diff --git a/diamond.pro b/diamond.pro index 0424a9c..664f732 100644 --- a/diamond.pro +++ b/diamond.pro @@ -228,7 +228,8 @@ HEADERS += src/qt/bitcoingui.h \ src/hash.h \ src/scrypt.h \ src/sph_groestl.h \ - src/sph_types.h + src/sph_types.h \ + src/auxpow.h SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/transactiontablemodel.cpp \ @@ -299,7 +300,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/pbkdf2.cpp \ src/hash.cpp \ src/scrypt.cpp \ - src/groestl.c + src/groestl.c \ + src/auxpow.cpp RESOURCES += \ src/qt/bitcoin.qrc diff --git a/src/auxpow.cpp b/src/auxpow.cpp new file mode 100644 index 0000000..943c22d --- /dev/null +++ b/src/auxpow.cpp @@ -0,0 +1,129 @@ +// Copyright (c) 2011 Vince Durham +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#include "script.h" +#include "auxpow.h" +#include "init.h" + +using namespace std; +using namespace boost; + +unsigned char pchMergedMiningHeader[] = { 0xfa, 0xbe, 'm', 'm' } ; + +void RemoveMergedMiningHeader(vector& vchAux) +{ + if (vchAux.begin() != std::search(vchAux.begin(), vchAux.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader))) + throw runtime_error("merged mining aux too short"); + vchAux.erase(vchAux.begin(), vchAux.begin() + sizeof(pchMergedMiningHeader)); +} + +bool CAuxPow::Check(uint256 hashAuxBlock, int nChainID) +{ + if (nIndex != 0) + return error("AuxPow is not a generate"); + + if (!fTestNet && parentBlock.GetChainID() == nChainID) + return error("Aux POW parent has our chain ID"); + + if (vChainMerkleBranch.size() > 30) + return error("Aux POW chain merkle branch too long"); + + // Check that the chain merkle root is in the coinbase + uint256 nRootHash = CBlock::CheckMerkleBranch(hashAuxBlock, vChainMerkleBranch, nChainIndex); + vector vchRootHash(nRootHash.begin(), nRootHash.end()); + std::reverse(vchRootHash.begin(), vchRootHash.end()); // correct endian + + // Check that we are in the parent block merkle tree + if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != parentBlock.hashMerkleRoot) + return error("Aux POW merkle root incorrect"); + + const CScript script = vin[0].scriptSig; + + // Check that the same work is not submitted twice to our chain. + // + + CScript::const_iterator pcHead = + std::search(script.begin(), script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)); + + CScript::const_iterator pc = + std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end()); + + if (pc == script.end()) + return error("Aux POW missing chain merkle root in parent coinbase"); + + if (pcHead != script.end()) + { + // Enforce only one chain merkle root by checking that a single instance of the merged + // mining header exists just before. + if (script.end() != std::search(pcHead + 1, script.end(), UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader))) + return error("Multiple merged mining headers in coinbase"); + if (pcHead + sizeof(pchMergedMiningHeader) != pc) + return error("Merged mining header is not just before chain merkle root"); + } + else + { + // For backward compatibility. + // Enforce only one chain merkle root by checking that it starts early in the coinbase. + // 8-12 bytes are enough to encode extraNonce and nBits. + if (pc - script.begin() > 20) + return error("Aux POW chain merkle root must start in the first 20 bytes of the parent coinbase"); + } + + + // Ensure we are at a deterministic point in the merkle leaves by hashing + // a nonce and our chain ID and comparing to the index. + pc += vchRootHash.size(); + if (script.end() - pc < 8) + return error("Aux POW missing chain merkle tree size and nonce in parent coinbase"); + + int nSize; + memcpy(&nSize, &pc[0], 4); + if (nSize != (1 << vChainMerkleBranch.size())) + return error("Aux POW merkle branch size does not match parent coinbase"); + + int nNonce; + memcpy(&nNonce, &pc[4], 4); + + // Choose a pseudo-random slot in the chain merkle tree + // but have it be fixed for a size/nonce/chain combination. + // + // This prevents the same work from being used twice for the + // same chain while reducing the chance that two chains clash + // for the same slot. + int rand = nNonce; + rand = rand * 1103515245 + 12345; + rand += nChainID; + rand = rand * 1103515245 + 12345; + + if (nChainIndex != (rand % nSize)) + return error("Aux POW wrong index"); + + return true; +} + +CScript MakeCoinbaseWithAux(unsigned int nHeight, unsigned int nExtraNonce, + vector& vchAux) { + vector vchAuxWithHeader(UBEGIN(pchMergedMiningHeader), UEND(pchMergedMiningHeader)); + vchAuxWithHeader.insert(vchAuxWithHeader.end(), vchAux.begin(), vchAux.end()); + + // Push OP_2 just in case we want versioning later + /* BIP34: v2 coin base must start with nHeight */ + return CScript() << nHeight << CBigNum(nExtraNonce) << COINBASE_FLAGS << OP_2 << vchAuxWithHeader; +} + + +void IncrementExtraNonceWithAux(CBlock* pblock, CBlockIndex* pindexPrev, + unsigned int& nExtraNonce, vector& vchAux) { + + // Update nExtraNonce + static uint256 hashPrevBlock; + if (hashPrevBlock != pblock->hashPrevBlock) + { + nExtraNonce = 0; + hashPrevBlock = pblock->hashPrevBlock; + } + ++nExtraNonce; + + pblock->vtx[0].vin[0].scriptSig = MakeCoinbaseWithAux(pindexPrev->nHeight + 1, nExtraNonce, vchAux); + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); +} diff --git a/src/auxpow.h b/src/auxpow.h new file mode 100644 index 0000000..854d172 --- /dev/null +++ b/src/auxpow.h @@ -0,0 +1,86 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_AUXPOW_H +#define BITCOIN_AUXPOW_H + +#include "main.h" + +class CAuxPow : public CMerkleTx +{ +public: + CAuxPow(const CTransaction& txIn) : CMerkleTx(txIn) + { + } + + CAuxPow() :CMerkleTx() + { + } + + // Merkle branch with root vchAux + // root must be present inside the coinbase + std::vector vChainMerkleBranch; + // Index of chain in chains merkle tree + int nChainIndex; + CBlock parentBlock; + + IMPLEMENT_SERIALIZE + ( + nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion, ser_action); + nVersion = this->nVersion; + READWRITE(vChainMerkleBranch); + READWRITE(nChainIndex); + + // Always serialize the saved parent block as header so that the size of CAuxPow + // is consistent. + nSerSize += SerReadWrite(s, parentBlock, nType | SER_BLOCKHEADERONLY, nVersion, ser_action); + ) + + bool Check(uint256 hashAuxBlock, int nChainID); + + uint256 GetParentBlockHash() { + return(parentBlock.GetHashGroestl()); + } +}; + +template +int ReadWriteAuxPow(Stream& s, const boost::shared_ptr& auxpow, int nType, int nVersion, CSerActionGetSerializeSize ser_action) +{ + if (nVersion & BLOCK_VERSION_AUXPOW) + { + return ::GetSerializeSize(*auxpow, nType, nVersion); + } + return 0; +} + +template +int ReadWriteAuxPow(Stream& s, const boost::shared_ptr& auxpow, int nType, int nVersion, CSerActionSerialize ser_action) +{ + if (nVersion & BLOCK_VERSION_AUXPOW) + { + return SerReadWrite(s, *auxpow, nType, nVersion, ser_action); + } + return 0; +} + +template +int ReadWriteAuxPow(Stream& s, boost::shared_ptr& auxpow, int nType, int nVersion, CSerActionUnserialize ser_action) +{ + if (nVersion & BLOCK_VERSION_AUXPOW) + { + auxpow.reset(new CAuxPow()); + return SerReadWrite(s, *auxpow, nType, nVersion, ser_action); + } + else + { + auxpow.reset(); + return 0; + } +} + +extern void RemoveMergedMiningHeader(std::vector& vchAux); +extern void IncrementExtraNonceWithAux(CBlock* pblock, CBlockIndex* pindexPrev, + unsigned int& nExtraNonce, std::vector& vchAux); +extern CScript MakeCoinbaseWithAux(unsigned int nBits, unsigned int nExtraNonce, + std::vector& vchAux); +#endif diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index d6ef609..d7e9617 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -247,9 +247,11 @@ static const CRPCCommand vRPCCommands[] = { "signmessage", &signmessage, false, false }, { "verifymessage", &verifymessage, false, false }, { "getwork", &getwork, true, false }, + { "getworkaux", &getworkaux, true, false }, { "listaccounts", &listaccounts, false, false }, { "settxfee", &settxfee, false, false }, { "getblocktemplate", &getblocktemplate, true, false }, + { "getauxblock", &getauxblock, true, false }, { "submitblock", &submitblock, false, false }, { "listsinceblock", &listsinceblock, false, false }, { "dumpprivkey", &dumpprivkey, false, false }, diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 9aec3b4..c80d075 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -151,6 +151,8 @@ extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool f extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getworkaux(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getauxblock(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp); diff --git a/src/db.cpp b/src/db.cpp index ebfe781..dbde1a7 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -9,6 +9,7 @@ #include "util.h" #include "main.h" #include "kernel.h" +#include "auxpow.h" #include #include #include @@ -913,6 +914,7 @@ bool CTxDB::LoadBlockIndexGuts() pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; + pindexNew->auxpow = diskindex.auxpow; if(!fTestNet && (totalCoin == VALUE_CHANGE)) pindexSave = pindexNew; diff --git a/src/kernel.cpp b/src/kernel.cpp index 6857c39..e324627 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -6,6 +6,7 @@ #include "kernel.h" #include "db.h" +#include "auxpow.h" using namespace std; diff --git a/src/main.cpp b/src/main.cpp index 1fe5715..83a0a13 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,8 @@ #include "checkpoints.h" #include "db.h" #include "net.h" -#include "init.h" +#include "init.h" +#include "auxpow.h" #include "ui_interface.h" #include "kernel.h" #include "scrypt_mine.h" @@ -772,7 +773,7 @@ int CMerkleTx::GetDepthInMainChain(CBlockIndex* &pindexRet) const // Make sure the merkle branch connects to this block if (!fMerkleVerified) { - if(CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex, pindex->nHeight) != pindex->hashMerkleRoot) + if(CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot) return 0; fMerkleVerified = true; } @@ -921,6 +922,14 @@ bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions) return true; } +void CBlock::SetAuxPow(CAuxPow* pow) { + if(pow != NULL) + nVersion |= BLOCK_VERSION_AUXPOW; + else + nVersion &= ~BLOCK_VERSION_AUXPOW; + auxpow.reset(pow); +} + uint256 static GetOrphanRoot(const CBlock* pblock) { // Work back to the first block in the orphan chain @@ -1240,25 +1249,6 @@ unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfS } -bool CheckProofOfWork(uint256 hash, unsigned int nBits) -{ - CBigNum bnTarget; - bnTarget.SetCompact(nBits); - - // danbi: substitute false for error as we call it with both algorithms for now - // Check range - if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit) - return false; -// return error("CheckProofOfWork() : nBits below minimum work"); - - // Check proof of work matches claimed amount - if (hash > bnTarget.getuint256()) - return false; -// return error("CheckProofOfWork() : hash doesn't match nBits"); - - return true; -} - // Return maximum amount of blocks that other nodes claim to have int GetNumBlocksOfPeers() { @@ -1645,7 +1635,7 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) { // Check it again in case a previous version let a bad block in - if (!CheckBlock(!fJustCheck, !fJustCheck, GetTotalCoin())) + if(!CheckBlock(!fJustCheck, !fJustCheck, GetTotalCoin())) return false; // Do not allow blocks that contain transactions which 'overwrite' older transactions, @@ -1670,7 +1660,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) // Since we're just checking the block and not actually connecting it, it might not (and probably shouldn't) be on the disk to get the transaction from nTxPos = 1; else - nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK, CLIENT_VERSION) - (2 * GetSizeOfCompactSize(0)) + GetSizeOfCompactSize(vtx.size()); + nTxPos = pindex->nBlockPos + ::GetSerializeSize(*this, SER_DISK | SER_BLOCKHEADERONLY, CLIENT_VERSION) + GetSizeOfCompactSize(vtx.size()); map mapQueuedChanges; int64 nFees = 0; @@ -2191,8 +2181,68 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) return true; } -bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const -{ +// Start accepting AUX POW at this block +// +// Even if we do not accept AUX POW ourselves, we can always be the parent chain. + +int GetAuxPowStartBlock() { + if(fTestNet) + return(nTestStage4); + else + return(INT_MAX); +} + +int GetOurChainID() { + return(0x0000); +} + +bool CBlock::CheckProofOfWork(int64 totalCoin) const { + int nHeight = GetBlockHeight(); + CBigNum bnTarget; + bnTarget.SetCompact(nBits); + + if(nHeight >= GetAuxPowStartBlock()) { + + // Prevent same work from being submitted twice: + // - this block must have our chain ID + // - parent block must not have the same chain ID (see CAuxPow::Check) + // - index of this chain in chain merkle tree must be pre-determined (see CAuxPow::Check) + if (!fTestNet && nHeight != INT_MAX && GetChainID() != GetOurChainID()) + return error("CheckProofOfWork() : block does not have our chain ID"); + + if(auxpow.get() != NULL) { + + if(!(nVersion & BLOCK_VERSION_AUXPOW)) + return(error("CheckProofOfWork() : AuxPoW block version is not valid")); + + if(!auxpow->Check(GetHashGroestl(), GetChainID())) + return(error("CheckProofOfWork() : AuxPoW is not valid")); + + if(bnTarget <= 0 || (bnTarget > bnProofOfWorkLimit) || (auxpow->GetParentBlockHash() > bnTarget.getuint256())) + return(error("CheckProofOfWork() : AuxPoW failed")); + } + else + { + + if(bnTarget <= 0 || (bnTarget > bnProofOfWorkLimit) || (GetHashGroestl() > bnTarget.getuint256())) + return(error("CheckProofOfWork() : PoW failed")); + + } + } + else + { + if(auxpow.get() != NULL) + return(error("CheckProofOfWork() : AuxPoW is not allowed at this block height")); + + if(bnTarget <= 0 || (bnTarget > bnProofOfWorkLimit) || (GetHash(false, totalCoin) > bnTarget.getuint256())) + return(error("CheckProofOfWork() : proof of work failed")); + } + + return(true); +} + +bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) const { + // Update the coin mechanics variables post algorithm change // Changing any of these requires a fork if(!fTestNet) { @@ -2223,7 +2273,7 @@ bool CBlock::CheckBlock(bool fCheckPOW, bool fCheckMerkleRoot, int64 totalCoin) // new block comes during initial sync and that might come from "future" // compromise: use optimization, but decrease penalty (was 50) // if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) - if (fCheckPOW && IsProofOfWork() && !CheckProofOfWork(GetHash(false, totalCoin), nBits)) + if(fCheckPOW && IsProofOfWork() && !CheckProofOfWork(totalCoin)) return(error("CheckBlock() : proof of work failed")); // Check timestamp @@ -2431,7 +2481,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); // Preliminary checks - if (!pblock->CheckBlock(true,true,GetTotalCoin())) + if(!pblock->CheckBlock(true, true, GetTotalCoin())) return error("ProcessBlock() : CheckBlock FAILED"); // ppcoin: verify hash target and signature of coinstake tx @@ -3683,7 +3733,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vRecv >> block; uint256 hashBlock = block.GetHash(); - printf("received block %s\n", hashBlock.ToString().substr(0,20).c_str()); + printf("received block %s height %d\n", + hashBlock.ToString().substr(0,20).c_str(), block.GetBlockHeight()); // block.print(); CInv inv(MSG_BLOCK, hashBlock); @@ -4592,12 +4643,35 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) uint256 hash = pblock->GetHash(); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); - if (hash > hashTarget && pblock->IsProofOfWork()) - return error("BitcoinMiner : proof-of-work not meeting target"); + if(pblock->IsProofOfWork()) { + CAuxPow *auxpow = pblock->auxpow.get(); + + if(auxpow != NULL) { + if(!auxpow->Check(hash, pblock->GetChainID())) + return(error("AuxPoW is not valid")); + + if(auxpow->GetParentBlockHash() > hashTarget) + return(error("AuxPoW parent hash %s is not under target %s", + auxpow->GetParentBlockHash().GetHex().c_str(), hashTarget.GetHex().c_str())); + + printf("DiamondMiner:\n"); + printf("AUX proof-of-work found \n our hash: %s \n parent hash: %s \n target: %s\n", + hash.GetHex().c_str(), auxpow->GetParentBlockHash().GetHex().c_str(), hashTarget.GetHex().c_str()); + } else { + if(hash > hashTarget) + return(error("DiamondMiner : proof-of-work not meeting target")); + + printf("DiamondMiner:\n"); + printf("proof-of-work found \n hash: %s \ntarget: %s\n", + hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + } + } else { + + printf("DiamondMiner:\n"); + printf("proof-of-stake found \n hash: %s \ntarget: %s\n", + hash.GetHex().c_str(), hashTarget.GetHex().c_str()); + } - //// debug print - printf("BitcoinMiner:\n"); - printf("new block found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); pblock->print(); printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); diff --git a/src/main.h b/src/main.h index 0f57d71..a562256 100644 --- a/src/main.h +++ b/src/main.h @@ -26,6 +26,7 @@ class CAddress; class CInv; class CRequestTracker; class CNode; +class CAuxPow; static const unsigned int MAX_BLOCK_SIZE = 1000000; static const unsigned int MAX_BLOCK_SIZE_GEN = MAX_BLOCK_SIZE/2; @@ -46,6 +47,7 @@ static const int64 POS_RESTART = 450000; // When to apply fixes to enable PoS static const int nTestStage1 = 315; /* Testnet: disable foundation PoW share */ static const int nTestStage2 = 330; /* Testnet: disable PoW block signature */ static const int nTestStage3 = 340; /* Testnet: reduce time drifts */ +static const int nTestStage4 = 440; /* Testnet: enable merged mining */ /* Testnet: SHA-256 transaction hashing after 8-Feb-2016 15:00 UTC */ static const unsigned int nTestTxSwitch = 1454943600; @@ -129,7 +131,6 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake=false); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); -bool CheckProofOfWork(uint256 hash, unsigned int nBits); int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash); int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight); unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); @@ -857,7 +858,29 @@ class CTxIndex }; - +template +int ReadWriteAuxPow(Stream& s, const boost::shared_ptr& auxpow, int nType, + int nVersion, CSerActionSerialize ser_action); + +template +int ReadWriteAuxPow(Stream& s, boost::shared_ptr& auxpow, int nType, + int nVersion, CSerActionUnserialize ser_action); + +template +int ReadWriteAuxPow(Stream& s, const boost::shared_ptr& auxpow, int nType, + int nVersion, CSerActionGetSerializeSize ser_action); + +enum { + // primary version + BLOCK_VERSION_DEFAULT = (1 << 0), + + // modifiers + BLOCK_VERSION_AUXPOW = (1 << 8), + + // bits allocated for chain ID + BLOCK_VERSION_CHAIN_START = (1 << 16), + BLOCK_VERSION_CHAIN_END = (1 << 30), +}; /** Nodes collect new transactions into a block, hash them into a hash tree, @@ -885,6 +908,9 @@ class CBlock // network and disk std::vector vtx; + // header + boost::shared_ptr auxpow; + // ppcoin: block signature - signed by one of the coin base txout[N]'s owner std::vector vchBlockSig; @@ -910,8 +936,10 @@ class CBlock READWRITE(nBits); READWRITE(nNonce); + nSerSize += ReadWriteAuxPow(s, auxpow, nType, nVersion, ser_action); + // ConnectBlock depends on vtx following header to generate CDiskTxPos - if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) + if(!(nType & (SER_BLOCKHEADERONLY))) { READWRITE(vtx); READWRITE(vchBlockSig); @@ -935,6 +963,7 @@ class CBlock vchBlockSig.clear(); vMerkleTree.clear(); nDoS = 0; + auxpow.reset(); } bool IsNull() const @@ -942,6 +971,12 @@ class CBlock return (nBits == 0); } + int GetChainID() const { + return(nVersion / BLOCK_VERSION_CHAIN_START); + } + + void SetAuxPow(CAuxPow* pow); + /* Extracts block height from v2+ coin base; * ignores nVersion because it's unreliable */ int GetBlockHeight() const { @@ -1062,7 +1097,7 @@ class CBlock } static uint256 CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, - int nIndex, int nHeight) { + int nIndex) { if (nIndex == -1) return 0; BOOST_FOREACH(const uint256& otherside, vMerkleBranch) @@ -1123,8 +1158,8 @@ class CBlock } // Check the header - if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) - return error("CBlock::ReadFromDisk() : errors in block header"); +// if (fReadTransactions && IsProofOfWork() && !CheckProofOfWork(GetHashScrypt(), nBits) && !CheckProofOfWork(GetHashGroestl(), nBits)) +// return error("CBlock::ReadFromDisk() : errors in block header"); return true; } @@ -1162,6 +1197,7 @@ class CBlock bool GetCoinAge(uint64& nCoinAge) const; // ppcoin: calculate total coin age spent in block bool SignBlock(const CKeyStore& keystore); bool CheckBlockSignature(int nHeight) const; + bool CheckProofOfWork(int64 totalCoin) const; private: bool SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew); @@ -1216,6 +1252,9 @@ class CBlockIndex unsigned int nBits; unsigned int nNonce; + // if this is an aux work block + boost::shared_ptr auxpow; + CBlockIndex() { phashBlock = NULL; @@ -1239,6 +1278,7 @@ class CBlockIndex nTime = 0; nBits = 0; nNonce = 0; + auxpow.reset(); } CBlockIndex(unsigned int nFileIn, unsigned int nBlockPosIn, CBlock& block) @@ -1273,6 +1313,7 @@ class CBlockIndex nTime = block.nTime; nBits = block.nBits; nNonce = block.nNonce; + auxpow = block.auxpow; } CBlock GetBlockHeader() const @@ -1285,6 +1326,7 @@ class CBlockIndex block.nTime = nTime; block.nBits = nBits; block.nNonce = nNonce; + block.auxpow = auxpow; return block; } @@ -1464,6 +1506,7 @@ class CDiskBlockIndex : public CBlockIndex READWRITE(nBits); READWRITE(nNonce); READWRITE(blockHash); + ReadWriteAuxPow(s, auxpow, nType, this->nVersion, ser_action); ) uint256 GetBlockHash() const diff --git a/src/makefile.bsd b/src/makefile.bsd index 6ee0e4b..1e93741 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -142,7 +142,8 @@ OBJS= \ obj/pbkdf2.o \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ - obj/scrypt-x86_64.o + obj/scrypt-x86_64.o \ + obj/auxpow.o all: diamondd diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 5f65ab2..909bf04 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -87,7 +87,8 @@ OBJS= \ obj/pbkdf2.o \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ - obj/scrypt-x86_64.o + obj/scrypt-x86_64.o \ + obj/auxpow.o all: diamondd.exe diff --git a/src/makefile.mingw b/src/makefile.mingw index 75696a6..ca5986c 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -83,7 +83,8 @@ OBJS= \ obj/pbkdf2.o \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ - obj/scrypt-x86_64.o + obj/scrypt-x86_64.o \ + obj/auxpow.o all: diamondd.exe diff --git a/src/makefile.osx b/src/makefile.osx index 31458d8..5c74614 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -104,7 +104,8 @@ OBJS= \ obj/kernel.o \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ - obj/scrypt-x86_64.o + obj/scrypt-x86_64.o \ + obj/auxpow.o ifndef USE_UPNP override USE_UPNP = - diff --git a/src/makefile.unix b/src/makefile.unix index 3df072e..e5fd8fc 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -146,7 +146,8 @@ OBJS= \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ obj/scrypt-x86_64.o \ - obj/scrypt-arm.o + obj/scrypt-arm.o \ + obj/auxpow.o all: diamondd diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 761180f..4f82ef9 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -5,6 +5,7 @@ #include "main.h" #include "bitcoinrpc.h" +#include "auxpow.h" using namespace json_spirit; using namespace std; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 2abc301..347db4a 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -7,6 +7,7 @@ #include "db.h" #include "init.h" #include "bitcoinrpc.h" +#include "auxpow.h" using namespace json_spirit; using namespace std; @@ -234,6 +235,273 @@ Value getwork(const Array& params, bool fHelp) } } +Value getworkaux(const Array& params, bool fHelp) { + unsigned int i; + + if (fHelp || params.size() < 1) + throw runtime_error( + "getworkaux \n" + "getworkaux '' \n" + "getworkaux 'submit' \n" + "getworkaux '' *\n" + " get work with auxiliary data in coinbase, for multichain mining\n" + " is the merkle root of the auxiliary chain block hashes, concatenated with the aux chain merkle tree size and a nonce\n" + " is the aux chain index in the aux chain merkle tree\n" + " is the optional merkle branch of the aux chain\n" + "If is not specified, returns formatted hash data to work on:\n" + " \"midstate\" : precomputed hash state after hashing the first half of the data\n" + " \"data\" : block data\n" + " \"hash1\" : formatted hash buffer for second hash\n" + " \"target\" : little endian hash target\n" + "If is specified and 'submit', tries to solve the block for this (parent) chain and returns true if it was successful." + "If is specified and empty first argument, returns the aux merkle root, with size and nonce." + "If and are specified, creates an auxiliary proof of work for the chain specified and returns:\n" + " \"aux\" : merkle root of auxiliary chain block hashes\n" + " \"auxpow\" : aux proof of work to submit to aux chain\n" + ); + + if(vNodes.empty()) + throw(JSONRPCError(-9, "Diamond is not connected!")); + + if(IsInitialBlockDownload()) + throw(JSONRPCError(-10, "Diamond is downloading blocks...")); + + static map > mapNewBlock; + static vector vNewBlock; + static CReserveKey reservekey(pwalletMain); + + if (params.size() == 1) + { + static vector vchAuxPrev; + vector vchAux = ParseHex(params[0].get_str()); + + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + vchAux != vchAuxPrev || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) + { + if (pindexPrev != pindexBest) + { + // Deallocate old blocks since they're obsolete now + mapNewBlock.clear(); + BOOST_FOREACH(CBlock* pblock, vNewBlock) + delete pblock; + vNewBlock.clear(); + } + nTransactionsUpdatedLast = nTransactionsUpdated; + pindexPrev = pindexBest; + vchAuxPrev = vchAux; + nStart = GetTime(); + + // Create new block + pblock = CreateNewBlock(pwalletMain); + if (!pblock) + throw JSONRPCError(-7, "Out of memory"); + vNewBlock.push_back(pblock); + } + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + // Update nExtraNonce + static unsigned int nExtraNonce = 0; + IncrementExtraNonceWithAux(pblock, pindexPrev, nExtraNonce, vchAux); + + // Save + mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce); + + // Prebuild hash buffers + char pmidstate[32]; + char pdata[128]; + char phash1[64]; + FormatHashBuffers(pblock, pmidstate, pdata, phash1); + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + Object result; + result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); + result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); + result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); + result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); + return result; + } + else + { + if (params[0].get_str() != "submit" && params[0].get_str() != "") + throw JSONRPCError(-8, " must be the empty string or 'submit' if work is being submitted"); + // Parse parameters + vector vchData = ParseHex(params[1].get_str()); + if (vchData.size() != 128) + throw JSONRPCError(-8, "Invalid parameter"); + CBlock* pdata = (CBlock*)&vchData[0]; + + // Byte reverse + for(i = 0; i < 128/4; i++) + ((unsigned int*)pdata)[i] = ByteReverse(((unsigned int*)pdata)[i]); + + // Get saved block + if (!mapNewBlock.count(pdata->hashMerkleRoot)) + return false; + CBlock* pblock = mapNewBlock[pdata->hashMerkleRoot].first; + unsigned int nExtraNonce = mapNewBlock[pdata->hashMerkleRoot].second; + + pblock->nTime = pdata->nTime; + pblock->nNonce = pdata->nNonce; + + // Get the aux merkle root from the coinbase + CScript script = pblock->vtx[0].vin[0].scriptSig; + opcodetype opcode; + CScript::const_iterator pc = script.begin(); + script.GetOp(pc, opcode); + script.GetOp(pc, opcode); + script.GetOp(pc, opcode); + if (opcode != OP_2) + throw runtime_error("invalid aux pow script"); + vector vchAux; + script.GetOp(pc, opcode, vchAux); + + RemoveMergedMiningHeader(vchAux); + + static CBlockIndex* pindexPrev; + pblock->vtx[0].vin[0].scriptSig = MakeCoinbaseWithAux(pindexPrev->nHeight + 1, nExtraNonce, vchAux); + pblock->hashMerkleRoot = pblock->BuildMerkleTree(); + + if (params.size() > 2) + { + // Requested aux proof of work + int nChainIndex = params[2].get_int(); + + CAuxPow pow(pblock->vtx[0]); + + for(i = 3 ; i < params.size() ; i++) { + uint256 nHash; + nHash.SetHex(params[i].get_str()); + pow.vChainMerkleBranch.push_back(nHash); + } + + pow.SetMerkleBranch(pblock); + pow.nChainIndex = nChainIndex; + pow.parentBlock = *pblock; + CDataStream ss(SER_GETHASH | SER_BLOCKHEADERONLY, 0); + ss << pow; + Object result; + result.push_back(Pair("auxpow", HexStr(ss.begin(), ss.end()))); + return result; + } + else + { + if (params[0].get_str() == "submit") + { + return CheckWork(pblock, *pwalletMain, reservekey); + } + else + { + Object result; + result.push_back(Pair("aux", HexStr(vchAux.begin(), vchAux.end()))); + result.push_back(Pair("hash", pblock->GetHash().GetHex())); + return result; + } + } + } +} + +Value getauxblock(const Array& params, bool fHelp) +{ + if (fHelp || (params.size() != 0 && params.size() != 2)) + throw runtime_error( + "getauxblock [ ]\n" + " create a new block" + "If , is not specified, returns a new block hash.\n" + "If , is specified, tries to solve the block based on " + "the aux proof of work and returns true if it was successful."); + + if (vNodes.empty()) + throw JSONRPCError(-9, "Diamond is not connected!"); + + if (IsInitialBlockDownload()) + throw JSONRPCError(-10, "Diamond is downloading blocks..."); + + static map mapNewBlock; + static vector vNewBlock; + static CReserveKey reservekey(pwalletMain); + + if (params.size() == 0) + { + // Update block + static unsigned int nTransactionsUpdatedLast; + static CBlockIndex* pindexPrev; + static int64 nStart; + static CBlock* pblock; + if (pindexPrev != pindexBest || + (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)) + { + if (pindexPrev != pindexBest) + { + // Deallocate old blocks since they're obsolete now + mapNewBlock.clear(); + BOOST_FOREACH(CBlock* pblock, vNewBlock) + delete pblock; + vNewBlock.clear(); + } + nTransactionsUpdatedLast = nTransactionsUpdated; + pindexPrev = pindexBest; + nStart = GetTime(); + + // Create new block with nonce = 0 and extraNonce = 1 + pblock = CreateNewBlock(pwalletMain); + + // Update nTime + pblock->UpdateTime(pindexPrev); + pblock->nNonce = 0; + + // Update nExtraNonce + static unsigned int nExtraNonce = 0; + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + + // Sets the version + pblock->SetAuxPow(new CAuxPow()); + + // Save + mapNewBlock[pblock->GetHash()] = pblock; + + if (!pblock) + throw JSONRPCError(-7, "Out of memory"); + vNewBlock.push_back(pblock); + } + + uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); + + Object result; + result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); + result.push_back(Pair("hash", pblock->GetHash().GetHex())); + result.push_back(Pair("chainid", pblock->GetChainID())); + return result; + } + else + { + uint256 hash; + hash.SetHex(params[0].get_str()); + vector vchAuxPow = ParseHex(params[1].get_str()); + CDataStream ss(vchAuxPow, SER_GETHASH | SER_BLOCKHEADERONLY, 0); + CAuxPow* pow = new CAuxPow(); + ss >> *pow; + if (!mapNewBlock.count(hash)) + return ::error("getauxblock() : block not found"); + + CBlock* pblock = mapNewBlock[hash]; + pblock->SetAuxPow(pow); + + if(!CheckWork(pblock, *pwalletMain, reservekey)) + return(false); + + return(true); + } +} Value getblocktemplate(const Array& params, bool fHelp) { diff --git a/src/wallet.cpp b/src/wallet.cpp index 48e9155..4747b63 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -11,6 +11,7 @@ #include "ui_interface.h" #include "base58.h" #include "kernel.h" +#include "auxpow.h" #include "coincontrol.h" #include From c5fecb1c8bae241e8a58e4e842dbff5f69a09457 Mon Sep 17 00:00:00 2001 From: shadowrider26 Date: Tue, 16 Feb 2016 07:57:06 +1000 Subject: [PATCH 175/218] changes to payment coin selection to prefer newest coins with least coin age stops coins with greater staking potential being un-neccessarily used for transacting. --- src/wallet.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 48e9155..81400ff 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -33,6 +33,11 @@ struct CompareValueOnly } }; +bool CompareAgeOnly(const COutput t1, const COutput t2) +{ + return (t1.tx->nTime < t2.tx->nTime); +} + CPubKey CWallet::GenerateNewKey() { bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets @@ -1039,7 +1044,9 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue > 0 && (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); - } + + sort(vCoins.begin(), vCoins.end(), CompareAgeOnly); // found available coins so sort in age order (TK) + reverse(vCoins.begin(), vCoins.end()); // and return vector with coins sorted from newest to oldest (TK) } } } @@ -1120,7 +1127,8 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in vector > > vValue; int64 nTotalLower = 0; - random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); +// Don't shuffle - we want to use newest coin pile/s possible to stop hurting coin age for minting!! (TK) +// random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); BOOST_FOREACH(COutput output, vCoins) { @@ -1138,13 +1146,15 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in pair > coin = make_pair(n,make_pair(pcoin, i)); - if (n == nTargetValue) +/* if (n == nTargetValue) // first one of any size >= target amount wins, we don't want this! (TK) { setCoinsRet.insert(coin.second); nValueRet += coin.first; return true; } - else if (n < nTargetValue + CENT) + else +*/ + if (n < nTargetValue + CENT) { vValue.push_back(coin); nTotalLower += n; @@ -1155,7 +1165,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in } } - if (nTotalLower == nTargetValue) +/* if (nTotalLower == nTargetValue) // nor this (TK) { for (unsigned int i = 0; i < vValue.size(); ++i) { @@ -1164,6 +1174,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in } return true; } +*/ if (nTotalLower < nTargetValue) { @@ -1175,7 +1186,8 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in } // Solve subset sum by stochastic approximation - sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); + // Don't sort by value - we want to prefer newest to oldest (TK) + // sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); vector vfBest; int64 nBest; @@ -1634,13 +1646,15 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (txNew.vin.size() >= 100) break; // Stop adding more inputs if value is already pretty significant - if (nCredit > nCombineThreshold) + if (nCredit >= nCombineThreshold) break; // Stop adding inputs if reached reserve limit if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) break; + if (nCredit + pcoin.first->vout[pcoin.second].nValue == nBalance) // always leave 2 blocks min - don't combine entire wallet into one block! (TK) + break; // Do not add additional significant input - if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold) + if (pcoin.first->vout[pcoin.second].nValue >= nCombineThreshold) continue; // Do not add input that is still too young if (pcoin.first->nTime + nStakeMaxAge > txNew.nTime) From 266588e0d946cf771fb796c8872a8175d0076951 Mon Sep 17 00:00:00 2001 From: shadowrider26 Date: Tue, 16 Feb 2016 08:15:19 +1000 Subject: [PATCH 176/218] typo --- src/wallet.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 81400ff..8c496f3 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1046,7 +1046,8 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); sort(vCoins.begin(), vCoins.end(), CompareAgeOnly); // found available coins so sort in age order (TK) - reverse(vCoins.begin(), vCoins.end()); // and return vector with coins sorted from newest to oldest (TK) } + reverse(vCoins.begin(), vCoins.end()); // and return vector with coins sorted from newest to oldest (TK) + } } } From a2368c97eb33a6cb53ddc47aaa9a72d7b7d414f5 Mon Sep 17 00:00:00 2001 From: John Doering Date: Wed, 17 Feb 2016 03:11:41 +0200 Subject: [PATCH 177/218] RPC geatuxblock Exception Handling --- src/rpcmining.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 347db4a..0011815 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -387,7 +387,7 @@ Value getworkaux(const Array& params, bool fHelp) { pow.SetMerkleBranch(pblock); pow.nChainIndex = nChainIndex; pow.parentBlock = *pblock; - CDataStream ss(SER_GETHASH | SER_BLOCKHEADERONLY, 0); + CDataStream ss(SER_GETHASH | SER_BLOCKHEADERONLY, PROTOCOL_VERSION); ss << pow; Object result; result.push_back(Pair("auxpow", HexStr(ss.begin(), ss.end()))); @@ -403,7 +403,7 @@ Value getworkaux(const Array& params, bool fHelp) { { Object result; result.push_back(Pair("aux", HexStr(vchAux.begin(), vchAux.end()))); - result.push_back(Pair("hash", pblock->GetHash().GetHex())); + result.push_back(Pair("hash", pblock->GetHashGroestl().GetHex())); return result; } } @@ -487,9 +487,15 @@ Value getauxblock(const Array& params, bool fHelp) uint256 hash; hash.SetHex(params[0].get_str()); vector vchAuxPow = ParseHex(params[1].get_str()); - CDataStream ss(vchAuxPow, SER_GETHASH | SER_BLOCKHEADERONLY, 0); + CDataStream ss(vchAuxPow, SER_GETHASH | SER_BLOCKHEADERONLY, PROTOCOL_VERSION); CAuxPow* pow = new CAuxPow(); - ss >> *pow; + try { + ss >> *pow; + } + catch(std::exception &e) { + throw(JSONRPCError(RPC_DESERIALIZATION_ERROR, "AuxPoW decode failed")); + } + if (!mapNewBlock.count(hash)) return ::error("getauxblock() : block not found"); From 45fe00e76f11641f49caa9b19ab0c1ce0142db8d Mon Sep 17 00:00:00 2001 From: John Doering Date: Mon, 29 Feb 2016 04:05:04 +0200 Subject: [PATCH 178/218] MakeCoinbaseWithAux() Fixed --- src/auxpow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auxpow.cpp b/src/auxpow.cpp index 943c22d..f8248c8 100644 --- a/src/auxpow.cpp +++ b/src/auxpow.cpp @@ -108,7 +108,7 @@ CScript MakeCoinbaseWithAux(unsigned int nHeight, unsigned int nExtraNonce, // Push OP_2 just in case we want versioning later /* BIP34: v2 coin base must start with nHeight */ - return CScript() << nHeight << CBigNum(nExtraNonce) << COINBASE_FLAGS << OP_2 << vchAuxWithHeader; + return(((CScript() << nHeight << CBigNum(nExtraNonce)) + COINBASE_FLAGS) << OP_2 << vchAuxWithHeader); } From 48c5d3cb39330f0eeebac4daf0134243cabd7d54 Mon Sep 17 00:00:00 2001 From: John Doering Date: Mon, 29 Feb 2016 23:56:26 +0200 Subject: [PATCH 179/218] Getwork Buffers Compacted --- src/main.cpp | 121 ++++++++++++---------------------------------- src/main.h | 2 +- src/rpcmining.cpp | 22 ++------- src/util.h | 1 + 4 files changed, 36 insertions(+), 110 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 83a0a13..ac27f19 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4169,50 +4169,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } - - - -////////////////////////////////////////////////////////////////////////////// -// -// BitcoinMiner -// - -int static FormatHashBlocks(void* pbuffer, unsigned int len) -{ - unsigned char* pdata = (unsigned char*)pbuffer; - unsigned int blocks = 1 + ((len + 8) / 64); - unsigned char* pend = pdata + 64 * blocks; - memset(pdata + len, 0, 64 * blocks - len); - pdata[len] = 0x80; - unsigned int bits = len * 8; - pend[-1] = (bits >> 0) & 0xff; - pend[-2] = (bits >> 8) & 0xff; - pend[-3] = (bits >> 16) & 0xff; - pend[-4] = (bits >> 24) & 0xff; - return blocks; -} - -static const unsigned int pSHA256InitState[8] = -{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; - -void SHA256Transform(void* pstate, void* pinput, const void* pinit) -{ - SHA256_CTX ctx; - unsigned char data[64]; - - SHA256_Init(&ctx); - - for (int i = 0; i < 16; i++) - ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); - - for (int i = 0; i < 8; i++) - ctx.h[i] = ((uint32_t*)pinit)[i]; - - SHA256_Update(&ctx, data, sizeof(data)); - for (int i = 0; i < 8; i++) - ((uint32_t*)pstate)[i] = ctx.h[i]; -} - // Some explaining would be appreciated class COrphan { @@ -4592,49 +4548,33 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& } -void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) -{ - // - // Pre-build hash buffers - // - struct - { - struct unnamed2 - { - int nVersion; - uint256 hashPrevBlock; - uint256 hashMerkleRoot; - unsigned int nTime; - unsigned int nBits; - unsigned int nNonce; - } - block; - unsigned char pchPadding0[64]; - uint256 hash1; - unsigned char pchPadding1[64]; - } - tmp; - memset(&tmp, 0, sizeof(tmp)); - - tmp.block.nVersion = pblock->nVersion; - tmp.block.hashPrevBlock = pblock->hashPrevBlock; - tmp.block.hashMerkleRoot = pblock->hashMerkleRoot; - tmp.block.nTime = pblock->nTime; - tmp.block.nBits = pblock->nBits; - tmp.block.nNonce = pblock->nNonce; - - FormatHashBlocks(&tmp.block, sizeof(tmp.block)); - FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); - - // Byte swap all the input buffer - for (unsigned int i = 0; i < sizeof(tmp)/4; i++) - ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]); - - // Precalc the first half of the first hash, which stays constant - SHA256Transform(pmidstate, &tmp.block, pSHA256InitState); - - memcpy(pdata, &tmp.block, 128); - memcpy(phash1, &tmp.hash1, 64); +void FormatDataBuffer(CBlock *pblock, uint *pdata) { + uint i; + + struct { + int nVersion; + uint256 hashPrevBlock; + uint256 hashMerkleRoot; + uint nTime; + uint nBits; + uint nNonce; + } data; + + data.nVersion = pblock->nVersion; + data.hashPrevBlock = pblock->hashPrevBlock; + data.hashMerkleRoot = pblock->hashMerkleRoot; + data.nTime = pblock->nTime; + data.nBits = pblock->nBits; + data.nNonce = pblock->nNonce; + + /* Block header size in bits */ + pdata[31] = 640; + /* Convert LE to BE and copy */ + for(i = 0; i < 20; i++) + pdata[i] = ByteReverse(((uint *) &data)[i]); + /* Erase the remaining part */ + for(i = 20; i < 31; i++) + pdata[i] = 0; } @@ -4778,11 +4718,10 @@ void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) // // Pre-build hash buffers // - char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); - char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); - char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf); + char pdatabuf[128+16]; + char *pdata = alignup<16>(pdatabuf); - FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1); + FormatDataBuffer(pblock.get(), (uint *) pdata); unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); // unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); diff --git a/src/main.h b/src/main.h index a562256..44cd26b 100644 --- a/src/main.h +++ b/src/main.h @@ -129,7 +129,7 @@ bool LoadExternalBlockFile(FILE* fileIn); void GenerateBitcoins(bool fGenerate, CWallet* pwallet); CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake=false); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); -void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); +void FormatDataBuffer(CBlock *pblock, unsigned int *pdata); bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash); int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 0011815..77c8d30 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -126,9 +126,7 @@ Value getwork(const Array& params, bool fHelp) throw runtime_error( "getwork [data]\n" "If [data] is not specified, returns formatted hash data to work on:\n" - " \"midstate\" : precomputed hash state after hashing the first half of the data (DEPRECATED)\n" // deprecated " \"data\" : block data\n" - " \"hash1\" : formatted hash buffer for second hash (DEPRECATED)\n" // deprecated " \"target\" : little endian hash target\n" "If [data] is specified, tries to solve the block and returns true if it was successful."); @@ -191,18 +189,13 @@ Value getwork(const Array& params, bool fHelp) // Save mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, pblock->vtx[0].vin[0].scriptSig); - // Pre-build hash buffers - char pmidstate[32]; char pdata[128]; - char phash1[64]; - FormatHashBuffers(pblock, pmidstate, pdata, phash1); + FormatDataBuffer(pblock, (uint *) pdata); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); Object result; - result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); // deprecated result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); - result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); // deprecated result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); return result; } @@ -249,9 +242,7 @@ Value getworkaux(const Array& params, bool fHelp) { " is the aux chain index in the aux chain merkle tree\n" " is the optional merkle branch of the aux chain\n" "If is not specified, returns formatted hash data to work on:\n" - " \"midstate\" : precomputed hash state after hashing the first half of the data\n" " \"data\" : block data\n" - " \"hash1\" : formatted hash buffer for second hash\n" " \"target\" : little endian hash target\n" "If is specified and 'submit', tries to solve the block for this (parent) chain and returns true if it was successful." "If is specified and empty first argument, returns the aux merkle root, with size and nonce." @@ -315,18 +306,13 @@ Value getworkaux(const Array& params, bool fHelp) { // Save mapNewBlock[pblock->hashMerkleRoot] = make_pair(pblock, nExtraNonce); - // Prebuild hash buffers - char pmidstate[32]; char pdata[128]; - char phash1[64]; - FormatHashBuffers(pblock, pmidstate, pdata, phash1); + FormatDataBuffer(pblock, (uint *) pdata); uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); Object result; - result.push_back(Pair("midstate", HexStr(BEGIN(pmidstate), END(pmidstate)))); result.push_back(Pair("data", HexStr(BEGIN(pdata), END(pdata)))); - result.push_back(Pair("hash1", HexStr(BEGIN(phash1), END(phash1)))); result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); return result; } @@ -467,7 +453,7 @@ Value getauxblock(const Array& params, bool fHelp) pblock->SetAuxPow(new CAuxPow()); // Save - mapNewBlock[pblock->GetHash()] = pblock; + mapNewBlock[pblock->GetHashGroestl()] = pblock; if (!pblock) throw JSONRPCError(-7, "Out of memory"); @@ -478,7 +464,7 @@ Value getauxblock(const Array& params, bool fHelp) Object result; result.push_back(Pair("target", HexStr(BEGIN(hashTarget), END(hashTarget)))); - result.push_back(Pair("hash", pblock->GetHash().GetHex())); + result.push_back(Pair("hash", pblock->GetHashGroestl().GetHex())); result.push_back(Pair("chainid", pblock->GetChainID())); return result; } diff --git a/src/util.h b/src/util.h index 260f6a5..c782777 100644 --- a/src/util.h +++ b/src/util.h @@ -31,6 +31,7 @@ typedef int pid_t; /* define for Windows compatibility */ typedef long long int64; typedef unsigned long long uint64; +typedef unsigned int uint; static const int64 COIN = 1000000; static const int64 CENT = 10000; From 86a1ade08d83aeeec2921c24610d938fbe8bb049 Mon Sep 17 00:00:00 2001 From: John Doering Date: Tue, 29 Mar 2016 05:30:46 +0300 Subject: [PATCH 180/218] Livenet Min. Stake Age Fixed Should exceed 761920 seconds (8.818519 days) according to the stake modifier interval of 6 hours. --- src/checkpoints.cpp | 4 ++-- src/kernel.cpp | 32 +++++++++++++++++++++++++------- src/kernel.h | 3 +++ src/main.cpp | 7 +++++-- src/main.h | 4 ++++ src/wallet.cpp | 4 ++-- 6 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 024fe26..fde274a 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -362,8 +362,8 @@ namespace Checkpoints // sync-checkpoint should always be accepted block assert(mapBlockIndex.count(hashSyncCheckpoint)); const CBlockIndex* pindexSync = mapBlockIndex[hashSyncCheckpoint]; - return (nBestHeight >= pindexSync->nHeight + nCoinbaseMaturity || - pindexSync->GetBlockTime() + nStakeMinAge < GetAdjustedTime()); + return((nBestHeight >= pindexSync->nHeight + nCoinbaseMaturity) || + (pindexSync->GetBlockTime() + nStakeMinAgeFixed < GetAdjustedTime())); } // Is the sync-checkpoint too old? diff --git a/src/kernel.cpp b/src/kernel.cpp index e324627..3fcad2d 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -33,14 +33,27 @@ static std::map mapStakeModifierCheckpoints = ( 317997, 0xfd318368u ) ; +/* Selects the appropriate minimal stake age */ +uint GetStakeMinAge(uint nStakeTime) { + + if(fTestNet) + return(nStakeMinAge); + + if(nStakeTime > nLiveTimeSwitch) + return(nStakeMinAgeFixed); + else + return(nStakeMinAge); +} + // Get time weight -int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd) -{ +int64 GetWeight(int64 nIntervalBeginning, int64 nIntervalEnd) { + uint nStakeMinAgeCurrent = GetStakeMinAge(nIntervalEnd); + // Kernel hash weight starts from 0 at the min age // this change increases active coins participating the hash and helps // to secure the network when proof-of-stake difficulty is low - return min(nIntervalEnd - nIntervalBeginning - nStakeMinAge, (int64)nStakeMaxAge); + return(min(nIntervalEnd - nIntervalBeginning - nStakeMinAgeCurrent, (int64)nStakeMaxAge)); } // Get the last stake modifier and its generation time from a given block @@ -240,6 +253,9 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier const CBlockIndex* pindexFrom = mapBlockIndex[hashBlockFrom]; nStakeModifierHeight = pindexFrom->nHeight; nStakeModifierTime = pindexFrom->GetBlockTime(); + + uint nStakeMinAgeCurrent = GetStakeMinAge(nStakeModifierTime); + int64 nStakeModifierSelectionInterval = GetStakeModifierSelectionInterval(); const CBlockIndex* pindex = pindexFrom; // loop to find the stake modifier later by a selection interval @@ -247,7 +263,7 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier { if (!pindex->pnext) { // reached best block; may happen if node is behind on block chain - if (fPrintProofOfStake || (pindex->GetBlockTime() + nStakeMinAge - nStakeModifierSelectionInterval > GetAdjustedTime())) + if(fPrintProofOfStake || (pindex->GetBlockTime() + nStakeMinAgeCurrent - nStakeModifierSelectionInterval > GetAdjustedTime())) return error("GetKernelStakeModifier() : reached best block %s at height %d from block %s", pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, hashBlockFrom.ToString().c_str()); else @@ -293,7 +309,10 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned return error("CheckStakeKernelHash() : nTime violation"); unsigned int nTimeBlockFrom = blockFrom.GetBlockTime(); - if (nTimeBlockFrom + nStakeMinAge > nTimeTx) // Min age requirement + + uint nStakeMinAgeCurrent = GetStakeMinAge(nTimeBlockFrom); + + if(nTimeBlockFrom + nStakeMinAgeCurrent > nTimeTx) // Min age requirement return error("CheckStakeKernelHash() : min age violation"); CBigNum bnTargetPerCoinDay; @@ -305,8 +324,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned // v0.3 protocol kernel hash weight starts from 0 at the min age // this change increases active coins participating the hash and helps // to secure the network when proof-of-stake difficulty is low -// DK changing calculations here creates a fork - int64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)nStakeMaxAge) - nStakeMinAge; + int64 nTimeWeight = min((int64)nTimeTx - txPrev.nTime, (int64)nStakeMaxAge) - nStakeMinAgeCurrent; CBigNum bnCoinDayWeight = CBigNum(nValueIn) * nTimeWeight / COIN / (24 * 60 * 60); // Calculate hash CDataStream ss(SER_GETHASH, 0); diff --git a/src/kernel.h b/src/kernel.h index 412deb3..cf0e3f4 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -14,6 +14,9 @@ extern unsigned int nModifierInterval; // ratio of group interval length between the last group and the first group static const int MODIFIER_INTERVAL_RATIO = 3; +/* Selects the appropriate minimal stake age */ +uint GetStakeMinAge(uint nStakeTime); + // Compute the hash modifier for proof-of-stake bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64& nStakeModifier, bool& fGeneratedStakeModifier); diff --git a/src/main.cpp b/src/main.cpp index ac27f19..1e0265d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ static CBigNum bnProofOfStakeLimit(~uint256(0) >> 20); static CBigNum bnProofOfWorkLimitTestNet(~uint256(0) >> 24); static CBigNum bnProofOfStakeLimitTestNet(~uint256(0) >> 16); unsigned int nStakeMinAge = 60 * 60 * 24 * 7; // minimum age for coin age: 7d +unsigned int nStakeMinAgeFixed = 60 * 60 * 24 * 9; /* must be > 8.82 days */ unsigned int nStakeMaxAge = 60 * 60 * 24 * 30; // stake age of full weight: 30d int64 nStakeTargetSpacing = 60; // 1-minute block spacing int64 nWorkTargetSpacing = 60; // 1-minute block spacing @@ -2065,7 +2066,7 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const CBlock block; if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) return false; // unable to read block of previous transaction - if (block.GetBlockTime() + nStakeMinAge > nTime) + if(block.GetBlockTime() + GetStakeMinAge(block.GetBlockTime()) > nTime) continue; // only count coins meeting min age requirement int64 nValueIn = txPrev.vout[txin.prevout.n].nValue; @@ -2800,6 +2801,7 @@ bool LoadBlockIndex(bool fAllowNew) bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; nStakeMinAge = 60 * 60; + nStakeMinAgeFixed = 60 * 60; nStakeMaxAge = 2 * 24 * 60 * 60; nModifierInterval = 5 * 60; nCoinbaseMaturity = 10; @@ -3589,7 +3591,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fDebug) printf(" getblocks (hashStop) stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes); // ppcoin: tell downloading node about the latest block if it's // without risk being rejected due to stake connection check - if (hashStop != hashBestChain && pindex->GetBlockTime() + nStakeMinAge > pindexBest->GetBlockTime()) + if((hashStop != hashBestChain) && + (pindex->GetBlockTime() + nStakeMinAgeFixed > pindexBest->GetBlockTime())) pfrom->PushInventory(CInv(MSG_BLOCK, hashBestChain)); break; } diff --git a/src/main.h b/src/main.h index 44cd26b..54b78d4 100644 --- a/src/main.h +++ b/src/main.h @@ -52,6 +52,9 @@ static const int nTestStage4 = 440; /* Testnet: enable merged mining */ /* Testnet: SHA-256 transaction hashing after 8-Feb-2016 15:00 UTC */ static const unsigned int nTestTxSwitch = 1454943600; +/* Livenet: SHA-256 transaction hashing and fixed min. stake age */ +static const unsigned int nLiveTimeSwitch = ~0U; + inline bool MoneyRange(int64 nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } // Threshold for nLockTime: below this value it is interpreted as block number, otherwise as UNIX timestamp. static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC @@ -79,6 +82,7 @@ extern std::set > setStakeSeen; extern uint256 hashGenesisBlock; extern CBlockIndex* pindexGenesisBlock; extern unsigned int nStakeMinAge; +extern unsigned int nStakeMinAgeFixed; extern int nCoinbaseMaturity; extern int nBestHeight; extern CBigNum bnBestChainTrust; diff --git a/src/wallet.cpp b/src/wallet.cpp index 4747b63..d9a6edb 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1422,7 +1422,7 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) continue; // Do not count input that is still too young - if (pcoin.first->nTime + nStakeMinAge > GetTime()) + if(pcoin.first->nTime + nStakeMinAgeFixed > GetTime()) continue; bnCentSecond += CBigNum(pcoin.first->vout[pcoin.second].nValue) * (GetTime() - pcoin.first->nTime) / CENT; @@ -1549,7 +1549,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int static int nMaxStakeSearchInterval = 60; - if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval) + if(block.GetBlockTime() + nStakeMinAgeFixed > txNew.nTime - nMaxStakeSearchInterval) continue; // only count coins meeting min age requirement bool fKernelFound = false; From 96353b3e9d268f4e419c8f331c0db497f4d14514 Mon Sep 17 00:00:00 2001 From: John Doering Date: Tue, 29 Mar 2016 05:55:39 +0300 Subject: [PATCH 181/218] Stake Combine Threshold Improved --- src/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index d9a6edb..16ad2d5 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1499,7 +1499,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // The following split & combine thresholds are important to security // Should not be adjusted if you don't understand the consequences static unsigned int nStakeSplitAge = fTestNet ? (60 * 60) : (60 * 60 * 24 * 30); // Age under which amounts are split in two - int64 nCombineThreshold = 100 * COIN; // amount to combine smaller coints into + int64 nCombineThreshold = fTestNet ? (100 * COIN) : (totalCoin / 10000); CBigNum bnTargetPerCoinDay; bnTargetPerCoinDay.SetCompact(nBits); From 6fba9549b49fe41037e12a1fa06b90054058177d Mon Sep 17 00:00:00 2001 From: John Doering Date: Tue, 29 Mar 2016 05:56:13 +0300 Subject: [PATCH 182/218] Expected Time to Stake Removed --- src/qt/bitcoingui.cpp | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 03dacc8..bd2dc30 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -976,28 +976,8 @@ void BitcoinGUI::updateMintingIcon() } else if (nLastCoinStakeSearchInterval) { - uint64 nEstimateTime = nStakeTargetSpacing * nNetworkWeight / nWeight; - - QString text; - if (nEstimateTime < 60) - { - text = tr("%n second(s)", "", nEstimateTime); - } - else if (nEstimateTime < 60*60) - { - text = tr("%n minute(s)", "", nEstimateTime/60); - } - else if (nEstimateTime < 24*60*60) - { - text = tr("%n hour(s)", "", nEstimateTime/(60*60)); - } - else - { - text = tr("%n day(s)", "", nEstimateTime/(60*60*24)); - } - labelMintingIcon->setEnabled(true); - labelMintingIcon->setToolTip(tr("Minting.
    Your weight is %1.
    Network weight is %2.
    Expected time to earn reward is %3.").arg(nWeight).arg(nNetworkWeight).arg(text)); + labelMintingIcon->setToolTip(tr("Minting.
    Your weight is %1.
    Network weight is %2.").arg(nWeight).arg(nNetworkWeight)); } else { From 8ea6da0bec9a3da6620b82666c7f49e190790b8f Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Thu, 31 Dec 2015 14:13:23 -0600 Subject: [PATCH 183/218] Add reactor code with test data Use a small set of addresses for a private test and an early start time Includes a passing test for stake confirmation checks --- diamond.pro | 7 +- src/bitcoinrpc.cpp | 3 +- src/bitcoinrpc.h | 1 + src/init.cpp | 14 +++- src/main.cpp | 36 ++++++--- src/main.h | 22 +++-- src/makefile.bsd | 5 +- src/makefile.linux-mingw | 4 +- src/makefile.mingw | 8 +- src/makefile.osx | 4 +- src/makefile.unix | 5 +- src/reactorlist.cpp | 54 +++++++++++++ src/reactors.cpp | 163 ++++++++++++++++++++++++++++++++++++++ src/reactors.h | 50 ++++++++++++ src/rpcwallet.cpp | 46 +++++++++++ src/script.cpp | 3 +- src/script.h | 3 +- src/test/reactortests.cpp | 62 +++++++++++++++ src/test/test_bitcoin.cpp | 3 +- src/wallet.cpp | 96 ++++++++++++++++++++-- src/wallet.h | 2 + 21 files changed, 551 insertions(+), 40 deletions(-) create mode 100644 src/reactorlist.cpp create mode 100644 src/reactors.cpp create mode 100644 src/reactors.h create mode 100644 src/test/reactortests.cpp diff --git a/diamond.pro b/diamond.pro index 664f732..be622cf 100644 --- a/diamond.pro +++ b/diamond.pro @@ -229,7 +229,8 @@ HEADERS += src/qt/bitcoingui.h \ src/scrypt.h \ src/sph_groestl.h \ src/sph_types.h \ - src/auxpow.h + src/auxpow.h \ + src/reactors.h SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/transactiontablemodel.cpp \ @@ -301,7 +302,9 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/hash.cpp \ src/scrypt.cpp \ src/groestl.c \ - src/auxpow.cpp + src/auxpow.cpp \ + src/reactors.cpp \ + src/reactorlist.cpp RESOURCES += \ src/qt/bitcoin.qrc diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index d7e9617..a2f4c68 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -274,7 +274,8 @@ static const CRPCCommand vRPCCommands[] = { "getscrapeaddress", &getscrapeaddress, true, false }, { "listscrapeaddresses", &listscrapeaddresses, true, false }, { "setscrapeaddress", &setscrapeaddress, true, true }, - { "deletescrapeaddress", &deletescrapeaddress, true, true } + { "deletescrapeaddress", &deletescrapeaddress, true, true }, + { "listreactordata", &listreactordata, true, false } }; CRPCTable::CRPCTable() diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index c80d075..47d04c0 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -192,6 +192,7 @@ extern json_spirit::Value makekeypair(const json_spirit::Array& params, bool fHe extern json_spirit::Value validatepubkey(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnewpubkey(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listreactordata(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); diff --git a/src/init.cpp b/src/init.cpp index 4cf60cd..07d3e98 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -10,6 +10,7 @@ #include "util.h" #include "ui_interface.h" #include "checkpoints.h" +#include "reactors.h" #include #include #include @@ -903,7 +904,16 @@ bool AppInit2() printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n", addrman.size(), GetTimeMillis() - nStart); - // ********************************************************* Step 11: start node + // ********************************************************* Step 11: initialize reactor db + + uiInterface.InitMessage(_("Loading reactors...")); + printf("Loading reactors...\n"); + nStart = GetTimeMillis(); + + InitReactors(); + printf(" reactors %" PRI64d "ms\n", GetTimeMillis() - nStart); + + // ********************************************************* Step 12: start node if (!CheckDiskSpace()) return false; @@ -923,7 +933,7 @@ bool AppInit2() if (fServer) NewThread(ThreadRPCServer, NULL); - // ********************************************************* Step 12: finished + // ********************************************************* Step 13: finished uiInterface.InitMessage(_("Done loading")); printf("Done loading\n"); diff --git a/src/main.cpp b/src/main.cpp index 1e0265d..bc9bca1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ #include "ui_interface.h" #include "kernel.h" #include "scrypt_mine.h" +#include "reactors.h" #include #include #include @@ -997,10 +998,11 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) // miner's coin stake reward based on nBits and coin age spent (coin-days) // simple algorithm, not depend on the diff -int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight) +int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight, int reactorRate) { int64 nRewardCoinYear; int64 nSubsidy = 0; + if (totalCoin > VALUE_CHANGE || fTestNet) { nRewardCoinYear = MAX_MINT_PROOF_OF_STAKE; @@ -1061,6 +1063,11 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi nRewardCoinYear = bnUpperBound.getuint64(); nRewardCoinYear = min((nRewardCoinYear / CENT) * CENT, MAX_MINT_PROOF_OF_STAKE); + /* If the reactor rate is greater than 0 adjust the nRewardCoinYear by + * the given rate. */ + if (reactorRate > 0) + nRewardCoinYear = nRewardCoinYear * (reactorRate * CENT); + nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear; if (fDebug && GetBoolArg("-printcreation")) printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits); @@ -1535,9 +1542,16 @@ bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs, uint64 nCoinAge; if (!GetCoinAge(txdb, nCoinAge)) return error("ConnectInputs() : %s unable to get coin age for coinstake", GetHash().ToString().substr(0,10).c_str()); - int64 nStakeReward = GetValueOut() - nValueIn; - if (nStakeReward > GetProofOfStakeReward(nCoinAge, pindexBlock->nBits, nTime, pindexBlock->nHeight) - GetMinFee() + MIN_TX_FEE) - return DoS(100, error("ConnectInputs() : %s stake reward exceeded", GetHash().ToString().substr(0,10).c_str())); + + // If vout[0] is not empty check if this is a reactor stake. + if (!vout[0].IsEmpty()) { + // OP_REACTOR is stored in vout[0] destination is stored in vout[1] + return IsReactorStake(GetReactorDBFile(), vout[0].scriptPubKey, vout[1].scriptPubKey, nTime, nValueIn, GetValueOut(), nCoinAge, pindexBlock->nBits, pindexBlock->nHeight); + } else { + int64 nStakeReward = GetValueOut() - nValueIn; + if (nStakeReward > GetProofOfStakeReward(nCoinAge, pindexBlock->nBits, nTime, pindexBlock->nHeight) - GetMinFee() + MIN_TX_FEE) + return DoS(100, error("ConnectInputs() : %s stake reward exceeded", GetHash().ToString().substr(0,10).c_str())); + } } else { @@ -2040,7 +2054,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) // ppcoin: total coin age spent in transaction, in the unit of coin-days. // Only those coins meeting minimum age requirement counts. As those // transactions not in main chain are not currently indexed so we -// might not find out about their coin age. Older transactions are +// might not find out about their coin age. Older transactions are // guaranteed to be in main chain by sync-checkpoint. This rule is // introduced to help nodes establish a consistent view of the coin // age (trust score) of competing branches. @@ -2183,9 +2197,9 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) } // Start accepting AUX POW at this block -// +// // Even if we do not accept AUX POW ourselves, we can always be the parent chain. - + int GetAuxPowStartBlock() { if(fTestNet) return(nTestStage4); @@ -2522,7 +2536,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) pblock->print(); printf("\n"); } - // danbi: Only refuse this block if time distance between the last sync checkpoint + // danbi: Only refuse this block if time distance between the last sync checkpoint // and the block's time is less than the checkpoints max span if (deltaTime < CHECKPOINT_MAX_SPAN) return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work"); @@ -3530,7 +3544,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (inv.hash == pfrom->hashContinue) { // ppcoin: send latest proof-of-work block to allow the - // download node to accept as orphan (proof-of-stake + // download node to accept as orphan (proof-of-stake // block might be rejected by stake connection check) vector vInv; vInv.push_back(CInv(MSG_BLOCK, GetLastBlockIndex(pindexBest, false)->GetBlockHash())); @@ -4200,7 +4214,7 @@ class COrphan uint64 nLastBlockTx = 0; uint64 nLastBlockSize = 0; int64 nLastCoinStakeSearchInterval = 0; - + // We want to sort transactions by priority and fee, so: typedef boost::tuple TxPriority; class TxPriorityCompare @@ -4587,7 +4601,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256(); if(pblock->IsProofOfWork()) { - CAuxPow *auxpow = pblock->auxpow.get(); + CAuxPow *auxpow = pblock->auxpow.get(); if(auxpow != NULL) { if(!auxpow->Check(hash, pblock->GetChainID())) diff --git a/src/main.h b/src/main.h index 54b78d4..c5f0ef8 100644 --- a/src/main.h +++ b/src/main.h @@ -136,7 +136,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& void FormatDataBuffer(CBlock *pblock, unsigned int *pdata); bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash); -int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight); +int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight, int reactorRate = 0); unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); unsigned int ComputeMinStake(unsigned int nBase, int64 nTime, unsigned int nBlockTime); int GetNumBlocksOfPeers(); @@ -564,8 +564,13 @@ class CTransaction bool IsCoinStake() const { - // ppcoin: the coin stake transaction is marked with the first output empty - return (vin.size() > 0 && (!vin[0].prevout.IsNull()) && vout.size() >= 2 && vout[0].IsEmpty()); + /* Reactor stakes are marked with an OP code in the first output all + * other stakes are marked by having the first output left empty. */ + if (!vout[0].IsEmpty() && vout[0].scriptPubKey[0] == OP_REACTOR) { + return (vin.size() > 0 && (!vin[0].prevout.IsNull()) && vout.size() >= 2 && vout[0].scriptPubKey[0] == OP_REACTOR); + } else { + return (vin.size() > 0 && (!vin[0].prevout.IsNull()) && vout.size() >= 2 && vout[0].IsEmpty()); + } } bool IsCoinBaseOrStake() const @@ -573,6 +578,13 @@ class CTransaction return (IsCoinBase() || IsCoinStake()); } + /** Check if a stake transaction is a reactor stake + this is defined in reactors.cpp and is utilized in ConnectInputs. + Passes the database filename so that tests can be ran on a mockdb + instead of using the db in the datadir. + @ return True for valid and DoS or false for all else. + */ + bool IsReactorStake(std::string strFileName, CScript scriptPubKeyType, CScript scriptPubKeyAddress, unsigned int nTime, int64 nValueIn, int64 nValueOut, uint64 nCoinAge, unsigned int nBits, int nHeight); /** Check for standard transaction types @return True if all outputs (scriptPubKeys) use only standard transaction forms @@ -1234,7 +1246,7 @@ class CBlockIndex int64 nMoneySupply; unsigned int nFlags; // ppcoin: block index flags - enum + enum { BLOCK_PROOF_OF_STAKE = (1 << 0), // is proof-of-stake block BLOCK_STAKE_ENTROPY = (1 << 1), // entropy bit for stake modifier @@ -1438,7 +1450,7 @@ class CBlockIndex pprev, pnext, nFile, nBlockPos, nHeight, FormatMoney(nMint).c_str(), FormatMoney(nMoneySupply).c_str(), GeneratedStakeModifier() ? "MOD" : "-", GetStakeEntropyBit(), IsProofOfStake()? "PoS" : "PoW", - nStakeModifier, nStakeModifierChecksum, + nStakeModifier, nStakeModifierChecksum, hashProofOfStake.ToString().c_str(), prevoutStake.ToString().c_str(), nStakeTime, hashMerkleRoot.ToString().c_str(), diff --git a/src/makefile.bsd b/src/makefile.bsd index 1e93741..7b5fcbf 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -143,8 +143,9 @@ OBJS= \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ obj/scrypt-x86_64.o \ - obj/auxpow.o - + obj/auxpow.o \ + obj/reactors.o \ + obj/reactorlist.o all: diamondd diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 909bf04..34c4be4 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -88,7 +88,9 @@ OBJS= \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ obj/scrypt-x86_64.o \ - obj/auxpow.o + obj/auxpow.o \ + obj/reactors.o \ + obj/reactorlist.o all: diamondd.exe diff --git a/src/makefile.mingw b/src/makefile.mingw index ca5986c..34f7061 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -9,11 +9,11 @@ INCLUDEPATHS= \ -I"C:\deps\boost_1_55_0" \ -I"C:\deps\db-4.8.30.NC\build_unix" \ -I"C:\deps\openssl-1.0.1e\include - + LIBPATHS= \ -L"C:\deps\boost_1_55_0\stage/lib" \ -L"C:\deps\db-4.8.30.NC\build_unix" \ - -L"C:\deps\openssl-1.0.1e" + -L"C:\deps\openssl-1.0.1e" LIBS= \ -l boost_system-mgw45-mt-d-1_55 \ @@ -84,7 +84,9 @@ OBJS= \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ obj/scrypt-x86_64.o \ - obj/auxpow.o + obj/auxpow.o \ + obj/reactors.o \ + obj/reactorlist.o all: diamondd.exe diff --git a/src/makefile.osx b/src/makefile.osx index 5c74614..a08de85 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -105,7 +105,9 @@ OBJS= \ obj/scrypt_mine.o \ obj/scrypt-x86.o \ obj/scrypt-x86_64.o \ - obj/auxpow.o + obj/auxpow.o \ + obj/reactors.o \ + obj/reactorlist.o ifndef USE_UPNP override USE_UPNP = - diff --git a/src/makefile.unix b/src/makefile.unix index e5fd8fc..dd2369a 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -147,8 +147,9 @@ OBJS= \ obj/scrypt-x86.o \ obj/scrypt-x86_64.o \ obj/scrypt-arm.o \ - obj/auxpow.o - + obj/auxpow.o \ + obj/reactors.o \ + obj/reactorlist.o all: diamondd diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp new file mode 100644 index 0000000..7c3dc3e --- /dev/null +++ b/src/reactorlist.cpp @@ -0,0 +1,54 @@ +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "reactors.h" + +// TODO replace with proper time +unsigned int REACTOR_START_TIME = 1453075200; + +void CReactorDB::WriteReactorDB() { + LOCK(cs); + + WriteReactorDBVersion(CURRENT_REACTOR_VERSION); + + // Year 1 group 1 + WriteReactorAddr(std::string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); + WriteReactorAddr(std::string("dRS7Rnjp8wjrKigAPfbP56bfEsNA7wfoJ8"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); + WriteReactorAddr(std::string("dVUu5KNpGBLFcUWyKTBrVnkniHNQasRN5b"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); + WriteReactorAddr(std::string("dRUAjN82ySuftGFuQonboB8bvyiNp561pA"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); + WriteReactorAddr(std::string("daiPqSjPMNpxqX4UDnhcsgv1GazoDzNXZb"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); + + // Year 1 group 2 + WriteReactorAddr(std::string("dcF2DnzGyi7XdPiHFfUK8eZS2ad4Tfn3jt"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + + // Year 2 group 1 + WriteReactorAddr(std::string("dReEVEHa7o9AJreZfnrB1rDtDqvuh9eeVL"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + + // Year 2 group 2 + WriteReactorAddr(std::string("dXizuUsA36u4u1BaPzMLp693QhdvkDCdWq"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + + // Year 3 group 1 + WriteReactorAddr(std::string("dFvsna2hKRw98tuyHLwDhnefgSmhqfF8YK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + + // Year 3 group 2 + WriteReactorAddr(std::string("dbEz4pgizZ6UfMnbasZcxnXLsdXxBrj74e"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + + // Year 4 group 1 + WriteReactorAddr(std::string("dFx64NPzLDDXTK1ajJ4w82bX7ra6RPzCvN"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + + // Year 4 group 2 + WriteReactorAddr(std::string("dJFFCAK9pBVsiRQuhbQvkiVjLXKYVyap7Z"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + + // Year 5 group 1 + WriteReactorAddr(std::string("dDepYKJesaenykkJpqZuzKir8crcymJ15w"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + + // Year 5 group 2 + WriteReactorAddr(std::string("dVJf23zDxRTtpQVP5ZUU6L83DmcJVxtCBa"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + + // Legendaries (only list max here), no shutoff time. + WriteReactorAddr(std::string("dGXqvYugQ11mf2rmp4L2M8vRRigjU1Mv8S"), REACTOR_START_TIME, -1, 15000); + + // Foundation, no shutoff time. + WriteReactorAddr(std::string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6"), REACTOR_START_TIME, -1, 10000); +} diff --git a/src/reactors.cpp b/src/reactors.cpp new file mode 100644 index 0000000..87e6278 --- /dev/null +++ b/src/reactors.cpp @@ -0,0 +1,163 @@ +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "base58.h" +#include "util.h" +#include "reactors.h" + +using namespace std; + +int CURRENT_REACTOR_VERSION = -1; // Test version + +bool maybeWipeReactorDB(string strFileName) { + int dbversion; + if (CReactorDB(strFileName).CheckReactorDBVersion(dbversion)) { + if (dbversion == CURRENT_REACTOR_VERSION) + return false; + } + + // No version set or version is invalid, wipe the DB. + printf("maybeWipeReactorDB() : reactor databse is outdated, removing for recreation\n"); + CReactorDB(strFileName).Close(); + bitdb.CloseDb("reactors.dat"); + boost::filesystem::remove(strFileName); + // Return true so we know to re-inflate the DB. + return true; +} + +/* This function should not be called by tests (is not currently required for + * them) as it will use the reactor.dat found in the datadir instead of the + * mockdb. */ +void InitReactors() { + bool inflatedb = false; + // Check if the reactor database exists and check the version if it does. + string reactordbfile = GetReactorDBFile(); + if (boost::filesystem::exists(boost::filesystem::path(reactordbfile))) { + if (maybeWipeReactorDB(reactordbfile)) + inflatedb = true; + + if (!inflatedb) { + // TODO Replace with correct first and last reactor addresses. + if (!CReactorDB(reactordbfile).CheckReactorAddr(string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ")) + || !CReactorDB(reactordbfile).CheckReactorAddr(string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6"))) + inflatedb = true; + } + } else { + inflatedb = true; + } + + if (inflatedb) + InflateReactorDB(reactordbfile); +} + +bool CTransaction::IsReactorStake(string strFileName, CScript scriptPubKeyType, CScript scriptPubKeyAddress, unsigned int nTime, int64 nValueIn, int64 nValueOut, uint64 nCoinAge, unsigned int nBits, int nHeight) { + int64 nStakeReward = nValueOut - nValueIn; + + // Should never be anything else. + if (scriptPubKeyType[0] == OP_REACTOR) { + unsigned int valid_starting; + unsigned int valid_until; + int64 reactorStakeValue; + + /* Destination address is stored in the CScript for vout[1] of the input + * so extract it against our database. */ + if (!CReactorDB(strFileName).IsReactor(strFileName, scriptPubKeyAddress, reactorStakeValue, valid_starting, valid_until)) + return DoS(100, error("IsReactorStake() : invalid reactor address, HAXORS!!!")); + + if (nTime < valid_starting) + return DoS(100, error("IsReactorStake() : reactor is not valid yet")); + + if (nTime >= valid_until && valid_until != (unsigned int)-1) + return DoS(100, error("IsReactorStake() : reactor is expired")); + + /* If this is a reactor check that the size of the stake matches the + * requirements of the given reactor.*/ + if (reactorStakeValue == 3000 || reactorStakeValue == 15000) { + if (nValueIn < (reactorStakeValue * COIN)) + return DoS(100, error("IsReactorStake() : nValueIn doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %d or %d", nValueIn, 3000, 15000)); + + if (nValueIn > (reactorStakeValue * COIN)) + return DoS(100, error("IsReactorStake() : nValueIn exceeds value of reactor; credit %" PRI64d "; reactor size %d or %d", nValueIn, 3000, 15000)); + } else { + if (nValueIn < (reactorStakeValue * COIN)) + return DoS(100, error("IsReactorStake() : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); + + if (nValueIn > (reactorStakeValue * COIN)) + return DoS(100, error("IsReactorStake() : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); + } + + if (nStakeReward > GetProofOfStakeReward(nCoinAge, nBits, nTime, nHeight, GetReactorRate(reactorStakeValue, nValueIn)) - GetMinFee() + MIN_TX_FEE) + return DoS(100, error("IsReactorStake() : %s stake reward exceeded", GetHash().ToString().substr(0, 10).c_str())); + + return true; + } + + return false; +} + +// Inflate the reactor table in the reactorDB +void InflateReactorDB(string strFileName) { + printf("InflateReactorDB() : inflating reactor database.\n"); + + CReactorDB(strFileName, "cw+").WriteReactorDB(); +} + +int GetReactorRate(int64 reactorStakeValue, int64 nValueIn) { + if (reactorStakeValue == 1000 || reactorStakeValue == 10000) + return 2; + + /* We store the max value of the Legendaries in the database and override + * the rate for 3000 coin stakes here. */ + if (reactorStakeValue == 15000 && nValueIn == 3000) + return 2; + + if (reactorStakeValue == 15000 && nValueIn == 15000) + return 1.5; + + return 0; +} + +bool CReactorDB::WriteReactorDBVersion(int version) +{ + return Write(string("dbversion"), version); +} + +bool CReactorDB::WriteReactorAddr(const string address, unsigned int valid_starting, unsigned int valid_until, int64 reactorStakeValue) +{ + return Write(make_pair(string("reactor"), address), boost::make_tuple(valid_starting, valid_until, reactorStakeValue)); +} + +bool CReactorDB::CheckReactorDBVersion(int &version) +{ + if (!Exists(string("dbversion"))) + return false; + + Read(string("dbversion"), version); + return true; +} + +bool CReactorDB::CheckReactorAddr(const string address) +{ + return Exists(make_pair(string("reactor"), address)); +} + +bool CReactorDB::IsReactor(std::string strFileName, CScript scriptPubKeyAddress, int64 &reactorStakeValue, unsigned int &valid_starting, unsigned int &valid_until) +{ + CTxDestination address; + ExtractDestination(scriptPubKeyAddress, address); + CBitcoinAddress addr(address); + + // Check if the address exists in the reactor database. + if (!CReactorDB(strFileName).CheckReactorAddr(addr.ToString())) + return false; + + boost::tuple t; + Read(make_pair(string("reactor"), addr.ToString()), t); + + valid_starting = t.get<0>(); + valid_until = t.get<1>(); + + reactorStakeValue = t.get<2>(); + return true; +} diff --git a/src/reactors.h b/src/reactors.h new file mode 100644 index 0000000..6fce97a --- /dev/null +++ b/src/reactors.h @@ -0,0 +1,50 @@ +// Copyright (c) 2015-2016 Nathan Bass "IngCr3at1on" +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef REACTORS_H +#define REACTORS_H + +#include "db.h" +#include "script.h" + +extern int CURRENT_REACTOR_VERSION; +extern unsigned int REACTOR_START_TIME; + +void InitReactors(); + +class CReactorDB : public CDB +{ +public: + CReactorDB(std::string strFileName, const char *pszMode="r+") : CDB(strFileName.c_str(), pszMode) { } +private: + mutable CCriticalSection cs; + + CReactorDB(const CReactorDB&); + void operator=(const CReactorDB); + + bool WriteReactorAddr(const std::string /*address*/, unsigned int /*valid_starting*/, unsigned int /*valid_until*/, int64 /*reactorStakeValue*/); + bool WriteReactorDBVersion(int /*version*/); +public: + void WriteReactorDB(); + void WriteTestReactorDB(); + + bool CheckReactorDBVersion(int &/*version*/); + + bool IsReactor(std::string /*strFileName*/, CScript /*scriptPubKeyAddress*/, int64 &/*reactorStakeValue*/, unsigned int &/*valid_starting*/, unsigned int &/*valid_until*/); + bool CheckReactorAddr(const std::string /*address*/); +}; + +/* Pass the filename instead of getting it in the function so that we can + * properly run tests in a mock db instead of using the db in the datadir.*/ +void InflateReactorDB(std::string strFileName); + +/* Get the reactorRate (Legendaries have two possible rates so use nValueIn + * when calculating for them). */ +int GetReactorRate(int64 /*reactorStakeValue*/, int64 /*nValueIn*/); + +inline std::string GetReactorDBFile() { + return (GetDataDir() / "reactors.dat").string(); +} + +#endif // REACTORS_H diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 774222e..ecd175f 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -9,6 +9,7 @@ #include "bitcoinrpc.h" #include "init.h" #include "base58.h" +#include "reactors.h" using namespace json_spirit; using namespace std; @@ -1953,3 +1954,48 @@ Value deletescrapeaddress(const Array& params, bool fHelp) return pwalletMain->EraseScrapeAddress(strAddress); } + +Value listreactordata(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "listreactordata\n" + "List the data regarding a given reactor address (only lists\n" + "valid addresses found in wallet)."); + + string strAddress = params[0].get_str(); + CBitcoinAddress address(strAddress); + + if (!IsMine(*pwalletMain, address.Get())) + throw runtime_error("Address must be in wallet."); + + string reactordbfile = GetReactorDBFile(); + if (!CReactorDB(reactordbfile).CheckReactorAddr(strAddress)) + throw runtime_error("Address is not a valid reactor address."); + + int64 reactorStakeValue; + unsigned int valid_starting; + unsigned int valid_until; + CScript scriptReactorAddress; + scriptReactorAddress.SetDestination(address.Get()); + if (!CReactorDB(reactordbfile).IsReactor(reactordbfile, scriptReactorAddress, reactorStakeValue, valid_starting, valid_until)) + throw runtime_error("Address is not a valid reactor address."); + + Object obj; + obj.push_back(Pair("Address", strAddress)); + if (reactorStakeValue == 15000) { + obj.push_back(Pair("Value 1", 3000)); + obj.push_back(Pair("Value 2", (int)reactorStakeValue)); + } else { + obj.push_back(Pair("Value", (int)reactorStakeValue)); + } + obj.push_back(Pair("Valid starting", (int)valid_starting)); + + if (valid_until == (unsigned int)-1) { + obj.push_back(Pair("Expires", "never")); + } else { + obj.push_back(Pair("Expires", (int)valid_until)); + } + + return obj; +} diff --git a/src/script.cpp b/src/script.cpp index 7184679..ed4a177 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -238,7 +238,8 @@ const char* GetOpName(opcodetype opcode) case OP_NOP9 : return "OP_NOP9"; case OP_NOP10 : return "OP_NOP10"; - + // Reactors + case OP_REACTOR : return "OP_REACTOR"; // template matching params case OP_PUBKEYHASH : return "OP_PUBKEYHASH"; diff --git a/src/script.h b/src/script.h index 99465cb..1fc2314 100644 --- a/src/script.h +++ b/src/script.h @@ -189,7 +189,8 @@ enum opcodetype OP_NOP9 = 0xb8, OP_NOP10 = 0xb9, - + // Reactors + OP_REACTOR = 0xc0, // template matching params OP_SMALLINTEGER = 0xfa, diff --git a/src/test/reactortests.cpp b/src/test/reactortests.cpp new file mode 100644 index 0000000..cd46d92 --- /dev/null +++ b/src/test/reactortests.cpp @@ -0,0 +1,62 @@ +#include + +#include "base58.h" +#include "main.h" +#include "reactors.h" + +using namespace std; + +BOOST_AUTO_TEST_SUITE(reactor_tests) + +BOOST_AUTO_TEST_CASE(reactor_validity) +{ + CScript scriptPubKeyAddress; + CScript scriptReactorOP; + string strReactorValid = "dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ"; + string strReactorValid2 = "dcF2DnzGyi7XdPiHFfUK8eZS2ad4Tfn3jt"; + string strReactorInvalid = "dVSWVAnKL4BzVBAAvVDbatWfKeEpxXnLXT"; + + scriptReactorOP << OP_REACTOR; + + // Empty database, returns false. + BOOST_CHECK(!CReactorDB("reactors.dat").CheckReactorAddr(strReactorValid)); + BOOST_CHECK(!CReactorDB("reactors.dat").CheckReactorAddr(strReactorInvalid)); + + // Inflate the database. + InflateReactorDB("reactors.dat"); + + BOOST_CHECK(CReactorDB("reactors.dat").CheckReactorAddr(strReactorValid)); + BOOST_CHECK(!CReactorDB("reactors.dat").CheckReactorAddr(strReactorInvalid)); + + CBitcoinAddress addr(strReactorValid); + scriptPubKeyAddress.SetDestination(addr.Get()); + + CTransaction tx; + BOOST_CHECK(tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME, 1000 * COIN, 0, 0, 0, 0)); + // Value exceeds max stakeable balance of address (reactorStakeValue) + BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME, 1000 * COIN + 1, 0, 0, 0, 0)); + // Value in is too low for reactor + BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME, 1000 * COIN - 1, 0, 0, 0, 0)); + // Excessive reward. + BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME, 1000 * COIN, 1500 * COIN, 0, 0, 0)); + + // Invalid reactor address + addr = CBitcoinAddress(strReactorInvalid); + scriptPubKeyAddress.clear(); + scriptPubKeyAddress.SetDestination(addr.Get()); + BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME, 1000 * COIN, 0, 0, 0, 0)); + + // Not yet valid + addr = CBitcoinAddress(strReactorValid2); + scriptPubKeyAddress.clear(); + scriptPubKeyAddress.SetDestination(addr.Get()); + BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME, 1000 * COIN, 0, 0, 0, 0)); + + // Expired + addr = CBitcoinAddress(strReactorValid); + scriptPubKeyAddress.clear(); + scriptPubKeyAddress.SetDestination(addr.Get()); + BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000 * COIN, 0, 0, 0, 0)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 5f50e9a..5181997 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -15,7 +15,7 @@ bool fUseFastIndex = true; struct TestingSetup { TestingSetup() { - fPrintToDebugger = true; // don't want to write to debug.log file + fPrintToConsole = true; // don't want to write to debug.log file noui_connect(); bitdb.MakeMock(); LoadBlockIndex(true); @@ -43,4 +43,3 @@ void StartShutdown() { exit(0); } - diff --git a/src/wallet.cpp b/src/wallet.cpp index 16ad2d5..579ad0d 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -13,6 +13,7 @@ #include "kernel.h" #include "auxpow.h" #include "coincontrol.h" +#include "reactors.h" #include @@ -1506,10 +1507,10 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int txNew.vin.clear(); txNew.vout.clear(); - // Mark coin stake transaction - CScript scriptEmpty; - scriptEmpty.clear(); - txNew.vout.push_back(CTxOut(0, scriptEmpty)); + + /* Wait to mark non-reactor stakes until after we know what coins are + * staking. */ + // Choose coins to use int64 nBalance = GetBalance(); int64 nReserveBalance = 0; @@ -1529,6 +1530,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int int64 nCredit = 0; CScript scriptPubKeyKernel; + + int64 reactorStakeValue; + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { CTxDB txdb("r"); @@ -1599,6 +1603,35 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int scriptPubKeyOut = scriptPubKeyKernel; txNew.nTime -= n; + /* We found a kernel so we can check if it's address matches a + * reactor address. Do this now, before splitting the stake so + * that reactors don't split their stake and before adding the + * PubKeyOut to the transaction */ + CScript scriptStake; + unsigned int valid_starting; + unsigned int valid_until; + string reactordbfile = GetReactorDBFile(); + /* Check if the staking address is a reactor and if it is active + * and if so mark the stake as a reactor stake (otherwise mark + * it as a standard stake); if it is a reactor stake we also + * change the nComebineThreshold to be the size of the reactor. + * + * We pass the DB file because we run CheckReactorAddr() from + * within IsReactor(), this allows tests to be ran on a mockdb + * instead of in the diamond directory on the system. */ + if (CReactorDB(reactordbfile).IsReactor(reactordbfile, scriptPubKeyOut, reactorStakeValue, valid_starting, valid_until)) { + // Check that the reactor is active. + if (txNew.nTime >= valid_starting && (txNew.nTime < valid_until || valid_until == (unsigned int)-1)) { + scriptStake << OP_REACTOR; + nCombineThreshold = reactorStakeValue * COIN; + } else { + /* Just make sure the script being pushed to vout is + * blank to mark the stake as a standard stake. */ + scriptStake.clear(); + } + txNew.vout.push_back(CTxOut(0, scriptStake)); + } + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; @@ -1606,7 +1639,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int vwtxPrev.push_back(pcoin.first); txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); - if (block.GetBlockTime() + nStakeSplitAge > txNew.nTime) + // Don't split the stake on reactors. + if (block.GetBlockTime() + nStakeSplitAge > txNew.nTime && reactorStakeValue == 0) txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake if (fDebug && GetBoolArg("-printcoinstake")) @@ -1661,7 +1695,30 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (!txNew.GetCoinAge(txdb, nCoinAge)) return error("CreateCoinStake : failed to calculate coin age"); - int64 nReward = GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime, pIndex0->nHeight); + + if (reactorStakeValue > 0) { + int64 addressbalance; + if (GetSingleAddressBalance(txNew.vout[1].scriptPubKey, addressbalance) > reactorStakeValue * COIN) + return error("CreateCoinStake : address balance is too high for reactor size; address balance %" PRI64d "; reactor size %" PRI64d "\n", addressbalance, reactorStakeValue); + + /* If this is a reactor check that the size of the stake matches the + * requirements of the given reactor.*/ + if (reactorStakeValue == 3000 || reactorStakeValue == 15000) { + if (nCredit < (reactorStakeValue * COIN)) + return error("CreateCoinStake : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %d or %d\n", nCredit, 3000, 15000); + + if (nCredit > (reactorStakeValue * COIN)) + return error("CreateCoinStake : credit exceeds value of reactor; credit %" PRI64d "; reactor size %d or %d\n", nCredit, 3000, 15000); + } else { + if (nCredit < (reactorStakeValue * COIN)) + return error("CreateCoinStake : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); + + if (nCredit > (reactorStakeValue * COIN)) + return error("CreateCoinStake : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); + } + } + + int64 nReward = GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime, pIndex0->nHeight, GetReactorRate(reactorStakeValue, nCredit)); /* Check the staking address against the scrape addresses in the * walletdb and see if it has a scrape address for it, if it does @@ -2114,6 +2171,33 @@ int64 CWallet::GetOldestKeyPoolTime() return keypool.nTime; } +/* Return false if the address balance being looked up is not an address in this + * wallet. */ +bool CWallet::GetSingleAddressBalance(CTxDestination address, int64 &balance) +{ + std::map addressbalances = GetAddressBalances(); + /* If the address is not ours it won't be in the addressbalances and + * std::map::at will throw an out_of_range exception. If thrown, catch it + * and return false.*/ + try { + balance = addressbalances.at(address); + return true; + } catch (const std::out_of_range &oor) { + return false; + } +} + +/* Overload for the above that allows a CScript instead of CTxDestination. + * Just return the above if an address is extracted from the key. */ +bool CWallet::GetSingleAddressBalance(CScript scriptPubKey, int64 &balance) +{ + CTxDestination addr; + if(!ExtractDestination(scriptPubKey, addr)) + return false; + + return GetSingleAddressBalance(addr, balance); +} + std::map CWallet::GetAddressBalances() { map balances; diff --git a/src/wallet.h b/src/wallet.h index a4d6700..1876078 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -185,6 +185,8 @@ class CWallet : public CCryptoKeyStore bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false, std::string strTxComment = ""); + bool GetSingleAddressBalance(CTxDestination address, int64 &balance); + bool GetSingleAddressBalance(CScript scriptPubKey, int64 &balance); bool NewKeyPool(); bool TopUpKeyPool(); From 84ceb45ea4ed099d13210e84d9274dea22459753 Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Fri, 15 Jan 2016 12:53:09 -0600 Subject: [PATCH 184/218] Change reactor shutdown times to run for 1 year instead of 6 months --- src/reactorlist.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index 7c3dc3e..0acf8ac 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -13,38 +13,38 @@ void CReactorDB::WriteReactorDB() { WriteReactorDBVersion(CURRENT_REACTOR_VERSION); // Year 1 group 1 - WriteReactorAddr(std::string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); - WriteReactorAddr(std::string("dRS7Rnjp8wjrKigAPfbP56bfEsNA7wfoJ8"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); - WriteReactorAddr(std::string("dVUu5KNpGBLFcUWyKTBrVnkniHNQasRN5b"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); - WriteReactorAddr(std::string("dRUAjN82ySuftGFuQonboB8bvyiNp561pA"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); - WriteReactorAddr(std::string("daiPqSjPMNpxqX4UDnhcsgv1GazoDzNXZb"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000); + WriteReactorAddr(std::string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dRS7Rnjp8wjrKigAPfbP56bfEsNA7wfoJ8"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dVUu5KNpGBLFcUWyKTBrVnkniHNQasRN5b"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dRUAjN82ySuftGFuQonboB8bvyiNp561pA"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("daiPqSjPMNpxqX4UDnhcsgv1GazoDzNXZb"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); // Year 1 group 2 - WriteReactorAddr(std::string("dcF2DnzGyi7XdPiHFfUK8eZS2ad4Tfn3jt"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dcF2DnzGyi7XdPiHFfUK8eZS2ad4Tfn3jt"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2) , 1000); // Year 2 group 1 - WriteReactorAddr(std::string("dReEVEHa7o9AJreZfnrB1rDtDqvuh9eeVL"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dReEVEHa7o9AJreZfnrB1rDtDqvuh9eeVL"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); // Year 2 group 2 - WriteReactorAddr(std::string("dXizuUsA36u4u1BaPzMLp693QhdvkDCdWq"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dXizuUsA36u4u1BaPzMLp693QhdvkDCdWq"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); // Year 3 group 1 - WriteReactorAddr(std::string("dFvsna2hKRw98tuyHLwDhnefgSmhqfF8YK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dFvsna2hKRw98tuyHLwDhnefgSmhqfF8YK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); // Year 3 group 2 - WriteReactorAddr(std::string("dbEz4pgizZ6UfMnbasZcxnXLsdXxBrj74e"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dbEz4pgizZ6UfMnbasZcxnXLsdXxBrj74e"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); // Year 4 group 1 - WriteReactorAddr(std::string("dFx64NPzLDDXTK1ajJ4w82bX7ra6RPzCvN"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dFx64NPzLDDXTK1ajJ4w82bX7ra6RPzCvN"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); // Year 4 group 2 - WriteReactorAddr(std::string("dJFFCAK9pBVsiRQuhbQvkiVjLXKYVyap7Z"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dJFFCAK9pBVsiRQuhbQvkiVjLXKYVyap7Z"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); // Year 5 group 1 - WriteReactorAddr(std::string("dDepYKJesaenykkJpqZuzKir8crcymJ15w"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dDepYKJesaenykkJpqZuzKir8crcymJ15w"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); // Year 5 group 2 - WriteReactorAddr(std::string("dVJf23zDxRTtpQVP5ZUU6L83DmcJVxtCBa"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dVJf23zDxRTtpQVP5ZUU6L83DmcJVxtCBa"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); // Legendaries (only list max here), no shutoff time. WriteReactorAddr(std::string("dGXqvYugQ11mf2rmp4L2M8vRRigjU1Mv8S"), REACTOR_START_TIME, -1, 15000); From 8b96e7abfdceed33049d13f1edbaf620d96a9950 Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Mon, 8 Feb 2016 13:30:52 -0600 Subject: [PATCH 185/218] Add some testnet rules and addresses --- src/reactorlist.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++ src/reactors.cpp | 9 ++++++--- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index 0acf8ac..126bbfa 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -6,6 +6,7 @@ // TODO replace with proper time unsigned int REACTOR_START_TIME = 1453075200; +unsigned int REACTOR_TEST_START_TIME = 1453075200; void CReactorDB::WriteReactorDB() { LOCK(cs); @@ -52,3 +53,49 @@ void CReactorDB::WriteReactorDB() { // Foundation, no shutoff time. WriteReactorAddr(std::string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6"), REACTOR_START_TIME, -1, 10000); } + +void CReactorDB::WriteTestReactorDB() { + LOCK(cs); + + WriteReactorDBVersion(CURRENT_REACTOR_VERSION); + + // Year 1 group 1 + WriteReactorAddr(std::string("muLhTBAfaS2ro2fhDFh6D7MArg6qGv1j1i"), REACTOR_TEST_START_TIME, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("n2hXsAStBuJbjyL3QWvW11HG9t4hwPDvNu"), REACTOR_TEST_START_TIME, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("mrCAtCNfhLPfmJt3V4SYjU3Eq7K4eL89hv"), REACTOR_TEST_START_TIME, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("n4j5bHDq7C81xqE5C8mVGapcxANXDp1weh"), REACTOR_TEST_START_TIME, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("mgJ68V5ftC62DhjPDn5UMrR1qrk1a2dNqa"), REACTOR_TEST_START_TIME, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365, 1000); + + // Year 1 group 2 + WriteReactorAddr(std::string("mpw6YDtRPFayKdnVXdHpqugoqWFeZvt4j8"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 + 365 / 2) , 1000); + + // Year 2 group 1 + WriteReactorAddr(std::string("mrQDYWsroDVgjB2R3QtAc38Ka6YxrHQWui"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + + // Year 2 group 2 + WriteReactorAddr(std::string("mo7meRhKuC2NUCvK6Lg3U2vf2LVc7a61zn"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + + // Year 3 group 1 + WriteReactorAddr(std::string("mrUemWu2UiKUbBVdfky7iYyivyaB7v8y8v"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + + // Year 3 group 2 + WriteReactorAddr(std::string("mzbPu8daUDK96iPcQNWp8aKvqRjyUYeXWG"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + + // Year 4 group 1 + WriteReactorAddr(std::string("moDY5fXrdpGpHramVMisq3PZMfkyvFVXJk"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + + // Year 4 group 2 + WriteReactorAddr(std::string("mne2paA6HQqNmbSSMn4MbhGobR9XukBx3S"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + + // Year 5 group 1 + WriteReactorAddr(std::string("n2vgS6NTvYXDLufLeuz4ZSXFCSwddCnEt2"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_TEST_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + + // Year 5 group 2 + WriteReactorAddr(std::string("n2ZGE24BDNMAe4yRwXSNvkV2d45HuW2PE2"), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_TEST_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + + // Legendaries (only list max here), no shutoff time. + WriteReactorAddr(std::string("mkKzRqz4hQNM3re3wZrcGnsMRRJPudPsQu"), REACTOR_TEST_START_TIME, -1, 15000); + + // Foundation, no shutoff time. + WriteReactorAddr(std::string("mgCRA4ZXqaB8GBwb2AN2EaKL476caTdf26"), REACTOR_TEST_START_TIME, -1, 10000); +} diff --git a/src/reactors.cpp b/src/reactors.cpp index 87e6278..a0dd6bb 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -39,8 +39,11 @@ void InitReactors() { if (!inflatedb) { // TODO Replace with correct first and last reactor addresses. - if (!CReactorDB(reactordbfile).CheckReactorAddr(string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ")) - || !CReactorDB(reactordbfile).CheckReactorAddr(string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6"))) + if (!fTestNet && (!CReactorDB(reactordbfile).CheckReactorAddr(string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ")) + || !CReactorDB(reactordbfile).CheckReactorAddr(string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6")))) + inflatedb = true; + else if (fTestNet && (!CReactorDB(reactordbfile).CheckReactorAddr(string("muLhTBAfaS2ro2fhDFh6D7MArg6qGv1j1i")) + || !CReactorDB(reactordbfile).CheckReactorAddr(string("mgCRA4ZXqaB8GBwb2AN2EaKL476caTdf26")))) inflatedb = true; } } else { @@ -100,7 +103,7 @@ bool CTransaction::IsReactorStake(string strFileName, CScript scriptPubKeyType, void InflateReactorDB(string strFileName) { printf("InflateReactorDB() : inflating reactor database.\n"); - CReactorDB(strFileName, "cw+").WriteReactorDB(); + fTestNet ? CReactorDB(strFileName, "cw+").WriteTestReactorDB() : CReactorDB(strFileName, "cw+").WriteReactorDB(); } int GetReactorRate(int64 reactorStakeValue, int64 nValueIn) { From d2aaed36db2bcb8f099eb286709fc6538067db3c Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Mon, 8 Feb 2016 14:48:02 -0600 Subject: [PATCH 186/218] Add staisybit reactor address --- src/reactorlist.cpp | 11 ++++++++--- src/reactors.cpp | 6 +++--- src/wallet.cpp | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index 126bbfa..b893a52 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -4,9 +4,8 @@ #include "reactors.h" -// TODO replace with proper time -unsigned int REACTOR_START_TIME = 1453075200; -unsigned int REACTOR_TEST_START_TIME = 1453075200; +unsigned int REACTOR_START_TIME = 1453075200; // TODO replace with proper time +unsigned int REACTOR_TEST_START_TIME = 1453075200; // Sun Jan 17 18:00:00 CST 2016 void CReactorDB::WriteReactorDB() { LOCK(cs); @@ -52,6 +51,9 @@ void CReactorDB::WriteReactorDB() { // Foundation, no shutoff time. WriteReactorAddr(std::string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6"), REACTOR_START_TIME, -1, 10000); + + // Staisybit address + WriteReactorAddr(std::string("dK8Sh1R81YxaFrwwMmYEH1QET6ejhUw3pQ"), REACTOR_START_TIME, -1, 100); } void CReactorDB::WriteTestReactorDB() { @@ -98,4 +100,7 @@ void CReactorDB::WriteTestReactorDB() { // Foundation, no shutoff time. WriteReactorAddr(std::string("mgCRA4ZXqaB8GBwb2AN2EaKL476caTdf26"), REACTOR_TEST_START_TIME, -1, 10000); + + // Staisybit address + WriteReactorAddr(std::string("mkB4XAhFZmG5rNuhs4mnnBFWN3jKD2rXw2"), REACTOR_TEST_START_TIME, -1, 100); } diff --git a/src/reactors.cpp b/src/reactors.cpp index a0dd6bb..383a549 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -8,7 +8,7 @@ using namespace std; -int CURRENT_REACTOR_VERSION = -1; // Test version +int CURRENT_REACTOR_VERSION = -2; // Test version bool maybeWipeReactorDB(string strFileName) { int dbversion; @@ -40,10 +40,10 @@ void InitReactors() { if (!inflatedb) { // TODO Replace with correct first and last reactor addresses. if (!fTestNet && (!CReactorDB(reactordbfile).CheckReactorAddr(string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ")) - || !CReactorDB(reactordbfile).CheckReactorAddr(string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6")))) + || !CReactorDB(reactordbfile).CheckReactorAddr(string("dK8Sh1R81YxaFrwwMmYEH1QET6ejhUw3pQ")))) inflatedb = true; else if (fTestNet && (!CReactorDB(reactordbfile).CheckReactorAddr(string("muLhTBAfaS2ro2fhDFh6D7MArg6qGv1j1i")) - || !CReactorDB(reactordbfile).CheckReactorAddr(string("mgCRA4ZXqaB8GBwb2AN2EaKL476caTdf26")))) + || !CReactorDB(reactordbfile).CheckReactorAddr(string("mkB4XAhFZmG5rNuhs4mnnBFWN3jKD2rXw2")))) inflatedb = true; } } else { diff --git a/src/wallet.cpp b/src/wallet.cpp index 579ad0d..22c9aad 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1698,7 +1698,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (reactorStakeValue > 0) { int64 addressbalance; - if (GetSingleAddressBalance(txNew.vout[1].scriptPubKey, addressbalance) > reactorStakeValue * COIN) + if (GetSingleAddressBalance(txNew.vout[1].scriptPubKey, addressbalance) > reactorStakeValue * COIN && reactorStakeValue != 100) return error("CreateCoinStake : address balance is too high for reactor size; address balance %" PRI64d "; reactor size %" PRI64d "\n", addressbalance, reactorStakeValue); /* If this is a reactor check that the size of the stake matches the From 0ca16c83fcd7478090b2501f79ea88064b71a1d8 Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Tue, 9 Feb 2016 18:07:43 -0600 Subject: [PATCH 187/218] Fix legendary reactor rate and add staisybit rate the second was done but somehow didn't make it into the commit... --- src/reactors.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/reactors.cpp b/src/reactors.cpp index 383a549..897bf16 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -107,16 +107,19 @@ void InflateReactorDB(string strFileName) { } int GetReactorRate(int64 reactorStakeValue, int64 nValueIn) { + if (reactorStakeValue == 100) + return 1.05; + if (reactorStakeValue == 1000 || reactorStakeValue == 10000) return 2; /* We store the max value of the Legendaries in the database and override * the rate for 3000 coin stakes here. */ - if (reactorStakeValue == 15000 && nValueIn == 3000) + if (reactorStakeValue == 15000 && nValueIn == 3000 * COIN) return 2; - if (reactorStakeValue == 15000 && nValueIn == 15000) - return 1.5; + if (reactorStakeValue == 15000 && nValueIn == 15000 * COIN) + return 1.25; return 0; } From 9fe77ebeb8a3b1e819cf0723e949e88ddb30f0e7 Mon Sep 17 00:00:00 2001 From: Nathan Bass Date: Mon, 15 Feb 2016 14:37:30 -0600 Subject: [PATCH 188/218] Allow dust transactions on reactors Only lock the reactor if balance makes up reactor value * 2 --- src/wallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 22c9aad..a430fb4 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1698,7 +1698,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (reactorStakeValue > 0) { int64 addressbalance; - if (GetSingleAddressBalance(txNew.vout[1].scriptPubKey, addressbalance) > reactorStakeValue * COIN && reactorStakeValue != 100) + if (GetSingleAddressBalance(txNew.vout[1].scriptPubKey, addressbalance) > ((reactorStakeValue * COIN * 2) - 1 * COIN) && reactorStakeValue != 100) return error("CreateCoinStake : address balance is too high for reactor size; address balance %" PRI64d "; reactor size %" PRI64d "\n", addressbalance, reactorStakeValue); /* If this is a reactor check that the size of the stake matches the From 49509afd7c23148b9859b30678b8f0ed6f586a16 Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Thu, 24 Mar 2016 11:01:27 -0500 Subject: [PATCH 189/218] Replace original "test" addresses with production addresses. Minor change to legendary checks: Originally I understood legendaries as being either 3k or 15k stakeable inputs; either one. After seeing the final addresses it's clear that they are only one or the other so I removed some of the redundant logic that only existed for that functionality. --- src/reactorlist.cpp | 421 ++++++++++++++++++++++++++++++++++++-- src/reactors.cpp | 18 +- src/test/reactortests.cpp | 6 +- src/wallet.cpp | 18 +- 4 files changed, 417 insertions(+), 46 deletions(-) diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index b893a52..dfbcd1f 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -13,46 +13,433 @@ void CReactorDB::WriteReactorDB() { WriteReactorDBVersion(CURRENT_REACTOR_VERSION); // Year 1 group 1 - WriteReactorAddr(std::string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dRS7Rnjp8wjrKigAPfbP56bfEsNA7wfoJ8"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dVUu5KNpGBLFcUWyKTBrVnkniHNQasRN5b"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dRUAjN82ySuftGFuQonboB8bvyiNp561pA"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("daiPqSjPMNpxqX4UDnhcsgv1GazoDzNXZb"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o2f1xpRqjbhtJzzMQKFCnrPmkY35W"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oizJFn3SmAkb6joFxeGdkxJfD5hma"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oy5gCoTBpzcDow7zBVQzkjXkEK4zg"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36ofwR2BKWvDHE9R2PMTZgcpqCXMCSh"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36op6aXpdqrrguid183dFokfNgWj2LE"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36orZs9Tt9aVQMe3zwwPSDu4V3Y3gSx"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oYfiD1H2dAA6MKyvVypX6t1vzgyn7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oC3cJ1tq3paRoudv67FzjWAUzUmxk"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oWVvkFWVcDwn9rLrv9ho7hHe8e2Aj"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36odLYXup2aeHu1F8peZ2DLuru8sR4a"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o4JMpMsFdx5WhWheNmMsJ6RxuQGoi"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oGrLK8EFHxYvjFr3cHKaFaganBc3T"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36ovsMxr7XTwUWTvkKBMNmZqxdAq2Qf"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oNNJu54XVfpp22GQNC52QWbwEkZBu"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oQ9Mo518CZDZYyWpq6NXHBTGdEuz7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36obh51hvr94tZMYcaaS71ESW7rR4wp"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oiMbbonehWLTk8fSRPvLerKWEuxq9"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oaFt14PGrLKtGjsQCYuk11RWoQseB"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oSPP6eBK3UyFJTQ1gXc2ATi2PptpB"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oJ6tKMi64xNwhGRuZ7tGKkTA2w91L"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36obGd94CMTchB8Ej8Uywb3TXCLABi8"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36ogK8wGoemauLuwxYuzm9ZCaTq8Unv"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oMramh7TjUMuSrbz8XandDKh7sG4L"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oZGt7x4jcWYrvsi3mmUCcJYwj5ycJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oG39FLCTXYixrPeM2P1zbnCLyuuWt"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oN4KZvixno5JwpafaUKSN2atbHhJ7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36od2grzbCZrFbzukcvQSckngZ8P9FT"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oYg1bXP25GpDVPWpWZUkDqbMZeVfT"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o7kSGthLtqsTnL5SSifSTFzoKqs2Z"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o8aSPwAN8N7nX3sN7T7B3nxPoNpJU"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36ozBZ3s7Xxt7jHpaf23ypURWC3MtzE"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oCxTaNdWW1L3EzwQfNkg99LZZ399z"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oxvXtSjkLoASTTbYEWLhevb1x83wJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oUFiEUdMSn1B2QXhgu3Z3h2TuP9gs"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oLh44w8X1WhRvp4jyVA6vwucBuS2S"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oAuLE9VDuAZF15zQKy43XyRGygdLZ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oXeTJWGk8yV22jsamGqaUBwn56aKa"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oQrHRKnKmYFKwELP2qGw8hPtSHtSd"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o4ntQ3aSBS6ZbseCA5qe4TWuuNT61"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oRXmj3hb7oiw1MapLpmdKDdDstMkh"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36osq1Vg9tHk7dyLamkqgsNjMcTRADS"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36ojhQS4mEffzv6rZkNZtpufsW8WFJV"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36ooJ27wqGTbbcaFP46FGwD2BNc6W7D"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36onmRjUtfzkKmNrHpxtA7ugtJgRBEK"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oz6Wa3Jm4Yk82nxwbexW385XgLjer"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o4NWrvwE2156mpFEkUKFLa9c39MnN"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oiEsJEsu5JXRCNi6Vy5HQRs89kbvJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o2LrskBknTtXBw6ry5aRqLrAizFby"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36ojMQ7wMuYdyJ6PNhpjAva2dkXaByK"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36oVDG9Z3VPaCVC8ZFvfMsai8aJ36VR"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); // Year 1 group 2 - WriteReactorAddr(std::string("dcF2DnzGyi7XdPiHFfUK8eZS2ad4Tfn3jt"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2) , 1000); + WriteReactorAddr(std::string("dMd36oZL8CnJKVbsUxtaGLzMzyofKSFqMn"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oM5h4BFXZ8D9ZAQN8vSRMtKdb4Jnq"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oz34cbiyhrcRKpfmhXKDmsVMKfJ1V"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36o1AtREdscY8HoX42dUCkvhwxsPKoc"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oFgNikhdiv5haAWhcjji3VmHeMz8V"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36o9vbH32MaU2KmMDkNo1JRkdPigLck"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oJ9oxQ8m2i9Jhmab9NtfUe1H7c8yV"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36obgAMMEGckQb1R88kpPpd5EWYwda1"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oknqBxpwNq8TLuCKbDHg7eY8URFaf"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oonaU9gmQZ1CEAhfsUFQ9tPidb8P5"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oW1AFSJAiDXr67r7CCj8E87xuSgGS"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36o7PoLjERuej3zVY6DMoLXVmo3UxCs"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36ogopQ56XyPLNaqccx6g7DwyZHdEgX"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36omJmSu4opY1nTy1yznPUtSgNLZ4PP"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oZmgCiSxXgCjb5QEWrZmG9CupYL5p"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oGEXTyuKc8pF1dTggT3o6xS389Hwm"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36odLauWP47k6VpNMxQha5VGE56Qyhn"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36ooK4j4rQdB81EVhvPWN1yzYHcnpcJ"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oR8hGxPWv398cyao8R5gYz35GxLaf"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oFKAne7u1zJZoEEt8Lx87BoqrBqfx"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36onvuwthQ1Dg6tQiCYpN87jmA7WEpB"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oPKg8uss6FLZuxv2iXQS4DrF3FsPa"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oxP8XjGRtumZ3im6rSkZ42nZuY3A2"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36ofmiUmHHcmwgiwxJterCd9mEZQmRP"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oJjyHf9y842JnoqtQuKpcoYErNzMV"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36o47zSy7bmERdLFdsvkSUaV8VgKkK6"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oGHmnrW5HJnHVnHkWwZMPC4GGdfSQ"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36o3ceJMD3pXJq1yXp1sQhB3dmkTyb6"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oxPUiFraQHEeg9iYB8cL8h7pKqQHm"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); + WriteReactorAddr(std::string("dMd36oov9SH3bNG3qB6kr1pz2W77odn7GS"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); // Year 2 group 1 - WriteReactorAddr(std::string("dReEVEHa7o9AJreZfnrB1rDtDqvuh9eeVL"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oMMnScuNL6qiK9UU6whWWDjYbY4Md"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36orfHpvyqd5mMVWg7pzXidfZhMHAni"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oRU3itkvwVZaxsnJG7ePkRFTGrZAp"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oJ2m1tkJdqrmuXHppmfuRJuMFy2QS"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oxmibF2dCv2yWpR3vjxfudUdUH7m1"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ou7SXuR4PXATDyatajHF4Uk4zKGTW"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ozvLn9jxh9kLzyVMce63Rcj8mzKGm"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oh8Wf7GksZ8byqLYETKx935WjW3cY"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oiiF4q5UEx38Azmi1yx85y5RTVC6R"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oCYt7uyDUwQwNSDRsQR3cPPZp68Z8"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36omxRb9FvNVaAmyuqWKubigsqVQVjv"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36opdXiyCg6RHcQMnpAwZr7nW6PnRSF"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oTczE1XAK4Gy3NE3tEeh9PjzgsK2L"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ozivzmpCFCZnBy1ZxWvzjajN2AqAf"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36omSPXMQbW21zgbqTQJ8AcuRKN6uzk"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oux17dbgBHDqJ161L2S11i34FhTtD"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oLEoziV5B4jspBPTwkcVzwXte1C7k"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oaZNyvrzczfwGZ6ju6c39PB3LBRmW"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ovnydN3MjEYE8GrohomUpxZUnJyMB"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ohd1D7kY1TqmdvVGK2PAG1aTE9DPJ"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ow47Q29WNcd5X1oT1tTqfhmBCvWLS"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ovgqEX9pEpYiGTNp9TRtKqvgekMc6"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ogmCu5SCoveeSTPJwEEaohUPZzH9v"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36o4pyYrTFVmMGamrGDD6hwkYedfNdT"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oUwLtFviPeZsrZjGoorKT3XFTaSAg"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oUzfNoqMMnnTKoH4yGRE8346BKGVy"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36o48DmwrzopGBsw99cPUN81TK3CC5D"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36ob7NE9ZHQXfGaQtwusy7f2YkBtsz5"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36oSfWPBZy3T3Xgapi2po28UDj7JRD3"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); + WriteReactorAddr(std::string("dMd36o1yiGk56Nv2XCnCJLXwRkAngosWKG"), REACTOR_START_TIME + 60 * 60 * 24 * 365, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, 1000); // Year 2 group 2 - WriteReactorAddr(std::string("dXizuUsA36u4u1BaPzMLp693QhdvkDCdWq"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oheiFcrK4Fi1S6YQGyzms5kGQNM6m"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o89VvVB93fZKtdNKJ4ViXMBYbDwYC"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oQR2f6RETor8FcyZwuhTahLDfN1db"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36okQ8hCuTjNHV8XcxEtbW1GoCKwvoT"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oWnuiMcr4X69zKqThs3kqfZyVT9wA"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oqQkXpvbRLJiXQtqirQzmGH5ooZLw"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oY7tsmsaUi2q98LiUt5tQqtqq6n41"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oamoqhXFWpGxsKgrNSiiZ5G1cThoE"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oMWeEPbqMc4fMby82cjf2CcCi2sy1"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oHxBudoHY1vVWn39hYBQgHP6VoT7X"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oS8CGtqkdeFQu2RrexD4tWck7cfC9"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oVHPhNxb4pX9jME7vMQt9UB85WEEf"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ocrqUwJeR3SkfxsVzFQ6RUtVCmzJL"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o2UaDUgmXSmRWRLorfjLR7DekMdTP"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ohPiMqcz4nopVUz36ehj5udyUfLjx"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o5a1jZ9ohgVZDGXxBhLfPCr74T5iA"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ooiDaGpmRBeVSgK1bpi13XqFBsc5p"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oMN7k57YTJcBrnCHHCbpYroe6bk64"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oZRNRaz9SnPWxAusURi1t1RaHBeb7"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36of6RGUmqnceCXiHsEAsjLG7PNJFBY"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oz7bnZYNo9se7SyHW9rczV4KPGVvp"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ox7AXap7SvT55e5bbmTdB6RpcvdXh"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36onaJDAyvLqBcYWjk5DDuGwoqymyAV"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oDVqTUrpQiRh6qxQPNcgNLtCGh22E"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oFgtStDgM78VHcnAvPpuqTRLL7xEj"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o3cuHpUJphfGTAjEyHHu68CuNt5C5"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oKrJiBCVTMtkHhifRTR38zC2A1Nfc"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oFjhgxdDYryhZiqAS3Uh3dcSJhtU8"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o2Lvkwhi4UFhfhiZqH7xakHhiLJQo"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o7V9qmJoruQW5jyhbM3ev5wUYjupg"), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), 1000); // Year 3 group 1 - WriteReactorAddr(std::string("dFvsna2hKRw98tuyHLwDhnefgSmhqfF8YK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o2inYGNQsjrbviPTmQHBbGLFd5Dwx"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o9cQ5LyH5KyzKMip4pEFMkx45F4TF"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oPXSooCF8WMEovBAAxxPFsM8XCMBy"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o9Ye7xQFQ7puB218vXwVt6Awvva3r"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36owy3kitfTy5bzM92KtY4WELjKtvTJ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o5V9yB8YJtJW5n85WFUw6gbRzZTBZ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36ouaJLZtEVgcAKEhVHwAYcMAHmVHXy"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oM5kK86Qp12xZ6MvDowfdJZZqZQ2p"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oFaK8iJuruezuXUZJDsciTxdmcyGt"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o8DhzQ8dDMWaGX3oeB4WQKr51mR4U"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oV6MyiPoy5DCxadXfJyJhff18QrJs"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o36FwLSR8goPBcUaCG5YpRUZnXdZQ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oSd7RcfdYiDhAZoLRhgvHbXdzXyMv"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oFRUmZ99tx4UBqo49qsSzaVkhi7dz"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oL83sZtKjGhAn6zhyWxZNfAD5vJxC"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oUV8QvnZ6cPjigKjZS7F26QVavSYp"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36otpin5u94ZyPCoPqA2gbDvkEFg6iH"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oEvLPXaKxhYhjxxQMu77NjpkanHnf"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36otyxXs7kt8J27ZmXYpvqVFy22JYBY"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o3nokGTUfKQm3PQZwqx7D41iWCEwK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36omMNpP8Lj715tQrfHRdGkFh9QPndE"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oeEC7ub5sHD6gqmFwg5RmZN9waQ3u"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oNVVW8UDdZ5qy9JsJkPmFd7gTuhHX"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o7HGByuyk4emA5E4cGkTtVP1hsRTc"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oPZYkZtmCZoPSJMo5Dk57mCiiS2DC"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36ofRRYSYywcUSzwaVMSdKkzBHmzLSL"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o9H6r6m2phZ4uDkk8e9Kxm7okcRvH"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36oh451uBqjfDWxiJNCC8GzUugy4CfK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36o6AkB9wbJ4VDN4EBZ4q3Q8nkY6Nay"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); + WriteReactorAddr(std::string("dMd36ombweBLcCTMweFBWKxLHsk9W4WrAx"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 2, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, 1000); // Year 3 group 2 - WriteReactorAddr(std::string("dbEz4pgizZ6UfMnbasZcxnXLsdXxBrj74e"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oZ1uhFvdzP8TULR7b2ETvBZyD16LM"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oAh8GRCPzrgRWC4ykFT4oyrZP3Nks"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o667bZtfxckXP3ocFb1sByKnwAYRa"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oS6CdmBV5dcBHS2csodE7aiN5eJyn"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o13cajnt8gtq7jxejU75KBJrQSqCS"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oW7kaisdjC1ewdmhTqR9wRfMhKRd8"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ogpFLKSrv1tMajgUURatoY9Zsj9M2"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oMJKcSEewgMr3iqH7QtLZwPUvkLfi"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oBbjQMyZNx8s673sFSk1MGCntVJ2P"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oVCrpwDt3Saa4AryTvMDVUeQVFVJ3"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ovZkS4FVg1e4L4hQex6um8Q2qY5oH"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36omJF33uQ9SHY6wjJM1JmqcHzHAj2T"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36opnHw3LwbhssqocSBCYsUqCdfjufk"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oEMBCTA7S3WbfcYrZwwtQx5AtSirw"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36opdZiz8oEV7EA98ANEWjb2hjABBEE"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oTputpQVdXUbbMVf9hBXiY7Da5ZeQ"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oQGdvrXdeXNzpdvj1bKjRngX1Suqw"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oCCKwprSg2Tjqgz1Gukn7ybJ38zUM"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oY4uaSmgMvnYtVzo6nDYVK3dy5of6"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ojibE7GxovWuwyB9f1DjSpH8zZTXP"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ohcPLYU8Dd7xM5FRTEaPmgjaNkLPp"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o3k561mQmQwYGhvdTGFtkK1ngM7ss"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oHX1XDkhepMj8yTLUbJCohBEA4AbH"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oUMSevHtgZSKNtQVwjJFC3dWG6DQs"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o6ZdRoQZAbJxUKdgJKFsnqjNX3ZyB"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oQ11TqmoWacR4nC7931quCfYeCw7W"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oCTVs2SmLhGwHY4bWaoNwbKbNVjm8"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oFoWYo93JMfDm2trtrrKCEbi7YMpF"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oxjuu9wgEZDEeWUciDKx1JM357jbm"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oHf9xxULEVC5R6pu2pKQGtEsRbtvY"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 2 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), 1000); // Year 4 group 1 - WriteReactorAddr(std::string("dFx64NPzLDDXTK1ajJ4w82bX7ra6RPzCvN"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oBakBHeJ1h7e6xwGjvB1RMAgDP8TT"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oWqbHRQmHKdgsJC6WM527MMrreNNM"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oe5pbTdPpnBptgds6Pf64x2iPcn3Z"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oJ3SByKPUsYAedqyCUVyq3zo8Fdiz"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36o6xDseQLYTpXfSpkjjFmvi6FZCib5"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oU12z2GcPd1rdmxKGtoqgtQdEFX5H"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oS1tNDKjqjFkHRZtLT3gGXpbUx2Ae"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oB1FcA6cdvR6PUymhG1BC9yoEe9s7"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oHPf8WjeinByMptbN68DJpJ5uGU2G"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oGbuZn6LTCGnXQbFcvgSRDsr3hwLE"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oGcvh6pmkEMVpnjan1priLBXV8cgh"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oJeDyA5aJUKtG1x6DEHSG8SWVN6pP"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oV8dZvsXjmtk4trGZRyMsTRxKbJhJ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oMZaiVXFT2yXKQRbTCozZTSYFXDfs"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36o1qRsAijrzgzp5xQauTnrqpzrvz6q"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36orasqXxbuUQFjesvgedQgpNUJ5xg5"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36o697vqa3Y6veUUauPkcqkX1zYTo9i"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oW2gyNhw3MBzA3zY8PAkUv6oujn6w"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36o1tZnMqX9fsDnFUjFM1kEAFa8Wn1g"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oTJcLsiWHr2CESK3Ag8ybnjLa9Wv3"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oqwXqYU1AAJaYU8tt9fZBifLk551d"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oMZhzk9oEc8EHRsum74BcCg7FCfQJ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oU44s5uSsPT3GzHupVjiJQwEPU2vk"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oUmzD9rUgGUNKpaBVKLWf4cjSw4GP"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oq3sK1W6hLSLarbnFJCyAVEgKiRTQ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36o4PJvWJD6aUTfdPxuAF3J5uNnnGCq"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36o1GYFDTovyfQN7cgiZEj2stCZD8pr"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36oT9JZkJz2k5yQg6kqvp7qr7TDPCSu"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36obEHBp8sN2HQMeJFmDkFvTwRZwWxY"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); + WriteReactorAddr(std::string("dMd36ooVCZa9VxJP9x1d4zy8S9FVRuCfKr"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 3, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, 1000); // Year 4 group 2 - WriteReactorAddr(std::string("dJFFCAK9pBVsiRQuhbQvkiVjLXKYVyap7Z"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o7GFjHsQCqW1MjnHxyq2LspFGQjfA"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oq7fs93HFV9yXZ79gxcSf8VGJGy2B"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ohY48bw65dLaFVcReuMkmQtdJiqdx"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o3MttJEWJNpBFUH1LJ2wBe43Um8Xr"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oNgRDTYtZm99UWVSWihLEaPhXExKL"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oV7BUS312c6GSMArwMivkT6DSjZXg"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ovoEbC1qEm2xRrNCgANcHJrPcasrE"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oceKzCYQ54Uv7hdRWt6dH1seSz3VA"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36or46U46ZGytF8bSUbxANCZEsYSyUj"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ohMeGEEpvHGG7esB5eMNPQvJztJdN"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oC9bkJtcMFhYrtZQJSAECSkHdsY6z"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36odYhxwonp8LBnL6P7ZdM3qZrDThLK"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ozmEojszv35rkf1S6WYFZYUC6ze2P"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o2S9f8cuAW4k6FGhqqWzU7ZuGD9Qv"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oVuGfGe3ZazYwbNET5BtBpc1cGACN"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oe2j3pL8dH6dzKqbUuMSTnJezHNpP"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oX7LAnfNMPFVfvcJBcDPcJRYUvvRo"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o7pGGn6nf1vmmTvgRtjcwvJE9hCA7"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oDDkNyPFeeVq5N38PvvNry9qctST6"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36odmMdMKV5tRi4EWWGja9jLvmkw219"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o5qRWHb4GxVUj3tyy91N7xPG4PJ7U"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o8FErExgrKWMkUtMfJZmyYNUNvDA4"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36omecJLtDK6NofCrYuWvB4iwnDvBYq"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oBbwariDhR1RBQZndVdHcpoxDkZxT"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oeAVcno4R9u1aauvxef2WWNQX2pwT"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o7UtCYwSdbb5JjxD5x81sR4yJvCQb"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oXam37orGtFTA496LqrErVNWw1ao4"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oTP7mnM93nFnqyhsXa2xmwpo4utWM"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oZt9cqBUY8qEYtjT5STR4FWP3sA4d"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36okrNi5dUxoSYYduEpxTRB5rkoZjJs"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 3 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), 1000); // Year 5 group 1 - WriteReactorAddr(std::string("dDepYKJesaenykkJpqZuzKir8crcymJ15w"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36o9umQgGZxF1PNhGDQGdh1PPig1VrK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36opPwHvhzbTqZCg6nHsdbFxkKfCBYX"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oKX2jZzvNgCursjvpYd6fxEtryRrK"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oNpjzYvh672hsYkiAAG5XRZmeXq2x"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36ojborkoooUYfyYMasHRJYnPwTbsax"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36osjB34sKpSPD2yjxCSzhQzF1YX3MJ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oqrgLYoQNj2Dygcxozna3tPu9C18R"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oa49jkBkb9P3Cb7pRLF2ejNNHEc5p"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oKHiG9PU2rWgXHcB5vuRg4WHwY1AB"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oVmSAag5uzT56CdL8KtJUja9ofLjc"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36obzmJqMKMYzLM4rqYPm9foYyupb9A"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36ohTf8FrgkTX9fEybDrD5XRFDZZ1sE"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36o2KEeh93YEZ8cPGkk7sfMXXEkN1as"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oqyyywoaZWDPKranEpWdHnhxApLNN"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oNaBPzwYPeK2bqH6DN6EimUavRV5x"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36ouAHJAQLxpKJ6qQ9ptUE6teAXd1QD"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oL2PDn2pXhc8EwFxDtQf7JqqT5FFB"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36ofwKq8XcMhH2iaQSdg23KXkQhV8Rx"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oW8HZSr4VamfbrD1XwfnQUVsJfVoH"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36o75BBMGSekBvUFKLCgXCFNfUXLFdD"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oWKYDHYvitBmjzYsnRJ2DmjiupfJ1"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36o6kU6Usx93SP42nka5bvr1cVyUV6B"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oYFbMhaB8aYE1WNnXKdXvx4QtN7fX"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36ozf4ngdgUEXjHbZFLEEtX3pi8uk3P"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oEF6YuS4oyi8tMVY3t31QXax3pTNR"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oKq8wizd6Bf57efJTanzC44wTzZcd"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36o4cm6yBeT1rLPKsX4ruv8m1NBzbM6"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36o5qFZW8ksMRX5v3rVZjyN1PtTfNWc"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oes7Y6ZrusSrZzjxRUfvVeDtkHubp"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); + WriteReactorAddr(std::string("dMd36oTs7GZqQxBY6nRMffiMDhtVQF44Uj"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 4, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, 1000); // Year 5 group 2 - WriteReactorAddr(std::string("dVJf23zDxRTtpQVP5ZUU6L83DmcJVxtCBa"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); - - // Legendaries (only list max here), no shutoff time. - WriteReactorAddr(std::string("dGXqvYugQ11mf2rmp4L2M8vRRigjU1Mv8S"), REACTOR_START_TIME, -1, 15000); + WriteReactorAddr(std::string("dMd36oHTmMzUQEFkzUyrHYBq1ZhFQBov9w"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36onBPfWMvv69EpxNXfwAahBvudWJPJ"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ou7ov8513weh2RQsBNcuHMpbLaQVx"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oWD3yMKA113Fv3dNbtkD7yJH9xZYy"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ouVchHGt5iXdZv2H1fgCoZYb6DxpF"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oy62TV181FbbL9s8AXo4s6KsMNt4x"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oLxiRrCDkkpsuxYvYGbFFeqVod2vc"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oRdof2cqGzrFqCqBFgSaQ7W6em8Ep"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ozSRfjVSU89z5SUaSsAWgx2q4NiJF"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oVn826RT4YddFad1jTq5NtkgtSrwg"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oJeTrfJshm3mhCQ9feNvm2AjM316p"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o3oUqgcTHuoAMd2xhUVqPVcMsAUn1"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oqo6nNHyaUJfHtqu3ZdQRHJCNGAFB"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oH1LRWzkRjuHcf2NdspoacpYsbcmh"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oD314YtkWf6e5hpsnt9cwj6NfoGTB"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oMVhbyvkUbsbcShhuhPHfxNd43KtW"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oJ9KdqGqm1K9c6sx5VKPfScY1YKZC"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oBgAUK25m83sNAGGYmK5pYj7rCvaD"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ob9UQusMEF9dEXvGT3k2je9fXQox9"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36o8r9MC4QBgrLqHrUTpRoWxUhSLjDL"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oh9ttBHQxHrja7859cRqfEKvAkCeF"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ophXvDzifXBrk98D7pZAU6LbTBXcR"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oWR7wtjgaxB6mgWZEMf9wutM1BB8n"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oxScfgJMaHctWbBNZTTkRU75AUSoq"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oCbP7pQytLuDLxeEZu1DgHUwR3Udp"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36ohHhJFXyhSndcemVJmvdaAPmVWFUz"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oERDvd1Vb4qsfT7u6G5XsbV7VP6QY"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oChxkUxQL5GzWbqqsw6GBniEcJFUY"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36owM7A4HyH9cpsq7Xn8igA9pL9CKXJ"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + WriteReactorAddr(std::string("dMd36oq2qhwhYFK9Y62dp5zKFCeYqqgVje"), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 4 + (365 / 2)), REACTOR_START_TIME + 60 * 60 * 24 * (365 * 5 + (365 / 2)), 1000); + + // Year 6 (1 group) + WriteReactorAddr(std::string("dMd36oMNnpTfRC5BKL1i1uCrtiZb8Ynedn"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36ok1VajGGHaVUcms7dG2W7s5HFkQKe"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oNbX1k9bXvfdh7dpWWH2u5dAiGudb"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36orfGuHp1bgwfjFJWX6Ln1WcwkEx7X"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36of2YXpGR4LD2mENSvQ2WaiMaM2U8H"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36o7K968tsu8d6XyNR8ixbraTtbTm3f"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36okyYkJWJf3koJAtdghPfbCyHDJWqU"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oFer1etuhi8vS1qQweSCtwwekJ56B"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36okGNy7eyiRU7TJUzvcWqoeeWoR4qD"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36ohTnE9LK6aMVefobASfhUAtQG6z5Q"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oH9Vb1sEe5Ac3nEmZQRzWP2WnbsCJ"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oBbWy8a1ddLT8nZsFf4YmGyafGjKh"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36owYp5DYr7eBCdkYbNjSUCeVSCVVvw"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oJEBC68pvXC77rKKC3FcZuGRJPdUD"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oW4crZ8FCCnYsNz1qpSwfidaztRVv"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36o19QGANdBpFipB9dMfFhrfMND6ac5"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36ojooynBmXXSjKXZQhEc9vPoMYU9Qo"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oJZU4ynmrYaz8Pd9ZtMpW9PcALaZC"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36otXFLwz2iHDZ5kbWMFVWRb5qKcATs"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oy4euTaeKHVZW7fJZoCjH146XE2in"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36ohA44QM4pmTBeeA1S8JJ99FWhuAQw"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oib3EdFVavFXBmd8pwQGQWnWBPjuG"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36ofRxGFJw9kDzZym1AqS5Y2zKLuoNh"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oYZ1TAkvka1snB6yG7iNgrhgfqXh1"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oxpnHFCC2hYxiqauPyRYovyr84nZa"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oQPXhfPzTKN5vcQugrWyLea4Z95ct"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oTYh1CperuJBorfrCexRoDXojFuEu"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oT1Vb7HGsgfuRGqr2PRrBgF8Yn7tW"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36oaRy2Pfgxzp1HMYc9nnhN1r2kHkRD"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + WriteReactorAddr(std::string("dMd36o4YfLwRy1WqoyPc9DXRKkviDsMj5h"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); + + // Legendaries, no shutoff time. + + /* The Hearth of Eternity. + * Every great dream begins with a dreamer. Within him lies the strength, + * the patience, and the passion to reach for the stars to change the world. + */ + WriteReactorAddr(std::string("dasHERZmwgtvWGNRxs55GPrXsAKwY7bX85"), REACTOR_START_TIME, -1, 15000); + /* The Cullinan. + * To be announced later. + */ + WriteReactorAddr(std::string("dEB799gGhnG89b8bkcPUitgXiJWc7ggNCM"), REACTOR_START_TIME, -1, 15000); + /* Koh-I-Noor. + * Rough diamonds may sometimes be mistaken for worthless pebbles, just like + * the true value of a human being can be hidden beneath a hard surface. + */ + WriteReactorAddr(std::string("dMdjuF7xcsUvkYy2ikaQkx5z5viqNvhzxz"), REACTOR_START_TIME, -1, 15000); + /* The Allnatt. + * Watch your thoughts, thoughts become words and words become actions. + * Actions build character and character defines your destiny. AreTimes.com + */ + WriteReactorAddr(std::string("dTKsf6qD7BeVN7bNZpBM2M1iXfbrt5vvak"), REACTOR_START_TIME, -1, 15000); + /* The Steinmetz Pink. + * Kishore Now That You Are One Of The Legends, May You Be Immortalized In + * History. And Bring Hope To, Those Who Have Lost Hope. + */ + WriteReactorAddr(std::string("dW4mnJLQZwFExTBFTBdGSNte71TfvqC8LX"), REACTOR_START_TIME, -1, 15000); + /* De Beers Centenary. + * To be announced later. + */ + WriteReactorAddr(std::string("dTuJJvYoDcerBaHwoK8cK2oEEpYEWr8Tdh"), REACTOR_START_TIME, -1, 15000); + /* The Moussaieff Red. + * Dear son Andrei, we love you and wish for you the happiest of days and + * a bright, healthy future! + */ + WriteReactorAddr(std::string("dMbc7KM7cDy487C9FrWwvyaquprTgtCWZ8"), REACTOR_START_TIME, -1, 3000); + /* The Sancy. + * To grow a Diamond is a challenge but a good Diamond gains its value over + * time. For every Diamond that makes my life a Bliss, a grateful THANKS! + */ + WriteReactorAddr(std::string("dJWVbYhykxPwJQ1PxxjtQjBoGc1abhfQh7"), REACTOR_START_TIME, -1, 3000); + /* Wittelsbach. + * Leonidas pros Perses - Molon Lave - Apo ta kokkala bgalmenh twn Ellhnwn + * ta Iera. Kai san prwta andreiwmenh. Xaire w Xaire Elefteria. Annoula. + */ + WriteReactorAddr(std::string("dFKNwDWexXFapBBxRh5FsYtj3GkG8TyS75"), REACTOR_START_TIME, -1, 3000); + /* The Hope. + * To be announced later. + */ + WriteReactorAddr(std::string("dZTEMvLjwWjtiH3k1LCCX2soLXhQcUDLyZ"), REACTOR_START_TIME, -1, 3000); // Foundation, no shutoff time. + // TODO: rip this out or replace it... WriteReactorAddr(std::string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6"), REACTOR_START_TIME, -1, 10000); // Staisybit address + // TODO: rip this out or replace it... WriteReactorAddr(std::string("dK8Sh1R81YxaFrwwMmYEH1QET6ejhUw3pQ"), REACTOR_START_TIME, -1, 100); } diff --git a/src/reactors.cpp b/src/reactors.cpp index 897bf16..4968fc6 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -76,19 +76,11 @@ bool CTransaction::IsReactorStake(string strFileName, CScript scriptPubKeyType, /* If this is a reactor check that the size of the stake matches the * requirements of the given reactor.*/ - if (reactorStakeValue == 3000 || reactorStakeValue == 15000) { - if (nValueIn < (reactorStakeValue * COIN)) - return DoS(100, error("IsReactorStake() : nValueIn doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %d or %d", nValueIn, 3000, 15000)); - - if (nValueIn > (reactorStakeValue * COIN)) - return DoS(100, error("IsReactorStake() : nValueIn exceeds value of reactor; credit %" PRI64d "; reactor size %d or %d", nValueIn, 3000, 15000)); - } else { - if (nValueIn < (reactorStakeValue * COIN)) - return DoS(100, error("IsReactorStake() : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); - - if (nValueIn > (reactorStakeValue * COIN)) - return DoS(100, error("IsReactorStake() : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); - } + if (nValueIn < (reactorStakeValue * COIN)) + return DoS(100, error("IsReactorStake() : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); + + if (nValueIn > (reactorStakeValue * COIN)) + return DoS(100, error("IsReactorStake() : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); if (nStakeReward > GetProofOfStakeReward(nCoinAge, nBits, nTime, nHeight, GetReactorRate(reactorStakeValue, nValueIn)) - GetMinFee() + MIN_TX_FEE) return DoS(100, error("IsReactorStake() : %s stake reward exceeded", GetHash().ToString().substr(0, 10).c_str())); diff --git a/src/test/reactortests.cpp b/src/test/reactortests.cpp index cd46d92..e1e9ae3 100644 --- a/src/test/reactortests.cpp +++ b/src/test/reactortests.cpp @@ -12,8 +12,8 @@ BOOST_AUTO_TEST_CASE(reactor_validity) { CScript scriptPubKeyAddress; CScript scriptReactorOP; - string strReactorValid = "dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ"; - string strReactorValid2 = "dcF2DnzGyi7XdPiHFfUK8eZS2ad4Tfn3jt"; + string strReactorValid = "dMd36o2f1xpRqjbhtJzzMQKFCnrPmkY35W"; + string strReactorValid2 = "dMd36oZL8CnJKVbsUxtaGLzMzyofKSFqMn"; string strReactorInvalid = "dVSWVAnKL4BzVBAAvVDbatWfKeEpxXnLXT"; scriptReactorOP << OP_REACTOR; @@ -56,7 +56,7 @@ BOOST_AUTO_TEST_CASE(reactor_validity) addr = CBitcoinAddress(strReactorValid); scriptPubKeyAddress.clear(); scriptPubKeyAddress.SetDestination(addr.Get()); - BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), 1000 * COIN, 0, 0, 0, 0)); + BOOST_CHECK(!tx.IsReactorStake("reactors.dat", scriptReactorOP, scriptPubKeyAddress, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000 * COIN, 0, 0, 0, 0)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/wallet.cpp b/src/wallet.cpp index a430fb4..9935885 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1703,19 +1703,11 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int /* If this is a reactor check that the size of the stake matches the * requirements of the given reactor.*/ - if (reactorStakeValue == 3000 || reactorStakeValue == 15000) { - if (nCredit < (reactorStakeValue * COIN)) - return error("CreateCoinStake : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %d or %d\n", nCredit, 3000, 15000); - - if (nCredit > (reactorStakeValue * COIN)) - return error("CreateCoinStake : credit exceeds value of reactor; credit %" PRI64d "; reactor size %d or %d\n", nCredit, 3000, 15000); - } else { - if (nCredit < (reactorStakeValue * COIN)) - return error("CreateCoinStake : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); - - if (nCredit > (reactorStakeValue * COIN)) - return error("CreateCoinStake : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); - } + if (nCredit < (reactorStakeValue * COIN)) + return error("CreateCoinStake : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); + + if (nCredit > (reactorStakeValue * COIN)) + return error("CreateCoinStake : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); } int64 nReward = GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime, pIndex0->nHeight, GetReactorRate(reactorStakeValue, nCredit)); From fb67f783859205fe8077f368c66439b9b3d3b0f4 Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Tue, 5 Apr 2016 15:13:32 -0500 Subject: [PATCH 190/218] Update reactor start timestamp --- src/reactorlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index dfbcd1f..e77af6c 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -4,7 +4,7 @@ #include "reactors.h" -unsigned int REACTOR_START_TIME = 1453075200; // TODO replace with proper time +unsigned int REACTOR_START_TIME = 1460149200; // Fri, 08 Apr 2016 21:00:00 GMT unsigned int REACTOR_TEST_START_TIME = 1453075200; // Sun Jan 17 18:00:00 CST 2016 void CReactorDB::WriteReactorDB() { From 47cc0547e471542853f57a870ff1addb3f896115 Mon Sep 17 00:00:00 2001 From: John Doering Date: Fri, 8 Apr 2016 17:53:51 +0000 Subject: [PATCH 191/218] Livenet Beta Fork --- src/main.cpp | 18 +++++++++++------- src/main.h | 2 ++ src/net.cpp | 2 +- src/rpcmining.cpp | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bc9bca1..b22371c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1241,8 +1241,10 @@ unsigned int GetNextTargetRequired_v2(const CBlockIndex* pindexLast, bool fProof /* Disable legacy PoW block signature */ if(fSignWorkBlock) { - if(fTestNet && (pindexPrev->nHeight + 1 >= nTestStage2)) - fSignWorkBlock = false; + if((fTestNet && (pindexPrev->nHeight + 1 >= nTestStage2)) || + (!fTestNet && (pindexPrev->nHeight + 1 >= nLiveFork1))) { + fSignWorkBlock = false; + } } return bnNew.GetCompact(); @@ -1774,7 +1776,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) bool fContribution = false; if((fTestNet && (nPrevHeight + 1 < nTestStage1)) || - (!fTestNet && (totalCoin > VALUE_CHANGE))) + (!fTestNet && ((totalCoin > VALUE_CHANGE) && (nPrevHeight + 1 < nLiveFork1)))) fContribution = true; if(IsProofOfWork()) { @@ -2366,7 +2368,8 @@ bool CBlock::AcceptBlock() int nHeight = pindexPrev->nHeight+1; int64 nMaxDrift = nMaxClockDrift; - if(fTestNet && (nHeight >= nTestStage3)) { + if((fTestNet && (nHeight >= nTestStage3)) || + (!fTestNet && (nHeight >= nLiveFork1))) { nMaxDrift = nNewMaxClockDrift; } @@ -2382,7 +2385,7 @@ bool CBlock::AcceptBlock() if(IsProofOfStake()) { if((fTestNet && (nHeight < nTestStage1)) || - (!fTestNet && (totalCoin > VALUE_CHANGE))) { + (!fTestNet && ((totalCoin > VALUE_CHANGE) && (nHeight < nLiveFork1)))) { /* vtx[0] must have 2 empty outputs */ if((vtx[0].vout.size() != 2) || !vtx[0].vout[0].IsEmpty() || !vtx[0].vout[1].IsEmpty()) return(error("AcceptBlock() : coin base outputs invalid for proof-of-stake block")); @@ -2701,7 +2704,8 @@ bool CBlock::CheckBlockSignature(int nHeight) const } else { - if(fTestNet && (nHeight >= nTestStage2)) { + if((fTestNet && (nHeight >= nTestStage2)) || + (!fTestNet && (nHeight >= nLiveFork1))) { /* Insist on empty PoW block signatures */ return(vchBlockSig.empty()); } @@ -4254,7 +4258,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) bool fContribution = false; if((fTestNet && (nPrevHeight + 1 < nTestStage1)) || - (!fTestNet && (totalCoin > VALUE_CHANGE))) + (!fTestNet && ((totalCoin > VALUE_CHANGE) && (nPrevHeight + 1 < nLiveFork1)))) fContribution = true; // Create coinbase tx diff --git a/src/main.h b/src/main.h index c5f0ef8..82cfb89 100644 --- a/src/main.h +++ b/src/main.h @@ -52,6 +52,8 @@ static const int nTestStage4 = 440; /* Testnet: enable merged mining */ /* Testnet: SHA-256 transaction hashing after 8-Feb-2016 15:00 UTC */ static const unsigned int nTestTxSwitch = 1454943600; +static const int nLiveFork1 = 1486800; /* Livenet: cumulative hard fork */ + /* Livenet: SHA-256 transaction hashing and fixed min. stake age */ static const unsigned int nLiveTimeSwitch = ~0U; diff --git a/src/net.cpp b/src/net.cpp index 849a50a..b0bfc5f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1175,7 +1175,7 @@ void MapPort() // The first name is used as information source for addrman. // The second name should resolve to a list of seed addresses. static const char *strDNSSeed[][2] = { - {"seed.bit.diamond", "seed.bit.diamond"}, + {"seed.bit.diamonds", "seed.bit.diamonds"}, {"dmdseed.danbo.bg", "dmdseed.danbo.bg"}, {"", ""}, }; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 77c8d30..4106536 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -636,7 +636,7 @@ Value getblocktemplate(const Array& params, bool fHelp) result.push_back(Pair("transactions", transactions)); result.push_back(Pair("coinbaseaux", aux)); if((fTestNet && (pindexPrev->nHeight + 1 < nTestStage1)) || - (!fTestNet && (totalCoin > VALUE_CHANGE))) { + (!fTestNet && ((totalCoin > VALUE_CHANGE) && (pindexPrev->nHeight + 1 < nLiveFork1)))) { result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue + (int64_t)pblock->vtx[0].vout[1].nValue)); } else { From e7ae158f2693ca8080bf8bdb24535d3d0d782d5a Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Thu, 21 Apr 2016 14:51:15 -0500 Subject: [PATCH 192/218] Fix staking since reactor code. --- src/wallet.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/wallet.cpp b/src/wallet.cpp index 6ea7c40..8fc129c 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1048,7 +1048,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); sort(vCoins.begin(), vCoins.end(), CompareAgeOnly); // found available coins so sort in age order (TK) - reverse(vCoins.begin(), vCoins.end()); // and return vector with coins sorted from newest to oldest (TK) + reverse(vCoins.begin(), vCoins.end()); // and return vector with coins sorted from newest to oldest (TK) } } } @@ -1155,8 +1155,8 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in nValueRet += coin.first; return true; } - else -*/ + else +*/ if (n < nTargetValue + CENT) { vValue.push_back(coin); @@ -1189,7 +1189,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in } // Solve subset sum by stochastic approximation - // Don't sort by value - we want to prefer newest to oldest (TK) + // Don't sort by value - we want to prefer newest to oldest (TK) // sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); vector vfBest; int64 nBest; @@ -1637,14 +1637,16 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (txNew.nTime >= valid_starting && (txNew.nTime < valid_until || valid_until == (unsigned int)-1)) { scriptStake << OP_REACTOR; nCombineThreshold = reactorStakeValue * COIN; - } else { - /* Just make sure the script being pushed to vout is - * blank to mark the stake as a standard stake. */ - scriptStake.clear(); } - txNew.vout.push_back(CTxOut(0, scriptStake)); + } else { + // Initialize empty value + reactorStakeValue = 0; + /* Just make sure the script being pushed to vout is + * blank to mark the stake as a standard stake. */ + scriptStake.clear(); } + txNew.vout.push_back(CTxOut(0, scriptStake)); txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; @@ -1687,7 +1689,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // Stop adding inputs if reached reserve limit if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) break; - if (nCredit + pcoin.first->vout[pcoin.second].nValue == nBalance) // always leave 2 blocks min - don't combine entire wallet into one block! (TK) + if (nCredit + pcoin.first->vout[pcoin.second].nValue == nBalance) // always leave 2 blocks min - don't combine entire wallet into one block! (TK) break; // Do not add additional significant input if (pcoin.first->vout[pcoin.second].nValue >= nCombineThreshold) From 2fcdd11e588b4bf1f9d48f319781668d10237c30 Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Mon, 25 Apr 2016 11:30:16 -0500 Subject: [PATCH 193/218] Fix reactor staking add POS check when checking that outputs are not empty fix "dust" recognition --- src/main.cpp | 2 +- src/reactors.cpp | 2 +- src/wallet.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b22371c..a21ca13 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -478,7 +478,7 @@ bool CTransaction::CheckTransaction() const if(fTestNet || (!fTestNet && ((totalCoin <= VALUE_CHANGE) || (totalCoin > POS_RESTART)))) { // ppcoin: enforce minimum output amount - if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT) + if ((!txout.IsEmpty()) && (!IsCoinStake()) && txout.nValue < MIN_TXOUT_AMOUNT) return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum")); } else diff --git a/src/reactors.cpp b/src/reactors.cpp index 4968fc6..c7e40ab 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -79,7 +79,7 @@ bool CTransaction::IsReactorStake(string strFileName, CScript scriptPubKeyType, if (nValueIn < (reactorStakeValue * COIN)) return DoS(100, error("IsReactorStake() : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); - if (nValueIn > (reactorStakeValue * COIN)) + if (nValueIn > ((reactorStakeValue * COIN * 2) - 1 * COIN)) return DoS(100, error("IsReactorStake() : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "", nValueIn, reactorStakeValue)); if (nStakeReward > GetProofOfStakeReward(nCoinAge, nBits, nTime, nHeight, GetReactorRate(reactorStakeValue, nValueIn)) - GetMinFee() + MIN_TX_FEE) diff --git a/src/wallet.cpp b/src/wallet.cpp index 8fc129c..8bd64dd 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1723,8 +1723,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (nCredit < (reactorStakeValue * COIN)) return error("CreateCoinStake : credit doesn't meet requirement for reactor stake; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); - if (nCredit > (reactorStakeValue * COIN)) - return error("CreateCoinStake : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue); + if (nCredit > ((reactorStakeValue * COIN * 2) - 1 * COIN) && reactorStakeValue != 100) + return error("CreateCoinStake : credit exceeds value of reactor; credit %" PRI64d "; reactor size %" PRI64d "\n", nCredit, reactorStakeValue * COIN); } int64 nReward = GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime, pIndex0->nHeight, GetReactorRate(reactorStakeValue, nCredit)); From 0f7da4b7fcc23a48abbcea6e9a8bc5f27f71b853 Mon Sep 17 00:00:00 2001 From: John Doering Date: Fri, 29 Apr 2016 19:38:20 +0300 Subject: [PATCH 194/218] Diamond v2.1.0.0 --- COPYING | 2 +- diamond.pro | 2 +- src/checkpoints.cpp | 2 +- src/main.cpp | 34 +++++++++------------------------- src/main.h | 2 +- src/qt/forms/aboutdialog.ui | 4 ++-- src/reactorlist.cpp | 2 +- src/version.h | 10 +++++----- 8 files changed, 21 insertions(+), 37 deletions(-) diff --git a/COPYING b/COPYING index 0f96bda..1554b1a 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2013-2015 Diamond Foundation +Copyright (c) 2013-2016 Diamond Foundation Copyright (c) 2011-2012 PPCoin Developers Copyright (c) 2009-2012 Bitcoin Developers diff --git a/diamond.pro b/diamond.pro index be622cf..c7b2ab2 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 2.0.5.7 +VERSION = 2.1.0.0 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index fde274a..8cc9d25 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -39,7 +39,7 @@ namespace Checkpoints (443923, uint256("0x0000000001f9b10759fa67418e4c20a772ec39c3eff33742cb5899c7b50d7348")) (468356, uint256("0x000000000543a19eaf97aa0ad933cb6423dedacb09786f4891126ac02bd8b7d4")) (895493, uint256("0x0000000003140f322a3913d0d67b77b462b0bcdd2a4a0ec0cd791de743cf9202")) - + (1500000, uint256("0x0000000008040b20b2e7ebdea7cf0c57d43195ec1da886b652339cb87253f369")) ; static MapCheckpoints mapCheckpointsTestnet = diff --git a/src/main.cpp b/src/main.cpp index b22371c..51ed583 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3256,16 +3256,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return false; } - if (totalCoin >= 1000000 && (pfrom->nVersion < MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE)) { - printf("ERROR: partner %s using version %i from before reward decrease; disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); - // immediate ban - pfrom->Misbehaving(100); - pfrom->fDisconnect = true; - return false; - } - - if (pfrom->nVersion == 10300) - pfrom->nVersion = 300; if (!vRecv.empty()) vRecv >> addrFrom >> nNonce; if (!vRecv.empty()) @@ -3287,21 +3277,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - // Diamond: disconnect any known version prior 2.0.3 - // as these have PoS not working and could serve us garbage - printf("connected subver %s\n", pfrom->strSubVer.c_str()); - if (!strcmp(pfrom->strSubVer.c_str(),"/Diamond:2.0.1/") - || !strcmp(pfrom->strSubVer.c_str(),"/Diamond:2.0.2.1/") - || !strcmp(pfrom->strSubVer.c_str(),"/Diamond:0.7.2/") - || !strcmp(pfrom->strSubVer.c_str(),"/Satoshi:0.7.2/") - || !strcmp(pfrom->strSubVer.c_str(),"") - ) - { - printf("partner %s using obsolete client %s\n", pfrom->addr.ToString().c_str(), pfrom->strSubVer.c_str()); - // immediate ban - pfrom->Misbehaving(100); - pfrom->fDisconnect = true; - return false; + /* Disconnect all obsolete clients after 10 May 2016 12:00:00 UTC */ + uint nAdjTime = GetAdjustedTime(); + if(nAdjTime > 1462881600) { + if(pfrom->nVersion < MIN_PROTOCOL_VERSION) { + printf("obsolete node %s with client %d, disconnecting\n", + pfrom->addr.ToString().c_str(), pfrom->nVersion); + pfrom->fDisconnect = true; + return(true); + } } // ppcoin: record my external IP reported by peer diff --git a/src/main.h b/src/main.h index 82cfb89..19ba8bf 100644 --- a/src/main.h +++ b/src/main.h @@ -52,7 +52,7 @@ static const int nTestStage4 = 440; /* Testnet: enable merged mining */ /* Testnet: SHA-256 transaction hashing after 8-Feb-2016 15:00 UTC */ static const unsigned int nTestTxSwitch = 1454943600; -static const int nLiveFork1 = 1486800; /* Livenet: cumulative hard fork */ +static const int nLiveFork1 = 1540400; /* Livenet: cumulative hard fork */ /* Livenet: SHA-256 transaction hashing and fixed min. stake age */ static const unsigned int nLiveTimeSwitch = ~0U; diff --git a/src/qt/forms/aboutdialog.ui b/src/qt/forms/aboutdialog.ui index 9f86741..af5428b 100644 --- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -63,7 +63,7 @@ IBeamCursor - 2.0.5.7 + 2.1.0.0 Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse @@ -94,7 +94,7 @@ Copyright © 2009-2014 Bitcoin Developers Copyright © 2012-2014 PPCoin Developers -Copyright © 2013-2015 Diamond Foundation +Copyright © 2013-2016 Diamond Foundation diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index e77af6c..4fa59b3 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -4,7 +4,7 @@ #include "reactors.h" -unsigned int REACTOR_START_TIME = 1460149200; // Fri, 08 Apr 2016 21:00:00 GMT +unsigned int REACTOR_START_TIME = 1462881600; // Tue 10 May 2016 12:00:00 UTC unsigned int REACTOR_TEST_START_TIME = 1453075200; // Sun Jan 17 18:00:00 CST 2016 void CReactorDB::WriteReactorDB() { diff --git a/src/version.h b/src/version.h index cb133be..f43b818 100644 --- a/src/version.h +++ b/src/version.h @@ -25,8 +25,8 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60012; -static const int MIN_PROTO_VERSION_AFTER_FIRST_REWARD_DECREASE = 60012; +static const int PROTOCOL_VERSION = 60013; +static const int MIN_PROTOCOL_VERSION = 60013; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; @@ -46,8 +46,8 @@ static const int BIP0031_VERSION = 60000; static const int MEMPOOL_GD_VERSION = 60002; #define DISPLAY_VERSION_MAJOR 2 -#define DISPLAY_VERSION_MINOR 0 -#define DISPLAY_VERSION_REVISION 5 -#define DISPLAY_VERSION_BUILD 7 +#define DISPLAY_VERSION_MINOR 1 +#define DISPLAY_VERSION_REVISION 0 +#define DISPLAY_VERSION_BUILD 0 #endif From ebd85b0cf9b1da8a9f93c4018793bbeda24bb5a4 Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Sun, 1 May 2016 13:50:56 -0500 Subject: [PATCH 195/218] Finalize reactor addresses and start time. --- src/reactorlist.cpp | 227 ++++++++++++++++++++++---------------------- src/reactors.cpp | 6 +- 2 files changed, 119 insertions(+), 114 deletions(-) diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index e77af6c..e073faf 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -4,65 +4,128 @@ #include "reactors.h" -unsigned int REACTOR_START_TIME = 1460149200; // Fri, 08 Apr 2016 21:00:00 GMT +unsigned int REACTOR_START_TIME = 1462881600; // Tue 10 May 2016 12:00:00 UTC unsigned int REACTOR_TEST_START_TIME = 1453075200; // Sun Jan 17 18:00:00 CST 2016 +/* If changing anything here make sure to update the CURRENT_REACTOR_VERSION to + * force old databases to be rewritten and update the first and last keys in + * InitReactors */ + void CReactorDB::WriteReactorDB() { LOCK(cs); WriteReactorDBVersion(CURRENT_REACTOR_VERSION); + // Legendaries, no shutoff time. + + /* The Hearth of Eternity. + * Every great dream begins with a dreamer. Within him lies the strength, + * the patience, and the passion to reach for the stars to change the world. + */ + WriteReactorAddr(std::string("dasHERZmwgtvWGNRxs55GPrXsAKwY7bX85"), REACTOR_START_TIME, -1, 15000); + /* The Cullinan. + * Cowards die many times before their deaths; The valiant never taste of + * death but once. + */ + WriteReactorAddr(std::string("dEB799gGhnG89b8bkcPUitgXiJWc7ggNCM"), REACTOR_START_TIME, -1, 15000); + /* Koh-I-Noor. + * Rough diamonds may sometimes be mistaken for worthless pebbles, just like + * the true value of a human being can be hidden beneath a hard surface. + */ + WriteReactorAddr(std::string("dMdjuF7xcsUvkYy2ikaQkx5z5viqNvhzxz"), REACTOR_START_TIME, -1, 15000); + /* The Allnatt. + * Watch your thoughts, thoughts become words and words become actions. + * Actions build character and character defines your destiny. AreTimes.com + */ + WriteReactorAddr(std::string("dTKsf6qD7BeVN7bNZpBM2M1iXfbrt5vvak"), REACTOR_START_TIME, -1, 15000); + /* The Steinmetz Pink. + * Kishore Now That You Are One Of The Legends, May You Be Immortalized In + * History. And Bring Hope To, Those Who Have Lost Hope. + */ + WriteReactorAddr(std::string("dW4mnJLQZwFExTBFTBdGSNte71TfvqC8LX"), REACTOR_START_TIME, -1, 15000); + /* De Beers Centenary. + * Violence: It is not any once race. The victems of the violence are black + * and white. Most importantly they were human beings who loved others. BK + */ + WriteReactorAddr(std::string("dTuJJvYoDcerBaHwoK8cK2oEEpYEWr8Tdh"), REACTOR_START_TIME, -1, 15000); + /* The Moussaieff Red. + * Dear son Andrei, we love you and wish for you the happiest of days and + * a bright, healthy future! + */ + WriteReactorAddr(std::string("dMbc7KM7cDy487C9FrWwvyaquprTgtCWZ8"), REACTOR_START_TIME, -1, 3000); + /* The Sancy. + * To grow a Diamond is a challenge but a good Diamond gains its value over + * time. For every Diamond that makes my life a Bliss, a grateful THANKS! + */ + WriteReactorAddr(std::string("dJWVbYhykxPwJQ1PxxjtQjBoGc1abhfQh7"), REACTOR_START_TIME, -1, 3000); + /* Wittelsbach. + * Leonidas pros Perses - Molon Lave - Apo ta kokkala bgalmenh twn Ellhnwn + * ta Iera. Kai san prwta andreiwmenh. Xaire w Xaire Elefteria. Annoula. + */ + WriteReactorAddr(std::string("dFKNwDWexXFapBBxRh5FsYtj3GkG8TyS75"), REACTOR_START_TIME, -1, 3000); + /* The Hope. + * In retrospect all will see this impulsive decision helped change the + * world. Only things impossible are things not yet figured out. + */ + WriteReactorAddr(std::string("dZTEMvLjwWjtiH3k1LCCX2soLXhQcUDLyZ"), REACTOR_START_TIME, -1, 3000); + + // Foundation, variant 1 (disabled). + WriteReactorAddr(std::string("VARIANTDISABLED"), -1, -1, 10000); + + // Foundation, variant 2. + WriteReactorAddr(std::string("dRwXJFujnkqLVCE1He4Se8TzBUGfTNZKVJ"), REACTOR_START_TIME, -1, 100); + // Year 1 group 1 - WriteReactorAddr(std::string("dMd36o2f1xpRqjbhtJzzMQKFCnrPmkY35W"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oizJFn3SmAkb6joFxeGdkxJfD5hma"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oy5gCoTBpzcDow7zBVQzkjXkEK4zg"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36ofwR2BKWvDHE9R2PMTZgcpqCXMCSh"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36op6aXpdqrrguid183dFokfNgWj2LE"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36orZs9Tt9aVQMe3zwwPSDu4V3Y3gSx"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oYfiD1H2dAA6MKyvVypX6t1vzgyn7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oC3cJ1tq3paRoudv67FzjWAUzUmxk"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oWVvkFWVcDwn9rLrv9ho7hHe8e2Aj"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36odLYXup2aeHu1F8peZ2DLuru8sR4a"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36o4JMpMsFdx5WhWheNmMsJ6RxuQGoi"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oGrLK8EFHxYvjFr3cHKaFaganBc3T"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36ovsMxr7XTwUWTvkKBMNmZqxdAq2Qf"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oNNJu54XVfpp22GQNC52QWbwEkZBu"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oQ9Mo518CZDZYyWpq6NXHBTGdEuz7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36obh51hvr94tZMYcaaS71ESW7rR4wp"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oiMbbonehWLTk8fSRPvLerKWEuxq9"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oaFt14PGrLKtGjsQCYuk11RWoQseB"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oSPP6eBK3UyFJTQ1gXc2ATi2PptpB"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oJ6tKMi64xNwhGRuZ7tGKkTA2w91L"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36obGd94CMTchB8Ej8Uywb3TXCLABi8"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36ogK8wGoemauLuwxYuzm9ZCaTq8Unv"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oMramh7TjUMuSrbz8XandDKh7sG4L"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oZGt7x4jcWYrvsi3mmUCcJYwj5ycJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oG39FLCTXYixrPeM2P1zbnCLyuuWt"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oN4KZvixno5JwpafaUKSN2atbHhJ7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36od2grzbCZrFbzukcvQSckngZ8P9FT"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oYg1bXP25GpDVPWpWZUkDqbMZeVfT"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36o7kSGthLtqsTnL5SSifSTFzoKqs2Z"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36o8aSPwAN8N7nX3sN7T7B3nxPoNpJU"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36ozBZ3s7Xxt7jHpaf23ypURWC3MtzE"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oCxTaNdWW1L3EzwQfNkg99LZZ399z"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oxvXtSjkLoASTTbYEWLhevb1x83wJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oUFiEUdMSn1B2QXhgu3Z3h2TuP9gs"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oLh44w8X1WhRvp4jyVA6vwucBuS2S"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oAuLE9VDuAZF15zQKy43XyRGygdLZ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oXeTJWGk8yV22jsamGqaUBwn56aKa"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oQrHRKnKmYFKwELP2qGw8hPtSHtSd"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36o4ntQ3aSBS6ZbseCA5qe4TWuuNT61"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oRXmj3hb7oiw1MapLpmdKDdDstMkh"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36osq1Vg9tHk7dyLamkqgsNjMcTRADS"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36ojhQS4mEffzv6rZkNZtpufsW8WFJV"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36ooJ27wqGTbbcaFP46FGwD2BNc6W7D"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36onmRjUtfzkKmNrHpxtA7ugtJgRBEK"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oz6Wa3Jm4Yk82nxwbexW385XgLjer"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36o4NWrvwE2156mpFEkUKFLa9c39MnN"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oiEsJEsu5JXRCNi6Vy5HQRs89kbvJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36o2LrskBknTtXBw6ry5aRqLrAizFby"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36ojMQ7wMuYdyJ6PNhpjAva2dkXaByK"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); - WriteReactorAddr(std::string("dMd36oVDG9Z3VPaCVC8ZFvfMsai8aJ36VR"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 365, 1000); + WriteReactorAddr(std::string("dMd36o2f1xpRqjbhtJzzMQKFCnrPmkY35W"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oizJFn3SmAkb6joFxeGdkxJfD5hma"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oy5gCoTBpzcDow7zBVQzkjXkEK4zg"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36ofwR2BKWvDHE9R2PMTZgcpqCXMCSh"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36op6aXpdqrrguid183dFokfNgWj2LE"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36orZs9Tt9aVQMe3zwwPSDu4V3Y3gSx"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oYfiD1H2dAA6MKyvVypX6t1vzgyn7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oC3cJ1tq3paRoudv67FzjWAUzUmxk"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oWVvkFWVcDwn9rLrv9ho7hHe8e2Aj"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36odLYXup2aeHu1F8peZ2DLuru8sR4a"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36o4JMpMsFdx5WhWheNmMsJ6RxuQGoi"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oGrLK8EFHxYvjFr3cHKaFaganBc3T"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36ovsMxr7XTwUWTvkKBMNmZqxdAq2Qf"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oNNJu54XVfpp22GQNC52QWbwEkZBu"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oQ9Mo518CZDZYyWpq6NXHBTGdEuz7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36obh51hvr94tZMYcaaS71ESW7rR4wp"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oiMbbonehWLTk8fSRPvLerKWEuxq9"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oaFt14PGrLKtGjsQCYuk11RWoQseB"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oSPP6eBK3UyFJTQ1gXc2ATi2PptpB"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oJ6tKMi64xNwhGRuZ7tGKkTA2w91L"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36obGd94CMTchB8Ej8Uywb3TXCLABi8"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36ogK8wGoemauLuwxYuzm9ZCaTq8Unv"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oMramh7TjUMuSrbz8XandDKh7sG4L"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oZGt7x4jcWYrvsi3mmUCcJYwj5ycJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oG39FLCTXYixrPeM2P1zbnCLyuuWt"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oN4KZvixno5JwpafaUKSN2atbHhJ7"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36od2grzbCZrFbzukcvQSckngZ8P9FT"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oYg1bXP25GpDVPWpWZUkDqbMZeVfT"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36o7kSGthLtqsTnL5SSifSTFzoKqs2Z"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36o8aSPwAN8N7nX3sN7T7B3nxPoNpJU"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36ozBZ3s7Xxt7jHpaf23ypURWC3MtzE"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oCxTaNdWW1L3EzwQfNkg99LZZ399z"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oxvXtSjkLoASTTbYEWLhevb1x83wJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oUFiEUdMSn1B2QXhgu3Z3h2TuP9gs"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oLh44w8X1WhRvp4jyVA6vwucBuS2S"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oAuLE9VDuAZF15zQKy43XyRGygdLZ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oXeTJWGk8yV22jsamGqaUBwn56aKa"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oQrHRKnKmYFKwELP2qGw8hPtSHtSd"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36o4ntQ3aSBS6ZbseCA5qe4TWuuNT61"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oRXmj3hb7oiw1MapLpmdKDdDstMkh"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36osq1Vg9tHk7dyLamkqgsNjMcTRADS"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36ojhQS4mEffzv6rZkNZtpufsW8WFJV"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36ooJ27wqGTbbcaFP46FGwD2BNc6W7D"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36onmRjUtfzkKmNrHpxtA7ugtJgRBEK"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oz6Wa3Jm4Yk82nxwbexW385XgLjer"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36o4NWrvwE2156mpFEkUKFLa9c39MnN"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oiEsJEsu5JXRCNi6Vy5HQRs89kbvJ"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36o2LrskBknTtXBw6ry5aRqLrAizFby"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36ojMQ7wMuYdyJ6PNhpjAva2dkXaByK"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); + WriteReactorAddr(std::string("dMd36oVDG9Z3VPaCVC8ZFvfMsai8aJ36VR"), REACTOR_START_TIME, REACTOR_START_TIME + 60 * 60 * 24 * 395, 1000); // Year 1 group 2 WriteReactorAddr(std::string("dMd36oZL8CnJKVbsUxtaGLzMzyofKSFqMn"), REACTOR_START_TIME + 60 * 60 * 24 * (365 / 2), REACTOR_START_TIME + 60 * 60 * 24 * (365 + 365 / 2), 1000); @@ -383,64 +446,6 @@ void CReactorDB::WriteReactorDB() { WriteReactorAddr(std::string("dMd36oT1Vb7HGsgfuRGqr2PRrBgF8Yn7tW"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); WriteReactorAddr(std::string("dMd36oaRy2Pfgxzp1HMYc9nnhN1r2kHkRD"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); WriteReactorAddr(std::string("dMd36o4YfLwRy1WqoyPc9DXRKkviDsMj5h"), REACTOR_START_TIME + 60 * 60 * 24 * 365 * 5, REACTOR_START_TIME + 60 * 60 * 24 * 365 * 6, 1000); - - // Legendaries, no shutoff time. - - /* The Hearth of Eternity. - * Every great dream begins with a dreamer. Within him lies the strength, - * the patience, and the passion to reach for the stars to change the world. - */ - WriteReactorAddr(std::string("dasHERZmwgtvWGNRxs55GPrXsAKwY7bX85"), REACTOR_START_TIME, -1, 15000); - /* The Cullinan. - * To be announced later. - */ - WriteReactorAddr(std::string("dEB799gGhnG89b8bkcPUitgXiJWc7ggNCM"), REACTOR_START_TIME, -1, 15000); - /* Koh-I-Noor. - * Rough diamonds may sometimes be mistaken for worthless pebbles, just like - * the true value of a human being can be hidden beneath a hard surface. - */ - WriteReactorAddr(std::string("dMdjuF7xcsUvkYy2ikaQkx5z5viqNvhzxz"), REACTOR_START_TIME, -1, 15000); - /* The Allnatt. - * Watch your thoughts, thoughts become words and words become actions. - * Actions build character and character defines your destiny. AreTimes.com - */ - WriteReactorAddr(std::string("dTKsf6qD7BeVN7bNZpBM2M1iXfbrt5vvak"), REACTOR_START_TIME, -1, 15000); - /* The Steinmetz Pink. - * Kishore Now That You Are One Of The Legends, May You Be Immortalized In - * History. And Bring Hope To, Those Who Have Lost Hope. - */ - WriteReactorAddr(std::string("dW4mnJLQZwFExTBFTBdGSNte71TfvqC8LX"), REACTOR_START_TIME, -1, 15000); - /* De Beers Centenary. - * To be announced later. - */ - WriteReactorAddr(std::string("dTuJJvYoDcerBaHwoK8cK2oEEpYEWr8Tdh"), REACTOR_START_TIME, -1, 15000); - /* The Moussaieff Red. - * Dear son Andrei, we love you and wish for you the happiest of days and - * a bright, healthy future! - */ - WriteReactorAddr(std::string("dMbc7KM7cDy487C9FrWwvyaquprTgtCWZ8"), REACTOR_START_TIME, -1, 3000); - /* The Sancy. - * To grow a Diamond is a challenge but a good Diamond gains its value over - * time. For every Diamond that makes my life a Bliss, a grateful THANKS! - */ - WriteReactorAddr(std::string("dJWVbYhykxPwJQ1PxxjtQjBoGc1abhfQh7"), REACTOR_START_TIME, -1, 3000); - /* Wittelsbach. - * Leonidas pros Perses - Molon Lave - Apo ta kokkala bgalmenh twn Ellhnwn - * ta Iera. Kai san prwta andreiwmenh. Xaire w Xaire Elefteria. Annoula. - */ - WriteReactorAddr(std::string("dFKNwDWexXFapBBxRh5FsYtj3GkG8TyS75"), REACTOR_START_TIME, -1, 3000); - /* The Hope. - * To be announced later. - */ - WriteReactorAddr(std::string("dZTEMvLjwWjtiH3k1LCCX2soLXhQcUDLyZ"), REACTOR_START_TIME, -1, 3000); - - // Foundation, no shutoff time. - // TODO: rip this out or replace it... - WriteReactorAddr(std::string("dLBh6YiVNwAYWd731R9yrxxAT97eHPa8Y6"), REACTOR_START_TIME, -1, 10000); - - // Staisybit address - // TODO: rip this out or replace it... - WriteReactorAddr(std::string("dK8Sh1R81YxaFrwwMmYEH1QET6ejhUw3pQ"), REACTOR_START_TIME, -1, 100); } void CReactorDB::WriteTestReactorDB() { @@ -485,9 +490,9 @@ void CReactorDB::WriteTestReactorDB() { // Legendaries (only list max here), no shutoff time. WriteReactorAddr(std::string("mkKzRqz4hQNM3re3wZrcGnsMRRJPudPsQu"), REACTOR_TEST_START_TIME, -1, 15000); - // Foundation, no shutoff time. + // Foundation, variant 1 WriteReactorAddr(std::string("mgCRA4ZXqaB8GBwb2AN2EaKL476caTdf26"), REACTOR_TEST_START_TIME, -1, 10000); - // Staisybit address + // Foundation, variant 2 WriteReactorAddr(std::string("mkB4XAhFZmG5rNuhs4mnnBFWN3jKD2rXw2"), REACTOR_TEST_START_TIME, -1, 100); } diff --git a/src/reactors.cpp b/src/reactors.cpp index c7e40ab..15d2817 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -8,7 +8,7 @@ using namespace std; -int CURRENT_REACTOR_VERSION = -2; // Test version +int CURRENT_REACTOR_VERSION = 1; bool maybeWipeReactorDB(string strFileName) { int dbversion; @@ -39,8 +39,8 @@ void InitReactors() { if (!inflatedb) { // TODO Replace with correct first and last reactor addresses. - if (!fTestNet && (!CReactorDB(reactordbfile).CheckReactorAddr(string("dMajkjpXzy2KTk21JkFx8aDtUVoaXmeMEZ")) - || !CReactorDB(reactordbfile).CheckReactorAddr(string("dK8Sh1R81YxaFrwwMmYEH1QET6ejhUw3pQ")))) + if (!fTestNet && (!CReactorDB(reactordbfile).CheckReactorAddr(string("dasHERZmwgtvWGNRxs55GPrXsAKwY7bX85")) + || !CReactorDB(reactordbfile).CheckReactorAddr(string("dMd36o4YfLwRy1WqoyPc9DXRKkviDsMj5h")))) inflatedb = true; else if (fTestNet && (!CReactorDB(reactordbfile).CheckReactorAddr(string("muLhTBAfaS2ro2fhDFh6D7MArg6qGv1j1i")) || !CReactorDB(reactordbfile).CheckReactorAddr(string("mkB4XAhFZmG5rNuhs4mnnBFWN3jKD2rXw2")))) From d8d92d739cd1bc713e5debfeb84076c51519a764 Mon Sep 17 00:00:00 2001 From: John Doering Date: Fri, 6 May 2016 00:00:27 +0000 Subject: [PATCH 196/218] Wallet Locking while Staking Fixed --- src/qt/askpassphrasedialog.cpp | 12 +++++------ src/qt/askpassphrasedialog.h | 2 +- src/qt/bitcoingui.cpp | 15 ++++--------- src/qt/walletmodel.cpp | 39 +++++++++++++++------------------- src/qt/walletmodel.h | 3 ++- src/rpcdump.cpp | 9 ++++---- src/rpcwallet.cpp | 13 ++++++------ src/util.cpp | 1 + src/util.h | 1 + src/wallet.cpp | 7 +----- src/wallet.h | 1 - src/walletdb.cpp | 1 - 12 files changed, 45 insertions(+), 59 deletions(-) diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index e3f448f..def9959 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -4,12 +4,12 @@ #include "guiconstants.h" #include "walletmodel.h" +#include "util.h" + #include #include #include -extern bool fWalletUnlockMintOnly; - AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : QDialog(parent), ui(new Ui::AskPassphraseDialog), @@ -35,7 +35,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
    Please use a passphrase of 10 or more random characters, or eight or more words.")); setWindowTitle(tr("Encrypt wallet")); break; - case UnlockMinting: + case(UnlockStaking): ui->mintingCheckBox->setChecked(true); ui->mintingCheckBox->show(); // fallthru @@ -144,7 +144,7 @@ void AskPassphraseDialog::accept() QDialog::reject(); // Cancelled } } break; - case UnlockMinting: + case(UnlockStaking): case Unlock: if(!model->setWalletLocked(false, oldpass)) { @@ -153,7 +153,7 @@ void AskPassphraseDialog::accept() } else { - fWalletUnlockMintOnly = ui->mintingCheckBox->isChecked(); + fStakingOnly = ui->mintingCheckBox->isChecked(); QDialog::accept(); // Success } break; @@ -201,7 +201,7 @@ void AskPassphraseDialog::textChanged() case Encrypt: // New passphrase x2 acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); break; - case UnlockMinting: + case(UnlockStaking): case Unlock: // Old passphrase x1 case Decrypt: acceptable = !ui->passEdit1->text().isEmpty(); diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index ca01274..0ddb24f 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -18,8 +18,8 @@ class AskPassphraseDialog : public QDialog public: enum Mode { Encrypt, /**< Ask passphrase twice and encrypt */ - UnlockMinting, /**< Ask passphrase and unlock for minting only */ Unlock, /**< Ask passphrase and unlock */ + UnlockStaking, /* Ask passphrase and unlock for staking only */ ChangePass, /**< Ask old passphrase + new passphrase twice */ Decrypt /**< Ask passphrase and decrypt wallet */ }; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index bd2dc30..2c5651b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -68,7 +68,6 @@ extern CWallet *pwalletMain; extern int64 nLastCoinStakeSearchInterval; extern unsigned int nStakeTargetSpacing; -extern bool fWalletUnlockMintOnly; BitcoinGUI::BitcoinGUI(QWidget *parent): QMainWindow(parent), @@ -896,7 +895,7 @@ void BitcoinGUI::unlockWallet() return; // Unlock wallet when requested by wallet model - if(walletModel->getEncryptionStatus() == WalletModel::Locked || fWalletUnlockMintOnly) + if(walletModel->getEncryptionStatus() == WalletModel::Locked) { AskPassphraseDialog::Mode mode = AskPassphraseDialog::Unlock; AskPassphraseDialog dlg(mode, this); @@ -910,18 +909,12 @@ void BitcoinGUI::lockWalletToggle() if(!walletModel) return; - // Unlock wallet when requested by wallet model - if(walletModel->getEncryptionStatus() == WalletModel::Locked) - { - AskPassphraseDialog::Mode mode = AskPassphraseDialog::UnlockMinting; - AskPassphraseDialog dlg(mode, this); + if(walletModel->getEncryptionStatus() == WalletModel::Locked) { + AskPassphraseDialog dlg(AskPassphraseDialog::UnlockStaking, this); dlg.setModel(walletModel); dlg.exec(); - } - else if(walletModel->getEncryptionStatus() == WalletModel::Unlocked) - { + } else { walletModel->setWalletLocked(true); - fWalletUnlockMintOnly = false; } } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 320a300..5e2b28f 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -12,8 +12,6 @@ #include #include -extern bool fWalletUnlockMintOnly; - WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), transactionTableModel(0), @@ -255,20 +253,18 @@ TransactionTableModel *WalletModel::getTransactionTableModel() return transactionTableModel; } -WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const -{ +WalletModel::EncryptionStatus WalletModel::getEncryptionStatus() const { + if(!wallet->IsCrypted()) - { - return Unencrypted; - } - else if(wallet->IsLocked()) - { - return Locked; - } + return(Unencrypted); + + if(wallet->IsLocked()) + return(Locked); + + if(fStakingOnly) + return(UnlockedStaking); else - { - return Unlocked; - } + return(Unlocked); } bool WalletModel::setWalletEncrypted(bool encrypted, const SecureString &passphrase) @@ -360,23 +356,22 @@ void WalletModel::unsubscribeFromCoreSignals() WalletModel::UnlockContext WalletModel::requestUnlock() { bool was_locked = getEncryptionStatus() == Locked; + + if((!was_locked) && fStakingOnly) { + setWalletLocked(true); + was_locked = getEncryptionStatus() == Locked; + } + if(was_locked) { // Request UI to unlock wallet emit requireUnlock(); } - else if(fWalletUnlockMintOnly) - { - // Relock so the user must give the right passphrase to continue - setWalletLocked(true); - // Request UI to unlock wallet - emit requireUnlock(); - } // If wallet is still locked, unlock was failed or cancelled, mark context as invalid bool valid = getEncryptionStatus() != Locked; - return UnlockContext(this, valid, was_locked); + return(UnlockContext(this, valid, was_locked && !fStakingOnly)); } WalletModel::UnlockContext::UnlockContext(WalletModel *wallet, bool valid, bool relock): diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index fc71da9..ef50f29 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -56,7 +56,8 @@ class WalletModel : public QObject { Unencrypted, // !wallet->IsCrypted() Locked, // wallet->IsCrypted() && wallet->IsLocked() - Unlocked // wallet->IsCrypted() && !wallet->IsLocked() + Unlocked, /* wallet->IsCrypted() && !wallet->IsLocked() && !fStakingOnly */ + UnlockedStaking /* wallet->IsCrypted() && !wallet->IsLocked() && fStakingOnly */ }; OptionsModel *getOptionsModel(); diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 89078bc..df5400e 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -47,8 +47,8 @@ Value importprivkey(const Array& params, bool fHelp) bool fGood = vchSecret.SetString(strSecret); if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); - if (fWalletUnlockMintOnly) // ppcoin: no importprivkey in mint-only mode - throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only."); + + EnsureWalletIsUnlocked(); CKey key; bool fCompressed; @@ -82,8 +82,9 @@ Value dumpprivkey(const Array& params, bool fHelp) CBitcoinAddress address; if (!address.SetString(strAddress)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Diamond address"); - if (fWalletUnlockMintOnly) // ppcoin: no dumpprivkey in mint-only mode - throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only."); + + EnsureWalletIsUnlocked(); + CKeyID keyID; if (!address.GetKeyID(keyID)) throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index ecd175f..813cede 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -33,8 +33,9 @@ void EnsureWalletIsUnlocked() { if (pwalletMain->IsLocked()) throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); - if (fWalletUnlockMintOnly) - throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Wallet unlocked for block minting only."); + + if(fStakingOnly) + throw(JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Wallet unlocked for staking only.")); } void WalletTxToJSON(const CWalletTx& wtx, Object& entry) @@ -1466,11 +1467,11 @@ Value walletpassphrase(const Array& params, bool fHelp) int64* pnSleepTime = new int64(params[1].get_int64()); NewThread(ThreadCleanWalletPassphrase, pnSleepTime); - // ppcoin: if user OS account compromised prevent trivial sendmoney commands - if (params.size() > 2) - fWalletUnlockMintOnly = params[2].get_bool(); + /* Disables some wallet functionality if unlocked for staking only */ + if(params.size() > 2) + fStakingOnly = params[2].get_bool(); else - fWalletUnlockMintOnly = false; + fStakingOnly = false; return Value::null; } diff --git a/src/util.cpp b/src/util.cpp index 6432822..499ea2e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -79,6 +79,7 @@ bool fNoListen = false; bool fLogTimestamps = true; CMedianFilter vTimeOffsets(200,0); bool fReopenDebugLog = false; +bool fStakingOnly = false; // Init OpenSSL library multithreading support static CCriticalSection** ppmutexOpenSSL; diff --git a/src/util.h b/src/util.h index c782777..77c393e 100644 --- a/src/util.h +++ b/src/util.h @@ -150,6 +150,7 @@ extern bool fTestNet; extern bool fNoListen; extern bool fLogTimestamps; extern bool fReopenDebugLog; +extern bool fStakingOnly; void RandAddSeed(); void RandAddSeedPerfmon(); diff --git a/src/wallet.cpp b/src/wallet.cpp index 8bd64dd..a8dab27 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -93,10 +93,6 @@ bool CWallet::AddCScript(const CScript& redeemScript) return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); } -// ppcoin: optional setting to unlock wallet for block minting only; -// serves to disable the trivial sendmoney when OS account compromised -bool fWalletUnlockMintOnly = false; - bool CWallet::Unlock(const SecureString& strWalletPassphrase) { if (!IsLocked()) @@ -1859,8 +1855,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, printf("SendMoney() : %s", strError.c_str()); return strError; } - if (fWalletUnlockMintOnly) - { + if(fStakingOnly) { string strError = _("Error: Wallet unlocked for block minting only, unable to create transaction."); printf("SendMoney() : %s", strError.c_str()); return strError; diff --git a/src/wallet.h b/src/wallet.h index 1876078..69733d6 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -19,7 +19,6 @@ #include "util.h" #include "walletdb.h" -extern bool fWalletUnlockMintOnly; class CAccountingEntry; class CWalletTx; class CReserveKey; diff --git a/src/walletdb.cpp b/src/walletdb.cpp index e24ed50..97d3305 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -13,7 +13,6 @@ using namespace boost; using namespace json_spirit; static uint64 nAccountingEntryNumber = 0; -extern bool fWalletUnlockMintOnly; // // CWalletDB From 7fb011aa294aaed4ad3e3a3fd80ee5bcf22cdbbb Mon Sep 17 00:00:00 2001 From: John Doering Date: Sun, 8 May 2016 13:06:30 +0000 Subject: [PATCH 197/218] Diamond v2.1.0.1 --- diamond.pro | 2 +- src/clientversion.h | 6 +++--- src/main.h | 2 +- src/reactorlist.cpp | 2 +- src/version.h | 8 ++++---- src/wallet.cpp | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/diamond.pro b/diamond.pro index c7b2ab2..998f477 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 2.1.0.0 +VERSION = 2.1.0.1 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES diff --git a/src/clientversion.h b/src/clientversion.h index af44bc4..8b87536 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -7,9 +7,9 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 2 -#define CLIENT_VERSION_MINOR 0 -#define CLIENT_VERSION_REVISION 5 -#define CLIENT_VERSION_BUILD 7 +#define CLIENT_VERSION_MINOR 1 +#define CLIENT_VERSION_REVISION 0 +#define CLIENT_VERSION_BUILD 1 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/main.h b/src/main.h index 19ba8bf..edf0c75 100644 --- a/src/main.h +++ b/src/main.h @@ -52,7 +52,7 @@ static const int nTestStage4 = 440; /* Testnet: enable merged mining */ /* Testnet: SHA-256 transaction hashing after 8-Feb-2016 15:00 UTC */ static const unsigned int nTestTxSwitch = 1454943600; -static const int nLiveFork1 = 1540400; /* Livenet: cumulative hard fork */ +static const int nLiveFork1 = 1549200; /* Livenet: cumulative hard fork */ /* Livenet: SHA-256 transaction hashing and fixed min. stake age */ static const unsigned int nLiveTimeSwitch = ~0U; diff --git a/src/reactorlist.cpp b/src/reactorlist.cpp index e073faf..6c983ae 100644 --- a/src/reactorlist.cpp +++ b/src/reactorlist.cpp @@ -4,7 +4,7 @@ #include "reactors.h" -unsigned int REACTOR_START_TIME = 1462881600; // Tue 10 May 2016 12:00:00 UTC +unsigned int REACTOR_START_TIME = 1463313600; // Tue 15 May 2016 12:00:00 UTC unsigned int REACTOR_TEST_START_TIME = 1453075200; // Sun Jan 17 18:00:00 CST 2016 /* If changing anything here make sure to update the CURRENT_REACTOR_VERSION to diff --git a/src/version.h b/src/version.h index f43b818..8645ff6 100644 --- a/src/version.h +++ b/src/version.h @@ -45,9 +45,9 @@ static const int BIP0031_VERSION = 60000; // "mempool" command, enhanced "getdata" behavior starts with this version: static const int MEMPOOL_GD_VERSION = 60002; -#define DISPLAY_VERSION_MAJOR 2 -#define DISPLAY_VERSION_MINOR 1 -#define DISPLAY_VERSION_REVISION 0 -#define DISPLAY_VERSION_BUILD 0 +#define DISPLAY_VERSION_MAJOR CLIENT_VERSION_MAJOR +#define DISPLAY_VERSION_MINOR CLIENT_VERSION_MINOR +#define DISPLAY_VERSION_REVISION CLIENT_VERSION_REVISION +#define DISPLAY_VERSION_BUILD CLIENT_VERSION_BUILD #endif diff --git a/src/wallet.cpp b/src/wallet.cpp index a8dab27..f878f7f 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1509,7 +1509,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // The following split & combine thresholds are important to security // Should not be adjusted if you don't understand the consequences static unsigned int nStakeSplitAge = fTestNet ? (60 * 60) : (60 * 60 * 24 * 30); // Age under which amounts are split in two - int64 nCombineThreshold = fTestNet ? (100 * COIN) : (totalCoin / 10000); + int64 nCombineThreshold = fTestNet ? (100 * COIN) : (150 * COIN); CBigNum bnTargetPerCoinDay; bnTargetPerCoinDay.SetCompact(nBits); From 390c765295849243c53a6e5c63981cfa8828233e Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Wed, 11 May 2016 21:50:30 +0200 Subject: [PATCH 198/218] fix a typo and remove unneeded parts --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index add9662..dfd16fb 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,8 @@ Update ubuntu *navigate to the downloaded files cd ~ *navigate to the src file in the source code - cd diamond/src + cd Diamond/src -*create obj folder - - mkdir obj *build diamondd !This will take a while! From c5a4a06dbd2ad610292b90d49a284f19ceb0279a Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Thu, 12 May 2016 01:02:52 +0200 Subject: [PATCH 199/218] adapt block old wallets triggertimer --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 4e7ae27..e27a457 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3277,9 +3277,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - /* Disconnect all obsolete clients after 10 May 2016 12:00:00 UTC */ + /* Disconnect all obsolete clients after 15 May 2016 12:00:00 UTC */ uint nAdjTime = GetAdjustedTime(); - if(nAdjTime > 1462881600) { + if(nAdjTime > 1463313600) { if(pfrom->nVersion < MIN_PROTOCOL_VERSION) { printf("obsolete node %s with client %d, disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); From a2bae7cfb448012e7abd1de2cca6dd0dcc603550 Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Tue, 24 May 2016 16:30:30 -0500 Subject: [PATCH 200/218] Haxor the reactorRate do to errors in the original code. Includes significant checks to attempt to avoid mini-forks... --- src/main.cpp | 18 +++++++-------- src/main.h | 14 ++++++------ src/reactors.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++------ src/reactors.h | 8 ++++--- 4 files changed, 71 insertions(+), 27 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e27a457..62c071e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -998,7 +998,7 @@ int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash) // miner's coin stake reward based on nBits and coin age spent (coin-days) // simple algorithm, not depend on the diff -int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight, int reactorRate) +int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight, float reactorRate) { int64 nRewardCoinYear; int64 nSubsidy = 0; @@ -1006,10 +1006,11 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi if (totalCoin > VALUE_CHANGE || fTestNet) { nRewardCoinYear = MAX_MINT_PROOF_OF_STAKE; - if(fTestNet) - nSubsidy = nCoinAge * 50 * CENT / 365; - else - { + if(fTestNet) { + nRewardCoinYear = 25 * CENT; + nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, reactorRate); + nSubsidy = nCoinAge * nRewardCoinYear / 365; + } else { // Diamond v2 PoS spec: // 50% algorithm switch to 1,500,000 coins // 25% from 1,500,000 to 2,500,000 coins @@ -1024,6 +1025,7 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi else nRewardCoinYear = 50 * CENT; + nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, reactorRate); nSubsidy = nCoinAge * nRewardCoinYear / 365; } @@ -1031,6 +1033,7 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits); return nSubsidy; } + // DEAD CODE, nothing past this line runs anymore... else { CBigNum bnRewardCoinYearLimit = MAX_MINT_PROOF_OF_STAKE; // Base stake mint rate, 100% year interest @@ -1063,11 +1066,6 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi nRewardCoinYear = bnUpperBound.getuint64(); nRewardCoinYear = min((nRewardCoinYear / CENT) * CENT, MAX_MINT_PROOF_OF_STAKE); - /* If the reactor rate is greater than 0 adjust the nRewardCoinYear by - * the given rate. */ - if (reactorRate > 0) - nRewardCoinYear = nRewardCoinYear * (reactorRate * CENT); - nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear; if (fDebug && GetBoolArg("-printcreation")) printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d" nBits=%d\n", FormatMoney(nSubsidy).c_str(), nCoinAge, nBits); diff --git a/src/main.h b/src/main.h index edf0c75..43a6607 100644 --- a/src/main.h +++ b/src/main.h @@ -71,7 +71,7 @@ static const uint256 hashGenesisBlockOfficial("0x2d8b2c67b7f56e70b9b16b377b988bb static const uint256 hashGenesisBlockTestNet ("0x0000004b5393b6564f68472ce799a25c56fc63f45d55b7b1f450ac5836598a20"); static const int64 nMaxClockDrift = 2 * 60 * 60; // two hours -static const int64 nNewMaxClockDrift = 15 * 60; +static const int64 nNewMaxClockDrift = 15 * 60; extern bool fOldMerkleHash; @@ -138,7 +138,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& void FormatDataBuffer(CBlock *pblock, unsigned int *pdata); bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); int64 GetProofOfWorkReward(int nHeight, int64 nFees, uint256 prevHash); -int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight, int reactorRate = 0); +int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTime, int nHeight, float reactorRate = 0); unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); unsigned int ComputeMinStake(unsigned int nBase, int64 nTime, unsigned int nBlockTime); int GetNumBlocksOfPeers(); @@ -879,22 +879,22 @@ class CTxIndex template int ReadWriteAuxPow(Stream& s, const boost::shared_ptr& auxpow, int nType, int nVersion, CSerActionSerialize ser_action); - + template int ReadWriteAuxPow(Stream& s, boost::shared_ptr& auxpow, int nType, int nVersion, CSerActionUnserialize ser_action); - + template int ReadWriteAuxPow(Stream& s, const boost::shared_ptr& auxpow, int nType, int nVersion, CSerActionGetSerializeSize ser_action); - + enum { // primary version - BLOCK_VERSION_DEFAULT = (1 << 0), + BLOCK_VERSION_DEFAULT = (1 << 0), // modifiers BLOCK_VERSION_AUXPOW = (1 << 8), - + // bits allocated for chain ID BLOCK_VERSION_CHAIN_START = (1 << 16), BLOCK_VERSION_CHAIN_END = (1 << 30), diff --git a/src/reactors.cpp b/src/reactors.cpp index 15d2817..6dfb2ef 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -9,6 +9,8 @@ using namespace std; int CURRENT_REACTOR_VERSION = 1; +unsigned int REACTOR_FIX_TIME = 1465689599; // Sat, 11 Jun 2016 23:59:59 GMT +unsigned int REACTOR_TEST_FIX_TIME = 1464123019; // Tue, 24 May 2016 20:50:19 GMT bool maybeWipeReactorDB(string strFileName) { int dbversion; @@ -98,24 +100,66 @@ void InflateReactorDB(string strFileName) { fTestNet ? CReactorDB(strFileName, "cw+").WriteTestReactorDB() : CReactorDB(strFileName, "cw+").WriteReactorDB(); } -int GetReactorRate(int64 reactorStakeValue, int64 nValueIn) { +float GetReactorRate(int64 reactorStakeValue, int64 nValueIn) { + unsigned int fix_time = REACTOR_FIX_TIME; + if (fTestNet) + fix_time = REACTOR_TEST_FIX_TIME; + if (reactorStakeValue == 100) return 1.05; if (reactorStakeValue == 1000 || reactorStakeValue == 10000) return 2; - /* We store the max value of the Legendaries in the database and override - * the rate for 3000 coin stakes here. */ - if (reactorStakeValue == 15000 && nValueIn == 3000 * COIN) - return 2; + /* Originally the spec for the legendaries made it sound like they could + * have one or the other value (instead of being set to one specifically), + * this segment of code was overlooked in previous updates... + * While this check is probably not necessary we'll do it anyway as a sanity + * check to ensure that we don't inadvertently cause mini-forks. */ + if (GetTime() < fix_time) { + if (reactorStakeValue == 15000 && nValueIn == 3000 * COIN) + return 2; + } else { + if (reactorStakeValue == 3000) + return 2; + } - if (reactorStakeValue == 15000 && nValueIn == 15000 * COIN) - return 1.25; + if (GetTime() < fix_time) { + if (reactorStakeValue == 15000 && nValueIn == 15000 * COIN) + return 1.25; + } else { + if (reactorStakeValue == 15000) + return 1.25; + } return 0; } +int64 GetAdjustedCoinYear(int64 nRewardCoinYear, float reactorRate) { + unsigned int fix_time = REACTOR_FIX_TIME; + if (fTestNet) + fix_time = REACTOR_TEST_FIX_TIME; + + /* If the reactor rate is greater than 0 adjust the nRewardCoinYear by + * the given rate. */ + if (reactorRate > 0) { + // If prior to fix cast reactorRate to int to avoid mini-forks. + if (GetTime() < fix_time) { + nRewardCoinYear = nRewardCoinYear * (int)reactorRate; + } else { + nRewardCoinYear = nRewardCoinYear * reactorRate; + } + } else { + /* For 30 days after the fix_time we want to boost the normal stake rate + * by 30%. */ + if (GetTime() >= fix_time && GetTime() < fix_time+(60*60*24*30)) { + nRewardCoinYear = nRewardCoinYear * .3; + } + } + + return nRewardCoinYear; +} + bool CReactorDB::WriteReactorDBVersion(int version) { return Write(string("dbversion"), version); diff --git a/src/reactors.h b/src/reactors.h index 6fce97a..e77755e 100644 --- a/src/reactors.h +++ b/src/reactors.h @@ -39,9 +39,11 @@ class CReactorDB : public CDB * properly run tests in a mock db instead of using the db in the datadir.*/ void InflateReactorDB(std::string strFileName); -/* Get the reactorRate (Legendaries have two possible rates so use nValueIn - * when calculating for them). */ -int GetReactorRate(int64 /*reactorStakeValue*/, int64 /*nValueIn*/); +// Get the reactorRate (see inline comments for why nValueIn is needed). +float GetReactorRate(int64 /*reactorStakeValue*/, int64 /*nValueIn*/); +/* Get the adjusted coin year based on the reactorRate (depending on the time + * in relation to REACTOR_FIX_TIME. */ +int64 GetAdjustedCoinYear(int64 /*nRewardCoinYear*/, float /*reactorRate*/); inline std::string GetReactorDBFile() { return (GetDataDir() / "reactors.dat").string(); From b3852549480d01afb9dff79f52d289b51ad21b16 Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Wed, 1 Jun 2016 19:23:22 -0500 Subject: [PATCH 201/218] 30% base rate not 30 * old base (25) --- src/reactors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactors.cpp b/src/reactors.cpp index 6dfb2ef..aeb444a 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -153,7 +153,7 @@ int64 GetAdjustedCoinYear(int64 nRewardCoinYear, float reactorRate) { /* For 30 days after the fix_time we want to boost the normal stake rate * by 30%. */ if (GetTime() >= fix_time && GetTime() < fix_time+(60*60*24*30)) { - nRewardCoinYear = nRewardCoinYear * .3; + nRewardCoinYear = 30 * CENT; } } From 25c3a92c29ae27b1f520ce461760ab90a32ff8a2 Mon Sep 17 00:00:00 2001 From: John Doering Date: Fri, 3 Jun 2016 15:52:37 +0000 Subject: [PATCH 202/218] Diamond v2.1.0.2 --- diamond.pro | 2 +- src/clientversion.h | 2 +- src/main.cpp | 4 ++-- src/version.h | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/diamond.pro b/diamond.pro index 998f477..1fd26a5 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 2.1.0.1 +VERSION = 2.1.0.2 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES diff --git a/src/clientversion.h b/src/clientversion.h index 8b87536..a091469 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 1 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_BUILD 2 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/main.cpp b/src/main.cpp index 62c071e..400ae28 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3275,9 +3275,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - /* Disconnect all obsolete clients after 15 May 2016 12:00:00 UTC */ + /* Disconnect all obsolete clients after 12 June 2016 12:00:00 UTC */ uint nAdjTime = GetAdjustedTime(); - if(nAdjTime > 1463313600) { + if(nAdjTime > 1465732800) { if(pfrom->nVersion < MIN_PROTOCOL_VERSION) { printf("obsolete node %s with client %d, disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); diff --git a/src/version.h b/src/version.h index 8645ff6..9f93788 100644 --- a/src/version.h +++ b/src/version.h @@ -25,8 +25,8 @@ extern const std::string CLIENT_DATE; // network protocol versioning // -static const int PROTOCOL_VERSION = 60013; -static const int MIN_PROTOCOL_VERSION = 60013; +static const int PROTOCOL_VERSION = 60014; +static const int MIN_PROTOCOL_VERSION = 60014; // earlier versions not supported as of Feb 2012, and are disconnected static const int MIN_PROTO_VERSION = 209; From e2b278619979adb87c494ede01aee9b11b4eb97b Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Sat, 4 Jun 2016 15:19:15 +0200 Subject: [PATCH 203/218] Update reactors.cpp changed the 30% for a month is base stakerate for all addresses not only addresses without stakeboost --- src/reactors.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/reactors.cpp b/src/reactors.cpp index aeb444a..ba0d2e5 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -139,7 +139,11 @@ int64 GetAdjustedCoinYear(int64 nRewardCoinYear, float reactorRate) { unsigned int fix_time = REACTOR_FIX_TIME; if (fTestNet) fix_time = REACTOR_TEST_FIX_TIME; - + /* For 30 days after the fix_time we want to boost the normal stake rate + * by 30%. */ + if (GetTime() >= fix_time && GetTime() < fix_time+(60*60*24*30)) { + nRewardCoinYear = 30 * CENT; + } /* If the reactor rate is greater than 0 adjust the nRewardCoinYear by * the given rate. */ if (reactorRate > 0) { @@ -149,12 +153,6 @@ int64 GetAdjustedCoinYear(int64 nRewardCoinYear, float reactorRate) { } else { nRewardCoinYear = nRewardCoinYear * reactorRate; } - } else { - /* For 30 days after the fix_time we want to boost the normal stake rate - * by 30%. */ - if (GetTime() >= fix_time && GetTime() < fix_time+(60*60*24*30)) { - nRewardCoinYear = 30 * CENT; - } } return nRewardCoinYear; From b5e6ff2727040a03a6e2babb6401dfd6df9588da Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Sun, 5 Jun 2016 23:58:13 +0200 Subject: [PATCH 204/218] Update reactors.cpp --- src/reactors.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/reactors.cpp b/src/reactors.cpp index ba0d2e5..08ec2c3 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -105,8 +105,13 @@ float GetReactorRate(int64 reactorStakeValue, int64 nValueIn) { if (fTestNet) fix_time = REACTOR_TEST_FIX_TIME; - if (reactorStakeValue == 100) - return 1.05; +if (reactorStakeValue == 100 && (GetTime() > fix_time)) { + return 1.20; +} else { + if (reactorStakeValue == 100 && (GetTime() < fix_time)) { + return 1.05; + } +} if (reactorStakeValue == 1000 || reactorStakeValue == 10000) return 2; From 808e782c3174dc66c3bd0ab4a026133da869fa9c Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Mon, 6 Jun 2016 00:05:20 +0200 Subject: [PATCH 205/218] Update reactors.cpp --- src/reactors.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/reactors.cpp b/src/reactors.cpp index 08ec2c3..6852340 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -105,12 +105,9 @@ float GetReactorRate(int64 reactorStakeValue, int64 nValueIn) { if (fTestNet) fix_time = REACTOR_TEST_FIX_TIME; -if (reactorStakeValue == 100 && (GetTime() > fix_time)) { - return 1.20; -} else { - if (reactorStakeValue == 100 && (GetTime() < fix_time)) { - return 1.05; - } +if(reactorStakeValue == 100) { + if(GetTime() > fix_time) return(1.20); + else return(1.05); } if (reactorStakeValue == 1000 || reactorStakeValue == 10000) From aa09a7334ac99ab2ec1ea39ffee6bb34c9e15ebc Mon Sep 17 00:00:00 2001 From: John Doering Date: Tue, 7 Jun 2016 12:33:45 +0000 Subject: [PATCH 206/218] Diamond v2.1.0.3 --- diamond.pro | 2 +- src/clientversion.h | 2 +- src/main.cpp | 4 ++-- src/reactors.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/diamond.pro b/diamond.pro index 1fd26a5..b538eac 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 2.1.0.2 +VERSION = 2.1.0.3 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES diff --git a/src/clientversion.h b/src/clientversion.h index a091469..c2847ee 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 1 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 2 +#define CLIENT_VERSION_BUILD 3 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! diff --git a/src/main.cpp b/src/main.cpp index 400ae28..f7e96ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3275,9 +3275,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return true; } - /* Disconnect all obsolete clients after 12 June 2016 12:00:00 UTC */ + /* Disconnect all obsolete clients after 20 June 2016 12:00:00 UTC */ uint nAdjTime = GetAdjustedTime(); - if(nAdjTime > 1465732800) { + if(nAdjTime > 1466424000) { if(pfrom->nVersion < MIN_PROTOCOL_VERSION) { printf("obsolete node %s with client %d, disconnecting\n", pfrom->addr.ToString().c_str(), pfrom->nVersion); diff --git a/src/reactors.cpp b/src/reactors.cpp index 6852340..010f942 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -9,7 +9,7 @@ using namespace std; int CURRENT_REACTOR_VERSION = 1; -unsigned int REACTOR_FIX_TIME = 1465689599; // Sat, 11 Jun 2016 23:59:59 GMT +unsigned int REACTOR_FIX_TIME = 1466337600; // 19 Jun 2016 12:00:00 UTC unsigned int REACTOR_TEST_FIX_TIME = 1464123019; // Tue, 24 May 2016 20:50:19 GMT bool maybeWipeReactorDB(string strFileName) { From 4187c8b5942cf96cb556fccae8e7d2282cf1084d Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 21 Jun 2016 12:26:10 +0300 Subject: [PATCH 207/218] Make --debugnet behave as intended Even if fDebugNet was false, some network debugging was still active. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f7e96ba..320325f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3506,14 +3506,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) return error("message getdata size() = %"PRIszu"", vInv.size()); } - if (fDebugNet || (vInv.size() != 1)) + if (fDebugNet && (vInv.size() != 1)) printf("received getdata (%"PRIszu" invsz)\n", vInv.size()); BOOST_FOREACH(const CInv& inv, vInv) { if (fShutdown) return true; - if (fDebugNet || (vInv.size() == 1)) + if (fDebugNet && (vInv.size() == 1)) printf("received getdata for: %s\n", inv.ToString().c_str()); if (inv.type == MSG_BLOCK) From 1738e8e080badf01685664b900beb377e4f2806a Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 21 Jun 2016 12:38:16 +0300 Subject: [PATCH 208/218] More extraneous network debug If it is a debug print, it should only happen when the appropriate debug option is activated, in this case --debugnet --- src/net.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index b0bfc5f..faf368d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -485,9 +485,10 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout) /// debug print - printf("trying connection %s lastseen=%.1fhrs\n", - pszDest ? pszDest : addrConnect.ToString().c_str(), - pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); + if (fDebugNet) + printf("trying connection %s lastseen=%.1fhrs\n", + pszDest ? pszDest : addrConnect.ToString().c_str(), + pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0); // Connect SOCKET hSocket; @@ -496,7 +497,8 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest, int64 nTimeout) addrman.Attempt(addrConnect); /// debug print - printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str()); + if (fDebugNet) + printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str()); // Set to non-blocking #ifdef WIN32 From 173bc4991b6068436fbf90fbcb3f91c28c2453a4 Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 21 Jun 2016 12:47:26 +0300 Subject: [PATCH 209/218] Make some more diagnostic prints debug output Some of the networking code outputs diagnostic messages, that are useful for debug. Make these conditional on fDebugNet There are more out there.. --- src/netbase.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/netbase.cpp b/src/netbase.cpp index 95d6493..06ab06d 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -368,13 +368,15 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); if (nRet == 0) { - printf("connection timeout\n"); + if (fDebugNet) + printf("connection timeout\n"); closesocket(hSocket); return false; } if (nRet == SOCKET_ERROR) { - printf("select() for connection failed: %i\n",WSAGetLastError()); + if (fDebugNet) + printf("select() for connection failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } @@ -385,13 +387,15 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) #endif { - printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); + if (fDebugNet) + printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } if (nRet != 0) { - printf("connect() failed after select(): %s\n",strerror(nRet)); + if (fDebugNet) + printf("connect() failed after select(): %s\n",strerror(nRet)); closesocket(hSocket); return false; } @@ -402,7 +406,8 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe else #endif { - printf("connect() failed: %i\n",WSAGetLastError()); + if (fDebugNet) + printf("connect() failed: %i\n",WSAGetLastError()); closesocket(hSocket); return false; } From 8d900ac514e34ddb3ff41c8cf415cc67b548ac7f Mon Sep 17 00:00:00 2001 From: Daniel Kalchev Date: Tue, 21 Jun 2016 12:56:27 +0300 Subject: [PATCH 210/218] More network prints made debug only There are many more cases, but some of the prints are useless without context --- src/net.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index faf368d..9e263af 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -174,14 +174,16 @@ bool RecvLine(SOCKET hSocket, string& strLine) if (nBytes == 0) { // socket closed - printf("socket closed\n"); + if (fDebugNet) + printf("socket closed\n"); return false; } else { // socket error int nErr = WSAGetLastError(); - printf("recv failed: %d\n", nErr); + if (fDebugNet) + printf("recv failed: %d\n", nErr); return false; } } @@ -536,7 +538,8 @@ void CNode::CloseSocketDisconnect() fDisconnect = true; if (hSocket != INVALID_SOCKET) { - printf("disconnecting node %s\n", addrName.c_str()); + if (fDebugNet) + printf("disconnecting node %s\n", addrName.c_str()); closesocket(hSocket); hSocket = INVALID_SOCKET; vRecv.clear(); @@ -805,7 +808,8 @@ void ThreadSocketHandler2(void* parg) if (have_fds) { int nErr = WSAGetLastError(); - printf("socket select error %d\n", nErr); + if (fDebugNet) + printf("socket select error %d\n", nErr); for (unsigned int i = 0; i <= hSocketMax; i++) FD_SET(i, &fdsetRecv); } From da70a3e170f0fac665262c4cf4f1c854402b790f Mon Sep 17 00:00:00 2001 From: IngCr3at1on Date: Tue, 5 Jul 2016 18:53:43 -0500 Subject: [PATCH 211/218] Safer checks for GetAdjustedCoinYear --- src/main.cpp | 4 ++-- src/reactors.cpp | 8 ++++---- src/reactors.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f7e96ba..79cd674 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1008,7 +1008,7 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi nRewardCoinYear = MAX_MINT_PROOF_OF_STAKE; if(fTestNet) { nRewardCoinYear = 25 * CENT; - nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, reactorRate); + nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, nTime, reactorRate); nSubsidy = nCoinAge * nRewardCoinYear / 365; } else { // Diamond v2 PoS spec: @@ -1025,7 +1025,7 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi else nRewardCoinYear = 50 * CENT; - nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, reactorRate); + nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, nTime, reactorRate); nSubsidy = nCoinAge * nRewardCoinYear / 365; } diff --git a/src/reactors.cpp b/src/reactors.cpp index 010f942..384ff55 100644 --- a/src/reactors.cpp +++ b/src/reactors.cpp @@ -137,20 +137,20 @@ if(reactorStakeValue == 100) { return 0; } -int64 GetAdjustedCoinYear(int64 nRewardCoinYear, float reactorRate) { +int64 GetAdjustedCoinYear(int64 nRewardCoinYear, unsigned int nTime, float reactorRate) { unsigned int fix_time = REACTOR_FIX_TIME; if (fTestNet) fix_time = REACTOR_TEST_FIX_TIME; /* For 30 days after the fix_time we want to boost the normal stake rate * by 30%. */ - if (GetTime() >= fix_time && GetTime() < fix_time+(60*60*24*30)) { + if (nTime >= fix_time && nTime < fix_time+(60*60*24*30)) { nRewardCoinYear = 30 * CENT; - } + } /* If the reactor rate is greater than 0 adjust the nRewardCoinYear by * the given rate. */ if (reactorRate > 0) { // If prior to fix cast reactorRate to int to avoid mini-forks. - if (GetTime() < fix_time) { + if (nTime < fix_time) { nRewardCoinYear = nRewardCoinYear * (int)reactorRate; } else { nRewardCoinYear = nRewardCoinYear * reactorRate; diff --git a/src/reactors.h b/src/reactors.h index e77755e..dc2ade1 100644 --- a/src/reactors.h +++ b/src/reactors.h @@ -43,7 +43,7 @@ void InflateReactorDB(std::string strFileName); float GetReactorRate(int64 /*reactorStakeValue*/, int64 /*nValueIn*/); /* Get the adjusted coin year based on the reactorRate (depending on the time * in relation to REACTOR_FIX_TIME. */ -int64 GetAdjustedCoinYear(int64 /*nRewardCoinYear*/, float /*reactorRate*/); +int64 GetAdjustedCoinYear(int64 /*nRewardCoinYear*/, unsigned int /*nTime*/, float /*reactorRate*/); inline std::string GetReactorDBFile() { return (GetDataDir() / "reactors.dat").string(); From 6548ffcbf2cb6b75980f6963f2c3710534c7aefb Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Thu, 7 Jul 2016 22:43:12 +0200 Subject: [PATCH 212/218] Update diamond.pro --- diamond.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diamond.pro b/diamond.pro index b538eac..f4d851d 100644 --- a/diamond.pro +++ b/diamond.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = diamond-qt -VERSION = 2.1.0.3 +VERSION = 2.1.0.4 INCLUDEPATH += src src/json src/qt QT += core gui network DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN __NO_SYSTEM_INCLUDES From 4b6658da0e883847252d6925d29e4bfdee3db864 Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Thu, 7 Jul 2016 22:44:59 +0200 Subject: [PATCH 213/218] Update clientversion.h --- src/clientversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clientversion.h b/src/clientversion.h index c2847ee..55df318 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -9,7 +9,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 1 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 3 +#define CLIENT_VERSION_BUILD 4 // Converts the parameter X to a string after macro replacement on X has been performed. // Don't merge these into one macro! From 24464e5b8a74664e66d6e0f420cb2943e074c360 Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Thu, 7 Jul 2016 22:56:30 +0200 Subject: [PATCH 214/218] Update main.cpp --- src/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8fb6e49..53d08b7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1025,8 +1025,10 @@ int64 GetProofOfStakeReward(int64 nCoinAge, unsigned int nBits, unsigned int nTi else nRewardCoinYear = 50 * CENT; - nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, nTime, reactorRate); - nSubsidy = nCoinAge * nRewardCoinYear / 365; + if(nTime > REACTOR_START_TIME) + nRewardCoinYear = GetAdjustedCoinYear(nRewardCoinYear, nTime, reactorRate); + + nSubsidy = nCoinAge * nRewardCoinYear / 365; } if (fDebug && GetBoolArg("-printcreation")) From 70ebaf5b9e9c8447b379329beba528261b42b5d9 Mon Sep 17 00:00:00 2001 From: Helmut Siedl Date: Wed, 23 Aug 2017 10:47:36 +0200 Subject: [PATCH 215/218] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index dfd16fb..6e61005 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ +please be aware this codebase is soon set inactive +DMD Diamond move forward to DMDv3 codebase +balance from DMDv2 addresses will be available with same private keys in DMDv3 + +to stay up to date following us on bitcointalk +https://bitcointalk.org/index.php?topic=580725.0 +and twitter @dmdcoin + + +------------------------------------------ Diamond (DMD) Instructions for compiling in Linux. From 61abde4fca299db740c31a1148e2aaf124d52f10 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 15 Sep 2017 21:24:43 +0200 Subject: [PATCH 216/218] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6e61005..7e1a382 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +------------------------------------------ +Diamond (DMD) Old Version - Do not use this Source !! + + please be aware this codebase is soon set inactive DMD Diamond move forward to DMDv3 codebase balance from DMDv2 addresses will be available with same private keys in DMDv3 From 5935dbfcf00a9ac54c45e5a91ab89929068cf262 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 15 Sep 2017 21:25:22 +0200 Subject: [PATCH 217/218] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7e1a382..8bb39da 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ------------------------------------------ -Diamond (DMD) Old Version - Do not use this Source !! +* Diamond (DMD) Old Version - Do not use this Source !!* please be aware this codebase is soon set inactive From 2fad0c21627d56a7d9d7d54f164965ffe285f356 Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 15 Sep 2017 21:25:35 +0200 Subject: [PATCH 218/218] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8bb39da..026f3e4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ ------------------------------------------ -* Diamond (DMD) Old Version - Do not use this Source !!* +Diamond (DMD) Old Version - Do not use this Source !! +--- please be aware this codebase is soon set inactive