2010-08-29 18:58:15 +02:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2012-02-07 17:28:30 +01:00
// Copyright (c) 2009-2012 The Bitcoin developers
2010-08-29 18:58:15 +02:00
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
2011-09-08 22:50:58 +02:00
# include "checkpoints.h"
2011-05-14 22:57:34 +02:00
# include "db.h"
2011-05-14 23:20:30 +02:00
# include "net.h"
2011-05-15 23:52:31 +02:00
# include "init.h"
2012-04-15 22:10:54 +02:00
# include "ui_interface.h"
2012-01-03 21:24:28 +01:00
# include <boost/algorithm/string/replace.hpp>
2011-06-20 00:12:31 +02:00
# include <boost/filesystem.hpp>
2011-05-16 05:45:35 +02:00
# include <boost/filesystem/fstream.hpp>
2010-08-29 18:58:15 +02:00
2011-05-15 09:11:04 +02:00
using namespace std ;
using namespace boost ;
2010-08-29 18:58:15 +02:00
//
// Global state
//
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
CCriticalSection cs_setpwalletRegistered ;
set < CWallet * > setpwalletRegistered ;
2010-08-29 18:58:15 +02:00
CCriticalSection cs_main ;
2011-08-11 13:41:01 +02:00
static map < uint256 , CTransaction > mapTransactions ;
2010-08-29 18:58:15 +02:00
CCriticalSection cs_mapTransactions ;
unsigned int nTransactionsUpdated = 0 ;
map < COutPoint , CInPoint > mapNextTx ;
map < uint256 , CBlockIndex * > mapBlockIndex ;
2010-10-19 19:16:51 +02:00
uint256 hashGenesisBlock ( " 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f " ) ;
2011-08-11 13:41:01 +02:00
static CBigNum bnProofOfWorkLimit ( ~ uint256 ( 0 ) > > 32 ) ;
2010-08-29 18:58:15 +02:00
CBlockIndex * pindexGenesisBlock = NULL ;
int nBestHeight = - 1 ;
CBigNum bnBestChainWork = 0 ;
CBigNum bnBestInvalidWork = 0 ;
uint256 hashBestChain = 0 ;
CBlockIndex * pindexBest = NULL ;
2011-12-21 22:33:19 +01:00
int64 nTimeBestReceived = 0 ;
2010-08-29 18:58:15 +02:00
2011-09-28 21:35:58 +02:00
CMedianFilter < int > cPeerBlockCounts ( 5 , 0 ) ; // Amount of blocks that other nodes claim to have
2010-08-29 18:58:15 +02:00
map < uint256 , CBlock * > mapOrphanBlocks ;
multimap < uint256 , CBlock * > mapOrphanBlocksByPrev ;
map < uint256 , CDataStream * > mapOrphanTransactions ;
multimap < uint256 , CDataStream * > mapOrphanTransactionsByPrev ;
2012-02-06 21:48:00 +01:00
// Constant stuff for coinbase transactions we create:
CScript COINBASE_FLAGS ;
2010-08-29 18:58:15 +02:00
2011-12-23 16:14:57 +01:00
const string strMessageMagic = " Bitcoin Signed Message: \n " ;
2010-08-29 18:58:15 +02:00
double dHashesPerSec ;
2011-12-21 22:33:19 +01:00
int64 nHPSTimerStart ;
2010-08-29 18:58:15 +02:00
// Settings
2011-12-21 22:33:19 +01:00
int64 nTransactionFee = 0 ;
2012-02-16 21:00:16 +01:00
2011-03-26 13:01:27 +01:00
2010-08-29 18:58:15 +02:00
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
//////////////////////////////////////////////////////////////////////////////
//
// dispatching functions
//
2011-11-07 00:05:42 +01:00
// These functions dispatch to one or all registered wallets
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void RegisterWallet ( CWallet * pwalletIn )
{
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_setpwalletRegistered ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
setpwalletRegistered . insert ( pwalletIn ) ;
}
}
void UnregisterWallet ( CWallet * pwalletIn )
{
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_setpwalletRegistered ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
setpwalletRegistered . erase ( pwalletIn ) ;
}
}
2011-11-07 00:05:42 +01:00
// check whether the passed transaction is from us
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
bool static IsFromMe ( CTransaction & tx )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
if ( pwallet - > IsFromMe ( tx ) )
return true ;
return false ;
}
2011-11-07 00:05:42 +01:00
// get the wallet transaction with the given hash (if it exists)
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
bool static GetTransaction ( const uint256 & hashTx , CWalletTx & wtx )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
if ( pwallet - > GetTransaction ( hashTx , wtx ) )
return true ;
return false ;
}
2011-11-07 00:05:42 +01:00
// erases transaction with the given hash from all wallets
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static EraseFromWallets ( uint256 hash )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > EraseFromWallet ( hash ) ;
}
2011-11-07 00:05:42 +01:00
// make sure all wallets know about the given transaction, in the given block
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static SyncWithWallets ( const CTransaction & tx , const CBlock * pblock = NULL , bool fUpdate = false )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > AddToWalletIfInvolvingMe ( tx , pblock , fUpdate ) ;
}
2011-11-07 00:05:42 +01:00
// notify wallets about a new best chain
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static SetBestChain ( const CBlockLocator & loc )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > SetBestChain ( loc ) ;
}
2011-11-07 00:05:42 +01:00
// notify wallets about an updated transaction
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static UpdatedTransaction ( const uint256 & hashTx )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > UpdatedTransaction ( hashTx ) ;
}
2011-11-07 00:05:42 +01:00
// dump all wallets
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static PrintWallets ( const CBlock & block )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > PrintWallet ( block ) ;
}
2011-11-07 00:05:42 +01:00
// notify wallets about an incoming inventory (for request counts)
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static Inventory ( const uint256 & hash )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > Inventory ( hash ) ;
}
2011-11-07 00:05:42 +01:00
// ask wallets to resend their transactions
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static ResendWalletTransactions ( )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > ResendWalletTransactions ( ) ;
}
2010-08-29 18:58:15 +02:00
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//
2012-02-29 16:14:18 +01:00
void AddOrphanTx ( const CDataStream & vMsg )
2010-08-29 18:58:15 +02:00
{
CTransaction tx ;
CDataStream ( vMsg ) > > tx ;
uint256 hash = tx . GetHash ( ) ;
if ( mapOrphanTransactions . count ( hash ) )
return ;
2012-02-29 16:14:18 +01:00
2010-08-29 18:58:15 +02:00
CDataStream * pvMsg = mapOrphanTransactions [ hash ] = new CDataStream ( vMsg ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
2010-08-29 18:58:15 +02:00
mapOrphanTransactionsByPrev . insert ( make_pair ( txin . prevout . hash , pvMsg ) ) ;
}
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static EraseOrphanTx ( uint256 hash )
2010-08-29 18:58:15 +02:00
{
if ( ! mapOrphanTransactions . count ( hash ) )
return ;
const CDataStream * pvMsg = mapOrphanTransactions [ hash ] ;
CTransaction tx ;
CDataStream ( * pvMsg ) > > tx ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
2010-08-29 18:58:15 +02:00
{
for ( multimap < uint256 , CDataStream * > : : iterator mi = mapOrphanTransactionsByPrev . lower_bound ( txin . prevout . hash ) ;
mi ! = mapOrphanTransactionsByPrev . upper_bound ( txin . prevout . hash ) ; )
{
if ( ( * mi ) . second = = pvMsg )
mapOrphanTransactionsByPrev . erase ( mi + + ) ;
else
mi + + ;
}
}
delete pvMsg ;
mapOrphanTransactions . erase ( hash ) ;
}
2012-02-29 16:14:18 +01:00
int LimitOrphanTxSize ( int nMaxOrphans )
{
int nEvicted = 0 ;
while ( mapOrphanTransactions . size ( ) > nMaxOrphans )
{
// Evict a random orphan:
std : : vector < unsigned char > randbytes ( 32 ) ;
RAND_bytes ( & randbytes [ 0 ] , 32 ) ;
uint256 randomhash ( randbytes ) ;
map < uint256 , CDataStream * > : : iterator it = mapOrphanTransactions . lower_bound ( randomhash ) ;
if ( it = = mapOrphanTransactions . end ( ) )
it = mapOrphanTransactions . begin ( ) ;
EraseOrphanTx ( it - > first ) ;
+ + nEvicted ;
}
return nEvicted ;
}
2010-08-29 18:58:15 +02:00
//////////////////////////////////////////////////////////////////////////////
//
2011-03-02 22:27:24 +01:00
// CTransaction and CTxIndex
2010-08-29 18:58:15 +02:00
//
2010-11-08 23:06:07 +01:00
bool CTransaction : : ReadFromDisk ( CTxDB & txdb , COutPoint prevout , CTxIndex & txindexRet )
{
SetNull ( ) ;
if ( ! txdb . ReadTxIndex ( prevout . hash , txindexRet ) )
return false ;
if ( ! ReadFromDisk ( txindexRet . pos ) )
return false ;
if ( prevout . n > = vout . size ( ) )
{
SetNull ( ) ;
return false ;
}
return true ;
}
bool CTransaction : : ReadFromDisk ( CTxDB & txdb , COutPoint prevout )
{
CTxIndex txindex ;
return ReadFromDisk ( txdb , prevout , txindex ) ;
}
bool CTransaction : : ReadFromDisk ( COutPoint prevout )
{
CTxDB txdb ( " r " ) ;
CTxIndex txindex ;
return ReadFromDisk ( txdb , prevout , txindex ) ;
}
2011-10-03 19:05:43 +02:00
bool CTransaction : : IsStandard ( ) const
{
BOOST_FOREACH ( const CTxIn & txin , vin )
{
2011-11-08 19:20:29 +01:00
// Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG
2012-01-05 03:40:52 +01:00
// pay-to-script-hash, which is 3 ~80-byte signatures, 3
2011-10-03 19:05:43 +02:00
// ~65-byte public keys, plus a few script ops.
2011-11-08 19:20:29 +01:00
if ( txin . scriptSig . size ( ) > 500 )
2012-01-05 03:40:52 +01:00
return false ;
2011-10-03 19:05:43 +02:00
if ( ! txin . scriptSig . IsPushOnly ( ) )
2012-01-05 03:40:52 +01:00
return false ;
2011-10-03 19:05:43 +02:00
}
BOOST_FOREACH ( const CTxOut & txout , vout )
if ( ! : : IsStandard ( txout . scriptPubKey ) )
2012-01-05 03:40:52 +01:00
return false ;
2011-10-03 19:05:43 +02:00
return true ;
}
//
// Check transaction inputs, and make sure any
2012-01-05 03:40:52 +01:00
// pay-to-script-hash transactions are evaluating IsStandard scripts
2011-10-03 19:05:43 +02:00
//
// Why bother? To avoid denial-of-service attacks; an attacker
2012-01-05 03:40:52 +01:00
// can submit a standard HASH... OP_EQUAL transaction,
// which will get accepted into blocks. The redemption
// script can be anything; an attacker could use a very
2011-10-03 19:05:43 +02:00
// expensive-to-check-upon-redemption script like:
// DUP CHECKSIG DROP ... repeated 100 times... OP_1
//
2012-01-11 02:18:00 +01:00
bool CTransaction : : AreInputsStandard ( const MapPrevTx & mapInputs ) const
2011-10-03 19:05:43 +02:00
{
2012-01-11 02:18:00 +01:00
if ( IsCoinBase ( ) )
2012-01-21 02:59:04 +01:00
return true ; // Coinbases don't use vin normally
2012-01-11 02:18:00 +01:00
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2011-10-03 19:05:43 +02:00
{
2012-01-11 02:18:00 +01:00
const CTxOut & prev = GetOutputFor ( vin [ i ] , mapInputs ) ;
2011-10-03 19:05:43 +02:00
vector < vector < unsigned char > > vSolutions ;
2011-11-08 19:20:29 +01:00
txnouttype whichType ;
// get the scriptPubKey corresponding to this input:
2012-01-11 02:18:00 +01:00
const CScript & prevScript = prev . scriptPubKey ;
2011-11-08 19:20:29 +01:00
if ( ! Solver ( prevScript , whichType , vSolutions ) )
2012-01-05 03:40:52 +01:00
return false ;
2012-01-19 19:30:54 +01:00
int nArgsExpected = ScriptSigArgsExpected ( whichType , vSolutions ) ;
// Transactions with extra stuff in their scriptSigs are
// non-standard. Note that this EvalScript() call will
// be quick, because if there are any operations
// beside "push data" in the scriptSig the
// IsStandard() call returns false
vector < vector < unsigned char > > stack ;
if ( ! EvalScript ( stack , vin [ i ] . scriptSig , * this , i , 0 ) )
return false ;
2011-10-03 19:05:43 +02:00
if ( whichType = = TX_SCRIPTHASH )
{
2012-01-05 03:40:52 +01:00
if ( stack . empty ( ) )
2011-10-03 19:05:43 +02:00
return false ;
2011-11-08 19:20:29 +01:00
CScript subscript ( stack . back ( ) . begin ( ) , stack . back ( ) . end ( ) ) ;
2012-01-19 19:30:54 +01:00
vector < vector < unsigned char > > vSolutions2 ;
txnouttype whichType2 ;
if ( ! Solver ( subscript , whichType2 , vSolutions2 ) )
2012-01-05 03:40:52 +01:00
return false ;
2012-01-19 19:30:54 +01:00
if ( whichType2 = = TX_SCRIPTHASH )
return false ;
nArgsExpected + = ScriptSigArgsExpected ( whichType2 , vSolutions2 ) ;
2011-10-03 19:05:43 +02:00
}
2012-01-19 19:30:54 +01:00
if ( stack . size ( ) ! = nArgsExpected )
return false ;
2011-10-03 19:05:43 +02:00
}
return true ;
}
2012-01-05 03:40:52 +01:00
int
CTransaction : : GetLegacySigOpCount ( ) const
{
int nSigOps = 0 ;
BOOST_FOREACH ( const CTxIn & txin , vin )
{
nSigOps + = txin . scriptSig . GetSigOpCount ( false ) ;
}
BOOST_FOREACH ( const CTxOut & txout , vout )
{
nSigOps + = txout . scriptPubKey . GetSigOpCount ( false ) ;
}
return nSigOps ;
}
2010-08-29 18:58:15 +02:00
int CMerkleTx : : SetMerkleBranch ( const CBlock * pblock )
{
if ( fClient )
{
if ( hashBlock = = 0 )
return 0 ;
}
else
{
CBlock blockTmp ;
if ( pblock = = NULL )
{
// Load the block this tx is in
CTxIndex txindex ;
if ( ! CTxDB ( " r " ) . ReadTxIndex ( GetHash ( ) , txindex ) )
return 0 ;
if ( ! blockTmp . ReadFromDisk ( txindex . pos . nFile , txindex . pos . nBlockPos ) )
return 0 ;
pblock = & blockTmp ;
}
// Update the tx's hashBlock
hashBlock = pblock - > GetHash ( ) ;
// Locate the transaction
for ( nIndex = 0 ; nIndex < pblock - > vtx . size ( ) ; nIndex + + )
if ( pblock - > vtx [ nIndex ] = = * ( CTransaction * ) this )
break ;
if ( nIndex = = pblock - > vtx . size ( ) )
{
vMerkleBranch . clear ( ) ;
nIndex = - 1 ;
printf ( " ERROR: SetMerkleBranch() : couldn't find tx in block \n " ) ;
return 0 ;
}
// Fill in merkle branch
vMerkleBranch = pblock - > GetMerkleBranch ( nIndex ) ;
}
// Is the tx in a block that's in the main chain
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( hashBlock ) ;
if ( mi = = mapBlockIndex . end ( ) )
return 0 ;
CBlockIndex * pindex = ( * mi ) . second ;
if ( ! pindex | | ! pindex - > IsInMainChain ( ) )
return 0 ;
return pindexBest - > nHeight - pindex - > nHeight + 1 ;
}
2010-09-30 18:23:07 +02:00
bool CTransaction : : CheckTransaction ( ) const
{
// Basic checks that don't depend on any context
2011-08-16 02:33:00 +02:00
if ( vin . empty ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 10 , error ( " CTransaction::CheckTransaction() : vin empty " )) ;
2011-08-16 02:33:00 +02:00
if ( vout . empty ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 10 , error ( " CTransaction::CheckTransaction() : vout empty " )) ;
2010-09-30 18:23:07 +02:00
// Size limits
2012-04-16 14:56:45 +02:00
if ( : : GetSerializeSize ( * this , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CTransaction::CheckTransaction() : size limits failed " )) ;
2010-09-30 18:23:07 +02:00
// Check for negative or overflow output values
2011-12-21 22:33:19 +01:00
int64 nValueOut = 0 ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTxOut & txout , vout )
2010-09-30 18:23:07 +02:00
{
if ( txout . nValue < 0 )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CTransaction::CheckTransaction() : txout . nValue negative " )) ;
2010-09-30 18:23:07 +02:00
if ( txout . nValue > MAX_MONEY )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CTransaction::CheckTransaction() : txout . nValue too high " )) ;
2010-09-30 18:23:07 +02:00
nValueOut + = txout . nValue ;
if ( ! MoneyRange ( nValueOut ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CTransaction::CheckTransaction() : txout total out of range " )) ;
2010-09-30 18:23:07 +02:00
}
2011-07-30 23:01:45 +02:00
// Check for duplicate inputs
set < COutPoint > vInOutPoints ;
BOOST_FOREACH ( const CTxIn & txin , vin )
{
if ( vInOutPoints . count ( txin . prevout ) )
return false ;
vInOutPoints . insert ( txin . prevout ) ;
}
2010-09-30 18:23:07 +02:00
if ( IsCoinBase ( ) )
{
if ( vin [ 0 ] . scriptSig . size ( ) < 2 | | vin [ 0 ] . scriptSig . size ( ) > 100 )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CTransaction::CheckTransaction() : coinbase script size " )) ;
2010-09-30 18:23:07 +02:00
}
else
{
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTxIn & txin , vin )
2010-09-30 18:23:07 +02:00
if ( txin . prevout . IsNull ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 10 , error ( " CTransaction::CheckTransaction() : prevout is null " )) ;
2010-09-30 18:23:07 +02:00
}
return true ;
}
2010-09-07 03:12:53 +02:00
bool CTransaction : : AcceptToMemoryPool ( CTxDB & txdb , bool fCheckInputs , bool * pfMissingInputs )
2010-08-29 18:58:15 +02:00
{
if ( pfMissingInputs )
* pfMissingInputs = false ;
2010-09-30 18:23:07 +02:00
if ( ! CheckTransaction ( ) )
return error ( " AcceptToMemoryPool() : CheckTransaction failed " ) ;
2010-08-29 18:58:15 +02:00
// Coinbase is only valid in a block, not as a loose transaction
if ( IsCoinBase ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " AcceptToMemoryPool() : coinbase as individual tx " )) ;
2010-08-29 18:58:15 +02:00
// To help v0.1.5 clients who would see it as a negative number
2011-12-21 22:33:19 +01:00
if ( ( int64 ) nLockTime > std : : numeric_limits < int > : : max ( ) )
2010-09-07 03:12:53 +02:00
return error ( " AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet " ) ;
2011-04-20 17:20:33 +02:00
// Rather not work on nonstandard transactions (unless -testnet)
if ( ! fTestNet & & ! IsStandard ( ) )
2010-12-12 19:20:36 +01:00
return error ( " AcceptToMemoryPool() : nonstandard transaction type " ) ;
2010-08-29 18:58:15 +02:00
// Do we already have it?
uint256 hash = GetHash ( ) ;
2012-04-06 18:39:12 +02:00
{
LOCK ( cs_mapTransactions ) ;
2010-08-29 18:58:15 +02:00
if ( mapTransactions . count ( hash ) )
return false ;
2012-04-06 18:39:12 +02:00
}
2010-08-29 18:58:15 +02:00
if ( fCheckInputs )
if ( txdb . ContainsTx ( hash ) )
return false ;
// Check for conflicts with in-memory transactions
CTransaction * ptxOld = NULL ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
COutPoint outpoint = vin [ i ] . prevout ;
if ( mapNextTx . count ( outpoint ) )
{
// Disable replacement feature for now
return false ;
// Allow replacing with a newer version of the same transaction
if ( i ! = 0 )
return false ;
ptxOld = mapNextTx [ outpoint ] . ptx ;
2010-11-19 21:22:46 +01:00
if ( ptxOld - > IsFinal ( ) )
return false ;
2010-08-29 18:58:15 +02:00
if ( ! IsNewerThan ( * ptxOld ) )
return false ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
COutPoint outpoint = vin [ i ] . prevout ;
if ( ! mapNextTx . count ( outpoint ) | | mapNextTx [ outpoint ] . ptx ! = ptxOld )
return false ;
}
break ;
}
}
2010-12-12 19:20:36 +01:00
if ( fCheckInputs )
2010-08-29 18:58:15 +02:00
{
2012-01-11 02:18:00 +01:00
MapPrevTx mapInputs ;
2010-12-12 19:20:36 +01:00
map < uint256 , CTxIndex > mapUnused ;
2012-01-18 19:36:44 +01:00
bool fInvalid = false ;
if ( ! FetchInputs ( txdb , mapUnused , false , false , mapInputs , fInvalid ) )
2011-10-03 19:05:43 +02:00
{
2012-01-18 19:36:44 +01:00
if ( fInvalid )
return error ( " AcceptToMemoryPool() : FetchInputs found invalid tx % s " , hash.ToString().substr(0,10).c_str()) ;
2011-10-03 19:05:43 +02:00
if ( pfMissingInputs )
* pfMissingInputs = true ;
return error ( " AcceptToMemoryPool() : FetchInputs failed % s " , hash.ToString().substr(0,10).c_str()) ;
}
2012-01-05 03:40:52 +01:00
// Check for non-standard pay-to-script-hash in inputs
2012-01-21 02:59:04 +01:00
if ( ! AreInputsStandard ( mapInputs ) & & ! fTestNet )
2011-10-03 19:05:43 +02:00
return error ( " AcceptToMemoryPool() : nonstandard transaction input " ) ;
2012-01-20 23:07:40 +01:00
// Note: if you modify this code to accept non-standard transactions, then
// you should add code here to check that the transaction does a
// reasonable number of ECDSA signature verifications.
2012-01-11 02:18:00 +01:00
int64 nFees = GetValueIn ( mapInputs ) - GetValueOut ( ) ;
2012-04-16 14:56:45 +02:00
unsigned int nSize = : : GetSerializeSize ( * this , SER_NETWORK , PROTOCOL_VERSION ) ;
2012-01-11 02:18:00 +01:00
// Don't accept it if it can't get into a block
if ( nFees < GetMinFee ( 1000 , true , GMF_RELAY ) )
return error ( " AcceptToMemoryPool() : not enough fees " ) ;
2012-01-05 03:40:52 +01:00
2011-03-11 17:50:16 +01:00
// Continuously rate-limit free transactions
2011-03-13 19:38:07 +01:00
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make other's transactions take longer to confirm.
2011-05-26 00:38:20 +02:00
if ( nFees < MIN_RELAY_TX_FEE )
2010-12-12 19:20:36 +01:00
{
2011-03-13 19:38:07 +01:00
static CCriticalSection cs ;
2011-03-11 17:50:16 +01:00
static double dFreeCount ;
2011-12-21 22:33:19 +01:00
static int64 nLastTime ;
int64 nNow = GetTime ( ) ;
2011-03-13 19:38:07 +01:00
2010-12-12 19:20:36 +01:00
{
2012-04-06 18:39:12 +02:00
LOCK ( cs ) ;
2011-03-13 19:38:07 +01:00
// Use an exponentially decaying ~10-minute window:
dFreeCount * = pow ( 1.0 - 1.0 / 600.0 , ( double ) ( nNow - nLastTime ) ) ;
nLastTime = nNow ;
// -limitfreerelay unit is thousand-bytes-per-minute
// At default rate it would take over a month to fill 1GB
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
if ( dFreeCount > GetArg ( " -limitfreerelay " , 15 ) * 10 * 1000 & & ! IsFromMe ( * this ) )
2011-03-13 19:38:07 +01:00
return error ( " AcceptToMemoryPool() : free transaction rejected by rate limiter " ) ;
if ( fDebug )
printf ( " Rate limit dFreeCount: %g => %g \n " , dFreeCount , dFreeCount + nSize ) ;
dFreeCount + = nSize ;
2010-12-12 19:20:36 +01:00
}
}
2012-01-11 02:18:00 +01:00
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
if ( ! ConnectInputs ( mapInputs , mapUnused , CDiskTxPos ( 1 , 1 , 1 ) , pindexBest , false , false ) )
{
return error ( " AcceptToMemoryPool() : ConnectInputs failed % s " , hash.ToString().substr(0,10).c_str()) ;
}
2010-08-29 18:58:15 +02:00
}
// Store transaction in memory
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapTransactions ) ;
2010-08-29 18:58:15 +02:00
if ( ptxOld )
{
2010-09-07 03:12:53 +02:00
printf ( " AcceptToMemoryPool() : replacing tx %s with new version \n " , ptxOld - > GetHash ( ) . ToString ( ) . c_str ( ) ) ;
2010-08-29 18:58:15 +02:00
ptxOld - > RemoveFromMemoryPool ( ) ;
}
2010-09-07 03:12:53 +02:00
AddToMemoryPoolUnchecked ( ) ;
2010-08-29 18:58:15 +02:00
}
///// are we sure this is ok when loading transactions or restoring block txes
// If updated, erase old tx from wallet
if ( ptxOld )
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
EraseFromWallets ( ptxOld - > GetHash ( ) ) ;
2010-08-29 18:58:15 +02:00
2010-10-06 04:19:47 +02:00
printf ( " AcceptToMemoryPool(): accepted %s \n " , hash . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) ) ;
2010-08-29 18:58:15 +02:00
return true ;
}
2011-05-27 06:02:51 +02:00
uint64 nPooledTx = 0 ;
2010-09-07 03:12:53 +02:00
bool CTransaction : : AddToMemoryPoolUnchecked ( )
2010-08-29 18:58:15 +02:00
{
2011-05-27 06:02:51 +02:00
printf ( " AcceptToMemoryPoolUnchecked(): size %lu \n " , mapTransactions . size ( ) ) ;
2010-08-29 18:58:15 +02:00
// Add to memory pool without checking anything. Don't call this directly,
2010-09-07 03:12:53 +02:00
// call AcceptToMemoryPool to properly check the transaction first.
2010-08-29 18:58:15 +02:00
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapTransactions ) ;
2010-08-29 18:58:15 +02:00
uint256 hash = GetHash ( ) ;
mapTransactions [ hash ] = * this ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
mapNextTx [ vin [ i ] . prevout ] = CInPoint ( & mapTransactions [ hash ] , i ) ;
nTransactionsUpdated + + ;
2011-05-27 06:02:51 +02:00
+ + nPooledTx ;
2010-08-29 18:58:15 +02:00
}
return true ;
}
bool CTransaction : : RemoveFromMemoryPool ( )
{
// Remove transaction from memory pool
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapTransactions ) ;
2012-02-09 14:21:41 +01:00
uint256 hash = GetHash ( ) ;
if ( mapTransactions . count ( hash ) )
{
BOOST_FOREACH ( const CTxIn & txin , vin )
mapNextTx . erase ( txin . prevout ) ;
mapTransactions . erase ( hash ) ;
nTransactionsUpdated + + ;
- - nPooledTx ;
}
2010-08-29 18:58:15 +02:00
}
return true ;
}
2011-07-11 21:49:45 +02:00
int CMerkleTx : : GetDepthInMainChain ( CBlockIndex * & pindexRet ) const
2010-08-29 18:58:15 +02:00
{
if ( hashBlock = = 0 | | nIndex = = - 1 )
return 0 ;
// Find the block it claims to be in
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( hashBlock ) ;
if ( mi = = mapBlockIndex . end ( ) )
return 0 ;
CBlockIndex * pindex = ( * mi ) . second ;
if ( ! pindex | | ! pindex - > IsInMainChain ( ) )
return 0 ;
// Make sure the merkle branch connects to this block
if ( ! fMerkleVerified )
{
if ( CBlock : : CheckMerkleBranch ( GetHash ( ) , vMerkleBranch , nIndex ) ! = pindex - > hashMerkleRoot )
return 0 ;
fMerkleVerified = true ;
}
2011-07-11 21:49:45 +02:00
pindexRet = pindex ;
2010-08-29 18:58:15 +02:00
return pindexBest - > nHeight - pindex - > nHeight + 1 ;
}
int CMerkleTx : : GetBlocksToMaturity ( ) const
{
if ( ! IsCoinBase ( ) )
return 0 ;
return max ( 0 , ( COINBASE_MATURITY + 20 ) - GetDepthInMainChain ( ) ) ;
}
2010-09-07 03:12:53 +02:00
bool CMerkleTx : : AcceptToMemoryPool ( CTxDB & txdb , bool fCheckInputs )
2010-08-29 18:58:15 +02:00
{
if ( fClient )
{
if ( ! IsInMainChain ( ) & & ! ClientConnectInputs ( ) )
return false ;
2010-09-07 03:12:53 +02:00
return CTransaction : : AcceptToMemoryPool ( txdb , false ) ;
2010-08-29 18:58:15 +02:00
}
else
{
2010-09-07 03:12:53 +02:00
return CTransaction : : AcceptToMemoryPool ( txdb , fCheckInputs ) ;
2010-08-29 18:58:15 +02:00
}
}
2011-06-01 18:27:05 +02:00
bool CMerkleTx : : AcceptToMemoryPool ( )
{
CTxDB txdb ( " r " ) ;
return AcceptToMemoryPool ( txdb ) ;
}
2010-08-29 18:58:15 +02:00
bool CWalletTx : : AcceptWalletTransaction ( CTxDB & txdb , bool fCheckInputs )
{
2012-04-06 18:39:12 +02:00
2010-08-29 18:58:15 +02:00
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapTransactions ) ;
2010-09-07 03:12:53 +02:00
// Add previous supporting transactions first
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CMerkleTx & tx , vtxPrev )
2010-08-29 18:58:15 +02:00
{
if ( ! tx . IsCoinBase ( ) )
{
uint256 hash = tx . GetHash ( ) ;
if ( ! mapTransactions . count ( hash ) & & ! txdb . ContainsTx ( hash ) )
2010-09-07 03:12:53 +02:00
tx . AcceptToMemoryPool ( txdb , fCheckInputs ) ;
2010-08-29 18:58:15 +02:00
}
}
2010-09-07 03:12:53 +02:00
return AcceptToMemoryPool ( txdb , fCheckInputs ) ;
2010-08-29 18:58:15 +02:00
}
2010-09-07 03:12:53 +02:00
return false ;
2010-08-29 18:58:15 +02:00
}
2011-06-01 18:27:05 +02:00
bool CWalletTx : : AcceptWalletTransaction ( )
2010-08-29 18:58:15 +02:00
{
CTxDB txdb ( " r " ) ;
2011-06-01 18:27:05 +02:00
return AcceptWalletTransaction ( txdb ) ;
2010-08-29 18:58:15 +02:00
}
2011-03-02 22:27:24 +01:00
int CTxIndex : : GetDepthInMainChain ( ) const
{
// Read block header
CBlock block ;
if ( ! block . ReadFromDisk ( pos . nFile , pos . nBlockPos , false ) )
return 0 ;
// Find the block in the index
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( block . GetHash ( ) ) ;
if ( mi = = mapBlockIndex . end ( ) )
return 0 ;
CBlockIndex * pindex = ( * mi ) . second ;
if ( ! pindex | | ! pindex - > IsInMainChain ( ) )
return 0 ;
return 1 + nBestHeight - pindex - > nHeight ;
}
2010-08-29 18:58:15 +02:00
//////////////////////////////////////////////////////////////////////////////
//
// CBlock and CBlockIndex
//
bool CBlock : : ReadFromDisk ( const CBlockIndex * pindex , bool fReadTransactions )
{
2010-12-05 10:29:30 +01:00
if ( ! fReadTransactions )
{
* this = pindex - > GetBlockHeader ( ) ;
return true ;
}
2010-08-29 18:58:15 +02:00
if ( ! ReadFromDisk ( pindex - > nFile , pindex - > nBlockPos , fReadTransactions ) )
return false ;
if ( GetHash ( ) ! = pindex - > GetBlockHash ( ) )
return error ( " CBlock::ReadFromDisk() : GetHash ( ) doesn ' t match index " ) ;
return true ;
}
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
uint256 static GetOrphanRoot ( const CBlock * pblock )
2010-08-29 18:58:15 +02:00
{
// Work back to the first block in the orphan chain
while ( mapOrphanBlocks . count ( pblock - > hashPrevBlock ) )
pblock = mapOrphanBlocks [ pblock - > hashPrevBlock ] ;
return pblock - > GetHash ( ) ;
}
2011-12-21 22:33:19 +01:00
int64 static GetBlockValue ( int nHeight , int64 nFees )
2010-08-29 18:58:15 +02:00
{
2011-12-21 22:33:19 +01:00
int64 nSubsidy = 50 * COIN ;
2010-08-29 18:58:15 +02:00
// Subsidy is cut in half every 4 years
nSubsidy > > = ( nHeight / 210000 ) ;
return nSubsidy + nFees ;
}
2011-12-21 22:33:19 +01:00
static const int64 nTargetTimespan = 14 * 24 * 60 * 60 ; // two weeks
static const int64 nTargetSpacing = 10 * 60 ;
static const int64 nInterval = nTargetTimespan / nTargetSpacing ;
2011-09-08 18:51:43 +02:00
//
// minimum amount of work that could possibly be required nTime after
// minimum work required was nBase
//
2011-12-21 22:33:19 +01:00
unsigned int ComputeMinWork ( unsigned int nBase , int64 nTime )
2011-09-08 18:51:43 +02:00
{
2011-12-05 21:50:22 +01:00
// Testnet has min-difficulty blocks
// after nTargetSpacing*2 time between blocks:
if ( fTestNet & & nTime > nTargetSpacing * 2 )
return bnProofOfWorkLimit . GetCompact ( ) ;
2011-09-08 18:51:43 +02:00
CBigNum bnResult ;
bnResult . SetCompact ( nBase ) ;
while ( nTime > 0 & & bnResult < bnProofOfWorkLimit )
{
// Maximum 400% adjustment...
bnResult * = 4 ;
// ... in best-case exactly 4-times-normal target time
nTime - = nTargetTimespan * 4 ;
}
if ( bnResult > bnProofOfWorkLimit )
bnResult = bnProofOfWorkLimit ;
return bnResult . GetCompact ( ) ;
}
2011-12-05 21:50:22 +01:00
unsigned int static GetNextWorkRequired ( const CBlockIndex * pindexLast , const CBlock * pblock )
2010-08-29 18:58:15 +02:00
{
2011-12-05 21:50:22 +01:00
unsigned int nProofOfWorkLimit = bnProofOfWorkLimit . GetCompact ( ) ;
2010-08-29 18:58:15 +02:00
// Genesis block
if ( pindexLast = = NULL )
2011-12-05 21:50:22 +01:00
return nProofOfWorkLimit ;
2010-08-29 18:58:15 +02:00
// Only change once per interval
if ( ( pindexLast - > nHeight + 1 ) % nInterval ! = 0 )
2011-12-05 21:50:22 +01:00
{
// Special rules for testnet after 15 Feb 2012:
if ( fTestNet & & pblock - > nTime > 1329264000 )
{
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
if ( pblock - > nTime - pindexLast - > nTime > nTargetSpacing * 2 )
return nProofOfWorkLimit ;
else
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex * pindex = pindexLast ;
while ( pindex - > pprev & & pindex - > nHeight % nInterval ! = 0 & & pindex - > nBits = = nProofOfWorkLimit )
pindex = pindex - > pprev ;
return pindex - > nBits ;
}
}
2010-08-29 18:58:15 +02:00
return pindexLast - > nBits ;
2011-12-05 21:50:22 +01:00
}
2010-08-29 18:58:15 +02:00
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex * pindexFirst = pindexLast ;
for ( int i = 0 ; pindexFirst & & i < nInterval - 1 ; i + + )
pindexFirst = pindexFirst - > pprev ;
assert ( pindexFirst ) ;
// Limit adjustment step
2011-12-21 22:33:19 +01:00
int64 nActualTimespan = pindexLast - > GetBlockTime ( ) - pindexFirst - > GetBlockTime ( ) ;
2010-08-29 18:58:15 +02:00
printf ( " nActualTimespan = % " PRI64d " before bounds \n " , nActualTimespan ) ;
if ( nActualTimespan < nTargetTimespan / 4 )
nActualTimespan = nTargetTimespan / 4 ;
if ( nActualTimespan > nTargetTimespan * 4 )
nActualTimespan = nTargetTimespan * 4 ;
// Retarget
CBigNum bnNew ;
bnNew . SetCompact ( pindexLast - > nBits ) ;
bnNew * = nActualTimespan ;
bnNew / = nTargetTimespan ;
if ( bnNew > bnProofOfWorkLimit )
bnNew = bnProofOfWorkLimit ;
/// debug print
printf ( " GetNextWorkRequired RETARGET \n " ) ;
printf ( " nTargetTimespan = % " PRI64d " nActualTimespan = % " PRI64d " \n " , nTargetTimespan , nActualTimespan ) ;
printf ( " Before: %08x %s \n " , pindexLast - > nBits , CBigNum ( ) . SetCompact ( pindexLast - > nBits ) . getuint256 ( ) . ToString ( ) . c_str ( ) ) ;
printf ( " After: %08x %s \n " , bnNew . GetCompact ( ) , bnNew . getuint256 ( ) . ToString ( ) . c_str ( ) ) ;
return bnNew . GetCompact ( ) ;
}
bool CheckProofOfWork ( uint256 hash , unsigned int nBits )
{
CBigNum bnTarget ;
bnTarget . SetCompact ( nBits ) ;
// Check range
if ( bnTarget < = 0 | | bnTarget > bnProofOfWorkLimit )
return error ( " CheckProofOfWork() : nBits below minimum work " ) ;
// Check proof of work matches claimed amount
if ( hash > bnTarget . getuint256 ( ) )
return error ( " CheckProofOfWork() : hash doesn ' t match nBits " ) ;
return true ;
}
2011-09-02 18:02:22 +02:00
// Return maximum amount of blocks that other nodes claim to have
2011-09-11 10:49:30 +02:00
int GetNumBlocksOfPeers ( )
2011-09-02 18:02:22 +02:00
{
2011-09-08 22:50:58 +02:00
return std : : max ( cPeerBlockCounts . median ( ) , Checkpoints : : GetTotalBlocksEstimate ( ) ) ;
2011-09-02 18:02:22 +02:00
}
2010-08-29 18:58:15 +02:00
bool IsInitialBlockDownload ( )
{
2011-12-23 23:13:10 +01:00
if ( pindexBest = = NULL | | nBestHeight < Checkpoints : : GetTotalBlocksEstimate ( ) )
2010-08-29 18:58:15 +02:00
return true ;
2011-12-21 22:33:19 +01:00
static int64 nLastUpdate ;
2010-08-29 18:58:15 +02:00
static CBlockIndex * pindexLastBest ;
if ( pindexBest ! = pindexLastBest )
{
pindexLastBest = pindexBest ;
nLastUpdate = GetTime ( ) ;
}
return ( GetTime ( ) - nLastUpdate < 10 & &
pindexBest - > GetBlockTime ( ) < GetTime ( ) - 24 * 60 * 60 ) ;
}
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static InvalidChainFound ( CBlockIndex * pindexNew )
2010-08-29 18:58:15 +02:00
{
if ( pindexNew - > bnChainWork > bnBestInvalidWork )
{
bnBestInvalidWork = pindexNew - > bnChainWork ;
CTxDB ( ) . WriteBestInvalidWork ( bnBestInvalidWork ) ;
MainFrameRepaint ( ) ;
}
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 ( " InvalidChainFound: current best=%s height=%d work=%s \n " , hashBestChain . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , nBestHeight , bnBestChainWork . ToString ( ) . c_str ( ) ) ;
if ( pindexBest & & bnBestInvalidWork > bnBestChainWork + pindexBest - > GetBlockWork ( ) * 6 )
printf ( " InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. \n " ) ;
}
2012-02-16 16:22:31 +01:00
void CBlock : : UpdateTime ( const CBlockIndex * pindexPrev )
{
nTime = max ( pindexPrev - > GetMedianTimePast ( ) + 1 , GetAdjustedTime ( ) ) ;
// Updating time can change work required on testnet:
if ( fTestNet )
nBits = GetNextWorkRequired ( pindexPrev , this ) ;
}
2010-08-29 18:58:15 +02:00
bool CTransaction : : DisconnectInputs ( CTxDB & txdb )
{
// Relinquish previous transactions' spent pointers
if ( ! IsCoinBase ( ) )
{
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTxIn & txin , vin )
2010-08-29 18:58:15 +02:00
{
COutPoint prevout = txin . prevout ;
// Get prev txindex from disk
CTxIndex txindex ;
if ( ! txdb . ReadTxIndex ( prevout . hash , txindex ) )
return error ( " DisconnectInputs() : ReadTxIndex failed " ) ;
if ( prevout . n > = txindex . vSpent . size ( ) )
return error ( " DisconnectInputs() : prevout . n out of range " ) ;
// Mark outpoint as not spent
txindex . vSpent [ prevout . n ] . SetNull ( ) ;
// Write back
2010-10-06 04:19:47 +02:00
if ( ! txdb . UpdateTxIndex ( prevout . hash , txindex ) )
return error ( " DisconnectInputs() : UpdateTxIndex failed " ) ;
2010-08-29 18:58:15 +02:00
}
}
// Remove transaction from index
2012-02-17 17:58:02 +01:00
// This can fail if a duplicate of this transaction was in a chain that got
// reorganized away. This is only possible if this transaction was completely
// spent, so erasing it would be a no-op anway.
txdb . EraseTxIndex ( * this ) ;
2010-08-29 18:58:15 +02:00
return true ;
}
2011-10-03 19:05:43 +02:00
bool CTransaction : : FetchInputs ( CTxDB & txdb , const map < uint256 , CTxIndex > & mapTestPool ,
2012-01-18 19:36:44 +01:00
bool fBlock , bool fMiner , MapPrevTx & inputsRet , bool & fInvalid )
2011-10-03 19:05:43 +02:00
{
2012-01-18 19:36:44 +01:00
// FetchInputs can return false either because we just haven't seen some inputs
// (in which case the transaction should be stored as an orphan)
// or because the transaction is malformed (in which case the transaction should
// be dropped). If tx is definitely invalid, fInvalid will be set to true.
fInvalid = false ;
2011-10-03 19:05:43 +02:00
if ( IsCoinBase ( ) )
return true ; // Coinbase transactions have no inputs to fetch.
2011-12-17 00:03:48 +01:00
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2011-10-03 19:05:43 +02:00
{
COutPoint prevout = vin [ i ] . prevout ;
if ( inputsRet . count ( prevout . hash ) )
continue ; // Got it already
// Read txindex
CTxIndex & txindex = inputsRet [ prevout . hash ] . first ;
bool fFound = true ;
if ( ( fBlock | | fMiner ) & & mapTestPool . count ( prevout . hash ) )
{
// Get txindex from current proposed changes
txindex = mapTestPool . find ( prevout . hash ) - > second ;
}
else
{
// Read txindex from txdb
fFound = txdb . ReadTxIndex ( prevout . hash , txindex ) ;
}
if ( ! fFound & & ( fBlock | | fMiner ) )
return fMiner ? false : error ( " FetchInputs() : %s prev tx %s index entry not found " , GetHash ( ) . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) , prevout . hash . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) ) ;
// Read txPrev
CTransaction & txPrev = inputsRet [ prevout . hash ] . second ;
if ( ! fFound | | txindex . pos = = CDiskTxPos ( 1 , 1 , 1 ) )
{
// Get prev tx from single transactions in memory
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapTransactions ) ;
2011-10-03 19:05:43 +02:00
if ( ! mapTransactions . count ( prevout . hash ) )
return error ( " FetchInputs() : % s mapTransactions prev not found % s " , GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()) ;
txPrev = mapTransactions [ prevout . hash ] ;
}
if ( ! fFound )
txindex . vSpent . resize ( txPrev . vout . size ( ) ) ;
}
else
{
// Get prev tx from disk
if ( ! txPrev . ReadFromDisk ( txindex . pos ) )
return error ( " FetchInputs() : % s ReadFromDisk prev tx % s failed " , GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str()) ;
}
2011-12-25 16:32:05 +01:00
}
// Make sure all prevout.n's are valid:
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2011-12-25 16:32:05 +01:00
{
const COutPoint prevout = vin [ i ] . prevout ;
2012-01-11 02:18:00 +01:00
assert ( inputsRet . count ( prevout . hash ) ! = 0 ) ;
2011-12-25 16:32:05 +01:00
const CTxIndex & txindex = inputsRet [ prevout . hash ] . first ;
const CTransaction & txPrev = inputsRet [ prevout . hash ] . second ;
2011-12-25 14:45:09 +01:00
if ( prevout . n > = txPrev . vout . size ( ) | | prevout . n > = txindex . vSpent . size ( ) )
2012-01-18 19:36:44 +01:00
{
// Revisit this if/when transaction replacement is implemented and allows
// adding inputs:
fInvalid = true ;
2011-12-25 14:45:09 +01:00
return DoS ( 100 , error ( " FetchInputs() : % s prevout . n out of range % d % d % d prev tx % s \ n % s " , GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())) ;
2012-01-18 19:36:44 +01:00
}
2011-10-03 19:05:43 +02:00
}
2011-12-25 16:32:05 +01:00
2011-10-03 19:05:43 +02:00
return true ;
}
2012-01-11 02:18:00 +01:00
const CTxOut & CTransaction : : GetOutputFor ( const CTxIn & input , const MapPrevTx & inputs ) const
{
MapPrevTx : : const_iterator mi = inputs . find ( input . prevout . hash ) ;
if ( mi = = inputs . end ( ) )
throw std : : runtime_error ( " CTransaction::GetOutputFor() : prevout.hash not found " ) ;
const CTransaction & txPrev = ( mi - > second ) . second ;
if ( input . prevout . n > = txPrev . vout . size ( ) )
throw std : : runtime_error ( " CTransaction::GetOutputFor() : prevout.n out of range " ) ;
return txPrev . vout [ input . prevout . n ] ;
}
int64 CTransaction : : GetValueIn ( const MapPrevTx & inputs ) const
{
if ( IsCoinBase ( ) )
return 0 ;
int64 nResult = 0 ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2012-01-11 02:18:00 +01:00
{
nResult + = GetOutputFor ( vin [ i ] , inputs ) . nValue ;
}
return nResult ;
}
2012-01-20 23:07:40 +01:00
int CTransaction : : GetP2SHSigOpCount ( const MapPrevTx & inputs ) const
2012-01-11 02:18:00 +01:00
{
if ( IsCoinBase ( ) )
return 0 ;
int nSigOps = 0 ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2012-01-11 02:18:00 +01:00
{
2012-01-20 23:07:40 +01:00
const CTxOut & prevout = GetOutputFor ( vin [ i ] , inputs ) ;
if ( prevout . scriptPubKey . IsPayToScriptHash ( ) )
nSigOps + = prevout . scriptPubKey . GetSigOpCount ( vin [ i ] . scriptSig ) ;
2012-01-11 02:18:00 +01:00
}
return nSigOps ;
}
bool CTransaction : : ConnectInputs ( MapPrevTx inputs ,
2012-01-05 03:40:52 +01:00
map < uint256 , CTxIndex > & mapTestPool , const CDiskTxPos & posThisTx ,
2012-01-20 23:07:40 +01:00
const CBlockIndex * pindexBlock , bool fBlock , bool fMiner , bool fStrictPayToScriptHash )
2010-08-29 18:58:15 +02:00
{
// Take over previous transactions' spent pointers
2011-09-02 22:59:47 +02:00
// fBlock is true when this is called from AcceptBlock when a new best-block is added to the blockchain
// fMiner is true when called from the internal bitcoin miner
// ... both are false when called from CTransaction::AcceptToMemoryPool
2010-08-29 18:58:15 +02:00
if ( ! IsCoinBase ( ) )
{
2011-12-21 22:33:19 +01:00
int64 nValueIn = 0 ;
2012-01-11 02:18:00 +01:00
int64 nFees = 0 ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
COutPoint prevout = vin [ i ] . prevout ;
2011-10-03 19:05:43 +02:00
assert ( inputs . count ( prevout . hash ) > 0 ) ;
CTxIndex & txindex = inputs [ prevout . hash ] . first ;
CTransaction & txPrev = inputs [ prevout . hash ] . second ;
2010-08-29 18:58:15 +02:00
if ( prevout . n > = txPrev . vout . size ( ) | | prevout . n > = txindex . vSpent . size ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " ConnectInputs() : % s prevout . n out of range % d % d % d prev tx % s \ n % s " , GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str())) ;
2010-08-29 18:58:15 +02:00
// If prev is coinbase, check that it's matured
if ( txPrev . IsCoinBase ( ) )
2012-01-05 03:40:52 +01:00
for ( const CBlockIndex * pindex = pindexBlock ; pindex & & pindexBlock - > nHeight - pindex - > nHeight < COINBASE_MATURITY ; pindex = pindex - > pprev )
2010-08-29 18:58:15 +02:00
if ( pindex - > nBlockPos = = txindex . pos . nBlockPos & & pindex - > nFile = = txindex . pos . nFile )
return error ( " ConnectInputs() : tried to spend coinbase at depth % d " , pindexBlock->nHeight - pindex->nHeight) ;
2012-01-11 02:18:00 +01:00
// Check for conflicts (double-spend)
// This doesn't trigger the DoS code on purpose; if it did, it would make it easier
// for an attacker to attempt to split the network.
if ( ! txindex . vSpent [ prevout . n ] . IsNull ( ) )
return fMiner ? false : error ( " ConnectInputs() : %s prev tx already used at %s " , GetHash ( ) . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) , txindex . vSpent [ prevout . n ] . ToString ( ) . c_str ( ) ) ;
// Check for negative or overflow input values
nValueIn + = txPrev . vout [ prevout . n ] . nValue ;
if ( ! MoneyRange ( txPrev . vout [ prevout . n ] . nValue ) | | ! MoneyRange ( nValueIn ) )
return DoS ( 100 , error ( " ConnectInputs() : txin values out of range " )) ;
2011-12-23 23:13:10 +01:00
// Skip ECDSA signature verification when connecting blocks (fBlock=true)
// before the last blockchain checkpoint. This is safe because block merkle hashes are
2011-09-02 22:59:47 +02:00
// still computed and checked, and any change will be caught at the next checkpoint.
2011-12-23 23:13:10 +01:00
if ( ! ( fBlock & & ( nBestHeight < Checkpoints : : GetTotalBlocksEstimate ( ) ) ) )
2011-11-08 19:20:29 +01:00
{
2011-09-02 22:59:47 +02:00
// Verify signature
2012-01-05 03:40:52 +01:00
if ( ! VerifySignature ( txPrev , * this , i , fStrictPayToScriptHash , 0 ) )
2012-02-25 19:02:30 +01:00
{
// only during transition phase for P2SH: do not invoke anti-DoS code for
// potentially old clients relaying bad P2SH transactions
if ( fStrictPayToScriptHash & & VerifySignature ( txPrev , * this , i , false , 0 ) )
return error ( " ConnectInputs() : % s P2SH VerifySignature failed " , GetHash().ToString().substr(0,10).c_str()) ;
2011-09-02 22:59:47 +02:00
return DoS ( 100 , error ( " ConnectInputs() : % s VerifySignature failed " , GetHash().ToString().substr(0,10).c_str())) ;
2012-02-25 19:02:30 +01:00
}
2011-11-08 19:20:29 +01:00
}
2010-08-29 18:58:15 +02:00
// Mark outpoints as spent
txindex . vSpent [ prevout . n ] = posThisTx ;
// Write back
2011-09-05 20:33:07 +02:00
if ( fBlock | | fMiner )
2010-10-06 04:19:47 +02:00
{
2010-08-29 18:58:15 +02:00
mapTestPool [ prevout . hash ] = txindex ;
2010-10-06 04:19:47 +02:00
}
2010-08-29 18:58:15 +02:00
}
if ( nValueIn < GetValueOut ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " ConnectInputs() : % s value in < value out " , GetHash().ToString().substr(0,10).c_str())) ;
2010-08-29 18:58:15 +02:00
// Tally transaction fees
2011-12-21 22:33:19 +01:00
int64 nTxFee = nValueIn - GetValueOut ( ) ;
2010-08-29 18:58:15 +02:00
if ( nTxFee < 0 )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " ConnectInputs() : % s nTxFee < 0 " , GetHash().ToString().substr(0,10).c_str())) ;
2010-08-29 18:58:15 +02:00
nFees + = nTxFee ;
2010-09-07 03:12:53 +02:00
if ( ! MoneyRange ( nFees ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " ConnectInputs() : nFees out of range " )) ;
2010-08-29 18:58:15 +02:00
}
return true ;
}
bool CTransaction : : ClientConnectInputs ( )
{
if ( IsCoinBase ( ) )
return false ;
// Take over previous transactions' spent pointers
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapTransactions ) ;
2011-12-21 22:33:19 +01:00
int64 nValueIn = 0 ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
// Get prev tx from single transactions in memory
COutPoint prevout = vin [ i ] . prevout ;
if ( ! mapTransactions . count ( prevout . hash ) )
return false ;
CTransaction & txPrev = mapTransactions [ prevout . hash ] ;
if ( prevout . n > = txPrev . vout . size ( ) )
return false ;
// Verify signature
2012-01-05 03:40:52 +01:00
if ( ! VerifySignature ( txPrev , * this , i , true , 0 ) )
2010-08-29 18:58:15 +02:00
return error ( " ConnectInputs() : VerifySignature failed " ) ;
///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
///// this has to go away now that posNext is gone
// // Check for conflicts
// if (!txPrev.vout[prevout.n].posNext.IsNull())
// return error("ConnectInputs() : prev tx already used");
//
// // Flag outpoints as used
// txPrev.vout[prevout.n].posNext = posThisTx;
nValueIn + = txPrev . vout [ prevout . n ] . nValue ;
2010-09-07 03:12:53 +02:00
if ( ! MoneyRange ( txPrev . vout [ prevout . n ] . nValue ) | | ! MoneyRange ( nValueIn ) )
return error ( " ClientConnectInputs() : txin values out of range " ) ;
2010-08-29 18:58:15 +02:00
}
if ( GetValueOut ( ) > nValueIn )
return false ;
}
return true ;
}
bool CBlock : : DisconnectBlock ( CTxDB & txdb , CBlockIndex * pindex )
{
// Disconnect in reverse order
for ( int i = vtx . size ( ) - 1 ; i > = 0 ; i - - )
if ( ! vtx [ i ] . DisconnectInputs ( txdb ) )
return false ;
// Update block index on disk without changing it in memory.
// The memory index structure will be changed after the db commits.
if ( pindex - > pprev )
{
CDiskBlockIndex blockindexPrev ( pindex - > pprev ) ;
blockindexPrev . hashNext = 0 ;
2010-10-06 04:19:47 +02:00
if ( ! txdb . WriteBlockIndex ( blockindexPrev ) )
return error ( " DisconnectBlock() : WriteBlockIndex failed " ) ;
2010-08-29 18:58:15 +02:00
}
return true ;
}
bool CBlock : : ConnectBlock ( CTxDB & txdb , CBlockIndex * pindex )
{
// Check it again in case a previous version let a bad block in
if ( ! CheckBlock ( ) )
return false ;
2012-02-17 17:58:02 +01:00
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
// unless those are already completely spent.
// If such overwrites are allowed, coinbases and transactions depending upon those
// can be duplicated to remove the ability to spend the first instance -- even after
// being sent to another address.
// See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
// This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
// already refuses previously-known transaction id's entirely.
// This rule applies to all blocks whose timestamp is after March 15, 2012, 0:00 UTC.
// On testnet it is enabled as of februari 20, 2012, 0:00 UTC.
if ( pindex - > nTime > 1331769600 | | ( fTestNet & & pindex - > nTime > 1329696000 ) )
2012-04-15 13:27:00 +02:00
{
2012-02-17 17:58:02 +01:00
BOOST_FOREACH ( CTransaction & tx , vtx )
{
CTxIndex txindexOld ;
if ( txdb . ReadTxIndex ( tx . GetHash ( ) , txindexOld ) )
2012-04-15 13:27:00 +02:00
{
2012-02-17 17:58:02 +01:00
BOOST_FOREACH ( CDiskTxPos & pos , txindexOld . vSpent )
if ( pos . IsNull ( ) )
return false ;
2012-04-15 13:27:00 +02:00
}
2012-02-17 17:58:02 +01:00
}
2012-04-15 13:27:00 +02:00
}
2012-02-17 17:58:02 +01:00
2012-03-21 20:45:58 +01:00
// BIP16 didn't become active until Apr 1 2012 (Feb 15 on testnet)
int64 nBIP16SwitchTime = fTestNet ? 1329264000 : 1333238400 ;
bool fStrictPayToScriptHash = ( pindex - > nTime > = nBIP16SwitchTime ) ;
2012-01-20 23:07:40 +01:00
2010-08-29 18:58:15 +02:00
//// issue here: it doesn't know the version
2012-04-16 14:56:45 +02:00
unsigned int nTxPos = pindex - > nBlockPos + : : GetSerializeSize ( CBlock ( ) , SER_DISK , CLIENT_VERSION ) - 1 + GetSizeOfCompactSize ( vtx . size ( ) ) ;
2010-08-29 18:58:15 +02:00
2011-09-05 20:33:07 +02:00
map < uint256 , CTxIndex > mapQueuedChanges ;
2011-12-21 22:33:19 +01:00
int64 nFees = 0 ;
2011-10-03 19:05:43 +02:00
int nSigOps = 0 ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CTransaction & tx , vtx )
2010-08-29 18:58:15 +02:00
{
2012-01-20 23:07:40 +01:00
nSigOps + = tx . GetLegacySigOpCount ( ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
return DoS ( 100 , error ( " ConnectBlock() : too many sigops " )) ;
2010-08-29 18:58:15 +02:00
CDiskTxPos posThisTx ( pindex - > nFile , pindex - > nBlockPos , nTxPos ) ;
2012-04-16 14:56:45 +02:00
nTxPos + = : : GetSerializeSize ( tx , SER_DISK , CLIENT_VERSION ) ;
2010-08-29 18:58:15 +02:00
2012-01-11 02:18:00 +01:00
MapPrevTx mapInputs ;
if ( ! tx . IsCoinBase ( ) )
{
2012-01-18 19:36:44 +01:00
bool fInvalid ;
if ( ! tx . FetchInputs ( txdb , mapQueuedChanges , true , false , mapInputs , fInvalid ) )
2012-01-11 02:18:00 +01:00
return false ;
2012-01-05 03:40:52 +01:00
2012-01-20 23:07:40 +01:00
if ( fStrictPayToScriptHash )
{
// Add in sigops done by pay-to-script-hash inputs;
// this is to prevent a "rogue miner" from creating
// an incredibly-expensive-to-validate block.
nSigOps + = tx . GetP2SHSigOpCount ( mapInputs ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
return DoS ( 100 , error ( " ConnectBlock() : too many sigops " )) ;
}
2012-01-05 03:40:52 +01:00
2012-01-11 02:18:00 +01:00
nFees + = tx . GetValueIn ( mapInputs ) - tx . GetValueOut ( ) ;
2012-01-11 02:45:55 +01:00
2012-01-20 23:07:40 +01:00
if ( ! tx . ConnectInputs ( mapInputs , mapQueuedChanges , posThisTx , pindex , true , false , fStrictPayToScriptHash ) )
2012-01-11 02:45:55 +01:00
return false ;
2012-01-11 02:18:00 +01:00
}
2012-01-11 02:45:55 +01:00
mapQueuedChanges [ tx . GetHash ( ) ] = CTxIndex ( posThisTx , tx . vout . size ( ) ) ;
2010-08-29 18:58:15 +02:00
}
2011-10-03 19:05:43 +02:00
2011-09-05 20:33:07 +02:00
// Write queued txindex changes
for ( map < uint256 , CTxIndex > : : iterator mi = mapQueuedChanges . begin ( ) ; mi ! = mapQueuedChanges . end ( ) ; + + mi )
{
if ( ! txdb . UpdateTxIndex ( ( * mi ) . first , ( * mi ) . second ) )
return error ( " ConnectBlock() : UpdateTxIndex failed " ) ;
}
2010-08-29 18:58:15 +02:00
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
return false ;
// Update block index on disk without changing it in memory.
// The memory index structure will be changed after the db commits.
if ( pindex - > pprev )
{
CDiskBlockIndex blockindexPrev ( pindex - > pprev ) ;
blockindexPrev . hashNext = pindex - > GetBlockHash ( ) ;
2010-10-06 04:19:47 +02:00
if ( ! txdb . WriteBlockIndex ( blockindexPrev ) )
return error ( " ConnectBlock() : WriteBlockIndex failed " ) ;
2010-08-29 18:58:15 +02:00
}
// Watch for transactions paying to me
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CTransaction & tx , vtx )
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
SyncWithWallets ( tx , this , true ) ;
2010-08-29 18:58:15 +02:00
return true ;
}
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
bool static Reorganize ( CTxDB & txdb , CBlockIndex * pindexNew )
2010-08-29 18:58:15 +02:00
{
printf ( " REORGANIZE \n " ) ;
// Find the fork
CBlockIndex * pfork = pindexBest ;
CBlockIndex * plonger = pindexNew ;
while ( pfork ! = plonger )
{
while ( plonger - > nHeight > pfork - > nHeight )
if ( ! ( plonger = plonger - > pprev ) )
return error ( " Reorganize() : plonger - > pprev is null " ) ;
if ( pfork = = plonger )
break ;
if ( ! ( pfork = pfork - > pprev ) )
return error ( " Reorganize() : pfork - > pprev is null " ) ;
}
// List of what to disconnect
vector < CBlockIndex * > vDisconnect ;
for ( CBlockIndex * pindex = pindexBest ; pindex ! = pfork ; pindex = pindex - > pprev )
vDisconnect . push_back ( pindex ) ;
// List of what to connect
vector < CBlockIndex * > vConnect ;
for ( CBlockIndex * pindex = pindexNew ; pindex ! = pfork ; pindex = pindex - > pprev )
vConnect . push_back ( pindex ) ;
reverse ( vConnect . begin ( ) , vConnect . end ( ) ) ;
2012-03-21 13:15:27 +01:00
printf ( " REORGANIZE: Disconnect %i blocks; %s..%s \n " , vDisconnect . size ( ) , pfork - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , pindexBest - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) ) ;
printf ( " REORGANIZE: Connect %i blocks; %s..%s \n " , vConnect . size ( ) , pfork - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , pindexNew - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) ) ;
2010-08-29 18:58:15 +02:00
// Disconnect shorter branch
vector < CTransaction > vResurrect ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CBlockIndex * pindex , vDisconnect )
2010-08-29 18:58:15 +02:00
{
CBlock block ;
if ( ! block . ReadFromDisk ( pindex ) )
return error ( " Reorganize() : ReadFromDisk for disconnect failed " ) ;
if ( ! block . DisconnectBlock ( txdb , pindex ) )
2012-03-21 13:15:27 +01:00
return error ( " Reorganize() : DisconnectBlock % s failed " , pindex->GetBlockHash().ToString().substr(0,20).c_str()) ;
2010-08-29 18:58:15 +02:00
// Queue memory transactions to resurrect
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
2010-08-29 18:58:15 +02:00
if ( ! tx . IsCoinBase ( ) )
vResurrect . push_back ( tx ) ;
}
// Connect longer branch
vector < CTransaction > vDelete ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vConnect . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
CBlockIndex * pindex = vConnect [ i ] ;
CBlock block ;
if ( ! block . ReadFromDisk ( pindex ) )
return error ( " Reorganize() : ReadFromDisk for connect failed " ) ;
if ( ! block . ConnectBlock ( txdb , pindex ) )
{
// Invalid block
txdb . TxnAbort ( ) ;
2012-03-21 13:15:27 +01:00
return error ( " Reorganize() : ConnectBlock % s failed " , pindex->GetBlockHash().ToString().substr(0,20).c_str()) ;
2010-08-29 18:58:15 +02:00
}
// Queue memory transactions to delete
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
2010-08-29 18:58:15 +02:00
vDelete . push_back ( tx ) ;
}
if ( ! txdb . WriteHashBestChain ( pindexNew - > GetBlockHash ( ) ) )
return error ( " Reorganize() : WriteHashBestChain failed " ) ;
2010-10-06 04:19:47 +02:00
// Make sure it's successfully written to disk before changing memory structure
if ( ! txdb . TxnCommit ( ) )
return error ( " Reorganize() : TxnCommit failed " ) ;
2010-08-29 18:58:15 +02:00
// Disconnect shorter branch
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CBlockIndex * pindex , vDisconnect )
2010-08-29 18:58:15 +02:00
if ( pindex - > pprev )
pindex - > pprev - > pnext = NULL ;
// Connect longer branch
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CBlockIndex * pindex , vConnect )
2010-08-29 18:58:15 +02:00
if ( pindex - > pprev )
pindex - > pprev - > pnext = pindex ;
// Resurrect memory transactions that were in the disconnected branch
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CTransaction & tx , vResurrect )
2010-09-07 03:12:53 +02:00
tx . AcceptToMemoryPool ( txdb , false ) ;
2010-08-29 18:58:15 +02:00
// Delete redundant memory transactions that are in the connected branch
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CTransaction & tx , vDelete )
2010-08-29 18:58:15 +02:00
tx . RemoveFromMemoryPool ( ) ;
2012-03-21 13:15:27 +01:00
printf ( " REORGANIZE: done \n " ) ;
2012-02-19 19:42:15 +01:00
2010-08-29 18:58:15 +02:00
return true ;
}
2012-01-03 21:24:28 +01:00
static void
runCommand ( std : : string strCommand )
{
int nErr = : : system ( strCommand . c_str ( ) ) ;
if ( nErr )
printf ( " runCommand error: system(%s) returned %d \n " , strCommand . c_str ( ) , nErr ) ;
}
2012-03-20 16:41:36 +01:00
// Called from inside SetBestChain: attaches a block to the new best chain being built
2012-03-10 23:04:06 +01:00
bool CBlock : : SetBestChainInner ( CTxDB & txdb , CBlockIndex * pindexNew )
{
uint256 hash = GetHash ( ) ;
// Adding to current best branch
if ( ! ConnectBlock ( txdb , pindexNew ) | | ! txdb . WriteHashBestChain ( hash ) )
{
txdb . TxnAbort ( ) ;
InvalidChainFound ( pindexNew ) ;
return false ;
}
if ( ! txdb . TxnCommit ( ) )
return error ( " SetBestChain() : TxnCommit failed " ) ;
// Add to current best branch
pindexNew - > pprev - > pnext = pindexNew ;
// Delete redundant memory transactions
BOOST_FOREACH ( CTransaction & tx , vtx )
tx . RemoveFromMemoryPool ( ) ;
return true ;
}
2010-08-29 18:58:15 +02:00
bool CBlock : : SetBestChain ( CTxDB & txdb , CBlockIndex * pindexNew )
{
uint256 hash = GetHash ( ) ;
txdb . TxnBegin ( ) ;
if ( pindexGenesisBlock = = NULL & & hash = = hashGenesisBlock )
{
txdb . WriteHashBestChain ( hash ) ;
2010-10-06 04:19:47 +02:00
if ( ! txdb . TxnCommit ( ) )
return error ( " SetBestChain() : TxnCommit failed " ) ;
pindexGenesisBlock = pindexNew ;
2010-08-29 18:58:15 +02:00
}
else if ( hashPrevBlock = = hashBestChain )
{
2012-03-10 23:04:06 +01:00
if ( ! SetBestChainInner ( txdb , pindexNew ) )
return error ( " SetBestChain() : SetBestChainInner failed " ) ;
}
else
{
// the first block in the new chain that will cause it to become the new best chain
CBlockIndex * pindexIntermediate = pindexNew ;
// list of blocks that need to be connected afterwards
std : : vector < CBlockIndex * > vpindexSecondary ;
// Reorganize is costly in terms of db load, as it works in a single db transaction.
// Try to limit how much needs to be done inside
while ( pindexIntermediate - > pprev & & pindexIntermediate - > pprev - > bnChainWork > pindexBest - > bnChainWork )
2010-08-29 18:58:15 +02:00
{
2012-03-10 23:04:06 +01:00
vpindexSecondary . push_back ( pindexIntermediate ) ;
pindexIntermediate = pindexIntermediate - > pprev ;
2010-08-29 18:58:15 +02:00
}
2010-10-06 04:19:47 +02:00
2012-03-10 23:04:06 +01:00
if ( ! vpindexSecondary . empty ( ) )
printf ( " Postponing %i reconnects \n " , vpindexSecondary . size ( ) ) ;
2010-08-29 18:58:15 +02:00
2012-03-10 23:04:06 +01:00
// Switch to new best branch
if ( ! Reorganize ( txdb , pindexIntermediate ) )
2010-08-29 18:58:15 +02:00
{
txdb . TxnAbort ( ) ;
InvalidChainFound ( pindexNew ) ;
return error ( " SetBestChain() : Reorganize failed " ) ;
}
2012-03-10 23:04:06 +01:00
// Connect futher blocks
BOOST_REVERSE_FOREACH ( CBlockIndex * pindex , vpindexSecondary )
{
CBlock block ;
if ( ! block . ReadFromDisk ( pindex ) )
{
printf ( " SetBestChain() : ReadFromDisk failed \n " ) ;
break ;
}
txdb . TxnBegin ( ) ;
// errors now are not fatal, we still did a reorganisation to a new chain in a valid way
if ( ! block . SetBestChainInner ( txdb , pindex ) )
break ;
}
2010-08-29 18:58:15 +02:00
}
2011-04-13 16:16:30 +02:00
// Update best block in wallet (so we can detect restored wallets)
2012-01-03 21:24:28 +01:00
bool fIsInitialDownload = IsInitialBlockDownload ( ) ;
if ( ! fIsInitialDownload )
2011-04-13 16:16:30 +02:00
{
const CBlockLocator locator ( pindexNew ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
: : SetBestChain ( locator ) ;
2011-04-13 16:16:30 +02:00
}
2010-08-29 18:58:15 +02:00
// New best block
hashBestChain = hash ;
pindexBest = pindexNew ;
nBestHeight = pindexBest - > nHeight ;
bnBestChainWork = pindexNew - > bnChainWork ;
nTimeBestReceived = GetTime ( ) ;
nTransactionsUpdated + + ;
printf ( " SetBestChain: new best=%s height=%d work=%s \n " , hashBestChain . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , nBestHeight , bnBestChainWork . ToString ( ) . c_str ( ) ) ;
2012-01-03 21:24:28 +01:00
std : : string strCmd = GetArg ( " -blocknotify " , " " ) ;
if ( ! fIsInitialDownload & & ! strCmd . empty ( ) )
{
boost : : replace_all ( strCmd , " %s " , hashBestChain . GetHex ( ) ) ;
boost : : thread t ( runCommand , strCmd ) ; // thread runs free
}
2010-08-29 18:58:15 +02:00
return true ;
}
bool CBlock : : AddToBlockIndex ( unsigned int nFile , unsigned int nBlockPos )
{
// Check for duplicate
uint256 hash = GetHash ( ) ;
if ( mapBlockIndex . count ( hash ) )
return error ( " AddToBlockIndex() : % s already exists " , hash.ToString().substr(0,20).c_str()) ;
// Construct new block index object
CBlockIndex * pindexNew = new CBlockIndex ( nFile , nBlockPos , * this ) ;
if ( ! pindexNew )
return error ( " AddToBlockIndex() : new CBlockIndex failed " ) ;
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . insert ( make_pair ( hash , pindexNew ) ) . first ;
pindexNew - > phashBlock = & ( ( * mi ) . first ) ;
map < uint256 , CBlockIndex * > : : iterator miPrev = mapBlockIndex . find ( hashPrevBlock ) ;
if ( miPrev ! = mapBlockIndex . end ( ) )
{
pindexNew - > pprev = ( * miPrev ) . second ;
pindexNew - > nHeight = pindexNew - > pprev - > nHeight + 1 ;
}
pindexNew - > bnChainWork = ( pindexNew - > pprev ? pindexNew - > pprev - > bnChainWork : 0 ) + pindexNew - > GetBlockWork ( ) ;
CTxDB txdb ;
2010-12-05 10:29:30 +01:00
txdb . TxnBegin ( ) ;
2010-08-29 18:58:15 +02:00
txdb . WriteBlockIndex ( CDiskBlockIndex ( pindexNew ) ) ;
2010-12-05 10:29:30 +01:00
if ( ! txdb . TxnCommit ( ) )
return false ;
2010-08-29 18:58:15 +02:00
// New best
if ( pindexNew - > bnChainWork > bnBestChainWork )
if ( ! SetBestChain ( txdb , pindexNew ) )
return false ;
txdb . Close ( ) ;
if ( pindexNew = = pindexBest )
{
// Notify UI to display prev block's coinbase if it was ours
static uint256 hashPrevBestCoinBase ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
UpdatedTransaction ( hashPrevBestCoinBase ) ;
2010-08-29 18:58:15 +02:00
hashPrevBestCoinBase = vtx [ 0 ] . GetHash ( ) ;
}
MainFrameRepaint ( ) ;
return true ;
}
bool CBlock : : CheckBlock ( ) const
{
// These are checks that are independent of context
// that can be verified before saving an orphan block.
// Size limits
2012-04-16 14:56:45 +02:00
if ( vtx . empty ( ) | | vtx . size ( ) > MAX_BLOCK_SIZE | | : : GetSerializeSize ( * this , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CheckBlock() : size limits failed " )) ;
2010-08-29 18:58:15 +02:00
2010-09-19 23:20:34 +02:00
// Check proof of work matches claimed amount
if ( ! CheckProofOfWork ( GetHash ( ) , nBits ) )
2011-09-06 22:59:38 +02:00
return DoS ( 50 , error ( " CheckBlock() : proof of work failed " )) ;
2010-09-19 23:20:34 +02:00
2010-08-29 18:58:15 +02:00
// Check timestamp
if ( GetBlockTime ( ) > GetAdjustedTime ( ) + 2 * 60 * 60 )
return error ( " CheckBlock() : block timestamp too far in the future " ) ;
// First transaction must be coinbase, the rest must not be
if ( vtx . empty ( ) | | ! vtx [ 0 ] . IsCoinBase ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CheckBlock() : first tx is not coinbase " )) ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 1 ; i < vtx . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
if ( vtx [ i ] . IsCoinBase ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CheckBlock() : more than one coinbase " )) ;
2010-08-29 18:58:15 +02:00
// Check transactions
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTransaction & tx , vtx )
2010-08-29 18:58:15 +02:00
if ( ! tx . CheckTransaction ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( tx . nDoS , error ( " CheckBlock() : CheckTransaction failed " )) ;
2010-08-29 18:58:15 +02:00
2011-10-03 19:05:43 +02:00
int nSigOps = 0 ;
BOOST_FOREACH ( const CTransaction & tx , vtx )
{
2012-01-05 03:40:52 +01:00
nSigOps + = tx . GetLegacySigOpCount ( ) ;
2011-10-03 19:05:43 +02:00
}
if ( nSigOps > MAX_BLOCK_SIGOPS )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CheckBlock() : out - of - bounds SigOpCount " )) ;
2010-08-29 18:58:15 +02:00
// Check merkleroot
if ( hashMerkleRoot ! = BuildMerkleTree ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " CheckBlock() : hashMerkleRoot mismatch " )) ;
2010-08-29 18:58:15 +02:00
return true ;
}
bool CBlock : : AcceptBlock ( )
{
// Check for duplicate
uint256 hash = GetHash ( ) ;
if ( mapBlockIndex . count ( hash ) )
return error ( " AcceptBlock() : block already in mapBlockIndex " ) ;
// Get prev block index
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( hashPrevBlock ) ;
if ( mi = = mapBlockIndex . end ( ) )
2011-09-06 22:59:38 +02:00
return DoS ( 10 , error ( " AcceptBlock() : prev block not found " )) ;
2010-08-29 18:58:15 +02:00
CBlockIndex * pindexPrev = ( * mi ) . second ;
2010-09-07 03:12:53 +02:00
int nHeight = pindexPrev - > nHeight + 1 ;
2010-09-19 23:20:34 +02:00
// Check proof of work
2011-12-05 21:50:22 +01:00
if ( nBits ! = GetNextWorkRequired ( pindexPrev , this ) )
2011-09-06 22:59:38 +02:00
return DoS ( 100 , error ( " AcceptBlock() : incorrect proof of work " )) ;
2010-08-29 18:58:15 +02:00
// Check timestamp against prev
if ( GetBlockTime ( ) < = pindexPrev - > GetMedianTimePast ( ) )
return error ( " AcceptBlock() : block ' s timestamp is too early " ) ;
// Check that all transactions are finalized
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTransaction & tx , vtx )
2010-09-07 03:12:53 +02:00
if ( ! tx . IsFinal ( nHeight , GetBlockTime ( ) ) )
2011-09-06 22:59:38 +02:00
return DoS ( 10 , error ( " AcceptBlock() : contains a non - final transaction " )) ;
2010-08-29 18:58:15 +02:00
// Check that the block chain matches the known block chain up to a checkpoint
2011-09-08 22:50:58 +02:00
if ( ! Checkpoints : : CheckBlock ( nHeight , hash ) )
return DoS ( 100 , error ( " AcceptBlock() : rejected by checkpoint lockin at % d " , nHeight)) ;
2010-08-29 18:58:15 +02:00
// Write block to history file
2012-04-16 14:56:45 +02:00
if ( ! CheckDiskSpace ( : : GetSerializeSize ( * this , SER_DISK , CLIENT_VERSION ) ) )
2010-08-29 18:58:15 +02:00
return error ( " AcceptBlock() : out of disk space " ) ;
2010-12-05 10:29:30 +01:00
unsigned int nFile = - 1 ;
unsigned int nBlockPos = 0 ;
if ( ! WriteToDisk ( nFile , nBlockPos ) )
2010-08-29 18:58:15 +02:00
return error ( " AcceptBlock() : WriteToDisk failed " ) ;
if ( ! AddToBlockIndex ( nFile , nBlockPos ) )
return error ( " AcceptBlock() : AddToBlockIndex failed " ) ;
// Relay inventory, but don't relay old inventory during initial block download
2012-03-20 18:45:45 +01:00
int nBlockEstimate = Checkpoints : : GetTotalBlocksEstimate ( ) ;
2010-08-29 18:58:15 +02:00
if ( hashBestChain = = hash )
2012-04-06 18:39:12 +02:00
{
LOCK ( cs_vNodes ) ;
BOOST_FOREACH ( CNode * pnode , vNodes )
if ( nBestHeight > ( pnode - > nStartingHeight ! = - 1 ? pnode - > nStartingHeight - 2000 : nBlockEstimate ) )
pnode - > PushInventory ( CInv ( MSG_BLOCK , hash ) ) ;
}
2010-08-29 18:58:15 +02:00
return true ;
}
2011-09-07 00:15:46 +02:00
bool ProcessBlock ( CNode * pfrom , CBlock * pblock )
2010-08-29 18:58:15 +02:00
{
// Check for duplicate
uint256 hash = pblock - > GetHash ( ) ;
if ( mapBlockIndex . count ( hash ) )
return error ( " ProcessBlock() : already have block % d % s " , mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str()) ;
if ( mapOrphanBlocks . count ( hash ) )
return error ( " ProcessBlock() : already have block ( orphan ) % s " , hash.ToString().substr(0,20).c_str()) ;
// Preliminary checks
if ( ! pblock - > CheckBlock ( ) )
return error ( " ProcessBlock() : CheckBlock FAILED " ) ;
2011-09-08 18:51:43 +02:00
CBlockIndex * pcheckpoint = Checkpoints : : GetLastCheckpoint ( mapBlockIndex ) ;
if ( pcheckpoint & & pblock - > hashPrevBlock ! = hashBestChain )
{
// Extra checks to prevent "fill up memory by spamming with bogus blocks"
2011-12-21 22:33:19 +01:00
int64 deltaTime = pblock - > GetBlockTime ( ) - pcheckpoint - > nTime ;
2011-09-08 18:51:43 +02:00
if ( deltaTime < 0 )
{
2012-02-20 22:35:08 +01:00
if ( pfrom )
pfrom - > Misbehaving ( 100 ) ;
2011-09-08 18:51:43 +02:00
return error ( " ProcessBlock() : block with timestamp before last checkpoint " ) ;
}
CBigNum bnNewBlock ;
bnNewBlock . SetCompact ( pblock - > nBits ) ;
CBigNum bnRequired ;
bnRequired . SetCompact ( ComputeMinWork ( pcheckpoint - > nBits , deltaTime ) ) ;
if ( bnNewBlock > bnRequired )
{
2012-02-20 22:35:08 +01:00
if ( pfrom )
pfrom - > Misbehaving ( 100 ) ;
2011-09-08 18:51:43 +02:00
return error ( " ProcessBlock() : block with too little proof - of - work " ) ;
}
}
2010-08-29 18:58:15 +02:00
// If don't already have its previous block, shunt it off to holding area until we get it
if ( ! mapBlockIndex . count ( pblock - > hashPrevBlock ) )
{
printf ( " ProcessBlock: ORPHAN BLOCK, prev=%s \n " , pblock - > hashPrevBlock . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) ) ;
2010-11-23 20:16:36 +01:00
CBlock * pblock2 = new CBlock ( * pblock ) ;
mapOrphanBlocks . insert ( make_pair ( hash , pblock2 ) ) ;
mapOrphanBlocksByPrev . insert ( make_pair ( pblock2 - > hashPrevBlock , pblock2 ) ) ;
2010-08-29 18:58:15 +02:00
// Ask this guy to fill in what we're missing
if ( pfrom )
2010-11-23 20:16:36 +01:00
pfrom - > PushGetBlocks ( pindexBest , GetOrphanRoot ( pblock2 ) ) ;
2010-08-29 18:58:15 +02:00
return true ;
}
// Store to disk
if ( ! pblock - > AcceptBlock ( ) )
return error ( " ProcessBlock() : AcceptBlock FAILED " ) ;
// Recursively process any orphan blocks that depended on this one
vector < uint256 > vWorkQueue ;
vWorkQueue . push_back ( hash ) ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vWorkQueue . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
uint256 hashPrev = vWorkQueue [ i ] ;
for ( multimap < uint256 , CBlock * > : : iterator mi = mapOrphanBlocksByPrev . lower_bound ( hashPrev ) ;
mi ! = mapOrphanBlocksByPrev . upper_bound ( hashPrev ) ;
+ + mi )
{
CBlock * pblockOrphan = ( * mi ) . second ;
if ( pblockOrphan - > AcceptBlock ( ) )
vWorkQueue . push_back ( pblockOrphan - > GetHash ( ) ) ;
mapOrphanBlocks . erase ( pblockOrphan - > GetHash ( ) ) ;
delete pblockOrphan ;
}
mapOrphanBlocksByPrev . erase ( hashPrev ) ;
}
printf ( " ProcessBlock: ACCEPTED \n " ) ;
return true ;
}
2011-12-21 22:33:19 +01:00
bool CheckDiskSpace ( uint64 nAdditionalBytes )
2010-08-29 18:58:15 +02:00
{
2011-12-21 22:33:19 +01:00
uint64 nFreeBytesAvailable = filesystem : : space ( GetDataDir ( ) ) . available ;
2010-08-29 18:58:15 +02:00
// Check for 15MB because database could create another 10MB log file at any time
2011-12-21 22:33:19 +01:00
if ( nFreeBytesAvailable < ( uint64 ) 15000000 + nAdditionalBytes )
2010-08-29 18:58:15 +02:00
{
fShutdown = true ;
string strMessage = _ ( " Warning: Disk space is low " ) ;
strMiscWarning = strMessage ;
printf ( " *** %s \n " , strMessage . c_str ( ) ) ;
2012-03-25 20:47:33 +02:00
ThreadSafeMessageBox ( strMessage , " Bitcoin " , wxOK | wxICON_EXCLAMATION | wxMODAL ) ;
2012-03-25 20:17:59 +02:00
QueueShutdown ( ) ;
2010-08-29 18:58:15 +02:00
return false ;
}
return true ;
}
FILE * OpenBlockFile ( unsigned int nFile , unsigned int nBlockPos , const char * pszMode )
{
if ( nFile = = - 1 )
return NULL ;
2012-04-09 23:50:56 +02:00
FILE * file = fopen ( ( GetDataDir ( ) / strprintf ( " blk%04d.dat " , nFile ) ) . string ( ) . c_str ( ) , pszMode ) ;
2010-08-29 18:58:15 +02:00
if ( ! file )
return NULL ;
if ( nBlockPos ! = 0 & & ! strchr ( pszMode , ' a ' ) & & ! strchr ( pszMode , ' w ' ) )
{
if ( fseek ( file , nBlockPos , SEEK_SET ) ! = 0 )
{
fclose ( file ) ;
return NULL ;
}
}
return file ;
}
static unsigned int nCurrentBlockFile = 1 ;
FILE * AppendBlockFile ( unsigned int & nFileRet )
{
nFileRet = 0 ;
loop
{
FILE * file = OpenBlockFile ( nCurrentBlockFile , 0 , " ab " ) ;
if ( ! file )
return NULL ;
if ( fseek ( file , 0 , SEEK_END ) ! = 0 )
return NULL ;
// FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB
if ( ftell ( file ) < 0x7F000000 - MAX_SIZE )
{
nFileRet = nCurrentBlockFile ;
return file ;
}
fclose ( file ) ;
nCurrentBlockFile + + ;
}
}
bool LoadBlockIndex ( bool fAllowNew )
{
2010-10-19 19:16:51 +02:00
if ( fTestNet )
{
2011-02-03 14:21:21 +01:00
hashGenesisBlock = uint256 ( " 0x00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008 " ) ;
2010-10-19 19:16:51 +02:00
bnProofOfWorkLimit = CBigNum ( ~ uint256 ( 0 ) > > 28 ) ;
pchMessageStart [ 0 ] = 0xfa ;
pchMessageStart [ 1 ] = 0xbf ;
pchMessageStart [ 2 ] = 0xb5 ;
pchMessageStart [ 3 ] = 0xda ;
}
2010-08-29 18:58:15 +02:00
//
// Load block index
//
CTxDB txdb ( " cr " ) ;
if ( ! txdb . LoadBlockIndex ( ) )
return false ;
txdb . Close ( ) ;
//
// Init with genesis block
//
if ( mapBlockIndex . empty ( ) )
{
if ( ! fAllowNew )
return false ;
// Genesis Block:
// 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)
// CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
// CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
// vMerkleTree: 4a5e1e
// Genesis block
const char * pszTimestamp = " The Times 03/Jan/2009 Chancellor on brink of second bailout for banks " ;
CTransaction txNew ;
txNew . vin . 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 . vout [ 0 ] . nValue = 50 * COIN ;
txNew . vout [ 0 ] . scriptPubKey = CScript ( ) < < ParseHex ( " 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f " ) < < OP_CHECKSIG ;
CBlock block ;
block . vtx . push_back ( txNew ) ;
block . hashPrevBlock = 0 ;
block . hashMerkleRoot = block . BuildMerkleTree ( ) ;
block . nVersion = 1 ;
block . nTime = 1231006505 ;
block . nBits = 0x1d00ffff ;
block . nNonce = 2083236893 ;
2010-10-19 19:16:51 +02:00
if ( fTestNet )
{
2011-02-03 14:21:21 +01:00
block . nTime = 1296688602 ;
2010-10-19 19:16:51 +02:00
block . nBits = 0x1d07fff8 ;
2011-02-03 14:21:21 +01:00
block . nNonce = 384568319 ;
2010-10-19 19:16:51 +02:00
}
2010-08-29 18:58:15 +02:00
2010-10-19 19:16:51 +02:00
//// 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 ( ) ;
2010-08-29 18:58:15 +02:00
assert ( block . GetHash ( ) = = hashGenesisBlock ) ;
// Start new block file
unsigned int nFile ;
unsigned int nBlockPos ;
2010-12-05 10:29:30 +01:00
if ( ! block . WriteToDisk ( nFile , nBlockPos ) )
2010-08-29 18:58:15 +02:00
return error ( " LoadBlockIndex() : writing genesis block to disk failed " ) ;
if ( ! block . AddToBlockIndex ( nFile , nBlockPos ) )
return error ( " LoadBlockIndex() : genesis block not accepted " ) ;
}
return true ;
}
void PrintBlockTree ( )
{
// precompute tree structure
map < CBlockIndex * , vector < CBlockIndex * > > mapNext ;
for ( map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . begin ( ) ; mi ! = mapBlockIndex . end ( ) ; + + mi )
{
CBlockIndex * pindex = ( * mi ) . second ;
mapNext [ pindex - > pprev ] . push_back ( pindex ) ;
// test
//while (rand() % 3 == 0)
// mapNext[pindex->pprev].push_back(pindex);
}
vector < pair < int , CBlockIndex * > > vStack ;
vStack . push_back ( make_pair ( 0 , pindexGenesisBlock ) ) ;
int nPrevCol = 0 ;
while ( ! vStack . empty ( ) )
{
int nCol = vStack . back ( ) . first ;
CBlockIndex * pindex = vStack . back ( ) . second ;
vStack . pop_back ( ) ;
// print split or gap
if ( nCol > nPrevCol )
{
for ( int i = 0 ; i < nCol - 1 ; i + + )
printf ( " | " ) ;
printf ( " | \\ \n " ) ;
}
else if ( nCol < nPrevCol )
{
for ( int i = 0 ; i < nCol ; i + + )
printf ( " | " ) ;
printf ( " | \n " ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
}
2010-08-29 18:58:15 +02:00
nPrevCol = nCol ;
// print columns
for ( int i = 0 ; i < nCol ; i + + )
printf ( " | " ) ;
// print item
CBlock block ;
block . ReadFromDisk ( pindex ) ;
printf ( " %d (%u,%u) %s %s tx %d " ,
pindex - > nHeight ,
pindex - > nFile ,
pindex - > nBlockPos ,
block . GetHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) ,
DateTimeStrFormat ( " %x %H:%M:%S " , block . GetBlockTime ( ) ) . c_str ( ) ,
block . vtx . size ( ) ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
PrintWallets ( block ) ;
2010-08-29 18:58:15 +02:00
// put the main timechain first
vector < CBlockIndex * > & vNext = mapNext [ pindex ] ;
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vNext . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
if ( vNext [ i ] - > pnext )
{
swap ( vNext [ 0 ] , vNext [ i ] ) ;
break ;
}
}
// iterate children
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vNext . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
vStack . push_back ( make_pair ( nCol + i , vNext [ i ] ) ) ;
}
}
//////////////////////////////////////////////////////////////////////////////
//
// CAlert
//
map < uint256 , CAlert > mapAlerts ;
CCriticalSection cs_mapAlerts ;
string GetWarnings ( string strFor )
{
int nPriority = 0 ;
string strStatusBar ;
string strRPC ;
2010-12-03 20:38:09 +01:00
if ( GetBoolArg ( " -testsafemode " ) )
2010-08-29 18:58:15 +02:00
strRPC = " test " ;
// 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
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapAlerts ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
2010-08-29 18:58:15 +02:00
{
const CAlert & alert = item . second ;
if ( alert . AppliesToMe ( ) & & alert . nPriority > nPriority )
{
nPriority = alert . nPriority ;
strStatusBar = alert . strStatusBar ;
}
}
}
if ( strFor = = " statusbar " )
return strStatusBar ;
else if ( strFor = = " rpc " )
return strRPC ;
2011-06-24 19:56:23 +02:00
assert ( ! " GetWarnings() : invalid parameter " ) ;
2010-08-29 18:58:15 +02:00
return " error " ;
}
bool CAlert : : ProcessAlert ( )
{
if ( ! CheckSignature ( ) )
return false ;
if ( ! IsInEffect ( ) )
return false ;
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapAlerts ) ;
2010-08-29 18:58:15 +02:00
// 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
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
2010-08-29 18:58:15 +02:00
{
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
//
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
bool static AlreadyHave ( CTxDB & txdb , const CInv & inv )
2010-08-29 18:58:15 +02:00
{
switch ( inv . type )
{
2012-04-14 00:24:55 +02:00
case MSG_TX :
{
2012-04-17 18:31:51 +02:00
bool txInMap = false ;
{
2012-04-17 18:30:00 +02:00
LOCK ( cs_mapTransactions ) ;
2012-04-17 18:31:51 +02:00
txInMap = ( mapTransactions . count ( inv . hash ) ! = 0 ) ;
}
2012-04-17 18:30:00 +02:00
return txInMap | |
2012-04-14 00:24:55 +02:00
mapOrphanTransactions . count ( inv . hash ) | |
txdb . ContainsTx ( inv . hash ) ;
}
case MSG_BLOCK :
return mapBlockIndex . count ( inv . hash ) | |
mapOrphanBlocks . count ( inv . hash ) ;
2010-08-29 18:58:15 +02:00
}
// Don't know what it is, just say we already got one
return true ;
}
2010-10-19 19:16:51 +02:00
// 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.
2011-08-07 18:19:14 +02:00
unsigned char pchMessageStart [ 4 ] = { 0xf9 , 0xbe , 0xb4 , 0xd9 } ;
2010-08-29 18:58:15 +02:00
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
bool static ProcessMessage ( CNode * pfrom , string strCommand , CDataStream & vRecv )
2010-08-29 18:58:15 +02:00
{
2012-01-03 23:33:31 +01:00
static map < CService , vector < unsigned char > > mapReuseKey ;
2010-08-29 18:58:15 +02:00
RandAddSeedPerfmon ( ) ;
2011-09-17 18:29:41 +02:00
if ( fDebug ) {
2010-08-29 18:58:15 +02:00
printf ( " %s " , DateTimeStrFormat ( " %x %H:%M:%S " , GetTime ( ) ) . c_str ( ) ) ;
2011-09-17 18:29:41 +02:00
printf ( " received: %s (%d bytes) \n " , strCommand . c_str ( ) , vRecv . size ( ) ) ;
}
2010-08-29 18:58:15 +02:00
if ( mapArgs . count ( " -dropmessagestest " ) & & GetRand ( atoi ( mapArgs [ " -dropmessagestest " ] ) ) = = 0 )
{
printf ( " dropmessagestest DROPPING RECV MESSAGE \n " ) ;
return true ;
}
if ( strCommand = = " version " )
{
// Each connection can only send one version message
if ( pfrom - > nVersion ! = 0 )
2011-09-06 23:41:51 +02:00
{
pfrom - > Misbehaving ( 1 ) ;
2010-08-29 18:58:15 +02:00
return false ;
2011-09-06 23:41:51 +02:00
}
2010-08-29 18:58:15 +02:00
2011-12-21 22:33:19 +01:00
int64 nTime ;
2010-08-29 18:58:15 +02:00
CAddress addrMe ;
CAddress addrFrom ;
2011-12-21 22:33:19 +01:00
uint64 nNonce = 1 ;
2010-08-29 18:58:15 +02:00
vRecv > > pfrom - > nVersion > > pfrom - > nServices > > nTime > > addrMe ;
2012-04-13 02:07:49 +02:00
if ( pfrom - > nVersion < MIN_PROTO_VERSION )
2012-02-20 01:33:31 +01:00
{
2012-02-28 13:31:56 +01:00
// Since February 20, 2012, the protocol is initiated at version 209,
2012-02-20 01:33:31 +01:00
// and earlier versions are no longer supported
printf ( " partner %s using obsolete version %i; disconnecting \n " , pfrom - > addr . ToString ( ) . c_str ( ) , pfrom - > nVersion ) ;
pfrom - > fDisconnect = true ;
return false ;
}
2010-08-29 18:58:15 +02:00
if ( pfrom - > nVersion = = 10300 )
pfrom - > nVersion = 300 ;
2012-02-20 01:33:31 +01:00
if ( ! vRecv . empty ( ) )
2010-08-29 18:58:15 +02:00
vRecv > > addrFrom > > nNonce ;
2012-02-20 01:33:31 +01:00
if ( ! vRecv . empty ( ) )
2010-08-29 18:58:15 +02:00
vRecv > > pfrom - > strSubVer ;
2012-02-20 01:33:31 +01:00
if ( ! vRecv . empty ( ) )
2010-08-29 18:58:15 +02:00
vRecv > > pfrom - > nStartingHeight ;
// Disconnect if we connected to ourself
if ( nNonce = = nLocalHostNonce & & nNonce > 1 )
{
2010-10-06 04:19:47 +02:00
printf ( " connected to self at %s, disconnecting \n " , pfrom - > addr . ToString ( ) . c_str ( ) ) ;
2010-08-29 18:58:15 +02:00
pfrom - > fDisconnect = true ;
return true ;
}
2011-01-24 16:42:17 +01:00
// Be shy and don't send version until we hear
if ( pfrom - > fInbound )
pfrom - > PushVersion ( ) ;
2010-08-29 18:58:15 +02:00
pfrom - > fClient = ! ( pfrom - > nServices & NODE_NETWORK ) ;
2012-01-03 23:33:31 +01:00
AddTimeData ( pfrom - > addr , nTime ) ;
2010-08-29 18:58:15 +02:00
// Change version
2012-02-20 01:33:31 +01:00
pfrom - > PushMessage ( " verack " ) ;
2011-12-16 22:26:14 +01:00
pfrom - > vSend . SetVersion ( min ( pfrom - > nVersion , PROTOCOL_VERSION ) ) ;
2010-08-29 18:58:15 +02:00
2010-10-23 19:43:53 +02:00
if ( ! pfrom - > fInbound )
{
// Advertise our address
2012-02-02 00:08:03 +01:00
if ( ! fNoListen & & ! fUseProxy & & addrLocalHost . IsRoutable ( ) & &
! IsInitialBlockDownload ( ) )
2010-10-23 19:43:53 +02:00
{
CAddress addr ( addrLocalHost ) ;
addr . nTime = GetAdjustedTime ( ) ;
pfrom - > PushAddress ( addr ) ;
}
// Get recent addresses
2012-04-13 02:07:49 +02:00
if ( pfrom - > nVersion > = CADDR_TIME_VERSION | | addrman . size ( ) < 1000 )
2010-10-23 19:43:53 +02:00
{
pfrom - > PushMessage ( " getaddr " ) ;
pfrom - > fGetAddr = true ;
}
2012-01-04 23:39:45 +01:00
addrman . Good ( pfrom - > addr ) ;
} else {
if ( ( ( CNetAddr ) pfrom - > addr ) = = ( CNetAddr ) addrFrom )
{
addrman . Add ( addrFrom , addrFrom ) ;
addrman . Good ( addrFrom ) ;
}
2010-10-23 19:43:53 +02:00
}
2010-08-29 18:58:15 +02:00
// Ask the first connected node for block updates
2011-12-20 01:04:47 +01:00
static int nAskedForBlocks = 0 ;
2011-09-02 18:56:10 +02:00
if ( ! pfrom - > fClient & &
2012-04-13 02:07:49 +02:00
( pfrom - > nVersion < NOBLKS_VERSION_START | |
2012-04-17 18:31:51 +02:00
pfrom - > nVersion > = NOBLKS_VERSION_END ) & &
2011-09-02 18:56:10 +02:00
( nAskedForBlocks < 1 | | vNodes . size ( ) < = 1 ) )
2010-08-29 18:58:15 +02:00
{
nAskedForBlocks + + ;
pfrom - > PushGetBlocks ( pindexBest , uint256 ( 0 ) ) ;
}
// Relay alerts
2012-04-06 18:39:12 +02:00
{
LOCK ( cs_mapAlerts ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
2010-08-29 18:58:15 +02:00
item . second . RelayTo ( pfrom ) ;
2012-04-06 18:39:12 +02:00
}
2010-08-29 18:58:15 +02:00
pfrom - > fSuccessfullyConnected = true ;
printf ( " version message: version %d, blocks=%d \n " , pfrom - > nVersion , pfrom - > nStartingHeight ) ;
2011-09-28 21:35:58 +02:00
cPeerBlockCounts . input ( pfrom - > nStartingHeight ) ;
2010-08-29 18:58:15 +02:00
}
else if ( pfrom - > nVersion = = 0 )
{
// Must have a version message before anything else
2011-09-06 23:41:51 +02:00
pfrom - > Misbehaving ( 1 ) ;
2010-08-29 18:58:15 +02:00
return false ;
}
else if ( strCommand = = " verack " )
{
2011-12-16 22:26:14 +01:00
pfrom - > vRecv . SetVersion ( min ( pfrom - > nVersion , PROTOCOL_VERSION ) ) ;
2010-08-29 18:58:15 +02:00
}
else if ( strCommand = = " addr " )
{
vector < CAddress > vAddr ;
vRecv > > vAddr ;
2010-10-23 19:43:53 +02:00
// Don't want addr from older versions unless seeding
2012-04-13 02:07:49 +02:00
if ( pfrom - > nVersion < CADDR_TIME_VERSION & & addrman . size ( ) > 1000 )
2010-08-29 18:58:15 +02:00
return true ;
if ( vAddr . size ( ) > 1000 )
2011-09-06 23:41:51 +02:00
{
pfrom - > Misbehaving ( 20 ) ;
2010-08-29 18:58:15 +02:00
return error ( " message addr size() = % d " , vAddr.size()) ;
2011-09-06 23:41:51 +02:00
}
2010-08-29 18:58:15 +02:00
// Store the new addresses
2011-12-21 22:33:19 +01:00
int64 nNow = GetAdjustedTime ( ) ;
int64 nSince = nNow - 10 * 60 ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CAddress & addr , vAddr )
2010-08-29 18:58:15 +02:00
{
if ( fShutdown )
return true ;
// ignore IPv6 for now, since it isn't implemented anyway
if ( ! addr . IsIPv4 ( ) )
continue ;
2010-10-23 19:43:53 +02:00
if ( addr . nTime < = 100000000 | | addr . nTime > nNow + 10 * 60 )
addr . nTime = nNow - 5 * 24 * 60 * 60 ;
2010-08-29 18:58:15 +02:00
pfrom - > AddAddressKnown ( addr ) ;
2010-10-23 19:43:53 +02:00
if ( addr . nTime > nSince & & ! pfrom - > fGetAddr & & vAddr . size ( ) < = 10 & & addr . IsRoutable ( ) )
2010-08-29 18:58:15 +02:00
{
// Relay to a limited number of other nodes
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_vNodes ) ;
2010-10-19 19:16:51 +02:00
// Use deterministic randomness to send to the same nodes for 24 hours
// at a time so the setAddrKnowns of the chosen nodes prevent repeats
2010-08-29 18:58:15 +02:00
static uint256 hashSalt ;
if ( hashSalt = = 0 )
RAND_bytes ( ( unsigned char * ) & hashSalt , sizeof ( hashSalt ) ) ;
2012-01-03 23:33:31 +01:00
int64 hashAddr = addr . GetHash ( ) ;
uint256 hashRand = hashSalt ^ ( hashAddr < < 32 ) ^ ( ( GetTime ( ) + hashAddr ) / ( 24 * 60 * 60 ) ) ;
2010-10-19 19:16:51 +02:00
hashRand = Hash ( BEGIN ( hashRand ) , END ( hashRand ) ) ;
2010-08-29 18:58:15 +02:00
multimap < uint256 , CNode * > mapMix ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CNode * pnode , vNodes )
2010-10-19 19:16:51 +02:00
{
2012-04-13 02:07:49 +02:00
if ( pnode - > nVersion < CADDR_TIME_VERSION )
2010-10-23 19:43:53 +02:00
continue ;
2010-10-19 19:16:51 +02:00
unsigned int nPointer ;
memcpy ( & nPointer , & pnode , sizeof ( nPointer ) ) ;
uint256 hashKey = hashRand ^ nPointer ;
hashKey = Hash ( BEGIN ( hashKey ) , END ( hashKey ) ) ;
mapMix . insert ( make_pair ( hashKey , pnode ) ) ;
}
2010-09-07 03:12:53 +02:00
int nRelayNodes = 2 ;
2010-08-29 18:58:15 +02:00
for ( multimap < uint256 , CNode * > : : iterator mi = mapMix . begin ( ) ; mi ! = mapMix . end ( ) & & nRelayNodes - - > 0 ; + + mi )
( ( * mi ) . second ) - > PushAddress ( addr ) ;
}
}
}
2012-01-04 23:39:45 +01:00
addrman . Add ( vAddr , pfrom - > addr , 2 * 60 * 60 ) ;
2010-08-29 18:58:15 +02:00
if ( vAddr . size ( ) < 1000 )
pfrom - > fGetAddr = false ;
}
else if ( strCommand = = " inv " )
{
vector < CInv > vInv ;
vRecv > > vInv ;
if ( vInv . size ( ) > 50000 )
2011-09-06 23:41:51 +02:00
{
pfrom - > Misbehaving ( 20 ) ;
2010-08-29 18:58:15 +02:00
return error ( " message inv size() = % d " , vInv.size()) ;
2011-09-06 23:41:51 +02:00
}
2010-08-29 18:58:15 +02:00
CTxDB txdb ( " r " ) ;
2012-04-15 22:52:09 +02:00
for ( unsigned int nInv = 0 ; nInv < vInv . size ( ) ; nInv + + )
2010-08-29 18:58:15 +02:00
{
2012-03-18 23:47:26 +01:00
const CInv & inv = vInv [ nInv ] ;
2010-08-29 18:58:15 +02:00
if ( fShutdown )
return true ;
pfrom - > AddInventoryKnown ( inv ) ;
bool fAlreadyHave = AlreadyHave ( txdb , inv ) ;
2011-09-17 18:29:41 +02:00
if ( fDebug )
printf ( " got inventory: %s %s \n " , inv . ToString ( ) . c_str ( ) , fAlreadyHave ? " have " : " new " ) ;
2010-08-29 18:58:15 +02:00
2012-03-18 23:47:26 +01:00
// Always request the last block in an inv bundle (even if we already have it), as it is the
// trigger for the other side to send further invs. If we are stuck on a (very long) side chain,
// this is necessary to connect earlier received orphan blocks to the chain again.
if ( ! fAlreadyHave | | ( inv . type = = MSG_BLOCK & & nInv = = vInv . size ( ) - 1 ) )
2010-08-29 18:58:15 +02:00
pfrom - > AskFor ( inv ) ;
2012-03-18 23:47:26 +01:00
if ( inv . type = = MSG_BLOCK & & mapOrphanBlocks . count ( inv . hash ) )
2010-08-29 18:58:15 +02:00
pfrom - > PushGetBlocks ( pindexBest , GetOrphanRoot ( mapOrphanBlocks [ inv . hash ] ) ) ;
// Track requests for our stuff
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
Inventory ( inv . hash ) ;
2010-08-29 18:58:15 +02:00
}
}
else if ( strCommand = = " getdata " )
{
vector < CInv > vInv ;
vRecv > > vInv ;
if ( vInv . size ( ) > 50000 )
2011-09-06 23:41:51 +02:00
{
pfrom - > Misbehaving ( 20 ) ;
2010-08-29 18:58:15 +02:00
return error ( " message getdata size() = % d " , vInv.size()) ;
2011-09-06 23:41:51 +02:00
}
2010-08-29 18:58:15 +02:00
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CInv & inv , vInv )
2010-08-29 18:58:15 +02:00
{
if ( fShutdown )
return true ;
printf ( " received getdata for: %s \n " , inv . ToString ( ) . c_str ( ) ) ;
if ( inv . type = = MSG_BLOCK )
{
// Send block from disk
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( inv . hash ) ;
if ( mi ! = mapBlockIndex . end ( ) )
{
CBlock block ;
2010-12-05 10:29:30 +01:00
block . ReadFromDisk ( ( * mi ) . second ) ;
2010-08-29 18:58:15 +02:00
pfrom - > PushMessage ( " block " , block ) ;
// Trigger them to send a getblocks request for the next batch of inventory
if ( inv . hash = = pfrom - > hashContinue )
{
// Bypass PushInventory, this must send even if redundant,
// and we want it right after the last block so they don't
// wait for other stuff first.
vector < CInv > vInv ;
vInv . push_back ( CInv ( MSG_BLOCK , hashBestChain ) ) ;
pfrom - > PushMessage ( " inv " , vInv ) ;
pfrom - > hashContinue = 0 ;
}
}
}
else if ( inv . IsKnownType ( ) )
{
// Send stream from relay memory
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_mapRelay ) ;
2010-08-29 18:58:15 +02:00
map < CInv , CDataStream > : : iterator mi = mapRelay . find ( inv ) ;
if ( mi ! = mapRelay . end ( ) )
pfrom - > PushMessage ( inv . GetCommand ( ) , ( * mi ) . second ) ;
}
}
// Track requests for our stuff
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
Inventory ( inv . hash ) ;
2010-08-29 18:58:15 +02:00
}
}
else if ( strCommand = = " getblocks " )
{
CBlockLocator locator ;
uint256 hashStop ;
vRecv > > locator > > hashStop ;
2010-12-05 10:29:30 +01:00
// Find the last block the caller has in the main chain
2010-08-29 18:58:15 +02:00
CBlockIndex * pindex = locator . GetBlockIndex ( ) ;
// Send the rest of the chain
if ( pindex )
pindex = pindex - > pnext ;
int nLimit = 500 + locator . GetDistanceBack ( ) ;
2011-06-30 23:29:44 +02:00
unsigned int nBytes = 0 ;
2010-08-29 18:58:15 +02:00
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 )
{
2011-06-30 23:29:44 +02:00
printf ( " getblocks stopping at %d %s (%u bytes) \n " , pindex - > nHeight , pindex - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , nBytes ) ;
2010-08-29 18:58:15 +02:00
break ;
}
pfrom - > PushInventory ( CInv ( MSG_BLOCK , pindex - > GetBlockHash ( ) ) ) ;
2011-06-30 23:29:44 +02:00
CBlock block ;
block . ReadFromDisk ( pindex , true ) ;
2012-04-16 14:56:45 +02:00
nBytes + = block . GetSerializeSize ( SER_NETWORK , PROTOCOL_VERSION ) ;
2011-06-30 23:29:44 +02:00
if ( - - nLimit < = 0 | | nBytes > = SendBufferSize ( ) / 2 )
2010-08-29 18:58:15 +02:00
{
// When this block is requested, we'll send an inv that'll make them
// getblocks the next batch of inventory.
2011-06-30 23:29:44 +02:00
printf ( " getblocks stopping at limit %d %s (%u bytes) \n " , pindex - > nHeight , pindex - > GetBlockHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) , nBytes ) ;
2010-08-29 18:58:15 +02:00
pfrom - > hashContinue = pindex - > GetBlockHash ( ) ;
break ;
}
}
}
2010-12-05 10:29:30 +01:00
else if ( strCommand = = " getheaders " )
{
CBlockLocator locator ;
uint256 hashStop ;
vRecv > > locator > > hashStop ;
CBlockIndex * pindex = NULL ;
if ( locator . IsNull ( ) )
{
// If locator is null, return the hashStop block
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( hashStop ) ;
if ( mi = = mapBlockIndex . end ( ) )
return true ;
pindex = ( * mi ) . second ;
}
else
{
// Find the last block the caller has in the main chain
pindex = locator . GetBlockIndex ( ) ;
if ( pindex )
pindex = pindex - > pnext ;
}
vector < CBlock > vHeaders ;
2012-03-19 05:13:15 +01:00
int nLimit = 2000 ;
printf ( " getheaders %d to %s \n " , ( pindex ? pindex - > nHeight : - 1 ) , hashStop . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) ) ;
2010-12-05 10:29:30 +01:00
for ( ; pindex ; pindex = pindex - > pnext )
{
vHeaders . push_back ( pindex - > GetBlockHeader ( ) ) ;
if ( - - nLimit < = 0 | | pindex - > GetBlockHash ( ) = = hashStop )
break ;
}
pfrom - > PushMessage ( " headers " , vHeaders ) ;
}
2010-08-29 18:58:15 +02:00
else if ( strCommand = = " tx " )
{
vector < uint256 > vWorkQueue ;
CDataStream vMsg ( vRecv ) ;
2012-04-13 23:48:15 +02:00
CTxDB txdb ( " r " ) ;
2010-08-29 18:58:15 +02:00
CTransaction tx ;
vRecv > > tx ;
CInv inv ( MSG_TX , tx . GetHash ( ) ) ;
pfrom - > AddInventoryKnown ( inv ) ;
bool fMissingInputs = false ;
2012-04-13 23:48:15 +02:00
if ( tx . AcceptToMemoryPool ( txdb , true , & fMissingInputs ) )
2010-08-29 18:58:15 +02:00
{
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
SyncWithWallets ( tx , NULL , true ) ;
2010-08-29 18:58:15 +02:00
RelayMessage ( inv , vMsg ) ;
mapAlreadyAskedFor . erase ( inv ) ;
vWorkQueue . push_back ( inv . hash ) ;
// Recursively process any orphan transactions that depended on this one
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < vWorkQueue . size ( ) ; i + + )
2010-08-29 18:58:15 +02:00
{
uint256 hashPrev = vWorkQueue [ i ] ;
for ( multimap < uint256 , CDataStream * > : : iterator mi = mapOrphanTransactionsByPrev . lower_bound ( hashPrev ) ;
mi ! = mapOrphanTransactionsByPrev . upper_bound ( hashPrev ) ;
+ + mi )
{
const CDataStream & vMsg = * ( ( * mi ) . second ) ;
CTransaction tx ;
CDataStream ( vMsg ) > > tx ;
CInv inv ( MSG_TX , tx . GetHash ( ) ) ;
2012-04-13 23:48:15 +02:00
if ( tx . AcceptToMemoryPool ( txdb , true ) )
2010-08-29 18:58:15 +02:00
{
2010-10-06 04:19:47 +02:00
printf ( " accepted orphan tx %s \n " , inv . hash . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
SyncWithWallets ( tx , NULL , true ) ;
2010-08-29 18:58:15 +02:00
RelayMessage ( inv , vMsg ) ;
mapAlreadyAskedFor . erase ( inv ) ;
vWorkQueue . push_back ( inv . hash ) ;
}
}
}
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( uint256 hash , vWorkQueue )
2010-08-29 18:58:15 +02:00
EraseOrphanTx ( hash ) ;
}
else if ( fMissingInputs )
{
2010-10-06 04:19:47 +02:00
printf ( " storing orphan tx %s \n " , inv . hash . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) ) ;
2010-08-29 18:58:15 +02:00
AddOrphanTx ( vMsg ) ;
2012-02-29 16:14:18 +01:00
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
int nEvicted = LimitOrphanTxSize ( MAX_ORPHAN_TRANSACTIONS ) ;
if ( nEvicted > 0 )
printf ( " mapOrphan overflow, removed %d tx \n " , nEvicted ) ;
2010-08-29 18:58:15 +02:00
}
2011-09-06 22:59:38 +02:00
if ( tx . nDoS ) pfrom - > Misbehaving ( tx . nDoS ) ;
2010-08-29 18:58:15 +02:00
}
else if ( strCommand = = " block " )
{
2010-12-05 10:29:30 +01:00
CBlock block ;
vRecv > > block ;
2010-08-29 18:58:15 +02:00
2010-12-05 10:29:30 +01:00
printf ( " received block %s \n " , block . GetHash ( ) . ToString ( ) . substr ( 0 , 20 ) . c_str ( ) ) ;
// block.print();
2010-08-29 18:58:15 +02:00
2010-12-05 10:29:30 +01:00
CInv inv ( MSG_BLOCK , block . GetHash ( ) ) ;
2010-08-29 18:58:15 +02:00
pfrom - > AddInventoryKnown ( inv ) ;
2010-12-05 10:29:30 +01:00
if ( ProcessBlock ( pfrom , & block ) )
2010-08-29 18:58:15 +02:00
mapAlreadyAskedFor . erase ( inv ) ;
2011-09-06 22:59:38 +02:00
if ( block . nDoS ) pfrom - > Misbehaving ( block . nDoS ) ;
2010-08-29 18:58:15 +02:00
}
else if ( strCommand = = " getaddr " )
{
pfrom - > vAddrToSend . clear ( ) ;
2012-01-04 23:39:45 +01:00
vector < CAddress > vAddr = addrman . GetAddr ( ) ;
BOOST_FOREACH ( const CAddress & addr , vAddr )
pfrom - > PushAddress ( addr ) ;
2010-08-29 18:58:15 +02:00
}
else if ( strCommand = = " checkorder " )
{
uint256 hashReply ;
2010-12-07 14:43:31 +01:00
vRecv > > hashReply ;
2010-08-29 18:58:15 +02:00
2010-12-07 14:43:31 +01:00
if ( ! GetBoolArg ( " -allowreceivebyip " ) )
2010-09-19 23:20:34 +02:00
{
pfrom - > PushMessage ( " reply " , hashReply , ( int ) 2 , string ( " " ) ) ;
return true ;
}
2010-12-07 14:43:31 +01:00
CWalletTx order ;
vRecv > > order ;
2010-08-29 18:58:15 +02:00
/// we have a chance to check the order here
// Keep giving the same key to the same ip until they use it
2012-01-03 23:33:31 +01:00
if ( ! mapReuseKey . count ( pfrom - > addr ) )
pwalletMain - > GetKeyFromPool ( mapReuseKey [ pfrom - > addr ] , true ) ;
2010-08-29 18:58:15 +02:00
// Send back approval of order and pubkey to use
CScript scriptPubKey ;
2012-01-03 23:33:31 +01:00
scriptPubKey < < mapReuseKey [ pfrom - > addr ] < < OP_CHECKSIG ;
2010-08-29 18:58:15 +02:00
pfrom - > PushMessage ( " reply " , hashReply , ( int ) 0 , scriptPubKey ) ;
}
else if ( strCommand = = " reply " )
{
uint256 hashReply ;
vRecv > > hashReply ;
CRequestTracker tracker ;
{
2012-04-06 18:39:12 +02:00
LOCK ( pfrom - > cs_mapRequests ) ;
2010-08-29 18:58:15 +02:00
map < uint256 , CRequestTracker > : : iterator mi = pfrom - > mapRequests . find ( hashReply ) ;
if ( mi ! = pfrom - > mapRequests . end ( ) )
{
tracker = ( * mi ) . second ;
pfrom - > mapRequests . erase ( mi ) ;
}
}
if ( ! tracker . IsNull ( ) )
tracker . fn ( tracker . param1 , vRecv ) ;
}
else if ( strCommand = = " ping " )
{
2012-04-11 18:38:03 +02:00
if ( pfrom - > nVersion > BIP0031_VERSION )
{
uint64 nonce = 0 ;
vRecv > > nonce ;
// Echo the message back with the nonce. This allows for two useful features:
//
// 1) A remote node can quickly check if the connection is operational
// 2) Remote nodes can measure the latency of the network thread. If this node
// is overloaded it won't respond to pings quickly and the remote node can
// avoid sending us more work, like chain download requests.
//
// The nonce stops the remote getting confused between different pings: without
// it, if the remote node sends a ping once per second and this node takes 5
// seconds to respond to each, the 5th ping the remote sends would appear to
// return very quickly.
pfrom - > PushMessage ( " pong " , nonce ) ;
}
2010-08-29 18:58:15 +02:00
}
else if ( strCommand = = " alert " )
{
CAlert alert ;
vRecv > > alert ;
if ( alert . ProcessAlert ( ) )
{
// Relay
pfrom - > setKnown . insert ( alert . GetHash ( ) ) ;
2012-04-06 18:39:12 +02:00
{
LOCK ( cs_vNodes ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CNode * pnode , vNodes )
2010-08-29 18:58:15 +02:00
alert . RelayTo ( pnode ) ;
2012-04-06 18:39:12 +02:00
}
2010-08-29 18:58:15 +02:00
}
}
else
{
// Ignore unknown commands for extensibility
}
// Update the last seen time for this node's address
if ( pfrom - > fNetworkNode )
if ( strCommand = = " version " | | strCommand = = " addr " | | strCommand = = " inv " | | strCommand = = " getdata " | | strCommand = = " ping " )
AddressCurrentlyConnected ( pfrom - > addr ) ;
return true ;
}
2011-06-01 18:27:05 +02:00
bool ProcessMessages ( CNode * pfrom )
{
CDataStream & vRecv = pfrom - > vRecv ;
if ( vRecv . empty ( ) )
return true ;
//if (fDebug)
// printf("ProcessMessages(%u bytes)\n", vRecv.size());
2010-08-29 18:58:15 +02:00
2011-06-01 18:27:05 +02:00
//
// Message format
// (4) message start
// (12) command
// (4) size
// (4) checksum
// (x) data
//
2010-08-29 18:58:15 +02:00
2011-06-01 18:27:05 +02:00
loop
{
// Scan for message start
CDataStream : : iterator pstart = search ( vRecv . begin ( ) , vRecv . end ( ) , BEGIN ( pchMessageStart ) , END ( pchMessageStart ) ) ;
int nHeaderSize = vRecv . GetSerializeSize ( CMessageHeader ( ) ) ;
if ( vRecv . end ( ) - pstart < nHeaderSize )
{
if ( vRecv . size ( ) > nHeaderSize )
{
printf ( " \n \n PROCESSMESSAGE MESSAGESTART NOT FOUND \n \n " ) ;
vRecv . erase ( vRecv . begin ( ) , vRecv . end ( ) - nHeaderSize ) ;
}
break ;
}
if ( pstart - vRecv . begin ( ) > 0 )
printf ( " \n \n PROCESSMESSAGE SKIPPED %d BYTES \n \n " , pstart - vRecv . begin ( ) ) ;
vRecv . erase ( vRecv . begin ( ) , pstart ) ;
2010-08-29 18:58:15 +02:00
2011-06-01 18:27:05 +02:00
// Read header
vector < char > vHeaderSave ( vRecv . begin ( ) , vRecv . begin ( ) + nHeaderSize ) ;
CMessageHeader hdr ;
vRecv > > hdr ;
if ( ! hdr . IsValid ( ) )
{
printf ( " \n \n PROCESSMESSAGE: ERRORS IN HEADER %s \n \n \n " , hdr . GetCommand ( ) . c_str ( ) ) ;
continue ;
}
string strCommand = hdr . GetCommand ( ) ;
// Message size
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 ( ) )
{
// Rewind and wait for rest of message
vRecv . insert ( vRecv . begin ( ) , vHeaderSave . begin ( ) , vHeaderSave . end ( ) ) ;
break ;
}
// Checksum
2012-02-20 01:33:31 +01:00
uint256 hash = Hash ( vRecv . begin ( ) , vRecv . begin ( ) + nMessageSize ) ;
unsigned int nChecksum = 0 ;
memcpy ( & nChecksum , & hash , sizeof ( nChecksum ) ) ;
if ( nChecksum ! = hdr . nChecksum )
2011-06-01 18:27:05 +02:00
{
2012-02-20 01:33:31 +01:00
printf ( " ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x \n " ,
strCommand . c_str ( ) , nMessageSize , nChecksum , hdr . nChecksum ) ;
continue ;
2011-06-01 18:27:05 +02:00
}
// 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
{
2012-04-06 18:39:12 +02:00
{
LOCK ( cs_main ) ;
2011-06-01 18:27:05 +02:00
fRet = ProcessMessage ( pfrom , strCommand , vMsg ) ;
2012-04-06 18:39:12 +02:00
}
2011-06-01 18:27:05 +02:00
if ( fShutdown )
return true ;
}
catch ( std : : ios_base : : failure & e )
{
if ( strstr ( e . what ( ) , " end of data " ) )
{
// Allow exceptions from underlength message on vRecv
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 " ) )
{
// Allow exceptions from overlong size
printf ( " ProcessMessage(%s, %u bytes) : Exception '%s' caught \n " , strCommand . c_str ( ) , nMessageSize , e . what ( ) ) ;
}
else
{
PrintExceptionContinue ( & e , " ProcessMessage() " ) ;
}
}
catch ( std : : exception & e ) {
PrintExceptionContinue ( & e , " ProcessMessage() " ) ;
} catch ( . . . ) {
PrintExceptionContinue ( NULL , " ProcessMessage() " ) ;
}
if ( ! fRet )
printf ( " ProcessMessage(%s, %u bytes) FAILED \n " , strCommand . c_str ( ) , nMessageSize ) ;
}
vRecv . Compact ( ) ;
return true ;
}
2010-08-29 18:58:15 +02:00
bool SendMessages ( CNode * pto , bool fSendTrickle )
{
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_main ) ;
2010-08-29 18:58:15 +02:00
// Don't send anything until we get their version message
if ( pto - > nVersion = = 0 )
return true ;
2012-04-11 18:38:03 +02:00
// Keep-alive ping. We send a nonce of zero because we don't use it anywhere
// right now.
if ( pto - > nLastSend & & GetTime ( ) - pto - > nLastSend > 30 * 60 & & pto - > vSend . empty ( ) ) {
if ( pto - > nVersion > BIP0031_VERSION )
pto - > PushMessage ( " ping " , 0 ) ;
else
pto - > PushMessage ( " ping " ) ;
}
2010-08-29 18:58:15 +02:00
2010-10-23 19:43:53 +02:00
// Resend wallet transactions that haven't gotten in a block yet
ResendWalletTransactions ( ) ;
2010-08-29 18:58:15 +02:00
// Address refresh broadcast
2011-12-21 22:33:19 +01:00
static int64 nLastRebroadcast ;
2012-02-02 00:08:03 +01:00
if ( ! IsInitialBlockDownload ( ) & & ( GetTime ( ) - nLastRebroadcast > 24 * 60 * 60 ) )
2010-08-29 18:58:15 +02:00
{
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_vNodes ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( CNode * pnode , vNodes )
2010-08-29 18:58:15 +02:00
{
// Periodically clear setAddrKnown to allow refresh broadcasts
2012-02-02 00:08:03 +01:00
if ( nLastRebroadcast )
pnode - > setAddrKnown . clear ( ) ;
2010-08-29 18:58:15 +02:00
// Rebroadcast our address
2012-02-02 00:08:03 +01:00
if ( ! fNoListen & & ! fUseProxy & & addrLocalHost . IsRoutable ( ) )
2010-10-23 19:43:53 +02:00
{
CAddress addr ( addrLocalHost ) ;
addr . nTime = GetAdjustedTime ( ) ;
pnode - > PushAddress ( addr ) ;
}
2010-08-29 18:58:15 +02:00
}
}
2012-02-02 00:08:03 +01:00
nLastRebroadcast = GetTime ( ) ;
2010-08-29 18:58:15 +02:00
}
//
// Message: addr
//
if ( fSendTrickle )
{
vector < CAddress > vAddr ;
vAddr . reserve ( pto - > vAddrToSend . size ( ) ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CAddress & addr , pto - > vAddrToSend )
2010-08-29 18:58:15 +02:00
{
// returns true if wasn't already contained in the set
if ( pto - > setAddrKnown . insert ( addr ) . second )
{
vAddr . push_back ( addr ) ;
// receiver rejects addr messages larger than 1000
if ( vAddr . size ( ) > = 1000 )
{
pto - > PushMessage ( " addr " , vAddr ) ;
vAddr . clear ( ) ;
}
}
}
pto - > vAddrToSend . clear ( ) ;
if ( ! vAddr . empty ( ) )
pto - > PushMessage ( " addr " , vAddr ) ;
}
//
// Message: inventory
//
vector < CInv > vInv ;
vector < CInv > vInvWait ;
{
2012-04-06 18:39:12 +02:00
LOCK ( pto - > cs_inventory ) ;
2010-08-29 18:58:15 +02:00
vInv . reserve ( pto - > vInventoryToSend . size ( ) ) ;
vInvWait . reserve ( pto - > vInventoryToSend . size ( ) ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CInv & inv , pto - > vInventoryToSend )
2010-08-29 18:58:15 +02:00
{
if ( pto - > setInventoryKnown . count ( inv ) )
continue ;
// trickle out tx inv to protect privacy
if ( inv . type = = MSG_TX & & ! fSendTrickle )
{
// 1/4 of tx invs blast to all immediately
static uint256 hashSalt ;
if ( hashSalt = = 0 )
RAND_bytes ( ( unsigned char * ) & hashSalt , sizeof ( hashSalt ) ) ;
uint256 hashRand = inv . hash ^ hashSalt ;
hashRand = Hash ( BEGIN ( hashRand ) , END ( hashRand ) ) ;
bool fTrickleWait = ( ( hashRand & 3 ) ! = 0 ) ;
// always trickle our own transactions
if ( ! fTrickleWait )
{
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
CWalletTx wtx ;
if ( GetTransaction ( inv . hash , wtx ) )
if ( wtx . fFromMe )
fTrickleWait = true ;
2010-08-29 18:58:15 +02:00
}
if ( fTrickleWait )
{
vInvWait . push_back ( inv ) ;
continue ;
}
}
// returns true if wasn't already contained in the set
if ( pto - > setInventoryKnown . insert ( inv ) . second )
{
vInv . push_back ( inv ) ;
if ( vInv . size ( ) > = 1000 )
{
pto - > PushMessage ( " inv " , vInv ) ;
vInv . clear ( ) ;
}
}
}
pto - > vInventoryToSend = vInvWait ;
}
if ( ! vInv . empty ( ) )
pto - > PushMessage ( " inv " , vInv ) ;
//
// Message: getdata
//
vector < CInv > vGetData ;
2011-12-21 22:33:19 +01:00
int64 nNow = GetTime ( ) * 1000000 ;
2010-08-29 18:58:15 +02:00
CTxDB txdb ( " r " ) ;
while ( ! pto - > mapAskFor . empty ( ) & & ( * pto - > mapAskFor . begin ( ) ) . first < = nNow )
{
const CInv & inv = ( * pto - > mapAskFor . begin ( ) ) . second ;
if ( ! AlreadyHave ( txdb , inv ) )
{
printf ( " sending getdata: %s \n " , inv . ToString ( ) . c_str ( ) ) ;
vGetData . push_back ( inv ) ;
if ( vGetData . size ( ) > = 1000 )
{
pto - > PushMessage ( " getdata " , vGetData ) ;
vGetData . clear ( ) ;
}
}
2011-07-21 22:06:20 +02:00
mapAlreadyAskedFor [ inv ] = nNow ;
2010-08-29 18:58:15 +02:00
pto - > mapAskFor . erase ( pto - > mapAskFor . begin ( ) ) ;
}
if ( ! vGetData . empty ( ) )
pto - > PushMessage ( " getdata " , vGetData ) ;
}
return true ;
}
//////////////////////////////////////////////////////////////////////////////
//
// BitcoinMiner
//
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
int static FormatHashBlocks ( void * pbuffer , unsigned int len )
2010-09-14 00:14:24 +02:00
{
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 } ;
2011-09-27 20:16:07 +02:00
void SHA256Transform ( void * pstate , void * pinput , const void * pinit )
2010-09-14 00:14:24 +02:00
{
2011-09-27 20:16:07 +02:00
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 ] ;
2010-09-14 00:14:24 +02:00
}
//
// ScanHash scans nonces looking for a hash with at least some zero bits.
// It operates on big endian data. Caller does the byte reversing.
// All input buffers are 16-byte aligned. nNonce is usually preserved
2010-11-23 20:16:36 +01:00
// between calls, but periodically or if nNonce is 0xffff0000 or above,
2010-09-14 00:14:24 +02:00
// the block is rebuilt and nNonce starts over at zero.
//
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
unsigned int static ScanHash_CryptoPP ( char * pmidstate , char * pdata , char * phash1 , char * phash , unsigned int & nHashesDone )
2010-09-14 00:14:24 +02:00
{
2010-11-23 20:16:36 +01:00
unsigned int & nNonce = * ( unsigned int * ) ( pdata + 12 ) ;
2010-09-14 00:14:24 +02:00
for ( ; ; )
{
// Crypto++ SHA-256
2010-11-23 20:16:36 +01:00
// Hash pdata using pmidstate as the starting state into
2010-09-14 00:14:24 +02:00
// preformatted buffer phash1, then hash phash1 into phash
nNonce + + ;
2010-11-23 20:16:36 +01:00
SHA256Transform ( phash1 , pdata , pmidstate ) ;
2010-09-14 00:14:24 +02:00
SHA256Transform ( phash , phash1 , pSHA256InitState ) ;
// Return the nonce if the hash has at least some zero bits,
// caller will check if it has enough to reach the target
if ( ( ( unsigned short * ) phash ) [ 14 ] = = 0 )
return nNonce ;
// If nothing found after trying for a while, return -1
if ( ( nNonce & 0xffff ) = = 0 )
{
nHashesDone = 0xffff + 1 ;
return - 1 ;
}
}
}
2011-08-16 02:33:00 +02:00
// Some explaining would be appreciated
2010-11-19 21:22:46 +01:00
class COrphan
{
public :
CTransaction * ptx ;
set < uint256 > setDependsOn ;
double dPriority ;
COrphan ( CTransaction * ptxIn )
{
ptx = ptxIn ;
dPriority = 0 ;
}
void print ( ) const
{
printf ( " COrphan(hash=%s, dPriority=%.1f) \n " , ptx - > GetHash ( ) . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) , dPriority ) ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( uint256 hash , setDependsOn )
2010-11-19 21:22:46 +01:00
printf ( " setDependsOn %s \n " , hash . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) ) ;
}
} ;
2011-05-27 06:02:51 +02:00
uint64 nLastBlockTx = 0 ;
uint64 nLastBlockSize = 0 ;
2010-11-23 20:16:36 +01:00
CBlock * CreateNewBlock ( CReserveKey & reservekey )
{
CBlockIndex * pindexPrev = pindexBest ;
// Create new block
auto_ptr < CBlock > pblock ( new CBlock ( ) ) ;
if ( ! pblock . get ( ) )
return NULL ;
// Create coinbase tx
CTransaction txNew ;
txNew . vin . resize ( 1 ) ;
txNew . vin [ 0 ] . prevout . SetNull ( ) ;
txNew . vout . resize ( 1 ) ;
txNew . vout [ 0 ] . scriptPubKey < < reservekey . GetReservedKey ( ) < < OP_CHECKSIG ;
// Add our coinbase tx as first transaction
pblock - > vtx . push_back ( txNew ) ;
// Collect memory pool transactions into the block
2011-12-21 22:33:19 +01:00
int64 nFees = 0 ;
2010-11-23 20:16:36 +01:00
{
2012-04-06 18:39:12 +02:00
LOCK2 ( cs_main , cs_mapTransactions ) ;
2010-11-23 20:16:36 +01:00
CTxDB txdb ( " r " ) ;
// Priority order to process transactions
list < COrphan > vOrphan ; // list memory doesn't move
map < uint256 , vector < COrphan * > > mapDependers ;
multimap < double , CTransaction * > mapPriority ;
for ( map < uint256 , CTransaction > : : iterator mi = mapTransactions . begin ( ) ; mi ! = mapTransactions . end ( ) ; + + mi )
{
CTransaction & tx = ( * mi ) . second ;
if ( tx . IsCoinBase ( ) | | ! tx . IsFinal ( ) )
continue ;
COrphan * porphan = NULL ;
double dPriority = 0 ;
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
2010-11-23 20:16:36 +01:00
{
// Read prev transaction
CTransaction txPrev ;
CTxIndex txindex ;
if ( ! txPrev . ReadFromDisk ( txdb , txin . prevout , txindex ) )
{
// Has to wait for dependencies
if ( ! porphan )
{
// Use list for automatic deletion
vOrphan . push_back ( COrphan ( & tx ) ) ;
porphan = & vOrphan . back ( ) ;
}
mapDependers [ txin . prevout . hash ] . push_back ( porphan ) ;
porphan - > setDependsOn . insert ( txin . prevout . hash ) ;
continue ;
}
2011-12-21 22:33:19 +01:00
int64 nValueIn = txPrev . vout [ txin . prevout . n ] . nValue ;
2010-11-23 20:16:36 +01:00
// Read block header
2011-03-02 22:27:24 +01:00
int nConf = txindex . GetDepthInMainChain ( ) ;
2010-11-23 20:16:36 +01:00
dPriority + = ( double ) nValueIn * nConf ;
2010-12-03 20:38:09 +01:00
if ( fDebug & & GetBoolArg ( " -printpriority " ) )
2010-11-23 20:16:36 +01:00
printf ( " priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f \n " , nValueIn , nConf , dPriority ) ;
}
// Priority is sum(valuein * age) / txsize
2012-04-16 14:56:45 +02:00
dPriority / = : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ;
2010-11-23 20:16:36 +01:00
if ( porphan )
porphan - > dPriority = dPriority ;
else
mapPriority . insert ( make_pair ( - dPriority , & ( * mi ) . second ) ) ;
2010-12-03 20:38:09 +01:00
if ( fDebug & & GetBoolArg ( " -printpriority " ) )
2010-11-23 20:16:36 +01:00
{
printf ( " priority %-20.1f %s \n %s " , dPriority , tx . GetHash ( ) . ToString ( ) . substr ( 0 , 10 ) . c_str ( ) , tx . ToString ( ) . c_str ( ) ) ;
if ( porphan )
porphan - > print ( ) ;
printf ( " \n " ) ;
}
}
// Collect transactions into block
map < uint256 , CTxIndex > mapTestPool ;
2011-12-21 22:33:19 +01:00
uint64 nBlockSize = 1000 ;
2011-05-27 06:02:51 +02:00
uint64 nBlockTx = 0 ;
2012-01-20 23:07:40 +01:00
int nBlockSigOps = 100 ;
2010-11-23 20:16:36 +01:00
while ( ! mapPriority . empty ( ) )
{
// Take highest priority transaction off priority queue
double dPriority = - ( * mapPriority . begin ( ) ) . first ;
CTransaction & tx = * ( * mapPriority . begin ( ) ) . second ;
mapPriority . erase ( mapPriority . begin ( ) ) ;
// Size limits
2012-04-16 14:56:45 +02:00
unsigned int nTxSize = : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ;
2010-11-23 20:16:36 +01:00
if ( nBlockSize + nTxSize > = MAX_BLOCK_SIZE_GEN )
continue ;
2012-01-05 03:40:52 +01:00
// Legacy limits on sigOps:
2012-01-20 23:07:40 +01:00
int nTxSigOps = tx . GetLegacySigOpCount ( ) ;
if ( nBlockSigOps + nTxSigOps > = MAX_BLOCK_SIGOPS )
2012-01-05 03:40:52 +01:00
continue ;
2010-11-23 20:16:36 +01:00
// Transaction fee required depends on block size
2011-03-02 22:27:24 +01:00
bool fAllowFree = ( nBlockSize + nTxSize < 4000 | | CTransaction : : AllowFree ( dPriority ) ) ;
2011-12-21 22:33:19 +01:00
int64 nMinFee = tx . GetMinFee ( nBlockSize , fAllowFree , GMF_BLOCK ) ;
2010-11-23 20:16:36 +01:00
// Connecting shouldn't fail due to dependency on other memory pool transactions
// because we're already processing them in order of dependency
map < uint256 , CTxIndex > mapTestPoolTmp ( mapTestPool ) ;
2012-01-11 02:18:00 +01:00
MapPrevTx mapInputs ;
2012-01-18 19:36:44 +01:00
bool fInvalid ;
if ( ! tx . FetchInputs ( txdb , mapTestPoolTmp , false , true , mapInputs , fInvalid ) )
2011-10-03 19:05:43 +02:00
continue ;
2012-01-05 03:40:52 +01:00
2012-01-28 16:16:21 +01:00
int64 nTxFees = tx . GetValueIn ( mapInputs ) - tx . GetValueOut ( ) ;
if ( nTxFees < nMinFee )
2011-10-03 19:05:43 +02:00
continue ;
2012-01-11 02:18:00 +01:00
2012-01-20 23:07:40 +01:00
nTxSigOps + = tx . GetP2SHSigOpCount ( mapInputs ) ;
if ( nBlockSigOps + nTxSigOps > = MAX_BLOCK_SIGOPS )
2010-11-23 20:16:36 +01:00
continue ;
2012-01-11 02:18:00 +01:00
if ( ! tx . ConnectInputs ( mapInputs , mapTestPoolTmp , CDiskTxPos ( 1 , 1 , 1 ) , pindexPrev , false , true ) )
continue ;
2012-01-11 02:45:55 +01:00
mapTestPoolTmp [ tx . GetHash ( ) ] = CTxIndex ( CDiskTxPos ( 1 , 1 , 1 ) , tx . vout . size ( ) ) ;
2010-11-23 20:16:36 +01:00
swap ( mapTestPool , mapTestPoolTmp ) ;
// Added
pblock - > vtx . push_back ( tx ) ;
nBlockSize + = nTxSize ;
2011-05-27 06:02:51 +02:00
+ + nBlockTx ;
2012-01-20 23:07:40 +01:00
nBlockSigOps + = nTxSigOps ;
2012-01-28 16:16:21 +01:00
nFees + = nTxFees ;
2010-11-23 20:16:36 +01:00
// Add transactions that depend on this one to the priority queue
uint256 hash = tx . GetHash ( ) ;
if ( mapDependers . count ( hash ) )
{
2011-05-15 09:11:04 +02:00
BOOST_FOREACH ( COrphan * porphan , mapDependers [ hash ] )
2010-11-23 20:16:36 +01:00
{
if ( ! porphan - > setDependsOn . empty ( ) )
{
porphan - > setDependsOn . erase ( hash ) ;
if ( porphan - > setDependsOn . empty ( ) )
mapPriority . insert ( make_pair ( - porphan - > dPriority , porphan - > ptx ) ) ;
}
}
}
}
2011-05-27 06:02:51 +02:00
nLastBlockTx = nBlockTx ;
nLastBlockSize = nBlockSize ;
printf ( " CreateNewBlock(): total size %lu \n " , nBlockSize ) ;
2010-11-23 20:16:36 +01:00
}
pblock - > vtx [ 0 ] . vout [ 0 ] . nValue = GetBlockValue ( pindexPrev - > nHeight + 1 , nFees ) ;
// Fill in header
pblock - > hashPrevBlock = pindexPrev - > GetBlockHash ( ) ;
pblock - > hashMerkleRoot = pblock - > BuildMerkleTree ( ) ;
2012-02-16 16:22:31 +01:00
pblock - > UpdateTime ( pindexPrev ) ;
2011-12-05 21:50:22 +01:00
pblock - > nBits = GetNextWorkRequired ( pindexPrev , pblock . get ( ) ) ;
2010-11-23 20:16:36 +01:00
pblock - > nNonce = 0 ;
return pblock . release ( ) ;
}
2011-09-06 22:39:05 +02:00
void IncrementExtraNonce ( CBlock * pblock , CBlockIndex * pindexPrev , unsigned int & nExtraNonce )
2010-11-23 20:16:36 +01:00
{
// Update nExtraNonce
2011-06-13 02:16:54 +02:00
static uint256 hashPrevBlock ;
if ( hashPrevBlock ! = pblock - > hashPrevBlock )
2010-11-23 20:16:36 +01:00
{
2011-06-13 02:16:54 +02:00
nExtraNonce = 0 ;
hashPrevBlock = pblock - > hashPrevBlock ;
2010-11-23 20:16:36 +01:00
}
2011-06-13 02:16:54 +02:00
+ + nExtraNonce ;
2012-01-15 00:51:52 +01:00
pblock - > vtx [ 0 ] . vin [ 0 ] . scriptSig = ( CScript ( ) < < pblock - > nTime < < CBigNum ( nExtraNonce ) ) + COINBASE_FLAGS ;
2011-10-13 22:03:58 +02:00
assert ( pblock - > vtx [ 0 ] . vin [ 0 ] . scriptSig . size ( ) < = 100 ) ;
2010-11-23 20:16:36 +01:00
pblock - > hashMerkleRoot = pblock - > BuildMerkleTree ( ) ;
}
void FormatHashBuffers ( CBlock * pblock , char * pmidstate , char * pdata , char * phash1 )
{
//
// Prebuild 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
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < sizeof ( tmp ) / 4 ; i + + )
2010-11-23 20:16:36 +01:00
( ( 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 ) ;
}
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
bool CheckWork ( CBlock * pblock , CWallet & wallet , CReserveKey & reservekey )
2010-11-23 20:16:36 +01:00
{
uint256 hash = pblock - > GetHash ( ) ;
uint256 hashTarget = CBigNum ( ) . SetCompact ( pblock - > nBits ) . getuint256 ( ) ;
if ( hash > hashTarget )
return false ;
//// debug print
printf ( " BitcoinMiner: \n " ) ;
printf ( " proof-of-work found \n hash: %s \n target: %s \n " , hash . GetHex ( ) . c_str ( ) , hashTarget . GetHex ( ) . c_str ( ) ) ;
pblock - > print ( ) ;
printf ( " %s " , DateTimeStrFormat ( " %x %H:%M " , GetTime ( ) ) . c_str ( ) ) ;
printf ( " generated %s \n " , FormatMoney ( pblock - > vtx [ 0 ] . vout [ 0 ] . nValue ) . c_str ( ) ) ;
// Found a solution
{
2012-04-06 18:39:12 +02:00
LOCK ( cs_main ) ;
2010-11-23 20:16:36 +01:00
if ( pblock - > hashPrevBlock ! = hashBestChain )
return error ( " BitcoinMiner : generated block is stale " ) ;
// Remove key from key pool
reservekey . KeepKey ( ) ;
// Track how many getdata requests this block gets
2012-04-06 18:39:12 +02:00
{
LOCK ( wallet . cs_wallet ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
wallet . mapRequestCount [ pblock - > GetHash ( ) ] = 0 ;
2012-04-06 18:39:12 +02:00
}
2010-11-23 20:16:36 +01:00
// Process this block the same as if we had received it from another node
if ( ! ProcessBlock ( NULL , pblock ) )
return error ( " BitcoinMiner : ProcessBlock, block not accepted " ) ;
}
return true ;
}
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static ThreadBitcoinMiner ( void * parg ) ;
2012-02-16 21:00:16 +01:00
static bool fGenerateBitcoins = false ;
static bool fLimitProcessors = false ;
static int nLimitProcessors = - 1 ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static BitcoinMiner ( CWallet * pwallet )
2010-08-29 18:58:15 +02:00
{
printf ( " BitcoinMiner started \n " ) ;
SetThreadPriority ( THREAD_PRIORITY_LOWEST ) ;
2010-11-23 20:16:36 +01:00
// Each thread has its own key and counter
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
CReserveKey reservekey ( pwallet ) ;
2010-10-19 19:16:51 +02:00
unsigned int nExtraNonce = 0 ;
2010-11-23 20:16:36 +01:00
2010-08-29 18:58:15 +02:00
while ( fGenerateBitcoins )
{
if ( fShutdown )
return ;
while ( vNodes . empty ( ) | | IsInitialBlockDownload ( ) )
{
Sleep ( 1000 ) ;
if ( fShutdown )
return ;
if ( ! fGenerateBitcoins )
return ;
}
//
// Create new block
//
2010-11-23 20:16:36 +01:00
unsigned int nTransactionsUpdatedLast = nTransactionsUpdated ;
CBlockIndex * pindexPrev = pindexBest ;
auto_ptr < CBlock > pblock ( CreateNewBlock ( reservekey ) ) ;
2010-08-29 18:58:15 +02:00
if ( ! pblock . get ( ) )
return ;
2011-09-06 22:39:05 +02:00
IncrementExtraNonce ( pblock . get ( ) , pindexPrev , nExtraNonce ) ;
2010-08-29 18:58:15 +02:00
printf ( " Running BitcoinMiner with %d transactions in block \n " , pblock - > vtx . size ( ) ) ;
//
2010-11-23 20:16:36 +01:00
// Prebuild hash buffers
2010-08-29 18:58:15 +02:00
//
2010-11-23 20:16:36 +01:00
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 ) ;
FormatHashBuffers ( pblock . get ( ) , pmidstate , pdata , phash1 ) ;
unsigned int & nBlockTime = * ( unsigned int * ) ( pdata + 64 + 4 ) ;
2012-02-16 16:22:31 +01:00
unsigned int & nBlockBits = * ( unsigned int * ) ( pdata + 64 + 8 ) ;
2010-11-23 20:16:36 +01:00
unsigned int & nBlockNonce = * ( unsigned int * ) ( pdata + 64 + 12 ) ;
2010-08-29 18:58:15 +02:00
//
// Search
//
2011-12-21 22:33:19 +01:00
int64 nStart = GetTime ( ) ;
2010-08-29 18:58:15 +02:00
uint256 hashTarget = CBigNum ( ) . SetCompact ( pblock - > nBits ) . getuint256 ( ) ;
uint256 hashbuf [ 2 ] ;
uint256 & hash = * alignup < 16 > ( hashbuf ) ;
loop
{
2010-09-14 00:14:24 +02:00
unsigned int nHashesDone = 0 ;
unsigned int nNonceFound ;
2011-04-03 20:21:52 +02:00
// Crypto++ SHA-256
nNonceFound = ScanHash_CryptoPP ( pmidstate , pdata + 64 , phash1 ,
( char * ) & hash , nHashesDone ) ;
2010-08-29 18:58:15 +02:00
2010-09-14 00:14:24 +02:00
// Check if something found
if ( nNonceFound ! = - 1 )
2010-08-29 18:58:15 +02:00
{
2012-04-15 22:52:09 +02:00
for ( unsigned int i = 0 ; i < sizeof ( hash ) / 4 ; i + + )
2010-08-29 18:58:15 +02:00
( ( unsigned int * ) & hash ) [ i ] = ByteReverse ( ( ( unsigned int * ) & hash ) [ i ] ) ;
if ( hash < = hashTarget )
{
2010-09-14 00:14:24 +02:00
// Found a solution
pblock - > nNonce = ByteReverse ( nNonceFound ) ;
2010-08-29 18:58:15 +02:00
assert ( hash = = pblock - > GetHash ( ) ) ;
SetThreadPriority ( THREAD_PRIORITY_NORMAL ) ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
CheckWork ( pblock . get ( ) , * pwalletMain , reservekey ) ;
2010-08-29 18:58:15 +02:00
SetThreadPriority ( THREAD_PRIORITY_LOWEST ) ;
break ;
}
}
2010-09-14 00:14:24 +02:00
// Meter hashes/sec
2011-12-21 22:33:19 +01:00
static int64 nHashCounter ;
2010-09-14 00:14:24 +02:00
if ( nHPSTimerStart = = 0 )
2010-08-29 18:58:15 +02:00
{
2010-09-14 00:14:24 +02:00
nHPSTimerStart = GetTimeMillis ( ) ;
nHashCounter = 0 ;
}
else
nHashCounter + = nHashesDone ;
if ( GetTimeMillis ( ) - nHPSTimerStart > 4000 )
{
static CCriticalSection cs ;
2010-08-29 18:58:15 +02:00
{
2012-04-06 18:39:12 +02:00
LOCK ( cs ) ;
2010-09-14 00:14:24 +02:00
if ( GetTimeMillis ( ) - nHPSTimerStart > 4000 )
2010-08-29 18:58:15 +02:00
{
2010-09-14 00:14:24 +02:00
dHashesPerSec = 1000.0 * nHashCounter / ( GetTimeMillis ( ) - nHPSTimerStart ) ;
nHPSTimerStart = GetTimeMillis ( ) ;
nHashCounter = 0 ;
2011-12-21 22:33:19 +01:00
static int64 nLogTime ;
2010-09-14 00:14:24 +02:00
if ( GetTime ( ) - nLogTime > 30 * 60 )
2010-08-29 18:58:15 +02:00
{
2010-09-14 00:14:24 +02:00
nLogTime = GetTime ( ) ;
printf ( " %s " , DateTimeStrFormat ( " %x %H:%M " , GetTime ( ) ) . c_str ( ) ) ;
2012-02-07 19:42:29 +01:00
printf ( " hashmeter %3d CPUs %6.0f khash/s \n " , vnThreadsRunning [ THREAD_MINER ] , dHashesPerSec / 1000.0 ) ;
2010-08-29 18:58:15 +02:00
}
}
}
2010-09-14 00:14:24 +02:00
}
2010-08-29 18:58:15 +02:00
2010-09-14 00:14:24 +02:00
// Check for stop or if block needs to be rebuilt
if ( fShutdown )
return ;
if ( ! fGenerateBitcoins )
return ;
2012-02-07 19:42:29 +01:00
if ( fLimitProcessors & & vnThreadsRunning [ THREAD_MINER ] > nLimitProcessors )
2010-09-14 00:14:24 +02:00
return ;
if ( vNodes . empty ( ) )
break ;
2010-11-23 20:16:36 +01:00
if ( nBlockNonce > = 0xffff0000 )
2010-09-14 00:14:24 +02:00
break ;
if ( nTransactionsUpdated ! = nTransactionsUpdatedLast & & GetTime ( ) - nStart > 60 )
break ;
if ( pindexPrev ! = pindexBest )
break ;
2010-08-29 18:58:15 +02:00
2010-09-14 00:14:24 +02:00
// Update nTime every few seconds
2012-02-16 16:22:31 +01:00
pblock - > UpdateTime ( pindexPrev ) ;
2010-11-23 20:16:36 +01:00
nBlockTime = ByteReverse ( pblock - > nTime ) ;
2012-02-16 16:22:31 +01:00
if ( fTestNet )
{
// Changing pblock->nTime can change work required on testnet:
nBlockBits = ByteReverse ( pblock - > nBits ) ;
hashTarget = CBigNum ( ) . SetCompact ( pblock - > nBits ) . getuint256 ( ) ;
}
2010-08-29 18:58:15 +02:00
}
}
}
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void static ThreadBitcoinMiner ( void * parg )
2010-08-29 18:58:15 +02:00
{
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
CWallet * pwallet = ( CWallet * ) parg ;
2011-06-01 18:27:05 +02:00
try
2010-08-29 18:58:15 +02:00
{
2012-02-07 19:42:29 +01:00
vnThreadsRunning [ THREAD_MINER ] + + ;
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
BitcoinMiner ( pwallet ) ;
2012-02-07 19:42:29 +01:00
vnThreadsRunning [ THREAD_MINER ] - - ;
2011-03-17 22:54:20 +01:00
}
2011-06-01 18:27:05 +02:00
catch ( std : : exception & e ) {
2012-02-07 19:42:29 +01:00
vnThreadsRunning [ THREAD_MINER ] - - ;
2011-06-01 18:27:05 +02:00
PrintException ( & e , " ThreadBitcoinMiner() " ) ;
} catch ( . . . ) {
2012-02-07 19:42:29 +01:00
vnThreadsRunning [ THREAD_MINER ] - - ;
2011-06-01 18:27:05 +02:00
PrintException ( NULL , " ThreadBitcoinMiner() " ) ;
2010-08-29 18:58:15 +02:00
}
2011-06-01 18:27:05 +02:00
nHPSTimerStart = 0 ;
2012-02-07 19:42:29 +01:00
if ( vnThreadsRunning [ THREAD_MINER ] = = 0 )
2011-06-01 18:27:05 +02:00
dHashesPerSec = 0 ;
2012-02-07 19:42:29 +01:00
printf ( " ThreadBitcoinMiner exiting, %d threads remaining \n " , vnThreadsRunning [ THREAD_MINER ] ) ;
2010-11-09 20:47:07 +01:00
}
2010-08-29 18:58:15 +02:00
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
void GenerateBitcoins ( bool fGenerate , CWallet * pwallet )
2010-08-29 18:58:15 +02:00
{
2012-02-16 21:00:16 +01:00
fGenerateBitcoins = fGenerate ;
nLimitProcessors = GetArg ( " -genproclimit " , - 1 ) ;
if ( nLimitProcessors = = 0 )
fGenerateBitcoins = false ;
fLimitProcessors = ( nLimitProcessors ! = - 1 ) ;
if ( fGenerate )
2010-08-29 18:58:15 +02:00
{
2011-06-01 18:27:05 +02:00
int nProcessors = boost : : thread : : hardware_concurrency ( ) ;
printf ( " %d processors \n " , nProcessors ) ;
if ( nProcessors < 1 )
nProcessors = 1 ;
if ( fLimitProcessors & & nProcessors > nLimitProcessors )
nProcessors = nLimitProcessors ;
2012-02-07 19:42:29 +01:00
int nAddThreads = nProcessors - vnThreadsRunning [ THREAD_MINER ] ;
2011-06-01 18:27:05 +02:00
printf ( " Starting %d BitcoinMiner threads \n " , nAddThreads ) ;
for ( int i = 0 ; i < nAddThreads ; i + + )
2010-08-29 18:58:15 +02:00
{
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore.
* A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around.
* Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter
* CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions.
* Some code was moved from CWalletDB to CWallet, such as handling of reserve keys.
* Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument.
* The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable.
* Functions in main.cpp and db.cpp that are not used by other modules are marked static.
* The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
2011-06-01 18:28:20 +02:00
if ( ! CreateThread ( ThreadBitcoinMiner , pwallet ) )
2011-06-01 18:27:05 +02:00
printf ( " Error: CreateThread(ThreadBitcoinMiner) failed \n " ) ;
Sleep ( 10 ) ;
2010-08-29 18:58:15 +02:00
}
2011-04-05 04:24:35 +02:00
}
2010-08-29 18:58:15 +02:00
}