diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/chainparams.cpp | 51 | ||||
-rw-r--r-- | src/chainparams.h | 35 | ||||
-rw-r--r-- | src/consensus/params.h | 32 | ||||
-rw-r--r-- | src/init.cpp | 1 | ||||
-rw-r--r-- | src/main.cpp | 85 | ||||
-rw-r--r-- | src/main.h | 27 | ||||
-rw-r--r-- | src/miner.cpp | 4 | ||||
-rw-r--r-- | src/pow.cpp | 39 | ||||
-rw-r--r-- | src/pow.h | 8 | ||||
-rw-r--r-- | src/qt/addresstablemodel.cpp | 2 | ||||
-rw-r--r-- | src/qt/paymentserver.cpp | 1 | ||||
-rw-r--r-- | src/qt/sendcoinsdialog.cpp | 1 | ||||
-rw-r--r-- | src/qt/signverifymessagedialog.cpp | 1 | ||||
-rw-r--r-- | src/qt/transactionrecord.cpp | 3 | ||||
-rw-r--r-- | src/rpcmining.cpp | 3 | ||||
-rw-r--r-- | src/test/pow_tests.cpp | 13 | ||||
-rw-r--r-- | src/test/rpc_wallet_tests.cpp | 1 | ||||
-rw-r--r-- | src/txdb.cpp | 5 | ||||
-rw-r--r-- | src/txdb.h | 6 | ||||
-rw-r--r-- | src/validationinterface.cpp | 47 | ||||
-rw-r--r-- | src/validationinterface.h | 62 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 3 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 69 | ||||
-rw-r--r-- | src/wallet/wallet.h | 78 | ||||
-rw-r--r-- | src/wallet/walletdb.cpp | 1 |
26 files changed, 336 insertions, 245 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2c607c632e..37184b6286 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,6 +87,7 @@ BITCOIN_CORE_H = \ coins.h \ compat.h \ compressor.h \ + consensus/params.h \ core_io.h \ wallet/db.h \ eccryptoverify.h \ @@ -138,6 +139,7 @@ BITCOIN_CORE_H = \ utilmoneystr.h \ utilstrencodings.h \ utiltime.h \ + validationinterface.h \ version.h \ wallet/crypter.h \ wallet/walletdb.h \ @@ -191,6 +193,7 @@ libbitcoin_server_a_SOURCES = \ timedata.cpp \ txdb.cpp \ txmempool.cpp \ + validationinterface.cpp \ $(JSON_H) \ $(BITCOIN_CORE_H) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 2bc8976510..3e20d9f8f2 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -101,6 +101,14 @@ class CMainParams : public CChainParams { public: CMainParams() { strNetworkID = "main"; + consensus.nSubsidyHalvingInterval = 210000; + consensus.nMajorityEnforceBlockUpgrade = 750; + consensus.nMajorityRejectBlockOutdated = 950; + consensus.nMajorityWindow = 1000; + consensus.powLimit = ~arith_uint256(0) >> 32; + consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks + consensus.nPowTargetSpacing = 10 * 60; + consensus.fPowAllowMinDifficultyBlocks = false; /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -112,14 +120,7 @@ public: pchMessageStart[3] = 0xd9; vAlertPubKey = ParseHex("04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284"); nDefaultPort = 8333; - bnProofOfWorkLimit = ~arith_uint256(0) >> 32; - nSubsidyHalvingInterval = 210000; - nEnforceBlockUpgradeMajority = 750; - nRejectBlockOutdatedMajority = 950; - nToCheckBlockUpgradeMajority = 1000; nMinerThreads = 0; - nTargetTimespan = 14 * 24 * 60 * 60; // two weeks - nTargetSpacing = 10 * 60; /** * Build the genesis block. Note that the output of the genesis coinbase cannot @@ -146,8 +147,8 @@ public: genesis.nBits = 0x1d00ffff; genesis.nNonce = 2083236893; - hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); vSeeds.push_back(CDNSSeedData("bitcoin.sipa.be", "seed.bitcoin.sipa.be")); @@ -167,7 +168,6 @@ public: fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultCheckMemPool = false; - fAllowMinDifficultyBlocks = false; fRequireStandard = true; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = false; @@ -187,24 +187,23 @@ class CTestNetParams : public CMainParams { public: CTestNetParams() { strNetworkID = "test"; + consensus.nMajorityEnforceBlockUpgrade = 51; + consensus.nMajorityRejectBlockOutdated = 75; + consensus.nMajorityWindow = 100; + consensus.fPowAllowMinDifficultyBlocks = true; pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; pchMessageStart[3] = 0x07; vAlertPubKey = ParseHex("04302390343f91cc401d56d68b123028bf52e5fca1939df127f63c6467cdf9c8e2c14b61104cf817d0b780da337893ecc4aaff1309e536162dabbdb45200ca2b0a"); nDefaultPort = 18333; - nEnforceBlockUpgradeMajority = 51; - nRejectBlockOutdatedMajority = 75; - nToCheckBlockUpgradeMajority = 100; nMinerThreads = 0; - nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks - nTargetSpacing = 10 * 60; //! Modify the testnet genesis block so the timestamp is valid for a later start. genesis.nTime = 1296688602; genesis.nNonce = 414098458; - hashGenesisBlock = genesis.GetHash(); - assert(hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); + consensus.hashGenesisBlock = genesis.GetHash(); + assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); vFixedSeeds.clear(); vSeeds.clear(); @@ -224,7 +223,6 @@ public: fRequireRPCPassword = true; fMiningRequiresPeers = true; fDefaultCheckMemPool = false; - fAllowMinDifficultyBlocks = true; fRequireStandard = false; fMineBlocksOnDemand = false; fTestnetToBeDeprecatedFieldRPC = true; @@ -243,24 +241,22 @@ class CRegTestParams : public CTestNetParams { public: CRegTestParams() { strNetworkID = "regtest"; + consensus.nSubsidyHalvingInterval = 150; + consensus.nMajorityEnforceBlockUpgrade = 750; + consensus.nMajorityRejectBlockOutdated = 950; + consensus.nMajorityWindow = 1000; + consensus.powLimit = ~arith_uint256(0) >> 1; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; - nSubsidyHalvingInterval = 150; - nEnforceBlockUpgradeMajority = 750; - nRejectBlockOutdatedMajority = 950; - nToCheckBlockUpgradeMajority = 1000; nMinerThreads = 1; - nTargetTimespan = 14 * 24 * 60 * 60; //! two weeks - nTargetSpacing = 10 * 60; - bnProofOfWorkLimit = ~arith_uint256(0) >> 1; genesis.nTime = 1296688602; genesis.nBits = 0x207fffff; genesis.nNonce = 2; - hashGenesisBlock = genesis.GetHash(); + consensus.hashGenesisBlock = genesis.GetHash(); nDefaultPort = 18444; - assert(hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); + assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds. @@ -268,7 +264,6 @@ public: fRequireRPCPassword = false; fMiningRequiresPeers = false; fDefaultCheckMemPool = true; - fAllowMinDifficultyBlocks = true; fRequireStandard = false; fMineBlocksOnDemand = true; fTestnetToBeDeprecatedFieldRPC = false; diff --git a/src/chainparams.h b/src/chainparams.h index 134dcd6558..aa2ec1e301 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -6,11 +6,12 @@ #ifndef BITCOIN_CHAINPARAMS_H #define BITCOIN_CHAINPARAMS_H +#include "arith_uint256.h" #include "chainparamsbase.h" #include "checkpoints.h" +#include "consensus/params.h" #include "primitives/block.h" #include "protocol.h" -#include "arith_uint256.h" #include <vector> @@ -39,16 +40,16 @@ public: MAX_BASE58_TYPES }; - const uint256& HashGenesisBlock() const { return hashGenesisBlock; } + const Consensus::Params& GetConsensus() const { return consensus; } + const uint256& HashGenesisBlock() const { return consensus.hashGenesisBlock; } const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; } int GetDefaultPort() const { return nDefaultPort; } - const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; } - int SubsidyHalvingInterval() const { return nSubsidyHalvingInterval; } - /** Used to check majorities for block version upgrade */ - int EnforceBlockUpgradeMajority() const { return nEnforceBlockUpgradeMajority; } - int RejectBlockOutdatedMajority() const { return nRejectBlockOutdatedMajority; } - int ToCheckBlockUpgradeMajority() const { return nToCheckBlockUpgradeMajority; } + const arith_uint256& ProofOfWorkLimit() const { return consensus.powLimit; } + int SubsidyHalvingInterval() const { return consensus.nSubsidyHalvingInterval; } + int EnforceBlockUpgradeMajority() const { return consensus.nMajorityEnforceBlockUpgrade; } + int RejectBlockOutdatedMajority() const { return consensus.nMajorityRejectBlockOutdated; } + int ToCheckBlockUpgradeMajority() const { return consensus.nMajorityWindow; } /** Used if GenerateBitcoins is called with a negative number of threads */ int DefaultMinerThreads() const { return nMinerThreads; } @@ -59,12 +60,12 @@ public: /** Default value for -checkmempool argument */ bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; } /** Allow mining of a min-difficulty block */ - bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; } + bool AllowMinDifficultyBlocks() const { return consensus.fPowAllowMinDifficultyBlocks; } /** Make standard checks */ bool RequireStandard() const { return fRequireStandard; } - int64_t TargetTimespan() const { return nTargetTimespan; } - int64_t TargetSpacing() const { return nTargetSpacing; } - int64_t DifficultyAdjustmentInterval() const { return nTargetTimespan / nTargetSpacing; } + int64_t TargetTimespan() const { return consensus.nPowTargetTimespan; } + int64_t TargetSpacing() const { return consensus.nPowTargetSpacing; } + int64_t DifficultyAdjustmentInterval() const { return consensus.nPowTargetTimespan / consensus.nPowTargetSpacing; } /** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */ bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ @@ -78,18 +79,11 @@ public: protected: CChainParams() {} - uint256 hashGenesisBlock; + Consensus::Params consensus; CMessageHeader::MessageStartChars pchMessageStart; //! Raw pub key bytes for the broadcast alert signing key. std::vector<unsigned char> vAlertPubKey; int nDefaultPort; - arith_uint256 bnProofOfWorkLimit; - int nSubsidyHalvingInterval; - int nEnforceBlockUpgradeMajority; - int nRejectBlockOutdatedMajority; - int nToCheckBlockUpgradeMajority; - int64_t nTargetTimespan; - int64_t nTargetSpacing; int nMinerThreads; std::vector<CDNSSeedData> vSeeds; std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES]; @@ -99,7 +93,6 @@ protected: bool fRequireRPCPassword; bool fMiningRequiresPeers; bool fDefaultCheckMemPool; - bool fAllowMinDifficultyBlocks; bool fRequireStandard; bool fMineBlocksOnDemand; bool fTestnetToBeDeprecatedFieldRPC; diff --git a/src/consensus/params.h b/src/consensus/params.h new file mode 100644 index 0000000000..c4cfa48c7e --- /dev/null +++ b/src/consensus/params.h @@ -0,0 +1,32 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H +#define BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H + +#include "arith_uint256.h" +#include "uint256.h" + +namespace Consensus { +/** + * Parameters that influence chain consensus. + */ +struct Params { + uint256 hashGenesisBlock; + int nSubsidyHalvingInterval; + /** Used to check majorities for block version upgrade */ + int nMajorityEnforceBlockUpgrade; + int nMajorityRejectBlockOutdated; + int nMajorityWindow; + /** Proof of work parameters */ + arith_uint256 powLimit; + bool fPowAllowMinDifficultyBlocks; + int64_t nPowTargetSpacing; + int64_t nPowTargetTimespan; + int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } +}; +} // namespace Consensus + +#endif // BITCOIN_CONSENSUS_CONSENSUS_PARAMS_H diff --git a/src/init.cpp b/src/init.cpp index 95ec45015f..2a13af6690 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -23,6 +23,7 @@ #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" +#include "validationinterface.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" #include "wallet/walletdb.h" diff --git a/src/main.cpp b/src/main.cpp index 94cf213490..1d78eedc1a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,9 +5,9 @@ #include "main.h" -#include "arith_uint256.h" #include "addrman.h" #include "alert.h" +#include "arith_uint256.h" #include "chainparams.h" #include "checkpoints.h" #include "checkqueue.h" @@ -21,6 +21,7 @@ #include "undo.h" #include "util.h" #include "utilmoneystr.h" +#include "validationinterface.h" #include <sstream> @@ -158,68 +159,6 @@ namespace { ////////////////////////////////////////////////////////////////////////////// // -// dispatching functions -// - -// These functions dispatch to one or all registered wallets - -namespace { - -struct CMainSignals { - /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ - boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction; - /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ - boost::signals2::signal<void (const uint256 &)> EraseTransaction; - /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ - boost::signals2::signal<void (const uint256 &)> UpdatedTransaction; - /** Notifies listeners of a new active block chain. */ - boost::signals2::signal<void (const CBlockLocator &)> SetBestChain; - /** Notifies listeners about an inventory item being seen on the network. */ - boost::signals2::signal<void (const uint256 &)> Inventory; - /** Tells listeners to broadcast their data. */ - boost::signals2::signal<void ()> Broadcast; - /** Notifies listeners of a block validation result */ - boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked; -} g_signals; - -} // anon namespace - -void RegisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); - g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); - g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); - g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); -} - -void UnregisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); - g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); - g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); - g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); - g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); -} - -void UnregisterAllValidationInterfaces() { - g_signals.BlockChecked.disconnect_all_slots(); - g_signals.Broadcast.disconnect_all_slots(); - g_signals.Inventory.disconnect_all_slots(); - g_signals.SetBestChain.disconnect_all_slots(); - g_signals.UpdatedTransaction.disconnect_all_slots(); - g_signals.EraseTransaction.disconnect_all_slots(); - g_signals.SyncTransaction.disconnect_all_slots(); -} - -void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { - g_signals.SyncTransaction(tx, pblock); -} - -////////////////////////////////////////////////////////////////////////////// -// // Registration of network node signals. // @@ -1219,7 +1158,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) } // Check the header - if (!CheckProofOfWork(block.GetHash(), block.nBits)) + if (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); return true; @@ -1897,7 +1836,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Watch for changes to the previous coinbase transaction. static uint256 hashPrevBestCoinBase; - g_signals.UpdatedTransaction(hashPrevBestCoinBase); + GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); hashPrevBestCoinBase = block.vtx[0].GetHash(); int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3; @@ -1956,7 +1895,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode) { return state.Abort("Failed to write to coin database"); // Update best block in wallet (so we can detect restored wallets). if (mode != FLUSH_STATE_IF_NEEDED) { - g_signals.SetBestChain(chainActive.GetLocator()); + GetMainSignals().SetBestChain(chainActive.GetLocator()); } nLastWrite = GetTimeMicros(); } @@ -2080,7 +2019,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * CCoinsViewCache view(pcoinsTip); CInv inv(MSG_BLOCK, pindexNew->GetBlockHash()); bool rv = ConnectBlock(*pblock, state, pindexNew, view); - g_signals.BlockChecked(*pblock, state); + GetMainSignals().BlockChecked(*pblock, state); if (!rv) { if (state.IsInvalid()) InvalidBlockFound(pindexNew, state); @@ -2320,7 +2259,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { // add them again. BlockMap::iterator it = mapBlockIndex.begin(); while (it != mapBlockIndex.end()) { - if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && setBlockIndexCandidates.value_comp()(chainActive.Tip(), it->second)) { + if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) { setBlockIndexCandidates.insert(it->second); } it++; @@ -2523,7 +2462,7 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW) { // Check proof of work matches claimed amount - if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits)) + if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) return state.DoS(50, error("CheckBlockHeader(): proof of work failed"), REJECT_INVALID, "high-hash"); @@ -2606,7 +2545,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta int nHeight = pindexPrev->nHeight+1; // Check proof of work - if ((block.nBits != GetNextWorkRequired(pindexPrev, &block))) + if (block.nBits != GetNextWorkRequired(pindexPrev, &block, Params().GetConsensus())) return state.DoS(100, error("%s: incorrect proof of work", __func__), REJECT_INVALID, "bad-diffbits"); @@ -3471,7 +3410,7 @@ void static ProcessGetData(CNode* pfrom) } // Track requests for our stuff. - g_signals.Inventory(inv.hash); + GetMainSignals().Inventory(inv.hash); if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) break; @@ -3765,7 +3704,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Track requests for our stuff - g_signals.Inventory(inv.hash); + GetMainSignals().Inventory(inv.hash); if (pfrom->nSendSize > (SendBufferSize() * 2)) { Misbehaving(pfrom->GetId(), 50); @@ -4536,7 +4475,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // transactions become unconfirmed and spams other nodes. if (!fReindex && !fImporting && !IsInitialBlockDownload()) { - g_signals.Broadcast(); + GetMainSignals().Broadcast(); } // diff --git a/src/main.h b/src/main.h index 65693b44b7..ac73b242f1 100644 --- a/src/main.h +++ b/src/main.h @@ -17,7 +17,6 @@ #include "primitives/block.h" #include "primitives/transaction.h" #include "net.h" -#include "pow.h" #include "script/script.h" #include "script/sigcache.h" #include "script/standard.h" @@ -133,15 +132,6 @@ extern CBlockIndex *pindexBestHeader; /** Minimum disk space required - used in CheckDiskSpace() */ static const uint64_t nMinDiskSpace = 52428800; -/** Register a wallet to receive updates from core */ -void RegisterValidationInterface(CValidationInterface* pwalletIn); -/** Unregister a wallet from core */ -void UnregisterValidationInterface(CValidationInterface* pwalletIn); -/** Unregister all wallets from core */ -void UnregisterAllValidationInterfaces(); -/** Push an updated transaction to all registered wallets */ -void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); - /** Register with a network node to receive its signals */ void RegisterNodeSignals(CNodeSignals& nodeSignals); /** Unregister a network node */ @@ -152,7 +142,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals); * block is made active. Note that it does not, however, guarantee that the * specific block passed to it has been checked for validity! * - * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface - this will have its BlockChecked method called whenever *any* block completes validation. + * @param[out] state This may be set to an Error state if any error occurred processing it, including during validation/connection/etc of otherwise unrelated blocks during reorganisation; or it may be set to an Invalid state if pblock is itself invalid (but this is not guaranteed even when the block is checked). If you want to *possibly* get feedback on whether pblock is valid, you must also install a CValidationInterface (see validationinterface.h) - this will have its BlockChecked method called whenever *any* block completes validation. * @param[in] pfrom The node which we are receiving the block from; it is added to mapBlockSource and may be penalised if the block is invalid. * @param[in] pblock The block we want to process. * @param[out] dbp If pblock is stored to disk (or already there), this will be set to its location. @@ -517,19 +507,4 @@ extern CCoinsViewCache *pcoinsTip; /** Global variable that points to the active block tree (protected by cs_main) */ extern CBlockTreeDB *pblocktree; - -class CValidationInterface { -protected: - virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}; - virtual void EraseFromWallet(const uint256 &hash) {}; - virtual void SetBestChain(const CBlockLocator &locator) {}; - virtual void UpdatedTransaction(const uint256 &hash) {}; - virtual void Inventory(const uint256 &hash) {}; - virtual void ResendWalletTransactions() {}; - virtual void BlockChecked(const CBlock&, const CValidationState&) {}; - friend void ::RegisterValidationInterface(CValidationInterface*); - friend void ::UnregisterValidationInterface(CValidationInterface*); - friend void ::UnregisterAllValidationInterfaces(); -}; - #endif // BITCOIN_MAIN_H diff --git a/src/miner.cpp b/src/miner.cpp index 01212b19c4..cf08b78229 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -84,7 +84,7 @@ void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) // Updating time can change work required on testnet: if (Params().AllowMinDifficultyBlocks()) - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); } CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) @@ -326,7 +326,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); UpdateTime(pblock, pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); pblock->nNonce = 0; pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); diff --git a/src/pow.cpp b/src/pow.cpp index eb899ffc94..3c5a8d9d96 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -7,34 +7,33 @@ #include "arith_uint256.h" #include "chain.h" -#include "chainparams.h" #include "primitives/block.h" #include "uint256.h" #include "util.h" -unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock) +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { - unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact(); + unsigned int nProofOfWorkLimit = params.powLimit.GetCompact(); // Genesis block if (pindexLast == NULL) return nProofOfWorkLimit; // Only change once per difficulty adjustment interval - if ((pindexLast->nHeight+1) % Params().DifficultyAdjustmentInterval() != 0) + if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0) { - if (Params().AllowMinDifficultyBlocks()) + if (params.fPowAllowMinDifficultyBlocks) { // Special difficulty rule for testnet: // If the new block's timestamp is more than 2* 10 minutes // then allow mining of a min-difficulty block. - if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2) + if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) return nProofOfWorkLimit; else { // Return the last non-special-min-difficulty-rules-block const CBlockIndex* pindex = pindexLast; - while (pindex->pprev && pindex->nHeight % Params().DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) + while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit) pindex = pindex->pprev; return pindex->nBits; } @@ -44,22 +43,22 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead // Go back by what we want to be 14 days worth of blocks const CBlockIndex* pindexFirst = pindexLast; - for (int i = 0; pindexFirst && i < Params().DifficultyAdjustmentInterval()-1; i++) + for (int i = 0; pindexFirst && i < params.DifficultyAdjustmentInterval()-1; i++) pindexFirst = pindexFirst->pprev; assert(pindexFirst); - return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime()); + return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params); } -unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime) +unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { // Limit adjustment step int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan); - if (nActualTimespan < Params().TargetTimespan()/4) - nActualTimespan = Params().TargetTimespan()/4; - if (nActualTimespan > Params().TargetTimespan()*4) - nActualTimespan = Params().TargetTimespan()*4; + if (nActualTimespan < params.nPowTargetTimespan/4) + nActualTimespan = params.nPowTargetTimespan/4; + if (nActualTimespan > params.nPowTargetTimespan*4) + nActualTimespan = params.nPowTargetTimespan*4; // Retarget arith_uint256 bnNew; @@ -67,21 +66,21 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF bnNew.SetCompact(pindexLast->nBits); bnOld = bnNew; bnNew *= nActualTimespan; - bnNew /= Params().TargetTimespan(); + bnNew /= params.nPowTargetTimespan; - if (bnNew > Params().ProofOfWorkLimit()) - bnNew = Params().ProofOfWorkLimit(); + if (bnNew > params.powLimit) + bnNew = params.powLimit; /// debug print LogPrintf("GetNextWorkRequired RETARGET\n"); - LogPrintf("Params().TargetTimespan() = %d nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan); + LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan); LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString()); LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString()); return bnNew.GetCompact(); } -bool CheckProofOfWork(uint256 hash, unsigned int nBits) +bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) { bool fNegative; bool fOverflow; @@ -90,7 +89,7 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range - if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit()) + if (fNegative || bnTarget == 0 || fOverflow || bnTarget > params.powLimit) return error("CheckProofOfWork(): nBits below minimum work"); // Check proof of work matches claimed amount @@ -6,6 +6,8 @@ #ifndef BITCOIN_POW_H #define BITCOIN_POW_H +#include "consensus/params.h" + #include <stdint.h> class CBlockHeader; @@ -13,11 +15,11 @@ class CBlockIndex; class uint256; class arith_uint256; -unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock); -unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime); +unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&); +unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&); /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ -bool CheckProofOfWork(uint256 hash, unsigned int nBits); +bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&); arith_uint256 GetBlockProof(const CBlockIndex& block); #endif // BITCOIN_POW_H diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 9573fe43df..8e20836c65 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -10,6 +10,8 @@ #include "base58.h" #include "wallet/wallet.h" +#include <boost/foreach.hpp> + #include <QFont> #include <QDebug> diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 40d6e16f51..ad489de343 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -10,6 +10,7 @@ #include "base58.h" #include "chainparams.h" +#include "main.h" #include "ui_interface.h" #include "util.h" #include "wallet/wallet.h" diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 28c8fb95f6..774667d4ac 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -17,6 +17,7 @@ #include "base58.h" #include "coincontrol.h" +#include "main.h" #include "ui_interface.h" #include "wallet/wallet.h" diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 76da6904a9..ce166f3672 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -12,6 +12,7 @@ #include "base58.h" #include "init.h" +#include "main.h" // For strMessageMagic #include "wallet/wallet.h" #include <string> diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 19e3fc0dc2..9db5ad0fd4 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -5,11 +5,14 @@ #include "transactionrecord.h" #include "base58.h" +#include "main.h" #include "timedata.h" #include "wallet/wallet.h" #include <stdint.h> +#include <boost/foreach.hpp> + /* Return positive answer if transaction should be shown in list. */ bool TransactionRecord::showTransaction(const CWalletTx &wtx) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index a07acea9aa..fcba7e222d 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -13,6 +13,7 @@ #include "pow.h" #include "rpcserver.h" #include "util.h" +#include "validationinterface.h" #ifdef ENABLE_WALLET #include "wallet/db.h" #include "wallet/wallet.h" @@ -180,7 +181,7 @@ Value setgenerate(const Array& params, bool fHelp) LOCK(cs_main); IncrementExtraNonce(pblock, chainActive.Tip(), nExtraNonce); } - while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits)) { + while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) { // Yes, there is a chance every nonce could fail to satisfy the -regtest // target -- 1 in 2^(2^32). That ain't gonna happen. ++pblock->nNonce; diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 7b197c527d..4ce1591c35 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -17,51 +17,56 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(get_next_work) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); int64_t nLastRetargetTime = 1261130161; // Block #30240 CBlockIndex pindexLast; pindexLast.nHeight = 32255; pindexLast.nTime = 1262152739; // Block #32255 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00d86a); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00d86a); } /* Test the constraint on the upper bound for next work */ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); int64_t nLastRetargetTime = 1231006505; // Block #0 CBlockIndex pindexLast; pindexLast.nHeight = 2015; pindexLast.nTime = 1233061996; // Block #2015 pindexLast.nBits = 0x1d00ffff; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00ffff); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00ffff); } /* Test the constraint on the lower bound for actual time taken */ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); int64_t nLastRetargetTime = 1279008237; // Block #66528 CBlockIndex pindexLast; pindexLast.nHeight = 68543; pindexLast.nTime = 1279297671; // Block #68543 pindexLast.nBits = 0x1c05a3f4; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1c0168fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1c0168fd); } /* Test the constraint on the upper bound for actual time taken */ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) { SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& params = Params().GetConsensus(); + int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time CBlockIndex pindexLast; pindexLast.nHeight = 46367; pindexLast.nTime = 1269211443; // Block #46367 pindexLast.nBits = 0x1c387f6f; - BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00e1fd); + BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1d00e1fd); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index d97bea8bd2..4d5e92cbd4 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -6,6 +6,7 @@ #include "rpcclient.h" #include "base58.h" +#include "main.h" #include "wallet/wallet.h" #include "test/test_bitcoin.h" diff --git a/src/txdb.cpp b/src/txdb.cpp index da271bd5d1..df9ff8d8c9 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -5,6 +5,9 @@ #include "txdb.h" +#include "chainparams.h" +#include "hash.h" +#include "main.h" #include "pow.h" #include "uint256.h" @@ -222,7 +225,7 @@ bool CBlockTreeDB::LoadBlockIndexGuts() pindexNew->nStatus = diskindex.nStatus; pindexNew->nTx = diskindex.nTx; - if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits)) + if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, Params().GetConsensus())) return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString()); pcursor->Next(); diff --git a/src/txdb.h b/src/txdb.h index f6b6b84fcf..1ce93969d8 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -6,15 +6,17 @@ #ifndef BITCOIN_TXDB_H #define BITCOIN_TXDB_H +#include "coins.h" #include "leveldbwrapper.h" -#include "main.h" #include <map> #include <string> #include <utility> #include <vector> -class CCoins; +class CBlockFileInfo; +class CBlockIndex; +class CDiskTxPos; class uint256; //! -dbcache default (MiB) diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp new file mode 100644 index 0000000000..ae4cd3c592 --- /dev/null +++ b/src/validationinterface.cpp @@ -0,0 +1,47 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "validationinterface.h" + +static CMainSignals g_signals; + +CMainSignals& GetMainSignals() +{ + return g_signals; +} + +void RegisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); + g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); + g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); + g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); + g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); + g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); + g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); +} + +void UnregisterValidationInterface(CValidationInterface* pwalletIn) { + g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); + g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn)); + g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); + g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); + g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1)); + g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1)); + g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2)); +} + +void UnregisterAllValidationInterfaces() { + g_signals.BlockChecked.disconnect_all_slots(); + g_signals.Broadcast.disconnect_all_slots(); + g_signals.Inventory.disconnect_all_slots(); + g_signals.SetBestChain.disconnect_all_slots(); + g_signals.UpdatedTransaction.disconnect_all_slots(); + g_signals.EraseTransaction.disconnect_all_slots(); + g_signals.SyncTransaction.disconnect_all_slots(); +} + +void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) { + g_signals.SyncTransaction(tx, pblock); +} diff --git a/src/validationinterface.h b/src/validationinterface.h new file mode 100644 index 0000000000..b21b6e5782 --- /dev/null +++ b/src/validationinterface.h @@ -0,0 +1,62 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_VALIDATIONINTERFACE_H +#define BITCOIN_VALIDATIONINTERFACE_H + +#include <boost/signals2/signal.hpp> + +class CBlock; +class CBlockLocator; +class CTransaction; +class CValidationInterface; +class CValidationState; +class uint256; + +// These functions dispatch to one or all registered wallets + +/** Register a wallet to receive updates from core */ +void RegisterValidationInterface(CValidationInterface* pwalletIn); +/** Unregister a wallet from core */ +void UnregisterValidationInterface(CValidationInterface* pwalletIn); +/** Unregister all wallets from core */ +void UnregisterAllValidationInterfaces(); +/** Push an updated transaction to all registered wallets */ +void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL); + +class CValidationInterface { +protected: + virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}; + virtual void EraseFromWallet(const uint256 &hash) {}; + virtual void SetBestChain(const CBlockLocator &locator) {}; + virtual void UpdatedTransaction(const uint256 &hash) {}; + virtual void Inventory(const uint256 &hash) {}; + virtual void ResendWalletTransactions() {}; + virtual void BlockChecked(const CBlock&, const CValidationState&) {}; + friend void ::RegisterValidationInterface(CValidationInterface*); + friend void ::UnregisterValidationInterface(CValidationInterface*); + friend void ::UnregisterAllValidationInterfaces(); +}; + +struct CMainSignals { + /** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */ + boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction; + /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ + boost::signals2::signal<void (const uint256 &)> EraseTransaction; + /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ + boost::signals2::signal<void (const uint256 &)> UpdatedTransaction; + /** Notifies listeners of a new active block chain. */ + boost::signals2::signal<void (const CBlockLocator &)> SetBestChain; + /** Notifies listeners about an inventory item being seen on the network. */ + boost::signals2::signal<void (const uint256 &)> Inventory; + /** Tells listeners to broadcast their data. */ + boost::signals2::signal<void ()> Broadcast; + /** Notifies listeners of a block validation result */ + boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked; +}; + +CMainSignals& GetMainSignals(); + +#endif // BITCOIN_VALIDATIONINTERFACE_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5502b0b261..9318c1b2b1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -6,10 +6,11 @@ #include "amount.h" #include "base58.h" #include "core_io.h" -#include "rpcserver.h" #include "init.h" +#include "main.h" #include "net.h" #include "netbase.h" +#include "rpcserver.h" #include "timedata.h" #include "util.h" #include "utilmoneystr.h" diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 167639b53d..09bcda577e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -8,6 +8,7 @@ #include "base58.h" #include "checkpoints.h" #include "coincontrol.h" +#include "main.h" #include "net.h" #include "script/script.h" #include "script/sign.h" @@ -817,6 +818,18 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const return 0; } +isminetype CWallet::IsMine(const CTxOut& txout) const +{ + return ::IsMine(*this, txout.scriptPubKey); +} + +CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const +{ + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetCredit(): value out of range"); + return ((IsMine(txout) & filter) ? txout.nValue : 0); +} + bool CWallet::IsChange(const CTxOut& txout) const { // TODO: fix handling of 'change' outputs. The assumption is that any @@ -839,6 +852,62 @@ bool CWallet::IsChange(const CTxOut& txout) const return false; } +CAmount CWallet::GetChange(const CTxOut& txout) const +{ + if (!MoneyRange(txout.nValue)) + throw std::runtime_error("CWallet::GetChange(): value out of range"); + return (IsChange(txout) ? txout.nValue : 0); +} + +bool CWallet::IsMine(const CTransaction& tx) const +{ + BOOST_FOREACH(const CTxOut& txout, tx.vout) + if (IsMine(txout)) + return true; + return false; +} + +bool CWallet::IsFromMe(const CTransaction& tx) const +{ + return (GetDebit(tx, ISMINE_ALL) > 0); +} + +CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const +{ + CAmount nDebit = 0; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + nDebit += GetDebit(txin, filter); + if (!MoneyRange(nDebit)) + throw std::runtime_error("CWallet::GetDebit(): value out of range"); + } + return nDebit; +} + +CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const +{ + CAmount nCredit = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nCredit += GetCredit(txout, filter); + if (!MoneyRange(nCredit)) + throw std::runtime_error("CWallet::GetCredit(): value out of range"); + } + return nCredit; +} + +CAmount CWallet::GetChange(const CTransaction& tx) const +{ + CAmount nChange = 0; + BOOST_FOREACH(const CTxOut& txout, tx.vout) + { + nChange += GetChange(txout); + if (!MoneyRange(nChange)) + throw std::runtime_error("CWallet::GetChange(): value out of range"); + } + return nChange; +} + int64_t CWalletTx::GetTxTime() const { int64_t n = nTimeSmart; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3f5f2859b6..4a13f02195 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -7,12 +7,14 @@ #define BITCOIN_WALLET_H #include "amount.h" -#include "primitives/block.h" -#include "primitives/transaction.h" #include "key.h" #include "keystore.h" -#include "main.h" +#include "primitives/block.h" +#include "primitives/transaction.h" +#include "tinyformat.h" #include "ui_interface.h" +#include "utilstrencodings.h" +#include "validationinterface.h" #include "wallet/crypter.h" #include "wallet/wallet_ismine.h" #include "wallet/walletdb.h" @@ -48,10 +50,12 @@ static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWa static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; class CAccountingEntry; +class CBlockIndex; class CCoinControl; class COutput; class CReserveKey; class CScript; +class CTxMemPool; class CWalletTx; /** (client) version numbers for particular wallet features */ @@ -640,68 +644,16 @@ public: isminetype IsMine(const CTxIn& txin) const; CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; - isminetype IsMine(const CTxOut& txout) const - { - return ::IsMine(*this, txout.scriptPubKey); - } - CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const - { - if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); - return ((IsMine(txout) & filter) ? txout.nValue : 0); - } + isminetype IsMine(const CTxOut& txout) const; + CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const; bool IsChange(const CTxOut& txout) const; - CAmount GetChange(const CTxOut& txout) const - { - if (!MoneyRange(txout.nValue)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); - return (IsChange(txout) ? txout.nValue : 0); - } - bool IsMine(const CTransaction& tx) const - { - BOOST_FOREACH(const CTxOut& txout, tx.vout) - if (IsMine(txout)) - return true; - return false; - } + CAmount GetChange(const CTxOut& txout) const; + bool IsMine(const CTransaction& tx) const; /** should probably be renamed to IsRelevantToMe */ - bool IsFromMe(const CTransaction& tx) const - { - return (GetDebit(tx, ISMINE_ALL) > 0); - } - CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const - { - CAmount nDebit = 0; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - nDebit += GetDebit(txin, filter); - if (!MoneyRange(nDebit)) - throw std::runtime_error("CWallet::GetDebit(): value out of range"); - } - return nDebit; - } - CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const - { - CAmount nCredit = 0; - BOOST_FOREACH(const CTxOut& txout, tx.vout) - { - nCredit += GetCredit(txout, filter); - if (!MoneyRange(nCredit)) - throw std::runtime_error("CWallet::GetCredit(): value out of range"); - } - return nCredit; - } - CAmount GetChange(const CTransaction& tx) const - { - CAmount nChange = 0; - BOOST_FOREACH(const CTxOut& txout, tx.vout) - { - nChange += GetChange(txout); - if (!MoneyRange(nChange)) - throw std::runtime_error("CWallet::GetChange(): value out of range"); - } - return nChange; - } + bool IsFromMe(const CTransaction& tx) const; + CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const; + CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const; + CAmount GetChange(const CTransaction& tx) const; void SetBestChain(const CBlockLocator& loc); DBErrors LoadWallet(bool& fFirstRunRet); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index d7f70e435e..de56a2d1af 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -6,6 +6,7 @@ #include "wallet/walletdb.h" #include "base58.h" +#include "main.h" #include "protocol.h" #include "serialize.h" #include "sync.h" |