aboutsummaryrefslogtreecommitdiff
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp102
1 files changed, 67 insertions, 35 deletions
diff --git a/main.cpp b/main.cpp
index 569ea5372d..2d950eefb5 100644
--- a/main.cpp
+++ b/main.cpp
@@ -21,7 +21,8 @@ unsigned int nTransactionsUpdated = 0;
map<COutPoint, CInPoint> mapNextTx;
map<uint256, CBlockIndex*> mapBlockIndex;
-const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
+uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
+CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
CBlockIndex* pindexGenesisBlock = NULL;
int nBestHeight = -1;
CBigNum bnBestChainWork = 0;
@@ -1487,12 +1488,13 @@ bool CBlock::AcceptBlock()
return error("AcceptBlock() : contains a non-final transaction");
// Check that the block chain matches the known block chain up to a checkpoint
- if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ||
- (nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ||
- (nHeight == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) ||
- (nHeight == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a")) ||
- (nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")))
- return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight);
+ if (!fTestNet)
+ if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ||
+ (nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ||
+ (nHeight == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) ||
+ (nHeight == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a")) ||
+ (nHeight == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")))
+ return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight);
// Write block to history file
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
@@ -1683,6 +1685,16 @@ FILE* AppendBlockFile(unsigned int& nFileRet)
bool LoadBlockIndex(bool fAllowNew)
{
+ if (fTestNet)
+ {
+ hashGenesisBlock = uint256("0x0000000224b1593e3ff16a0e3b61285bbc393a39f78c8aa48c456142671f7110");
+ bnProofOfWorkLimit = CBigNum(~uint256(0) >> 28);
+ pchMessageStart[0] = 0xfa;
+ pchMessageStart[1] = 0xbf;
+ pchMessageStart[2] = 0xb5;
+ pchMessageStart[3] = 0xda;
+ }
+
//
// Load block index
//
@@ -1723,13 +1735,19 @@ bool LoadBlockIndex(bool fAllowNew)
block.nBits = 0x1d00ffff;
block.nNonce = 2083236893;
- //// debug print
- printf("%s\n", block.GetHash().ToString().c_str());
- printf("%s\n", hashGenesisBlock.ToString().c_str());
- printf("%s\n", block.hashMerkleRoot.ToString().c_str());
- assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
- block.print();
+ if (fTestNet)
+ {
+ block.nTime = 1279232055;
+ block.nBits = 0x1d07fff8;
+ block.nNonce = 81622180;
+ }
+ //// debug print
+ printf("%s\n", block.GetHash().ToString().c_str());
+ printf("%s\n", hashGenesisBlock.ToString().c_str());
+ printf("%s\n", block.hashMerkleRoot.ToString().c_str());
+ assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
+ block.print();
assert(block.GetHash() == hashGenesisBlock);
// Start new block file
@@ -1963,7 +1981,10 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv)
-
+// The message start string is designed to be unlikely to occur in normal data.
+// The characters are rarely used upper ascii, not valid as UTF-8, and produce
+// a large 4-byte int at any alignment.
+char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
bool ProcessMessages(CNode* pfrom)
@@ -2022,19 +2043,14 @@ bool ProcessMessages(CNode* pfrom)
if (nMessageSize > vRecv.size())
{
// Rewind and wait for rest of message
- ///// need a mechanism to give up waiting for overlong message size error
vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
break;
}
- // Copy message to its own buffer
- CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
- vRecv.ignore(nMessageSize);
-
// Checksum
if (vRecv.GetVersion() >= 209)
{
- uint256 hash = Hash(vMsg.begin(), vMsg.end());
+ uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
unsigned int nChecksum = 0;
memcpy(&nChecksum, &hash, sizeof(nChecksum));
if (nChecksum != hdr.nChecksum)
@@ -2045,6 +2061,10 @@ bool ProcessMessages(CNode* pfrom)
}
}
+ // Copy message to its own buffer
+ CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
+ vRecv.ignore(nMessageSize);
+
// Process message
bool fRet = false;
try
@@ -2208,20 +2228,27 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
addr.nTime -= 5 * 24 * 60 * 60;
AddAddress(addr);
pfrom->AddAddressKnown(addr);
- if (!pfrom->fGetAddr && addr.IsRoutable())
+ if (!pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
{
// Relay to a limited number of other nodes
CRITICAL_BLOCK(cs_vNodes)
{
- // Use deterministic randomness to send to
- // the same places for 12 hours at a time
+ // Use deterministic randomness to send to the same nodes for 24 hours
+ // at a time so the setAddrKnowns of the chosen nodes prevent repeats
static uint256 hashSalt;
if (hashSalt == 0)
RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
- uint256 hashRand = addr.ip ^ ((GetTime()+addr.ip)/(12*60*60)) ^ hashSalt;
+ uint256 hashRand = hashSalt ^ (((int64)addr.ip)<<32) ^ ((GetTime()+addr.ip)/(24*60*60));
+ hashRand = Hash(BEGIN(hashRand), END(hashRand));
multimap<uint256, CNode*> mapMix;
foreach(CNode* pnode, vNodes)
- mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode));
+ {
+ unsigned int nPointer;
+ memcpy(&nPointer, &pnode, sizeof(nPointer));
+ uint256 hashKey = hashRand ^ nPointer;
+ hashKey = Hash(BEGIN(hashKey), END(hashKey));
+ mapMix.insert(make_pair(hashKey, pnode));
+ }
int nRelayNodes = 2;
for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
((*mi).second)->PushAddress(addr);
@@ -2446,7 +2473,7 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
{
const CAddress& addr = item.second;
- if (addr.nTime > nSince && GetRand(nCount) < 2000)
+ if (addr.nTime > nSince && GetRand(nCount) < 2500)
pfrom->PushAddress(addr);
}
}
@@ -2931,10 +2958,12 @@ void BitcoinMiner()
f4WaySSE2 = (mapArgs["-4way"] != "0");
CReserveKey reservekey;
- CBigNum bnExtraNonce = 0;
+ unsigned int nExtraNonce = 0;
+ int64 nPrevTime = 0;
while (fGenerateBitcoins)
{
- Sleep(50);
+ if (AffinityBugWorkaround(ThreadBitcoinMiner))
+ return;
if (fShutdown)
return;
while (vNodes.empty() || IsInitialBlockDownload())
@@ -2957,7 +2986,13 @@ void BitcoinMiner()
CTransaction txNew;
txNew.vin.resize(1);
txNew.vin[0].prevout.SetNull();
- txNew.vin[0].scriptSig << ++bnExtraNonce;
+ int64 nNow = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ if (nNow > nPrevTime+1 && ++nExtraNonce >= 0x7f)
+ {
+ nExtraNonce = 1;
+ nPrevTime = nNow;
+ }
+ txNew.vin[0].scriptSig << nBits << CBigNum(nExtraNonce);
txNew.vout.resize(1);
txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
@@ -3045,9 +3080,9 @@ void BitcoinMiner()
tmpworkspace& tmp = *(tmpworkspace*)alignup<16>(tmpbuf);
tmp.block.nVersion = pblock->nVersion;
- tmp.block.hashPrevBlock = pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0);
+ tmp.block.hashPrevBlock = pblock->hashPrevBlock = pindexPrev->GetBlockHash();
tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- tmp.block.nTime = pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime());
+ tmp.block.nTime = pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
tmp.block.nBits = pblock->nBits = nBits;
tmp.block.nNonce = pblock->nNonce = 0;
@@ -3177,10 +3212,7 @@ void BitcoinMiner()
break;
// Update nTime every few seconds
- int64 nNewTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
- if (nNewTime != pblock->nTime && bnExtraNonce > 10)
- bnExtraNonce = 0;
- pblock->nTime = nNewTime;
+ pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
tmp.block.nTime = ByteReverse(pblock->nTime);
}
}