@ -898,14 +898,7 @@ bool IsInitialBlockDownload()
pindexBest - > GetBlockTime ( ) < GetTime ( ) - 24 * 60 * 60 ) ;
pindexBest - > GetBlockTime ( ) < GetTime ( ) - 24 * 60 * 60 ) ;
}
}
bool IsLockdown ( )
void InvalidChainFound ( CBlockIndex * pindexNew )
{
if ( ! pindexBest )
return false ;
return ( bnBestInvalidWork > bnBestChainWork + pindexBest - > GetBlockWork ( ) * 6 ) ;
}
void Lockdown ( CBlockIndex * pindexNew )
{
{
if ( pindexNew - > bnChainWork > bnBestInvalidWork )
if ( pindexNew - > bnChainWork > bnBestInvalidWork )
{
{
@ -913,11 +906,10 @@ void Lockdown(CBlockIndex* pindexNew)
CTxDB ( ) . WriteBestInvalidWork ( bnBestInvalidWork ) ;
CTxDB ( ) . WriteBestInvalidWork ( bnBestInvalidWork ) ;
MainFrameRepaint ( ) ;
MainFrameRepaint ( ) ;
}
}
printf ( " Lockdown: invalid block=%s height=%d work=%s \n " , pindexNew - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , pindexNew - > nHeight , pindexNew - > bnChainWork . ToString ( ) . c_str ( ) ) ;
printf ( " InvalidChainFound: invalid block=%s height=%d work=%s \n " , pindexNew - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , pindexNew - > nHeight , pindexNew - > bnChainWork . ToString ( ) . c_str ( ) ) ;
printf ( " Lockdown: current best=%s height=%d work=%s \n " , hashBestChain . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , nBestHeight , bnBestChainWork . ToString ( ) . c_str ( ) ) ;
printf ( " InvalidChainFound: current best=%s height=%d work=%s \n " , hashBestChain . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , nBestHeight , bnBestChainWork . ToString ( ) . c_str ( ) ) ;
printf ( " Lockdown: IsLockdown()=%d \n " , ( IsLockdown ( ) ? 1 : 0 ) ) ;
if ( pindexBest & & bnBestInvalidWork > bnBestChainWork + pindexBest - > GetBlockWork ( ) * 6 )
if ( IsLockdown ( ) )
printf ( " InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. \n " ) ;
printf ( " Lockdown: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. \n " ) ;
}
}
@ -927,6 +919,9 @@ void Lockdown(CBlockIndex* pindexNew)
bool CTransaction : : DisconnectInputs ( CTxDB & txdb )
bool CTransaction : : DisconnectInputs ( CTxDB & txdb )
{
{
// Relinquish previous transactions' spent pointers
// Relinquish previous transactions' spent pointers
@ -1282,7 +1277,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
if ( ! ConnectBlock ( txdb , pindexNew ) | | ! txdb . WriteHashBestChain ( hash ) )
if ( ! ConnectBlock ( txdb , pindexNew ) | | ! txdb . WriteHashBestChain ( hash ) )
{
{
txdb . TxnAbort ( ) ;
txdb . TxnAbort ( ) ;
Lockdown ( pindexNew ) ;
InvalidChainFound ( pindexNew ) ;
return error ( " SetBestChain() : ConnectBlock failed " ) ;
return error ( " SetBestChain() : ConnectBlock failed " ) ;
}
}
txdb . TxnCommit ( ) ;
txdb . TxnCommit ( ) ;
@ -1298,7 +1293,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
if ( ! Reorganize ( txdb , pindexNew ) )
if ( ! Reorganize ( txdb , pindexNew ) )
{
{
txdb . TxnAbort ( ) ;
txdb . TxnAbort ( ) ;
Lockdown ( pindexNew ) ;
InvalidChainFound ( pindexNew ) ;
return error ( " SetBestChain() : Reorganize failed " ) ;
return error ( " SetBestChain() : Reorganize failed " ) ;
}
}
}
}
@ -1571,16 +1566,16 @@ bool ScanMessageStart(Stream& s)
}
}
}
}
bool CheckDiskSpace ( int64 nAdditionalBytes )
bool CheckDiskSpace ( u int64 nAdditionalBytes )
{
{
uint64 nFreeBytesAvailable = filesystem : : space ( GetDataDir ( ) ) . available ;
uint64 nFreeBytesAvailable = filesystem : : space ( GetDataDir ( ) ) . available ;
// Check for 15MB because database could create another 10MB log file at any time
// Check for 15MB because database could create another 10MB log file at any time
if ( nFreeBytesAvailable < ( int64 ) 15000000 + nAdditionalBytes )
if ( nFreeBytesAvailable < ( u int64) 15000000 + nAdditionalBytes )
{
{
fShutdown = true ;
fShutdown = true ;
string strMessage = _ ( " Warning: Disk space is low " ) ;
string strMessage = _ ( " Warning: Disk space is low " ) ;
strWarning = strMessage ;
strMisc Warning = strMessage ;
printf ( " *** %s \n " , strMessage . c_str ( ) ) ;
printf ( " *** %s \n " , strMessage . c_str ( ) ) ;
ThreadSafeMessageBox ( strMessage , " Bitcoin " , wxOK | wxICON_EXCLAMATION ) ;
ThreadSafeMessageBox ( strMessage , " Bitcoin " , wxOK | wxICON_EXCLAMATION ) ;
CreateThread ( Shutdown , NULL ) ;
CreateThread ( Shutdown , NULL ) ;
@ -1648,17 +1643,7 @@ bool LoadBlockIndex(bool fAllowNew)
if ( ! fAllowNew )
if ( ! fAllowNew )
return false ;
return false ;
// Genesis Block:
// Genesis Block:
// GetHash() = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
// hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
// txNew.vin[0].scriptSig = 486604799 4 0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854
// txNew.vout[0].nValue = 5000000000
// txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG
// block.nVersion = 1
// block.nTime = 1231006505
// block.nBits = 0x1d00ffff
// block.nNonce = 2083236893
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
// CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
// CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
@ -1672,9 +1657,7 @@ bool LoadBlockIndex(bool fAllowNew)
txNew . vout . resize ( 1 ) ;
txNew . vout . resize ( 1 ) ;
txNew . vin [ 0 ] . scriptSig = CScript ( ) < < 486604799 < < CBigNum ( 4 ) < < vector < unsigned char > ( ( const unsigned char * ) pszTimestamp , ( const unsigned char * ) pszTimestamp + strlen ( pszTimestamp ) ) ;
txNew . vin [ 0 ] . scriptSig = CScript ( ) < < 486604799 < < CBigNum ( 4 ) < < vector < unsigned char > ( ( const unsigned char * ) pszTimestamp , ( const unsigned char * ) pszTimestamp + strlen ( pszTimestamp ) ) ;
txNew . vout [ 0 ] . nValue = 50 * COIN ;
txNew . vout [ 0 ] . nValue = 50 * COIN ;
CBigNum bnPubKey ;
txNew . vout [ 0 ] . scriptPubKey = CScript ( ) < < ParseHex ( " 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f " ) < < OP_CHECKSIG ;
bnPubKey . SetHex ( " 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 " ) ;
txNew . vout [ 0 ] . scriptPubKey = CScript ( ) < < bnPubKey < < OP_CHECKSIG ;
CBlock block ;
CBlock block ;
block . vtx . push_back ( txNew ) ;
block . vtx . push_back ( txNew ) ;
block . hashPrevBlock = 0 ;
block . hashPrevBlock = 0 ;
@ -1686,11 +1669,10 @@ bool LoadBlockIndex(bool fAllowNew)
//// debug print
//// debug print
printf ( " %s \n " , block . GetHash ( ) . ToString ( ) . c_str ( ) ) ;
printf ( " %s \n " , block . GetHash ( ) . ToString ( ) . c_str ( ) ) ;
printf ( " %s \n " , block . hashMerkleRoot . ToString ( ) . c_str ( ) ) ;
printf ( " %s \n " , hashGenesisBlock . ToString ( ) . c_str ( ) ) ;
printf ( " %s \n " , hashGenesisBlock . ToString ( ) . c_str ( ) ) ;
txNew . vout [ 0 ] . scriptPubKey . print ( ) ;
printf ( " %s \n " , block . hashMerkleRoot . ToString ( ) . c_str ( ) ) ;
block . print ( ) ;
assert ( block . hashMerkleRoot = = uint256 ( " 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b " ) ) ;
assert ( block . hashMerkleRoot = = uint256 ( " 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b " ) ) ;
block . print ( ) ;
assert ( block . GetHash ( ) = = hashGenesisBlock ) ;
assert ( block . GetHash ( ) = = hashGenesisBlock ) ;
@ -1798,6 +1780,111 @@ void PrintBlockTree()
//////////////////////////////////////////////////////////////////////////////
//
// CAlert
//
map < uint256 , CAlert > mapAlerts ;
CCriticalSection cs_mapAlerts ;
string GetWarnings ( string strFor )
{
int nPriority = 0 ;
string strStatusBar ;
string strRPC ;
// Misc warnings like out of disk space and clock is wrong
if ( strMiscWarning ! = " " )
{
nPriority = 1000 ;
strStatusBar = strMiscWarning ;
}
// Longer invalid proof-of-work chain
if ( pindexBest & & bnBestInvalidWork > bnBestChainWork + pindexBest - > GetBlockWork ( ) * 6 )
{
nPriority = 2000 ;
strStatusBar = strRPC = " WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. " ;
}
// Alerts
CRITICAL_BLOCK ( cs_mapAlerts )
{
foreach ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
{
const CAlert & alert = item . second ;
if ( alert . AppliesToMe ( ) & & alert . nPriority > nPriority )
{
nPriority = alert . nPriority ;
strStatusBar = alert . strStatusBar ;
strRPC = alert . strRPCError ;
}
}
}
if ( strFor = = " statusbar " )
return strStatusBar ;
else if ( strFor = = " rpc " )
return strRPC ;
assert ( ( " GetWarnings() : invalid parameter " , false ) ) ;
return " error " ;
}
bool CAlert : : ProcessAlert ( )
{
if ( ! CheckSignature ( ) )
return false ;
if ( ! IsInEffect ( ) )
return false ;
CRITICAL_BLOCK ( cs_mapAlerts )
{
// Cancel previous alerts
for ( map < uint256 , CAlert > : : iterator mi = mapAlerts . begin ( ) ; mi ! = mapAlerts . end ( ) ; )
{
const CAlert & alert = ( * mi ) . second ;
if ( Cancels ( alert ) )
{
printf ( " cancelling alert %d \n " , alert . nID ) ;
mapAlerts . erase ( mi + + ) ;
}
else if ( ! alert . IsInEffect ( ) )
{
printf ( " expiring alert %d \n " , alert . nID ) ;
mapAlerts . erase ( mi + + ) ;
}
else
mi + + ;
}
// Check if this alert has been cancelled
foreach ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
{
const CAlert & alert = item . second ;
if ( alert . Cancels ( * this ) )
{
printf ( " alert already cancelled by %d \n " , alert . nID ) ;
return false ;
}
}
// Add to mapAlerts
mapAlerts . insert ( make_pair ( GetHash ( ) , * this ) ) ;
}
printf ( " accepted alert %d, AppliesToMe()=%d \n " , nID , AppliesToMe ( ) ) ;
MainFrameRepaint ( ) ;
return true ;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
//
// Messages
// Messages
@ -1827,7 +1914,7 @@ bool ProcessMessages(CNode* pfrom)
if ( vRecv . empty ( ) )
if ( vRecv . empty ( ) )
return true ;
return true ;
//if (fDebug)
//if (fDebug)
// printf("ProcessMessages(%d bytes)\n", vRecv.size());
// printf("ProcessMessages(%u bytes)\n", vRecv.size());
//
//
// Message format
// Message format
@ -1869,6 +1956,11 @@ bool ProcessMessages(CNode* pfrom)
// Message size
// Message size
unsigned int nMessageSize = hdr . nMessageSize ;
unsigned int nMessageSize = hdr . nMessageSize ;
if ( nMessageSize > MAX_SIZE )
{
printf ( " ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE \n " , strCommand . c_str ( ) , nMessageSize ) ;
continue ;
}
if ( nMessageSize > vRecv . size ( ) )
if ( nMessageSize > vRecv . size ( ) )
{
{
// Rewind and wait for rest of message
// Rewind and wait for rest of message
@ -1889,7 +1981,7 @@ bool ProcessMessages(CNode* pfrom)
memcpy ( & nChecksum , & hash , sizeof ( nChecksum ) ) ;
memcpy ( & nChecksum , & hash , sizeof ( nChecksum ) ) ;
if ( nChecksum ! = hdr . nChecksum )
if ( nChecksum ! = hdr . nChecksum )
{
{
printf ( " ProcessMessage(%s, %d bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x \n " ,
printf ( " ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x \n " ,
strCommand . c_str ( ) , nMessageSize , nChecksum , hdr . nChecksum ) ;
strCommand . c_str ( ) , nMessageSize , nChecksum , hdr . nChecksum ) ;
continue ;
continue ;
}
}
@ -1906,15 +1998,15 @@ bool ProcessMessages(CNode* pfrom)
}
}
catch ( std : : ios_base : : failure & e )
catch ( std : : ios_base : : failure & e )
{
{
if ( strstr ( e . what ( ) , " CDataStream::read() : end of data" ) )
if ( strstr ( e . what ( ) , " end of data " ) )
{
{
// Allow exceptions from underlength message on vRecv
// Allow exceptions from underlength message on vRecv
printf ( " ProcessMessage(%s, %d bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length \n " , strCommand . c_str ( ) , nMessageSize , e . what ( ) ) ;
printf ( " ProcessMessage(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length \n " , strCommand . c_str ( ) , nMessageSize , e . what ( ) ) ;
}
}
else if ( strstr ( e . what ( ) , " : size too large" ) )
else if ( strstr ( e . what ( ) , " size too large " ) )
{
{
// Allow exceptions from overlong size
// Allow exceptions from overlong size
printf ( " ProcessMessage(%s, %d bytes) : Exception '%s' caught \n " , strCommand . c_str ( ) , nMessageSize , e . what ( ) ) ;
printf ( " ProcessMessage(%s, %u bytes) : Exception '%s' caught \n " , strCommand . c_str ( ) , nMessageSize , e . what ( ) ) ;
}
}
else
else
{
{
@ -1928,7 +2020,7 @@ bool ProcessMessages(CNode* pfrom)
}
}
if ( ! fRet )
if ( ! fRet )
printf ( " ProcessMessage(%s, %d bytes) FAILED \n " , strCommand . c_str ( ) , nMessageSize ) ;
printf ( " ProcessMessage(%s, %u bytes) FAILED \n " , strCommand . c_str ( ) , nMessageSize ) ;
}
}
vRecv . Compact ( ) ;
vRecv . Compact ( ) ;
@ -1965,14 +2057,13 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CAddress addrMe ;
CAddress addrMe ;
CAddress addrFrom ;
CAddress addrFrom ;
uint64 nNonce = 1 ;
uint64 nNonce = 1 ;
string strSubVer ;
vRecv > > pfrom - > nVersion > > pfrom - > nServices > > nTime > > addrMe ;
vRecv > > pfrom - > nVersion > > pfrom - > nServices > > nTime > > addrMe ;
if ( pfrom - > nVersion = = 10300 )
if ( pfrom - > nVersion = = 10300 )
pfrom - > nVersion = 300 ;
pfrom - > nVersion = 300 ;
if ( pfrom - > nVersion > = 106 & & ! vRecv . empty ( ) )
if ( pfrom - > nVersion > = 106 & & ! vRecv . empty ( ) )
vRecv > > addrFrom > > nNonce ;
vRecv > > addrFrom > > nNonce ;
if ( pfrom - > nVersion > = 106 & & ! vRecv . empty ( ) )
if ( pfrom - > nVersion > = 106 & & ! vRecv . empty ( ) )
vRecv > > strSubVer ;
vRecv > > pfrom - > strSubVer ;
if ( pfrom - > nVersion > = 209 & & ! vRecv . empty ( ) )
if ( pfrom - > nVersion > = 209 & & ! vRecv . empty ( ) )
vRecv > > pfrom - > nStartingHeight ;
vRecv > > pfrom - > nStartingHeight ;
@ -2010,6 +2101,11 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
pfrom - > PushGetBlocks ( pindexBest , uint256 ( 0 ) ) ;
pfrom - > PushGetBlocks ( pindexBest , uint256 ( 0 ) ) ;
}
}
// Relay alerts
CRITICAL_BLOCK ( cs_mapAlerts )
foreach ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
item . second . RelayTo ( pfrom ) ;
pfrom - > fSuccessfullyConnected = true ;
pfrom - > fSuccessfullyConnected = true ;
printf ( " version message: version %d, blocks=%d \n " , pfrom - > nVersion , pfrom - > nStartingHeight ) ;
printf ( " version message: version %d, blocks=%d \n " , pfrom - > nVersion , pfrom - > nStartingHeight ) ;
@ -2362,6 +2458,22 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
}
else if ( strCommand = = " alert " )
{
CAlert alert ;
vRecv > > alert ;
if ( alert . ProcessAlert ( ) )
{
// Relay
pfrom - > setKnown . insert ( alert . GetHash ( ) ) ;
CRITICAL_BLOCK ( cs_vNodes )
foreach ( CNode * pnode , vNodes )
alert . RelayTo ( pnode ) ;
}
}
else
else
{
{
// Ignore unknown commands for extensibility
// Ignore unknown commands for extensibility
@ -2695,7 +2807,7 @@ void BitcoinMiner()
map < uint256 , CTxIndex > mapTestPool ;
map < uint256 , CTxIndex > mapTestPool ;
vector < char > vfAlreadyAdded ( mapTransactions . size ( ) ) ;
vector < char > vfAlreadyAdded ( mapTransactions . size ( ) ) ;
bool fFoundSomething = true ;
bool fFoundSomething = true ;
unsigned int nBlockSize = 0 ;
uint64 nBlockSize = 0 ;
while ( fFoundSomething & & nBlockSize < MAX_SIZE / 2 )
while ( fFoundSomething & & nBlockSize < MAX_SIZE / 2 )
{
{
fFoundSomething = false ;
fFoundSomething = false ;