|
|
@ -21,7 +21,8 @@ unsigned int nTransactionsUpdated = 0; |
|
|
|
map<COutPoint, CInPoint> mapNextTx; |
|
|
|
map<COutPoint, CInPoint> mapNextTx; |
|
|
|
|
|
|
|
|
|
|
|
map<uint256, CBlockIndex*> mapBlockIndex; |
|
|
|
map<uint256, CBlockIndex*> mapBlockIndex; |
|
|
|
const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); |
|
|
|
uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"); |
|
|
|
|
|
|
|
CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); |
|
|
|
CBlockIndex* pindexGenesisBlock = NULL; |
|
|
|
CBlockIndex* pindexGenesisBlock = NULL; |
|
|
|
int nBestHeight = -1; |
|
|
|
int nBestHeight = -1; |
|
|
|
CBigNum bnBestChainWork = 0; |
|
|
|
CBigNum bnBestChainWork = 0; |
|
|
@ -1487,6 +1488,7 @@ bool CBlock::AcceptBlock() |
|
|
|
return error("AcceptBlock() : contains a non-final transaction"); |
|
|
|
return error("AcceptBlock() : contains a non-final transaction"); |
|
|
|
|
|
|
|
|
|
|
|
// Check that the block chain matches the known block chain up to a checkpoint
|
|
|
|
// Check that the block chain matches the known block chain up to a checkpoint
|
|
|
|
|
|
|
|
if (!fTestNet) |
|
|
|
if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) || |
|
|
|
if ((nHeight == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) || |
|
|
|
(nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) || |
|
|
|
(nHeight == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) || |
|
|
|
(nHeight == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) || |
|
|
|
(nHeight == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) || |
|
|
@ -1683,6 +1685,16 @@ FILE* AppendBlockFile(unsigned int& nFileRet) |
|
|
|
|
|
|
|
|
|
|
|
bool LoadBlockIndex(bool fAllowNew) |
|
|
|
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
|
|
|
|
// Load block index
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -1723,13 +1735,19 @@ bool LoadBlockIndex(bool fAllowNew) |
|
|
|
block.nBits = 0x1d00ffff; |
|
|
|
block.nBits = 0x1d00ffff; |
|
|
|
block.nNonce = 2083236893; |
|
|
|
block.nNonce = 2083236893; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fTestNet) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
block.nTime = 1279232055; |
|
|
|
|
|
|
|
block.nBits = 0x1d07fff8; |
|
|
|
|
|
|
|
block.nNonce = 81622180; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//// debug print
|
|
|
|
//// debug print
|
|
|
|
printf("%s\n", block.GetHash().ToString().c_str()); |
|
|
|
printf("%s\n", block.GetHash().ToString().c_str()); |
|
|
|
printf("%s\n", hashGenesisBlock.ToString().c_str()); |
|
|
|
printf("%s\n", hashGenesisBlock.ToString().c_str()); |
|
|
|
printf("%s\n", block.hashMerkleRoot.ToString().c_str()); |
|
|
|
printf("%s\n", block.hashMerkleRoot.ToString().c_str()); |
|
|
|
assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); |
|
|
|
assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); |
|
|
|
block.print(); |
|
|
|
block.print(); |
|
|
|
|
|
|
|
|
|
|
|
assert(block.GetHash() == hashGenesisBlock); |
|
|
|
assert(block.GetHash() == hashGenesisBlock); |
|
|
|
|
|
|
|
|
|
|
|
// Start new block file
|
|
|
|
// 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) |
|
|
|
bool ProcessMessages(CNode* pfrom) |
|
|
@ -2022,19 +2043,14 @@ bool ProcessMessages(CNode* pfrom) |
|
|
|
if (nMessageSize > vRecv.size()) |
|
|
|
if (nMessageSize > vRecv.size()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Rewind and wait for rest of message
|
|
|
|
// 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()); |
|
|
|
vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Copy message to its own buffer
|
|
|
|
|
|
|
|
CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion); |
|
|
|
|
|
|
|
vRecv.ignore(nMessageSize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Checksum
|
|
|
|
// Checksum
|
|
|
|
if (vRecv.GetVersion() >= 209) |
|
|
|
if (vRecv.GetVersion() >= 209) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint256 hash = Hash(vMsg.begin(), vMsg.end()); |
|
|
|
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize); |
|
|
|
unsigned int nChecksum = 0; |
|
|
|
unsigned int nChecksum = 0; |
|
|
|
memcpy(&nChecksum, &hash, sizeof(nChecksum)); |
|
|
|
memcpy(&nChecksum, &hash, sizeof(nChecksum)); |
|
|
|
if (nChecksum != hdr.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
|
|
|
|
// Process message
|
|
|
|
bool fRet = false; |
|
|
|
bool fRet = false; |
|
|
|
try |
|
|
|
try |
|
|
@ -2208,20 +2228,27 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) |
|
|
|
addr.nTime -= 5 * 24 * 60 * 60; |
|
|
|
addr.nTime -= 5 * 24 * 60 * 60; |
|
|
|
AddAddress(addr); |
|
|
|
AddAddress(addr); |
|
|
|
pfrom->AddAddressKnown(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
|
|
|
|
// Relay to a limited number of other nodes
|
|
|
|
CRITICAL_BLOCK(cs_vNodes) |
|
|
|
CRITICAL_BLOCK(cs_vNodes) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Use deterministic randomness to send to
|
|
|
|
// Use deterministic randomness to send to the same nodes for 24 hours
|
|
|
|
// the same places for 12 hours at a time
|
|
|
|
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
|
|
|
|
static uint256 hashSalt; |
|
|
|
static uint256 hashSalt; |
|
|
|
if (hashSalt == 0) |
|
|
|
if (hashSalt == 0) |
|
|
|
RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt)); |
|
|
|
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; |
|
|
|
multimap<uint256, CNode*> mapMix; |
|
|
|
foreach(CNode* pnode, vNodes) |
|
|
|
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; |
|
|
|
int nRelayNodes = 2; |
|
|
|
for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) |
|
|
|
for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) |
|
|
|
((*mi).second)->PushAddress(addr); |
|
|
|
((*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) |
|
|
|
foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const CAddress& addr = item.second; |
|
|
|
const CAddress& addr = item.second; |
|
|
|
if (addr.nTime > nSince && GetRand(nCount) < 2000) |
|
|
|
if (addr.nTime > nSince && GetRand(nCount) < 2500) |
|
|
|
pfrom->PushAddress(addr); |
|
|
|
pfrom->PushAddress(addr); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -2931,10 +2958,12 @@ void BitcoinMiner() |
|
|
|
f4WaySSE2 = (mapArgs["-4way"] != "0"); |
|
|
|
f4WaySSE2 = (mapArgs["-4way"] != "0"); |
|
|
|
|
|
|
|
|
|
|
|
CReserveKey reservekey; |
|
|
|
CReserveKey reservekey; |
|
|
|
CBigNum bnExtraNonce = 0; |
|
|
|
unsigned int nExtraNonce = 0; |
|
|
|
|
|
|
|
int64 nPrevTime = 0; |
|
|
|
while (fGenerateBitcoins) |
|
|
|
while (fGenerateBitcoins) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Sleep(50); |
|
|
|
if (AffinityBugWorkaround(ThreadBitcoinMiner)) |
|
|
|
|
|
|
|
return; |
|
|
|
if (fShutdown) |
|
|
|
if (fShutdown) |
|
|
|
return; |
|
|
|
return; |
|
|
|
while (vNodes.empty() || IsInitialBlockDownload()) |
|
|
|
while (vNodes.empty() || IsInitialBlockDownload()) |
|
|
@ -2957,7 +2986,13 @@ void BitcoinMiner() |
|
|
|
CTransaction txNew; |
|
|
|
CTransaction txNew; |
|
|
|
txNew.vin.resize(1); |
|
|
|
txNew.vin.resize(1); |
|
|
|
txNew.vin[0].prevout.SetNull(); |
|
|
|
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.resize(1); |
|
|
|
txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; |
|
|
|
txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; |
|
|
|
|
|
|
|
|
|
|
@ -3045,9 +3080,9 @@ void BitcoinMiner() |
|
|
|
tmpworkspace& tmp = *(tmpworkspace*)alignup<16>(tmpbuf); |
|
|
|
tmpworkspace& tmp = *(tmpworkspace*)alignup<16>(tmpbuf); |
|
|
|
|
|
|
|
|
|
|
|
tmp.block.nVersion = pblock->nVersion; |
|
|
|
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.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.nBits = pblock->nBits = nBits; |
|
|
|
tmp.block.nNonce = pblock->nNonce = 0; |
|
|
|
tmp.block.nNonce = pblock->nNonce = 0; |
|
|
|
|
|
|
|
|
|
|
@ -3177,10 +3212,7 @@ void BitcoinMiner() |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
// Update nTime every few seconds
|
|
|
|
// Update nTime every few seconds
|
|
|
|
int64 nNewTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); |
|
|
|
pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); |
|
|
|
if (nNewTime != pblock->nTime && bnExtraNonce > 10) |
|
|
|
|
|
|
|
bnExtraNonce = 0; |
|
|
|
|
|
|
|
pblock->nTime = nNewTime; |
|
|
|
|
|
|
|
tmp.block.nTime = ByteReverse(pblock->nTime); |
|
|
|
tmp.block.nTime = ByteReverse(pblock->nTime); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|