2010-08-29 09:58:15 -07:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2012-02-07 08:28:30 -08:00
// Copyright (c) 2009-2012 The Bitcoin developers
2010-08-29 09:58:15 -07:00
// Distributed under the MIT/X11 software license, see the accompanying
2012-05-18 07:02:28 -07:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2012-08-28 14:04:54 -07:00
# include "alert.h"
2011-09-08 13:50:58 -07:00
# include "checkpoints.h"
2011-05-14 13:57:34 -07:00
# include "db.h"
2012-09-03 12:14:03 -07:00
# include "txdb.h"
2011-05-14 14:20:30 -07:00
# include "net.h"
2011-05-15 14:52:31 -07:00
# include "init.h"
2012-04-15 13:10:54 -07:00
# include "ui_interface.h"
2012-12-01 14:04:14 -08:00
# include "checkqueue.h"
2012-01-03 12:24:28 -08:00
# include <boost/algorithm/string/replace.hpp>
2011-06-19 15:12:31 -07:00
# include <boost/filesystem.hpp>
2011-05-15 20:45:35 -07:00
# include <boost/filesystem/fstream.hpp>
2010-08-29 09:58:15 -07:00
2011-05-15 00:11:04 -07:00
using namespace std ;
using namespace boost ;
2010-08-29 09:58:15 -07: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 09:28:20 -07:00
CCriticalSection cs_setpwalletRegistered ;
set < CWallet * > setpwalletRegistered ;
2010-08-29 09:58:15 -07:00
CCriticalSection cs_main ;
2012-04-13 13:28:07 -07:00
CTxMemPool mempool ;
2010-08-29 09:58:15 -07:00
unsigned int nTransactionsUpdated = 0 ;
map < uint256 , CBlockIndex * > mapBlockIndex ;
2013-05-12 06:50:22 -07:00
std : : vector < CBlockIndex * > vBlockIndexByHeight ;
2010-10-19 10:16:51 -07:00
uint256 hashGenesisBlock ( " 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f " ) ;
2011-08-11 04:41:01 -07:00
static CBigNum bnProofOfWorkLimit ( ~ uint256 ( 0 ) > > 32 ) ;
2010-08-29 09:58:15 -07:00
CBlockIndex * pindexGenesisBlock = NULL ;
int nBestHeight = - 1 ;
2013-03-28 15:51:50 -07:00
uint256 nBestChainWork = 0 ;
uint256 nBestInvalidWork = 0 ;
2010-08-29 09:58:15 -07:00
uint256 hashBestChain = 0 ;
CBlockIndex * pindexBest = NULL ;
2012-08-18 15:33:01 -07:00
set < CBlockIndex * , CBlockIndexWorkComparator > setBlockIndexValid ; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed
2011-12-21 13:33:19 -08:00
int64 nTimeBestReceived = 0 ;
2012-12-01 14:04:14 -08:00
int nScriptCheckThreads = 0 ;
2012-09-13 05:33:52 -07:00
bool fImporting = false ;
2012-10-21 12:23:13 -07:00
bool fReindex = false ;
2012-12-01 11:10:23 -08:00
bool fBenchmark = false ;
2013-01-10 16:47:57 -08:00
bool fTxIndex = false ;
2012-11-04 08:11:48 -08:00
unsigned int nCoinCacheSize = 5000 ;
2013-05-26 11:00:16 -07:00
bool fHaveGUI = false ;
2010-08-29 09:58:15 -07:00
2013-04-25 17:11:27 -07:00
/** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
int64 CTransaction : : nMinTxFee = 10000 ; // Override with -mintxfee
/** Fees smaller than this (in satoshi) are considered zero fee (for relaying) */
int64 CTransaction : : nMinRelayTxFee = 10000 ;
2013-01-03 13:13:24 -08:00
CMedianFilter < int > cPeerBlockCounts ( 8 , 0 ) ; // Amount of blocks that other nodes claim to have
2011-09-28 12:35:58 -07:00
2010-08-29 09:58:15 -07:00
map < uint256 , CBlock * > mapOrphanBlocks ;
multimap < uint256 , CBlock * > mapOrphanBlocksByPrev ;
map < uint256 , CDataStream * > mapOrphanTransactions ;
2012-05-15 12:53:30 -07:00
map < uint256 , map < uint256 , CDataStream * > > mapOrphanTransactionsByPrev ;
2010-08-29 09:58:15 -07:00
2012-02-06 12:48:00 -08:00
// Constant stuff for coinbase transactions we create:
CScript COINBASE_FLAGS ;
2010-08-29 09:58:15 -07:00
2011-12-23 07:14:57 -08:00
const string strMessageMagic = " Bitcoin Signed Message: \n " ;
2013-03-06 19:16:05 -08:00
double dHashesPerSec = 0.0 ;
int64 nHPSTimerStart = 0 ;
2010-08-29 09:58:15 -07:00
// Settings
2011-12-21 13:33:19 -08:00
int64 nTransactionFee = 0 ;
2012-02-16 12:00:16 -08:00
2011-03-26 05:01:27 -07:00
2010-08-29 09:58:15 -07: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 09:28:20 -07:00
//////////////////////////////////////////////////////////////////////////////
//
// dispatching functions
//
2011-11-06 15:05:42 -08: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 09:28:20 -07:00
void RegisterWallet ( CWallet * pwalletIn )
{
{
2012-04-06 09:39:12 -07: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 09:28:20 -07:00
setpwalletRegistered . insert ( pwalletIn ) ;
}
}
void UnregisterWallet ( CWallet * pwalletIn )
{
{
2012-04-06 09:39:12 -07: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 09:28:20 -07:00
setpwalletRegistered . erase ( pwalletIn ) ;
}
}
2011-11-06 15:05:42 -08: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 09:28:20 -07: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-06 15:05:42 -08: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 09:28:20 -07:00
void static EraseFromWallets ( uint256 hash )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > EraseFromWallet ( hash ) ;
}
2011-11-06 15:05:42 -08:00
// make sure all wallets know about the given transaction, in the given block
2012-07-07 15:06:34 -07:00
void SyncWithWallets ( const uint256 & hash , const CTransaction & tx , const CBlock * pblock , bool fUpdate )
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 09:28:20 -07:00
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
2012-07-07 15:06:34 -07:00
pwallet - > AddToWalletIfInvolvingMe ( hash , tx , pblock , fUpdate ) ;
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 09:28:20 -07:00
}
2011-11-06 15:05:42 -08: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 09:28:20 -07:00
void static SetBestChain ( const CBlockLocator & loc )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > SetBestChain ( loc ) ;
}
2011-11-06 15:05:42 -08: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 09:28:20 -07:00
void static UpdatedTransaction ( const uint256 & hashTx )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > UpdatedTransaction ( hashTx ) ;
}
2011-11-06 15:05:42 -08: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 09:28:20 -07:00
void static PrintWallets ( const CBlock & block )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > PrintWallet ( block ) ;
}
2011-11-06 15:05:42 -08: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 09:28:20 -07:00
void static Inventory ( const uint256 & hash )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > Inventory ( hash ) ;
}
2011-11-06 15:05:42 -08: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 09:28:20 -07:00
void static ResendWalletTransactions ( )
{
BOOST_FOREACH ( CWallet * pwallet , setpwalletRegistered )
pwallet - > ResendWalletTransactions ( ) ;
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
//////////////////////////////////////////////////////////////////////////////
//
// CCoinsView implementations
//
2013-01-20 09:05:34 -08:00
bool CCoinsView : : GetCoins ( const uint256 & txid , CCoins & coins ) { return false ; }
bool CCoinsView : : SetCoins ( const uint256 & txid , const CCoins & coins ) { return false ; }
bool CCoinsView : : HaveCoins ( const uint256 & txid ) { return false ; }
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CBlockIndex * CCoinsView : : GetBestBlock ( ) { return NULL ; }
bool CCoinsView : : SetBestBlock ( CBlockIndex * pindex ) { return false ; }
2012-07-06 07:33:34 -07:00
bool CCoinsView : : BatchWrite ( const std : : map < uint256 , CCoins > & mapCoins , CBlockIndex * pindex ) { return false ; }
2012-09-25 14:04:54 -07:00
bool CCoinsView : : GetStats ( CCoinsStats & stats ) { return false ; }
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
2012-07-08 10:04:05 -07:00
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CCoinsViewBacked : : CCoinsViewBacked ( CCoinsView & viewIn ) : base ( & viewIn ) { }
2013-01-20 09:05:34 -08:00
bool CCoinsViewBacked : : GetCoins ( const uint256 & txid , CCoins & coins ) { return base - > GetCoins ( txid , coins ) ; }
bool CCoinsViewBacked : : SetCoins ( const uint256 & txid , const CCoins & coins ) { return base - > SetCoins ( txid , coins ) ; }
bool CCoinsViewBacked : : HaveCoins ( const uint256 & txid ) { return base - > HaveCoins ( txid ) ; }
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CBlockIndex * CCoinsViewBacked : : GetBestBlock ( ) { return base - > GetBestBlock ( ) ; }
bool CCoinsViewBacked : : SetBestBlock ( CBlockIndex * pindex ) { return base - > SetBestBlock ( pindex ) ; }
void CCoinsViewBacked : : SetBackend ( CCoinsView & viewIn ) { base = & viewIn ; }
2012-07-06 07:33:34 -07:00
bool CCoinsViewBacked : : BatchWrite ( const std : : map < uint256 , CCoins > & mapCoins , CBlockIndex * pindex ) { return base - > BatchWrite ( mapCoins , pindex ) ; }
2012-09-25 14:04:54 -07:00
bool CCoinsViewBacked : : GetStats ( CCoinsStats & stats ) { return base - > GetStats ( stats ) ; }
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CCoinsViewCache : : CCoinsViewCache ( CCoinsView & baseIn , bool fDummy ) : CCoinsViewBacked ( baseIn ) , pindexTip ( NULL ) { }
2013-01-20 09:05:34 -08:00
bool CCoinsViewCache : : GetCoins ( const uint256 & txid , CCoins & coins ) {
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( cacheCoins . count ( txid ) ) {
coins = cacheCoins [ txid ] ;
return true ;
}
if ( base - > GetCoins ( txid , coins ) ) {
cacheCoins [ txid ] = coins ;
return true ;
}
return false ;
}
2013-01-20 09:05:34 -08:00
std : : map < uint256 , CCoins > : : iterator CCoinsViewCache : : FetchCoins ( const uint256 & txid ) {
std : : map < uint256 , CCoins > : : iterator it = cacheCoins . lower_bound ( txid ) ;
if ( it ! = cacheCoins . end ( ) & & it - > first = = txid )
2012-07-08 10:04:05 -07:00
return it ;
CCoins tmp ;
if ( ! base - > GetCoins ( txid , tmp ) )
2013-01-20 09:05:34 -08:00
return cacheCoins . end ( ) ;
std : : map < uint256 , CCoins > : : iterator ret = cacheCoins . insert ( it , std : : make_pair ( txid , CCoins ( ) ) ) ;
tmp . swap ( ret - > second ) ;
return ret ;
2012-07-08 10:04:05 -07:00
}
2013-01-20 09:05:34 -08:00
CCoins & CCoinsViewCache : : GetCoins ( const uint256 & txid ) {
2012-07-08 10:04:05 -07:00
std : : map < uint256 , CCoins > : : iterator it = FetchCoins ( txid ) ;
assert ( it ! = cacheCoins . end ( ) ) ;
return it - > second ;
}
2013-01-20 09:05:34 -08:00
bool CCoinsViewCache : : SetCoins ( const uint256 & txid , const CCoins & coins ) {
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
cacheCoins [ txid ] = coins ;
return true ;
}
2013-01-20 09:05:34 -08:00
bool CCoinsViewCache : : HaveCoins ( const uint256 & txid ) {
2012-07-08 10:04:05 -07:00
return FetchCoins ( txid ) ! = cacheCoins . end ( ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
CBlockIndex * CCoinsViewCache : : GetBestBlock ( ) {
if ( pindexTip = = NULL )
pindexTip = base - > GetBestBlock ( ) ;
return pindexTip ;
}
bool CCoinsViewCache : : SetBestBlock ( CBlockIndex * pindex ) {
pindexTip = pindex ;
return true ;
}
2012-07-06 07:33:34 -07:00
bool CCoinsViewCache : : BatchWrite ( const std : : map < uint256 , CCoins > & mapCoins , CBlockIndex * pindex ) {
for ( std : : map < uint256 , CCoins > : : const_iterator it = mapCoins . begin ( ) ; it ! = mapCoins . end ( ) ; it + + )
cacheCoins [ it - > first ] = it - > second ;
pindexTip = pindex ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
return true ;
}
2012-07-06 07:33:34 -07:00
bool CCoinsViewCache : : Flush ( ) {
bool fOk = base - > BatchWrite ( cacheCoins , pindexTip ) ;
if ( fOk )
cacheCoins . clear ( ) ;
return fOk ;
}
unsigned int CCoinsViewCache : : GetCacheSize ( ) {
return cacheCoins . size ( ) ;
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
/** CCoinsView that brings transactions from a memorypool into view.
It does not check for spendings by memory pool transactions . */
CCoinsViewMemPool : : CCoinsViewMemPool ( CCoinsView & baseIn , CTxMemPool & mempoolIn ) : CCoinsViewBacked ( baseIn ) , mempool ( mempoolIn ) { }
2013-01-20 09:05:34 -08:00
bool CCoinsViewMemPool : : GetCoins ( const uint256 & txid , CCoins & coins ) {
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( base - > GetCoins ( txid , coins ) )
return true ;
if ( mempool . exists ( txid ) ) {
const CTransaction & tx = mempool . lookup ( txid ) ;
coins = CCoins ( tx , MEMPOOL_HEIGHT ) ;
return true ;
}
return false ;
}
2013-01-20 09:05:34 -08:00
bool CCoinsViewMemPool : : HaveCoins ( const uint256 & txid ) {
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
return mempool . exists ( txid ) | | base - > HaveCoins ( txid ) ;
}
2012-07-06 07:33:34 -07:00
CCoinsViewCache * pcoinsTip = NULL ;
2012-09-03 06:26:57 -07:00
CBlockTreeDB * pblocktree = NULL ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
2010-08-29 09:58:15 -07:00
//////////////////////////////////////////////////////////////////////////////
//
// mapOrphanTransactions
//
2012-05-15 12:53:30 -07:00
bool AddOrphanTx ( const CDataStream & vMsg )
2010-08-29 09:58:15 -07:00
{
CTransaction tx ;
CDataStream ( vMsg ) > > tx ;
uint256 hash = tx . GetHash ( ) ;
if ( mapOrphanTransactions . count ( hash ) )
2012-05-15 12:53:30 -07:00
return false ;
CDataStream * pvMsg = new CDataStream ( vMsg ) ;
2012-02-29 07:14:18 -08:00
2012-05-15 12:53:30 -07:00
// Ignore big transactions, to avoid a
// send-big-orphans memory exhaustion attack. If a peer has a legitimate
// large transaction with a missing parent then we assume
// it will rebroadcast it later, after the parent transaction(s)
// have been mined or received.
// 10,000 orphans, each of which is at most 5,000 bytes big is
// at most 500 megabytes of orphans:
if ( pvMsg - > size ( ) > 5000 )
{
2013-04-06 18:40:33 -07:00
printf ( " ignoring large orphan tx (size: % " PRIszu " , hash: %s) \n " , pvMsg - > size ( ) , hash . ToString ( ) . c_str ( ) ) ;
2012-06-19 12:50:12 -07:00
delete pvMsg ;
2012-05-15 12:53:30 -07:00
return false ;
}
2012-02-29 07:14:18 -08:00
2012-05-15 12:53:30 -07:00
mapOrphanTransactions [ hash ] = pvMsg ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
2012-05-15 12:53:30 -07:00
mapOrphanTransactionsByPrev [ txin . prevout . hash ] . insert ( make_pair ( hash , pvMsg ) ) ;
2013-04-06 18:40:33 -07:00
printf ( " stored orphan tx %s (mapsz % " PRIszu " ) \n " , hash . ToString ( ) . c_str ( ) ,
2012-05-15 12:53:30 -07:00
mapOrphanTransactions . size ( ) ) ;
return true ;
2010-08-29 09:58:15 -07: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 09:28:20 -07:00
void static EraseOrphanTx ( uint256 hash )
2010-08-29 09:58:15 -07:00
{
if ( ! mapOrphanTransactions . count ( hash ) )
return ;
const CDataStream * pvMsg = mapOrphanTransactions [ hash ] ;
CTransaction tx ;
CDataStream ( * pvMsg ) > > tx ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
2010-08-29 09:58:15 -07:00
{
2012-05-15 12:53:30 -07:00
mapOrphanTransactionsByPrev [ txin . prevout . hash ] . erase ( hash ) ;
if ( mapOrphanTransactionsByPrev [ txin . prevout . hash ] . empty ( ) )
mapOrphanTransactionsByPrev . erase ( txin . prevout . hash ) ;
2010-08-29 09:58:15 -07:00
}
delete pvMsg ;
mapOrphanTransactions . erase ( hash ) ;
}
2012-04-23 11:14:03 -07:00
unsigned int LimitOrphanTxSize ( unsigned int nMaxOrphans )
2012-02-29 07:14:18 -08:00
{
2012-04-23 11:14:03 -07:00
unsigned int nEvicted = 0 ;
2012-02-29 07:14:18 -08:00
while ( mapOrphanTransactions . size ( ) > nMaxOrphans )
{
// Evict a random orphan:
2012-05-17 09:13:14 -07:00
uint256 randomhash = GetRandHash ( ) ;
2012-02-29 07:14:18 -08:00
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 09:58:15 -07:00
//////////////////////////////////////////////////////////////////////////////
//
2013-04-25 17:11:27 -07:00
// CTransaction / CTxOut
2010-08-29 09:58:15 -07:00
//
2013-04-25 17:11:27 -07:00
bool CTxOut : : IsDust ( ) const
{
// "Dust" is defined in terms of CTransaction::nMinRelayTxFee,
// which has units satoshis-per-kilobyte.
// If you'd pay more than 1/3 in fees
// to spend something, then we consider it dust.
// A typical txout is 33 bytes big, and will
// need a CTxIn of at least 148 bytes to spend,
// so dust is a txout less than 54 uBTC
// (5430 satoshis) with default nMinRelayTxFee
return ( ( nValue * 1000 ) / ( 3 * ( ( int ) GetSerializeSize ( SER_DISK , 0 ) + 148 ) ) < CTransaction : : nMinRelayTxFee ) ;
}
2011-10-03 10:05:43 -07:00
bool CTransaction : : IsStandard ( ) const
{
2012-06-27 09:43:19 -07:00
if ( nVersion > CTransaction : : CURRENT_VERSION )
return false ;
2013-01-26 11:38:40 -08:00
if ( ! IsFinal ( ) )
return false ;
2013-02-04 13:56:26 -08:00
// Extremely large transactions with lots of inputs can cost the network
// almost as much to process as they cost the sender in fees, because
// computing signature hashes is O(ninputs*txsize). Limiting transactions
// to MAX_STANDARD_TX_SIZE mitigates CPU exhaustion attacks.
unsigned int sz = this - > GetSerializeSize ( SER_NETWORK , CTransaction : : CURRENT_VERSION ) ;
if ( sz > = MAX_STANDARD_TX_SIZE )
return false ;
2011-10-03 10:05:43 -07:00
BOOST_FOREACH ( const CTxIn & txin , vin )
{
2011-11-08 10:20:29 -08:00
// Biggest 'standard' txin is a 3-signature 3-of-3 CHECKMULTISIG
2012-01-04 18:40:52 -08:00
// pay-to-script-hash, which is 3 ~80-byte signatures, 3
2011-10-03 10:05:43 -07:00
// ~65-byte public keys, plus a few script ops.
2011-11-08 10:20:29 -08:00
if ( txin . scriptSig . size ( ) > 500 )
2012-01-04 18:40:52 -08:00
return false ;
2011-10-03 10:05:43 -07:00
if ( ! txin . scriptSig . IsPushOnly ( ) )
2012-01-04 18:40:52 -08:00
return false ;
2011-10-03 10:05:43 -07:00
}
2012-08-24 03:14:48 -07:00
BOOST_FOREACH ( const CTxOut & txout , vout ) {
2011-10-03 10:05:43 -07:00
if ( ! : : IsStandard ( txout . scriptPubKey ) )
2012-01-04 18:40:52 -08:00
return false ;
2013-04-24 15:27:00 -07:00
if ( txout . IsDust ( ) )
2012-08-24 03:14:48 -07:00
return false ;
}
2011-10-03 10:05:43 -07:00
return true ;
}
//
// Check transaction inputs, and make sure any
2012-01-04 18:40:52 -08:00
// pay-to-script-hash transactions are evaluating IsStandard scripts
2011-10-03 10:05:43 -07:00
//
// Why bother? To avoid denial-of-service attacks; an attacker
2012-01-04 18:40:52 -08: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 10:05:43 -07:00
// expensive-to-check-upon-redemption script like:
// DUP CHECKSIG DROP ... repeated 100 times... OP_1
//
2012-07-08 10:04:05 -07:00
bool CTransaction : : AreInputsStandard ( CCoinsViewCache & mapInputs ) const
2011-10-03 10:05:43 -07:00
{
2012-01-10 17:18:00 -08:00
if ( IsCoinBase ( ) )
2012-01-20 17:59:04 -08:00
return true ; // Coinbases don't use vin normally
2012-01-10 17:18:00 -08:00
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2011-10-03 10:05:43 -07:00
{
2012-01-10 17:18:00 -08:00
const CTxOut & prev = GetOutputFor ( vin [ i ] , mapInputs ) ;
2011-10-03 10:05:43 -07:00
vector < vector < unsigned char > > vSolutions ;
2011-11-08 10:20:29 -08:00
txnouttype whichType ;
// get the scriptPubKey corresponding to this input:
2012-01-10 17:18:00 -08:00
const CScript & prevScript = prev . scriptPubKey ;
2011-11-08 10:20:29 -08:00
if ( ! Solver ( prevScript , whichType , vSolutions ) )
2012-01-04 18:40:52 -08:00
return false ;
2012-01-19 10:30:54 -08:00
int nArgsExpected = ScriptSigArgsExpected ( whichType , vSolutions ) ;
2012-04-22 10:44:12 -07:00
if ( nArgsExpected < 0 )
return false ;
2012-01-19 10:30:54 -08:00
// 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 ;
2012-08-22 13:33:21 -07:00
if ( ! EvalScript ( stack , vin [ i ] . scriptSig , * this , i , false , 0 ) )
2012-01-19 10:30:54 -08:00
return false ;
2011-10-03 10:05:43 -07:00
if ( whichType = = TX_SCRIPTHASH )
{
2012-01-04 18:40:52 -08:00
if ( stack . empty ( ) )
2011-10-03 10:05:43 -07:00
return false ;
2011-11-08 10:20:29 -08:00
CScript subscript ( stack . back ( ) . begin ( ) , stack . back ( ) . end ( ) ) ;
2012-01-19 10:30:54 -08:00
vector < vector < unsigned char > > vSolutions2 ;
txnouttype whichType2 ;
if ( ! Solver ( subscript , whichType2 , vSolutions2 ) )
2012-01-04 18:40:52 -08:00
return false ;
2012-01-19 10:30:54 -08:00
if ( whichType2 = = TX_SCRIPTHASH )
return false ;
2012-04-22 10:44:12 -07:00
int tmpExpected ;
tmpExpected = ScriptSigArgsExpected ( whichType2 , vSolutions2 ) ;
if ( tmpExpected < 0 )
return false ;
nArgsExpected + = tmpExpected ;
2011-10-03 10:05:43 -07:00
}
2012-01-19 10:30:54 -08:00
2012-04-22 10:44:12 -07:00
if ( stack . size ( ) ! = ( unsigned int ) nArgsExpected )
2012-01-19 10:30:54 -08:00
return false ;
2011-10-03 10:05:43 -07:00
}
return true ;
}
2013-01-18 06:07:05 -08:00
unsigned int CTransaction : : GetLegacySigOpCount ( ) const
2012-01-04 18:40:52 -08:00
{
2012-04-23 11:14:03 -07:00
unsigned int nSigOps = 0 ;
2012-01-04 18:40:52 -08:00
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 09:58:15 -07:00
int CMerkleTx : : SetMerkleBranch ( const CBlock * pblock )
{
2013-01-09 10:39:52 -08:00
CBlock blockTmp ;
if ( pblock = = NULL ) {
CCoins coins ;
if ( pcoinsTip - > GetCoins ( GetHash ( ) , coins ) ) {
CBlockIndex * pindex = FindBlockByHeight ( coins . nHeight ) ;
if ( pindex ) {
if ( ! blockTmp . ReadFromDisk ( pindex ) )
return 0 ;
pblock = & blockTmp ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
2010-08-29 09:58:15 -07:00
}
2013-01-09 10:39:52 -08:00
}
2010-08-29 09:58:15 -07:00
2013-01-09 10:39:52 -08:00
if ( pblock ) {
2010-08-29 09:58:15 -07:00
// Update the tx's hashBlock
hashBlock = pblock - > GetHash ( ) ;
// Locate the transaction
2012-04-22 10:51:16 -07:00
for ( nIndex = 0 ; nIndex < ( int ) pblock - > vtx . size ( ) ; nIndex + + )
2010-08-29 09:58:15 -07:00
if ( pblock - > vtx [ nIndex ] = = * ( CTransaction * ) this )
break ;
2012-04-22 10:51:16 -07:00
if ( nIndex = = ( int ) pblock - > vtx . size ( ) )
2010-08-29 09:58:15 -07:00
{
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 ;
}
2013-01-26 15:14:11 -08:00
bool CTransaction : : CheckTransaction ( CValidationState & state ) const
2010-09-30 09:23:07 -07:00
{
// Basic checks that don't depend on any context
2011-08-15 17:33:00 -07:00
if ( vin . empty ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 10 , error ( " CTransaction::CheckTransaction() : vin empty " ) ) ;
2011-08-15 17:33:00 -07:00
if ( vout . empty ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 10 , error ( " CTransaction::CheckTransaction() : vout empty " ) ) ;
2010-09-30 09:23:07 -07:00
// Size limits
2012-04-16 05:56:45 -07:00
if ( : : GetSerializeSize ( * this , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : size limits failed " ) ) ;
2010-09-30 09:23:07 -07:00
// Check for negative or overflow output values
2011-12-21 13:33:19 -08:00
int64 nValueOut = 0 ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CTxOut & txout , vout )
2010-09-30 09:23:07 -07:00
{
if ( txout . nValue < 0 )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : txout.nValue negative " ) ) ;
2010-09-30 09:23:07 -07:00
if ( txout . nValue > MAX_MONEY )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : txout.nValue too high " ) ) ;
2010-09-30 09:23:07 -07:00
nValueOut + = txout . nValue ;
if ( ! MoneyRange ( nValueOut ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : txout total out of range " ) ) ;
2010-09-30 09:23:07 -07:00
}
2011-07-30 14:01:45 -07:00
// Check for duplicate inputs
set < COutPoint > vInOutPoints ;
BOOST_FOREACH ( const CTxIn & txin , vin )
{
if ( vInOutPoints . count ( txin . prevout ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : duplicate inputs " ) ) ;
2011-07-30 14:01:45 -07:00
vInOutPoints . insert ( txin . prevout ) ;
}
2010-09-30 09:23:07 -07:00
if ( IsCoinBase ( ) )
{
if ( vin [ 0 ] . scriptSig . size ( ) < 2 | | vin [ 0 ] . scriptSig . size ( ) > 100 )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CTransaction::CheckTransaction() : coinbase script size " ) ) ;
2010-09-30 09:23:07 -07:00
}
else
{
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CTxIn & txin , vin )
2010-09-30 09:23:07 -07:00
if ( txin . prevout . IsNull ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 10 , error ( " CTransaction::CheckTransaction() : prevout is null " ) ) ;
2010-09-30 09:23:07 -07:00
}
return true ;
}
2013-01-08 03:42:22 -08:00
int64 GetMinFee ( const CTransaction & tx , unsigned int nBlockSize , bool fAllowFree , enum GetMinFee_mode mode )
2012-09-09 13:39:45 -07:00
{
2013-04-25 17:11:27 -07:00
// Base fee is either nMinTxFee or nMinRelayTxFee
2013-01-08 03:42:22 -08:00
int64 nBaseFee = ( mode = = GMF_RELAY ) ? tx . nMinRelayTxFee : tx . nMinTxFee ;
2012-09-09 13:39:45 -07:00
2013-01-08 03:42:22 -08:00
unsigned int nBytes = : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ;
2012-09-09 13:39:45 -07:00
unsigned int nNewBlockSize = nBlockSize + nBytes ;
int64 nMinFee = ( 1 + ( int64 ) nBytes / 1000 ) * nBaseFee ;
if ( fAllowFree )
{
if ( nBlockSize = = 1 )
{
// Transactions under 10K are free
// (about 4500 BTC if made of 50 BTC inputs)
if ( nBytes < 10000 )
nMinFee = 0 ;
}
else
{
// Free transaction area
if ( nNewBlockSize < 27000 )
nMinFee = 0 ;
}
}
2013-04-25 17:11:27 -07:00
// To limit dust spam, require base fee if any output is less than 0.01
2012-09-09 13:39:45 -07:00
if ( nMinFee < nBaseFee )
{
2013-01-08 03:42:22 -08:00
BOOST_FOREACH ( const CTxOut & txout , tx . vout )
2012-09-09 13:39:45 -07:00
if ( txout . nValue < CENT )
nMinFee = nBaseFee ;
}
// Raise the price as the block approaches full
if ( nBlockSize ! = 1 & & nNewBlockSize > = MAX_BLOCK_SIZE_GEN / 2 )
{
if ( nNewBlockSize > = MAX_BLOCK_SIZE_GEN )
return MAX_MONEY ;
nMinFee * = MAX_BLOCK_SIZE_GEN / ( MAX_BLOCK_SIZE_GEN - nNewBlockSize ) ;
}
if ( ! MoneyRange ( nMinFee ) )
nMinFee = MAX_MONEY ;
return nMinFee ;
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
void CTxMemPool : : pruneSpent ( const uint256 & hashTx , CCoins & coins )
{
LOCK ( cs ) ;
std : : map < COutPoint , CInPoint > : : iterator it = mapNextTx . lower_bound ( COutPoint ( hashTx , 0 ) ) ;
// iterate over all COutPoints in mapNextTx whose hash equals the provided hashTx
while ( it ! = mapNextTx . end ( ) & & it - > first . hash = = hashTx ) {
coins . Spend ( it - > first . n ) ; // and remove those outputs from coins
it + + ;
}
}
2012-09-09 13:39:45 -07:00
2013-01-26 15:14:11 -08:00
bool CTxMemPool : : accept ( CValidationState & state , CTransaction & tx , bool fCheckInputs , bool fLimitFree ,
2012-04-13 14:34:22 -07:00
bool * pfMissingInputs )
2010-08-29 09:58:15 -07:00
{
if ( pfMissingInputs )
* pfMissingInputs = false ;
2013-01-26 15:14:11 -08:00
if ( ! tx . CheckTransaction ( state ) )
2012-04-13 14:34:22 -07:00
return error ( " CTxMemPool::accept() : CheckTransaction failed " ) ;
2010-09-30 09:23:07 -07:00
2010-08-29 09:58:15 -07:00
// Coinbase is only valid in a block, not as a loose transaction
2012-04-13 14:34:22 -07:00
if ( tx . IsCoinBase ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CTxMemPool::accept() : coinbase as individual tx " ) ) ;
2010-08-29 09:58:15 -07:00
// To help v0.1.5 clients who would see it as a negative number
2012-04-13 14:34:22 -07:00
if ( ( int64 ) tx . nLockTime > std : : numeric_limits < int > : : max ( ) )
return error ( " CTxMemPool::accept() : not accepting nLockTime beyond 2038 yet " ) ;
2010-09-06 18:12:53 -07:00
2011-04-20 08:20:33 -07:00
// Rather not work on nonstandard transactions (unless -testnet)
2012-04-13 14:34:22 -07:00
if ( ! fTestNet & & ! tx . IsStandard ( ) )
return error ( " CTxMemPool::accept() : nonstandard transaction type " ) ;
2010-12-12 10:20:36 -08:00
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// is it already in the memory pool?
2012-04-13 14:34:22 -07:00
uint256 hash = tx . GetHash ( ) ;
2012-04-06 09:39:12 -07:00
{
2012-04-13 14:34:22 -07:00
LOCK ( cs ) ;
if ( mapTx . count ( hash ) )
2010-08-29 09:58:15 -07:00
return false ;
2012-04-06 09:39:12 -07:00
}
2010-08-29 09:58:15 -07:00
// Check for conflicts with in-memory transactions
CTransaction * ptxOld = NULL ;
2012-04-17 11:12:48 -07:00
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
{
2012-04-13 14:34:22 -07:00
COutPoint outpoint = tx . vin [ i ] . prevout ;
2010-08-29 09:58:15 -07:00
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 12:22:46 -08:00
if ( ptxOld - > IsFinal ( ) )
return false ;
2012-04-13 14:34:22 -07:00
if ( ! tx . IsNewerThan ( * ptxOld ) )
2010-08-29 09:58:15 -07:00
return false ;
2012-04-17 11:12:48 -07:00
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
{
2012-04-13 14:34:22 -07:00
COutPoint outpoint = tx . vin [ i ] . prevout ;
2010-08-29 09:58:15 -07:00
if ( ! mapNextTx . count ( outpoint ) | | mapNextTx [ outpoint ] . ptx ! = ptxOld )
return false ;
}
break ;
}
}
2010-12-12 10:20:36 -08:00
if ( fCheckInputs )
2010-08-29 09:58:15 -07:00
{
2012-10-22 16:16:26 -07:00
CCoinsView dummy ;
CCoinsViewCache view ( dummy ) ;
{
LOCK ( cs ) ;
CCoinsViewMemPool viewMemPool ( * pcoinsTip , * this ) ;
view . SetBackend ( viewMemPool ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// do we already have it?
if ( view . HaveCoins ( hash ) )
2012-05-10 17:31:46 -07:00
return false ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// do all inputs exist?
2012-10-22 15:21:16 -07:00
// Note that this does not check for the presence of actual outputs (see the next check for that),
// only helps filling in pfMissingInputs (to determine missing vs spent).
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
BOOST_FOREACH ( const CTxIn txin , tx . vin ) {
if ( ! view . HaveCoins ( txin . prevout . hash ) ) {
if ( pfMissingInputs )
* pfMissingInputs = true ;
return false ;
}
2011-10-03 10:05:43 -07:00
}
2012-10-22 15:21:16 -07:00
// are the actual inputs available?
2012-07-08 10:04:05 -07:00
if ( ! tx . HaveInputs ( view ) )
2013-01-26 15:14:11 -08:00
return state . Invalid ( error ( " CTxMemPool::accept() : inputs already spent " ) ) ;
2012-11-11 04:11:42 -08:00
2012-10-22 16:16:26 -07:00
// Bring the best block into scope
view . GetBestBlock ( ) ;
// we have all inputs cached now, so switch back to dummy, so we don't need to keep lock on mempool
view . SetBackend ( dummy ) ;
}
2012-07-08 10:04:05 -07:00
2012-01-04 18:40:52 -08:00
// Check for non-standard pay-to-script-hash in inputs
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( ! tx . AreInputsStandard ( view ) & & ! fTestNet )
2012-04-13 14:34:22 -07:00
return error ( " CTxMemPool::accept() : nonstandard transaction input " ) ;
2011-10-03 10:05:43 -07:00
2012-01-20 14:07:40 -08: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.
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
int64 nFees = tx . GetValueIn ( view ) - tx . GetValueOut ( ) ;
2012-04-17 11:12:48 -07:00
unsigned int nSize = : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ;
2012-01-10 17:18:00 -08:00
// Don't accept it if it can't get into a block
2013-01-08 03:42:22 -08:00
int64 txMinFee = GetMinFee ( tx , 1000 , true , GMF_RELAY ) ;
2013-01-14 13:52:33 -08:00
if ( fLimitFree & & nFees < txMinFee )
2012-09-09 14:05:26 -07:00
return error ( " CTxMemPool::accept() : not enough fees %s, % " PRI64d " < % " PRI64d ,
2012-09-18 12:24:31 -07:00
hash . ToString ( ) . c_str ( ) ,
2012-09-09 14:05:26 -07:00
nFees , txMinFee ) ;
2012-01-04 18:40:52 -08:00
2011-03-11 08:50:16 -08:00
// Continuously rate-limit free transactions
2011-03-13 11:38:07 -07:00
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
2012-07-25 20:25:26 -07:00
// be annoying or make others' transactions take longer to confirm.
2013-04-25 17:11:27 -07:00
if ( fLimitFree & & nFees < CTransaction : : nMinRelayTxFee )
2010-12-12 10:20:36 -08:00
{
2011-03-11 08:50:16 -08:00
static double dFreeCount ;
2011-12-21 13:33:19 -08:00
static int64 nLastTime ;
int64 nNow = GetTime ( ) ;
2011-03-13 11:38:07 -07:00
2013-01-14 13:52:33 -08:00
LOCK ( cs ) ;
// 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
2013-01-23 17:24:10 -08:00
if ( dFreeCount > = GetArg ( " -limitfreerelay " , 15 ) * 10 * 1000 )
2013-01-14 13:52:33 -08:00
return error ( " CTxMemPool::accept() : free transaction rejected by rate limiter " ) ;
if ( fDebug )
printf ( " Rate limit dFreeCount: %g => %g \n " , dFreeCount , dFreeCount + nSize ) ;
dFreeCount + = nSize ;
2010-12-12 10:20:36 -08:00
}
2012-01-10 17:18:00 -08:00
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
2013-04-13 15:17:49 -07:00
if ( ! tx . CheckInputs ( state , view , true , SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC ) )
2012-01-10 17:18:00 -08:00
{
2013-04-06 18:40:33 -07:00
return error ( " CTxMemPool::accept() : ConnectInputs failed % s " , hash.ToString().c_str()) ;
2012-01-10 17:18:00 -08:00
}
2010-08-29 09:58:15 -07:00
}
// Store transaction in memory
{
2012-04-13 14:34:22 -07:00
LOCK ( cs ) ;
2010-08-29 09:58:15 -07:00
if ( ptxOld )
{
2012-04-13 14:34:22 -07:00
printf ( " CTxMemPool::accept() : replacing tx %s with new version \n " , ptxOld - > GetHash ( ) . ToString ( ) . c_str ( ) ) ;
remove ( * ptxOld ) ;
2010-08-29 09:58:15 -07:00
}
2012-07-03 22:12:44 -07:00
addUnchecked ( hash , tx ) ;
2010-08-29 09:58:15 -07: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 09:28:20 -07:00
EraseFromWallets ( ptxOld - > GetHash ( ) ) ;
2013-01-18 07:01:05 -08:00
SyncWithWallets ( hash , tx , NULL , true ) ;
2010-08-29 09:58:15 -07:00
2012-09-29 02:57:44 -07:00
printf ( " CTxMemPool::accept() : accepted %s (poolsz % " PRIszu " ) \n " ,
2013-04-06 18:40:33 -07:00
hash . ToString ( ) . c_str ( ) ,
2012-05-10 17:20:31 -07:00
mapTx . size ( ) ) ;
2010-08-29 09:58:15 -07:00
return true ;
}
2013-01-26 15:14:11 -08:00
bool CTransaction : : AcceptToMemoryPool ( CValidationState & state , bool fCheckInputs , bool fLimitFree , bool * pfMissingInputs )
2012-04-13 14:34:22 -07:00
{
2013-01-28 16:44:19 -08:00
try {
return mempool . accept ( state , * this , fCheckInputs , fLimitFree , pfMissingInputs ) ;
} catch ( std : : runtime_error & e ) {
return state . Abort ( _ ( " System error: " ) + e . what ( ) ) ;
}
2012-04-13 14:34:22 -07:00
}
2011-05-26 21:02:51 -07:00
2012-07-03 22:12:44 -07:00
bool CTxMemPool : : addUnchecked ( const uint256 & hash , CTransaction & tx )
2010-08-29 09:58:15 -07:00
{
// Add to memory pool without checking anything. Don't call this directly,
2012-04-13 14:34:22 -07:00
// call CTxMemPool::accept to properly check the transaction first.
2010-08-29 09:58:15 -07:00
{
2012-04-13 13:28:07 -07:00
mapTx [ hash ] = tx ;
2012-04-17 11:12:48 -07:00
for ( unsigned int i = 0 ; i < tx . vin . size ( ) ; i + + )
2012-04-13 13:28:07 -07:00
mapNextTx [ tx . vin [ i ] . prevout ] = CInPoint ( & mapTx [ hash ] , i ) ;
2010-08-29 09:58:15 -07:00
nTransactionsUpdated + + ;
}
return true ;
}
2012-11-24 05:26:51 -08:00
bool CTxMemPool : : remove ( const CTransaction & tx , bool fRecursive )
2010-08-29 09:58:15 -07:00
{
// Remove transaction from memory pool
{
2012-04-13 13:28:07 -07:00
LOCK ( cs ) ;
uint256 hash = tx . GetHash ( ) ;
if ( mapTx . count ( hash ) )
2012-02-09 05:21:41 -08:00
{
2012-11-24 05:26:51 -08:00
if ( fRecursive ) {
for ( unsigned int i = 0 ; i < tx . vout . size ( ) ; i + + ) {
std : : map < COutPoint , CInPoint > : : iterator it = mapNextTx . find ( COutPoint ( hash , i ) ) ;
if ( it ! = mapNextTx . end ( ) )
remove ( * it - > second . ptx , true ) ;
}
}
2012-04-13 13:28:07 -07:00
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
2012-02-09 05:21:41 -08:00
mapNextTx . erase ( txin . prevout ) ;
2012-04-13 13:28:07 -07:00
mapTx . erase ( hash ) ;
2012-02-09 05:21:41 -08:00
nTransactionsUpdated + + ;
}
2010-08-29 09:58:15 -07:00
}
return true ;
}
2012-11-24 05:26:51 -08:00
bool CTxMemPool : : removeConflicts ( const CTransaction & tx )
{
// Remove transactions which depend on inputs of tx, recursively
LOCK ( cs ) ;
BOOST_FOREACH ( const CTxIn & txin , tx . vin ) {
std : : map < COutPoint , CInPoint > : : iterator it = mapNextTx . find ( txin . prevout ) ;
if ( it ! = mapNextTx . end ( ) ) {
const CTransaction & txConflict = * it - > second . ptx ;
if ( txConflict ! = tx )
remove ( txConflict , true ) ;
}
}
return true ;
}
2012-08-23 23:44:51 -07:00
void CTxMemPool : : clear ( )
2012-05-22 14:55:15 -07:00
{
LOCK ( cs ) ;
mapTx . clear ( ) ;
mapNextTx . clear ( ) ;
+ + nTransactionsUpdated ;
}
2012-06-22 08:43:34 -07:00
void CTxMemPool : : queryHashes ( std : : vector < uint256 > & vtxid )
{
vtxid . clear ( ) ;
2010-08-29 09:58:15 -07:00
2012-06-22 08:43:34 -07:00
LOCK ( cs ) ;
vtxid . reserve ( mapTx . size ( ) ) ;
for ( map < uint256 , CTransaction > : : iterator mi = mapTx . begin ( ) ; mi ! = mapTx . end ( ) ; + + mi )
vtxid . push_back ( ( * mi ) . first ) ;
}
2010-08-29 09:58:15 -07:00
2011-07-11 12:49:45 -07:00
int CMerkleTx : : GetDepthInMainChain ( CBlockIndex * & pindexRet ) const
2010-08-29 09:58:15 -07: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 12:49:45 -07:00
pindexRet = pindex ;
2010-08-29 09:58:15 -07:00
return pindexBest - > nHeight - pindex - > nHeight + 1 ;
}
int CMerkleTx : : GetBlocksToMaturity ( ) const
{
if ( ! IsCoinBase ( ) )
return 0 ;
return max ( 0 , ( COINBASE_MATURITY + 20 ) - GetDepthInMainChain ( ) ) ;
}
2013-01-14 13:52:33 -08:00
bool CMerkleTx : : AcceptToMemoryPool ( bool fCheckInputs , bool fLimitFree )
2010-08-29 09:58:15 -07:00
{
2013-01-26 15:14:11 -08:00
CValidationState state ;
return CTransaction : : AcceptToMemoryPool ( state , fCheckInputs , fLimitFree ) ;
2010-08-29 09:58:15 -07:00
}
2012-07-06 07:33:34 -07:00
bool CWalletTx : : AcceptWalletTransaction ( bool fCheckInputs )
2010-08-29 09:58:15 -07:00
{
{
2012-04-13 13:03:09 -07:00
LOCK ( mempool . cs ) ;
2010-09-06 18:12:53 -07:00
// Add previous supporting transactions first
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( CMerkleTx & tx , vtxPrev )
2010-08-29 09:58:15 -07:00
{
if ( ! tx . IsCoinBase ( ) )
{
uint256 hash = tx . GetHash ( ) ;
2012-07-06 07:33:34 -07:00
if ( ! mempool . exists ( hash ) & & pcoinsTip - > HaveCoins ( hash ) )
2013-01-14 13:52:33 -08:00
tx . AcceptToMemoryPool ( fCheckInputs , false ) ;
2010-08-29 09:58:15 -07:00
}
}
2013-01-14 13:52:33 -08:00
return AcceptToMemoryPool ( fCheckInputs , false ) ;
2010-08-29 09:58:15 -07:00
}
2010-09-06 18:12:53 -07:00
return false ;
2010-08-29 09:58:15 -07:00
}
2011-03-02 13:27:24 -08:00
2012-02-15 08:49:04 -08:00
// Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
bool GetTransaction ( const uint256 & hash , CTransaction & txOut , uint256 & hashBlock , bool fAllowSlow )
2012-02-15 08:49:04 -08:00
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CBlockIndex * pindexSlow = NULL ;
2012-02-15 08:49:04 -08:00
{
LOCK ( cs_main ) ;
{
LOCK ( mempool . cs ) ;
if ( mempool . exists ( hash ) )
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
txOut = mempool . lookup ( hash ) ;
2012-02-15 08:49:04 -08:00
return true ;
}
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
2013-01-10 16:47:57 -08:00
if ( fTxIndex ) {
CDiskTxPos postx ;
if ( pblocktree - > ReadTxIndex ( hash , postx ) ) {
CAutoFile file ( OpenBlockFile ( postx , true ) , SER_DISK , CLIENT_VERSION ) ;
CBlockHeader header ;
try {
file > > header ;
fseek ( file , postx . nTxOffset , SEEK_CUR ) ;
file > > txOut ;
} catch ( std : : exception & e ) {
return error ( " %s() : deserialize or I / O error " , __PRETTY_FUNCTION__) ;
}
hashBlock = header . GetHash ( ) ;
if ( txOut . GetHash ( ) ! = hash )
return error ( " %s() : txid mismatch " , __PRETTY_FUNCTION__) ;
return true ;
}
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( fAllowSlow ) { // use coin database to locate block that contains transaction, and scan it
int nHeight = - 1 ;
{
2012-07-06 07:33:34 -07:00
CCoinsViewCache & view = * pcoinsTip ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CCoins coins ;
if ( view . GetCoins ( hash , coins ) )
nHeight = coins . nHeight ;
}
if ( nHeight > 0 )
pindexSlow = FindBlockByHeight ( nHeight ) ;
2012-02-15 08:49:04 -08:00
}
}
2010-08-29 09:58:15 -07:00
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( pindexSlow ) {
CBlock block ;
if ( block . ReadFromDisk ( pindexSlow ) ) {
BOOST_FOREACH ( const CTransaction & tx , block . vtx ) {
if ( tx . GetHash ( ) = = hash ) {
txOut = tx ;
hashBlock = pindexSlow - > GetBlockHash ( ) ;
return true ;
}
}
}
}
2010-08-29 09:58:15 -07:00
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
return false ;
}
2010-08-29 09:58:15 -07:00
//////////////////////////////////////////////////////////////////////////////
//
// CBlock and CBlockIndex
//
2012-07-19 13:06:20 -07:00
static CBlockIndex * pblockindexFBBHLast ;
CBlockIndex * FindBlockByHeight ( int nHeight )
{
2013-05-12 06:50:22 -07:00
if ( nHeight > = ( int ) vBlockIndexByHeight . size ( ) )
return NULL ;
return vBlockIndexByHeight [ nHeight ] ;
2012-07-19 13:06:20 -07:00
}
2012-11-14 13:18:10 -08:00
bool CBlock : : ReadFromDisk ( const CBlockIndex * pindex )
2010-08-29 09:58:15 -07:00
{
2012-11-14 13:18:10 -08:00
if ( ! ReadFromDisk ( pindex - > GetBlockPos ( ) ) )
2010-08-29 09:58:15 -07:00
return false ;
if ( GetHash ( ) ! = pindex - > GetBlockHash ( ) )
return error ( " CBlock::ReadFromDisk() : GetHash ( ) doesn ' t match index " ) ;
return true ;
}
2012-11-14 13:18:10 -08:00
uint256 static GetOrphanRoot ( const CBlockHeader * pblock )
2010-08-29 09:58:15 -07: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 13:33:19 -08:00
int64 static GetBlockValue ( int nHeight , int64 nFees )
2010-08-29 09:58:15 -07:00
{
2011-12-21 13:33:19 -08:00
int64 nSubsidy = 50 * COIN ;
2010-08-29 09:58:15 -07:00
2012-07-18 00:37:05 -07:00
// Subsidy is cut in half every 210000 blocks, which will occur approximately every 4 years
2010-08-29 09:58:15 -07:00
nSubsidy > > = ( nHeight / 210000 ) ;
return nSubsidy + nFees ;
}
2011-12-21 13:33:19 -08: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 09:51:43 -07:00
//
// minimum amount of work that could possibly be required nTime after
// minimum work required was nBase
//
2011-12-21 13:33:19 -08:00
unsigned int ComputeMinWork ( unsigned int nBase , int64 nTime )
2011-09-08 09:51:43 -07:00
{
2011-12-05 12:50:22 -08:00
// Testnet has min-difficulty blocks
// after nTargetSpacing*2 time between blocks:
if ( fTestNet & & nTime > nTargetSpacing * 2 )
return bnProofOfWorkLimit . GetCompact ( ) ;
2011-09-08 09:51:43 -07: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 ( ) ;
}
2012-11-14 13:18:10 -08:00
unsigned int static GetNextWorkRequired ( const CBlockIndex * pindexLast , const CBlockHeader * pblock )
2010-08-29 09:58:15 -07:00
{
2011-12-05 12:50:22 -08:00
unsigned int nProofOfWorkLimit = bnProofOfWorkLimit . GetCompact ( ) ;
2010-08-29 09:58:15 -07:00
// Genesis block
if ( pindexLast = = NULL )
2011-12-05 12:50:22 -08:00
return nProofOfWorkLimit ;
2010-08-29 09:58:15 -07:00
// Only change once per interval
if ( ( pindexLast - > nHeight + 1 ) % nInterval ! = 0 )
2011-12-05 12:50:22 -08:00
{
2012-04-13 11:38:05 -07:00
// Special difficulty rule for testnet:
if ( fTestNet )
2011-12-05 12:50:22 -08:00
{
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
2012-04-13 11:38:05 -07:00
if ( pblock - > nTime > pindexLast - > nTime + nTargetSpacing * 2 )
2011-12-05 12:50:22 -08:00
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 09:58:15 -07:00
return pindexLast - > nBits ;
2011-12-05 12:50:22 -08:00
}
2010-08-29 09:58:15 -07: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 13:33:19 -08:00
int64 nActualTimespan = pindexLast - > GetBlockTime ( ) - pindexFirst - > GetBlockTime ( ) ;
2010-08-29 09:58:15 -07: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 09:02:22 -07:00
// Return maximum amount of blocks that other nodes claim to have
2011-09-11 01:49:30 -07:00
int GetNumBlocksOfPeers ( )
2011-09-02 09:02:22 -07:00
{
2011-09-08 13:50:58 -07:00
return std : : max ( cPeerBlockCounts . median ( ) , Checkpoints : : GetTotalBlocksEstimate ( ) ) ;
2011-09-02 09:02:22 -07:00
}
2010-08-29 09:58:15 -07:00
bool IsInitialBlockDownload ( )
{
2013-01-18 06:07:05 -08:00
if ( pindexBest = = NULL | | fImporting | | fReindex | | nBestHeight < Checkpoints : : GetTotalBlocksEstimate ( ) )
2010-08-29 09:58:15 -07:00
return true ;
2011-12-21 13:33:19 -08:00
static int64 nLastUpdate ;
2010-08-29 09:58:15 -07: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 09:28:20 -07:00
void static InvalidChainFound ( CBlockIndex * pindexNew )
2010-08-29 09:58:15 -07:00
{
2013-03-28 15:51:50 -07:00
if ( pindexNew - > nChainWork > nBestInvalidWork )
2010-08-29 09:58:15 -07:00
{
2013-03-28 15:51:50 -07:00
nBestInvalidWork = pindexNew - > nChainWork ;
pblocktree - > WriteBestInvalidWork ( CBigNum ( nBestInvalidWork ) ) ;
2012-05-06 10:40:58 -07:00
uiInterface . NotifyBlocksChanged ( ) ;
2010-08-29 09:58:15 -07:00
}
2013-03-28 15:51:50 -07:00
printf ( " InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s \n " ,
2013-04-06 18:40:33 -07:00
pindexNew - > GetBlockHash ( ) . ToString ( ) . c_str ( ) , pindexNew - > nHeight ,
2013-03-28 15:51:50 -07:00
log ( pindexNew - > nChainWork . getdouble ( ) ) / log ( 2.0 ) , DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " ,
2012-05-14 11:39:50 -07:00
pindexNew - > GetBlockTime ( ) ) . c_str ( ) ) ;
2013-03-28 15:51:50 -07:00
printf ( " InvalidChainFound: current best=%s height=%d log2_work=%.8g date=%s \n " ,
hashBestChain . ToString ( ) . c_str ( ) , nBestHeight , log ( nBestChainWork . getdouble ( ) ) / log ( 2.0 ) ,
2013-01-01 12:28:28 -08:00
DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , pindexBest - > GetBlockTime ( ) ) . c_str ( ) ) ;
2013-03-28 15:51:50 -07:00
if ( pindexBest & & nBestInvalidWork > nBestChainWork + ( pindexBest - > GetBlockWork ( ) * 6 ) . getuint256 ( ) )
2012-07-26 23:36:43 -07:00
printf ( " InvalidChainFound: Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. \n " ) ;
2010-08-29 09:58:15 -07:00
}
2012-08-18 15:33:01 -07:00
void static InvalidBlockFound ( CBlockIndex * pindex ) {
pindex - > nStatus | = BLOCK_FAILED_VALID ;
2012-09-03 06:26:57 -07:00
pblocktree - > WriteBlockIndex ( CDiskBlockIndex ( pindex ) ) ;
2012-08-18 15:33:01 -07:00
setBlockIndexValid . erase ( pindex ) ;
InvalidChainFound ( pindex ) ;
2013-05-12 06:50:22 -07:00
if ( pindex - > GetNextInMainChain ( ) ) {
2013-01-26 15:14:11 -08:00
CValidationState stateDummy ;
ConnectBestBlock ( stateDummy ) ; // reorganise away from the failed block
}
2012-08-18 15:33:01 -07:00
}
2013-01-26 15:14:11 -08:00
bool ConnectBestBlock ( CValidationState & state ) {
2012-08-18 15:33:01 -07:00
do {
CBlockIndex * pindexNewBest ;
{
std : : set < CBlockIndex * , CBlockIndexWorkComparator > : : reverse_iterator it = setBlockIndexValid . rbegin ( ) ;
if ( it = = setBlockIndexValid . rend ( ) )
return true ;
pindexNewBest = * it ;
}
2013-03-28 15:51:50 -07:00
if ( pindexNewBest = = pindexBest | | ( pindexBest & & pindexNewBest - > nChainWork = = pindexBest - > nChainWork ) )
2012-08-18 15:33:01 -07:00
return true ; // nothing to do
// check ancestry
CBlockIndex * pindexTest = pindexNewBest ;
std : : vector < CBlockIndex * > vAttach ;
do {
if ( pindexTest - > nStatus & BLOCK_FAILED_MASK ) {
// mark descendants failed
CBlockIndex * pindexFailed = pindexNewBest ;
while ( pindexTest ! = pindexFailed ) {
pindexFailed - > nStatus | = BLOCK_FAILED_CHILD ;
setBlockIndexValid . erase ( pindexFailed ) ;
2012-09-03 06:26:57 -07:00
pblocktree - > WriteBlockIndex ( CDiskBlockIndex ( pindexFailed ) ) ;
2012-08-18 15:33:01 -07:00
pindexFailed = pindexFailed - > pprev ;
}
InvalidChainFound ( pindexNewBest ) ;
break ;
}
2013-03-28 15:51:50 -07:00
if ( pindexBest = = NULL | | pindexTest - > nChainWork > pindexBest - > nChainWork )
2012-08-18 15:33:01 -07:00
vAttach . push_back ( pindexTest ) ;
2013-05-12 06:50:22 -07:00
if ( pindexTest - > pprev = = NULL | | pindexTest - > GetNextInMainChain ( ) ) {
2012-08-18 15:33:01 -07:00
reverse ( vAttach . begin ( ) , vAttach . end ( ) ) ;
2012-12-04 14:53:26 -08:00
BOOST_FOREACH ( CBlockIndex * pindexSwitch , vAttach ) {
2013-03-09 09:02:57 -08:00
boost : : this_thread : : interruption_point ( ) ;
2013-01-28 16:44:19 -08:00
try {
if ( ! SetBestChain ( state , pindexSwitch ) )
return false ;
} catch ( std : : runtime_error & e ) {
return state . Abort ( _ ( " System error: " ) + e . what ( ) ) ;
}
2012-12-04 14:53:26 -08:00
}
2012-08-18 15:33:01 -07:00
return true ;
}
pindexTest = pindexTest - > pprev ;
} while ( true ) ;
} while ( true ) ;
}
2012-11-14 13:18:10 -08:00
void CBlockHeader : : UpdateTime ( const CBlockIndex * pindexPrev )
2012-02-16 07:22:31 -08:00
{
nTime = max ( pindexPrev - > GetMedianTimePast ( ) + 1 , GetAdjustedTime ( ) ) ;
// Updating time can change work required on testnet:
if ( fTestNet )
nBits = GetNextWorkRequired ( pindexPrev , this ) ;
}
2010-08-29 09:58:15 -07:00
2012-07-08 10:04:05 -07:00
const CTxOut & CTransaction : : GetOutputFor ( const CTxIn & input , CCoinsViewCache & view )
2011-10-03 10:05:43 -07:00
{
2012-07-08 10:04:05 -07:00
const CCoins & coins = view . GetCoins ( input . prevout . hash ) ;
assert ( coins . IsAvailable ( input . prevout . n ) ) ;
return coins . vout [ input . prevout . n ] ;
2012-01-10 17:18:00 -08:00
}
2012-07-08 10:04:05 -07:00
int64 CTransaction : : GetValueIn ( CCoinsViewCache & inputs ) const
2012-01-10 17:18:00 -08:00
{
if ( IsCoinBase ( ) )
return 0 ;
int64 nResult = 0 ;
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2012-01-10 17:18:00 -08:00
nResult + = GetOutputFor ( vin [ i ] , inputs ) . nValue ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
return nResult ;
2012-01-10 17:18:00 -08:00
}
2012-07-08 10:04:05 -07:00
unsigned int CTransaction : : GetP2SHSigOpCount ( CCoinsViewCache & inputs ) const
2012-01-10 17:18:00 -08:00
{
if ( IsCoinBase ( ) )
return 0 ;
2012-04-23 11:14:03 -07:00
unsigned int nSigOps = 0 ;
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2012-01-10 17:18:00 -08:00
{
2012-07-08 10:04:05 -07:00
const CTxOut & prevout = GetOutputFor ( vin [ i ] , inputs ) ;
2012-01-20 14:07:40 -08:00
if ( prevout . scriptPubKey . IsPayToScriptHash ( ) )
nSigOps + = prevout . scriptPubKey . GetSigOpCount ( vin [ i ] . scriptSig ) ;
2012-01-10 17:18:00 -08:00
}
return nSigOps ;
}
2013-05-20 17:36:48 -07:00
void CTransaction : : UpdateCoins ( CValidationState & state , CCoinsViewCache & inputs , CTxUndo & txundo , int nHeight , const uint256 & txhash ) const
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
{
// mark inputs spent
if ( ! IsCoinBase ( ) ) {
BOOST_FOREACH ( const CTxIn & txin , vin ) {
2012-07-08 10:04:05 -07:00
CCoins & coins = inputs . GetCoins ( txin . prevout . hash ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CTxInUndo undo ;
2013-01-26 15:14:11 -08:00
assert ( coins . Spend ( txin . prevout , undo ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
txundo . vprevout . push_back ( undo ) ;
}
}
// add outputs
2013-01-26 15:14:11 -08:00
assert ( inputs . SetCoins ( txhash , CCoins ( * this , nHeight ) ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
2012-07-08 10:04:05 -07:00
bool CTransaction : : HaveInputs ( CCoinsViewCache & inputs ) const
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
{
2012-10-05 10:22:21 -07:00
if ( ! IsCoinBase ( ) ) {
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// first check whether information about the prevout hash is available
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + ) {
const COutPoint & prevout = vin [ i ] . prevout ;
if ( ! inputs . HaveCoins ( prevout . hash ) )
return false ;
}
// then check whether the actual outputs are available
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + ) {
const COutPoint & prevout = vin [ i ] . prevout ;
2012-07-08 10:04:05 -07:00
const CCoins & coins = inputs . GetCoins ( prevout . hash ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( ! coins . IsAvailable ( prevout . n ) )
return false ;
}
}
return true ;
}
2012-12-01 13:30:06 -08:00
bool CScriptCheck : : operator ( ) ( ) const {
const CScript & scriptSig = ptxTo - > vin [ nIn ] . scriptSig ;
if ( ! VerifyScript ( scriptSig , scriptPubKey , * ptxTo , nIn , nFlags , nHashType ) )
2013-04-06 18:40:33 -07:00
return error ( " CScriptCheck() : % s VerifySignature failed " , ptxTo->GetHash().ToString().c_str()) ;
2012-12-01 13:30:06 -08:00
return true ;
}
2012-09-08 08:33:10 -07:00
bool VerifySignature ( const CCoins & txFrom , const CTransaction & txTo , unsigned int nIn , unsigned int flags , int nHashType )
{
2012-12-01 13:30:06 -08:00
return CScriptCheck ( txFrom , txTo , nIn , flags , nHashType ) ( ) ;
2012-09-08 08:33:10 -07:00
}
2013-01-26 15:14:11 -08:00
bool CTransaction : : CheckInputs ( CValidationState & state , CCoinsViewCache & inputs , bool fScriptChecks , unsigned int flags , std : : vector < CScriptCheck > * pvChecks ) const
2010-08-29 09:58:15 -07:00
{
if ( ! IsCoinBase ( ) )
{
2012-12-01 14:04:14 -08:00
if ( pvChecks )
pvChecks - > reserve ( vin . size ( ) ) ;
2012-07-08 10:04:05 -07:00
// 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 ( ! HaveInputs ( inputs ) )
2013-04-06 18:40:33 -07:00
return state . Invalid ( error ( " CheckInputs() : %s inputs unavailable " , GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
2012-07-08 10:04:05 -07:00
2012-10-22 00:22:15 -07:00
// While checking, GetBestBlock() refers to the parent block.
// This is also true for mempool checks.
2012-11-11 04:11:42 -08:00
int nSpendHeight = inputs . GetBestBlock ( ) - > nHeight + 1 ;
2011-12-21 13:33:19 -08:00
int64 nValueIn = 0 ;
2012-01-10 17:18:00 -08:00
int64 nFees = 0 ;
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
const COutPoint & prevout = vin [ i ] . prevout ;
2012-07-08 10:04:05 -07:00
const CCoins & coins = inputs . GetCoins ( prevout . hash ) ;
2010-08-29 09:58:15 -07:00
// If prev is coinbase, check that it's matured
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( coins . IsCoinBase ( ) ) {
2012-10-22 00:22:15 -07:00
if ( nSpendHeight - coins . nHeight < COINBASE_MATURITY )
2013-01-26 15:14:11 -08:00
return state . Invalid ( error ( " CheckInputs() : tried to spend coinbase at depth %d " , nSpendHeight - coins . nHeight ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
2010-08-29 09:58:15 -07:00
2012-05-16 08:26:56 -07:00
// Check for negative or overflow input values
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
nValueIn + = coins . vout [ prevout . n ] . nValue ;
if ( ! MoneyRange ( coins . vout [ prevout . n ] . nValue ) | | ! MoneyRange ( nValueIn ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckInputs() : txin values out of range " ) ) ;
2012-05-16 08:26:56 -07:00
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( nValueIn < GetValueOut ( ) )
2013-04-06 18:40:33 -07:00
return state . DoS ( 100 , error ( " CheckInputs() : %s value in < value out " , GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// Tally transaction fees
int64 nTxFee = nValueIn - GetValueOut ( ) ;
if ( nTxFee < 0 )
2013-04-06 18:40:33 -07:00
return state . DoS ( 100 , error ( " CheckInputs() : %s nTxFee < 0 " , GetHash ( ) . ToString ( ) . c_str ( ) ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
nFees + = nTxFee ;
if ( ! MoneyRange ( nFees ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckInputs() : nFees out of range " ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
2012-05-16 08:26:56 -07:00
// The first loop above does all the inexpensive checks.
// Only if ALL inputs pass do we perform expensive ECDSA signature checks.
// Helps prevent CPU exhaustion attacks.
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// Skip ECDSA signature verification when connecting blocks
2012-10-05 10:22:21 -07:00
// before the last block chain checkpoint. This is safe because block merkle hashes are
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// still computed and checked, and any change will be caught at the next checkpoint.
2012-12-01 13:51:10 -08:00
if ( fScriptChecks ) {
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
for ( unsigned int i = 0 ; i < vin . size ( ) ; i + + ) {
const COutPoint & prevout = vin [ i ] . prevout ;
2012-07-08 10:04:05 -07:00
const CCoins & coins = inputs . GetCoins ( prevout . hash ) ;
2012-01-10 17:18:00 -08:00
2011-09-02 13:59:47 -07:00
// Verify signature
2012-12-01 14:04:14 -08:00
CScriptCheck check ( coins , * this , i , flags , 0 ) ;
if ( pvChecks ) {
pvChecks - > push_back ( CScriptCheck ( ) ) ;
check . swap ( pvChecks - > back ( ) ) ;
2013-04-18 13:17:05 -07:00
} else if ( ! check ( ) ) {
if ( flags & SCRIPT_VERIFY_STRICTENC ) {
// For now, check whether the failure was caused by non-canonical
// encodings or not; if so, don't trigger DoS protection.
CScriptCheck check ( coins , * this , i , flags & ( ~ SCRIPT_VERIFY_STRICTENC ) , 0 ) ;
if ( check ( ) )
return state . Invalid ( ) ;
}
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , false ) ;
2013-04-18 13:17:05 -07:00
}
2011-11-08 10:20:29 -08:00
}
2010-08-29 09:58:15 -07:00
}
}
return true ;
}
2013-01-26 15:14:11 -08:00
bool CBlock : : DisconnectBlock ( CValidationState & state , CBlockIndex * pindex , CCoinsViewCache & view , bool * pfClean )
2010-08-29 09:58:15 -07:00
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
assert ( pindex = = view . GetBestBlock ( ) ) ;
2010-08-29 09:58:15 -07:00
2012-12-30 06:29:39 -08:00
if ( pfClean )
* pfClean = false ;
bool fClean = true ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CBlockUndo blockUndo ;
2012-12-30 14:41:41 -08:00
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
if ( pos . IsNull ( ) )
return error ( " DisconnectBlock() : no undo data available " ) ;
if ( ! blockUndo . ReadFromDisk ( pos , pindex - > pprev - > GetBlockHash ( ) ) )
return error ( " DisconnectBlock() : failure reading undo data " ) ;
2010-08-29 09:58:15 -07:00
2012-12-30 06:29:39 -08:00
if ( blockUndo . vtxundo . size ( ) + 1 ! = vtx . size ( ) )
return error ( " DisconnectBlock() : block and undo data inconsistent " ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// undo transactions in reverse order
for ( int i = vtx . size ( ) - 1 ; i > = 0 ; i - - ) {
const CTransaction & tx = vtx [ i ] ;
uint256 hash = tx . GetHash ( ) ;
// check that all outputs are available
2012-12-30 06:29:39 -08:00
if ( ! view . HaveCoins ( hash ) ) {
fClean = fClean & & error ( " DisconnectBlock() : outputs still spent? database corrupted " ) ;
view . SetCoins ( hash , CCoins ( ) ) ;
}
2012-07-08 10:04:05 -07:00
CCoins & outs = view . GetCoins ( hash ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CCoins outsBlock = CCoins ( tx , pindex - > nHeight ) ;
if ( outs ! = outsBlock )
2012-12-30 06:29:39 -08:00
fClean = fClean & & error ( " DisconnectBlock() : added transaction mismatch? database corrupted " ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// remove outputs
2012-07-08 10:04:05 -07:00
outs = CCoins ( ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// restore inputs
if ( i > 0 ) { // not coinbases
const CTxUndo & txundo = blockUndo . vtxundo [ i - 1 ] ;
2012-12-30 06:29:39 -08:00
if ( txundo . vprevout . size ( ) ! = tx . vin . size ( ) )
return error ( " DisconnectBlock() : transaction and undo data inconsistent " ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
for ( unsigned int j = tx . vin . size ( ) ; j - - > 0 ; ) {
const COutPoint & out = tx . vin [ j ] . prevout ;
const CTxInUndo & undo = txundo . vprevout [ j ] ;
CCoins coins ;
view . GetCoins ( out . hash , coins ) ; // this can fail if the prevout was already entirely spent
2012-12-30 06:29:39 -08:00
if ( undo . nHeight ! = 0 ) {
// undo data contains height: this is the last output of the prevout tx being spent
if ( ! coins . IsPruned ( ) )
fClean = fClean & & error ( " DisconnectBlock() : undo data overwriting existing transaction " ) ;
coins = CCoins ( ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
coins . fCoinBase = undo . fCoinBase ;
coins . nHeight = undo . nHeight ;
coins . nVersion = undo . nVersion ;
} else {
2012-12-30 06:29:39 -08:00
if ( coins . IsPruned ( ) )
fClean = fClean & & error ( " DisconnectBlock() : undo data adding output to missing transaction " ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
if ( coins . IsAvailable ( out . n ) )
2012-12-30 06:29:39 -08:00
fClean = fClean & & error ( " DisconnectBlock() : undo data overwriting existing output " ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( coins . vout . size ( ) < out . n + 1 )
coins . vout . resize ( out . n + 1 ) ;
coins . vout [ out . n ] = undo . txout ;
if ( ! view . SetCoins ( out . hash , coins ) )
return error ( " DisconnectBlock() : cannot restore coin inputs " ) ;
}
}
}
// move best block pointer to prevout block
view . SetBestBlock ( pindex - > pprev ) ;
2012-12-30 06:29:39 -08:00
if ( pfClean ) {
* pfClean = fClean ;
return true ;
} else {
return fClean ;
}
2010-08-29 09:58:15 -07:00
}
2013-01-29 19:17:33 -08:00
void static FlushBlockFile ( bool fFinalize = false )
2012-09-05 18:21:18 -07:00
{
LOCK ( cs_LastBlockFile ) ;
2012-12-03 01:14:54 -08:00
CDiskBlockPos posOld ( nLastBlockFile , 0 ) ;
2012-09-05 18:21:18 -07:00
FILE * fileOld = OpenBlockFile ( posOld ) ;
2012-12-01 02:36:53 -08:00
if ( fileOld ) {
2013-01-29 19:17:33 -08:00
if ( fFinalize )
TruncateFile ( fileOld , infoLastBlockFile . nSize ) ;
2012-12-01 02:36:53 -08:00
FileCommit ( fileOld ) ;
fclose ( fileOld ) ;
}
2012-09-05 18:21:18 -07:00
fileOld = OpenUndoFile ( posOld ) ;
2012-12-01 02:36:53 -08:00
if ( fileOld ) {
2013-01-29 19:17:33 -08:00
if ( fFinalize )
TruncateFile ( fileOld , infoLastBlockFile . nUndoSize ) ;
2012-12-01 02:36:53 -08:00
FileCommit ( fileOld ) ;
fclose ( fileOld ) ;
}
2012-09-05 18:21:18 -07:00
}
2013-01-26 15:14:11 -08:00
bool FindUndoPos ( CValidationState & state , int nFile , CDiskBlockPos & pos , unsigned int nAddSize ) ;
2012-08-13 10:11:05 -07:00
2012-12-01 14:04:14 -08:00
static CCheckQueue < CScriptCheck > scriptcheckqueue ( 128 ) ;
2013-03-06 19:31:26 -08:00
void ThreadScriptCheck ( ) {
2012-12-01 14:04:14 -08:00
RenameThread ( " bitcoin-scriptch " ) ;
scriptcheckqueue . Thread ( ) ;
}
2013-01-26 15:14:11 -08:00
bool CBlock : : ConnectBlock ( CValidationState & state , CBlockIndex * pindex , CCoinsViewCache & view , bool fJustCheck )
2010-08-29 09:58:15 -07:00
{
// Check it again in case a previous version let a bad block in
2013-01-26 15:14:11 -08:00
if ( ! CheckBlock ( state , ! fJustCheck , ! fJustCheck ) )
2010-08-29 09:58:15 -07:00
return false ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// verify that the view's current state corresponds to the previous block
assert ( pindex - > pprev = = view . GetBestBlock ( ) ) ;
2013-01-18 15:35:17 -08:00
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if ( GetHash ( ) = = hashGenesisBlock ) {
view . SetBestBlock ( pindex ) ;
pindexGenesisBlock = pindex ;
return true ;
}
2012-12-01 13:51:10 -08:00
bool fScriptChecks = pindex - > nHeight > = Checkpoints : : GetTotalBlocksEstimate ( ) ;
2012-02-17 08:58:02 -08: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
2012-07-25 20:25:26 -07:00
// already refuses previously-known transaction ids entirely.
2012-09-09 17:11:04 -07:00
// This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC.
// Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
// two in the chain that violate it. This prevents exploiting the issue against nodes in their
// initial block download.
2012-10-23 22:41:52 -07:00
bool fEnforceBIP30 = ( ! pindex - > phashBlock ) | | // Enforce on CreateNewBlock invocations which don't have a hash.
! ( ( pindex - > nHeight = = 91842 & & pindex - > GetBlockHash ( ) = = uint256 ( " 0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec " ) ) | |
2012-09-09 17:11:04 -07:00
( pindex - > nHeight = = 91880 & & pindex - > GetBlockHash ( ) = = uint256 ( " 0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721 " ) ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( fEnforceBIP30 ) {
2012-07-07 15:06:34 -07:00
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + ) {
uint256 hash = GetTxHash ( i ) ;
2012-07-08 10:04:05 -07:00
if ( view . HaveCoins ( hash ) & & ! view . GetCoins ( hash ) . IsPruned ( ) )
2013-02-06 07:33:51 -08:00
return state . DoS ( 100 , error ( " ConnectBlock() : tried to overwrite transaction " ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
}
2012-02-17 08:58:02 -08:00
2012-06-22 08:50:52 -07:00
// BIP16 didn't become active until Apr 1 2012
int64 nBIP16SwitchTime = 1333238400 ;
2012-03-21 12:45:58 -07:00
bool fStrictPayToScriptHash = ( pindex - > nTime > = nBIP16SwitchTime ) ;
2012-01-20 14:07:40 -08:00
2012-12-08 13:49:04 -08:00
unsigned int flags = SCRIPT_VERIFY_NOCACHE |
( fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE ) ;
2012-06-23 05:17:13 -07:00
CBlockUndo blockundo ;
2012-12-01 14:04:14 -08:00
CCheckQueueControl < CScriptCheck > control ( fScriptChecks & & nScriptCheckThreads ? & scriptcheckqueue : NULL ) ;
2012-12-01 11:10:23 -08:00
int64 nStart = GetTimeMicros ( ) ;
2011-12-21 13:33:19 -08:00
int64 nFees = 0 ;
2012-12-01 11:10:23 -08:00
int nInputs = 0 ;
2012-04-23 11:14:03 -07:00
unsigned int nSigOps = 0 ;
2013-01-10 16:47:57 -08:00
CDiskTxPos pos ( pindex - > GetBlockPos ( ) , GetSizeOfCompactSize ( vtx . size ( ) ) ) ;
std : : vector < std : : pair < uint256 , CDiskTxPos > > vPos ;
vPos . reserve ( vtx . size ( ) ) ;
2012-07-07 15:06:34 -07:00
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
{
2012-07-07 15:06:34 -07:00
const CTransaction & tx = vtx [ i ] ;
2012-12-01 11:10:23 -08:00
nInputs + = tx . vin . size ( ) ;
2012-01-20 14:07:40 -08:00
nSigOps + = tx . GetLegacySigOpCount ( ) ;
if ( nSigOps > MAX_BLOCK_SIGOPS )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " ConnectBlock() : too many sigops " ) ) ;
2012-01-20 14:07:40 -08:00
2012-01-10 17:18:00 -08:00
if ( ! tx . IsCoinBase ( ) )
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( ! tx . HaveInputs ( view ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " ConnectBlock() : inputs missing/spent " ) ) ;
2012-01-04 18:40:52 -08:00
2012-01-20 14:07:40 -08: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.
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
nSigOps + = tx . GetP2SHSigOpCount ( view ) ;
2012-01-20 14:07:40 -08:00
if ( nSigOps > MAX_BLOCK_SIGOPS )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " ConnectBlock() : too many sigops " ) ) ;
2012-01-20 14:07:40 -08:00
}
2012-01-04 18:40:52 -08:00
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
nFees + = tx . GetValueIn ( view ) - tx . GetValueOut ( ) ;
2012-06-23 05:17:13 -07:00
2012-12-01 14:04:14 -08:00
std : : vector < CScriptCheck > vChecks ;
2013-01-26 15:14:11 -08:00
if ( ! tx . CheckInputs ( state , view , fScriptChecks , flags , nScriptCheckThreads ? & vChecks : NULL ) )
2012-01-10 17:45:55 -08:00
return false ;
2012-12-01 14:04:14 -08:00
control . Add ( vChecks ) ;
2012-01-10 17:18:00 -08:00
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CTxUndo txundo ;
2013-05-20 17:36:48 -07:00
tx . UpdateCoins ( state , view , txundo , pindex - > nHeight , GetTxHash ( i ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( ! tx . IsCoinBase ( ) )
blockundo . vtxundo . push_back ( txundo ) ;
2012-12-01 11:10:23 -08:00
2013-01-10 16:47:57 -08:00
vPos . push_back ( std : : make_pair ( GetTxHash ( i ) , pos ) ) ;
pos . nTxOffset + = : : GetSerializeSize ( tx , SER_DISK , CLIENT_VERSION ) ;
2010-08-29 09:58:15 -07:00
}
2012-12-01 11:10:23 -08:00
int64 nTime = GetTimeMicros ( ) - nStart ;
if ( fBenchmark )
printf ( " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) \n " , ( unsigned ) vtx . size ( ) , 0.001 * nTime , 0.001 * nTime / vtx . size ( ) , nInputs < = 1 ? 0 : 0.001 * nTime / ( nInputs - 1 ) ) ;
2011-10-03 10:05:43 -07:00
2012-10-22 12:46:00 -07:00
if ( vtx [ 0 ] . GetValueOut ( ) > GetBlockValue ( pindex - > nHeight , nFees ) )
2013-01-26 15:15:45 -08:00
return state . DoS ( 100 , error ( " ConnectBlock() : coinbase pays too much (actual=% " PRI64d " vs limit=% " PRI64d " ) " , vtx [ 0 ] . GetValueOut ( ) , GetBlockValue ( pindex - > nHeight , nFees ) ) ) ;
2012-10-22 12:46:00 -07:00
2012-12-01 14:04:14 -08:00
if ( ! control . Wait ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , false ) ;
2012-12-01 14:04:14 -08:00
int64 nTime2 = GetTimeMicros ( ) - nStart ;
if ( fBenchmark )
printf ( " - Verify %u txins: %.2fms (%.3fms/txin) \n " , nInputs - 1 , 0.001 * nTime2 , nInputs < = 1 ? 0 : 0.001 * nTime2 / ( nInputs - 1 ) ) ;
2012-05-09 10:24:44 -07:00
if ( fJustCheck )
return true ;
2012-08-13 10:11:05 -07:00
// Write undo information to disk
2012-08-18 15:33:01 -07:00
if ( pindex - > GetUndoPos ( ) . IsNull ( ) | | ( pindex - > nStatus & BLOCK_VALID_MASK ) < BLOCK_VALID_SCRIPTS )
2012-08-13 10:11:05 -07:00
{
2012-08-18 15:33:01 -07:00
if ( pindex - > GetUndoPos ( ) . IsNull ( ) ) {
CDiskBlockPos pos ;
2013-01-26 15:14:11 -08:00
if ( ! FindUndoPos ( state , pindex - > nFile , pos , : : GetSerializeSize ( blockundo , SER_DISK , CLIENT_VERSION ) + 40 ) )
2012-08-18 15:33:01 -07:00
return error ( " ConnectBlock() : FindUndoPos failed " ) ;
2012-12-30 14:41:41 -08:00
if ( ! blockundo . WriteToDisk ( pos , pindex - > pprev - > GetBlockHash ( ) ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write undo data " ) ) ;
2012-08-18 15:33:01 -07:00
// update nUndoPos in block index
pindex - > nUndoPos = pos . nPos ;
pindex - > nStatus | = BLOCK_HAVE_UNDO ;
}
pindex - > nStatus = ( pindex - > nStatus & ~ BLOCK_VALID_MASK ) | BLOCK_VALID_SCRIPTS ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CDiskBlockIndex blockindex ( pindex ) ;
2012-09-03 06:26:57 -07:00
if ( ! pblocktree - > WriteBlockIndex ( blockindex ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write block index " ) ) ;
2010-08-29 09:58:15 -07:00
}
2013-01-10 16:47:57 -08:00
if ( fTxIndex )
2013-01-26 15:14:11 -08:00
if ( ! pblocktree - > WriteTxIndex ( vPos ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write transaction index " ) ) ;
2013-01-10 16:47:57 -08:00
2012-10-05 10:22:21 -07:00
// add this block to the view's block chain
2013-01-26 16:24:06 -08:00
assert ( view . SetBestBlock ( pindex ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
2010-08-29 09:58:15 -07:00
// Watch for transactions paying to me
2012-07-07 15:06:34 -07:00
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + )
SyncWithWallets ( GetTxHash ( i ) , vtx [ i ] , this , true ) ;
2010-08-29 09:58:15 -07:00
return true ;
}
2013-01-26 15:14:11 -08:00
bool SetBestChain ( CValidationState & state , CBlockIndex * pindexNew )
2010-08-29 09:58:15 -07:00
{
2012-12-01 07:46:23 -08:00
// All modifications to the coin state will be done in this cache.
// Only when all have succeeded, we push it to pcoinsTip.
CCoinsViewCache view ( * pcoinsTip , true ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// Find the fork (typically, there is none)
CBlockIndex * pfork = view . GetBestBlock ( ) ;
2010-08-29 09:58:15 -07:00
CBlockIndex * plonger = pindexNew ;
2012-12-02 12:59:22 -08:00
while ( pfork & & pfork ! = plonger )
2010-08-29 09:58:15 -07:00
{
2013-01-26 16:24:06 -08:00
while ( plonger - > nHeight > pfork - > nHeight ) {
plonger = plonger - > pprev ;
assert ( plonger ! = NULL ) ;
}
2010-08-29 09:58:15 -07:00
if ( pfork = = plonger )
break ;
2013-01-26 16:24:06 -08:00
pfork = pfork - > pprev ;
assert ( pfork ! = NULL ) ;
2010-08-29 09:58:15 -07:00
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// List of what to disconnect (typically nothing)
2010-08-29 09:58:15 -07:00
vector < CBlockIndex * > vDisconnect ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
for ( CBlockIndex * pindex = view . GetBestBlock ( ) ; pindex ! = pfork ; pindex = pindex - > pprev )
2010-08-29 09:58:15 -07:00
vDisconnect . push_back ( pindex ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// List of what to connect (typically only pindexNew)
2010-08-29 09:58:15 -07:00
vector < CBlockIndex * > vConnect ;
for ( CBlockIndex * pindex = pindexNew ; pindex ! = pfork ; pindex = pindex - > pprev )
vConnect . push_back ( pindex ) ;
reverse ( vConnect . begin ( ) , vConnect . end ( ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( vDisconnect . size ( ) > 0 ) {
2013-04-06 18:40:33 -07:00
printf ( " REORGANIZE: Disconnect % " PRIszu " blocks; %s.. \n " , vDisconnect . size ( ) , pfork - > GetBlockHash ( ) . ToString ( ) . c_str ( ) ) ;
printf ( " REORGANIZE: Connect % " PRIszu " blocks; ..%s \n " , vConnect . size ( ) , pindexNew - > GetBlockHash ( ) . ToString ( ) . c_str ( ) ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
2012-03-21 05:15:27 -07:00
2010-08-29 09:58:15 -07:00
// Disconnect shorter branch
vector < CTransaction > vResurrect ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
BOOST_FOREACH ( CBlockIndex * pindex , vDisconnect ) {
2010-08-29 09:58:15 -07:00
CBlock block ;
if ( ! block . ReadFromDisk ( pindex ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to read block " ) ) ;
2012-12-01 11:10:23 -08:00
int64 nStart = GetTimeMicros ( ) ;
2013-01-26 15:14:11 -08:00
if ( ! block . DisconnectBlock ( state , pindex , view ) )
2013-04-06 18:40:33 -07:00
return error ( " SetBestBlock() : DisconnectBlock % s failed " , pindex->GetBlockHash().ToString().c_str()) ;
2012-12-01 11:10:23 -08:00
if ( fBenchmark )
printf ( " - Disconnect: %.2fms \n " , ( GetTimeMicros ( ) - nStart ) * 0.001 ) ;
2010-08-29 09:58:15 -07:00
2012-11-30 15:41:27 -08:00
// Queue memory transactions to resurrect.
// We only do this for blocks after the last checkpoint (reorganisation before that
// point should only happen with -reindex/-loadblock, or a misbehaving peer.
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
2012-11-30 15:41:27 -08:00
if ( ! tx . IsCoinBase ( ) & & pindex - > nHeight > Checkpoints : : GetTotalBlocksEstimate ( ) )
2010-08-29 09:58:15 -07:00
vResurrect . push_back ( tx ) ;
}
// Connect longer branch
vector < CTransaction > vDelete ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
BOOST_FOREACH ( CBlockIndex * pindex , vConnect ) {
2010-08-29 09:58:15 -07:00
CBlock block ;
2012-08-18 15:33:01 -07:00
if ( ! block . ReadFromDisk ( pindex ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to read block " ) ) ;
2012-12-01 11:10:23 -08:00
int64 nStart = GetTimeMicros ( ) ;
2013-01-26 15:14:11 -08:00
if ( ! block . ConnectBlock ( state , pindex , view ) ) {
if ( state . IsInvalid ( ) ) {
InvalidChainFound ( pindexNew ) ;
InvalidBlockFound ( pindex ) ;
}
2013-04-06 18:40:33 -07:00
return error ( " SetBestBlock() : ConnectBlock % s failed " , pindex->GetBlockHash().ToString().c_str()) ;
2010-08-29 09:58:15 -07:00
}
2012-12-01 11:10:23 -08:00
if ( fBenchmark )
2013-01-18 06:07:05 -08:00
printf ( " - Connect: %.2fms \n " , ( GetTimeMicros ( ) - nStart ) * 0.001 ) ;
2010-08-29 09:58:15 -07:00
// Queue memory transactions to delete
2012-08-18 15:33:01 -07:00
BOOST_FOREACH ( const CTransaction & tx , block . vtx )
2010-08-29 09:58:15 -07:00
vDelete . push_back ( tx ) ;
}
2012-12-01 07:46:23 -08:00
// Flush changes to global coin state
2012-12-01 11:10:23 -08:00
int64 nStart = GetTimeMicros ( ) ;
int nModified = view . GetCacheSize ( ) ;
2013-01-26 16:24:06 -08:00
assert ( view . Flush ( ) ) ;
2012-12-01 11:10:23 -08:00
int64 nTime = GetTimeMicros ( ) - nStart ;
if ( fBenchmark )
printf ( " - Flush %i transactions: %.2fms (%.4fms/tx) \n " , nModified , 0.001 * nTime , 0.001 * nTime / nModified ) ;
2012-12-01 07:46:23 -08:00
2010-10-05 19:19:47 -07:00
// Make sure it's successfully written to disk before changing memory structure
2012-07-06 07:33:34 -07:00
bool fIsInitialDownload = IsInitialBlockDownload ( ) ;
2012-12-01 07:46:23 -08:00
if ( ! fIsInitialDownload | | pcoinsTip - > GetCacheSize ( ) > nCoinCacheSize ) {
2013-01-26 15:22:15 -08:00
// Typical CCoins structures on disk are around 100 bytes in size.
// Pushing a new one to the database can cause it to be written
// twice (once in the log, and once in the tables). This is already
// an overestimation, as most will delete an existing entry or
// overwrite one. Still, use a conservative safety factor of 2.
if ( ! CheckDiskSpace ( 100 * 2 * 2 * pcoinsTip - > GetCacheSize ( ) ) )
return state . Error ( ) ;
2012-09-05 18:21:18 -07:00
FlushBlockFile ( ) ;
2012-09-03 12:14:03 -07:00
pblocktree - > Sync ( ) ;
2012-12-01 07:46:23 -08:00
if ( ! pcoinsTip - > Flush ( ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write to coin database " ) ) ;
2012-09-05 18:21:18 -07:00
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// At this point, all changes have been done to the database.
// Proceed by updating the memory structures.
2010-08-29 09:58:15 -07:00
2013-05-12 06:50:22 -07:00
// Register new best chain
vBlockIndexByHeight . resize ( pindexNew - > nHeight + 1 ) ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( CBlockIndex * pindex , vConnect )
2013-05-12 06:50:22 -07:00
vBlockIndexByHeight [ pindex - > nHeight ] = pindex ;
2010-08-29 09:58:15 -07:00
// Resurrect memory transactions that were in the disconnected branch
2013-01-26 15:14:11 -08:00
BOOST_FOREACH ( CTransaction & tx , vResurrect ) {
// ignore validation errors in resurrected transactions
CValidationState stateDummy ;
tx . AcceptToMemoryPool ( stateDummy , true , false ) ;
}
2010-08-29 09:58:15 -07:00
// Delete redundant memory transactions that are in the connected branch
2012-11-24 05:26:51 -08:00
BOOST_FOREACH ( CTransaction & tx , vDelete ) {
2012-04-13 13:28:07 -07:00
mempool . remove ( tx ) ;
2012-11-24 05:26:51 -08:00
mempool . removeConflicts ( tx ) ;
}
2010-08-29 09:58:15 -07:00
2011-04-13 07:16:30 -07:00
// Update best block in wallet (so we can detect restored wallets)
2013-05-22 11:58:53 -07:00
if ( ( pindexNew - > nHeight % 20160 ) = = 0 | | ( ! fIsInitialDownload & & ( pindexNew - > nHeight % 144 ) = = 0 ) )
2011-04-13 07:16:30 -07: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 09:28:20 -07:00
: : SetBestChain ( locator ) ;
2011-04-13 07:16:30 -07:00
}
2010-08-29 09:58:15 -07:00
// New best block
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
hashBestChain = pindexNew - > GetBlockHash ( ) ;
2010-08-29 09:58:15 -07:00
pindexBest = pindexNew ;
2012-07-19 13:06:20 -07:00
pblockindexFBBHLast = NULL ;
2010-08-29 09:58:15 -07:00
nBestHeight = pindexBest - > nHeight ;
2013-03-28 15:51:50 -07:00
nBestChainWork = pindexNew - > nChainWork ;
2010-08-29 09:58:15 -07:00
nTimeBestReceived = GetTime ( ) ;
nTransactionsUpdated + + ;
2013-03-28 15:51:50 -07:00
printf ( " SetBestChain: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f \n " ,
hashBestChain . ToString ( ) . c_str ( ) , nBestHeight , log ( nBestChainWork . getdouble ( ) ) / log ( 2.0 ) , ( unsigned long ) pindexNew - > nChainTx ,
2013-04-03 17:39:37 -07:00
DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , pindexBest - > GetBlockTime ( ) ) . c_str ( ) ,
Checkpoints : : GuessVerificationProgress ( pindexBest ) ) ;
2010-08-29 09:58:15 -07:00
2012-06-27 10:51:51 -07:00
// Check the version of the last 100 blocks to see if we need to upgrade:
if ( ! fIsInitialDownload )
{
int nUpgraded = 0 ;
const CBlockIndex * pindex = pindexBest ;
for ( int i = 0 ; i < 100 & & pindex ! = NULL ; i + + )
{
if ( pindex - > nVersion > CBlock : : CURRENT_VERSION )
+ + nUpgraded ;
pindex = pindex - > pprev ;
}
if ( nUpgraded > 0 )
printf ( " SetBestChain: %d of last 100 blocks above version %d \n " , nUpgraded , CBlock : : CURRENT_VERSION ) ;
if ( nUpgraded > 100 / 2 )
// strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
2012-07-26 23:36:43 -07:00
strMiscWarning = _ ( " Warning: This version is obsolete, upgrade required! " ) ;
2012-06-27 10:51:51 -07:00
}
2012-01-03 12:24:28 -08: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 09:58:15 -07:00
return true ;
}
2013-01-26 15:14:11 -08:00
bool CBlock : : AddToBlockIndex ( CValidationState & state , const CDiskBlockPos & pos )
2010-08-29 09:58:15 -07:00
{
// Check for duplicate
uint256 hash = GetHash ( ) ;
if ( mapBlockIndex . count ( hash ) )
2013-04-06 18:40:33 -07:00
return state . Invalid ( error ( " AddToBlockIndex() : %s already exists " , hash . ToString ( ) . c_str ( ) ) ) ;
2010-08-29 09:58:15 -07:00
// Construct new block index object
2012-06-18 16:36:43 -07:00
CBlockIndex * pindexNew = new CBlockIndex ( * this ) ;
2013-01-26 16:24:06 -08:00
assert ( pindexNew ) ;
2010-08-29 09:58:15 -07:00
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 ;
}
2012-08-18 15:33:01 -07:00
pindexNew - > nTx = vtx . size ( ) ;
2013-03-28 15:51:50 -07:00
pindexNew - > nChainWork = ( pindexNew - > pprev ? pindexNew - > pprev - > nChainWork : 0 ) + pindexNew - > GetBlockWork ( ) . getuint256 ( ) ;
2012-08-18 15:33:01 -07:00
pindexNew - > nChainTx = ( pindexNew - > pprev ? pindexNew - > pprev - > nChainTx : 0 ) + pindexNew - > nTx ;
pindexNew - > nFile = pos . nFile ;
pindexNew - > nDataPos = pos . nPos ;
2012-08-13 10:11:05 -07:00
pindexNew - > nUndoPos = 0 ;
2012-08-18 15:33:01 -07:00
pindexNew - > nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA ;
setBlockIndexValid . insert ( pindexNew ) ;
2010-08-29 09:58:15 -07:00
2013-01-26 15:14:11 -08:00
if ( ! pblocktree - > WriteBlockIndex ( CDiskBlockIndex ( pindexNew ) ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write block index " ) ) ;
2010-08-29 09:58:15 -07:00
2012-08-18 15:33:01 -07:00
// New best?
2013-01-26 15:14:11 -08:00
if ( ! ConnectBestBlock ( state ) )
2012-07-06 07:33:34 -07:00
return false ;
2010-08-29 09:58:15 -07:00
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 09:28:20 -07:00
UpdatedTransaction ( hashPrevBestCoinBase ) ;
2012-07-07 15:06:34 -07:00
hashPrevBestCoinBase = GetTxHash ( 0 ) ;
2010-08-29 09:58:15 -07:00
}
2013-01-26 15:14:11 -08:00
if ( ! pblocktree - > Flush ( ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to sync block index " ) ) ;
2012-09-03 06:26:57 -07:00
2012-05-06 10:40:58 -07:00
uiInterface . NotifyBlocksChanged ( ) ;
2010-08-29 09:58:15 -07:00
return true ;
}
2013-01-26 15:14:11 -08:00
bool FindBlockPos ( CValidationState & state , CDiskBlockPos & pos , unsigned int nAddSize , unsigned int nHeight , uint64 nTime , bool fKnown = false )
2012-08-13 10:11:05 -07:00
{
bool fUpdatedLast = false ;
LOCK ( cs_LastBlockFile ) ;
2012-10-21 12:23:13 -07:00
if ( fKnown ) {
if ( nLastBlockFile ! = pos . nFile ) {
nLastBlockFile = pos . nFile ;
infoLastBlockFile . SetNull ( ) ;
pblocktree - > ReadBlockFileInfo ( nLastBlockFile , infoLastBlockFile ) ;
2012-12-04 14:46:30 -08:00
fUpdatedLast = true ;
2012-10-21 12:23:13 -07:00
}
} else {
while ( infoLastBlockFile . nSize + nAddSize > = MAX_BLOCKFILE_SIZE ) {
printf ( " Leaving block file %i: %s \n " , nLastBlockFile , infoLastBlockFile . ToString ( ) . c_str ( ) ) ;
2013-01-29 19:17:33 -08:00
FlushBlockFile ( true ) ;
2012-10-21 12:23:13 -07:00
nLastBlockFile + + ;
infoLastBlockFile . SetNull ( ) ;
pblocktree - > ReadBlockFileInfo ( nLastBlockFile , infoLastBlockFile ) ; // check whether data for the new file somehow already exist; can fail just fine
fUpdatedLast = true ;
}
pos . nFile = nLastBlockFile ;
pos . nPos = infoLastBlockFile . nSize ;
2012-08-13 10:11:05 -07:00
}
infoLastBlockFile . nSize + = nAddSize ;
infoLastBlockFile . AddBlock ( nHeight , nTime ) ;
2012-10-21 12:23:13 -07:00
if ( ! fKnown ) {
unsigned int nOldChunks = ( pos . nPos + BLOCKFILE_CHUNK_SIZE - 1 ) / BLOCKFILE_CHUNK_SIZE ;
unsigned int nNewChunks = ( infoLastBlockFile . nSize + BLOCKFILE_CHUNK_SIZE - 1 ) / BLOCKFILE_CHUNK_SIZE ;
if ( nNewChunks > nOldChunks ) {
2012-12-03 22:48:57 -08:00
if ( CheckDiskSpace ( nNewChunks * BLOCKFILE_CHUNK_SIZE - pos . nPos ) ) {
FILE * file = OpenBlockFile ( pos ) ;
if ( file ) {
printf ( " Pre-allocating up to position 0x%x in blk%05u.dat \n " , nNewChunks * BLOCKFILE_CHUNK_SIZE , pos . nFile ) ;
AllocateFileRange ( file , pos . nPos , nNewChunks * BLOCKFILE_CHUNK_SIZE - pos . nPos ) ;
fclose ( file ) ;
}
2012-10-21 12:23:13 -07:00
}
2012-12-03 22:48:57 -08:00
else
2013-01-26 16:24:06 -08:00
return state . Error ( ) ;
2012-08-15 17:21:28 -07:00
}
}
2012-09-03 06:26:57 -07:00
if ( ! pblocktree - > WriteBlockFileInfo ( nLastBlockFile , infoLastBlockFile ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write file info " ) ) ;
2012-08-13 10:11:05 -07:00
if ( fUpdatedLast )
2012-09-03 06:26:57 -07:00
pblocktree - > WriteLastBlockFile ( nLastBlockFile ) ;
2012-08-13 10:11:05 -07:00
return true ;
}
2013-01-26 15:14:11 -08:00
bool FindUndoPos ( CValidationState & state , int nFile , CDiskBlockPos & pos , unsigned int nAddSize )
2012-08-13 10:11:05 -07:00
{
pos . nFile = nFile ;
LOCK ( cs_LastBlockFile ) ;
2012-08-15 17:21:28 -07:00
unsigned int nNewSize ;
2012-08-13 10:11:05 -07:00
if ( nFile = = nLastBlockFile ) {
pos . nPos = infoLastBlockFile . nUndoSize ;
2012-08-15 17:21:28 -07:00
nNewSize = ( infoLastBlockFile . nUndoSize + = nAddSize ) ;
2012-09-03 06:26:57 -07:00
if ( ! pblocktree - > WriteBlockFileInfo ( nLastBlockFile , infoLastBlockFile ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write block info " ) ) ;
2012-08-15 17:21:28 -07:00
} else {
CBlockFileInfo info ;
2012-09-03 06:26:57 -07:00
if ( ! pblocktree - > ReadBlockFileInfo ( nFile , info ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to read block info " ) ) ;
2012-08-15 17:21:28 -07:00
pos . nPos = info . nUndoSize ;
nNewSize = ( info . nUndoSize + = nAddSize ) ;
2012-09-03 06:26:57 -07:00
if ( ! pblocktree - > WriteBlockFileInfo ( nFile , info ) )
2013-01-28 16:44:19 -08:00
return state . Abort ( _ ( " Failed to write block info " ) ) ;
2012-08-15 17:21:28 -07:00
}
unsigned int nOldChunks = ( pos . nPos + UNDOFILE_CHUNK_SIZE - 1 ) / UNDOFILE_CHUNK_SIZE ;
unsigned int nNewChunks = ( nNewSize + UNDOFILE_CHUNK_SIZE - 1 ) / UNDOFILE_CHUNK_SIZE ;
if ( nNewChunks > nOldChunks ) {
2012-12-03 22:48:57 -08:00
if ( CheckDiskSpace ( nNewChunks * UNDOFILE_CHUNK_SIZE - pos . nPos ) ) {
FILE * file = OpenUndoFile ( pos ) ;
if ( file ) {
printf ( " Pre-allocating up to position 0x%x in rev%05u.dat \n " , nNewChunks * UNDOFILE_CHUNK_SIZE , pos . nFile ) ;
AllocateFileRange ( file , pos . nPos , nNewChunks * UNDOFILE_CHUNK_SIZE - pos . nPos ) ;
fclose ( file ) ;
}
2012-08-15 17:21:28 -07:00
}
2012-12-03 22:48:57 -08:00
else
2013-01-26 16:24:06 -08:00
return state . Error ( ) ;
2012-08-13 10:11:05 -07:00
}
return true ;
}
2010-08-29 09:58:15 -07:00
2013-01-26 15:14:11 -08:00
bool CBlock : : CheckBlock ( CValidationState & state , bool fCheckPOW , bool fCheckMerkleRoot ) const
2010-08-29 09:58:15 -07:00
{
// These are checks that are independent of context
// that can be verified before saving an orphan block.
// Size limits
2012-04-16 05:56:45 -07:00
if ( vtx . empty ( ) | | vtx . size ( ) > MAX_BLOCK_SIZE | | : : GetSerializeSize ( * this , SER_NETWORK , PROTOCOL_VERSION ) > MAX_BLOCK_SIZE )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckBlock() : size limits failed " ) ) ;
2010-08-29 09:58:15 -07:00
2010-09-19 14:20:34 -07:00
// Check proof of work matches claimed amount
2012-05-09 10:24:44 -07:00
if ( fCheckPOW & & ! CheckProofOfWork ( GetHash ( ) , nBits ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 50 , error ( " CheckBlock() : proof of work failed " ) ) ;
2010-09-19 14:20:34 -07:00
2010-08-29 09:58:15 -07:00
// Check timestamp
if ( GetBlockTime ( ) > GetAdjustedTime ( ) + 2 * 60 * 60 )
2013-01-26 15:14:11 -08:00
return state . Invalid ( error ( " CheckBlock() : block timestamp too far in the future " ) ) ;
2010-08-29 09:58:15 -07:00
// First transaction must be coinbase, the rest must not be
if ( vtx . empty ( ) | | ! vtx [ 0 ] . IsCoinBase ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckBlock() : first tx is not coinbase " ) ) ;
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 1 ; i < vtx . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
if ( vtx [ i ] . IsCoinBase ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckBlock() : more than one coinbase " ) ) ;
2010-08-29 09:58:15 -07:00
// Check transactions
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CTransaction & tx , vtx )
2013-01-26 15:14:11 -08:00
if ( ! tx . CheckTransaction ( state ) )
return error ( " CheckBlock() : CheckTransaction failed " ) ;
2010-08-29 09:58:15 -07:00
2012-10-22 15:21:16 -07:00
// Build the merkle tree already. We need it anyway later, and it makes the
// block cache the transaction hashes, which means they don't need to be
// recalculated many times during this block's validation.
BuildMerkleTree ( ) ;
2012-04-29 17:56:55 -07:00
// Check for duplicate txids. This is caught by ConnectInputs(),
// but catching it earlier avoids a potential DoS attack:
set < uint256 > uniqueTx ;
2012-07-07 15:06:34 -07:00
for ( unsigned int i = 0 ; i < vtx . size ( ) ; i + + ) {
uniqueTx . insert ( GetTxHash ( i ) ) ;
2012-04-29 17:56:55 -07:00
}
if ( uniqueTx . size ( ) ! = vtx . size ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckBlock() : duplicate transaction " ) ) ;
2012-04-29 17:56:55 -07:00
2012-04-23 11:14:03 -07:00
unsigned int nSigOps = 0 ;
2011-10-03 10:05:43 -07:00
BOOST_FOREACH ( const CTransaction & tx , vtx )
{
2012-01-04 18:40:52 -08:00
nSigOps + = tx . GetLegacySigOpCount ( ) ;
2011-10-03 10:05:43 -07:00
}
if ( nSigOps > MAX_BLOCK_SIGOPS )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckBlock() : out-of-bounds SigOpCount " ) ) ;
2010-08-29 09:58:15 -07:00
2012-07-25 17:48:39 -07:00
// Check merkle root
2012-05-09 10:24:44 -07:00
if ( fCheckMerkleRoot & & hashMerkleRoot ! = BuildMerkleTree ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " CheckBlock() : hashMerkleRoot mismatch " ) ) ;
2010-08-29 09:58:15 -07:00
return true ;
}
2013-01-26 15:14:11 -08:00
bool CBlock : : AcceptBlock ( CValidationState & state , CDiskBlockPos * dbp )
2010-08-29 09:58:15 -07:00
{
// Check for duplicate
uint256 hash = GetHash ( ) ;
if ( mapBlockIndex . count ( hash ) )
2013-01-26 15:14:11 -08:00
return state . Invalid ( error ( " AcceptBlock() : block already in mapBlockIndex " ) ) ;
2010-08-29 09:58:15 -07:00
// Get prev block index
2012-10-21 12:23:13 -07:00
CBlockIndex * pindexPrev = NULL ;
int nHeight = 0 ;
if ( hash ! = hashGenesisBlock ) {
2012-11-10 05:26:34 -08:00
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( hashPrevBlock ) ;
if ( mi = = mapBlockIndex . end ( ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 10 , error ( " AcceptBlock() : prev block not found " ) ) ;
2012-11-10 05:26:34 -08:00
pindexPrev = ( * mi ) . second ;
nHeight = pindexPrev - > nHeight + 1 ;
// Check proof of work
if ( nBits ! = GetNextWorkRequired ( pindexPrev , this ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " AcceptBlock() : incorrect proof of work " ) ) ;
2012-11-10 05:26:34 -08:00
// Check timestamp against prev
if ( GetBlockTime ( ) < = pindexPrev - > GetMedianTimePast ( ) )
2013-01-26 15:14:11 -08:00
return state . Invalid ( error ( " AcceptBlock() : block's timestamp is too early " ) ) ;
2012-11-10 05:26:34 -08:00
// Check that all transactions are finalized
BOOST_FOREACH ( const CTransaction & tx , vtx )
if ( ! tx . IsFinal ( nHeight , GetBlockTime ( ) ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 10 , error ( " AcceptBlock() : contains a non-final transaction " ) ) ;
2012-11-10 05:26:34 -08:00
// Check that the block chain matches the known block chain up to a checkpoint
if ( ! Checkpoints : : CheckBlock ( nHeight , hash ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " AcceptBlock() : rejected by checkpoint lock-in at %d " , nHeight ) ) ;
2012-11-10 05:26:34 -08:00
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
if ( nVersion < 2 )
2012-07-05 18:22:16 -07:00
{
2012-11-10 05:26:34 -08:00
if ( ( ! fTestNet & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 950 , 1000 ) ) | |
( fTestNet & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 75 , 100 ) ) )
{
2013-01-26 15:14:11 -08:00
return state . Invalid ( error ( " AcceptBlock() : rejected nVersion=1 block " ) ) ;
2012-11-10 05:26:34 -08:00
}
2012-07-05 18:22:16 -07:00
}
2012-11-10 05:26:34 -08:00
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
if ( nVersion > = 2 )
2012-06-27 16:30:39 -07:00
{
2012-11-10 05:26:34 -08:00
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
if ( ( ! fTestNet & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 750 , 1000 ) ) | |
( fTestNet & & CBlockIndex : : IsSuperMajority ( 2 , pindexPrev , 51 , 100 ) ) )
{
CScript expect = CScript ( ) < < nHeight ;
if ( ! std : : equal ( expect . begin ( ) , expect . end ( ) , vtx [ 0 ] . vin [ 0 ] . scriptSig . begin ( ) ) )
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " AcceptBlock() : block height mismatch in coinbase " ) ) ;
2012-11-10 05:26:34 -08:00
}
2012-06-27 16:30:39 -07:00
}
}
2010-08-29 09:58:15 -07:00
// Write block to history file
2013-01-28 16:44:19 -08:00
try {
unsigned int nBlockSize = : : GetSerializeSize ( * this , SER_DISK , CLIENT_VERSION ) ;
CDiskBlockPos blockPos ;
if ( dbp ! = NULL )
blockPos = * dbp ;
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , nHeight , nTime , dbp ! = NULL ) )
return error ( " AcceptBlock() : FindBlockPos failed " ) ;
if ( dbp = = NULL )
if ( ! WriteToDisk ( blockPos ) )
return state . Abort ( _ ( " Failed to write block " ) ) ;
if ( ! AddToBlockIndex ( state , blockPos ) )
return error ( " AcceptBlock() : AddToBlockIndex failed " ) ;
} catch ( std : : runtime_error & e ) {
return state . Abort ( _ ( " System error: " ) + e . what ( ) ) ;
}
2010-08-29 09:58:15 -07:00
// Relay inventory, but don't relay old inventory during initial block download
2012-03-20 10:45:45 -07:00
int nBlockEstimate = Checkpoints : : GetTotalBlocksEstimate ( ) ;
2010-08-29 09:58:15 -07:00
if ( hashBestChain = = hash )
2012-04-06 09:39:12 -07: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 09:58:15 -07:00
return true ;
}
2012-06-27 16:30:39 -07:00
bool CBlockIndex : : IsSuperMajority ( int minVersion , const CBlockIndex * pstart , unsigned int nRequired , unsigned int nToCheck )
{
unsigned int nFound = 0 ;
for ( unsigned int i = 0 ; i < nToCheck & & nFound < nRequired & & pstart ! = NULL ; i + + )
{
if ( pstart - > nVersion > = minVersion )
+ + nFound ;
pstart = pstart - > pprev ;
}
return ( nFound > = nRequired ) ;
}
2013-01-07 06:39:53 -08:00
void PushGetBlocks ( CNode * pnode , CBlockIndex * pindexBegin , uint256 hashEnd )
{
// Filter out duplicate requests
if ( pindexBegin = = pnode - > pindexLastGetBlocksBegin & & hashEnd = = pnode - > hashLastGetBlocksEnd )
return ;
pnode - > pindexLastGetBlocksBegin = pindexBegin ;
pnode - > hashLastGetBlocksEnd = hashEnd ;
pnode - > PushMessage ( " getblocks " , CBlockLocator ( pindexBegin ) , hashEnd ) ;
}
2013-01-26 15:14:11 -08:00
bool ProcessBlock ( CValidationState & state , CNode * pfrom , CBlock * pblock , CDiskBlockPos * dbp )
2010-08-29 09:58:15 -07:00
{
// Check for duplicate
uint256 hash = pblock - > GetHash ( ) ;
if ( mapBlockIndex . count ( hash ) )
2013-04-06 18:40:33 -07:00
return state . Invalid ( error ( " ProcessBlock() : already have block %d %s " , mapBlockIndex [ hash ] - > nHeight , hash . ToString ( ) . c_str ( ) ) ) ;
2010-08-29 09:58:15 -07:00
if ( mapOrphanBlocks . count ( hash ) )
2013-04-06 18:40:33 -07:00
return state . Invalid ( error ( " ProcessBlock() : already have block (orphan) %s " , hash . ToString ( ) . c_str ( ) ) ) ;
2010-08-29 09:58:15 -07:00
// Preliminary checks
2013-01-26 15:14:11 -08:00
if ( ! pblock - > CheckBlock ( state ) )
2010-08-29 09:58:15 -07:00
return error ( " ProcessBlock() : CheckBlock FAILED " ) ;
2011-09-08 09:51:43 -07: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 13:33:19 -08:00
int64 deltaTime = pblock - > GetBlockTime ( ) - pcheckpoint - > nTime ;
2011-09-08 09:51:43 -07:00
if ( deltaTime < 0 )
{
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " ProcessBlock() : block with timestamp before last checkpoint " ) ) ;
2011-09-08 09:51:43 -07:00
}
CBigNum bnNewBlock ;
bnNewBlock . SetCompact ( pblock - > nBits ) ;
CBigNum bnRequired ;
bnRequired . SetCompact ( ComputeMinWork ( pcheckpoint - > nBits , deltaTime ) ) ;
if ( bnNewBlock > bnRequired )
{
2013-01-26 15:14:11 -08:00
return state . DoS ( 100 , error ( " ProcessBlock() : block with too little proof-of-work " ) ) ;
2011-09-08 09:51:43 -07:00
}
}
2012-08-21 10:18:53 -07:00
// If we don't already have its previous block, shunt it off to holding area until we get it
2012-10-21 12:23:13 -07:00
if ( pblock - > hashPrevBlock ! = 0 & & ! mapBlockIndex . count ( pblock - > hashPrevBlock ) )
2010-08-29 09:58:15 -07:00
{
2013-04-06 18:40:33 -07:00
printf ( " ProcessBlock: ORPHAN BLOCK, prev=%s \n " , pblock - > hashPrevBlock . ToString ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
2012-08-21 10:18:53 -07:00
// Accept orphans as long as there is a node to request its parents from
if ( pfrom ) {
CBlock * pblock2 = new CBlock ( * pblock ) ;
mapOrphanBlocks . insert ( make_pair ( hash , pblock2 ) ) ;
mapOrphanBlocksByPrev . insert ( make_pair ( pblock2 - > hashPrevBlock , pblock2 ) ) ;
// Ask this guy to fill in what we're missing
2013-01-07 06:39:53 -08:00
PushGetBlocks ( pfrom , pindexBest , GetOrphanRoot ( pblock2 ) ) ;
2012-08-21 10:18:53 -07:00
}
2010-08-29 09:58:15 -07:00
return true ;
}
// Store to disk
2013-01-26 15:14:11 -08:00
if ( ! pblock - > AcceptBlock ( state , dbp ) )
2010-08-29 09:58:15 -07:00
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 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vWorkQueue . size ( ) ; i + + )
2010-08-29 09:58:15 -07: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 ;
2013-01-30 19:53:21 -08:00
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid block based on LegitBlockX in order to get anyone relaying LegitBlockX banned)
CValidationState stateDummy ;
if ( pblockOrphan - > AcceptBlock ( stateDummy ) )
2010-08-29 09:58:15 -07:00
vWorkQueue . push_back ( pblockOrphan - > GetHash ( ) ) ;
mapOrphanBlocks . erase ( pblockOrphan - > GetHash ( ) ) ;
delete pblockOrphan ;
}
mapOrphanBlocksByPrev . erase ( hashPrev ) ;
}
printf ( " ProcessBlock: ACCEPTED \n " ) ;
return true ;
}
2012-08-18 20:40:00 -07:00
CMerkleBlock : : CMerkleBlock ( const CBlock & block , CBloomFilter & filter )
{
header = block . GetBlockHeader ( ) ;
2012-11-08 13:26:25 -08:00
vector < bool > vMatch ;
vector < uint256 > vHashes ;
vMatch . reserve ( block . vtx . size ( ) ) ;
vHashes . reserve ( block . vtx . size ( ) ) ;
for ( unsigned int i = 0 ; i < block . vtx . size ( ) ; i + + )
2012-08-18 20:40:00 -07:00
{
uint256 hash = block . vtx [ i ] . GetHash ( ) ;
if ( filter . IsRelevantAndUpdate ( block . vtx [ i ] , hash ) )
{
2012-11-08 13:26:25 -08:00
vMatch . push_back ( true ) ;
vMatchedTxn . push_back ( make_pair ( i , hash ) ) ;
2012-08-18 20:40:00 -07:00
}
2012-11-08 13:26:25 -08:00
else
vMatch . push_back ( false ) ;
vHashes . push_back ( hash ) ;
2012-08-18 20:40:00 -07:00
}
2012-11-08 13:26:25 -08:00
txn = CPartialMerkleTree ( vHashes , vMatch ) ;
2012-08-18 20:40:00 -07:00
}
2012-10-27 12:08:45 -07:00
uint256 CPartialMerkleTree : : CalcHash ( int height , unsigned int pos , const std : : vector < uint256 > & vTxid ) {
if ( height = = 0 ) {
// hash at height 0 is the txids themself
return vTxid [ pos ] ;
} else {
// calculate left hash
uint256 left = CalcHash ( height - 1 , pos * 2 , vTxid ) , right ;
// calculate right hash if not beyong the end of the array - copy left hash otherwise1
if ( pos * 2 + 1 < CalcTreeWidth ( height - 1 ) )
right = CalcHash ( height - 1 , pos * 2 + 1 , vTxid ) ;
else
right = left ;
// combine subhashes
return Hash ( BEGIN ( left ) , END ( left ) , BEGIN ( right ) , END ( right ) ) ;
}
}
void CPartialMerkleTree : : TraverseAndBuild ( int height , unsigned int pos , const std : : vector < uint256 > & vTxid , const std : : vector < bool > & vMatch ) {
// determine whether this node is the parent of at least one matched txid
bool fParentOfMatch = false ;
for ( unsigned int p = pos < < height ; p < ( pos + 1 ) < < height & & p < nTransactions ; p + + )
fParentOfMatch | = vMatch [ p ] ;
// store as flag bit
vBits . push_back ( fParentOfMatch ) ;
if ( height = = 0 | | ! fParentOfMatch ) {
// if at height 0, or nothing interesting below, store hash and stop
vHash . push_back ( CalcHash ( height , pos , vTxid ) ) ;
} else {
// otherwise, don't store any hash, but descend into the subtrees
TraverseAndBuild ( height - 1 , pos * 2 , vTxid , vMatch ) ;
if ( pos * 2 + 1 < CalcTreeWidth ( height - 1 ) )
TraverseAndBuild ( height - 1 , pos * 2 + 1 , vTxid , vMatch ) ;
}
}
uint256 CPartialMerkleTree : : TraverseAndExtract ( int height , unsigned int pos , unsigned int & nBitsUsed , unsigned int & nHashUsed , std : : vector < uint256 > & vMatch ) {
if ( nBitsUsed > = vBits . size ( ) ) {
// overflowed the bits array - failure
fBad = true ;
return 0 ;
}
bool fParentOfMatch = vBits [ nBitsUsed + + ] ;
if ( height = = 0 | | ! fParentOfMatch ) {
// if at height 0, or nothing interesting below, use stored hash and do not descend
if ( nHashUsed > = vHash . size ( ) ) {
// overflowed the hash array - failure
fBad = true ;
return 0 ;
}
const uint256 & hash = vHash [ nHashUsed + + ] ;
if ( height = = 0 & & fParentOfMatch ) // in case of height 0, we have a matched txid
vMatch . push_back ( hash ) ;
return hash ;
} else {
// otherwise, descend into the subtrees to extract matched txids and hashes
uint256 left = TraverseAndExtract ( height - 1 , pos * 2 , nBitsUsed , nHashUsed , vMatch ) , right ;
if ( pos * 2 + 1 < CalcTreeWidth ( height - 1 ) )
right = TraverseAndExtract ( height - 1 , pos * 2 + 1 , nBitsUsed , nHashUsed , vMatch ) ;
else
right = left ;
// and combine them before returning
return Hash ( BEGIN ( left ) , END ( left ) , BEGIN ( right ) , END ( right ) ) ;
}
}
CPartialMerkleTree : : CPartialMerkleTree ( const std : : vector < uint256 > & vTxid , const std : : vector < bool > & vMatch ) : nTransactions ( vTxid . size ( ) ) , fBad ( false ) {
// reset state
vBits . clear ( ) ;
vHash . clear ( ) ;
// calculate height of tree
int nHeight = 0 ;
while ( CalcTreeWidth ( nHeight ) > 1 )
nHeight + + ;
// traverse the partial tree
TraverseAndBuild ( nHeight , 0 , vTxid , vMatch ) ;
}
CPartialMerkleTree : : CPartialMerkleTree ( ) : nTransactions ( 0 ) , fBad ( true ) { }
uint256 CPartialMerkleTree : : ExtractMatches ( std : : vector < uint256 > & vMatch ) {
vMatch . clear ( ) ;
// An empty set will not work
if ( nTransactions = = 0 )
return 0 ;
// check for excessively high numbers of transactions
if ( nTransactions > MAX_BLOCK_SIZE / 60 ) // 60 is the lower bound for the size of a serialized CTransaction
return 0 ;
// there can never be more hashes provided than one for every txid
if ( vHash . size ( ) > nTransactions )
return 0 ;
// there must be at least one bit per node in the partial tree, and at least one node per hash
if ( vBits . size ( ) < vHash . size ( ) )
return 0 ;
// calculate height of tree
int nHeight = 0 ;
while ( CalcTreeWidth ( nHeight ) > 1 )
nHeight + + ;
// traverse the partial tree
unsigned int nBitsUsed = 0 , nHashUsed = 0 ;
uint256 hashMerkleRoot = TraverseAndExtract ( nHeight , 0 , nBitsUsed , nHashUsed , vMatch ) ;
// verify that no problems occured during the tree traversal
if ( fBad )
return 0 ;
// verify that all bits were consumed (except for the padding caused by serializing it as a byte sequence)
if ( ( nBitsUsed + 7 ) / 8 ! = ( vBits . size ( ) + 7 ) / 8 )
return 0 ;
// verify that all hashes were consumed
if ( nHashUsed ! = vHash . size ( ) )
return 0 ;
return hashMerkleRoot ;
}
2013-01-26 16:24:06 -08:00
bool AbortNode ( const std : : string & strMessage ) {
strMiscWarning = strMessage ;
printf ( " *** %s \n " , strMessage . c_str ( ) ) ;
2013-01-18 06:07:05 -08:00
uiInterface . ThreadSafeMessageBox ( strMessage , " " , CClientUIInterface : : MSG_ERROR ) ;
2013-01-26 16:24:06 -08:00
StartShutdown ( ) ;
return false ;
}
2012-10-27 12:08:45 -07:00
2011-12-21 13:33:19 -08:00
bool CheckDiskSpace ( uint64 nAdditionalBytes )
2010-08-29 09:58:15 -07:00
{
2011-12-21 13:33:19 -08:00
uint64 nFreeBytesAvailable = filesystem : : space ( GetDataDir ( ) ) . available ;
2010-08-29 09:58:15 -07:00
2012-05-13 22:49:17 -07:00
// Check for nMinDiskSpace bytes (currently 50MB)
if ( nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes )
2013-01-26 16:24:06 -08:00
return AbortNode ( _ ( " Error: Disk space is low! " ) ) ;
2010-08-29 09:58:15 -07:00
return true ;
}
2012-08-13 10:11:05 -07:00
CCriticalSection cs_LastBlockFile ;
CBlockFileInfo infoLastBlockFile ;
int nLastBlockFile = 0 ;
FILE * OpenDiskFile ( const CDiskBlockPos & pos , const char * prefix , bool fReadOnly )
2012-09-04 18:40:26 -07:00
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( pos . IsNull ( ) )
2010-08-29 09:58:15 -07:00
return NULL ;
2012-08-13 10:11:05 -07:00
boost : : filesystem : : path path = GetDataDir ( ) / " blocks " / strprintf ( " %s%05u.dat " , prefix , pos . nFile ) ;
boost : : filesystem : : create_directories ( path . parent_path ( ) ) ;
FILE * file = fopen ( path . string ( ) . c_str ( ) , " rb+ " ) ;
if ( ! file & & ! fReadOnly )
file = fopen ( path . string ( ) . c_str ( ) , " wb+ " ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
if ( ! file ) {
printf ( " Unable to open file %s \n " , path . string ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
return NULL ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
}
2012-08-13 10:11:05 -07:00
if ( pos . nPos ) {
if ( fseek ( file , pos . nPos , SEEK_SET ) ) {
printf ( " Unable to seek to position %u of %s \n " , pos . nPos , path . string ( ) . c_str ( ) ) ;
fclose ( file ) ;
return NULL ;
}
}
2010-08-29 09:58:15 -07:00
return file ;
}
2012-08-13 10:11:05 -07:00
FILE * OpenBlockFile ( const CDiskBlockPos & pos , bool fReadOnly ) {
return OpenDiskFile ( pos , " blk " , fReadOnly ) ;
}
2013-01-18 06:07:05 -08:00
FILE * OpenUndoFile ( const CDiskBlockPos & pos , bool fReadOnly ) {
2012-08-13 10:11:05 -07:00
return OpenDiskFile ( pos , " rev " , fReadOnly ) ;
}
2012-09-03 12:14:03 -07:00
CBlockIndex * InsertBlockIndex ( uint256 hash )
{
if ( hash = = 0 )
return NULL ;
// Return existing
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( hash ) ;
if ( mi ! = mapBlockIndex . end ( ) )
return ( * mi ) . second ;
// Create new
CBlockIndex * pindexNew = new CBlockIndex ( ) ;
if ( ! pindexNew )
throw runtime_error ( " LoadBlockIndex() : new CBlockIndex failed " ) ;
mi = mapBlockIndex . insert ( make_pair ( hash , pindexNew ) ) . first ;
pindexNew - > phashBlock = & ( ( * mi ) . first ) ;
return pindexNew ;
}
bool static LoadBlockIndexDB ( )
{
if ( ! pblocktree - > LoadBlockIndexGuts ( ) )
return false ;
2013-03-09 09:02:57 -08:00
boost : : this_thread : : interruption_point ( ) ;
2012-09-03 12:14:03 -07:00
2013-03-28 15:51:50 -07:00
// Calculate nChainWork
2012-09-03 12:14:03 -07:00
vector < pair < int , CBlockIndex * > > vSortedByHeight ;
vSortedByHeight . reserve ( mapBlockIndex . size ( ) ) ;
BOOST_FOREACH ( const PAIRTYPE ( uint256 , CBlockIndex * ) & item , mapBlockIndex )
{
CBlockIndex * pindex = item . second ;
vSortedByHeight . push_back ( make_pair ( pindex - > nHeight , pindex ) ) ;
}
sort ( vSortedByHeight . begin ( ) , vSortedByHeight . end ( ) ) ;
BOOST_FOREACH ( const PAIRTYPE ( int , CBlockIndex * ) & item , vSortedByHeight )
{
CBlockIndex * pindex = item . second ;
2013-03-28 15:51:50 -07:00
pindex - > nChainWork = ( pindex - > pprev ? pindex - > pprev - > nChainWork : 0 ) + pindex - > GetBlockWork ( ) . getuint256 ( ) ;
2012-09-03 12:14:03 -07:00
pindex - > nChainTx = ( pindex - > pprev ? pindex - > pprev - > nChainTx : 0 ) + pindex - > nTx ;
if ( ( pindex - > nStatus & BLOCK_VALID_MASK ) > = BLOCK_VALID_TRANSACTIONS & & ! ( pindex - > nStatus & BLOCK_FAILED_MASK ) )
setBlockIndexValid . insert ( pindex ) ;
}
// Load block file info
pblocktree - > ReadLastBlockFile ( nLastBlockFile ) ;
2013-01-18 06:07:05 -08:00
printf ( " LoadBlockIndexDB(): last block file = %i \n " , nLastBlockFile ) ;
2012-09-03 12:14:03 -07:00
if ( pblocktree - > ReadBlockFileInfo ( nLastBlockFile , infoLastBlockFile ) )
2013-01-18 06:07:05 -08:00
printf ( " LoadBlockIndexDB(): last block file info: %s \n " , infoLastBlockFile . ToString ( ) . c_str ( ) ) ;
2012-10-05 10:22:21 -07:00
2013-03-28 15:51:50 -07:00
// Load nBestInvalidWork, OK if it doesn't exist
CBigNum bnBestInvalidWork ;
2012-12-02 12:59:22 -08:00
pblocktree - > ReadBestInvalidWork ( bnBestInvalidWork ) ;
2013-03-28 15:51:50 -07:00
nBestInvalidWork = bnBestInvalidWork . getuint256 ( ) ;
2012-12-02 12:59:22 -08:00
// Check whether we need to continue reindexing
bool fReindexing = false ;
pblocktree - > ReadReindexing ( fReindexing ) ;
fReindex | = fReindexing ;
2013-01-10 16:47:57 -08:00
// Check whether we have a transaction index
pblocktree - > ReadFlag ( " txindex " , fTxIndex ) ;
2013-01-18 06:07:05 -08:00
printf ( " LoadBlockIndexDB(): transaction index %s \n " , fTxIndex ? " enabled " : " disabled " ) ;
2013-01-10 16:47:57 -08:00
2012-09-03 12:14:03 -07:00
// Load hashBestChain pointer to end of best chain
pindexBest = pcoinsTip - > GetBestBlock ( ) ;
if ( pindexBest = = NULL )
2012-12-02 12:59:22 -08:00
return true ;
2012-09-03 12:14:03 -07:00
hashBestChain = pindexBest - > GetBlockHash ( ) ;
nBestHeight = pindexBest - > nHeight ;
2013-03-28 15:51:50 -07:00
nBestChainWork = pindexBest - > nChainWork ;
2012-09-03 12:14:03 -07:00
2013-05-12 06:50:22 -07:00
// register best chain
2012-09-03 12:14:03 -07:00
CBlockIndex * pindex = pindexBest ;
2013-05-12 06:50:22 -07:00
vBlockIndexByHeight . resize ( pindexBest - > nHeight + 1 ) ;
while ( pindex ! = NULL ) {
vBlockIndexByHeight [ pindex - > nHeight ] = pindex ;
pindex = pindex - > pprev ;
2012-09-03 12:14:03 -07:00
}
2013-01-18 06:07:05 -08:00
printf ( " LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s \n " ,
2013-04-06 18:40:33 -07:00
hashBestChain . ToString ( ) . c_str ( ) , nBestHeight ,
2013-01-01 12:28:28 -08:00
DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , pindexBest - > GetBlockTime ( ) ) . c_str ( ) ) ;
2012-09-03 12:14:03 -07:00
2013-01-03 06:29:07 -08:00
return true ;
}
bool VerifyDB ( ) {
if ( pindexBest = = NULL | | pindexBest - > pprev = = NULL )
return true ;
2012-09-03 12:14:03 -07:00
// Verify blocks in the best chain
2013-01-03 06:29:07 -08:00
int nCheckLevel = GetArg ( " -checklevel " , 3 ) ;
2013-01-26 09:57:07 -08:00
int nCheckDepth = GetArg ( " -checkblocks " , 288 ) ;
2012-09-03 12:14:03 -07:00
if ( nCheckDepth = = 0 )
nCheckDepth = 1000000000 ; // suffices until the year 19000
if ( nCheckDepth > nBestHeight )
nCheckDepth = nBestHeight ;
2013-01-03 06:29:07 -08:00
nCheckLevel = std : : max ( 0 , std : : min ( 4 , nCheckLevel ) ) ;
2012-09-03 12:14:03 -07:00
printf ( " Verifying last %i blocks at level %i \n " , nCheckDepth , nCheckLevel ) ;
2013-01-03 06:29:07 -08:00
CCoinsViewCache coins ( * pcoinsTip , true ) ;
CBlockIndex * pindexState = pindexBest ;
CBlockIndex * pindexFailure = NULL ;
int nGoodTransactions = 0 ;
2013-01-26 15:14:11 -08:00
CValidationState state ;
2012-09-03 12:14:03 -07:00
for ( CBlockIndex * pindex = pindexBest ; pindex & & pindex - > pprev ; pindex = pindex - > pprev )
{
2013-03-09 09:02:57 -08:00
boost : : this_thread : : interruption_point ( ) ;
if ( pindex - > nHeight < nBestHeight - nCheckDepth )
2012-09-03 12:14:03 -07:00
break ;
CBlock block ;
2013-01-03 06:29:07 -08:00
// check level 0: read from disk
2012-09-03 12:14:03 -07:00
if ( ! block . ReadFromDisk ( pindex ) )
2013-01-03 06:29:07 -08:00
return error ( " VerifyDB() : * * * block . ReadFromDisk failed at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString().c_str()) ;
2012-09-03 12:14:03 -07:00
// check level 1: verify block validity
2013-01-26 15:14:11 -08:00
if ( nCheckLevel > = 1 & & ! block . CheckBlock ( state ) )
2013-01-03 06:29:07 -08:00
return error ( " VerifyDB() : * * * found bad block at % d , hash = % s \ n " , pindex->nHeight, pindex->GetBlockHash().ToString().c_str()) ;
// check level 2: verify undo validity
if ( nCheckLevel > = 2 & & pindex ) {
CBlockUndo undo ;
CDiskBlockPos pos = pindex - > GetUndoPos ( ) ;
if ( ! pos . IsNull ( ) ) {
if ( ! undo . ReadFromDisk ( pos , pindex - > pprev - > GetBlockHash ( ) ) )
return error ( " VerifyDB() : * * * found bad undo data at % d , hash = % s \ n " , pindex->nHeight, pindex->GetBlockHash().ToString().c_str()) ;
}
}
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
if ( nCheckLevel > = 3 & & pindex = = pindexState & & ( coins . GetCacheSize ( ) + pcoinsTip - > GetCacheSize ( ) ) < = 2 * nCoinCacheSize + 32000 ) {
bool fClean = true ;
2013-01-26 15:14:11 -08:00
if ( ! block . DisconnectBlock ( state , pindex , coins , & fClean ) )
2013-01-03 06:29:07 -08:00
return error ( " VerifyDB() : * * * irrecoverable inconsistency in block data at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString().c_str()) ;
pindexState = pindex - > pprev ;
if ( ! fClean ) {
nGoodTransactions = 0 ;
pindexFailure = pindex ;
} else
nGoodTransactions + = block . vtx . size ( ) ;
2012-09-03 12:14:03 -07:00
}
}
2013-01-03 06:29:07 -08:00
if ( pindexFailure )
return error ( " VerifyDB() : * * * coin database inconsistencies found ( last % i blocks , % i good transactions before that ) \ n " , pindexBest->nHeight - pindexFailure->nHeight + 1, nGoodTransactions) ;
// check level 4: try reconnecting blocks
if ( nCheckLevel > = 4 ) {
CBlockIndex * pindex = pindexState ;
2013-03-09 09:02:57 -08:00
while ( pindex ! = pindexBest ) {
boost : : this_thread : : interruption_point ( ) ;
2013-05-12 06:50:22 -07:00
pindex = pindex - > GetNextInMainChain ( ) ;
2013-04-04 02:30:55 -07:00
CBlock block ;
if ( ! block . ReadFromDisk ( pindex ) )
return error ( " VerifyDB() : * * * block . ReadFromDisk failed at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString().c_str()) ;
if ( ! block . ConnectBlock ( state , pindex , coins ) )
return error ( " VerifyDB() : * * * found unconnectable block at % d , hash = % s " , pindex->nHeight, pindex->GetBlockHash().ToString().c_str()) ;
2013-01-03 06:29:07 -08:00
}
2012-09-03 12:14:03 -07:00
}
2013-01-03 06:29:07 -08:00
printf ( " No coin database inconsistencies in last %i blocks (%i transactions) \n " , pindexBest - > nHeight - pindexState - > nHeight , nGoodTransactions ) ;
2012-09-03 12:14:03 -07:00
return true ;
}
2013-02-16 08:58:45 -08:00
void UnloadBlockIndex ( )
{
mapBlockIndex . clear ( ) ;
setBlockIndexValid . clear ( ) ;
pindexGenesisBlock = NULL ;
nBestHeight = 0 ;
2013-03-28 15:51:50 -07:00
nBestChainWork = 0 ;
nBestInvalidWork = 0 ;
2013-02-16 08:58:45 -08:00
hashBestChain = 0 ;
pindexBest = NULL ;
}
2012-10-21 12:23:13 -07:00
bool LoadBlockIndex ( )
2010-08-29 09:58:15 -07:00
{
2010-10-19 10:16:51 -07:00
if ( fTestNet )
{
2012-07-26 14:20:20 -07:00
pchMessageStart [ 0 ] = 0x0b ;
pchMessageStart [ 1 ] = 0x11 ;
pchMessageStart [ 2 ] = 0x09 ;
pchMessageStart [ 3 ] = 0x07 ;
2012-04-12 18:26:35 -07:00
hashGenesisBlock = uint256 ( " 000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943 " ) ;
2010-10-19 10:16:51 -07:00
}
2010-08-29 09:58:15 -07:00
//
2012-09-03 06:26:57 -07:00
// Load block index from databases
2010-08-29 09:58:15 -07:00
//
2013-01-10 16:47:57 -08:00
if ( ! fReindex & & ! LoadBlockIndexDB ( ) )
2010-08-29 09:58:15 -07:00
return false ;
2013-01-30 12:43:36 -08:00
return true ;
}
2013-01-10 16:47:57 -08:00
2013-01-30 12:43:36 -08:00
bool InitBlockIndex ( ) {
// Check whether we're already initialized
if ( pindexGenesisBlock ! = NULL )
return true ;
// Use the provided setting for -txindex in the new database
fTxIndex = GetBoolArg ( " -txindex " , false ) ;
pblocktree - > WriteFlag ( " txindex " , fTxIndex ) ;
printf ( " Initializing databases... \n " ) ;
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
if ( ! fReindex ) {
2010-08-29 09:58:15 -07:00
// 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 10:16:51 -07:00
if ( fTestNet )
{
2011-02-03 05:21:21 -08:00
block . nTime = 1296688602 ;
2012-04-12 18:26:35 -07:00
block . nNonce = 414098458 ;
2010-10-19 10:16:51 -07:00
}
2010-08-29 09:58:15 -07:00
2010-10-19 10:16:51 -07:00
//// debug print
2012-06-18 16:36:43 -07:00
uint256 hash = block . GetHash ( ) ;
printf ( " %s \n " , hash . ToString ( ) . c_str ( ) ) ;
2010-10-19 10:16:51 -07:00
printf ( " %s \n " , hashGenesisBlock . ToString ( ) . c_str ( ) ) ;
printf ( " %s \n " , block . hashMerkleRoot . ToString ( ) . c_str ( ) ) ;
assert ( block . hashMerkleRoot = = uint256 ( " 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b " ) ) ;
block . print ( ) ;
2012-06-18 16:36:43 -07:00
assert ( hash = = hashGenesisBlock ) ;
2010-08-29 09:58:15 -07:00
// Start new block file
2013-01-30 12:43:36 -08:00
try {
unsigned int nBlockSize = : : GetSerializeSize ( block , SER_DISK , CLIENT_VERSION ) ;
CDiskBlockPos blockPos ;
CValidationState state ;
if ( ! FindBlockPos ( state , blockPos , nBlockSize + 8 , 0 , block . nTime ) )
2013-01-18 06:07:05 -08:00
return error ( " LoadBlockIndex() : FindBlockPos failed " ) ;
2013-01-30 12:43:36 -08:00
if ( ! block . WriteToDisk ( blockPos ) )
return error ( " LoadBlockIndex() : writing genesis block to disk failed " ) ;
if ( ! block . AddToBlockIndex ( state , blockPos ) )
return error ( " LoadBlockIndex() : genesis block not accepted " ) ;
} catch ( std : : runtime_error & e ) {
return error ( " LoadBlockIndex() : failed to initialize block database : % s " , e.what()) ;
}
2010-08-29 09:58:15 -07:00
}
return true ;
}
void PrintBlockTree ( )
{
2012-07-25 17:48:39 -07:00
// pre-compute tree structure
2010-08-29 09:58:15 -07:00
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 09:28:20 -07:00
}
2010-08-29 09:58:15 -07:00
nPrevCol = nCol ;
// print columns
for ( int i = 0 ; i < nCol ; i + + )
printf ( " | " ) ;
// print item
CBlock block ;
block . ReadFromDisk ( pindex ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
printf ( " %d (blk%05u.dat:0x%x) %s tx % " PRIszu " " ,
2010-08-29 09:58:15 -07:00
pindex - > nHeight ,
2012-08-13 10:11:05 -07:00
pindex - > GetBlockPos ( ) . nFile , pindex - > GetBlockPos ( ) . nPos ,
2013-01-01 12:28:28 -08:00
DateTimeStrFormat ( " %Y-%m-%d %H:%M:%S " , block . GetBlockTime ( ) ) . c_str ( ) ,
2010-08-29 09:58:15 -07:00
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 09:28:20 -07:00
PrintWallets ( block ) ;
2010-08-29 09:58:15 -07:00
2012-07-25 17:48:39 -07:00
// put the main time-chain first
2010-08-29 09:58:15 -07:00
vector < CBlockIndex * > & vNext = mapNext [ pindex ] ;
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vNext . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
{
2013-05-12 06:50:22 -07:00
if ( vNext [ i ] - > GetNextInMainChain ( ) )
2010-08-29 09:58:15 -07:00
{
swap ( vNext [ 0 ] , vNext [ i ] ) ;
break ;
}
}
// iterate children
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vNext . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
vStack . push_back ( make_pair ( nCol + i , vNext [ i ] ) ) ;
}
}
2012-10-21 12:23:13 -07:00
bool LoadExternalBlockFile ( FILE * fileIn , CDiskBlockPos * dbp )
2012-02-20 11:50:26 -08:00
{
2012-08-16 15:14:40 -07:00
int64 nStart = GetTimeMillis ( ) ;
2012-02-20 11:50:26 -08:00
int nLoaded = 0 ;
2013-01-28 16:44:19 -08:00
try {
2012-10-27 13:01:38 -07:00
CBufferedFile blkdat ( fileIn , 2 * MAX_BLOCK_SIZE , MAX_BLOCK_SIZE + 8 , SER_DISK , CLIENT_VERSION ) ;
2012-10-21 12:23:13 -07:00
uint64 nStartByte = 0 ;
if ( dbp ) {
// (try to) skip already indexed part
CBlockFileInfo info ;
if ( pblocktree - > ReadBlockFileInfo ( dbp - > nFile , info ) ) {
nStartByte = info . nSize ;
blkdat . Seek ( info . nSize ) ;
}
}
2012-10-27 13:01:38 -07:00
uint64 nRewind = blkdat . GetPos ( ) ;
2013-03-06 19:31:26 -08:00
while ( blkdat . good ( ) & & ! blkdat . eof ( ) ) {
boost : : this_thread : : interruption_point ( ) ;
2012-10-27 13:01:38 -07:00
blkdat . SetPos ( nRewind ) ;
nRewind + + ; // start one byte further next time, in case of failure
blkdat . SetLimit ( ) ; // remove former limit
2012-10-21 12:23:13 -07:00
unsigned int nSize = 0 ;
2012-10-27 13:01:38 -07:00
try {
// locate a header
unsigned char buf [ 4 ] ;
blkdat . FindByte ( pchMessageStart [ 0 ] ) ;
nRewind = blkdat . GetPos ( ) + 1 ;
blkdat > > FLATDATA ( buf ) ;
if ( memcmp ( buf , pchMessageStart , 4 ) )
continue ;
// read size
2012-02-20 11:50:26 -08:00
blkdat > > nSize ;
2012-10-27 13:01:38 -07:00
if ( nSize < 80 | | nSize > MAX_BLOCK_SIZE )
continue ;
2012-10-21 12:23:13 -07:00
} catch ( std : : exception & e ) {
// no valid block header found; don't complain
break ;
}
try {
2012-10-27 13:01:38 -07:00
// read block
2012-10-21 12:23:13 -07:00
uint64 nBlockPos = blkdat . GetPos ( ) ;
blkdat . SetLimit ( nBlockPos + nSize ) ;
2012-10-27 13:01:38 -07:00
CBlock block ;
blkdat > > block ;
nRewind = blkdat . GetPos ( ) ;
2012-10-21 12:23:13 -07:00
// process block
if ( nBlockPos > = nStartByte ) {
2012-09-13 05:33:52 -07:00
LOCK ( cs_main ) ;
2012-10-21 12:23:13 -07:00
if ( dbp )
dbp - > nPos = nBlockPos ;
2013-01-26 15:14:11 -08:00
CValidationState state ;
if ( ProcessBlock ( state , NULL , & block , dbp ) )
2012-02-20 11:50:26 -08:00
nLoaded + + ;
2013-01-26 15:14:11 -08:00
if ( state . IsError ( ) )
break ;
2012-02-20 11:50:26 -08:00
}
2012-10-27 13:01:38 -07:00
} catch ( std : : exception & e ) {
printf ( " %s() : Deserialize or I/O error caught during load \n " , __PRETTY_FUNCTION__ ) ;
2012-02-20 11:50:26 -08:00
}
}
2012-10-27 13:01:38 -07:00
fclose ( fileIn ) ;
2013-01-28 16:44:19 -08:00
} catch ( std : : runtime_error & e ) {
AbortNode ( _ ( " Error: system error: " ) + e . what ( ) ) ;
2012-02-20 11:50:26 -08:00
}
2012-10-21 12:23:13 -07:00
if ( nLoaded > 0 )
printf ( " Loaded %i blocks from external file in % " PRI64d " ms \n " , nLoaded , GetTimeMillis ( ) - nStart ) ;
2012-02-20 11:50:26 -08:00
return nLoaded > 0 ;
}
2010-08-29 09:58:15 -07:00
2012-09-13 05:33:52 -07:00
2010-08-29 09:58:15 -07:00
//////////////////////////////////////////////////////////////////////////////
//
// CAlert
//
2012-08-28 14:04:54 -07:00
extern map < uint256 , CAlert > mapAlerts ;
extern CCriticalSection cs_mapAlerts ;
2010-08-29 09:58:15 -07:00
string GetWarnings ( string strFor )
{
int nPriority = 0 ;
string strStatusBar ;
string strRPC ;
2012-10-24 12:47:07 -07:00
2013-04-28 08:37:50 -07:00
if ( GetBoolArg ( " -testsafemode " , false ) )
2010-08-29 09:58:15 -07:00
strRPC = " test " ;
2012-10-24 12:47:07 -07:00
if ( ! CLIENT_VERSION_IS_RELEASE )
strStatusBar = _ ( " This is a pre-release test build - use at your own risk - do not use for mining or merchant applications " ) ;
2010-08-29 09:58:15 -07:00
// Misc warnings like out of disk space and clock is wrong
if ( strMiscWarning ! = " " )
{
nPriority = 1000 ;
strStatusBar = strMiscWarning ;
}
// Longer invalid proof-of-work chain
2013-03-28 15:51:50 -07:00
if ( pindexBest & & nBestInvalidWork > nBestChainWork + ( pindexBest - > GetBlockWork ( ) * 6 ) . getuint256 ( ) )
2010-08-29 09:58:15 -07:00
{
nPriority = 2000 ;
2012-07-26 23:36:43 -07:00
strStatusBar = strRPC = _ ( " Warning: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade. " ) ;
2010-08-29 09:58:15 -07:00
}
// Alerts
{
2012-04-06 09:39:12 -07:00
LOCK ( cs_mapAlerts ) ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
2010-08-29 09:58:15 -07: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 10:56:23 -07:00
assert ( ! " GetWarnings() : invalid parameter " ) ;
2010-08-29 09:58:15 -07:00
return " error " ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Messages
//
2012-07-06 07:33:34 -07:00
bool static AlreadyHave ( const CInv & inv )
2010-08-29 09:58:15 -07:00
{
switch ( inv . type )
{
2012-04-13 15:24:55 -07:00
case MSG_TX :
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
bool txInMap = false ;
2012-04-17 09:31:51 -07:00
{
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
LOCK ( mempool . cs ) ;
txInMap = mempool . exists ( inv . hash ) ;
2012-04-17 09:31:51 -07:00
}
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
return txInMap | | mapOrphanTransactions . count ( inv . hash ) | |
2012-07-06 07:33:34 -07:00
pcoinsTip - > HaveCoins ( inv . hash ) ;
2012-04-13 15:24:55 -07:00
}
case MSG_BLOCK :
return mapBlockIndex . count ( inv . hash ) | |
mapOrphanBlocks . count ( inv . hash ) ;
2010-08-29 09:58:15 -07:00
}
// Don't know what it is, just say we already got one
return true ;
}
2010-10-19 10:16:51 -07:00
// The message start string is designed to be unlikely to occur in normal data.
2012-07-25 17:48:39 -07:00
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
2010-10-19 10:16:51 -07:00
// a large 4-byte int at any alignment.
2011-08-07 09:19:14 -07:00
unsigned char pchMessageStart [ 4 ] = { 0xf9 , 0xbe , 0xb4 , 0xd9 } ;
2010-08-29 09:58:15 -07:00
2013-03-29 15:49:38 -07:00
void static ProcessGetData ( CNode * pfrom )
{
std : : deque < CInv > : : iterator it = pfrom - > vRecvGetData . begin ( ) ;
vector < CInv > vNotFound ;
while ( it ! = pfrom - > vRecvGetData . end ( ) ) {
// Don't bother if send buffer is too full to respond anyway
if ( pfrom - > nSendSize > = SendBufferSize ( ) )
break ;
const CInv & inv = * it ;
{
2013-03-09 09:02:57 -08:00
boost : : this_thread : : interruption_point ( ) ;
2013-03-29 15:49:38 -07:00
it + + ;
if ( inv . type = = MSG_BLOCK | | inv . type = = MSG_FILTERED_BLOCK )
{
// Send block from disk
map < uint256 , CBlockIndex * > : : iterator mi = mapBlockIndex . find ( inv . hash ) ;
if ( mi ! = mapBlockIndex . end ( ) )
{
CBlock block ;
block . ReadFromDisk ( ( * mi ) . second ) ;
if ( inv . type = = MSG_BLOCK )
pfrom - > PushMessage ( " block " , block ) ;
else // MSG_FILTERED_BLOCK)
{
LOCK ( pfrom - > cs_filter ) ;
if ( pfrom - > pfilter )
{
CMerkleBlock merkleBlock ( block , * pfrom - > pfilter ) ;
pfrom - > PushMessage ( " merkleblock " , merkleBlock ) ;
// CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
// This avoids hurting performance by pointlessly requiring a round-trip
// Note that there is currently no way for a node to request any single transactions we didnt send here -
// they must either disconnect and retry or request the full block.
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
// however we MUST always provide at least what the remote peer needs
typedef std : : pair < unsigned int , uint256 > PairType ;
BOOST_FOREACH ( PairType & pair , merkleBlock . vMatchedTxn )
if ( ! pfrom - > setInventoryKnown . count ( CInv ( MSG_TX , pair . second ) ) )
pfrom - > PushMessage ( " tx " , block . vtx [ pair . first ] ) ;
}
// else
// no response
}
// 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
bool pushed = false ;
{
LOCK ( cs_mapRelay ) ;
map < CInv , CDataStream > : : iterator mi = mapRelay . find ( inv ) ;
if ( mi ! = mapRelay . end ( ) ) {
pfrom - > PushMessage ( inv . GetCommand ( ) , ( * mi ) . second ) ;
pushed = true ;
}
}
if ( ! pushed & & inv . type = = MSG_TX ) {
LOCK ( mempool . cs ) ;
if ( mempool . exists ( inv . hash ) ) {
CTransaction tx = mempool . lookup ( inv . hash ) ;
CDataStream ss ( SER_NETWORK , PROTOCOL_VERSION ) ;
ss . reserve ( 1000 ) ;
ss < < tx ;
pfrom - > PushMessage ( " tx " , ss ) ;
pushed = true ;
}
}
if ( ! pushed ) {
vNotFound . push_back ( inv ) ;
}
}
// Track requests for our stuff.
Inventory ( inv . hash ) ;
}
}
pfrom - > vRecvGetData . erase ( pfrom - > vRecvGetData . begin ( ) , it ) ;
if ( ! vNotFound . empty ( ) ) {
// Let the peer know that we didn't find what it asked for, so it doesn't
// have to wait around forever. Currently only SPV clients actually care
// about this message: it's needed when they are recursively walking the
// dependencies of relevant unconfirmed transactions. SPV clients want to
// do that because they want to know about (and store and rebroadcast and
// risk analyze) the dependencies of transactions relevant to them, without
// having to download the entire memory pool.
pfrom - > PushMessage ( " notfound " , vNotFound ) ;
}
}
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 09:28:20 -07:00
bool static ProcessMessage ( CNode * pfrom , string strCommand , CDataStream & vRecv )
2010-08-29 09:58:15 -07:00
{
RandAddSeedPerfmon ( ) ;
2012-05-11 15:09:33 -07:00
if ( fDebug )
2012-09-29 02:57:44 -07:00
printf ( " received: %s (% " PRIszu " bytes) \n " , strCommand . c_str ( ) , vRecv . size ( ) ) ;
2010-08-29 09:58:15 -07: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 14:41:51 -07:00
{
pfrom - > Misbehaving ( 1 ) ;
2010-08-29 09:58:15 -07:00
return false ;
2011-09-06 14:41:51 -07:00
}
2010-08-29 09:58:15 -07:00
2011-12-21 13:33:19 -08:00
int64 nTime ;
2010-08-29 09:58:15 -07:00
CAddress addrMe ;
CAddress addrFrom ;
2011-12-21 13:33:19 -08:00
uint64 nNonce = 1 ;
2010-08-29 09:58:15 -07:00
vRecv > > pfrom - > nVersion > > pfrom - > nServices > > nTime > > addrMe ;
2012-04-12 17:07:49 -07:00
if ( pfrom - > nVersion < MIN_PROTO_VERSION )
2012-02-19 16:33:31 -08:00
{
2012-02-28 04:31:56 -08:00
// Since February 20, 2012, the protocol is initiated at version 209,
2012-02-19 16:33:31 -08: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 09:58:15 -07:00
if ( pfrom - > nVersion = = 10300 )
pfrom - > nVersion = 300 ;
2012-02-19 16:33:31 -08:00
if ( ! vRecv . empty ( ) )
2010-08-29 09:58:15 -07:00
vRecv > > addrFrom > > nNonce ;
2012-02-19 16:33:31 -08:00
if ( ! vRecv . empty ( ) )
2010-08-29 09:58:15 -07:00
vRecv > > pfrom - > strSubVer ;
2012-02-19 16:33:31 -08:00
if ( ! vRecv . empty ( ) )
2010-08-29 09:58:15 -07:00
vRecv > > pfrom - > nStartingHeight ;
2012-08-20 18:10:25 -07:00
if ( ! vRecv . empty ( ) )
vRecv > > pfrom - > fRelayTxes ; // set to true after we get the first filter* message
else
pfrom - > fRelayTxes = true ;
2010-08-29 09:58:15 -07:00
2012-02-12 04:45:24 -08:00
if ( pfrom - > fInbound & & addrMe . IsRoutable ( ) )
{
pfrom - > addrLocal = addrMe ;
SeenLocal ( addrMe ) ;
}
2010-08-29 09:58:15 -07:00
// Disconnect if we connected to ourself
if ( nNonce = = nLocalHostNonce & & nNonce > 1 )
{
2010-10-05 19:19:47 -07:00
printf ( " connected to self at %s, disconnecting \n " , pfrom - > addr . ToString ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
pfrom - > fDisconnect = true ;
return true ;
}
2011-01-24 07:42:17 -08:00
// Be shy and don't send version until we hear
if ( pfrom - > fInbound )
pfrom - > PushVersion ( ) ;
2010-08-29 09:58:15 -07:00
pfrom - > fClient = ! ( pfrom - > nServices & NODE_NETWORK ) ;
2012-01-03 14:33:31 -08:00
AddTimeData ( pfrom - > addr , nTime ) ;
2010-08-29 09:58:15 -07:00
// Change version
2012-02-19 16:33:31 -08:00
pfrom - > PushMessage ( " verack " ) ;
2013-03-24 08:52:24 -07:00
pfrom - > ssSend . SetVersion ( min ( pfrom - > nVersion , PROTOCOL_VERSION ) ) ;
2010-08-29 09:58:15 -07:00
2010-10-23 10:43:53 -07:00
if ( ! pfrom - > fInbound )
{
// Advertise our address
2012-05-24 10:02:21 -07:00
if ( ! fNoListen & & ! IsInitialBlockDownload ( ) )
2010-10-23 10:43:53 -07:00
{
2012-02-12 04:45:24 -08:00
CAddress addr = GetLocalAddress ( & pfrom - > addr ) ;
if ( addr . IsRoutable ( ) )
pfrom - > PushAddress ( addr ) ;
2010-10-23 10:43:53 -07:00
}
// Get recent addresses
2012-04-23 17:15:00 -07:00
if ( pfrom - > fOneShot | | pfrom - > nVersion > = CADDR_TIME_VERSION | | addrman . size ( ) < 1000 )
2010-10-23 10:43:53 -07:00
{
pfrom - > PushMessage ( " getaddr " ) ;
pfrom - > fGetAddr = true ;
}
2012-01-04 14:39:45 -08:00
addrman . Good ( pfrom - > addr ) ;
} else {
if ( ( ( CNetAddr ) pfrom - > addr ) = = ( CNetAddr ) addrFrom )
{
addrman . Add ( addrFrom , addrFrom ) ;
addrman . Good ( addrFrom ) ;
}
2010-10-23 10:43:53 -07:00
}
2010-08-29 09:58:15 -07:00
// Relay alerts
2012-04-06 09:39:12 -07:00
{
LOCK ( cs_mapAlerts ) ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CAlert ) & item , mapAlerts )
2010-08-29 09:58:15 -07:00
item . second . RelayTo ( pfrom ) ;
2012-04-06 09:39:12 -07:00
}
2010-08-29 09:58:15 -07:00
pfrom - > fSuccessfullyConnected = true ;
2012-05-01 13:03:51 -07:00
printf ( " receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s \n " , pfrom - > nVersion , pfrom - > nStartingHeight , addrMe . ToString ( ) . c_str ( ) , addrFrom . ToString ( ) . c_str ( ) , pfrom - > addr . ToString ( ) . c_str ( ) ) ;
2011-09-28 12:35:58 -07:00
cPeerBlockCounts . input ( pfrom - > nStartingHeight ) ;
2010-08-29 09:58:15 -07:00
}
else if ( pfrom - > nVersion = = 0 )
{
// Must have a version message before anything else
2011-09-06 14:41:51 -07:00
pfrom - > Misbehaving ( 1 ) ;
2010-08-29 09:58:15 -07:00
return false ;
}
else if ( strCommand = = " verack " )
{
2012-11-15 16:41:12 -08:00
pfrom - > SetRecvVersion ( min ( pfrom - > nVersion , PROTOCOL_VERSION ) ) ;
2010-08-29 09:58:15 -07:00
}
else if ( strCommand = = " addr " )
{
vector < CAddress > vAddr ;
vRecv > > vAddr ;
2010-10-23 10:43:53 -07:00
// Don't want addr from older versions unless seeding
2012-04-12 17:07:49 -07:00
if ( pfrom - > nVersion < CADDR_TIME_VERSION & & addrman . size ( ) > 1000 )
2010-08-29 09:58:15 -07:00
return true ;
if ( vAddr . size ( ) > 1000 )
2011-09-06 14:41:51 -07:00
{
pfrom - > Misbehaving ( 20 ) ;
2012-09-29 02:57:44 -07:00
return error ( " message addr size() = % " PRIszu " " , vAddr.size()) ;
2011-09-06 14:41:51 -07:00
}
2010-08-29 09:58:15 -07:00
// Store the new addresses
2012-04-10 11:22:04 -07:00
vector < CAddress > vAddrOk ;
2011-12-21 13:33:19 -08:00
int64 nNow = GetAdjustedTime ( ) ;
int64 nSince = nNow - 10 * 60 ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( CAddress & addr , vAddr )
2010-08-29 09:58:15 -07:00
{
2013-03-09 09:02:57 -08:00
boost : : this_thread : : interruption_point ( ) ;
2010-10-23 10:43:53 -07:00
if ( addr . nTime < = 100000000 | | addr . nTime > nNow + 10 * 60 )
addr . nTime = nNow - 5 * 24 * 60 * 60 ;
2010-08-29 09:58:15 -07:00
pfrom - > AddAddressKnown ( addr ) ;
2012-04-10 11:22:04 -07:00
bool fReachable = IsReachable ( addr ) ;
2010-10-23 10:43:53 -07:00
if ( addr . nTime > nSince & & ! pfrom - > fGetAddr & & vAddr . size ( ) < = 10 & & addr . IsRoutable ( ) )
2010-08-29 09:58:15 -07:00
{
// Relay to a limited number of other nodes
{
2012-04-06 09:39:12 -07:00
LOCK ( cs_vNodes ) ;
2010-10-19 10:16:51 -07: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 09:58:15 -07:00
static uint256 hashSalt ;
if ( hashSalt = = 0 )
2012-05-17 09:13:14 -07:00
hashSalt = GetRandHash ( ) ;
2012-05-13 12:31:59 -07:00
uint64 hashAddr = addr . GetHash ( ) ;
2012-01-03 14:33:31 -08:00
uint256 hashRand = hashSalt ^ ( hashAddr < < 32 ) ^ ( ( GetTime ( ) + hashAddr ) / ( 24 * 60 * 60 ) ) ;
2010-10-19 10:16:51 -07:00
hashRand = Hash ( BEGIN ( hashRand ) , END ( hashRand ) ) ;
2010-08-29 09:58:15 -07:00
multimap < uint256 , CNode * > mapMix ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( CNode * pnode , vNodes )
2010-10-19 10:16:51 -07:00
{
2012-04-12 17:07:49 -07:00
if ( pnode - > nVersion < CADDR_TIME_VERSION )
2010-10-23 10:43:53 -07:00
continue ;
2010-10-19 10:16:51 -07: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 ) ) ;
}
2012-04-10 11:22:04 -07:00
int nRelayNodes = fReachable ? 2 : 1 ; // limited relaying of addresses outside our network(s)
2010-08-29 09:58:15 -07:00
for ( multimap < uint256 , CNode * > : : iterator mi = mapMix . begin ( ) ; mi ! = mapMix . end ( ) & & nRelayNodes - - > 0 ; + + mi )
( ( * mi ) . second ) - > PushAddress ( addr ) ;
}
}
2012-04-10 11:22:04 -07:00
// Do not store addresses outside our network
if ( fReachable )
vAddrOk . push_back ( addr ) ;
2010-08-29 09:58:15 -07:00
}
2012-04-10 11:22:04 -07:00
addrman . Add ( vAddrOk , pfrom - > addr , 2 * 60 * 60 ) ;
2010-08-29 09:58:15 -07:00
if ( vAddr . size ( ) < 1000 )
pfrom - > fGetAddr = false ;
2012-04-23 17:15:00 -07:00
if ( pfrom - > fOneShot )
pfrom - > fDisconnect = true ;
2010-08-29 09:58:15 -07:00
}
else if ( strCommand = = " inv " )
{
vector < CInv > vInv ;
vRecv > > vInv ;
2012-07-31 14:42:35 -07:00
if ( vInv . size ( ) > MAX_INV_SZ )
2011-09-06 14:41:51 -07:00
{
pfrom - > Misbehaving ( 20 ) ;
2012-09-29 02:57:44 -07:00
return error ( " message inv size() = % " PRIszu " " , vInv.size()) ;
2011-09-06 14:41:51 -07:00
}
2010-08-29 09:58:15 -07:00
2012-05-04 19:04:38 -07:00
// find last block in inv vector
unsigned int nLastBlock = ( unsigned int ) ( - 1 ) ;
for ( unsigned int nInv = 0 ; nInv < vInv . size ( ) ; nInv + + ) {
2012-05-07 12:36:30 -07:00
if ( vInv [ vInv . size ( ) - 1 - nInv ] . type = = MSG_BLOCK ) {
2012-05-04 19:04:38 -07:00
nLastBlock = vInv . size ( ) - 1 - nInv ;
2012-05-07 12:36:30 -07:00
break ;
}
2012-05-04 19:04:38 -07:00
}
2012-04-15 13:52:09 -07:00
for ( unsigned int nInv = 0 ; nInv < vInv . size ( ) ; nInv + + )
2010-08-29 09:58:15 -07:00
{
2012-03-18 15:47:26 -07:00
const CInv & inv = vInv [ nInv ] ;
2013-03-09 09:02:57 -08:00
boost : : this_thread : : interruption_point ( ) ;
2010-08-29 09:58:15 -07:00
pfrom - > AddInventoryKnown ( inv ) ;
2012-07-06 07:33:34 -07:00
bool fAlreadyHave = AlreadyHave ( inv ) ;
2011-09-17 09:29:41 -07:00
if ( fDebug )
printf ( " got inventory: %s %s \n " , inv . ToString ( ) . c_str ( ) , fAlreadyHave ? " have " : " new " ) ;
2010-08-29 09:58:15 -07:00
2012-09-13 05:33:52 -07:00
if ( ! fAlreadyHave ) {
2012-10-21 12:23:13 -07:00
if ( ! fImporting & & ! fReindex )
2012-09-13 05:33:52 -07:00
pfrom - > AskFor ( inv ) ;
} else if ( inv . type = = MSG_BLOCK & & mapOrphanBlocks . count ( inv . hash ) ) {
2013-01-07 06:39:53 -08:00
PushGetBlocks ( pfrom , pindexBest , GetOrphanRoot ( mapOrphanBlocks [ inv . hash ] ) ) ;
2012-05-07 12:36:30 -07:00
} else if ( nInv = = nLastBlock ) {
// In case we are on a very long side-chain, it is possible that we already have
// the last block in an inv bundle sent in response to getblocks. Try to detect
// this situation and push another getblocks to continue.
2013-01-07 06:39:53 -08:00
PushGetBlocks ( pfrom , mapBlockIndex [ inv . hash ] , uint256 ( 0 ) ) ;
2012-05-07 12:36:30 -07:00
if ( fDebug )
printf ( " force request: %s \n " , inv . ToString ( ) . c_str ( ) ) ;
}
2010-08-29 09:58:15 -07:00
// 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 09:28:20 -07:00
Inventory ( inv . hash ) ;
2010-08-29 09:58:15 -07:00
}
}
else if ( strCommand = = " getdata " )
{
vector < CInv > vInv ;
vRecv > > vInv ;
2012-07-31 14:42:35 -07:00
if ( vInv . size ( ) > MAX_INV_SZ )
2011-09-06 14:41:51 -07:00
{
pfrom - > Misbehaving ( 20 ) ;
2012-09-29 02:57:44 -07:00
return error ( " message getdata size() = % " PRIszu " " , vInv.size()) ;
2011-09-06 14:41:51 -07:00
}
2010-08-29 09:58:15 -07:00
2012-06-23 18:38:33 -07:00
if ( fDebugNet | | ( vInv . size ( ) ! = 1 ) )
2012-09-29 02:57:44 -07:00
printf ( " received getdata (% " PRIszu " invsz) \n " , vInv . size ( ) ) ;
2012-06-23 18:38:33 -07:00
2013-03-29 15:49:38 -07:00
if ( ( fDebugNet & & vInv . size ( ) > 0 ) | | ( vInv . size ( ) = = 1 ) )
printf ( " received getdata for: %s \n " , vInv [ 0 ] . ToString ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
2013-03-29 15:49:38 -07:00
pfrom - > vRecvGetData . insert ( pfrom - > vRecvGetData . end ( ) , vInv . begin ( ) , vInv . end ( ) ) ;
ProcessGetData ( pfrom ) ;
2010-08-29 09:58:15 -07:00
}
else if ( strCommand = = " getblocks " )
{
CBlockLocator locator ;
uint256 hashStop ;
vRecv > > locator > > hashStop ;
2010-12-05 01:29:30 -08:00
// Find the last block the caller has in the main chain
2010-08-29 09:58:15 -07:00
CBlockIndex * pindex = locator . GetBlockIndex ( ) ;
// Send the rest of the chain
if ( pindex )
2013-05-12 06:50:22 -07:00
pindex = pindex - > GetNextInMainChain ( ) ;
2012-03-21 19:10:50 -07:00
int nLimit = 500 ;
2013-04-06 18:40:33 -07:00
printf ( " getblocks %d to %s limit %d \n " , ( pindex ? pindex - > nHeight : - 1 ) , hashStop . ToString ( ) . c_str ( ) , nLimit ) ;
2013-05-12 06:50:22 -07:00
for ( ; pindex ; pindex = pindex - > GetNextInMainChain ( ) )
2010-08-29 09:58:15 -07:00
{
if ( pindex - > GetBlockHash ( ) = = hashStop )
{
2013-04-06 18:40:33 -07:00
printf ( " getblocks stopping at %d %s \n " , pindex - > nHeight , pindex - > GetBlockHash ( ) . ToString ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
break ;
}
pfrom - > PushInventory ( CInv ( MSG_BLOCK , pindex - > GetBlockHash ( ) ) ) ;
2012-03-21 19:10:50 -07:00
if ( - - nLimit < = 0 )
2010-08-29 09:58:15 -07:00
{
// When this block is requested, we'll send an inv that'll make them
// getblocks the next batch of inventory.
2013-04-06 18:40:33 -07:00
printf ( " getblocks stopping at limit %d %s \n " , pindex - > nHeight , pindex - > GetBlockHash ( ) . ToString ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
pfrom - > hashContinue = pindex - > GetBlockHash ( ) ;
break ;
}
}
}
2010-12-05 01:29:30 -08: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 )
2013-05-12 06:50:22 -07:00
pindex = pindex - > GetNextInMainChain ( ) ;
2010-12-05 01:29:30 -08:00
}
2012-11-14 13:18:10 -08:00
// we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
2010-12-05 01:29:30 -08:00
vector < CBlock > vHeaders ;
2012-03-18 21:13:15 -07:00
int nLimit = 2000 ;
2013-04-06 18:40:33 -07:00
printf ( " getheaders %d to %s \n " , ( pindex ? pindex - > nHeight : - 1 ) , hashStop . ToString ( ) . c_str ( ) ) ;
2013-05-12 06:50:22 -07:00
for ( ; pindex ; pindex = pindex - > GetNextInMainChain ( ) )
2010-12-05 01:29:30 -08:00
{
vHeaders . push_back ( pindex - > GetBlockHeader ( ) ) ;
if ( - - nLimit < = 0 | | pindex - > GetBlockHash ( ) = = hashStop )
break ;
}
pfrom - > PushMessage ( " headers " , vHeaders ) ;
}
2010-08-29 09:58:15 -07:00
else if ( strCommand = = " tx " )
{
vector < uint256 > vWorkQueue ;
2012-05-17 07:12:04 -07:00
vector < uint256 > vEraseQueue ;
2010-08-29 09:58:15 -07:00
CDataStream vMsg ( vRecv ) ;
CTransaction tx ;
vRecv > > tx ;
CInv inv ( MSG_TX , tx . GetHash ( ) ) ;
pfrom - > AddInventoryKnown ( inv ) ;
bool fMissingInputs = false ;
2013-01-26 15:14:11 -08:00
CValidationState state ;
if ( tx . AcceptToMemoryPool ( state , true , true , & fMissingInputs ) )
2010-08-29 09:58:15 -07:00
{
2012-08-12 20:26:30 -07:00
RelayTransaction ( tx , inv . hash , vMsg ) ;
2010-08-29 09:58:15 -07:00
mapAlreadyAskedFor . erase ( inv ) ;
vWorkQueue . push_back ( inv . hash ) ;
2012-05-17 07:12:04 -07:00
vEraseQueue . push_back ( inv . hash ) ;
2010-08-29 09:58:15 -07:00
// Recursively process any orphan transactions that depended on this one
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < vWorkQueue . size ( ) ; i + + )
2010-08-29 09:58:15 -07:00
{
uint256 hashPrev = vWorkQueue [ i ] ;
2012-05-15 12:53:30 -07:00
for ( map < uint256 , CDataStream * > : : iterator mi = mapOrphanTransactionsByPrev [ hashPrev ] . begin ( ) ;
mi ! = mapOrphanTransactionsByPrev [ hashPrev ] . end ( ) ;
2010-08-29 09:58:15 -07:00
+ + mi )
{
const CDataStream & vMsg = * ( ( * mi ) . second ) ;
CTransaction tx ;
CDataStream ( vMsg ) > > tx ;
CInv inv ( MSG_TX , tx . GetHash ( ) ) ;
2012-05-17 07:12:04 -07:00
bool fMissingInputs2 = false ;
2013-01-30 19:53:21 -08:00
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get anyone relaying LegitTxX banned)
CValidationState stateDummy ;
2010-08-29 09:58:15 -07:00
2013-01-30 19:53:21 -08:00
if ( tx . AcceptToMemoryPool ( stateDummy , true , true , & fMissingInputs2 ) )
2010-08-29 09:58:15 -07:00
{
2013-04-06 18:40:33 -07:00
printf ( " accepted orphan tx %s \n " , inv . hash . ToString ( ) . c_str ( ) ) ;
2012-08-12 20:26:30 -07:00
RelayTransaction ( tx , inv . hash , vMsg ) ;
2010-08-29 09:58:15 -07:00
mapAlreadyAskedFor . erase ( inv ) ;
vWorkQueue . push_back ( inv . hash ) ;
2012-05-17 07:12:04 -07:00
vEraseQueue . push_back ( inv . hash ) ;
}
else if ( ! fMissingInputs2 )
{
2013-01-14 13:52:33 -08:00
// invalid or too-little-fee orphan
2012-05-17 07:12:04 -07:00
vEraseQueue . push_back ( inv . hash ) ;
2013-04-06 18:40:33 -07:00
printf ( " removed orphan tx %s \n " , inv . hash . ToString ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
}
}
}
2012-05-17 07:12:04 -07:00
BOOST_FOREACH ( uint256 hash , vEraseQueue )
2010-08-29 09:58:15 -07:00
EraseOrphanTx ( hash ) ;
}
else if ( fMissingInputs )
{
AddOrphanTx ( vMsg ) ;
2012-02-29 07:14:18 -08:00
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
2012-04-23 11:14:03 -07:00
unsigned int nEvicted = LimitOrphanTxSize ( MAX_ORPHAN_TRANSACTIONS ) ;
2012-02-29 07:14:18 -08:00
if ( nEvicted > 0 )
2012-04-23 11:14:03 -07:00
printf ( " mapOrphan overflow, removed %u tx \n " , nEvicted ) ;
2010-08-29 09:58:15 -07:00
}
2013-01-26 15:14:11 -08:00
int nDoS ;
if ( state . IsInvalid ( nDoS ) )
pfrom - > Misbehaving ( nDoS ) ;
2010-08-29 09:58:15 -07:00
}
2012-10-21 12:23:13 -07:00
else if ( strCommand = = " block " & & ! fImporting & & ! fReindex ) // Ignore blocks received while importing
2010-08-29 09:58:15 -07:00
{
2010-12-05 01:29:30 -08:00
CBlock block ;
vRecv > > block ;
2010-08-29 09:58:15 -07:00
2013-04-06 18:40:33 -07:00
printf ( " received block %s \n " , block . GetHash ( ) . ToString ( ) . c_str ( ) ) ;
2010-12-05 01:29:30 -08:00
// block.print();
2010-08-29 09:58:15 -07:00
2010-12-05 01:29:30 -08:00
CInv inv ( MSG_BLOCK , block . GetHash ( ) ) ;
2010-08-29 09:58:15 -07:00
pfrom - > AddInventoryKnown ( inv ) ;
2013-01-26 15:14:11 -08:00
CValidationState state ;
if ( ProcessBlock ( state , pfrom , & block ) )
2010-08-29 09:58:15 -07:00
mapAlreadyAskedFor . erase ( inv ) ;
2013-01-26 15:14:11 -08:00
int nDoS ;
if ( state . IsInvalid ( nDoS ) )
pfrom - > Misbehaving ( nDoS ) ;
2010-08-29 09:58:15 -07:00
}
else if ( strCommand = = " getaddr " )
{
pfrom - > vAddrToSend . clear ( ) ;
2012-01-04 14:39:45 -08:00
vector < CAddress > vAddr = addrman . GetAddr ( ) ;
BOOST_FOREACH ( const CAddress & addr , vAddr )
pfrom - > PushAddress ( addr ) ;
2010-08-29 09:58:15 -07:00
}
2012-07-31 14:42:35 -07:00
else if ( strCommand = = " mempool " )
{
std : : vector < uint256 > vtxid ;
2013-01-10 11:06:30 -08:00
LOCK2 ( mempool . cs , pfrom - > cs_filter ) ;
2012-07-31 14:42:35 -07:00
mempool . queryHashes ( vtxid ) ;
vector < CInv > vInv ;
2013-01-10 11:06:30 -08:00
BOOST_FOREACH ( uint256 & hash , vtxid ) {
CInv inv ( MSG_TX , hash ) ;
if ( ( pfrom - > pfilter & & pfrom - > pfilter - > IsRelevantAndUpdate ( mempool . lookup ( hash ) , hash ) ) | |
( ! pfrom - > pfilter ) )
vInv . push_back ( inv ) ;
if ( vInv . size ( ) = = MAX_INV_SZ )
break ;
2012-07-31 14:42:35 -07:00
}
if ( vInv . size ( ) > 0 )
pfrom - > PushMessage ( " inv " , vInv ) ;
}
2010-08-29 09:58:15 -07:00
else if ( strCommand = = " ping " )
{
2012-04-11 09:38:03 -07: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 09:58:15 -07:00
}
else if ( strCommand = = " alert " )
{
CAlert alert ;
vRecv > > alert ;
2012-08-26 14:08:18 -07:00
uint256 alertHash = alert . GetHash ( ) ;
if ( pfrom - > setKnown . count ( alertHash ) = = 0 )
2010-08-29 09:58:15 -07:00
{
2012-08-26 14:08:18 -07:00
if ( alert . ProcessAlert ( ) )
2012-04-06 09:39:12 -07:00
{
2012-08-26 14:08:18 -07:00
// Relay
pfrom - > setKnown . insert ( alertHash ) ;
{
LOCK ( cs_vNodes ) ;
BOOST_FOREACH ( CNode * pnode , vNodes )
alert . RelayTo ( pnode ) ;
}
}
else {
// Small DoS penalty so peers that send us lots of
// duplicate/expired/invalid-signature/whatever alerts
// eventually get banned.
// This isn't a Misbehaving(100) (immediate ban) because the
// peer might be an older or different implementation with
// a different signature key, etc.
pfrom - > Misbehaving ( 10 ) ;
2012-04-06 09:39:12 -07:00
}
2010-08-29 09:58:15 -07:00
}
}
2012-08-12 20:26:29 -07:00
else if ( strCommand = = " filterload " )
{
CBloomFilter filter ;
vRecv > > filter ;
if ( ! filter . IsWithinSizeConstraints ( ) )
// There is no excuse for sending a too-large filter
pfrom - > Misbehaving ( 100 ) ;
else
{
LOCK ( pfrom - > cs_filter ) ;
delete pfrom - > pfilter ;
pfrom - > pfilter = new CBloomFilter ( filter ) ;
}
2012-08-20 18:10:25 -07:00
pfrom - > fRelayTxes = true ;
2012-08-12 20:26:29 -07:00
}
else if ( strCommand = = " filteradd " )
{
vector < unsigned char > vData ;
vRecv > > vData ;
// Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
// and thus, the maximum size any matched object can have) in a filteradd message
2013-01-18 10:55:18 -08:00
if ( vData . size ( ) > MAX_SCRIPT_ELEMENT_SIZE )
2012-08-12 20:26:29 -07:00
{
pfrom - > Misbehaving ( 100 ) ;
} else {
LOCK ( pfrom - > cs_filter ) ;
if ( pfrom - > pfilter )
pfrom - > pfilter - > insert ( vData ) ;
else
pfrom - > Misbehaving ( 100 ) ;
}
}
else if ( strCommand = = " filterclear " )
{
LOCK ( pfrom - > cs_filter ) ;
delete pfrom - > pfilter ;
pfrom - > pfilter = NULL ;
2012-08-20 18:10:25 -07:00
pfrom - > fRelayTxes = true ;
2012-08-12 20:26:29 -07:00
}
2010-08-29 09:58:15 -07: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 ;
}
2012-11-15 16:41:12 -08:00
// requires LOCK(cs_vRecvMsg)
2011-06-01 09:27:05 -07:00
bool ProcessMessages ( CNode * pfrom )
{
//if (fDebug)
2012-11-15 16:41:12 -08:00
// printf("ProcessMessages(%zu messages)\n", pfrom->vRecvMsg.size());
2010-08-29 09:58:15 -07:00
2011-06-01 09:27:05 -07:00
//
// Message format
// (4) message start
// (12) command
// (4) size
// (4) checksum
// (x) data
//
2013-02-28 16:41:28 -08:00
bool fOk = true ;
2010-08-29 09:58:15 -07:00
2013-03-29 15:49:38 -07:00
if ( ! pfrom - > vRecvGetData . empty ( ) )
ProcessGetData ( pfrom ) ;
2013-02-28 16:41:28 -08:00
std : : deque < CNetMessage > : : iterator it = pfrom - > vRecvMsg . begin ( ) ;
2013-03-24 08:52:24 -07:00
while ( ! pfrom - > fDisconnect & & it ! = pfrom - > vRecvMsg . end ( ) ) {
2012-03-21 19:10:50 -07:00
// Don't bother if send buffer is too full to respond anyway
2013-03-24 08:52:24 -07:00
if ( pfrom - > nSendSize > = SendBufferSize ( ) )
2012-03-21 19:10:50 -07:00
break ;
2013-02-28 16:41:28 -08:00
// get next message
CNetMessage & msg = * it ;
2012-11-15 16:41:12 -08:00
//if (fDebug)
// printf("ProcessMessages(message %u msgsz, %zu bytes, complete:%s)\n",
// msg.hdr.nMessageSize, msg.vRecv.size(),
// msg.complete() ? "Y" : "N");
2013-02-28 16:41:28 -08:00
// end, if an incomplete message is found
2012-11-15 16:41:12 -08:00
if ( ! msg . complete ( ) )
2011-06-01 09:27:05 -07:00
break ;
2012-11-15 16:41:12 -08:00
2013-02-28 16:41:28 -08:00
// at this point, any failure means we can delete the current message
it + + ;
2012-11-15 16:41:12 -08:00
// Scan for message start
if ( memcmp ( msg . hdr . pchMessageStart , pchMessageStart , sizeof ( pchMessageStart ) ) ! = 0 ) {
printf ( " \n \n PROCESSMESSAGE: INVALID MESSAGESTART \n \n " ) ;
2013-02-28 16:41:28 -08:00
fOk = false ;
break ;
2011-06-01 09:27:05 -07:00
}
2010-08-29 09:58:15 -07:00
2011-06-01 09:27:05 -07:00
// Read header
2012-11-15 16:41:12 -08:00
CMessageHeader & hdr = msg . hdr ;
2011-06-01 09:27:05 -07:00
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 ;
// Checksum
2012-11-15 16:41:12 -08:00
CDataStream & vRecv = msg . vRecv ;
2012-02-19 16:33:31 -08: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 09:27:05 -07:00
{
2012-05-22 04:06:08 -07:00
printf ( " ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x \n " ,
2012-02-19 16:33:31 -08:00
strCommand . c_str ( ) , nMessageSize , nChecksum , hdr . nChecksum ) ;
continue ;
2011-06-01 09:27:05 -07:00
}
// Process message
bool fRet = false ;
try
{
2012-04-06 09:39:12 -07:00
{
LOCK ( cs_main ) ;
2012-11-15 16:41:12 -08:00
fRet = ProcessMessage ( pfrom , strCommand , vRecv ) ;
2012-04-06 09:39:12 -07:00
}
2013-03-09 09:02:57 -08:00
boost : : this_thread : : interruption_point ( ) ;
2011-06-01 09:27:05 -07:00
}
catch ( std : : ios_base : : failure & e )
{
if ( strstr ( e . what ( ) , " end of data " ) )
{
2012-07-25 17:48:39 -07:00
// Allow exceptions from under-length message on vRecv
2012-05-22 04:06:08 -07:00
printf ( " ProcessMessages(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length \n " , strCommand . c_str ( ) , nMessageSize , e . what ( ) ) ;
2011-06-01 09:27:05 -07:00
}
else if ( strstr ( e . what ( ) , " size too large " ) )
{
2012-07-25 17:48:39 -07:00
// Allow exceptions from over-long size
2012-05-22 04:06:08 -07:00
printf ( " ProcessMessages(%s, %u bytes) : Exception '%s' caught \n " , strCommand . c_str ( ) , nMessageSize , e . what ( ) ) ;
2011-06-01 09:27:05 -07:00
}
else
{
2012-05-22 04:06:08 -07:00
PrintExceptionContinue ( & e , " ProcessMessages() " ) ;
2011-06-01 09:27:05 -07:00
}
}
2013-03-09 09:02:57 -08:00
catch ( boost : : thread_interrupted ) {
throw ;
}
2011-06-01 09:27:05 -07:00
catch ( std : : exception & e ) {
2012-05-22 04:06:08 -07:00
PrintExceptionContinue ( & e , " ProcessMessages() " ) ;
2011-06-01 09:27:05 -07:00
} catch ( . . . ) {
2012-05-22 04:06:08 -07:00
PrintExceptionContinue ( NULL , " ProcessMessages() " ) ;
2011-06-01 09:27:05 -07:00
}
if ( ! fRet )
printf ( " ProcessMessage(%s, %u bytes) FAILED \n " , strCommand . c_str ( ) , nMessageSize ) ;
}
2013-03-24 08:52:24 -07:00
// In case the connection got shut down, its receive buffer was wiped
if ( ! pfrom - > fDisconnect )
pfrom - > vRecvMsg . erase ( pfrom - > vRecvMsg . begin ( ) , it ) ;
2013-02-28 16:41:28 -08:00
return fOk ;
2011-06-01 09:27:05 -07:00
}
2010-08-29 09:58:15 -07:00
bool SendMessages ( CNode * pto , bool fSendTrickle )
{
2012-04-17 09:50:45 -07:00
TRY_LOCK ( cs_main , lockMain ) ;
if ( lockMain ) {
2010-08-29 09:58:15 -07:00
// Don't send anything until we get their version message
if ( pto - > nVersion = = 0 )
return true ;
2012-05-17 17:36:55 -07:00
// Keep-alive ping. We send a nonce of zero because we don't use it anywhere
2012-04-11 09:38:03 -07:00
// right now.
2013-03-24 08:52:24 -07:00
if ( pto - > nLastSend & & GetTime ( ) - pto - > nLastSend > 30 * 60 & & pto - > vSendMsg . empty ( ) ) {
2012-06-14 09:31:08 -07:00
uint64 nonce = 0 ;
2012-04-11 09:38:03 -07:00
if ( pto - > nVersion > BIP0031_VERSION )
2012-06-14 09:31:08 -07:00
pto - > PushMessage ( " ping " , nonce ) ;
2012-04-11 09:38:03 -07:00
else
pto - > PushMessage ( " ping " ) ;
}
2010-08-29 09:58:15 -07:00
2013-04-04 15:43:04 -07:00
// Start block sync
if ( pto - > fStartSync & & ! fImporting & & ! fReindex ) {
pto - > fStartSync = false ;
2013-01-07 06:39:53 -08:00
PushGetBlocks ( pto , pindexBest , uint256 ( 0 ) ) ;
2013-04-04 15:43:04 -07:00
}
2010-10-23 10:43:53 -07:00
// Resend wallet transactions that haven't gotten in a block yet
2013-02-05 11:35:23 -08:00
// Except during reindex, importing and IBD, when old wallet
// transactions become unconfirmed and spams other nodes.
if ( ! fReindex & & ! fImporting & & ! IsInitialBlockDownload ( ) )
{
ResendWalletTransactions ( ) ;
}
2010-10-23 10:43:53 -07:00
2010-08-29 09:58:15 -07:00
// Address refresh broadcast
2011-12-21 13:33:19 -08:00
static int64 nLastRebroadcast ;
2012-02-01 15:08:03 -08:00
if ( ! IsInitialBlockDownload ( ) & & ( GetTime ( ) - nLastRebroadcast > 24 * 60 * 60 ) )
2010-08-29 09:58:15 -07:00
{
{
2012-04-06 09:39:12 -07:00
LOCK ( cs_vNodes ) ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( CNode * pnode , vNodes )
2010-08-29 09:58:15 -07:00
{
// Periodically clear setAddrKnown to allow refresh broadcasts
2012-02-01 15:08:03 -08:00
if ( nLastRebroadcast )
pnode - > setAddrKnown . clear ( ) ;
2010-08-29 09:58:15 -07:00
// Rebroadcast our address
2012-05-24 10:02:21 -07:00
if ( ! fNoListen )
2010-10-23 10:43:53 -07:00
{
2012-02-12 04:45:24 -08:00
CAddress addr = GetLocalAddress ( & pnode - > addr ) ;
if ( addr . IsRoutable ( ) )
pnode - > PushAddress ( addr ) ;
2010-10-23 10:43:53 -07:00
}
2010-08-29 09:58:15 -07:00
}
}
2012-02-01 15:08:03 -08:00
nLastRebroadcast = GetTime ( ) ;
2010-08-29 09:58:15 -07:00
}
//
// Message: addr
//
if ( fSendTrickle )
{
vector < CAddress > vAddr ;
vAddr . reserve ( pto - > vAddrToSend . size ( ) ) ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CAddress & addr , pto - > vAddrToSend )
2010-08-29 09:58:15 -07: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 09:39:12 -07:00
LOCK ( pto - > cs_inventory ) ;
2010-08-29 09:58:15 -07:00
vInv . reserve ( pto - > vInventoryToSend . size ( ) ) ;
vInvWait . reserve ( pto - > vInventoryToSend . size ( ) ) ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CInv & inv , pto - > vInventoryToSend )
2010-08-29 09:58:15 -07: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 )
2012-05-17 09:13:14 -07:00
hashSalt = GetRandHash ( ) ;
2010-08-29 09:58:15 -07:00
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 09:28:20 -07:00
CWalletTx wtx ;
if ( GetTransaction ( inv . hash , wtx ) )
if ( wtx . fFromMe )
fTrickleWait = true ;
2010-08-29 09:58:15 -07: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 13:33:19 -08:00
int64 nNow = GetTime ( ) * 1000000 ;
2010-08-29 09:58:15 -07:00
while ( ! pto - > mapAskFor . empty ( ) & & ( * pto - > mapAskFor . begin ( ) ) . first < = nNow )
{
const CInv & inv = ( * pto - > mapAskFor . begin ( ) ) . second ;
2012-07-06 07:33:34 -07:00
if ( ! AlreadyHave ( inv ) )
2010-08-29 09:58:15 -07:00
{
2012-06-22 10:11:57 -07:00
if ( fDebugNet )
printf ( " sending getdata: %s \n " , inv . ToString ( ) . c_str ( ) ) ;
2010-08-29 09:58:15 -07:00
vGetData . push_back ( inv ) ;
if ( vGetData . size ( ) > = 1000 )
{
pto - > PushMessage ( " getdata " , vGetData ) ;
vGetData . clear ( ) ;
}
}
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 09:28:20 -07:00
int static FormatHashBlocks ( void * pbuffer , unsigned int len )
2010-09-13 15:14:24 -07: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 11:16:07 -07:00
void SHA256Transform ( void * pstate , void * pinput , const void * pinit )
2010-09-13 15:14:24 -07:00
{
2011-09-27 11:16:07 -07: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 ) ) ;
2012-05-17 17:36:55 -07:00
for ( int i = 0 ; i < 8 ; i + + )
2011-09-27 11:16:07 -07:00
( ( uint32_t * ) pstate ) [ i ] = ctx . h [ i ] ;
2010-09-13 15:14:24 -07: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 11:16:36 -08:00
// between calls, but periodically or if nNonce is 0xffff0000 or above,
2010-09-13 15:14:24 -07: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 09:28:20 -07:00
unsigned int static ScanHash_CryptoPP ( char * pmidstate , char * pdata , char * phash1 , char * phash , unsigned int & nHashesDone )
2010-09-13 15:14:24 -07:00
{
2010-11-23 11:16:36 -08:00
unsigned int & nNonce = * ( unsigned int * ) ( pdata + 12 ) ;
2010-09-13 15:14:24 -07:00
for ( ; ; )
{
2012-07-25 17:48:39 -07:00
// Crypto++ SHA256
2010-11-23 11:16:36 -08:00
// Hash pdata using pmidstate as the starting state into
2012-07-25 17:48:39 -07:00
// pre-formatted buffer phash1, then hash phash1 into phash
2010-09-13 15:14:24 -07:00
nNonce + + ;
2010-11-23 11:16:36 -08:00
SHA256Transform ( phash1 , pdata , pmidstate ) ;
2010-09-13 15:14:24 -07: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 ;
2012-04-22 10:51:16 -07:00
return ( unsigned int ) - 1 ;
2010-09-13 15:14:24 -07:00
}
2013-03-06 19:16:05 -08:00
if ( ( nNonce & 0xfff ) = = 0 )
boost : : this_thread : : interruption_point ( ) ;
2010-09-13 15:14:24 -07:00
}
}
2011-08-15 17:33:00 -07:00
// Some explaining would be appreciated
2010-11-19 12:22:46 -08:00
class COrphan
{
public :
CTransaction * ptx ;
set < uint256 > setDependsOn ;
double dPriority ;
2012-07-12 11:22:32 -07:00
double dFeePerKb ;
2010-11-19 12:22:46 -08:00
COrphan ( CTransaction * ptxIn )
{
ptx = ptxIn ;
2012-07-12 11:22:32 -07:00
dPriority = dFeePerKb = 0 ;
2010-11-19 12:22:46 -08:00
}
void print ( ) const
{
2012-07-12 11:22:32 -07:00
printf ( " COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f) \n " ,
2013-04-06 18:40:33 -07:00
ptx - > GetHash ( ) . ToString ( ) . c_str ( ) , dPriority , dFeePerKb ) ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( uint256 hash , setDependsOn )
2013-04-06 18:40:33 -07:00
printf ( " setDependsOn %s \n " , hash . ToString ( ) . c_str ( ) ) ;
2010-11-19 12:22:46 -08:00
}
} ;
2011-05-26 21:02:51 -07:00
uint64 nLastBlockTx = 0 ;
uint64 nLastBlockSize = 0 ;
2012-07-12 11:22:32 -07:00
// We want to sort transactions by priority and fee, so:
typedef boost : : tuple < double , double , CTransaction * > TxPriority ;
class TxPriorityCompare
{
bool byFee ;
public :
TxPriorityCompare ( bool _byFee ) : byFee ( _byFee ) { }
bool operator ( ) ( const TxPriority & a , const TxPriority & b )
{
if ( byFee )
{
if ( a . get < 1 > ( ) = = b . get < 1 > ( ) )
return a . get < 0 > ( ) < b . get < 0 > ( ) ;
return a . get < 1 > ( ) < b . get < 1 > ( ) ;
}
else
{
if ( a . get < 0 > ( ) = = b . get < 0 > ( ) )
return a . get < 1 > ( ) < b . get < 1 > ( ) ;
return a . get < 0 > ( ) < b . get < 0 > ( ) ;
}
}
} ;
2012-12-19 12:21:21 -08:00
CBlockTemplate * CreateNewBlock ( CReserveKey & reservekey )
2010-11-23 11:16:36 -08:00
{
// Create new block
2012-12-19 12:21:21 -08:00
auto_ptr < CBlockTemplate > pblocktemplate ( new CBlockTemplate ( ) ) ;
if ( ! pblocktemplate . get ( ) )
2010-11-23 11:16:36 -08:00
return NULL ;
2012-12-19 12:21:21 -08:00
CBlock * pblock = & pblocktemplate - > block ; // pointer for convenience
2010-11-23 11:16:36 -08:00
// Create coinbase tx
CTransaction txNew ;
txNew . vin . resize ( 1 ) ;
txNew . vin [ 0 ] . prevout . SetNull ( ) ;
txNew . vout . resize ( 1 ) ;
2013-04-25 10:30:28 -07:00
CPubKey pubkey ;
if ( ! reservekey . GetReservedKey ( pubkey ) )
return NULL ;
txNew . vout [ 0 ] . scriptPubKey < < pubkey < < OP_CHECKSIG ;
2010-11-23 11:16:36 -08:00
// Add our coinbase tx as first transaction
pblock - > vtx . push_back ( txNew ) ;
2012-12-19 12:21:21 -08:00
pblocktemplate - > vTxFees . push_back ( - 1 ) ; // updated at end
pblocktemplate - > vTxSigOps . push_back ( - 1 ) ; // updated at end
2010-11-23 11:16:36 -08:00
2012-07-12 11:22:32 -07:00
// Largest block you're willing to create:
unsigned int nBlockMaxSize = GetArg ( " -blockmaxsize " , MAX_BLOCK_SIZE_GEN / 2 ) ;
// Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
nBlockMaxSize = std : : max ( ( unsigned int ) 1000 , std : : min ( ( unsigned int ) ( MAX_BLOCK_SIZE - 1000 ) , nBlockMaxSize ) ) ;
// How much of the block should be dedicated to high-priority transactions,
// included regardless of the fees they pay
unsigned int nBlockPrioritySize = GetArg ( " -blockprioritysize " , 27000 ) ;
nBlockPrioritySize = std : : min ( nBlockMaxSize , nBlockPrioritySize ) ;
// Minimum block size you want to create; block will be filled with free transactions
// until there are no more or the block reaches this size:
unsigned int nBlockMinSize = GetArg ( " -blockminsize " , 0 ) ;
nBlockMinSize = std : : min ( nBlockMaxSize , nBlockMinSize ) ;
2010-11-23 11:16:36 -08:00
// Collect memory pool transactions into the block
2011-12-21 13:33:19 -08:00
int64 nFees = 0 ;
2010-11-23 11:16:36 -08:00
{
2012-04-13 13:03:09 -07:00
LOCK2 ( cs_main , mempool . cs ) ;
2012-10-23 22:41:52 -07:00
CBlockIndex * pindexPrev = pindexBest ;
2012-07-06 07:33:34 -07:00
CCoinsViewCache view ( * pcoinsTip , true ) ;
2010-11-23 11:16:36 -08:00
// Priority order to process transactions
list < COrphan > vOrphan ; // list memory doesn't move
map < uint256 , vector < COrphan * > > mapDependers ;
2013-04-28 08:37:50 -07:00
bool fPrintPriority = GetBoolArg ( " -printpriority " , false ) ;
2012-07-12 11:22:32 -07:00
// This vector will be sorted into a priority queue:
vector < TxPriority > vecPriority ;
vecPriority . reserve ( mempool . mapTx . size ( ) ) ;
2012-04-13 13:03:09 -07:00
for ( map < uint256 , CTransaction > : : iterator mi = mempool . mapTx . begin ( ) ; mi ! = mempool . mapTx . end ( ) ; + + mi )
2010-11-23 11:16:36 -08:00
{
CTransaction & tx = ( * mi ) . second ;
if ( tx . IsCoinBase ( ) | | ! tx . IsFinal ( ) )
continue ;
COrphan * porphan = NULL ;
double dPriority = 0 ;
2012-07-12 11:22:32 -07:00
int64 nTotalIn = 0 ;
2012-07-26 12:29:59 -07:00
bool fMissingInputs = false ;
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
2010-11-23 11:16:36 -08:00
{
// Read prev transaction
2013-05-20 17:36:48 -07:00
if ( ! view . HaveCoins ( txin . prevout . hash ) )
2010-11-23 11:16:36 -08:00
{
2012-07-26 12:29:59 -07:00
// This should never happen; all transactions in the memory
// pool should connect to either transactions in the chain
// or other transactions in the memory pool.
if ( ! mempool . mapTx . count ( txin . prevout . hash ) )
{
printf ( " ERROR: mempool transaction missing input \n " ) ;
if ( fDebug ) assert ( " mempool transaction missing input " = = 0 ) ;
fMissingInputs = true ;
if ( porphan )
vOrphan . pop_back ( ) ;
break ;
}
2010-11-23 11:16:36 -08:00
// 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 ) ;
2012-07-12 11:22:32 -07:00
nTotalIn + = mempool . mapTx [ txin . prevout . hash ] . vout [ txin . prevout . n ] . nValue ;
2010-11-23 11:16:36 -08:00
continue ;
}
2013-05-20 17:36:48 -07:00
const CCoins & coins = view . GetCoins ( txin . prevout . hash ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
int64 nValueIn = coins . vout [ txin . prevout . n ] . nValue ;
2012-07-12 11:22:32 -07:00
nTotalIn + = nValueIn ;
2010-11-23 11:16:36 -08:00
2012-10-22 15:10:12 -07:00
int nConf = pindexPrev - > nHeight - coins . nHeight + 1 ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
2010-11-23 11:16:36 -08:00
dPriority + = ( double ) nValueIn * nConf ;
}
2012-07-26 12:29:59 -07:00
if ( fMissingInputs ) continue ;
2010-11-23 11:16:36 -08:00
// Priority is sum(valuein * age) / txsize
2012-07-12 11:22:32 -07:00
unsigned int nTxSize = : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ;
dPriority / = nTxSize ;
2010-11-23 11:16:36 -08:00
2012-07-12 11:22:32 -07:00
// This is a more accurate fee-per-kilobyte than is used by the client code, because the
// client code rounds up the size to the nearest 1K. That's good, because it gives an
// incentive to create smaller transactions.
double dFeePerKb = double ( nTotalIn - tx . GetValueOut ( ) ) / ( double ( nTxSize ) / 1000.0 ) ;
2010-11-23 11:16:36 -08:00
2012-07-12 11:22:32 -07:00
if ( porphan )
2010-11-23 11:16:36 -08:00
{
2012-07-12 11:22:32 -07:00
porphan - > dPriority = dPriority ;
porphan - > dFeePerKb = dFeePerKb ;
2010-11-23 11:16:36 -08:00
}
2012-07-12 11:22:32 -07:00
else
vecPriority . push_back ( TxPriority ( dPriority , dFeePerKb , & ( * mi ) . second ) ) ;
2010-11-23 11:16:36 -08:00
}
// Collect transactions into block
2011-12-21 13:33:19 -08:00
uint64 nBlockSize = 1000 ;
2011-05-26 21:02:51 -07:00
uint64 nBlockTx = 0 ;
2012-01-20 14:07:40 -08:00
int nBlockSigOps = 100 ;
2012-07-12 11:22:32 -07:00
bool fSortedByFee = ( nBlockPrioritySize < = 0 ) ;
TxPriorityCompare comparer ( fSortedByFee ) ;
std : : make_heap ( vecPriority . begin ( ) , vecPriority . end ( ) , comparer ) ;
while ( ! vecPriority . empty ( ) )
2010-11-23 11:16:36 -08:00
{
2012-07-12 11:22:32 -07:00
// Take highest priority transaction off the priority queue:
double dPriority = vecPriority . front ( ) . get < 0 > ( ) ;
double dFeePerKb = vecPriority . front ( ) . get < 1 > ( ) ;
CTransaction & tx = * ( vecPriority . front ( ) . get < 2 > ( ) ) ;
std : : pop_heap ( vecPriority . begin ( ) , vecPriority . end ( ) , comparer ) ;
vecPriority . pop_back ( ) ;
2010-11-23 11:16:36 -08:00
// Size limits
2012-04-16 05:56:45 -07:00
unsigned int nTxSize = : : GetSerializeSize ( tx , SER_NETWORK , PROTOCOL_VERSION ) ;
2012-07-12 11:22:32 -07:00
if ( nBlockSize + nTxSize > = nBlockMaxSize )
2010-11-23 11:16:36 -08:00
continue ;
2012-01-04 18:40:52 -08:00
// Legacy limits on sigOps:
2012-04-23 11:14:03 -07:00
unsigned int nTxSigOps = tx . GetLegacySigOpCount ( ) ;
2012-01-20 14:07:40 -08:00
if ( nBlockSigOps + nTxSigOps > = MAX_BLOCK_SIGOPS )
2012-01-04 18:40:52 -08:00
continue ;
2012-07-12 11:22:32 -07:00
// Skip free transactions if we're past the minimum block size:
2013-04-25 17:11:27 -07:00
if ( fSortedByFee & & ( dFeePerKb < CTransaction : : nMinTxFee ) & & ( nBlockSize + nTxSize > = nBlockMinSize ) )
2012-07-12 11:22:32 -07:00
continue ;
// Prioritize by fee once past the priority size or we run out of high-priority
// transactions:
if ( ! fSortedByFee & &
( ( nBlockSize + nTxSize > = nBlockPrioritySize ) | | ( dPriority < COIN * 144 / 250 ) ) )
{
fSortedByFee = true ;
comparer = TxPriorityCompare ( fSortedByFee ) ;
std : : make_heap ( vecPriority . begin ( ) , vecPriority . end ( ) , comparer ) ;
}
2010-11-23 11:16:36 -08:00
2013-05-20 17:36:48 -07:00
if ( ! tx . HaveInputs ( view ) )
2011-10-03 10:05:43 -07:00
continue ;
2012-01-04 18:40:52 -08:00
2013-05-20 17:36:48 -07:00
int64 nTxFees = tx . GetValueIn ( view ) - tx . GetValueOut ( ) ;
2012-01-10 17:18:00 -08:00
2013-05-20 17:36:48 -07:00
nTxSigOps + = tx . GetP2SHSigOpCount ( view ) ;
2012-01-20 14:07:40 -08:00
if ( nBlockSigOps + nTxSigOps > = MAX_BLOCK_SIGOPS )
2010-11-23 11:16:36 -08:00
continue ;
2012-01-10 17:18:00 -08:00
2013-01-26 15:14:11 -08:00
CValidationState state ;
2013-05-20 17:36:48 -07:00
if ( ! tx . CheckInputs ( state , view , true , SCRIPT_VERIFY_P2SH ) )
2012-07-08 10:04:05 -07:00
continue ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
CTxUndo txundo ;
2012-07-07 15:06:34 -07:00
uint256 hash = tx . GetHash ( ) ;
2013-05-20 17:36:48 -07:00
tx . UpdateCoins ( state , view , txundo , pindexPrev - > nHeight + 1 , hash ) ;
2010-11-23 11:16:36 -08:00
// Added
pblock - > vtx . push_back ( tx ) ;
2012-12-19 12:21:21 -08:00
pblocktemplate - > vTxFees . push_back ( nTxFees ) ;
pblocktemplate - > vTxSigOps . push_back ( nTxSigOps ) ;
2010-11-23 11:16:36 -08:00
nBlockSize + = nTxSize ;
2011-05-26 21:02:51 -07:00
+ + nBlockTx ;
2012-01-20 14:07:40 -08:00
nBlockSigOps + = nTxSigOps ;
2012-01-28 07:16:21 -08:00
nFees + = nTxFees ;
2010-11-23 11:16:36 -08:00
2012-11-26 08:30:54 -08:00
if ( fPrintPriority )
2012-07-12 11:22:32 -07:00
{
printf ( " priority %.1f feeperkb %.1f txid %s \n " ,
dPriority , dFeePerKb , tx . GetHash ( ) . ToString ( ) . c_str ( ) ) ;
}
2010-11-23 11:16:36 -08:00
// Add transactions that depend on this one to the priority queue
if ( mapDependers . count ( hash ) )
{
2011-05-15 00:11:04 -07:00
BOOST_FOREACH ( COrphan * porphan , mapDependers [ hash ] )
2010-11-23 11:16:36 -08:00
{
if ( ! porphan - > setDependsOn . empty ( ) )
{
porphan - > setDependsOn . erase ( hash ) ;
if ( porphan - > setDependsOn . empty ( ) )
2012-07-12 11:22:32 -07:00
{
vecPriority . push_back ( TxPriority ( porphan - > dPriority , porphan - > dFeePerKb , porphan - > ptx ) ) ;
std : : push_heap ( vecPriority . begin ( ) , vecPriority . end ( ) , comparer ) ;
}
2010-11-23 11:16:36 -08:00
}
}
}
}
2011-05-26 21:02:51 -07:00
nLastBlockTx = nBlockTx ;
nLastBlockSize = nBlockSize ;
2012-09-29 02:57:44 -07:00
printf ( " CreateNewBlock(): total size % " PRI64u " \n " , nBlockSize ) ;
2011-05-26 21:02:51 -07:00
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
pblock - > vtx [ 0 ] . vout [ 0 ] . nValue = GetBlockValue ( pindexPrev - > nHeight + 1 , nFees ) ;
2012-12-19 12:21:21 -08:00
pblocktemplate - > vTxFees [ 0 ] = - nFees ;
2010-11-23 11:16:36 -08:00
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
// Fill in header
pblock - > hashPrevBlock = pindexPrev - > GetBlockHash ( ) ;
pblock - > UpdateTime ( pindexPrev ) ;
2012-12-19 12:21:21 -08:00
pblock - > nBits = GetNextWorkRequired ( pindexPrev , pblock ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
pblock - > nNonce = 0 ;
2012-10-12 14:49:44 -07:00
pblock - > vtx [ 0 ] . vin [ 0 ] . scriptSig = CScript ( ) < < OP_0 < < OP_0 ;
2012-12-19 12:21:21 -08:00
pblocktemplate - > vTxSigOps [ 0 ] = pblock - > vtx [ 0 ] . GetLegacySigOpCount ( ) ;
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
2012-07-01 09:54:00 -07:00
2012-06-18 16:36:43 -07:00
CBlockIndex indexDummy ( * pblock ) ;
2012-05-09 10:24:44 -07:00
indexDummy . pprev = pindexPrev ;
indexDummy . nHeight = pindexPrev - > nHeight + 1 ;
2012-07-06 07:33:34 -07:00
CCoinsViewCache viewNew ( * pcoinsTip , true ) ;
2013-01-26 15:14:11 -08:00
CValidationState state ;
if ( ! pblock - > ConnectBlock ( state , & indexDummy , viewNew , true ) )
2012-05-09 10:24:44 -07:00
throw std : : runtime_error ( " CreateNewBlock() : ConnectBlock failed " ) ;
}
2012-12-19 12:21:21 -08:00
return pblocktemplate . release ( ) ;
2010-11-23 11:16:36 -08:00
}
2011-09-06 13:39:05 -07:00
void IncrementExtraNonce ( CBlock * pblock , CBlockIndex * pindexPrev , unsigned int & nExtraNonce )
2010-11-23 11:16:36 -08:00
{
// Update nExtraNonce
2011-06-12 17:16:54 -07:00
static uint256 hashPrevBlock ;
if ( hashPrevBlock ! = pblock - > hashPrevBlock )
2010-11-23 11:16:36 -08:00
{
2011-06-12 17:16:54 -07:00
nExtraNonce = 0 ;
hashPrevBlock = pblock - > hashPrevBlock ;
2010-11-23 11:16:36 -08:00
}
2011-06-12 17:16:54 -07:00
+ + nExtraNonce ;
2012-06-27 16:30:39 -07:00
unsigned int nHeight = pindexPrev - > nHeight + 1 ; // Height first in coinbase required for block.version=2
pblock - > vtx [ 0 ] . vin [ 0 ] . scriptSig = ( CScript ( ) < < nHeight < < CBigNum ( nExtraNonce ) ) + COINBASE_FLAGS ;
2011-10-13 13:03:58 -07:00
assert ( pblock - > vtx [ 0 ] . vin [ 0 ] . scriptSig . size ( ) < = 100 ) ;
2010-11-23 11:16:36 -08:00
pblock - > hashMerkleRoot = pblock - > BuildMerkleTree ( ) ;
}
void FormatHashBuffers ( CBlock * pblock , char * pmidstate , char * pdata , char * phash1 )
{
//
2012-07-25 17:48:39 -07:00
// Pre-build hash buffers
2010-11-23 11:16:36 -08:00
//
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 13:52:09 -07:00
for ( unsigned int i = 0 ; i < sizeof ( tmp ) / 4 ; i + + )
2010-11-23 11:16:36 -08: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 09:28:20 -07:00
bool CheckWork ( CBlock * pblock , CWallet & wallet , CReserveKey & reservekey )
2010-11-23 11:16:36 -08: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 ( " generated %s \n " , FormatMoney ( pblock - > vtx [ 0 ] . vout [ 0 ] . nValue ) . c_str ( ) ) ;
// Found a solution
{
2012-04-06 09:39:12 -07:00
LOCK ( cs_main ) ;
2010-11-23 11:16:36 -08: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 09:39:12 -07: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 09:28:20 -07:00
wallet . mapRequestCount [ pblock - > GetHash ( ) ] = 0 ;
2012-04-06 09:39:12 -07:00
}
2010-11-23 11:16:36 -08:00
// Process this block the same as if we had received it from another node
2013-01-26 15:14:11 -08:00
CValidationState state ;
if ( ! ProcessBlock ( state , NULL , pblock ) )
2010-11-23 11:16:36 -08:00
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 09:28:20 -07:00
void static BitcoinMiner ( CWallet * pwallet )
2010-08-29 09:58:15 -07:00
{
printf ( " BitcoinMiner started \n " ) ;
SetThreadPriority ( THREAD_PRIORITY_LOWEST ) ;
2012-06-30 08:14:28 -07:00
RenameThread ( " bitcoin-miner " ) ;
2012-06-24 08:03:57 -07:00
2010-11-23 11:16:36 -08: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 09:28:20 -07:00
CReserveKey reservekey ( pwallet ) ;
2010-10-19 10:16:51 -07:00
unsigned int nExtraNonce = 0 ;
2010-11-23 11:16:36 -08:00
2013-03-06 19:16:05 -08:00
try { loop {
while ( vNodes . empty ( ) )
2013-03-07 11:25:21 -08:00
MilliSleep ( 1000 ) ;
2010-08-29 09:58:15 -07:00
//
// Create new block
//
2010-11-23 11:16:36 -08:00
unsigned int nTransactionsUpdatedLast = nTransactionsUpdated ;
CBlockIndex * pindexPrev = pindexBest ;
2012-12-19 12:21:21 -08:00
auto_ptr < CBlockTemplate > pblocktemplate ( CreateNewBlock ( reservekey ) ) ;
if ( ! pblocktemplate . get ( ) )
2010-08-29 09:58:15 -07:00
return ;
2012-12-19 12:21:21 -08:00
CBlock * pblock = & pblocktemplate - > block ;
IncrementExtraNonce ( pblock , pindexPrev , nExtraNonce ) ;
2010-08-29 09:58:15 -07:00
2012-09-29 02:57:44 -07:00
printf ( " Running BitcoinMiner with % " PRIszu " transactions in block (%u bytes) \n " , pblock - > vtx . size ( ) ,
2012-07-12 11:22:32 -07:00
: : GetSerializeSize ( * pblock , SER_NETWORK , PROTOCOL_VERSION ) ) ;
2010-08-29 09:58:15 -07:00
//
2012-07-25 17:48:39 -07:00
// Pre-build hash buffers
2010-08-29 09:58:15 -07:00
//
2010-11-23 11:16:36 -08: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 ) ;
2012-12-19 12:21:21 -08:00
FormatHashBuffers ( pblock , pmidstate , pdata , phash1 ) ;
2010-11-23 11:16:36 -08:00
unsigned int & nBlockTime = * ( unsigned int * ) ( pdata + 64 + 4 ) ;
2012-02-16 07:22:31 -08:00
unsigned int & nBlockBits = * ( unsigned int * ) ( pdata + 64 + 8 ) ;
2010-11-23 11:16:36 -08:00
unsigned int & nBlockNonce = * ( unsigned int * ) ( pdata + 64 + 12 ) ;
2010-08-29 09:58:15 -07:00
//
// Search
//
2011-12-21 13:33:19 -08:00
int64 nStart = GetTime ( ) ;
2010-08-29 09:58:15 -07:00
uint256 hashTarget = CBigNum ( ) . SetCompact ( pblock - > nBits ) . getuint256 ( ) ;
uint256 hashbuf [ 2 ] ;
uint256 & hash = * alignup < 16 > ( hashbuf ) ;
loop
{
2010-09-13 15:14:24 -07:00
unsigned int nHashesDone = 0 ;
unsigned int nNonceFound ;
2012-07-25 17:48:39 -07:00
// Crypto++ SHA256
2011-04-03 11:21:52 -07:00
nNonceFound = ScanHash_CryptoPP ( pmidstate , pdata + 64 , phash1 ,
( char * ) & hash , nHashesDone ) ;
2010-08-29 09:58:15 -07:00
2010-09-13 15:14:24 -07:00
// Check if something found
2012-04-22 10:51:16 -07:00
if ( nNonceFound ! = ( unsigned int ) - 1 )
2010-08-29 09:58:15 -07:00
{
2012-04-15 13:52:09 -07:00
for ( unsigned int i = 0 ; i < sizeof ( hash ) / 4 ; i + + )
2010-08-29 09:58:15 -07:00
( ( unsigned int * ) & hash ) [ i ] = ByteReverse ( ( ( unsigned int * ) & hash ) [ i ] ) ;
if ( hash < = hashTarget )
{
2010-09-13 15:14:24 -07:00
// Found a solution
pblock - > nNonce = ByteReverse ( nNonceFound ) ;
2010-08-29 09:58:15 -07:00
assert ( hash = = pblock - > GetHash ( ) ) ;
SetThreadPriority ( THREAD_PRIORITY_NORMAL ) ;
2012-12-19 12:21:21 -08:00
CheckWork ( pblock , * pwalletMain , reservekey ) ;
2010-08-29 09:58:15 -07:00
SetThreadPriority ( THREAD_PRIORITY_LOWEST ) ;
break ;
}
}
2010-09-13 15:14:24 -07:00
// Meter hashes/sec
2011-12-21 13:33:19 -08:00
static int64 nHashCounter ;
2010-09-13 15:14:24 -07:00
if ( nHPSTimerStart = = 0 )
2010-08-29 09:58:15 -07:00
{
2010-09-13 15:14:24 -07:00
nHPSTimerStart = GetTimeMillis ( ) ;
nHashCounter = 0 ;
}
else
nHashCounter + = nHashesDone ;
if ( GetTimeMillis ( ) - nHPSTimerStart > 4000 )
{
static CCriticalSection cs ;
2010-08-29 09:58:15 -07:00
{
2012-04-06 09:39:12 -07:00
LOCK ( cs ) ;
2010-09-13 15:14:24 -07:00
if ( GetTimeMillis ( ) - nHPSTimerStart > 4000 )
2010-08-29 09:58:15 -07:00
{
2010-09-13 15:14:24 -07:00
dHashesPerSec = 1000.0 * nHashCounter / ( GetTimeMillis ( ) - nHPSTimerStart ) ;
nHPSTimerStart = GetTimeMillis ( ) ;
nHashCounter = 0 ;
2011-12-21 13:33:19 -08:00
static int64 nLogTime ;
2010-09-13 15:14:24 -07:00
if ( GetTime ( ) - nLogTime > 30 * 60 )
2010-08-29 09:58:15 -07:00
{
2010-09-13 15:14:24 -07:00
nLogTime = GetTime ( ) ;
2013-03-06 19:16:05 -08:00
printf ( " hashmeter %6.0f khash/s \n " , dHashesPerSec / 1000.0 ) ;
2010-08-29 09:58:15 -07:00
}
}
}
2010-09-13 15:14:24 -07:00
}
2010-08-29 09:58:15 -07:00
2010-09-13 15:14:24 -07:00
// Check for stop or if block needs to be rebuilt
2013-03-06 19:16:05 -08:00
boost : : this_thread : : interruption_point ( ) ;
2010-09-13 15:14:24 -07:00
if ( vNodes . empty ( ) )
break ;
2010-11-23 11:16:36 -08:00
if ( nBlockNonce > = 0xffff0000 )
2010-09-13 15:14:24 -07:00
break ;
if ( nTransactionsUpdated ! = nTransactionsUpdatedLast & & GetTime ( ) - nStart > 60 )
break ;
if ( pindexPrev ! = pindexBest )
break ;
2010-08-29 09:58:15 -07:00
2010-09-13 15:14:24 -07:00
// Update nTime every few seconds
2012-02-16 07:22:31 -08:00
pblock - > UpdateTime ( pindexPrev ) ;
2010-11-23 11:16:36 -08:00
nBlockTime = ByteReverse ( pblock - > nTime ) ;
2012-02-16 07:22:31 -08: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 09:58:15 -07:00
}
2013-03-06 19:16:05 -08:00
} }
catch ( boost : : thread_interrupted )
2010-08-29 09:58:15 -07:00
{
2013-03-06 19:16:05 -08:00
printf ( " BitcoinMiner terminated \n " ) ;
throw ;
}
2010-11-09 11:47:07 -08: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 09:28:20 -07:00
void GenerateBitcoins ( bool fGenerate , CWallet * pwallet )
2010-08-29 09:58:15 -07:00
{
2013-03-06 19:16:05 -08:00
static boost : : thread_group * minerThreads = NULL ;
2012-02-16 12:00:16 -08:00
2013-03-06 19:16:05 -08:00
int nThreads = GetArg ( " -genproclimit " , - 1 ) ;
if ( nThreads < 0 )
nThreads = boost : : thread : : hardware_concurrency ( ) ;
2012-02-16 12:00:16 -08:00
2013-03-06 19:16:05 -08:00
if ( minerThreads ! = NULL )
2010-08-29 09:58:15 -07:00
{
2013-03-06 19:16:05 -08:00
minerThreads - > interrupt_all ( ) ;
delete minerThreads ;
minerThreads = NULL ;
2011-04-04 19:24:35 -07:00
}
2013-03-06 19:16:05 -08:00
if ( nThreads = = 0 | | ! fGenerate )
return ;
minerThreads = new boost : : thread_group ( ) ;
for ( int i = 0 ; i < nThreads ; i + + )
minerThreads - > create_thread ( boost : : bind ( & BitcoinMiner , pwallet ) ) ;
2010-08-29 09:58:15 -07:00
}
2012-06-16 04:36:00 -07:00
// Amount compression:
// * If the amount is 0, output 0
// * first, divide the amount (in base units) by the largest power of 10 possible; call the exponent e (e is max 9)
// * if e<9, the last digit of the resulting number cannot be 0; store it as d, and drop it (divide by 10)
// * call the result n
// * output 1 + 10*(9*n + d - 1) + e
// * if e==9, we only know the resulting number is not zero, so output 1 + 10*(n - 1) + 9
// (this is decodable, as d is in [1-9] and e is in [0-9])
uint64 CTxOutCompressor : : CompressAmount ( uint64 n )
{
if ( n = = 0 )
return 0 ;
int e = 0 ;
while ( ( ( n % 10 ) = = 0 ) & & e < 9 ) {
n / = 10 ;
e + + ;
}
if ( e < 9 ) {
int d = ( n % 10 ) ;
assert ( d > = 1 & & d < = 9 ) ;
n / = 10 ;
return 1 + ( n * 9 + d - 1 ) * 10 + e ;
} else {
return 1 + ( n - 1 ) * 10 + 9 ;
}
}
uint64 CTxOutCompressor : : DecompressAmount ( uint64 x )
{
// x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9
if ( x = = 0 )
return 0 ;
x - - ;
// x = 10*(9*n + d - 1) + e
int e = x % 10 ;
x / = 10 ;
uint64 n = 0 ;
if ( e < 9 ) {
// x = 9*n + d - 1
int d = ( x % 9 ) + 1 ;
x / = 9 ;
// x = n
n = x * 10 + d ;
} else {
n = x + 1 ;
}
while ( e ) {
n * = 10 ;
e - - ;
}
return n ;
}
2013-03-28 18:17:10 -07:00
class CMainCleanup
{
public :
CMainCleanup ( ) { }
~ CMainCleanup ( ) {
// block headers
std : : map < uint256 , CBlockIndex * > : : iterator it1 = mapBlockIndex . begin ( ) ;
for ( ; it1 ! = mapBlockIndex . end ( ) ; it1 + + )
delete ( * it1 ) . second ;
mapBlockIndex . clear ( ) ;
// orphan blocks
std : : map < uint256 , CBlock * > : : iterator it2 = mapOrphanBlocks . begin ( ) ;
for ( ; it2 ! = mapOrphanBlocks . end ( ) ; it2 + + )
delete ( * it2 ) . second ;
mapOrphanBlocks . clear ( ) ;
// orphan transactions
std : : map < uint256 , CDataStream * > : : iterator it3 = mapOrphanTransactions . begin ( ) ;
for ( ; it3 ! = mapOrphanTransactions . end ( ) ; it3 + + )
delete ( * it3 ) . second ;
mapOrphanTransactions . clear ( ) ;
}
} instance_of_cmaincleanup ;