diff options
Diffstat (limited to 'src')
105 files changed, 2100 insertions, 1396 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 94a582dfac..bd6f1ba0d5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,8 +65,10 @@ BITCOIN_CORE_H = \ addrman.h \ alert.h \ allocators.h \ + amount.h \ base58.h \ bloom.h \ + chain.h \ chainparams.h \ chainparamsbase.h \ chainparamsseeds.h \ @@ -145,6 +147,7 @@ libbitcoin_server_a_SOURCES = \ addrman.cpp \ alert.cpp \ bloom.cpp \ + chain.cpp \ checkpoints.cpp \ init.cpp \ leveldbwrapper.cpp \ diff --git a/src/amount.h b/src/amount.h new file mode 100644 index 0000000000..831fa1f6ca --- /dev/null +++ b/src/amount.h @@ -0,0 +1,13 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_AMOUNT_H +#define BITCOIN_AMOUNT_H + +#include <stdint.h> + +typedef int64_t CAmount; + +#endif // BITCOIN_AMOUNT_H diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index b6e7a6c540..a61b4fe29d 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -214,7 +214,7 @@ static void MutateTxAddOutAddr(CMutableTransaction& tx, const string& strInput) // extract and validate VALUE string strValue = strInput.substr(0, pos); - int64_t value; + CAmount value; if (!ParseMoney(strValue, value)) throw runtime_error("invalid TX output value"); @@ -242,7 +242,7 @@ static void MutateTxAddOutScript(CMutableTransaction& tx, const string& strInput // extract and validate VALUE string strValue = strInput.substr(0, pos); - int64_t value; + CAmount value; if (!ParseMoney(strValue, value)) throw runtime_error("invalid TX output value"); diff --git a/src/chain.cpp b/src/chain.cpp new file mode 100644 index 0000000000..05427a4569 --- /dev/null +++ b/src/chain.cpp @@ -0,0 +1,59 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "chain.h" + +using namespace std; + +// CChain implementation + +CBlockIndex *CChain::SetTip(CBlockIndex *pindex) { + if (pindex == NULL) { + vChain.clear(); + return NULL; + } + vChain.resize(pindex->nHeight + 1); + while (pindex && vChain[pindex->nHeight] != pindex) { + vChain[pindex->nHeight] = pindex; + pindex = pindex->pprev; + } + return pindex; +} + +CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { + int nStep = 1; + std::vector<uint256> vHave; + vHave.reserve(32); + + if (!pindex) + pindex = Tip(); + while (pindex) { + vHave.push_back(pindex->GetBlockHash()); + // Stop when we have added the genesis block. + if (pindex->nHeight == 0) + break; + // Exponentially larger steps back, plus the genesis block. + int nHeight = std::max(pindex->nHeight - nStep, 0); + if (Contains(pindex)) { + // Use O(1) CChain index if possible. + pindex = (*this)[nHeight]; + } else { + // Otherwise, use O(log n) skiplist. + pindex = pindex->GetAncestor(nHeight); + } + if (vHave.size() > 10) + nStep *= 2; + } + + return CBlockLocator(vHave); +} + +const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { + if (pindex->nHeight > Height()) + pindex = pindex->GetAncestor(Height()); + while (pindex && !Contains(pindex)) + pindex = pindex->pprev; + return pindex; +} diff --git a/src/chain.h b/src/chain.h new file mode 100644 index 0000000000..0aafb40b98 --- /dev/null +++ b/src/chain.h @@ -0,0 +1,390 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef H_BITCOIN_CHAIN +#define H_BITCOIN_CHAIN + +#include "core.h" +#include "pow.h" +#include "uint256.h" + +#include <vector> + +#include <boost/foreach.hpp> + +struct CDiskBlockPos +{ + int nFile; + unsigned int nPos; + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + READWRITE(VARINT(nFile)); + READWRITE(VARINT(nPos)); + } + + CDiskBlockPos() { + SetNull(); + } + + CDiskBlockPos(int nFileIn, unsigned int nPosIn) { + nFile = nFileIn; + nPos = nPosIn; + } + + friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) { + return (a.nFile == b.nFile && a.nPos == b.nPos); + } + + friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) { + return !(a == b); + } + + void SetNull() { nFile = -1; nPos = 0; } + bool IsNull() const { return (nFile == -1); } +}; + +enum BlockStatus { + BLOCK_VALID_UNKNOWN = 0, + BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future + BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint + BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root + BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30 + BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok + BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | + BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, + + BLOCK_HAVE_DATA = 8, // full block available in blk*.dat + BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat + BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, + + BLOCK_FAILED_VALID = 32, // stage after last reached validness failed + BLOCK_FAILED_CHILD = 64, // descends from failed block + BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, +}; + +/** The block chain is a tree shaped structure starting with the + * genesis block at the root, with each block potentially having multiple + * candidates to be the next block. A blockindex may have multiple pprev pointing + * to it, but at most one of them can be part of the currently active branch. + */ +class CBlockIndex +{ +public: + // pointer to the hash of the block, if any. memory is owned by this CBlockIndex + const uint256* phashBlock; + + // pointer to the index of the predecessor of this block + CBlockIndex* pprev; + + // pointer to the index of some further predecessor of this block + CBlockIndex* pskip; + + // height of the entry in the chain. The genesis block has height 0 + int nHeight; + + // Which # file this block is stored in (blk?????.dat) + int nFile; + + // Byte offset within blk?????.dat where this block's data is stored + unsigned int nDataPos; + + // Byte offset within rev?????.dat where this block's undo data is stored + unsigned int nUndoPos; + + // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block + uint256 nChainWork; + + // Number of transactions in this block. + // Note: in a potential headers-first mode, this number cannot be relied upon + unsigned int nTx; + + // (memory only) Number of transactions in the chain up to and including this block + unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030 + + // Verification status of this block. See enum BlockStatus + unsigned int nStatus; + + // block header + int nVersion; + uint256 hashMerkleRoot; + unsigned int nTime; + unsigned int nBits; + unsigned int nNonce; + + // (memory only) Sequencial id assigned to distinguish order in which blocks are received. + uint32_t nSequenceId; + + void SetNull() + { + phashBlock = NULL; + pprev = NULL; + pskip = NULL; + nHeight = 0; + nFile = 0; + nDataPos = 0; + nUndoPos = 0; + nChainWork = 0; + nTx = 0; + nChainTx = 0; + nStatus = 0; + nSequenceId = 0; + + nVersion = 0; + hashMerkleRoot = 0; + nTime = 0; + nBits = 0; + nNonce = 0; + } + + CBlockIndex() + { + SetNull(); + } + + CBlockIndex(CBlockHeader& block) + { + SetNull(); + + nVersion = block.nVersion; + hashMerkleRoot = block.hashMerkleRoot; + nTime = block.nTime; + nBits = block.nBits; + nNonce = block.nNonce; + } + + CDiskBlockPos GetBlockPos() const { + CDiskBlockPos ret; + if (nStatus & BLOCK_HAVE_DATA) { + ret.nFile = nFile; + ret.nPos = nDataPos; + } + return ret; + } + + CDiskBlockPos GetUndoPos() const { + CDiskBlockPos ret; + if (nStatus & BLOCK_HAVE_UNDO) { + ret.nFile = nFile; + ret.nPos = nUndoPos; + } + return ret; + } + + CBlockHeader GetBlockHeader() const + { + CBlockHeader block; + block.nVersion = nVersion; + if (pprev) + block.hashPrevBlock = pprev->GetBlockHash(); + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block; + } + + uint256 GetBlockHash() const + { + return *phashBlock; + } + + int64_t GetBlockTime() const + { + return (int64_t)nTime; + } + + uint256 GetBlockWork() const + { + return GetProofIncrement(nBits); + } + + enum { nMedianTimeSpan=11 }; + + int64_t GetMedianTimePast() const + { + int64_t pmedian[nMedianTimeSpan]; + int64_t* pbegin = &pmedian[nMedianTimeSpan]; + int64_t* pend = &pmedian[nMedianTimeSpan]; + + const CBlockIndex* pindex = this; + for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) + *(--pbegin) = pindex->GetBlockTime(); + + std::sort(pbegin, pend); + return pbegin[(pend - pbegin)/2]; + } + + /** + * Returns true if there are nRequired or more blocks of minVersion or above + * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart + * and going backwards. + */ + static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, + unsigned int nRequired); + + std::string ToString() const + { + return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", + pprev, nHeight, + hashMerkleRoot.ToString(), + GetBlockHash().ToString()); + } + + // Check whether this block index entry is valid up to the passed validity level. + bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const + { + assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. + if (nStatus & BLOCK_FAILED_MASK) + return false; + return ((nStatus & BLOCK_VALID_MASK) >= nUpTo); + } + + // Raise the validity level of this block index entry. + // Returns true if the validity was changed. + bool RaiseValidity(enum BlockStatus nUpTo) + { + assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. + if (nStatus & BLOCK_FAILED_MASK) + return false; + if ((nStatus & BLOCK_VALID_MASK) < nUpTo) { + nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo; + return true; + } + return false; + } + + // Build the skiplist pointer for this entry. + void BuildSkip(); + + // Efficiently find an ancestor of this block. + CBlockIndex* GetAncestor(int height); + const CBlockIndex* GetAncestor(int height) const; +}; + +/** Used to marshal pointers into hashes for db storage. */ +class CDiskBlockIndex : public CBlockIndex +{ +public: + uint256 hashPrev; + + CDiskBlockIndex() { + hashPrev = 0; + } + + explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) { + hashPrev = (pprev ? pprev->GetBlockHash() : 0); + } + + ADD_SERIALIZE_METHODS; + + template <typename Stream, typename Operation> + inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { + if (!(nType & SER_GETHASH)) + READWRITE(VARINT(nVersion)); + + READWRITE(VARINT(nHeight)); + READWRITE(VARINT(nStatus)); + READWRITE(VARINT(nTx)); + if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) + READWRITE(VARINT(nFile)); + if (nStatus & BLOCK_HAVE_DATA) + READWRITE(VARINT(nDataPos)); + if (nStatus & BLOCK_HAVE_UNDO) + READWRITE(VARINT(nUndoPos)); + + // block header + READWRITE(this->nVersion); + READWRITE(hashPrev); + READWRITE(hashMerkleRoot); + READWRITE(nTime); + READWRITE(nBits); + READWRITE(nNonce); + } + + uint256 GetBlockHash() const + { + CBlockHeader block; + block.nVersion = nVersion; + block.hashPrevBlock = hashPrev; + block.hashMerkleRoot = hashMerkleRoot; + block.nTime = nTime; + block.nBits = nBits; + block.nNonce = nNonce; + return block.GetHash(); + } + + + std::string ToString() const + { + std::string str = "CDiskBlockIndex("; + str += CBlockIndex::ToString(); + str += strprintf("\n hashBlock=%s, hashPrev=%s)", + GetBlockHash().ToString(), + hashPrev.ToString()); + return str; + } +}; + +/** An in-memory indexed chain of blocks. */ +class CChain { +private: + std::vector<CBlockIndex*> vChain; + +public: + /** Returns the index entry for the genesis block of this chain, or NULL if none. */ + CBlockIndex *Genesis() const { + return vChain.size() > 0 ? vChain[0] : NULL; + } + + /** Returns the index entry for the tip of this chain, or NULL if none. */ + CBlockIndex *Tip() const { + return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; + } + + /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ + CBlockIndex *operator[](int nHeight) const { + if (nHeight < 0 || nHeight >= (int)vChain.size()) + return NULL; + return vChain[nHeight]; + } + + /** Compare two chains efficiently. */ + friend bool operator==(const CChain &a, const CChain &b) { + return a.vChain.size() == b.vChain.size() && + a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; + } + + /** Efficiently check whether a block is present in this chain. */ + bool Contains(const CBlockIndex *pindex) const { + return (*this)[pindex->nHeight] == pindex; + } + + /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ + CBlockIndex *Next(const CBlockIndex *pindex) const { + if (Contains(pindex)) + return (*this)[pindex->nHeight + 1]; + else + return NULL; + } + + /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ + int Height() const { + return vChain.size() - 1; + } + + /** Set/initialize a chain with a given tip. Returns the forking point. */ + CBlockIndex *SetTip(CBlockIndex *pindex); + + /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ + CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; + + /** Find the last common block between this chain and a block index entry. */ + const CBlockIndex *FindFork(const CBlockIndex *pindex) const; +}; + +#endif // H_BITCOIN_CHAIN diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 179db5a818..31c67715c8 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -115,6 +115,7 @@ public: fAllowMinDifficultyBlocks = false; fRequireStandard = true; fMineBlocksOnDemand = false; + fSkipProofOfWorkCheck = false; } }; static CMainParams mainParams; @@ -214,8 +215,46 @@ public: }; static CRegTestParams regTestParams; +// +// Unit test +// +class CUnitTestParams : public CMainParams, public CModifiableParams { +public: + CUnitTestParams() { + networkID = CBaseChainParams::UNITTEST; + strNetworkID = "unittest"; + nDefaultPort = 18445; + vFixedSeeds.clear(); + vSeeds.clear(); // Regtest mode doesn't have any DNS seeds. + + fRequireRPCPassword = false; + fMiningRequiresPeers = false; + fDefaultCheckMemPool = true; + fAllowMinDifficultyBlocks = false; + fMineBlocksOnDemand = true; + } +public: + // Published setters to allow changing values in unit test cases + virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) { nSubsidyHalvingInterval=anSubsidyHalvingInterval; } + virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority) { nEnforceBlockUpgradeMajority=anEnforceBlockUpgradeMajority; } + virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority) { nRejectBlockOutdatedMajority=anRejectBlockOutdatedMajority; } + virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority) { nToCheckBlockUpgradeMajority=anToCheckBlockUpgradeMajority; } + virtual void setDefaultCheckMemPool(bool afDefaultCheckMemPool) { fDefaultCheckMemPool=afDefaultCheckMemPool; } + virtual void setAllowMinDifficultyBlocks(bool afAllowMinDifficultyBlocks) { fAllowMinDifficultyBlocks=afAllowMinDifficultyBlocks; } + virtual void setSkipProofOfWorkCheck(bool afSkipProofOfWorkCheck) { fSkipProofOfWorkCheck = afSkipProofOfWorkCheck; } +}; +static CUnitTestParams unitTestParams; + + static CChainParams *pCurrentParams = 0; +CModifiableParams *ModifiableParams() +{ + assert(pCurrentParams); + assert(pCurrentParams==&unitTestParams); + return (CModifiableParams*)&unitTestParams; +} + const CChainParams &Params() { assert(pCurrentParams); return *pCurrentParams; @@ -229,6 +268,8 @@ CChainParams &Params(CBaseChainParams::Network network) { return testNetParams; case CBaseChainParams::REGTEST: return regTestParams; + case CBaseChainParams::UNITTEST: + return unitTestParams; default: assert(false && "Unimplemented network"); return mainParams; diff --git a/src/chainparams.h b/src/chainparams.h index e5dfc87c6d..50441a89f3 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -61,6 +61,8 @@ public: bool DefaultCheckMemPool() const { return fDefaultCheckMemPool; } /* Allow mining of a min-difficulty block */ bool AllowMinDifficultyBlocks() const { return fAllowMinDifficultyBlocks; } + /* Skip proof-of-work check: allow mining of any difficulty block */ + bool SkipProofOfWorkCheck() const { return fSkipProofOfWorkCheck; } /* Make standard checks */ bool RequireStandard() const { return fRequireStandard; } int64_t TargetTimespan() const { return nTargetTimespan; } @@ -103,8 +105,27 @@ protected: bool fAllowMinDifficultyBlocks; bool fRequireStandard; bool fMineBlocksOnDemand; + bool fSkipProofOfWorkCheck; }; +/** Modifiable parameters interface is used by test cases to adapt the parameters in order +*** to test specific features more easily. Test cases should always restore the previous +*** values after finalization. +**/ + +class CModifiableParams { +public: + // Published setters to allow changing values in unit test cases + virtual void setSubsidyHalvingInterval(int anSubsidyHalvingInterval) =0; + virtual void setEnforceBlockUpgradeMajority(int anEnforceBlockUpgradeMajority)=0; + virtual void setRejectBlockOutdatedMajority(int anRejectBlockOutdatedMajority)=0; + virtual void setToCheckBlockUpgradeMajority(int anToCheckBlockUpgradeMajority)=0; + virtual void setDefaultCheckMemPool(bool aDefaultCheckMemPool)=0; + virtual void setAllowMinDifficultyBlocks(bool aAllowMinDifficultyBlocks)=0; + virtual void setSkipProofOfWorkCheck(bool aSkipProofOfWorkCheck)=0; +}; + + /** * Return the currently selected parameters. This won't change after app startup * outside of the unit tests. @@ -114,6 +135,9 @@ const CChainParams &Params(); /** Return parameters for the given network. */ CChainParams &Params(CBaseChainParams::Network network); +/** Get modifyable network parameters (UNITTEST only) */ +CModifiableParams *ModifiableParams(); + /** Sets the params returned by Params() to those for the given network. */ void SelectParams(CBaseChainParams::Network network); diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 98bb5b855f..e9d63197bd 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -57,6 +57,20 @@ public: }; static CBaseRegTestParams regTestParams; +// +// Unit test +// +class CBaseUnitTestParams : public CBaseMainParams +{ +public: + CBaseUnitTestParams() + { + networkID = CBaseChainParams::UNITTEST; + strDataDir = "unittest"; + } +}; +static CBaseUnitTestParams unitTestParams; + static CBaseChainParams* pCurrentBaseParams = 0; const CBaseChainParams& BaseParams() @@ -77,6 +91,9 @@ void SelectBaseParams(CBaseChainParams::Network network) case CBaseChainParams::REGTEST: pCurrentBaseParams = ®TestParams; break; + case CBaseChainParams::UNITTEST: + pCurrentBaseParams = &unitTestParams; + break; default: assert(false && "Unimplemented network"); return; diff --git a/src/chainparamsbase.h b/src/chainparamsbase.h index c054f03f17..cc154cf501 100644 --- a/src/chainparamsbase.h +++ b/src/chainparamsbase.h @@ -19,6 +19,7 @@ public: MAIN, TESTNET, REGTEST, + UNITTEST, MAX_NETWORK_TYPES }; diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index c41deea7ce..9a6bc05e63 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -88,6 +88,8 @@ namespace Checkpoints { return dataTestnet; else if (Params().NetworkID() == CBaseChainParams::MAIN) return data; + else if (Params().NetworkID() == CBaseChainParams::UNITTEST) // UnitTest share the same checkpoints as MAIN + return data; else return dataRegtest; } diff --git a/src/coins.cpp b/src/coins.cpp index 34485db2bd..9b8d63d4e4 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -171,12 +171,12 @@ const CTxOut &CCoinsViewCache::GetOutputFor(const CTxIn& input) const return coins->vout[input.prevout.n]; } -int64_t CCoinsViewCache::GetValueIn(const CTransaction& tx) const +CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const { if (tx.IsCoinBase()) return 0; - int64_t nResult = 0; + CAmount nResult = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) nResult += GetOutputFor(tx.vin[i]).nValue; diff --git a/src/coins.h b/src/coins.h index bf61f55aac..2583475323 100644 --- a/src/coins.h +++ b/src/coins.h @@ -266,7 +266,7 @@ struct CCoinsStats uint64_t nTransactionOutputs; uint64_t nSerializedSize; uint256 hashSerialized; - int64_t nTotalAmount; + CAmount nTotalAmount; CCoinsStats() : nHeight(0), hashBlock(0), nTransactions(0), nTransactionOutputs(0), nSerializedSize(0), hashSerialized(0), nTotalAmount(0) {} }; @@ -367,7 +367,7 @@ public: @param[in] tx transaction for which we are checking input total @return Sum of value of all inputs (scriptSigs) */ - int64_t GetValueIn(const CTransaction& tx) const; + CAmount GetValueIn(const CTransaction& tx) const; // Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp index 22f82e4259..f149a08cd5 100644 --- a/src/compat/glibc_compat.cpp +++ b/src/compat/glibc_compat.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) @@ -7,6 +7,7 @@ #endif #include <cstddef> + #if defined(HAVE_SYS_SELECT_H) #include <sys/select.h> #endif @@ -18,11 +19,11 @@ extern "C" void* memcpy(void* a, const void* b, size_t c) return memmove(a, b, c); } -extern "C" void __chk_fail (void) __attribute__((__noreturn__)); +extern "C" void __chk_fail(void) __attribute__((__noreturn__)); extern "C" FDELT_TYPE __fdelt_warn(FDELT_TYPE a) { if (a >= FD_SETSIZE) - __chk_fail (); + __chk_fail(); return a / __NFDBITS; } extern "C" FDELT_TYPE __fdelt_chk(FDELT_TYPE) __attribute__((weak, alias("__fdelt_warn"))); diff --git a/src/compat/glibc_sanity.cpp b/src/compat/glibc_sanity.cpp index d93602e0fe..607e23b568 100644 --- a/src/compat/glibc_sanity.cpp +++ b/src/compat/glibc_sanity.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) @@ -7,6 +7,7 @@ #endif #include <cstddef> + #if defined(HAVE_SYS_SELECT_H) #include <sys/select.h> #endif @@ -14,10 +15,11 @@ extern "C" void* memcpy(void* a, const void* b, size_t c); void* memcpy_int(void* a, const void* b, size_t c) { - return memcpy(a,b,c); + return memcpy(a, b, c); } -namespace { +namespace +{ // trigger: Use the memcpy_int wrapper which calls our internal memcpy. // A direct call to memcpy may be optimized away by the compiler. // test: Fill an array with a sequence of integers. memcpy to a new empty array. @@ -31,11 +33,10 @@ bool sanity_test_memcpy() for (unsigned int i = 0; i != T; ++i) memcpy_test[i] = i; - memcpy_int(memcpy_verify,memcpy_test,sizeof(memcpy_test)); + memcpy_int(memcpy_verify, memcpy_test, sizeof(memcpy_test)); - for (unsigned int i = 0; i != T; ++i) - { - if(memcpy_verify[i] != i) + for (unsigned int i = 0; i != T; ++i) { + if (memcpy_verify[i] != i) return false; } return true; @@ -51,7 +52,7 @@ bool sanity_test_fdelt() fd_set fds; FD_ZERO(&fds); FD_SET(0, &fds); - return FD_ISSET(0,&fds); + return FD_ISSET(0, &fds); } #endif diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp index cbe059735b..e0b4ac51f5 100644 --- a/src/compat/glibcxx_compat.cpp +++ b/src/compat/glibcxx_compat.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <cstddef> @@ -11,8 +11,8 @@ #define _GLIBCXX_USE_NOEXCEPT throw() #endif -namespace std { - +namespace std +{ const char* bad_exception::what() const throw() { return "std::bad_exception"; @@ -30,9 +30,8 @@ const char* bad_alloc::what() const throw() namespace __detail { -struct _List_node_base -{ - void _M_hook(std::__detail::_List_node_base* const __position) throw () __attribute__((used)) +struct _List_node_base { + void _M_hook(std::__detail::_List_node_base* const __position) throw() __attribute__((used)) { _M_next = __position; _M_prev = __position->_M_prev; @@ -62,9 +61,9 @@ template ostream& __ostream_insert(ostream&, const char*, streamsize); template istream& istream::_M_extract(long&); template istream& istream::_M_extract(unsigned short&); -out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { } +out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT {} -length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { } +length_error::~length_error() _GLIBCXX_USE_NOEXCEPT {} // Used with permission. // See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d @@ -85,11 +84,11 @@ void ctype<char>::_M_widen_init() const } } -void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__)); -void __throw_out_of_range_fmt(const char* err, ...) +void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__)); +void __throw_out_of_range_fmt(const char* err, ...) { // Safe and over-simplified version. Ignore the format and print it as-is. __throw_out_of_range(err); } -}// namespace std +} // namespace std diff --git a/src/compat/glibcxx_sanity.cpp b/src/compat/glibcxx_sanity.cpp index cd8da4fd67..aafa4a6aef 100644 --- a/src/compat/glibcxx_sanity.cpp +++ b/src/compat/glibcxx_sanity.cpp @@ -1,20 +1,20 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <list> #include <locale> #include <stdexcept> -namespace{ - +namespace +{ // trigger: use ctype<char>::widen to trigger ctype<char>::_M_widen_init(). // test: convert a char from narrow to wide and back. Verify that the result // matches the original. bool sanity_test_widen(char testchar) { - const std::ctype<char>& test(std::use_facet< std::ctype<char> >(std::locale())); - return test.narrow(test.widen(testchar),'b') == testchar; + const std::ctype<char>& test(std::use_facet<std::ctype<char> >(std::locale())); + return test.narrow(test.widen(testchar), 'b') == testchar; } // trigger: use list::push_back and list::pop_back to trigger _M_hook and @@ -25,14 +25,13 @@ bool sanity_test_list(unsigned int size) { std::list<unsigned int> test; for (unsigned int i = 0; i != size; ++i) - test.push_back(i+1); + test.push_back(i + 1); if (test.size() != size) return false; - while (!test.empty()) - { - if(test.back() != test.size()) + while (!test.empty()) { + if (test.back() != test.size()) return false; test.pop_back(); } @@ -47,15 +46,12 @@ bool sanity_test_list(unsigned int size) bool sanity_test_range_fmt() { std::string test; - try - { + try { test.at(1); - } - catch (const std::out_of_range&) - { + } catch (const std::out_of_range&) { return true; + } catch (...) { } - catch (...){} return false; } diff --git a/src/compat/sanity.h b/src/compat/sanity.h index e7df44307a..7016ac0ab7 100644 --- a/src/compat/sanity.h +++ b/src/compat/sanity.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCON_COMPAT_SANITY_H diff --git a/src/core.cpp b/src/core.cpp index e52327ba8e..380b1c38e0 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -43,7 +43,7 @@ std::string CTxIn::ToString() const return str; } -CTxOut::CTxOut(int64_t nValueIn, CScript scriptPubKeyIn) +CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn) { nValue = nValueIn; scriptPubKey = scriptPubKeyIn; @@ -59,7 +59,7 @@ std::string CTxOut::ToString() const return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30)); } -CFeeRate::CFeeRate(int64_t nFeePaid, size_t nSize) +CFeeRate::CFeeRate(const CAmount& nFeePaid, size_t nSize) { if (nSize > 0) nSatoshisPerK = nFeePaid*1000/nSize; @@ -67,9 +67,9 @@ CFeeRate::CFeeRate(int64_t nFeePaid, size_t nSize) nSatoshisPerK = 0; } -int64_t CFeeRate::GetFee(size_t nSize) const +CAmount CFeeRate::GetFee(size_t nSize) const { - int64_t nFee = nSatoshisPerK*nSize / 1000; + CAmount nFee = nSatoshisPerK*nSize / 1000; if (nFee == 0 && nSatoshisPerK > 0) nFee = nSatoshisPerK; @@ -110,9 +110,9 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) { return *this; } -int64_t CTransaction::GetValueOut() const +CAmount CTransaction::GetValueOut() const { - int64_t nValueOut = 0; + CAmount nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, vout) { nValueOut += txout.nValue; @@ -224,29 +224,66 @@ uint256 CBlockHeader::GetHash() const return Hash(BEGIN(nVersion), END(nNonce)); } -uint256 CBlock::BuildMerkleTree() const +uint256 CBlock::BuildMerkleTree(bool* fMutated) const { - // WARNING! If you're reading this because you're learning about crypto - // and/or designing a new system that will use merkle trees, keep in mind - // that the following merkle tree algorithm has a serious flaw related to - // duplicate txids, resulting in a vulnerability. (CVE-2012-2459) Bitcoin - // has since worked around the flaw, but for new applications you should - // use something different; don't just copy-and-paste this code without - // understanding the problem first. + /* WARNING! If you're reading this because you're learning about crypto + and/or designing a new system that will use merkle trees, keep in mind + that the following merkle tree algorithm has a serious flaw related to + duplicate txids, resulting in a vulnerability (CVE-2012-2459). + + The reason is that if the number of hashes in the list at a given time + is odd, the last one is duplicated before computing the next level (which + is unusual in Merkle trees). This results in certain sequences of + transactions leading to the same merkle root. For example, these two + trees: + + A A + / \ / \ + B C B C + / \ | / \ / \ + D E F D E F F + / \ / \ / \ / \ / \ / \ / \ + 1 2 3 4 5 6 1 2 3 4 5 6 5 6 + + for transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and + 6 are repeated) result in the same root hash A (because the hash of both + of (F) and (F,F) is C). + + The vulnerability results from being able to send a block with such a + transaction list, with the same merkle root, and the same block hash as + the original without duplication, resulting in failed validation. If the + receiving node proceeds to mark that block as permanently invalid + however, it will fail to accept further unmodified (and thus potentially + valid) versions of the same block. We defend against this by detecting + the case where we would hash two identical hashes at the end of the list + together, and treating that identically to the block having an invalid + merkle root. Assuming no double-SHA256 collisions, this will detect all + known ways of changing the transactions without affecting the merkle + root. + */ vMerkleTree.clear(); + vMerkleTree.reserve(vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. BOOST_FOREACH(const CTransaction& tx, vtx) vMerkleTree.push_back(tx.GetHash()); int j = 0; + bool mutated = false; for (int nSize = vtx.size(); nSize > 1; nSize = (nSize + 1) / 2) { for (int i = 0; i < nSize; i += 2) { int i2 = std::min(i+1, nSize-1); + if (i2 == i + 1 && i2 + 1 == nSize && vMerkleTree[j+i] == vMerkleTree[j+i2]) { + // Two identical hashes at the end of the list at a particular level. + mutated = true; + } vMerkleTree.push_back(Hash(BEGIN(vMerkleTree[j+i]), END(vMerkleTree[j+i]), BEGIN(vMerkleTree[j+i2]), END(vMerkleTree[j+i2]))); } j += nSize; } + if (fMutated) { + *fMutated = mutated; + } return (vMerkleTree.empty() ? 0 : vMerkleTree.back()); } diff --git a/src/core.h b/src/core.h index 9a2ac47487..a348293578 100644 --- a/src/core.h +++ b/src/core.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_CORE_H #define BITCOIN_CORE_H +#include "amount.h" #include "script/compressor.h" #include "script/script.h" #include "serialize.h" @@ -19,8 +20,8 @@ static const int64_t COIN = 100000000; static const int64_t CENT = 1000000; /** No amount larger than this (in satoshi) is valid */ -static const int64_t MAX_MONEY = 21000000 * COIN; -inline bool MoneyRange(int64_t nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } +static const CAmount MAX_MONEY = 21000000 * COIN; +inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } /** An outpoint - a combination of a transaction hash and an index n into its vout */ class COutPoint @@ -129,15 +130,15 @@ public: class CFeeRate { private: - int64_t nSatoshisPerK; // unit is satoshis-per-1,000-bytes + CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes public: CFeeRate() : nSatoshisPerK(0) { } - explicit CFeeRate(int64_t _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { } - CFeeRate(int64_t nFeePaid, size_t nSize); + explicit CFeeRate(const CAmount& _nSatoshisPerK): nSatoshisPerK(_nSatoshisPerK) { } + CFeeRate(const CAmount& nFeePaid, size_t nSize); CFeeRate(const CFeeRate& other) { nSatoshisPerK = other.nSatoshisPerK; } - int64_t GetFee(size_t size) const; // unit returned is satoshis - int64_t GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes + CAmount GetFee(size_t size) const; // unit returned is satoshis + CAmount GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes friend bool operator<(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK < b.nSatoshisPerK; } friend bool operator>(const CFeeRate& a, const CFeeRate& b) { return a.nSatoshisPerK > b.nSatoshisPerK; } @@ -161,7 +162,7 @@ public: class CTxOut { public: - int64_t nValue; + CAmount nValue; CScript scriptPubKey; CTxOut() @@ -169,7 +170,7 @@ public: SetNull(); } - CTxOut(int64_t nValueIn, CScript scriptPubKeyIn); + CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn); ADD_SERIALIZE_METHODS; @@ -276,7 +277,7 @@ public: } // Return sum of txouts. - int64_t GetValueOut() const; + CAmount GetValueOut() const; // GetValueIn() is a method on CCoinsViewCache, because // inputs must be known to compute value in. @@ -528,7 +529,11 @@ public: return block; } - uint256 BuildMerkleTree() const; + // Build the in-memory merkle tree for this block and return the merkle root. + // If non-NULL, *mutated is set to whether mutation was detected in the merkle + // tree (a duplication of transactions in the block leading to an identical + // merkle root). + uint256 BuildMerkleTree(bool* mutated = NULL) const; std::vector<uint256> GetMerkleBranch(int nIndex) const; static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex); diff --git a/src/core_io.h b/src/core_io.h index 6268a3bf58..94848f1c3d 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -20,6 +20,7 @@ extern uint256 ParseHashUV(const UniValue& v, const std::string& strName); extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName); // core_write.cpp +extern std::string FormatScript(const CScript& script); extern std::string EncodeHexTx(const CTransaction& tx); extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); diff --git a/src/core_write.cpp b/src/core_write.cpp index cd64aabf63..40d547fb33 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -17,6 +17,41 @@ using namespace std; +string FormatScript(const CScript& script) +{ + string ret; + CScript::const_iterator it = script.begin(); + opcodetype op; + while (it != script.end()) { + CScript::const_iterator it2 = it; + vector<unsigned char> vch; + if (script.GetOp2(it, op, &vch)) { + if (op == OP_0) { + ret += "0 "; + continue; + } else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) { + ret += strprintf("%i ", op - OP_1NEGATE - 1); + continue; + } else if (op >= OP_NOP && op <= OP_CHECKMULTISIGVERIFY) { + string str(GetOpName(op)); + if (str.substr(0, 3) == string("OP_")) { + ret += str.substr(3, string::npos) + " "; + continue; + } + } + if (vch.size() > 0) { + ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), HexStr(it - vch.size(), it)); + } else { + ret += strprintf("0x%x", HexStr(it2, it)); + } + continue; + } + ret += strprintf("0x%x ", HexStr(it2, script.end())); + break; + } + return ret.substr(0, ret.size() - 1); +} + string EncodeHexTx(const CTransaction& tx) { CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/crypto/common.h b/src/crypto/common.h index 8f675a16c5..67c30023c3 100644 --- a/src/crypto/common.h +++ b/src/crypto/common.h @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CRYPTO_COMMON_H @@ -8,12 +8,15 @@ #if defined(HAVE_CONFIG_H) #include "bitcoin-config.h" #endif + #include <stdint.h> + #if defined(HAVE_ENDIAN_H) #include <endian.h> #endif -uint32_t static inline ReadLE32(const unsigned char *ptr) { +uint32_t static inline ReadLE32(const unsigned char* ptr) +{ #if HAVE_DECL_LE32TOH == 1 return le32toh(*((uint32_t*)ptr)); #elif !defined(WORDS_BIGENDIAN) @@ -23,8 +26,8 @@ uint32_t static inline ReadLE32(const unsigned char *ptr) { #endif } -uint64_t static inline ReadLE64(const unsigned char *ptr) { - +uint64_t static inline ReadLE64(const unsigned char* ptr) +{ #if HAVE_DECL_LE64TOH == 1 return le64toh(*((uint64_t*)ptr)); #elif !defined(WORDS_BIGENDIAN) @@ -35,28 +38,40 @@ uint64_t static inline ReadLE64(const unsigned char *ptr) { #endif } -void static inline WriteLE32(unsigned char *ptr, uint32_t x) { +void static inline WriteLE32(unsigned char* ptr, uint32_t x) +{ #if HAVE_DECL_HTOLE32 == 1 *((uint32_t*)ptr) = htole32(x); #elif !defined(WORDS_BIGENDIAN) *((uint32_t*)ptr) = x; #else - ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x; + ptr[3] = x >> 24; + ptr[2] = x >> 16; + ptr[1] = x >> 8; + ptr[0] = x; #endif } -void static inline WriteLE64(unsigned char *ptr, uint64_t x) { +void static inline WriteLE64(unsigned char* ptr, uint64_t x) +{ #if HAVE_DECL_HTOLE64 == 1 *((uint64_t*)ptr) = htole64(x); #elif !defined(WORDS_BIGENDIAN) *((uint64_t*)ptr) = x; #else - ptr[7] = x >> 56; ptr[6] = x >> 48; ptr[5] = x >> 40; ptr[4] = x >> 32; - ptr[3] = x >> 24; ptr[2] = x >> 16; ptr[1] = x >> 8; ptr[0] = x; + ptr[7] = x >> 56; + ptr[6] = x >> 48; + ptr[5] = x >> 40; + ptr[4] = x >> 32; + ptr[3] = x >> 24; + ptr[2] = x >> 16; + ptr[1] = x >> 8; + ptr[0] = x; #endif } -uint32_t static inline ReadBE32(const unsigned char *ptr) { +uint32_t static inline ReadBE32(const unsigned char* ptr) +{ #if HAVE_DECL_BE32TOH == 1 return be32toh(*((uint32_t*)ptr)); #else @@ -64,7 +79,8 @@ uint32_t static inline ReadBE32(const unsigned char *ptr) { #endif } -uint64_t static inline ReadBE64(const unsigned char *ptr) { +uint64_t static inline ReadBE64(const unsigned char* ptr) +{ #if HAVE_DECL_BE64TOH == 1 return be64toh(*((uint64_t*)ptr)); #else @@ -73,21 +89,32 @@ uint64_t static inline ReadBE64(const unsigned char *ptr) { #endif } -void static inline WriteBE32(unsigned char *ptr, uint32_t x) { +void static inline WriteBE32(unsigned char* ptr, uint32_t x) +{ #if HAVE_DECL_HTOBE32 == 1 *((uint32_t*)ptr) = htobe32(x); #else - ptr[0] = x >> 24; ptr[1] = x >> 16; ptr[2] = x >> 8; ptr[3] = x; + ptr[0] = x >> 24; + ptr[1] = x >> 16; + ptr[2] = x >> 8; + ptr[3] = x; #endif } -void static inline WriteBE64(unsigned char *ptr, uint64_t x) { +void static inline WriteBE64(unsigned char* ptr, uint64_t x) +{ #if HAVE_DECL_HTOBE64 == 1 *((uint64_t*)ptr) = htobe64(x); #else - ptr[0] = x >> 56; ptr[1] = x >> 48; ptr[2] = x >> 40; ptr[3] = x >> 32; - ptr[4] = x >> 24; ptr[5] = x >> 16; ptr[6] = x >> 8; ptr[7] = x; + ptr[0] = x >> 56; + ptr[1] = x >> 48; + ptr[2] = x >> 40; + ptr[3] = x >> 32; + ptr[4] = x >> 24; + ptr[5] = x >> 16; + ptr[6] = x >> 8; + ptr[7] = x; #endif } -#endif +#endif // BITCOIN_CRYPTO_COMMON_H diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp index b5e9f0df49..cb4a94a44d 100644 --- a/src/crypto/ripemd160.cpp +++ b/src/crypto/ripemd160.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "crypto/ripemd160.h" @@ -9,11 +9,11 @@ #include <string.h> // Internal implementation code. -namespace { - +namespace +{ /// Internal RIPEMD-160 implementation. -namespace ripemd160 { - +namespace ripemd160 +{ uint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; } uint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); } uint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; } @@ -21,7 +21,8 @@ uint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~ uint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); } /** Initialize RIPEMD-160 state. */ -void inline Initialize(uint32_t *s) { +void inline Initialize(uint32_t* s) +{ s[0] = 0x67452301ul; s[1] = 0xEFCDAB89ul; s[2] = 0x98BADCFEul; @@ -29,139 +30,223 @@ void inline Initialize(uint32_t *s) { s[4] = 0xC3D2E1F0ul; } -uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32-i)); } +uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32 - i)); } -void inline Round(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) { +void inline Round(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r) +{ a = rol(a + f + x + k, r) + e; c = rol(c, 10); } -void inline R11(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } -void inline R21(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); } -void inline R31(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); } -void inline R41(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); } -void inline R51(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); } +void inline R11(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } +void inline R21(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); } +void inline R31(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); } +void inline R41(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); } +void inline R51(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); } -void inline R12(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); } -void inline R22(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); } -void inline R32(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); } -void inline R42(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); } -void inline R52(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } +void inline R12(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); } +void inline R22(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); } +void inline R32(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); } +void inline R42(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); } +void inline R52(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); } /** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */ -void Transform(uint32_t *s, const unsigned char *chunk) { +void Transform(uint32_t* s, const unsigned char* chunk) +{ uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4]; - uint32_t a2 = a1 , b2 = b1 , c2 = c1 , d2 = d1 , e2 = e1 ; - uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12); - uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28); - uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44); + uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1; + uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12); + uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28); + uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44); uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60); - R11(a1, b1, c1, d1, e1, w0 , 11); R12(a2, b2, c2, d2, e2, w5 , 8); - R11(e1, a1, b1, c1, d1, w1 , 14); R12(e2, a2, b2, c2, d2, w14, 9); - R11(d1, e1, a1, b1, c1, w2 , 15); R12(d2, e2, a2, b2, c2, w7 , 9); - R11(c1, d1, e1, a1, b1, w3 , 12); R12(c2, d2, e2, a2, b2, w0 , 11); - R11(b1, c1, d1, e1, a1, w4 , 5); R12(b2, c2, d2, e2, a2, w9 , 13); - R11(a1, b1, c1, d1, e1, w5 , 8); R12(a2, b2, c2, d2, e2, w2 , 15); - R11(e1, a1, b1, c1, d1, w6 , 7); R12(e2, a2, b2, c2, d2, w11, 15); - R11(d1, e1, a1, b1, c1, w7 , 9); R12(d2, e2, a2, b2, c2, w4 , 5); - R11(c1, d1, e1, a1, b1, w8 , 11); R12(c2, d2, e2, a2, b2, w13, 7); - R11(b1, c1, d1, e1, a1, w9 , 13); R12(b2, c2, d2, e2, a2, w6 , 7); - R11(a1, b1, c1, d1, e1, w10, 14); R12(a2, b2, c2, d2, e2, w15, 8); - R11(e1, a1, b1, c1, d1, w11, 15); R12(e2, a2, b2, c2, d2, w8 , 11); - R11(d1, e1, a1, b1, c1, w12, 6); R12(d2, e2, a2, b2, c2, w1 , 14); - R11(c1, d1, e1, a1, b1, w13, 7); R12(c2, d2, e2, a2, b2, w10, 14); - R11(b1, c1, d1, e1, a1, w14, 9); R12(b2, c2, d2, e2, a2, w3 , 12); - R11(a1, b1, c1, d1, e1, w15, 8); R12(a2, b2, c2, d2, e2, w12, 6); - - R21(e1, a1, b1, c1, d1, w7 , 7); R22(e2, a2, b2, c2, d2, w6 , 9); - R21(d1, e1, a1, b1, c1, w4 , 6); R22(d2, e2, a2, b2, c2, w11, 13); - R21(c1, d1, e1, a1, b1, w13, 8); R22(c2, d2, e2, a2, b2, w3 , 15); - R21(b1, c1, d1, e1, a1, w1 , 13); R22(b2, c2, d2, e2, a2, w7 , 7); - R21(a1, b1, c1, d1, e1, w10, 11); R22(a2, b2, c2, d2, e2, w0 , 12); - R21(e1, a1, b1, c1, d1, w6 , 9); R22(e2, a2, b2, c2, d2, w13, 8); - R21(d1, e1, a1, b1, c1, w15, 7); R22(d2, e2, a2, b2, c2, w5 , 9); - R21(c1, d1, e1, a1, b1, w3 , 15); R22(c2, d2, e2, a2, b2, w10, 11); - R21(b1, c1, d1, e1, a1, w12, 7); R22(b2, c2, d2, e2, a2, w14, 7); - R21(a1, b1, c1, d1, e1, w0 , 12); R22(a2, b2, c2, d2, e2, w15, 7); - R21(e1, a1, b1, c1, d1, w9 , 15); R22(e2, a2, b2, c2, d2, w8 , 12); - R21(d1, e1, a1, b1, c1, w5 , 9); R22(d2, e2, a2, b2, c2, w12, 7); - R21(c1, d1, e1, a1, b1, w2 , 11); R22(c2, d2, e2, a2, b2, w4 , 6); - R21(b1, c1, d1, e1, a1, w14, 7); R22(b2, c2, d2, e2, a2, w9 , 15); - R21(a1, b1, c1, d1, e1, w11, 13); R22(a2, b2, c2, d2, e2, w1 , 13); - R21(e1, a1, b1, c1, d1, w8 , 12); R22(e2, a2, b2, c2, d2, w2 , 11); - - R31(d1, e1, a1, b1, c1, w3 , 11); R32(d2, e2, a2, b2, c2, w15, 9); - R31(c1, d1, e1, a1, b1, w10, 13); R32(c2, d2, e2, a2, b2, w5 , 7); - R31(b1, c1, d1, e1, a1, w14, 6); R32(b2, c2, d2, e2, a2, w1 , 15); - R31(a1, b1, c1, d1, e1, w4 , 7); R32(a2, b2, c2, d2, e2, w3 , 11); - R31(e1, a1, b1, c1, d1, w9 , 14); R32(e2, a2, b2, c2, d2, w7 , 8); - R31(d1, e1, a1, b1, c1, w15, 9); R32(d2, e2, a2, b2, c2, w14, 6); - R31(c1, d1, e1, a1, b1, w8 , 13); R32(c2, d2, e2, a2, b2, w6 , 6); - R31(b1, c1, d1, e1, a1, w1 , 15); R32(b2, c2, d2, e2, a2, w9 , 14); - R31(a1, b1, c1, d1, e1, w2 , 14); R32(a2, b2, c2, d2, e2, w11, 12); - R31(e1, a1, b1, c1, d1, w7 , 8); R32(e2, a2, b2, c2, d2, w8 , 13); - R31(d1, e1, a1, b1, c1, w0 , 13); R32(d2, e2, a2, b2, c2, w12, 5); - R31(c1, d1, e1, a1, b1, w6 , 6); R32(c2, d2, e2, a2, b2, w2 , 14); - R31(b1, c1, d1, e1, a1, w13, 5); R32(b2, c2, d2, e2, a2, w10, 13); - R31(a1, b1, c1, d1, e1, w11, 12); R32(a2, b2, c2, d2, e2, w0 , 13); - R31(e1, a1, b1, c1, d1, w5 , 7); R32(e2, a2, b2, c2, d2, w4 , 7); - R31(d1, e1, a1, b1, c1, w12, 5); R32(d2, e2, a2, b2, c2, w13, 5); - - R41(c1, d1, e1, a1, b1, w1 , 11); R42(c2, d2, e2, a2, b2, w8 , 15); - R41(b1, c1, d1, e1, a1, w9 , 12); R42(b2, c2, d2, e2, a2, w6 , 5); - R41(a1, b1, c1, d1, e1, w11, 14); R42(a2, b2, c2, d2, e2, w4 , 8); - R41(e1, a1, b1, c1, d1, w10, 15); R42(e2, a2, b2, c2, d2, w1 , 11); - R41(d1, e1, a1, b1, c1, w0 , 14); R42(d2, e2, a2, b2, c2, w3 , 14); - R41(c1, d1, e1, a1, b1, w8 , 15); R42(c2, d2, e2, a2, b2, w11, 14); - R41(b1, c1, d1, e1, a1, w12, 9); R42(b2, c2, d2, e2, a2, w15, 6); - R41(a1, b1, c1, d1, e1, w4 , 8); R42(a2, b2, c2, d2, e2, w0 , 14); - R41(e1, a1, b1, c1, d1, w13, 9); R42(e2, a2, b2, c2, d2, w5 , 6); - R41(d1, e1, a1, b1, c1, w3 , 14); R42(d2, e2, a2, b2, c2, w12, 9); - R41(c1, d1, e1, a1, b1, w7 , 5); R42(c2, d2, e2, a2, b2, w2 , 12); - R41(b1, c1, d1, e1, a1, w15, 6); R42(b2, c2, d2, e2, a2, w13, 9); - R41(a1, b1, c1, d1, e1, w14, 8); R42(a2, b2, c2, d2, e2, w9 , 12); - R41(e1, a1, b1, c1, d1, w5 , 6); R42(e2, a2, b2, c2, d2, w7 , 5); - R41(d1, e1, a1, b1, c1, w6 , 5); R42(d2, e2, a2, b2, c2, w10, 15); - R41(c1, d1, e1, a1, b1, w2 , 12); R42(c2, d2, e2, a2, b2, w14, 8); - - R51(b1, c1, d1, e1, a1, w4 , 9); R52(b2, c2, d2, e2, a2, w12, 8); - R51(a1, b1, c1, d1, e1, w0 , 15); R52(a2, b2, c2, d2, e2, w15, 5); - R51(e1, a1, b1, c1, d1, w5 , 5); R52(e2, a2, b2, c2, d2, w10, 12); - R51(d1, e1, a1, b1, c1, w9 , 11); R52(d2, e2, a2, b2, c2, w4 , 9); - R51(c1, d1, e1, a1, b1, w7 , 6); R52(c2, d2, e2, a2, b2, w1 , 12); - R51(b1, c1, d1, e1, a1, w12, 8); R52(b2, c2, d2, e2, a2, w5 , 5); - R51(a1, b1, c1, d1, e1, w2 , 13); R52(a2, b2, c2, d2, e2, w8 , 14); - R51(e1, a1, b1, c1, d1, w10, 12); R52(e2, a2, b2, c2, d2, w7 , 6); - R51(d1, e1, a1, b1, c1, w14, 5); R52(d2, e2, a2, b2, c2, w6 , 8); - R51(c1, d1, e1, a1, b1, w1 , 12); R52(c2, d2, e2, a2, b2, w2 , 13); - R51(b1, c1, d1, e1, a1, w3 , 13); R52(b2, c2, d2, e2, a2, w13, 6); - R51(a1, b1, c1, d1, e1, w8 , 14); R52(a2, b2, c2, d2, e2, w14, 5); - R51(e1, a1, b1, c1, d1, w11, 11); R52(e2, a2, b2, c2, d2, w0 , 15); - R51(d1, e1, a1, b1, c1, w6 , 8); R52(d2, e2, a2, b2, c2, w3 , 13); - R51(c1, d1, e1, a1, b1, w15, 5); R52(c2, d2, e2, a2, b2, w9 , 11); - R51(b1, c1, d1, e1, a1, w13, 6); R52(b2, c2, d2, e2, a2, w11, 11); + R11(a1, b1, c1, d1, e1, w0, 11); + R12(a2, b2, c2, d2, e2, w5, 8); + R11(e1, a1, b1, c1, d1, w1, 14); + R12(e2, a2, b2, c2, d2, w14, 9); + R11(d1, e1, a1, b1, c1, w2, 15); + R12(d2, e2, a2, b2, c2, w7, 9); + R11(c1, d1, e1, a1, b1, w3, 12); + R12(c2, d2, e2, a2, b2, w0, 11); + R11(b1, c1, d1, e1, a1, w4, 5); + R12(b2, c2, d2, e2, a2, w9, 13); + R11(a1, b1, c1, d1, e1, w5, 8); + R12(a2, b2, c2, d2, e2, w2, 15); + R11(e1, a1, b1, c1, d1, w6, 7); + R12(e2, a2, b2, c2, d2, w11, 15); + R11(d1, e1, a1, b1, c1, w7, 9); + R12(d2, e2, a2, b2, c2, w4, 5); + R11(c1, d1, e1, a1, b1, w8, 11); + R12(c2, d2, e2, a2, b2, w13, 7); + R11(b1, c1, d1, e1, a1, w9, 13); + R12(b2, c2, d2, e2, a2, w6, 7); + R11(a1, b1, c1, d1, e1, w10, 14); + R12(a2, b2, c2, d2, e2, w15, 8); + R11(e1, a1, b1, c1, d1, w11, 15); + R12(e2, a2, b2, c2, d2, w8, 11); + R11(d1, e1, a1, b1, c1, w12, 6); + R12(d2, e2, a2, b2, c2, w1, 14); + R11(c1, d1, e1, a1, b1, w13, 7); + R12(c2, d2, e2, a2, b2, w10, 14); + R11(b1, c1, d1, e1, a1, w14, 9); + R12(b2, c2, d2, e2, a2, w3, 12); + R11(a1, b1, c1, d1, e1, w15, 8); + R12(a2, b2, c2, d2, e2, w12, 6); + + R21(e1, a1, b1, c1, d1, w7, 7); + R22(e2, a2, b2, c2, d2, w6, 9); + R21(d1, e1, a1, b1, c1, w4, 6); + R22(d2, e2, a2, b2, c2, w11, 13); + R21(c1, d1, e1, a1, b1, w13, 8); + R22(c2, d2, e2, a2, b2, w3, 15); + R21(b1, c1, d1, e1, a1, w1, 13); + R22(b2, c2, d2, e2, a2, w7, 7); + R21(a1, b1, c1, d1, e1, w10, 11); + R22(a2, b2, c2, d2, e2, w0, 12); + R21(e1, a1, b1, c1, d1, w6, 9); + R22(e2, a2, b2, c2, d2, w13, 8); + R21(d1, e1, a1, b1, c1, w15, 7); + R22(d2, e2, a2, b2, c2, w5, 9); + R21(c1, d1, e1, a1, b1, w3, 15); + R22(c2, d2, e2, a2, b2, w10, 11); + R21(b1, c1, d1, e1, a1, w12, 7); + R22(b2, c2, d2, e2, a2, w14, 7); + R21(a1, b1, c1, d1, e1, w0, 12); + R22(a2, b2, c2, d2, e2, w15, 7); + R21(e1, a1, b1, c1, d1, w9, 15); + R22(e2, a2, b2, c2, d2, w8, 12); + R21(d1, e1, a1, b1, c1, w5, 9); + R22(d2, e2, a2, b2, c2, w12, 7); + R21(c1, d1, e1, a1, b1, w2, 11); + R22(c2, d2, e2, a2, b2, w4, 6); + R21(b1, c1, d1, e1, a1, w14, 7); + R22(b2, c2, d2, e2, a2, w9, 15); + R21(a1, b1, c1, d1, e1, w11, 13); + R22(a2, b2, c2, d2, e2, w1, 13); + R21(e1, a1, b1, c1, d1, w8, 12); + R22(e2, a2, b2, c2, d2, w2, 11); + + R31(d1, e1, a1, b1, c1, w3, 11); + R32(d2, e2, a2, b2, c2, w15, 9); + R31(c1, d1, e1, a1, b1, w10, 13); + R32(c2, d2, e2, a2, b2, w5, 7); + R31(b1, c1, d1, e1, a1, w14, 6); + R32(b2, c2, d2, e2, a2, w1, 15); + R31(a1, b1, c1, d1, e1, w4, 7); + R32(a2, b2, c2, d2, e2, w3, 11); + R31(e1, a1, b1, c1, d1, w9, 14); + R32(e2, a2, b2, c2, d2, w7, 8); + R31(d1, e1, a1, b1, c1, w15, 9); + R32(d2, e2, a2, b2, c2, w14, 6); + R31(c1, d1, e1, a1, b1, w8, 13); + R32(c2, d2, e2, a2, b2, w6, 6); + R31(b1, c1, d1, e1, a1, w1, 15); + R32(b2, c2, d2, e2, a2, w9, 14); + R31(a1, b1, c1, d1, e1, w2, 14); + R32(a2, b2, c2, d2, e2, w11, 12); + R31(e1, a1, b1, c1, d1, w7, 8); + R32(e2, a2, b2, c2, d2, w8, 13); + R31(d1, e1, a1, b1, c1, w0, 13); + R32(d2, e2, a2, b2, c2, w12, 5); + R31(c1, d1, e1, a1, b1, w6, 6); + R32(c2, d2, e2, a2, b2, w2, 14); + R31(b1, c1, d1, e1, a1, w13, 5); + R32(b2, c2, d2, e2, a2, w10, 13); + R31(a1, b1, c1, d1, e1, w11, 12); + R32(a2, b2, c2, d2, e2, w0, 13); + R31(e1, a1, b1, c1, d1, w5, 7); + R32(e2, a2, b2, c2, d2, w4, 7); + R31(d1, e1, a1, b1, c1, w12, 5); + R32(d2, e2, a2, b2, c2, w13, 5); + + R41(c1, d1, e1, a1, b1, w1, 11); + R42(c2, d2, e2, a2, b2, w8, 15); + R41(b1, c1, d1, e1, a1, w9, 12); + R42(b2, c2, d2, e2, a2, w6, 5); + R41(a1, b1, c1, d1, e1, w11, 14); + R42(a2, b2, c2, d2, e2, w4, 8); + R41(e1, a1, b1, c1, d1, w10, 15); + R42(e2, a2, b2, c2, d2, w1, 11); + R41(d1, e1, a1, b1, c1, w0, 14); + R42(d2, e2, a2, b2, c2, w3, 14); + R41(c1, d1, e1, a1, b1, w8, 15); + R42(c2, d2, e2, a2, b2, w11, 14); + R41(b1, c1, d1, e1, a1, w12, 9); + R42(b2, c2, d2, e2, a2, w15, 6); + R41(a1, b1, c1, d1, e1, w4, 8); + R42(a2, b2, c2, d2, e2, w0, 14); + R41(e1, a1, b1, c1, d1, w13, 9); + R42(e2, a2, b2, c2, d2, w5, 6); + R41(d1, e1, a1, b1, c1, w3, 14); + R42(d2, e2, a2, b2, c2, w12, 9); + R41(c1, d1, e1, a1, b1, w7, 5); + R42(c2, d2, e2, a2, b2, w2, 12); + R41(b1, c1, d1, e1, a1, w15, 6); + R42(b2, c2, d2, e2, a2, w13, 9); + R41(a1, b1, c1, d1, e1, w14, 8); + R42(a2, b2, c2, d2, e2, w9, 12); + R41(e1, a1, b1, c1, d1, w5, 6); + R42(e2, a2, b2, c2, d2, w7, 5); + R41(d1, e1, a1, b1, c1, w6, 5); + R42(d2, e2, a2, b2, c2, w10, 15); + R41(c1, d1, e1, a1, b1, w2, 12); + R42(c2, d2, e2, a2, b2, w14, 8); + + R51(b1, c1, d1, e1, a1, w4, 9); + R52(b2, c2, d2, e2, a2, w12, 8); + R51(a1, b1, c1, d1, e1, w0, 15); + R52(a2, b2, c2, d2, e2, w15, 5); + R51(e1, a1, b1, c1, d1, w5, 5); + R52(e2, a2, b2, c2, d2, w10, 12); + R51(d1, e1, a1, b1, c1, w9, 11); + R52(d2, e2, a2, b2, c2, w4, 9); + R51(c1, d1, e1, a1, b1, w7, 6); + R52(c2, d2, e2, a2, b2, w1, 12); + R51(b1, c1, d1, e1, a1, w12, 8); + R52(b2, c2, d2, e2, a2, w5, 5); + R51(a1, b1, c1, d1, e1, w2, 13); + R52(a2, b2, c2, d2, e2, w8, 14); + R51(e1, a1, b1, c1, d1, w10, 12); + R52(e2, a2, b2, c2, d2, w7, 6); + R51(d1, e1, a1, b1, c1, w14, 5); + R52(d2, e2, a2, b2, c2, w6, 8); + R51(c1, d1, e1, a1, b1, w1, 12); + R52(c2, d2, e2, a2, b2, w2, 13); + R51(b1, c1, d1, e1, a1, w3, 13); + R52(b2, c2, d2, e2, a2, w13, 6); + R51(a1, b1, c1, d1, e1, w8, 14); + R52(a2, b2, c2, d2, e2, w14, 5); + R51(e1, a1, b1, c1, d1, w11, 11); + R52(e2, a2, b2, c2, d2, w0, 15); + R51(d1, e1, a1, b1, c1, w6, 8); + R52(d2, e2, a2, b2, c2, w3, 13); + R51(c1, d1, e1, a1, b1, w15, 5); + R52(c2, d2, e2, a2, b2, w9, 11); + R51(b1, c1, d1, e1, a1, w13, 6); + R52(b2, c2, d2, e2, a2, w11, 11); uint32_t t = s[0]; s[0] = s[1] + c1 + d2; s[1] = s[2] + d1 + e2; s[2] = s[3] + e1 + a2; s[3] = s[4] + a1 + b2; - s[4] = t + b1 + c2; + s[4] = t + b1 + c2; } -} // namespace ripemd160 +} // namespace ripemd160 -} // namespace +} // namespace ////// RIPEMD160 -CRIPEMD160::CRIPEMD160() : bytes(0) { +CRIPEMD160::CRIPEMD160() : bytes(0) +{ ripemd160::Initialize(s); } -CRIPEMD160& CRIPEMD160::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; +CRIPEMD160& CRIPEMD160::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; size_t bufsize = bytes % 64; if (bufsize && bufsize + len >= 64) { // Fill the buffer, and process it. @@ -185,20 +270,22 @@ CRIPEMD160& CRIPEMD160::Write(const unsigned char *data, size_t len) { return *this; } -void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) { +void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; WriteLE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteLE32(hash, s[0]); - WriteLE32(hash+4, s[1]); - WriteLE32(hash+8, s[2]); - WriteLE32(hash+12, s[3]); - WriteLE32(hash+16, s[4]); + WriteLE32(hash + 4, s[1]); + WriteLE32(hash + 8, s[2]); + WriteLE32(hash + 12, s[3]); + WriteLE32(hash + 16, s[4]); } -CRIPEMD160& CRIPEMD160::Reset() { +CRIPEMD160& CRIPEMD160::Reset() +{ bytes = 0; ripemd160::Initialize(s); return *this; diff --git a/src/crypto/ripemd160.h b/src/crypto/ripemd160.h index 44bd4879a5..902e7ca83f 100644 --- a/src/crypto/ripemd160.h +++ b/src/crypto/ripemd160.h @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_RIPEMD160_H @@ -9,7 +9,8 @@ #include <stdlib.h> /** A hasher class for RIPEMD-160. */ -class CRIPEMD160 { +class CRIPEMD160 +{ private: uint32_t s[5]; unsigned char buf[64]; @@ -19,9 +20,9 @@ public: static const size_t OUTPUT_SIZE = 20; CRIPEMD160(); - CRIPEMD160& Write(const unsigned char *data, size_t len); + CRIPEMD160& Write(const unsigned char* data, size_t len); void Finalize(unsigned char hash[OUTPUT_SIZE]); CRIPEMD160& Reset(); }; -#endif +#endif // BITCOIN_RIPEMD160_H diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index 819abab579..7f78fdfc6d 100644 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "crypto/sha1.h" @@ -9,14 +9,14 @@ #include <string.h> // Internal implementation code. -namespace { - +namespace +{ /// Internal SHA-1 implementation. -namespace sha1 { - +namespace sha1 +{ /** One round of SHA-1. */ -void inline Round(uint32_t a, uint32_t &b, uint32_t c, uint32_t d, uint32_t &e, - uint32_t f, uint32_t k, uint32_t w) { +void inline Round(uint32_t a, uint32_t& b, uint32_t c, uint32_t d, uint32_t& e, uint32_t f, uint32_t k, uint32_t w) +{ e += ((a << 5) | (a >> 27)) + f + k + w; b = (b << 30) | (b >> 2); } @@ -28,7 +28,8 @@ uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & ( uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); } /** Initialize SHA-1 state. */ -void inline Initialize(uint32_t *s) { +void inline Initialize(uint32_t* s) +{ s[0] = 0x67452301ul; s[1] = 0xEFCDAB89ul; s[2] = 0x98BADCFEul; @@ -42,20 +43,21 @@ const uint32_t k3 = 0x8F1BBCDCul; const uint32_t k4 = 0xCA62C1D6ul; /** Perform a SHA-1 transformation, processing a 64-byte chunk. */ -void Transform(uint32_t *s, const unsigned char *chunk) { +void Transform(uint32_t* s, const unsigned char* chunk) +{ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4]; uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0)); - Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4)); - Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8)); - Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12)); - Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16)); - Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20)); - Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24)); - Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28)); - Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32)); - Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36)); + Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0)); + Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4)); + Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8)); + Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12)); + Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16)); + Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20)); + Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24)); + Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28)); + Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32)); + Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36)); Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40)); Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44)); Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48)); @@ -63,73 +65,73 @@ void Transform(uint32_t *s, const unsigned char *chunk) { Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56)); Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60)); - Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15)); - Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0 )); - Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1 )); - - Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15)); - Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0 )); - Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1 )); - - Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15)); - Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0 )); - Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1 )); - - Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2 )); - Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3 )); - Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4 )); - Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5 )); - Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6 )); - Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7 )); - Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8 )); - Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9 )); - Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10)); - Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11)); - Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12)); - Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13)); - Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); - Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15)); - Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0 )); - Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1 )); + Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15)); + Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0)); + Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1)); + + Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15)); + Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0)); + Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1)); + + Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15)); + Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0)); + Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1)); + + Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2)); + Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3)); + Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4)); + Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5)); + Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6)); + Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7)); + Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8)); + Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9)); + Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10)); + Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11)); + Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12)); + Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13)); + Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14)); + Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15)); + Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0)); + Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1)); s[0] += a; s[1] += b; @@ -138,18 +140,20 @@ void Transform(uint32_t *s, const unsigned char *chunk) { s[4] += e; } -} // namespace sha1 +} // namespace sha1 -} // namespace +} // namespace ////// SHA1 -CSHA1::CSHA1() : bytes(0) { +CSHA1::CSHA1() : bytes(0) +{ sha1::Initialize(s); } -CSHA1& CSHA1::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; +CSHA1& CSHA1::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; size_t bufsize = bytes % 64; if (bufsize && bufsize + len >= 64) { // Fill the buffer, and process it. @@ -173,20 +177,22 @@ CSHA1& CSHA1::Write(const unsigned char *data, size_t len) { return *this; } -void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE]) { +void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; WriteBE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteBE32(hash, s[0]); - WriteBE32(hash+4, s[1]); - WriteBE32(hash+8, s[2]); - WriteBE32(hash+12, s[3]); - WriteBE32(hash+16, s[4]); + WriteBE32(hash + 4, s[1]); + WriteBE32(hash + 8, s[2]); + WriteBE32(hash + 12, s[3]); + WriteBE32(hash + 16, s[4]); } -CSHA1& CSHA1::Reset() { +CSHA1& CSHA1::Reset() +{ bytes = 0; sha1::Initialize(s); return *this; diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h index b16f2c88ce..68bd7ced9f 100644 --- a/src/crypto/sha1.h +++ b/src/crypto/sha1.h @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SHA1_H @@ -9,7 +9,8 @@ #include <stdlib.h> /** A hasher class for SHA1. */ -class CSHA1 { +class CSHA1 +{ private: uint32_t s[5]; unsigned char buf[64]; @@ -19,9 +20,9 @@ public: static const size_t OUTPUT_SIZE = 20; CSHA1(); - CSHA1& Write(const unsigned char *data, size_t len); + CSHA1& Write(const unsigned char* data, size_t len); void Finalize(unsigned char hash[OUTPUT_SIZE]); CSHA1& Reset(); }; -#endif +#endif // BITCOIN_SHA1_H diff --git a/src/crypto/sha2.cpp b/src/crypto/sha2.cpp index 72f191afcd..613aac2d71 100644 --- a/src/crypto/sha2.cpp +++ b/src/crypto/sha2.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "crypto/sha2.h" @@ -9,11 +9,11 @@ #include <string.h> // Internal implementation code. -namespace { - +namespace +{ /// Internal SHA-256 implementation. -namespace sha256 { - +namespace sha256 +{ uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); } uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); } uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); } @@ -22,9 +22,8 @@ uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); } /** One round of SHA-256. */ -void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d, - uint32_t e, uint32_t f, uint32_t g, uint32_t &h, - uint32_t k, uint32_t w) { +void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k, uint32_t w) +{ uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w; uint32_t t2 = Sigma0(a) + Maj(a, b, c); d += t1; @@ -32,7 +31,8 @@ void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d, } /** Initialize SHA-256 state. */ -void inline Initialize(uint32_t *s) { +void inline Initialize(uint32_t* s) +{ s[0] = 0x6a09e667ul; s[1] = 0xbb67ae85ul; s[2] = 0x3c6ef372ul; @@ -44,20 +44,21 @@ void inline Initialize(uint32_t *s) { } /** Perform one SHA-256 transformation, processing a 64-byte chunk. */ -void Transform(uint32_t *s, const unsigned char *chunk) { +void Transform(uint32_t* s, const unsigned char* chunk) +{ uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0)); - Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4)); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8)); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12)); - Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16)); - Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20)); - Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24)); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28)); - Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32)); - Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36)); + Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0)); + Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4)); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8)); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12)); + Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16)); + Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20)); + Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24)); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28)); + Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32)); + Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36)); Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40)); Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44)); Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48)); @@ -65,56 +66,56 @@ void Transform(uint32_t *s, const unsigned char *chunk) { Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56)); Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60)); - Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0( w0)); + Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); s[0] += a; s[1] += b; @@ -126,11 +127,11 @@ void Transform(uint32_t *s, const unsigned char *chunk) { s[7] += h; } -} // namespace sha256 +} // namespace sha256 /// Internal SHA-512 implementation. -namespace sha512 { - +namespace sha512 +{ uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); } uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); } uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); } @@ -139,9 +140,8 @@ uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); } /** One round of SHA-512. */ -void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t &d, - uint64_t e, uint64_t f, uint64_t g, uint64_t &h, - uint64_t k, uint64_t w) { +void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, uint64_t f, uint64_t g, uint64_t& h, uint64_t k, uint64_t w) +{ uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w; uint64_t t2 = Sigma0(a) + Maj(a, b, c); d += t1; @@ -149,7 +149,8 @@ void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t &d, } /** Initialize SHA-256 state. */ -void inline Initialize(uint64_t *s) { +void inline Initialize(uint64_t* s) +{ s[0] = 0x6a09e667f3bcc908ull; s[1] = 0xbb67ae8584caa73bull; s[2] = 0x3c6ef372fe94f82bull; @@ -161,20 +162,21 @@ void inline Initialize(uint64_t *s) { } /** Perform one SHA-512 transformation, processing a 128-byte chunk. */ -void Transform(uint64_t *s, const unsigned char *chunk) { +void Transform(uint64_t* s, const unsigned char* chunk) +{ uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0)); - Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8)); - Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16)); - Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24)); - Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32)); - Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40)); - Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48)); - Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56)); - Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64)); - Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72)); + Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0)); + Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8)); + Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16)); + Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24)); + Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32)); + Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40)); + Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48)); + Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56)); + Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64)); + Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72)); Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80)); Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88)); Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96)); @@ -182,73 +184,73 @@ void Transform(uint64_t *s, const unsigned char *chunk) { Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112)); Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120)); - Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0( w0)); - - Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0( w1)); - Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0( w2)); - Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1( w0) + w11 + sigma0( w3)); - Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1( w1) + w12 + sigma0( w4)); - Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1( w2) + w13 + sigma0( w5)); - Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1( w3) + w14 + sigma0( w6)); - Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1( w4) + w15 + sigma0( w7)); - Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1( w5) + w0 + sigma0( w8)); - Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1( w6) + w1 + sigma0( w9)); - Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1( w7) + w2 + sigma0(w10)); - Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1( w8) + w3 + sigma0(w11)); - Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1( w9) + w4 + sigma0(w12)); - Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 += sigma1(w13) + w8 + sigma0( w0)); + Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0)); + + Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1)); + Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2)); + Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3)); + Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4)); + Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5)); + Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6)); + Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7)); + Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8)); + Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9)); + Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10)); + Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11)); + Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12)); + Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13)); + Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14)); + Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 += sigma1(w12) + w7 + sigma0(w15)); + Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 += sigma1(w13) + w8 + sigma0(w0)); s[0] += a; s[1] += b; @@ -260,19 +262,21 @@ void Transform(uint64_t *s, const unsigned char *chunk) { s[7] += h; } -} // namespace sha512 +} // namespace sha512 -} // namespace +} // namespace ////// SHA-256 -CSHA256::CSHA256() : bytes(0) { +CSHA256::CSHA256() : bytes(0) +{ sha256::Initialize(s); } -CSHA256& CSHA256::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; +CSHA256& CSHA256::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; size_t bufsize = bytes % 64; if (bufsize && bufsize + len >= 64) { // Fill the buffer, and process it. @@ -296,23 +300,25 @@ CSHA256& CSHA256::Write(const unsigned char *data, size_t len) { return *this; } -void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) { +void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ static const unsigned char pad[64] = {0x80}; unsigned char sizedesc[8]; WriteBE64(sizedesc, bytes << 3); Write(pad, 1 + ((119 - (bytes % 64)) % 64)); Write(sizedesc, 8); WriteBE32(hash, s[0]); - WriteBE32(hash+4, s[1]); - WriteBE32(hash+8, s[2]); - WriteBE32(hash+12, s[3]); - WriteBE32(hash+16, s[4]); - WriteBE32(hash+20, s[5]); - WriteBE32(hash+24, s[6]); - WriteBE32(hash+28, s[7]); + WriteBE32(hash + 4, s[1]); + WriteBE32(hash + 8, s[2]); + WriteBE32(hash + 12, s[3]); + WriteBE32(hash + 16, s[4]); + WriteBE32(hash + 20, s[5]); + WriteBE32(hash + 24, s[6]); + WriteBE32(hash + 28, s[7]); } -CSHA256& CSHA256::Reset() { +CSHA256& CSHA256::Reset() +{ bytes = 0; sha256::Initialize(s); return *this; @@ -320,12 +326,14 @@ CSHA256& CSHA256::Reset() { ////// SHA-512 -CSHA512::CSHA512() : bytes(0) { +CSHA512::CSHA512() : bytes(0) +{ sha512::Initialize(s); } -CSHA512& CSHA512::Write(const unsigned char *data, size_t len) { - const unsigned char *end = data + len; +CSHA512& CSHA512::Write(const unsigned char* data, size_t len) +{ + const unsigned char* end = data + len; size_t bufsize = bytes % 128; if (bufsize && bufsize + len >= 128) { // Fill the buffer, and process it. @@ -349,23 +357,25 @@ CSHA512& CSHA512::Write(const unsigned char *data, size_t len) { return *this; } -void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) { +void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ static const unsigned char pad[128] = {0x80}; unsigned char sizedesc[16] = {0x00}; - WriteBE64(sizedesc+8, bytes << 3); + WriteBE64(sizedesc + 8, bytes << 3); Write(pad, 1 + ((239 - (bytes % 128)) % 128)); Write(sizedesc, 16); WriteBE64(hash, s[0]); - WriteBE64(hash+8, s[1]); - WriteBE64(hash+16, s[2]); - WriteBE64(hash+24, s[3]); - WriteBE64(hash+32, s[4]); - WriteBE64(hash+40, s[5]); - WriteBE64(hash+48, s[6]); - WriteBE64(hash+56, s[7]); + WriteBE64(hash + 8, s[1]); + WriteBE64(hash + 16, s[2]); + WriteBE64(hash + 24, s[3]); + WriteBE64(hash + 32, s[4]); + WriteBE64(hash + 40, s[5]); + WriteBE64(hash + 48, s[6]); + WriteBE64(hash + 56, s[7]); } -CSHA512& CSHA512::Reset() { +CSHA512& CSHA512::Reset() +{ bytes = 0; sha512::Initialize(s); return *this; @@ -373,7 +383,8 @@ CSHA512& CSHA512::Reset() { ////// HMAC-SHA-512 -CHMAC_SHA512::CHMAC_SHA512(const unsigned char *key, size_t keylen) { +CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen) +{ unsigned char rkey[128]; if (keylen <= 128) { memcpy(rkey, key, keylen); @@ -383,16 +394,17 @@ CHMAC_SHA512::CHMAC_SHA512(const unsigned char *key, size_t keylen) { memset(rkey + 64, 0, 64); } - for (int n=0; n<128; n++) + for (int n = 0; n < 128; n++) rkey[n] ^= 0x5c; outer.Write(rkey, 128); - for (int n=0; n<128; n++) + for (int n = 0; n < 128; n++) rkey[n] ^= 0x5c ^ 0x36; inner.Write(rkey, 128); } -void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) { +void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE]) +{ unsigned char temp[64]; inner.Finalize(temp); outer.Write(temp, 64).Finalize(hash); diff --git a/src/crypto/sha2.h b/src/crypto/sha2.h index 088d5e194c..a6cbe58554 100644 --- a/src/crypto/sha2.h +++ b/src/crypto/sha2.h @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_SHA2_H @@ -9,7 +9,8 @@ #include <stdlib.h> /** A hasher class for SHA-256. */ -class CSHA256 { +class CSHA256 +{ private: uint32_t s[8]; unsigned char buf[64]; @@ -19,13 +20,14 @@ public: static const size_t OUTPUT_SIZE = 32; CSHA256(); - CSHA256& Write(const unsigned char *data, size_t len); + CSHA256& Write(const unsigned char* data, size_t len); void Finalize(unsigned char hash[OUTPUT_SIZE]); CSHA256& Reset(); }; /** A hasher class for SHA-512. */ -class CSHA512 { +class CSHA512 +{ private: uint64_t s[8]; unsigned char buf[128]; @@ -35,13 +37,14 @@ public: static const size_t OUTPUT_SIZE = 64; CSHA512(); - CSHA512& Write(const unsigned char *data, size_t len); + CSHA512& Write(const unsigned char* data, size_t len); void Finalize(unsigned char hash[OUTPUT_SIZE]); CSHA512& Reset(); }; /** A hasher class for HMAC-SHA-512. */ -class CHMAC_SHA512 { +class CHMAC_SHA512 +{ private: CSHA512 outer; CSHA512 inner; @@ -49,12 +52,13 @@ private: public: static const size_t OUTPUT_SIZE = 64; - CHMAC_SHA512(const unsigned char *key, size_t keylen); - CHMAC_SHA512& Write(const unsigned char *data, size_t len) { + CHMAC_SHA512(const unsigned char* key, size_t keylen); + CHMAC_SHA512& Write(const unsigned char* data, size_t len) + { inner.Write(data, len); return *this; } void Finalize(unsigned char hash[OUTPUT_SIZE]); }; -#endif +#endif // BITCOIN_SHA2_H diff --git a/src/init.cpp b/src/init.cpp index 7299bd0f4a..980c589b29 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -45,7 +45,7 @@ using namespace boost; using namespace std; #ifdef ENABLE_WALLET -CWallet* pwalletMain; +CWallet* pwalletMain = NULL; #endif #ifdef WIN32 @@ -109,7 +109,7 @@ bool ShutdownRequested() return fRequestShutdown; } -static CCoinsViewDB *pcoinsdbview; +static CCoinsViewDB *pcoinsdbview = NULL; void Shutdown() { @@ -165,8 +165,8 @@ void Shutdown() #endif UnregisterAllWallets(); #ifdef ENABLE_WALLET - if (pwalletMain) - delete pwalletMain; + delete pwalletMain; + pwalletMain = NULL; #endif LogPrintf("%s: done\n", __func__); } @@ -662,7 +662,7 @@ bool AppInit2(boost::thread_group& threadGroup) // cost to you of processing a transaction. if (mapArgs.count("-minrelaytxfee")) { - int64_t n = 0; + CAmount n = 0; if (ParseMoney(mapArgs["-minrelaytxfee"], n) && n > 0) ::minRelayTxFee = CFeeRate(n); else @@ -672,7 +672,7 @@ bool AppInit2(boost::thread_group& threadGroup) #ifdef ENABLE_WALLET if (mapArgs.count("-mintxfee")) { - int64_t n = 0; + CAmount n = 0; if (ParseMoney(mapArgs["-mintxfee"], n) && n > 0) CWallet::minTxFee = CFeeRate(n); else @@ -680,7 +680,7 @@ bool AppInit2(boost::thread_group& threadGroup) } if (mapArgs.count("-paytxfee")) { - int64_t nFeePerK = 0; + CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) return InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s'"), mapArgs["-paytxfee"])); if (nFeePerK > nHighTransactionFeeWarning) @@ -701,6 +701,7 @@ bool AppInit2(boost::thread_group& threadGroup) fIsBareMultisigStd = GetArg("-permitbaremultisig", true) != 0; // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log + // Sanity check if (!InitSanityCheck()) return InitError(_("Initialization sanity check failed. Bitcoin Core is shutting down.")); @@ -1058,7 +1059,7 @@ bool AppInit2(boost::thread_group& threadGroup) } boost::filesystem::path est_path = GetDataDir() / FEE_ESTIMATES_FILENAME; - CAutoFile est_filein = CAutoFile(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION); + CAutoFile est_filein(fopen(est_path.string().c_str(), "rb"), SER_DISK, CLIENT_VERSION); // Allowed to fail as this file IS missing on first startup. if (est_filein) mempool.ReadFeeEstimates(est_filein); @@ -1159,7 +1160,7 @@ bool AppInit2(boost::thread_group& threadGroup) CWalletDB walletdb(strWalletFile); CBlockLocator locator; if (walletdb.ReadBestBlock(locator)) - pindexRescan = chainActive.FindFork(locator); + pindexRescan = FindForkInGlobalIndex(chainActive, locator); else pindexRescan = chainActive.Genesis(); } diff --git a/src/key.cpp b/src/key.cpp index 8ed787654a..c2251b4f2a 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -220,7 +220,7 @@ public: return o2i_ECPublicKey(&pkey, &pbegin, pubkey.size()) != NULL; } - bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) { + bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) { vchSig.clear(); ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey); if (sig == NULL) @@ -232,7 +232,7 @@ public: BIGNUM *halforder = BN_CTX_get(ctx); EC_GROUP_get_order(group, order, ctx); BN_rshift1(halforder, order); - if (BN_cmp(sig->s, halforder) > 0) { + if (lowS && BN_cmp(sig->s, halforder) > 0) { // enforce low S values, by negating the value (modulo the order) if above order/2. BN_sub(sig->s, order, sig->s); } @@ -467,7 +467,7 @@ CPubKey CKey::GetPubKey() const { return pubkey; } -bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const { +bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, bool lowS) const { if (!fValid) return false; #ifdef USE_SECP256K1 @@ -484,7 +484,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const { #else CECKey key; key.SetSecretBytes(vch); - return key.Sign(hash, vchSig); + return key.Sign(hash, vchSig, lowS); #endif } @@ -276,7 +276,7 @@ public: CPubKey GetPubKey() const; // Create a DER-serialized signature. - bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig) const; + bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool lowS = true) const; // Create a compact signature (65 bytes), which allows reconstructing the used public key. // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. diff --git a/src/main.cpp b/src/main.cpp index 15c3916a6f..55485c86ff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -17,6 +17,7 @@ #include "txmempool.h" #include "ui_interface.h" #include "util.h" +#include "utilmoneystr.h" #include <sstream> @@ -391,72 +392,19 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals) nodeSignals.FinalizeNode.disconnect(&FinalizeNode); } -////////////////////////////////////////////////////////////////////////////// -// -// CChain implementation -// - -CBlockIndex *CChain::SetTip(CBlockIndex *pindex) { - if (pindex == NULL) { - vChain.clear(); - return NULL; - } - vChain.resize(pindex->nHeight + 1); - while (pindex && vChain[pindex->nHeight] != pindex) { - vChain[pindex->nHeight] = pindex; - pindex = pindex->pprev; - } - return pindex; -} - -CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { - int nStep = 1; - std::vector<uint256> vHave; - vHave.reserve(32); - - if (!pindex) - pindex = Tip(); - while (pindex) { - vHave.push_back(pindex->GetBlockHash()); - // Stop when we have added the genesis block. - if (pindex->nHeight == 0) - break; - // Exponentially larger steps back, plus the genesis block. - int nHeight = std::max(pindex->nHeight - nStep, 0); - if (Contains(pindex)) { - // Use O(1) CChain index if possible. - pindex = (*this)[nHeight]; - } else { - // Otherwise, use O(log n) skiplist. - pindex = pindex->GetAncestor(nHeight); - } - if (vHave.size() > 10) - nStep *= 2; - } - - return CBlockLocator(vHave); -} - -CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const { +CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) +{ // Find the first block the caller has in the main chain BOOST_FOREACH(const uint256& hash, locator.vHave) { BlockMap::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex* pindex = (*mi).second; - if (Contains(pindex)) + if (chain.Contains(pindex)) return pindex; } } - return Genesis(); -} - -const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { - if (pindex->nHeight > Height()) - pindex = pindex->GetAncestor(Height()); - while (pindex && !Contains(pindex)) - pindex = pindex->pprev; - return pindex; + return chain.Genesis(); } CCoinsViewCache *pcoinsTip = NULL; @@ -781,7 +729,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values - int64_t nValueOut = 0; + CAmount nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { if (txout.nValue < 0) @@ -823,19 +771,19 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) return true; } -int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) +CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) { { LOCK(mempool.cs); uint256 hash = tx.GetHash(); double dPriorityDelta = 0; - int64_t nFeeDelta = 0; + CAmount nFeeDelta = 0; mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); if (dPriorityDelta > 0 || nFeeDelta > 0) return 0; } - int64_t nMinFee = ::minRelayTxFee.GetFee(nBytes); + CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes); if (fAllowFree) { @@ -898,7 +846,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa CCoinsView dummy; CCoinsViewCache view(dummy); - int64_t nValueIn = 0; + CAmount nValueIn = 0; { LOCK(pool.cs); CCoinsViewMemPool viewMemPool(*pcoinsTip, pool); @@ -950,15 +898,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa hash.ToString(), nSigOps, MAX_TX_SIGOPS), REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); - int64_t nValueOut = tx.GetValueOut(); - int64_t nFees = nValueIn-nValueOut; + CAmount nValueOut = tx.GetValueOut(); + CAmount nFees = nValueIn-nValueOut; double dPriority = view.GetPriority(tx, chainActive.Height()); CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height()); unsigned int nSize = entry.GetTxSize(); // Don't accept it if it can't get into a block - int64_t txMinFee = GetMinRelayFee(tx, nSize, true); + CAmount txMinFee = GetMinRelayFee(tx, nSize, true); if (fLimitFree && nFees < txMinFee) return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d", hash.ToString(), nFees, txMinFee), @@ -1082,7 +1030,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) { // Open history file to append - CAutoFile fileout = CAutoFile(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); + CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); if (!fileout) return error("WriteBlockToDisk : OpenBlockFile failed"); @@ -1110,7 +1058,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) block.SetNull(); // Open history file to read - CAutoFile filein = CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); + CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); if (!filein) return error("ReadBlockFromDisk : OpenBlockFile failed"); @@ -1178,7 +1126,7 @@ void static PruneOrphanBlocks() mapOrphanBlocks.erase(hash); } -int64_t GetBlockValue(int nHeight, int64_t nFees) +CAmount GetBlockValue(int nHeight, const CAmount& nFees) { int64_t nSubsidy = 50 * COIN; int halvings = nHeight / Params().SubsidyHalvingInterval(); @@ -1369,7 +1317,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool CScriptCheck::operator()() const { const CScript &scriptSig = ptxTo->vin[nIn].scriptSig; if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags)) - return error("CScriptCheck() : %s VerifySignature failed", ptxTo->GetHash().ToString()); + return error("CScriptCheck() : %s:%d VerifySignature failed", ptxTo->GetHash().ToString(), nIn); return true; } @@ -1389,8 +1337,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // This is also true for mempool checks. CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; int nSpendHeight = pindexPrev->nHeight + 1; - int64_t nValueIn = 0; - int64_t nFees = 0; + CAmount nValueIn = 0; + CAmount nFees = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; @@ -1414,11 +1362,12 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi } if (nValueIn < tx.GetValueOut()) - return state.DoS(100, error("CheckInputs() : %s value in < value out", tx.GetHash().ToString()), + return state.DoS(100, error("CheckInputs() : %s value in (%s) < value out (%s)", + tx.GetHash().ToString(), FormatMoney(nValueIn), FormatMoney(tx.GetValueOut())), REJECT_INVALID, "bad-txns-in-belowout"); // Tally transaction fees - int64_t nTxFee = nValueIn - tx.GetValueOut(); + CAmount nTxFee = nValueIn - tx.GetValueOut(); if (nTxFee < 0) return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()), REJECT_INVALID, "bad-txns-fee-negative"); @@ -1658,7 +1607,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); int64_t nTimeStart = GetTimeMicros(); - int64_t nFees = 0; + CAmount nFees = 0; int nInputs = 0; unsigned int nSigOps = 0; CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())); @@ -2289,13 +2238,12 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo if (!CheckTransaction(tx, state)) return error("CheckBlock() : CheckTransaction failed"); - // Check for duplicate txids. This is caught by ConnectInputs(), - // but catching it earlier avoids a potential DoS attack: - set<uint256> uniqueTx; - BOOST_FOREACH(const CTransaction &tx, block.vtx) { - uniqueTx.insert(tx.GetHash()); - } - if (uniqueTx.size() != block.vtx.size()) + // Check for merkle tree malleability (CVE-2012-2459): repeating sequences + // of transactions in a block without affecting the merkle root of a block, + // while still invalidating it. + bool mutated; + uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated); + if (mutated) return state.DoS(100, error("CheckBlock() : duplicate transaction"), REJECT_INVALID, "bad-txns-duplicate", true); @@ -2309,7 +2257,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo REJECT_INVALID, "bad-blk-sigops", true); // Check merkle root - if (fCheckMerkleRoot && block.hashMerkleRoot != block.BuildMerkleTree()) + if (fCheckMerkleRoot && block.hashMerkleRoot != hashMerkleRoot2) return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"), REJECT_INVALID, "bad-txnmrklroot", true); @@ -2357,7 +2305,8 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex nHeight = pindexPrev->nHeight+1; // Check proof of work - if (block.nBits != GetNextWorkRequired(pindexPrev, &block)) + if ((!Params().SkipProofOfWorkCheck()) && + (block.nBits != GetNextWorkRequired(pindexPrev, &block))) return state.DoS(100, error("AcceptBlock() : incorrect proof of work"), REJECT_INVALID, "bad-diffbits"); @@ -3709,7 +3658,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); // Find the last block the caller has in the main chain - CBlockIndex* pindex = chainActive.FindFork(locator); + CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator); // Send the rest of the chain if (pindex) @@ -3756,7 +3705,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else { // Find the last block the caller has in the main chain - pindex = chainActive.FindFork(locator); + pindex = FindForkInGlobalIndex(chainActive, locator); if (pindex) pindex = chainActive.Next(pindex); } @@ -4503,7 +4452,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) { // Open history file to append - CAutoFile fileout = CAutoFile(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); + CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); if (!fileout) return error("CBlockUndo::WriteToDisk : OpenUndoFile failed"); @@ -4535,7 +4484,7 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock) { // Open history file to read - CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); + CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); if (!filein) return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed"); diff --git a/src/main.h b/src/main.h index 5acc551793..7e849505dd 100644 --- a/src/main.h +++ b/src/main.h @@ -10,6 +10,7 @@ #include "config/bitcoin-config.h" #endif +#include "chain.h" #include "chainparams.h" #include "coins.h" #include "core.h" @@ -113,7 +114,6 @@ static const uint64_t nMinDiskSpace = 52428800; class CBlockTreeDB; -struct CDiskBlockPos; class CTxUndo; class CScriptCheck; class CValidationState; @@ -172,7 +172,7 @@ std::string GetWarnings(std::string strFor); bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ bool ActivateBestChain(CValidationState &state, CBlock *pblock = NULL); -int64_t GetBlockValue(int nHeight, int64_t nFees); +CAmount GetBlockValue(int nHeight, const CAmount& nFees); /** Create a new block index entry for a given block hash */ CBlockIndex * InsertBlockIndex(uint256 hash); @@ -189,51 +189,11 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa bool* pfMissingInputs, bool fRejectInsaneFee=false); - - - - - - struct CNodeStateStats { int nMisbehavior; int nSyncHeight; }; -struct CDiskBlockPos -{ - int nFile; - unsigned int nPos; - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - READWRITE(VARINT(nFile)); - READWRITE(VARINT(nPos)); - } - - CDiskBlockPos() { - SetNull(); - } - - CDiskBlockPos(int nFileIn, unsigned int nPosIn) { - nFile = nFileIn; - nPos = nPosIn; - } - - friend bool operator==(const CDiskBlockPos &a, const CDiskBlockPos &b) { - return (a.nFile == b.nFile && a.nPos == b.nPos); - } - - friend bool operator!=(const CDiskBlockPos &a, const CDiskBlockPos &b) { - return !(a == b); - } - - void SetNull() { nFile = -1; nPos = 0; } - bool IsNull() const { return (nFile == -1); } -}; - struct CDiskTxPos : public CDiskBlockPos { unsigned int nTxOffset; // after header @@ -260,7 +220,7 @@ struct CDiskTxPos : public CDiskBlockPos }; -int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); +CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree); // // Check transaction inputs, and make sure any @@ -545,288 +505,6 @@ public: } }; -enum BlockStatus { - BLOCK_VALID_UNKNOWN = 0, - BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future - BLOCK_VALID_TREE = 2, // parent found, difficulty matches, timestamp >= median previous, checkpoint - BLOCK_VALID_TRANSACTIONS = 3, // only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid, no duplicate txids, sigops, size, merkle root - BLOCK_VALID_CHAIN = 4, // outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends, BIP30 - BLOCK_VALID_SCRIPTS = 5, // scripts/signatures ok - BLOCK_VALID_MASK = BLOCK_VALID_HEADER | BLOCK_VALID_TREE | BLOCK_VALID_TRANSACTIONS | - BLOCK_VALID_CHAIN | BLOCK_VALID_SCRIPTS, - - BLOCK_HAVE_DATA = 8, // full block available in blk*.dat - BLOCK_HAVE_UNDO = 16, // undo data available in rev*.dat - BLOCK_HAVE_MASK = BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO, - - BLOCK_FAILED_VALID = 32, // stage after last reached validness failed - BLOCK_FAILED_CHILD = 64, // descends from failed block - BLOCK_FAILED_MASK = BLOCK_FAILED_VALID | BLOCK_FAILED_CHILD, -}; - -/** The block chain is a tree shaped structure starting with the - * genesis block at the root, with each block potentially having multiple - * candidates to be the next block. A blockindex may have multiple pprev pointing - * to it, but at most one of them can be part of the currently active branch. - */ -class CBlockIndex -{ -public: - // pointer to the hash of the block, if any. memory is owned by this CBlockIndex - const uint256* phashBlock; - - // pointer to the index of the predecessor of this block - CBlockIndex* pprev; - - // pointer to the index of some further predecessor of this block - CBlockIndex* pskip; - - // height of the entry in the chain. The genesis block has height 0 - int nHeight; - - // Which # file this block is stored in (blk?????.dat) - int nFile; - - // Byte offset within blk?????.dat where this block's data is stored - unsigned int nDataPos; - - // Byte offset within rev?????.dat where this block's undo data is stored - unsigned int nUndoPos; - - // (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block - uint256 nChainWork; - - // Number of transactions in this block. - // Note: in a potential headers-first mode, this number cannot be relied upon - unsigned int nTx; - - // (memory only) Number of transactions in the chain up to and including this block - unsigned int nChainTx; // change to 64-bit type when necessary; won't happen before 2030 - - // Verification status of this block. See enum BlockStatus - unsigned int nStatus; - - // block header - int nVersion; - uint256 hashMerkleRoot; - unsigned int nTime; - unsigned int nBits; - unsigned int nNonce; - - // (memory only) Sequencial id assigned to distinguish order in which blocks are received. - uint32_t nSequenceId; - - void SetNull() - { - phashBlock = NULL; - pprev = NULL; - pskip = NULL; - nHeight = 0; - nFile = 0; - nDataPos = 0; - nUndoPos = 0; - nChainWork = 0; - nTx = 0; - nChainTx = 0; - nStatus = 0; - nSequenceId = 0; - - nVersion = 0; - hashMerkleRoot = 0; - nTime = 0; - nBits = 0; - nNonce = 0; - } - - CBlockIndex() - { - SetNull(); - } - - CBlockIndex(CBlockHeader& block) - { - SetNull(); - - nVersion = block.nVersion; - hashMerkleRoot = block.hashMerkleRoot; - nTime = block.nTime; - nBits = block.nBits; - nNonce = block.nNonce; - } - - CDiskBlockPos GetBlockPos() const { - CDiskBlockPos ret; - if (nStatus & BLOCK_HAVE_DATA) { - ret.nFile = nFile; - ret.nPos = nDataPos; - } - return ret; - } - - CDiskBlockPos GetUndoPos() const { - CDiskBlockPos ret; - if (nStatus & BLOCK_HAVE_UNDO) { - ret.nFile = nFile; - ret.nPos = nUndoPos; - } - return ret; - } - - CBlockHeader GetBlockHeader() const - { - CBlockHeader block; - block.nVersion = nVersion; - if (pprev) - block.hashPrevBlock = pprev->GetBlockHash(); - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block; - } - - uint256 GetBlockHash() const - { - return *phashBlock; - } - - int64_t GetBlockTime() const - { - return (int64_t)nTime; - } - - uint256 GetBlockWork() const - { - return GetProofIncrement(nBits); - } - - enum { nMedianTimeSpan=11 }; - - int64_t GetMedianTimePast() const - { - int64_t pmedian[nMedianTimeSpan]; - int64_t* pbegin = &pmedian[nMedianTimeSpan]; - int64_t* pend = &pmedian[nMedianTimeSpan]; - - const CBlockIndex* pindex = this; - for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev) - *(--pbegin) = pindex->GetBlockTime(); - - std::sort(pbegin, pend); - return pbegin[(pend - pbegin)/2]; - } - - /** - * Returns true if there are nRequired or more blocks of minVersion or above - * in the last Params().ToCheckBlockUpgradeMajority() blocks, starting at pstart - * and going backwards. - */ - static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, - unsigned int nRequired); - - std::string ToString() const - { - return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", - pprev, nHeight, - hashMerkleRoot.ToString(), - GetBlockHash().ToString()); - } - - // Check whether this block index entry is valid up to the passed validity level. - bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const - { - assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. - if (nStatus & BLOCK_FAILED_MASK) - return false; - return ((nStatus & BLOCK_VALID_MASK) >= nUpTo); - } - - // Raise the validity level of this block index entry. - // Returns true if the validity was changed. - bool RaiseValidity(enum BlockStatus nUpTo) - { - assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed. - if (nStatus & BLOCK_FAILED_MASK) - return false; - if ((nStatus & BLOCK_VALID_MASK) < nUpTo) { - nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo; - return true; - } - return false; - } - - // Build the skiplist pointer for this entry. - void BuildSkip(); - - // Efficiently find an ancestor of this block. - CBlockIndex* GetAncestor(int height); - const CBlockIndex* GetAncestor(int height) const; -}; - -/** Used to marshal pointers into hashes for db storage. */ -class CDiskBlockIndex : public CBlockIndex -{ -public: - uint256 hashPrev; - - CDiskBlockIndex() { - hashPrev = 0; - } - - explicit CDiskBlockIndex(CBlockIndex* pindex) : CBlockIndex(*pindex) { - hashPrev = (pprev ? pprev->GetBlockHash() : 0); - } - - ADD_SERIALIZE_METHODS; - - template <typename Stream, typename Operation> - inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { - if (!(nType & SER_GETHASH)) - READWRITE(VARINT(nVersion)); - - READWRITE(VARINT(nHeight)); - READWRITE(VARINT(nStatus)); - READWRITE(VARINT(nTx)); - if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO)) - READWRITE(VARINT(nFile)); - if (nStatus & BLOCK_HAVE_DATA) - READWRITE(VARINT(nDataPos)); - if (nStatus & BLOCK_HAVE_UNDO) - READWRITE(VARINT(nUndoPos)); - - // block header - READWRITE(this->nVersion); - READWRITE(hashPrev); - READWRITE(hashMerkleRoot); - READWRITE(nTime); - READWRITE(nBits); - READWRITE(nNonce); - } - - uint256 GetBlockHash() const - { - CBlockHeader block; - block.nVersion = nVersion; - block.hashPrevBlock = hashPrev; - block.hashMerkleRoot = hashMerkleRoot; - block.nTime = nTime; - block.nBits = nBits; - block.nNonce = nNonce; - return block.GetHash(); - } - - - std::string ToString() const - { - std::string str = "CDiskBlockIndex("; - str += CBlockIndex::ToString(); - str += strprintf("\n hashBlock=%s, hashPrev=%s)", - GetBlockHash().ToString(), - hashPrev.ToString()); - return str; - } -}; - /** Capture information about block/transaction validation */ class CValidationState { private: @@ -898,65 +576,8 @@ public: bool VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth); }; -/** An in-memory indexed chain of blocks. */ -class CChain { -private: - std::vector<CBlockIndex*> vChain; - -public: - /** Returns the index entry for the genesis block of this chain, or NULL if none. */ - CBlockIndex *Genesis() const { - return vChain.size() > 0 ? vChain[0] : NULL; - } - - /** Returns the index entry for the tip of this chain, or NULL if none. */ - CBlockIndex *Tip() const { - return vChain.size() > 0 ? vChain[vChain.size() - 1] : NULL; - } - - /** Returns the index entry at a particular height in this chain, or NULL if no such height exists. */ - CBlockIndex *operator[](int nHeight) const { - if (nHeight < 0 || nHeight >= (int)vChain.size()) - return NULL; - return vChain[nHeight]; - } - - /** Compare two chains efficiently. */ - friend bool operator==(const CChain &a, const CChain &b) { - return a.vChain.size() == b.vChain.size() && - a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1]; - } - - /** Efficiently check whether a block is present in this chain. */ - bool Contains(const CBlockIndex *pindex) const { - return (*this)[pindex->nHeight] == pindex; - } - - /** Find the successor of a block in this chain, or NULL if the given index is not found or is the tip. */ - CBlockIndex *Next(const CBlockIndex *pindex) const { - if (Contains(pindex)) - return (*this)[pindex->nHeight + 1]; - else - return NULL; - } - - /** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */ - int Height() const { - return vChain.size() - 1; - } - - /** Set/initialize a chain with a given tip. Returns the forking point. */ - CBlockIndex *SetTip(CBlockIndex *pindex); - - /** Return a CBlockLocator that refers to a block in this chain (by default the tip). */ - CBlockLocator GetLocator(const CBlockIndex *pindex = NULL) const; - - /** Find the last common block between this chain and a locator. */ - CBlockIndex *FindFork(const CBlockLocator &locator) const; - - /** Find the last common block between this chain and a block index entry. */ - const CBlockIndex *FindFork(const CBlockIndex *pindex) const; -}; +/** Find the last common block between the parameter chain and a locator. */ +CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); /** The currently-connected chain of blocks. */ extern CChain chainActive; @@ -970,7 +591,7 @@ extern CBlockTreeDB *pblocktree; struct CBlockTemplate { CBlock block; - std::vector<int64_t> vTxFees; + std::vector<CAmount> vTxFees; std::vector<int64_t> vTxSigOps; }; diff --git a/src/miner.cpp b/src/miner.cpp index d05ddbeb1f..361a2bea41 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -111,7 +111,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize); // Collect memory pool transactions into the block - int64_t nFees = 0; + CAmount nFees = 0; { LOCK2(cs_main, mempool.cs); @@ -135,7 +135,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) COrphan* porphan = NULL; double dPriority = 0; - int64_t nTotalIn = 0; + CAmount nTotalIn = 0; bool fMissingInputs = false; BOOST_FOREACH(const CTxIn& txin, tx.vin) { @@ -170,7 +170,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) const CCoins* coins = view.AccessCoins(txin.prevout.hash); assert(coins); - int64_t nValueIn = coins->vout[txin.prevout.n].nValue; + CAmount nValueIn = coins->vout[txin.prevout.n].nValue; nTotalIn += nValueIn; int nConf = pindexPrev->nHeight - coins->nHeight + 1; @@ -229,7 +229,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) // Skip free transactions if we're past the minimum block size: const uint256& hash = tx.GetHash(); double dPriorityDelta = 0; - int64_t nFeeDelta = 0; + CAmount nFeeDelta = 0; mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize)) continue; @@ -247,7 +247,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) if (!view.HaveInputs(tx)) continue; - int64_t nTxFees = view.GetValueIn(tx)-tx.GetValueOut(); + CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut(); nTxSigOps += GetP2SHSigOpCount(tx, view); if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) diff --git a/src/net.cpp b/src/net.cpp index ab547e2fd7..866bac2c0e 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1957,7 +1957,7 @@ bool CAddrDB::Write(const CAddrMan& addr) // open temp output file, and associate with CAutoFile boost::filesystem::path pathTmp = GetDataDir() / tmpfn; FILE *file = fopen(pathTmp.string().c_str(), "wb"); - CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); + CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); if (!fileout) return error("%s : Failed to open file %s", __func__, pathTmp.string()); @@ -1982,7 +1982,7 @@ bool CAddrDB::Read(CAddrMan& addr) { // open input file, and associate with CAutoFile FILE *file = fopen(pathAddr.string().c_str(), "rb"); - CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); if (!filein) return error("%s : Failed to open file %s", __func__, pathAddr.string()); diff --git a/src/pow.cpp b/src/pow.cpp index 893f6c18be..d50222849c 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -81,6 +81,10 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) bool fNegative; bool fOverflow; uint256 bnTarget; + + if (Params().SkipProofOfWorkCheck()) + return true; + bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range diff --git a/src/protocol.cpp b/src/protocol.cpp index 341de0602a..0e28f3abbd 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -24,7 +24,6 @@ CMessageHeader::CMessageHeader() { memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE); memset(pchCommand, 0, sizeof(pchCommand)); - pchCommand[1] = 1; nMessageSize = -1; nChecksum = 0; } @@ -32,6 +31,7 @@ CMessageHeader::CMessageHeader() CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn) { memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE); + memset(pchCommand, 0, sizeof(pchCommand)); strncpy(pchCommand, pszCommand, COMMAND_SIZE); nMessageSize = nMessageSizeIn; nChecksum = 0; @@ -39,10 +39,7 @@ CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSize std::string CMessageHeader::GetCommand() const { - if (pchCommand[COMMAND_SIZE-1] == 0) - return std::string(pchCommand, pchCommand + strlen(pchCommand)); - else - return std::string(pchCommand, pchCommand + COMMAND_SIZE); + return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE)); } bool CMessageHeader::IsValid() const diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index bd686041c1..5e2fdc6c30 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -73,6 +73,7 @@ Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); // Declare meta types used for QMetaObject::invokeMethod Q_DECLARE_METATYPE(bool*) +Q_DECLARE_METATYPE(CAmount) static void InitMessage(const std::string &message) { @@ -509,6 +510,9 @@ int main(int argc, char *argv[]) // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType< bool* >(); + // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) + // IMPORTANT if it is no longer a typedef use the normal variant above + qRegisterMetaType< CAmount >("CAmount"); /// 3. Application identification // must be set before OptionsModel is initialized or translations are loaded, diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp index 6466039013..6e35bf17b3 100644 --- a/src/qt/bitcoinamountfield.cpp +++ b/src/qt/bitcoinamountfield.cpp @@ -44,7 +44,7 @@ public: void fixup(QString &input) const { bool valid = false; - qint64 val = parse(input, &valid); + CAmount val = parse(input, &valid); if(valid) { input = BitcoinUnits::format(currentUnit, val, false, BitcoinUnits::separatorAlways); @@ -52,12 +52,12 @@ public: } } - qint64 value(bool *valid_out=0) const + CAmount value(bool *valid_out=0) const { return parse(text(), valid_out); } - void setValue(qint64 value) + void setValue(const CAmount& value) { lineEdit()->setText(BitcoinUnits::format(currentUnit, value, false, BitcoinUnits::separatorAlways)); emit valueChanged(); @@ -66,9 +66,9 @@ public: void stepBy(int steps) { bool valid = false; - qint64 val = value(&valid); + CAmount val = value(&valid); val = val + steps * singleStep; - val = qMin(qMax(val, Q_INT64_C(0)), BitcoinUnits::maxMoney()); + val = qMin(qMax(val, CAmount(0)), BitcoinUnits::maxMoney()); setValue(val); } @@ -78,7 +78,7 @@ public: if(text().isEmpty()) // Allow step-up with empty field return StepUpEnabled; bool valid = false; - qint64 val = value(&valid); + CAmount val = value(&valid); if(valid) { if(val > 0) @@ -92,7 +92,7 @@ public: void setDisplayUnit(int unit) { bool valid = false; - qint64 val = value(&valid); + CAmount val = value(&valid); currentUnit = unit; @@ -102,7 +102,7 @@ public: clear(); } - void setSingleStep(qint64 step) + void setSingleStep(const CAmount& step) { singleStep = step; } @@ -140,7 +140,7 @@ public: } private: int currentUnit; - qint64 singleStep; + CAmount singleStep; mutable QSize cachedMinimumSizeHint; /** @@ -148,9 +148,9 @@ private: * return validity. * @note Must return 0 if !valid. */ - qint64 parse(const QString &text, bool *valid_out=0) const + CAmount parse(const QString &text, bool *valid_out=0) const { - qint64 val = 0; + CAmount val = 0; bool valid = BitcoinUnits::parse(currentUnit, text, &val); if(valid) { @@ -253,12 +253,12 @@ QWidget *BitcoinAmountField::setupTabChain(QWidget *prev) return unit; } -qint64 BitcoinAmountField::value(bool *valid_out) const +CAmount BitcoinAmountField::value(bool *valid_out) const { return amount->value(valid_out); } -void BitcoinAmountField::setValue(qint64 value) +void BitcoinAmountField::setValue(const CAmount& value) { amount->setValue(value); } @@ -285,7 +285,7 @@ void BitcoinAmountField::setDisplayUnit(int newUnit) unit->setValue(newUnit); } -void BitcoinAmountField::setSingleStep(qint64 step) +void BitcoinAmountField::setSingleStep(const CAmount& step) { amount->setSingleStep(step); } diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h index 84795a7e7a..e52feeb46e 100644 --- a/src/qt/bitcoinamountfield.h +++ b/src/qt/bitcoinamountfield.h @@ -5,6 +5,8 @@ #ifndef BITCOINAMOUNTFIELD_H #define BITCOINAMOUNTFIELD_H +#include "amount.h" + #include <QWidget> class AmountSpinBox; @@ -19,16 +21,16 @@ class BitcoinAmountField: public QWidget { Q_OBJECT - Q_PROPERTY(qint64 value READ value WRITE setValue NOTIFY valueChanged USER true) + Q_PROPERTY(CAmount value READ value WRITE setValue NOTIFY valueChanged USER true) public: explicit BitcoinAmountField(QWidget *parent = 0); - qint64 value(bool *valid=0) const; - void setValue(qint64 value); + CAmount value(bool *value=0) const; + void setValue(const CAmount& value); /** Set single step in satoshis **/ - void setSingleStep(qint64 step); + void setSingleStep(const CAmount& step); /** Make read-only **/ void setReadOnly(bool fReadOnly); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 443bed14d7..7380fbd240 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -864,7 +864,7 @@ void BitcoinGUI::closeEvent(QCloseEvent *event) } #ifdef ENABLE_WALLET -void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address) +void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address) { // On new transaction, make an info balloon message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"), diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 30b05cb7d9..8af6eda867 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -9,6 +9,8 @@ #include "config/bitcoin-config.h" #endif +#include "amount.h" + #include <QLabel> #include <QMainWindow> #include <QMap> @@ -159,7 +161,7 @@ public slots: bool handlePaymentRequest(const SendCoinsRecipient& recipient); /** Show incoming transaction notification for new transactions. */ - void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address); + void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address); #endif private slots: diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp index 3215363fa0..423b559bf7 100644 --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -91,12 +91,13 @@ int BitcoinUnits::decimals(int unit) } } -QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle separators) +QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators) { // Note: not using straight sprintf here because we do NOT want // localized number formatting. if(!valid(unit)) return QString(); // Refuse to format invalid unit + qint64 n = (qint64)nIn; qint64 coin = factor(unit); int num_decimals = decimals(unit); qint64 n_abs = (n > 0 ? n : -n); @@ -138,12 +139,12 @@ QString BitcoinUnits::format(int unit, qint64 n, bool fPlus, SeparatorStyle sepa // Please take care to use formatHtmlWithUnit instead, when // appropriate. -QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators) +QString BitcoinUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators) { return format(unit, amount, plussign, separators) + QString(" ") + name(unit); } -QString BitcoinUnits::formatHtmlWithUnit(int unit, qint64 amount, bool plussign, SeparatorStyle separators) +QString BitcoinUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators) { QString str(formatWithUnit(unit, amount, plussign, separators)); str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML)); @@ -151,7 +152,7 @@ QString BitcoinUnits::formatHtmlWithUnit(int unit, qint64 amount, bool plussign, } -bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out) +bool BitcoinUnits::parse(int unit, const QString &value, CAmount *val_out) { if(!valid(unit) || value.isEmpty()) return false; // Refuse to parse invalid unit or empty string @@ -182,7 +183,7 @@ bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out) { return false; // Longer numbers will exceed 63 bits } - qint64 retvalue = str.toLongLong(&ok); + CAmount retvalue(str.toLongLong(&ok)); if(val_out) { *val_out = retvalue; @@ -226,7 +227,7 @@ QVariant BitcoinUnits::data(const QModelIndex &index, int role) const return QVariant(); } -qint64 BitcoinUnits::maxMoney() +CAmount BitcoinUnits::maxMoney() { return MAX_MONEY; } diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h index be9dca6012..a392c42b9b 100644 --- a/src/qt/bitcoinunits.h +++ b/src/qt/bitcoinunits.h @@ -5,6 +5,8 @@ #ifndef BITCOINUNITS_H #define BITCOINUNITS_H +#include "amount.h" + #include <QAbstractListModel> #include <QString> @@ -85,12 +87,12 @@ public: //! Number of decimals left static int decimals(int unit); //! Format as string - static QString format(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + static QString format(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Format as string (with unit) - static QString formatWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard); - static QString formatHtmlWithUnit(int unit, qint64 amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); + static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard); //! Parse string to coin amount - static bool parse(int unit, const QString &value, qint64 *val_out); + static bool parse(int unit, const QString &value, CAmount *val_out); //! Gets title for amount column including current display unit if optionsModel reference available */ static QString getAmountColumnTitle(int unit); ///@} @@ -117,7 +119,7 @@ public: } //! Return maximum number of base units (Satoshis) - static qint64 maxMoney(); + static CAmount maxMoney(); private: QList<BitcoinUnits::Unit> unitlist; diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index d10463fd8f..ba0febe546 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -29,7 +29,7 @@ #include <QTreeWidgetItem> using namespace std; -QList<qint64> CoinControlDialog::payAmounts; +QList<CAmount> CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); CoinControlDialog::CoinControlDialog(QWidget *parent) : @@ -443,10 +443,10 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) return; // nPayAmount - qint64 nPayAmount = 0; + CAmount nPayAmount = 0; bool fDust = false; CMutableTransaction txDummy; - foreach(const qint64 &amount, CoinControlDialog::payAmounts) + foreach(const CAmount &amount, CoinControlDialog::payAmounts) { nPayAmount += amount; @@ -460,10 +460,10 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) } QString sPriorityLabel = tr("none"); - int64_t nAmount = 0; - int64_t nPayFee = 0; - int64_t nAfterFee = 0; - int64_t nChange = 0; + CAmount nAmount = 0; + CAmount nPayFee = 0; + CAmount nAfterFee = 0; + CAmount nChange = 0; unsigned int nBytes = 0; unsigned int nBytesInputs = 0; double dPriority = 0; @@ -684,7 +684,7 @@ void CoinControlDialog::updateView() itemWalletAddress->setText(COLUMN_ADDRESS, sWalletAddress); } - int64_t nSum = 0; + CAmount nSum = 0; double dPrioritySum = 0; int nChildren = 0; int nInputSum = 0; diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index a6f239a898..9eaa8eb41d 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -5,6 +5,8 @@ #ifndef COINCONTROLDIALOG_H #define COINCONTROLDIALOG_H +#include "amount.h" + #include <QAbstractButton> #include <QAction> #include <QDialog> @@ -37,7 +39,7 @@ public: static void updateLabels(WalletModel*, QDialog*); static QString getPriorityLabel(const CTxMemPool& pool, double); - static QList<qint64> payAmounts; + static QList<CAmount> payAmounts; static CCoinControl *coinControl; private: diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index fc22871a6b..91bb10755a 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -221,7 +221,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info) return ret; } -bool isDust(const QString& address, qint64 amount) +bool isDust(const QString& address, const CAmount& amount) { CTxDestination dest = CBitcoinAddress(address.toStdString()).Get(); CScript script = GetScriptForDestination(dest); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 67e11e59a0..0939c78f64 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -5,6 +5,8 @@ #ifndef GUIUTIL_H #define GUIUTIL_H +#include "amount.h" + #include <QHeaderView> #include <QMessageBox> #include <QObject> @@ -46,7 +48,7 @@ namespace GUIUtil QString formatBitcoinURI(const SendCoinsRecipient &info); // Returns true if given address+amount meets "dust" definition - bool isDust(const QString& address, qint64 amount); + bool isDust(const QString& address, const CAmount& amount); // HTML escaping for rich text controls QString HtmlEscape(const QString& str, bool fMultiLine=false); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index bd747faeb6..cb80bd0e3d 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -275,9 +275,9 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in #ifdef ENABLE_WALLET case Fee: { // core option - can be changed on-the-fly // Todo: Add is valid check and warn via message, if not - qint64 nTransactionFee = value.toLongLong(); + CAmount nTransactionFee(value.toLongLong()); payTxFee = CFeeRate(nTransactionFee, 1000); - settings.setValue("nTransactionFee", nTransactionFee); + settings.setValue("nTransactionFee", qint64(nTransactionFee)); emit transactionFeeChanged(nTransactionFee); break; } diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 80adab89c8..42ea3bf8e5 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -5,6 +5,8 @@ #ifndef OPTIONSMODEL_H #define OPTIONSMODEL_H +#include "amount.h" + #include <QAbstractListModel> QT_BEGIN_NAMESPACE @@ -82,7 +84,7 @@ private: signals: void displayUnitChanged(int unit); - void transactionFeeChanged(qint64); + void transactionFeeChanged(const CAmount&); void coinControlFeaturesChanged(bool); }; diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 90762bea5d..669d5474fd 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -146,7 +146,7 @@ OverviewPage::~OverviewPage() delete ui; } -void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance) +void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance) { int unit = walletModel->getOptionsModel()->getDisplayUnit(); currentBalance = balance; @@ -220,7 +220,7 @@ void OverviewPage::setWalletModel(WalletModel *model) // Keep up to date with wallet setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); - connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64, qint64, qint64))); + connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount))); connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index f46374efba..03f239008f 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -5,6 +5,8 @@ #ifndef OVERVIEWPAGE_H #define OVERVIEWPAGE_H +#include "amount.h" + #include <QWidget> class ClientModel; @@ -34,8 +36,8 @@ public: void showOutOfSyncWarning(bool fShow); public slots: - void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance); + void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); signals: void transactionClicked(const QModelIndex &index); @@ -44,12 +46,12 @@ private: Ui::OverviewPage *ui; ClientModel *clientModel; WalletModel *walletModel; - qint64 currentBalance; - qint64 currentUnconfirmedBalance; - qint64 currentImmatureBalance; - qint64 currentWatchOnlyBalance; - qint64 currentWatchUnconfBalance; - qint64 currentWatchImmatureBalance; + CAmount currentBalance; + CAmount currentUnconfirmedBalance; + CAmount currentImmatureBalance; + CAmount currentWatchOnlyBalance; + CAmount currentWatchUnconfBalance; + CAmount currentWatchImmatureBalance; TxViewDelegate *txdelegate; TransactionFilterProxy *filter; diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp index 7b7de49831..7aefffe24a 100644 --- a/src/qt/paymentrequestplus.cpp +++ b/src/qt/paymentrequestplus.cpp @@ -196,9 +196,9 @@ bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) c return fResult; } -QList<std::pair<CScript,qint64> > PaymentRequestPlus::getPayTo() const +QList<std::pair<CScript,CAmount> > PaymentRequestPlus::getPayTo() const { - QList<std::pair<CScript,qint64> > result; + QList<std::pair<CScript,CAmount> > result; for (int i = 0; i < details.outputs_size(); i++) { const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data(); diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h index 3c4861a4d4..3d94d93269 100644 --- a/src/qt/paymentrequestplus.h +++ b/src/qt/paymentrequestplus.h @@ -33,7 +33,7 @@ public: bool getMerchant(X509_STORE* certStore, QString& merchant) const; // Returns list of outputs, amount - QList<std::pair<CScript,qint64> > getPayTo() const; + QList<std::pair<CScript,CAmount> > getPayTo() const; const payments::PaymentDetails& getDetails() const { return details; } diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index cc4478f39f..707de55290 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -532,10 +532,10 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant); - QList<std::pair<CScript, qint64> > sendingTos = request.getPayTo(); + QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo(); QStringList addresses; - foreach(const PAIRTYPE(CScript, qint64)& sendingTo, sendingTos) { + foreach(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { // Extract and check destination addresses CTxDestination dest; if (ExtractDestination(sendingTo.first, dest)) { diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 25e3d2a0dc..ce94131cce 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -92,13 +92,13 @@ void SendCoinsDialog::setModel(WalletModel *model) setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getWatchBalance(), model->getWatchUnconfirmedBalance(), model->getWatchImmatureBalance()); - connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64, qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64, qint64, qint64, qint64))); + connect(model, SIGNAL(balanceChanged(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount)), this, SLOT(setBalance(CAmount,CAmount,CAmount,CAmount,CAmount,CAmount))); connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); // Coin Control connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels())); connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool))); - connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(qint64)), this, SLOT(coinControlUpdateLabels())); + connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(CAmount)), this, SLOT(coinControlUpdateLabels())); ui->frameCoinControl->setVisible(model->getOptionsModel()->getCoinControlFeatures()); coinControlUpdateLabels(); } @@ -203,7 +203,7 @@ void SendCoinsDialog::on_sendButton_clicked() return; } - qint64 txFee = currentTransaction.getTransactionFee(); + CAmount txFee = currentTransaction.getTransactionFee(); QString questionString = tr("Are you sure you want to send?"); questionString.append("<br /><br />%1"); @@ -218,7 +218,7 @@ void SendCoinsDialog::on_sendButton_clicked() // add total amount in all subdivision units questionString.append("<hr />"); - qint64 totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; + CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; QStringList alternativeUnits; foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { @@ -384,8 +384,8 @@ bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv) return true; } -void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchBalance, qint64 watchUnconfirmedBalance, qint64 watchImmatureBalance) +void SendCoinsDialog::setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchBalance, const CAmount& watchUnconfirmedBalance, const CAmount& watchImmatureBalance) { Q_UNUSED(unconfirmedBalance); Q_UNUSED(immatureBalance); diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index a090fa42d5..74cc4bde56 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -47,8 +47,8 @@ public slots: void accept(); SendCoinsEntry *addEntry(); void updateTabsAndLabels(); - void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance); + void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); private: Ui::SendCoinsDialog *ui; diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 4923718341..1efad8259b 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -56,9 +56,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco strHTML += "<html><font face='verdana, arial, helvetica, sans-serif'>"; int64_t nTime = wtx.GetTxTime(); - int64_t nCredit = wtx.GetCredit(ISMINE_ALL); - int64_t nDebit = wtx.GetDebit(ISMINE_ALL); - int64_t nNet = nCredit - nDebit; + CAmount nCredit = wtx.GetCredit(ISMINE_ALL); + CAmount nDebit = wtx.GetDebit(ISMINE_ALL); + CAmount nNet = nCredit - nDebit; strHTML += "<b>" + tr("Status") + ":</b> " + FormatTxStatus(wtx); int nRequests = wtx.GetRequestCount(); @@ -132,7 +132,7 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco // // Coinbase // - int64_t nUnmatured = 0; + CAmount nUnmatured = 0; BOOST_FOREACH(const CTxOut& txout, wtx.vout) nUnmatured += wallet->GetCredit(txout, ISMINE_ALL); strHTML += "<b>" + tr("Credit") + ":</b> "; @@ -206,13 +206,13 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco if (fAllToMe) { // Payment to self - int64_t nChange = wtx.GetChange(); - int64_t nValue = nCredit - nChange; + CAmount nChange = wtx.GetChange(); + CAmount nValue = nCredit - nChange; strHTML += "<b>" + tr("Total debit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nValue) + "<br>"; strHTML += "<b>" + tr("Total credit") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, nValue) + "<br>"; } - int64_t nTxFee = nDebit - wtx.GetValueOut(); + CAmount nTxFee = nDebit - wtx.GetValueOut(); if (nTxFee > 0) strHTML += "<b>" + tr("Transaction fee") + ":</b> " + BitcoinUnits::formatHtmlWithUnit(unit, -nTxFee) + "<br>"; } diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index 6ab029173b..2a0f621d1e 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -78,7 +78,7 @@ void TransactionFilterProxy::setTypeFilter(quint32 modes) invalidateFilter(); } -void TransactionFilterProxy::setMinAmount(qint64 minimum) +void TransactionFilterProxy::setMinAmount(const CAmount& minimum) { this->minAmount = minimum; invalidateFilter(); diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index f408317b53..ca31ee8f87 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -5,6 +5,8 @@ #ifndef TRANSACTIONFILTERPROXY_H #define TRANSACTIONFILTERPROXY_H +#include "amount.h" + #include <QDateTime> #include <QSortFilterProxyModel> @@ -38,7 +40,7 @@ public: @note Type filter takes a bit field created with TYPE() or ALL_TYPES */ void setTypeFilter(quint32 modes); - void setMinAmount(qint64 minimum); + void setMinAmount(const CAmount& minimum); void setWatchOnlyFilter(WatchOnlyFilter filter); /** Set maximum number of rows returned, -1 if unlimited. */ @@ -58,7 +60,7 @@ private: QString addrPrefix; quint32 typeFilter; WatchOnlyFilter watchOnlyFilter; - qint64 minAmount; + CAmount minAmount; int limitRows; bool showInactive; }; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 20c1449c92..afb343f349 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -32,9 +32,9 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * { QList<TransactionRecord> parts; int64_t nTime = wtx.GetTxTime(); - int64_t nCredit = wtx.GetCredit(true); - int64_t nDebit = wtx.GetDebit(ISMINE_ALL); - int64_t nNet = nCredit - nDebit; + CAmount nCredit = wtx.GetCredit(true); + CAmount nDebit = wtx.GetDebit(ISMINE_ALL); + CAmount nNet = nCredit - nDebit; uint256 hash = wtx.GetHash(); std::map<std::string, std::string> mapValue = wtx.mapValue; @@ -97,7 +97,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * if (fAllFromMe && fAllToMe) { // Payment to self - int64_t nChange = wtx.GetChange(); + CAmount nChange = wtx.GetChange(); parts.append(TransactionRecord(hash, nTime, TransactionRecord::SendToSelf, "", -(nDebit - nChange), nCredit - nChange)); @@ -108,7 +108,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * // // Debit // - int64_t nTxFee = nDebit - wtx.GetValueOut(); + CAmount nTxFee = nDebit - wtx.GetValueOut(); for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++) { @@ -138,7 +138,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet * sub.address = mapValue["to"]; } - int64_t nValue = txout.nValue; + CAmount nValue = txout.nValue; /* Add fee to first output */ if (nTxFee > 0) { diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 626b7654c6..9276c9f0af 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -5,6 +5,7 @@ #ifndef TRANSACTIONRECORD_H #define TRANSACTIONRECORD_H +#include "amount.h" #include "uint256.h" #include <QList> @@ -94,7 +95,7 @@ public: TransactionRecord(uint256 hash, qint64 time, Type type, const std::string &address, - qint64 debit, qint64 credit): + const CAmount& debit, const CAmount& credit): hash(hash), time(time), type(type), address(address), debit(debit), credit(credit), idx(0) { @@ -111,8 +112,8 @@ public: qint64 time; Type type; std::string address; - qint64 debit; - qint64 credit; + CAmount debit; + CAmount credit; /**@}*/ /** Subtransaction index, for sort key */ diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 2b869b4ea5..e34d776818 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -546,7 +546,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case ToAddress: return formatTxToAddress(rec, true); case Amount: - return rec->credit + rec->debit; + return qint64(rec->credit + rec->debit); } break; case Qt::ToolTipRole: @@ -583,7 +583,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case LabelRole: return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); case AmountRole: - return rec->credit + rec->debit; + return qint64(rec->credit + rec->debit); case TxIDRole: return rec->getTxID(); case TxHashRole: diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index a7ba100cd2..d153973872 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -304,7 +304,7 @@ void TransactionView::changedAmount(const QString &amount) { if(!transactionProxyModel) return; - qint64 amount_parsed = 0; + CAmount amount_parsed = 0; if(BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amount, &amount_parsed)) { transactionProxyModel->setMinAmount(amount_parsed); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index ed90914ba7..b8701a23a6 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -55,11 +55,11 @@ WalletModel::~WalletModel() unsubscribeFromCoreSignals(); } -qint64 WalletModel::getBalance(const CCoinControl *coinControl) const +CAmount WalletModel::getBalance(const CCoinControl *coinControl) const { if (coinControl) { - qint64 nBalance = 0; + CAmount nBalance = 0; std::vector<COutput> vCoins; wallet->AvailableCoins(vCoins, true, coinControl); BOOST_FOREACH(const COutput& out, vCoins) @@ -72,12 +72,12 @@ qint64 WalletModel::getBalance(const CCoinControl *coinControl) const return wallet->GetBalance(); } -qint64 WalletModel::getUnconfirmedBalance() const +CAmount WalletModel::getUnconfirmedBalance() const { return wallet->GetUnconfirmedBalance(); } -qint64 WalletModel::getImmatureBalance() const +CAmount WalletModel::getImmatureBalance() const { return wallet->GetImmatureBalance(); } @@ -87,17 +87,17 @@ bool WalletModel::haveWatchOnly() const return fHaveWatchOnly; } -qint64 WalletModel::getWatchBalance() const +CAmount WalletModel::getWatchBalance() const { return wallet->GetWatchOnlyBalance(); } -qint64 WalletModel::getWatchUnconfirmedBalance() const +CAmount WalletModel::getWatchUnconfirmedBalance() const { return wallet->GetUnconfirmedWatchOnlyBalance(); } -qint64 WalletModel::getWatchImmatureBalance() const +CAmount WalletModel::getWatchImmatureBalance() const { return wallet->GetImmatureWatchOnlyBalance(); } @@ -137,12 +137,12 @@ void WalletModel::pollBalanceChanged() void WalletModel::checkBalanceChanged() { - qint64 newBalance = getBalance(); - qint64 newUnconfirmedBalance = getUnconfirmedBalance(); - qint64 newImmatureBalance = getImmatureBalance(); - qint64 newWatchOnlyBalance = 0; - qint64 newWatchUnconfBalance = 0; - qint64 newWatchImmatureBalance = 0; + CAmount newBalance = getBalance(); + CAmount newUnconfirmedBalance = getUnconfirmedBalance(); + CAmount newImmatureBalance = getImmatureBalance(); + CAmount newWatchOnlyBalance = 0; + CAmount newWatchUnconfBalance = 0; + CAmount newWatchImmatureBalance = 0; if (haveWatchOnly()) { newWatchOnlyBalance = getWatchBalance(); @@ -194,9 +194,9 @@ bool WalletModel::validateAddress(const QString &address) WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl) { - qint64 total = 0; + CAmount total = 0; QList<SendCoinsRecipient> recipients = transaction.getRecipients(); - std::vector<std::pair<CScript, int64_t> > vecSend; + std::vector<std::pair<CScript, CAmount> > vecSend; if(recipients.empty()) { @@ -211,7 +211,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact { if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... - int64_t subtotal = 0; + CAmount subtotal = 0; const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); for (int i = 0; i < details.outputs_size(); i++) { @@ -220,7 +220,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact subtotal += out.amount(); const unsigned char* scriptStr = (const unsigned char*)out.script().data(); CScript scriptPubKey(scriptStr, scriptStr+out.script().size()); - vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, out.amount())); + vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, out.amount())); } if (subtotal <= 0) { @@ -242,7 +242,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact ++nAddresses; CScript scriptPubKey = GetScriptForDestination(CBitcoinAddress(rcp.address.toStdString()).Get()); - vecSend.push_back(std::pair<CScript, int64_t>(scriptPubKey, rcp.amount)); + vecSend.push_back(std::pair<CScript, CAmount>(scriptPubKey, rcp.amount)); total += rcp.amount; } @@ -252,7 +252,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact return DuplicateAddress; } - qint64 nBalance = getBalance(coinControl); + CAmount nBalance = getBalance(coinControl); if(total > nBalance) { @@ -263,7 +263,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact LOCK2(cs_main, wallet->cs_wallet); transaction.newPossibleKeyChange(wallet); - int64_t nFeeRequired = 0; + CAmount nFeeRequired = 0; std::string strFailReason; CWalletTx *newTx = transaction.getTransaction(); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 111ae2178c..b1d0f28f12 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -37,7 +37,7 @@ class SendCoinsRecipient { public: explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { } - explicit SendCoinsRecipient(const QString &addr, const QString &label, quint64 amount, const QString &message): + explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message): address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} // If from an insecure payment request, this is used for storing @@ -47,7 +47,7 @@ public: // Todo: This is a hack, should be replaced with a cleaner solution! QString address; QString label; - qint64 amount; + CAmount amount; // If from a payment request, this is used for storing the memo QString message; @@ -125,13 +125,13 @@ public: TransactionTableModel *getTransactionTableModel(); RecentRequestsTableModel *getRecentRequestsTableModel(); - qint64 getBalance(const CCoinControl *coinControl = NULL) const; - qint64 getUnconfirmedBalance() const; - qint64 getImmatureBalance() const; + CAmount getBalance(const CCoinControl *coinControl = NULL) const; + CAmount getUnconfirmedBalance() const; + CAmount getImmatureBalance() const; bool haveWatchOnly() const; - qint64 getWatchBalance() const; - qint64 getWatchUnconfirmedBalance() const; - qint64 getWatchImmatureBalance() const; + CAmount getWatchBalance() const; + CAmount getWatchUnconfirmedBalance() const; + CAmount getWatchImmatureBalance() const; EncryptionStatus getEncryptionStatus() const; bool processingQueuedTransactions() { return fProcessingQueuedTransactions; } @@ -210,12 +210,12 @@ private: RecentRequestsTableModel *recentRequestsTableModel; // Cache some values to be able to detect changes - qint64 cachedBalance; - qint64 cachedUnconfirmedBalance; - qint64 cachedImmatureBalance; - qint64 cachedWatchOnlyBalance; - qint64 cachedWatchUnconfBalance; - qint64 cachedWatchImmatureBalance; + CAmount cachedBalance; + CAmount cachedUnconfirmedBalance; + CAmount cachedImmatureBalance; + CAmount cachedWatchOnlyBalance; + CAmount cachedWatchUnconfBalance; + CAmount cachedWatchImmatureBalance; EncryptionStatus cachedEncryptionStatus; int cachedNumBlocks; @@ -227,8 +227,8 @@ private: signals: // Signal that balance in wallet changed - void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance, - qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance); + void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, + const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); // Encryption status of wallet changed void encryptionStatusChanged(int status); diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp index 943f13e208..ddd2d09bb5 100644 --- a/src/qt/walletmodeltransaction.cpp +++ b/src/qt/walletmodeltransaction.cpp @@ -31,19 +31,19 @@ CWalletTx *WalletModelTransaction::getTransaction() return walletTransaction; } -qint64 WalletModelTransaction::getTransactionFee() +CAmount WalletModelTransaction::getTransactionFee() { return fee; } -void WalletModelTransaction::setTransactionFee(qint64 newFee) +void WalletModelTransaction::setTransactionFee(const CAmount& newFee) { fee = newFee; } -qint64 WalletModelTransaction::getTotalTransactionAmount() +CAmount WalletModelTransaction::getTotalTransactionAmount() { - qint64 totalTransactionAmount = 0; + CAmount totalTransactionAmount = 0; foreach(const SendCoinsRecipient &rcp, recipients) { totalTransactionAmount += rcp.amount; diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index b7e85bcd11..4eadfbe4d1 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -26,10 +26,10 @@ public: CWalletTx *getTransaction(); - void setTransactionFee(qint64 newFee); - qint64 getTransactionFee(); + void setTransactionFee(const CAmount& newFee); + CAmount getTransactionFee(); - qint64 getTotalTransactionAmount(); + CAmount getTotalTransactionAmount(); void newPossibleKeyChange(CWallet *wallet); CReserveKey *getPossibleKeyChange(); @@ -38,7 +38,7 @@ private: const QList<SendCoinsRecipient> recipients; CWalletTx *walletTransaction; CReserveKey *keyChange; - qint64 fee; + CAmount fee; }; #endif // WALLETMODELTRANSACTION_H diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index b40ddc0a2f..eff50593bd 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -92,7 +92,7 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui) connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int))); // Pass through transaction notifications - connect(this, SIGNAL(incomingTransaction(QString,int,qint64,QString,QString)), gui, SLOT(incomingTransaction(QString,int,qint64,QString,QString))); + connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString))); } } diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 9cfa8d6760..cafba517fd 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -5,6 +5,8 @@ #ifndef WALLETVIEW_H #define WALLETVIEW_H +#include "amount.h" + #include <QStackedWidget> class BitcoinGUI; @@ -111,7 +113,7 @@ signals: /** Encryption status of wallet changed */ void encryptionStatusChanged(int status); /** Notify that a new transaction appeared */ - void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address); + void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address); }; #endif // WALLETVIEW_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 82eaf5d037..e794bf69e0 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -273,7 +273,7 @@ Value prioritisetransaction(const Array& params, bool fHelp) uint256 hash; hash.SetHex(params[0].get_str()); - int64_t nAmount = 0; + CAmount nAmount = 0; if (params[2].get_real() != 0.0) nAmount = AmountFromValue(params[2]); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index dbb0966ae2..bd87d77704 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -269,7 +269,7 @@ Value listunspent(const Array& params, bool fHelp) continue; } - int64_t nValue = out.tx->vout[out.i].nValue; + CAmount nValue = out.tx->vout[out.i].nValue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; Object entry; entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); @@ -367,7 +367,7 @@ Value createrawtransaction(const Array& params, bool fHelp) setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - int64_t nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(s.value_); CTxOut out(nAmount, scriptPubKey); rawTx.vout.push_back(out); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 190de62282..1a41344da5 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -88,18 +88,18 @@ static inline int64_t roundint64(double d) return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); } -int64_t AmountFromValue(const Value& value) +CAmount AmountFromValue(const Value& value) { double dAmount = value.get_real(); if (dAmount <= 0.0 || dAmount > 21000000.0) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); - int64_t nAmount = roundint64(dAmount * COIN); + CAmount nAmount = roundint64(dAmount * COIN); if (!MoneyRange(nAmount)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); return nAmount; } -Value ValueFromAmount(int64_t amount) +Value ValueFromAmount(const CAmount& amount) { return (double)amount / (double)COIN; } diff --git a/src/rpcserver.h b/src/rpcserver.h index 820c1bc081..d440035f15 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -6,6 +6,7 @@ #ifndef _BITCOINRPC_SERVER_H_ #define _BITCOINRPC_SERVER_H_ +#include "amount.h" #include "uint256.h" #include "rpcprotocol.h" @@ -116,8 +117,8 @@ extern void InitRPCMining(); extern void ShutdownRPCMining(); extern int64_t nWalletUnlockTime; -extern int64_t AmountFromValue(const json_spirit::Value& value); -extern json_spirit::Value ValueFromAmount(int64_t amount); +extern CAmount AmountFromValue(const json_spirit::Value& value); +extern json_spirit::Value ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(std::string methodname, std::string args); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index b361e67911..d7c0c0ef5c 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -336,7 +336,7 @@ Value sendtoaddress(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); // Amount - int64_t nAmount = AmountFromValue(params[1]); + CAmount nAmount = AmountFromValue(params[1]); // Wallet comments CWalletTx wtx; @@ -380,7 +380,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) ); Array jsonGroupings; - map<CTxDestination, int64_t> balances = pwalletMain->GetAddressBalances(); + map<CTxDestination, CAmount> balances = pwalletMain->GetAddressBalances(); BOOST_FOREACH(set<CTxDestination> grouping, pwalletMain->GetAddressGroupings()) { Array jsonGrouping; @@ -488,7 +488,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) nMinDepth = params[1].get_int(); // Tally - int64_t nAmount = 0; + CAmount nAmount = 0; for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; @@ -537,7 +537,7 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) set<CTxDestination> setAddress = pwalletMain->GetAccountAddresses(strAccount); // Tally - int64_t nAmount = 0; + CAmount nAmount = 0; for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; @@ -557,9 +557,9 @@ Value getreceivedbyaccount(const Array& params, bool fHelp) } -int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter) +CAmount GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth, const isminefilter& filter) { - int64_t nBalance = 0; + CAmount nBalance = 0; // Tally wallet transactions for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) @@ -568,7 +568,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi if (!IsFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || wtx.GetDepthInMainChain() < 0) continue; - int64_t nReceived, nSent, nFee; + CAmount nReceived, nSent, nFee; wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter); if (nReceived != 0 && wtx.GetDepthInMainChain() >= nMinDepth) @@ -582,7 +582,7 @@ int64_t GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMi return nBalance; } -int64_t GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter) +CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminefilter& filter) { CWalletDB walletdb(pwalletMain->strWalletFile); return GetAccountBalance(walletdb, strAccount, nMinDepth, filter); @@ -632,14 +632,14 @@ Value getbalance(const Array& params, bool fHelp) // Calculate total balance a different way from GetBalance() // (GetBalance() sums up all unspent TxOuts) // getbalance and getbalance '*' 0 should return the same number - int64_t nBalance = 0; + CAmount nBalance = 0; for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; if (!wtx.IsTrusted() || wtx.GetBlocksToMaturity() > 0) continue; - int64_t allFee; + CAmount allFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -658,7 +658,7 @@ Value getbalance(const Array& params, bool fHelp) string strAccount = AccountFromValue(params[0]); - int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, filter); + CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, filter); return ValueFromAmount(nBalance); } @@ -697,7 +697,7 @@ Value movecmd(const Array& params, bool fHelp) string strFrom = AccountFromValue(params[0]); string strTo = AccountFromValue(params[1]); - int64_t nAmount = AmountFromValue(params[2]); + CAmount nAmount = AmountFromValue(params[2]); if (params.size() > 3) // unused parameter, used to be nMinDepth, keep type-checking it though (void)params[3].get_int(); @@ -771,7 +771,7 @@ Value sendfrom(const Array& params, bool fHelp) CBitcoinAddress address(params[1].get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); - int64_t nAmount = AmountFromValue(params[2]); + CAmount nAmount = AmountFromValue(params[2]); int nMinDepth = 1; if (params.size() > 3) nMinDepth = params[3].get_int(); @@ -786,7 +786,7 @@ Value sendfrom(const Array& params, bool fHelp) EnsureWalletIsUnlocked(); // Check funds - int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (nAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); @@ -839,9 +839,9 @@ Value sendmany(const Array& params, bool fHelp) wtx.mapValue["comment"] = params[3].get_str(); set<CBitcoinAddress> setAddress; - vector<pair<CScript, int64_t> > vecSend; + vector<pair<CScript, CAmount> > vecSend; - int64_t totalAmount = 0; + CAmount totalAmount = 0; BOOST_FOREACH(const Pair& s, sendTo) { CBitcoinAddress address(s.name_); @@ -853,7 +853,7 @@ Value sendmany(const Array& params, bool fHelp) setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - int64_t nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(s.value_); totalAmount += nAmount; vecSend.push_back(make_pair(scriptPubKey, nAmount)); @@ -862,13 +862,13 @@ Value sendmany(const Array& params, bool fHelp) EnsureWalletIsUnlocked(); // Check funds - int64_t nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); + CAmount nBalance = GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); if (totalAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send CReserveKey keyChange(pwalletMain); - int64_t nFeeRequired = 0; + CAmount nFeeRequired = 0; string strFailReason; bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, strFailReason); if (!fCreated) @@ -928,7 +928,7 @@ Value addmultisigaddress(const Array& params, bool fHelp) struct tallyitem { - int64_t nAmount; + CAmount nAmount; int nConf; vector<uint256> txids; bool fIsWatchonly; @@ -1000,7 +1000,7 @@ Value ListReceived(const Array& params, bool fByAccounts) if (it == mapTally.end() && !fIncludeEmpty) continue; - int64_t nAmount = 0; + CAmount nAmount = 0; int nConf = std::numeric_limits<int>::max(); bool fIsWatchonly = false; if (it != mapTally.end()) @@ -1043,7 +1043,7 @@ Value ListReceived(const Array& params, bool fByAccounts) { for (map<string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it) { - int64_t nAmount = (*it).second.nAmount; + CAmount nAmount = (*it).second.nAmount; int nConf = (*it).second.nConf; Object obj; if((*it).second.fIsWatchonly) @@ -1130,7 +1130,7 @@ static void MaybePushAddress(Object & entry, const CTxDestination &dest) void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) { - int64_t nFee; + CAmount nFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -1360,7 +1360,7 @@ Value listaccounts(const Array& params, bool fHelp) if(params[1].get_bool()) includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; - map<string, int64_t> mapAccountBalances; + map<string, CAmount> mapAccountBalances; BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwalletMain->mapAddressBook) { if (IsMine(*pwalletMain, entry.first) & includeWatchonly) // This address belongs to me mapAccountBalances[entry.second.name] = 0; @@ -1369,7 +1369,7 @@ Value listaccounts(const Array& params, bool fHelp) for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; - int64_t nFee; + CAmount nFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -1396,7 +1396,7 @@ Value listaccounts(const Array& params, bool fHelp) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; Object ret; - BOOST_FOREACH(const PAIRTYPE(string, int64_t)& accountBalance, mapAccountBalances) { + BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) { ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); } return ret; @@ -1539,10 +1539,10 @@ Value gettransaction(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); const CWalletTx& wtx = pwalletMain->mapWallet[hash]; - int64_t nCredit = wtx.GetCredit(filter != 0); - int64_t nDebit = wtx.GetDebit(filter); - int64_t nNet = nCredit - nDebit; - int64_t nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0); + CAmount nCredit = wtx.GetCredit(filter != 0); + CAmount nDebit = wtx.GetDebit(filter); + CAmount nNet = nCredit - nDebit; + CAmount nFee = (wtx.IsFromMe(filter) ? wtx.GetValueOut() - nDebit : 0); entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee))); if (wtx.IsFromMe(filter)) @@ -1942,7 +1942,7 @@ Value settxfee(const Array& params, bool fHelp) ); // Amount - int64_t nAmount = 0; + CAmount nAmount = 0; if (params[0].get_real() != 0.0) nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index d742fb9eb9..a71f55dd26 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -839,7 +839,8 @@ public: itBegin = it; } } - s.write((char*)&itBegin[0], it-itBegin); + if (itBegin != scriptCode.end()) + s.write((char*)&itBegin[0], it-itBegin); } /** Serialize an input of txTo */ diff --git a/src/serialize.h b/src/serialize.h index 447d808dee..68501facf2 100644 --- a/src/serialize.h +++ b/src/serialize.h @@ -245,7 +245,7 @@ uint64_t ReadCompactSize(Stream& is) uint64_t xSize; READDATA(is, xSize); nSizeRet = xSize; - if (nSizeRet < 0x100000000LLu) + if (nSizeRet < 0x100000000ULL) throw std::ios_base::failure("non-canonical ReadCompactSize()"); } if (nSizeRet > (uint64_t)MAX_SIZE) @@ -1154,7 +1154,7 @@ public: -/** RAII wrapper for FILE*. +/** Non-refcounted RAII wrapper for FILE*. * * Will automatically close the file when it goes out of scope if not null. * If you're returning the file pointer, return file.release(). @@ -1162,6 +1162,10 @@ public: */ class CAutoFile { +private: + // Disallow copies + CAutoFile(const CAutoFile&); + CAutoFile& operator=(const CAutoFile&); protected: FILE* file; public: diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 4bee0f6b6e..af2a9a214f 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -15,7 +15,7 @@ extern CWallet* pwalletMain; BOOST_AUTO_TEST_SUITE(accounting_tests) static void -GetResults(CWalletDB& walletdb, std::map<int64_t, CAccountingEntry>& results) +GetResults(CWalletDB& walletdb, std::map<CAmount, CAccountingEntry>& results) { std::list<CAccountingEntry> aes; @@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) std::vector<CWalletTx*> vpwtx; CWalletTx wtx; CAccountingEntry ae; - std::map<int64_t, CAccountingEntry> results; + std::map<CAmount, CAccountingEntry> results; LOCK(pwalletMain->cs_wallet); diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 58fffb6df4..c298c805da 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); } } - SelectParams(CBaseChainParams::MAIN); + SelectParams(CBaseChainParams::UNITTEST); } // Goal: check that generated keys match test vectors @@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) CTxDestination nodest = CNoDestination(); BOOST_CHECK(!dummyAddr.Set(nodest)); - SelectParams(CBaseChainParams::MAIN); + SelectParams(CBaseChainParams::UNITTEST); } // Goal: check that base58 parsing code is robust against a variety of corrupted data diff --git a/src/test/bctest.py b/src/test/bctest.py index 1839f4fef4..ef461014ea 100644 --- a/src/test/bctest.py +++ b/src/test/bctest.py @@ -7,9 +7,11 @@ import os import json import sys -def bctest(testDir, testObj): - execargs = testObj['exec'] +def bctest(testDir, testObj, exeext): + execprog = testObj['exec'] + exeext + execargs = testObj['args'] + execrun = [execprog] + execargs stdinCfg = None inputData = None if "input" in testObj: @@ -22,12 +24,11 @@ def bctest(testDir, testObj): if "output_cmp" in testObj: outputFn = testObj['output_cmp'] outputData = open(testDir + "/" + outputFn).read() - - proc = subprocess.Popen(execargs, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True) try: outs = proc.communicate(input=inputData) except OSError: - print("OSError, Failed to execute " + execargs[0]) + print("OSError, Failed to execute " + execprog) sys.exit(1) if outputData and (outs[0] != outputData): @@ -41,13 +42,13 @@ def bctest(testDir, testObj): print("Return code mismatch for " + outputFn) sys.exit(1) -def bctester(testDir, input_basename): +def bctester(testDir, input_basename, buildenv): input_filename = testDir + "/" + input_basename raw_data = open(input_filename).read() input_data = json.loads(raw_data) for testObj in input_data: - bctest(testDir, testObj) + bctest(testDir, testObj, buildenv.exeext) sys.exit(0) diff --git a/src/test/bignum.h b/src/test/bignum.h index a75f5250fa..86980b2af6 100644 --- a/src/test/bignum.h +++ b/src/test/bignum.h @@ -63,11 +63,11 @@ public: int getint() const { - unsigned long n = BN_get_word(this); + BN_ULONG n = BN_get_word(this); if (!BN_is_negative(this)) - return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n); + return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n); else - return (n > (unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n); + return (n > (BN_ULONG)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(int)n); } void setint64(int64_t sn) diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py index 40690c2fed..0eece14cfe 100755 --- a/src/test/bitcoin-util-test.py +++ b/src/test/bitcoin-util-test.py @@ -5,8 +5,9 @@ import os import bctest +import buildenv if __name__ == '__main__': bctest.bctester(os.environ["srcdir"] + "/test/data", - "bitcoin-util-test.json") + "bitcoin-util-test.json",buildenv) diff --git a/src/test/buildenv.py.in b/src/test/buildenv.py.in new file mode 100644 index 0000000000..1618bdeb76 --- /dev/null +++ b/src/test/buildenv.py.in @@ -0,0 +1,2 @@ +#!/usr/bin/python +exeext="@EXEEXT@" diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index fdea12846a..67d40a45c7 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -35,7 +35,7 @@ bool read_block(const std::string& filename, CBlock& block) fseek(fp, 8, SEEK_SET); // skip msgheader/size - CAutoFile filein = CAutoFile(fp, SER_DISK, CLIENT_VERSION); + CAutoFile filein(fp, SER_DISK, CLIENT_VERSION); if (!filein) return false; filein >> block; diff --git a/src/test/data/bitcoin-util-test.json b/src/test/data/bitcoin-util-test.json index cb74d73ef2..f8424b72a3 100644 --- a/src/test/data/bitcoin-util-test.json +++ b/src/test/data/bitcoin-util-test.json @@ -1,33 +1,41 @@ [ - { "exec": ["./bitcoin-tx", "-create"], + { "exec": "././bitcoin-tx", + "args": ["-create"], "output_cmp": "blanktx.hex" }, - { "exec": ["./bitcoin-tx", "-"], + { "exec": "./bitcoin-tx", + "args": ["-"], "input": "blanktx.hex", "output_cmp": "blanktx.hex" }, - { "exec": ["./bitcoin-tx", "-", "delin=1"], + { "exec": "./bitcoin-tx", + "args": ["-", "delin=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delin1-out.hex" }, - { "exec": ["./bitcoin-tx", "-", "delin=31"], + { "exec": "./bitcoin-tx", + "args": ["-", "delin=31"], "input": "tx394b54bb.hex", "return_code": 1 }, - { "exec": ["./bitcoin-tx", "-", "delout=1"], + { "exec": "./bitcoin-tx", + "args": ["-", "delout=1"], "input": "tx394b54bb.hex", "output_cmp": "tt-delout1-out.hex" }, - { "exec": ["./bitcoin-tx", "-", "delout=2"], + { "exec": "./bitcoin-tx", + "args": ["-", "delout=2"], "input": "tx394b54bb.hex", "return_code": 1 }, - { "exec": ["./bitcoin-tx", "-", "locktime=317000"], + { "exec": "./bitcoin-tx", + "args": ["-", "locktime=317000"], "input": "tx394b54bb.hex", "output_cmp": "tt-locktime317000-out.hex" }, - { "exec": - ["./bitcoin-tx", "-create", + { "exec": "./bitcoin-tx", + "args": + ["-create", "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18", "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1", @@ -35,7 +43,8 @@ "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"], "output_cmp": "txcreate1.hex" }, - { "exec": ["./bitcoin-tx", "-create", "outscript=0:"], + { "exec": "./bitcoin-tx", + "args": ["-create", "outscript=0:"], "output_cmp": "txcreate2.hex" } ] diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 401031ad12..35a6794b01 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -384,18 +384,18 @@ nSequences are max. ["0x00", "'00' EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], -["0x48 0x3045022100ea4d62e1fb351ad977596457bb01dfce58e050541784277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with wrong signature"], -["0x47 0x304402207d09de5e34968c3f8b27d8217f173629f1106ee5216aa11d6b1f9813b3a214060220610a6ed25c704f901c6278f4f57fb11eadefdf0b22df298cfb6ce7ea84c86bf401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash using an anyonecanpay sighash"], -["0x47 0x3044022028686fb3c8d3e5068cc9924c494fb5026df201d23340896da62fe9bb73fd9d5f02202a239609524959c4ca3651fd0cc48245b0b240862146fc579f3a962a4f46942b01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkey with wrong signature"], -["0x47 0x3044022054cb0a3fca8694a0c231848ed9f965078148fd653e49dd4b6981fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "P2SH,STRICTENC", "P2SH with a pay to pubkeyhash inside with wrong signature"], -["0 0x48 0x3045022100e1c4e8800bd00c9ec3cd3df0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC", "Raw multisig with one pubkey with wrong signature"], -["0x49 0x304602220000ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with non-DER signature (too much R padding)"], -["0x47 0x30440220ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with non-DER signature (too little R padding)"], -["0x49 0x3046022100ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a950221003003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash with non-DER signature (too much S padding)"], -["0x48 0x3045022100e6eda3fd34862078233463cae19f0b47995e3f892102e5b175175e92a9163cc402204bf58445819093638481084322b61a2d49b68c96fd6fea17ed494722d0d67b4f01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "P2SH,STRICTENC", "Pay to pubkey with hybrid pubkey encoding"], -["0x48 0x304502203b56d65863e0cdb89313043c2402f46f518c31658648151b01ec6b5b6c89206a022100d71efefb4c24fab36abb44ade106963d8114c5af1bda033faa1923f54ec4ea6a01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC,LOW_S", "Pay to pubkey with high S"], -["0x47 0x3044022054cb0a3fca8694a0c231848fd9f965078148fd653e49dd4b6980fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "P2SH,STRICTENC", "P2SH with a pay to pubkeyhash inside with invalid signature"], -["1 0x48 0x3045022100e1c4e8800bd00c9ec3cd3de0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC,NULLDUMMY", "Raw multisig with one pubkey with non-zero dummy"], +["0x47 0x30440220304eff7556bba9560df47873275e64db45f3cd735998ce3f00d2e57b1bb5f31302205c0c9d14b8b80d43e2ac9b87532f1af6d8a3271262bc694ec4e14068392bb0a001", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", "P2PK, bad sig"], +["0x47 0x3044022037fcdb8e08f41e27588de8bc036d2c4b16eb3d09c1ba53b8f47a0a9c27722a39022058664b7a53b507e71dfafb77193e3786c3f0c119d78ce9104480ee7ece04f09301 0x21 0x03363d90d446b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640", "DUP HASH160 0x14 0xc0834c0c158f53be706d234c38fd52de7eece656 EQUALVERIFY CHECKSIG", "", "P2PKH, bad pubkey"], +["0x47 0x3044022035e5b6742d299861c84cebaf2ea64145ee427a95facab39e2594d6deebb0c1d602200acb16778faa2e467a59006f342f2535b1418d55ba63a8605b387b7f9ac86d9a01", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", "P2PK anyonecanpay marked with normal hashtype"], +["0x47 0x3044022029b2b8765ca950cf75a69e80b73b7ddfcaa8b27080c2db4c23b36aae60688e790220598ff368e17872ee065aa54d7d3a590682ca5204325b23b31d7da3c4a21ae67901 0x23 0x210279be667ef9dcbbac54a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", "P2SH(P2PK), bad redeemscript"], +["0x47 0x30440220647f906e63890df5ef1d3fed47ba892b31976c634281079e2bd38504fb54a1fb022021e8811f38fbe90efb6b74cb78da01d9badbac3bafdf70a861d7538a220d0b2601 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "P2SH", "P2SH(P2PKH), bad sig"], +["0 0x47 0x304402203ef170402f8887f2ac183f31b1f503b0bc60bfc968dd469b097ea6124aefac5002200612febadc4e4cacc086982cb85830a17af3680c1b6a3cf77c1708af7621cf1301 0 0x47 0x304402207821838251a24a2234844f68e7169e6d11945cdf052ea12bd3e4e37457aceb4402200b6b46c81361e314c740ae5133c072af5fa5c209d65d2db1679e1716f19a538101", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3, 2 sigs"], +["0 0 0x47 0x304402204661f7795e8db7be3132e8974e9a76d1d24b31f23df94c6fbcea07d1c205789102203f5e45a1c0b085279b58d11b36d5fea5449c3cf16f844ad10124e9b65e8777d201 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", "P2SH(2-of-3), 1 sig"], +["0x47 0x304402200052bc1600ca45c71f3538720fe62a5e8548dffd137af04467598c98466e9c0a0220789318ddbc9991ee477974089220a2feb6a6298a7c93d5ff6c25a92a2f4b48d501", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "STRICTENC", "P2PK with too much R padding"], +["0x48 0x304502206eb7b92628bfb3c4d2a04b65b986987bcbb1af4fceedb144d5a0437b7ee410590221005f57a52df4aa26366742eed0db182fce51fbcd7159011b0644a7c05943eb228901", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "STRICTENC", "P2PK with too much S padding"], +["0x47 0x30440220d8ad1efd55a3d2b8896495c38aba72056e1b3ca4a6ca15760e843eb1a9b9907602203eb0e8f3d6bec998262dfd03eaeb0f31c4e5105965436dec77550724b3771f3201", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "STRICTENC", "P2PK with too little R padding"], +["0x48 0x304502206c43e065c8a8db3bbe69015afb86a51fb2fc8870defd41d436da2a197d9d6c12022100fcec35816ee2d84ec271ad159fcabf5dd712157051169e48ac328a7818cdb51e01", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "LOW_S,STRICTENC", "P2PK with high S"], +["0x01 0x01 0x47 0x304402200e48ba1cf4d7182db94ffb57bd72ea31b5545dc0d1c512e665779b4fb2badc52022054b8388dfc074c708a75b62359b7be46402751ee40c0a111aef38a837b6ed09801 0x47 0x304402201c9820f59c49107bb30e6175cfc9ec95f897b03beb628b4bc854d2b80392aa0602200235d986ae418bcd111b8814f4c26a0ab5f475fb542a44884fc14912a97a252301 0x47 0x304402204cd7894c6f10a871f5b0c1f9c13228f8cdd4050248f0d0f498ee86be69ee3080022051bd2932c7d585eb600c7194235c74da820935f0d67972fd9545673aa1fd023301", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "NULLDUMMY", "3-of-3 with nonzero dummy"], ["The End"] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index e0b527996c..653f60d982 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -529,18 +529,19 @@ nSequences are max. ["0x00", "SIZE 0 EQUAL", "P2SH,STRICTENC", "Basic OP_0 execution"], -["0x48 0x3045022100ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkeyhash"], -["0x47 0x304402207d09de5e34968c3f8b27d8217f173629f1106ee5216aa11d6b1f9813b3a214060220610a6ed25c704f901c6278f4f57fb11eadefdf0b22df298cfb6ce7ea84c86bf481 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH,STRICTENC", "Anyonecanpay pay to pubkeyhash"], -["0x47 0x3044022028686fb3c8d3e5069cc9924c494fb5026df201d23340896da62fe9bb73fd9d5f02202a239609524959c4ca3651fd0cc48245b0b240862146fc579f3a962a4f46942b01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC", "Normal pay to pubkey"], -["0x47 0x3044022054cb0a3fca8694a0c231848ed9f965078148fd653e49dd4b6980fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "P2SH,STRICTENC", "P2SH with a pay to pubkeyhash inside"], -["0 0x48 0x3045022100e1c4e8800bd00c9ec3cd3de0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC", "Raw multisig with one pubkey"], -["0x49 0x304602220000ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH", "Normal pay to pubkeyhash with non-DER signature (too much R padding)"], -["0x47 0x30440220ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a9502203003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH", "Normal pay to pubkeyhash with non-DER signature (too little R padding)"], -["0x49 0x3046022100ea4d62e1fb351ad977596457bb01dfce58e050541774277bd825c33bd98c2a950221003003347cf04573be4dc786c3fc5e7db09821565bf45c7d60160709b962f0398401 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "DUP HASH160 0x14 0x751e76e8199196d454941c45d1b3a323f1433bd6 EQUALVERIFY CHECKSIG", "P2SH", "Normal pay to pubkeyhash with non-DER signature (too much S padding)"], -["0x48 0x3045022100e6eda3fd34862078233463cae19f0b47995e3f892102e5b175175e92a9163cc402204bf58445819093638481084322b61a2d49b68c96fd6fea17ed494722d0d67b4f01", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "P2SH", "Pay to pubkey with hybrid pubkey encoding"], -["0x48 0x304502203b56d65863e0cdb89313043c2402f46f518c31658648151b01ec6b5b6c89206a022100d71efefb4c24fab36abb44ade106963d8114c5af1bda033faa1923f54ec4ea6a01", "0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 CHECKSIG", "P2SH,STRICTENC", "Pay to pubkey with high S"], -["0x47 0x3044022054cb0a3fca8694a0c231848fd9f965078148fd653e49dd4b6980fadac0f5ba0702204085be5af427d4561f13a07fd5a1c5ab0ff02126e9ba191448f5a9dae0da585301 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x19 0x76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", "HASH160 0x14 0xcd7b44d0b03f2d026d1e586d7ae18903b0d385f6 EQUAL", "STRICTENC", "P2SH with a pay to pubkeyhash inside with invalid signature"], -["1 0x48 0x3045022100e1c4e8800bd00c9ec3cd3de0e53e63bc5e8c018d0b68099a652f0b121f1a7e020220108dab275be7d1358530d3451d48aed747af77cc54e0423cbae5c572b2e1abb801", "1 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 1 CHECKMULTISIG", "P2SH,STRICTENC", "Raw multisig with one pubkey with non-zero dummy"], +["0x47 0x3044022007415aa37ce7eaa6146001ac8bdefca0ddcba0e37c5dc08c4ac99392124ebac802207d382307fd53f65778b07b9c63b6e196edeadf0be719130c5db21ff1e700d67501", "0x41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG", "", "P2PK"], +["0x47 0x3044022069d40999786aeb2fd874f9eb2636461a062dc963471627ed8390a3a5f9556f640220350132a52415ce622f2aadd07f791c591500917ec1f8c5edbc5381ef7942534d01 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508", "DUP HASH160 0x14 0x1018853670f9f3b0582c5b9ee8ce93764ac32b93 EQUALVERIFY CHECKSIG", "", "P2PKH"], +["0x47 0x30440220519f2a6632ffa134c7811ea2819e9dcc951f0c7baf461f2dffdd09133f3b080a02203ec6bab5eb6619ed7f41b8701d7c6d70cfc83bb26c5c97f54b2ca6e304fc2bb581", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "", "P2PK anyonecanpay"], +["0x47 0x30440220279dad2170ffb5639f0a1ea71fc462ee37d75d420d86f84c978bac523c09b7f20220683b2789f5c5528a9e0a0d78f6e40db3f616cf1adb5a5fdef117d5974795cfe201 0x23 0x210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac", "HASH160 0x14 0x23b0ad3477f2178bc0b3eed26e4e6316f4e83aa1 EQUAL", "P2SH", "P2SH(P2PK)"], +["0x47 0x3044022066acbfb5ac96b7cbf3f05a2aaf358c32438c45d1d7359dee9fc1ee636940735f02205606a03fd8cbf6a6fcbcba60c8abb1e385c0b5753cb57a97538159106fd3684e01 0x19 0x76a9147cf9c846cd4882efec4bf07e44ebdad495c94f4b88ac", "HASH160 0x14 0x2df519943d5acc0ef5222091f9dfe3543f489a82 EQUAL", "", "P2SH(P2PKH), bad sig but no VERIFY_P2SH"], +["0 0x47 0x3044022004e791dd30a64c70e55e84e150c002af9feb3ce0ab1f20e86c53d1209003927502205a60453987fcd72aebaaacebc8ce4b15449cdd79e54cc82cefb83e69dbcfeabf01 0x47 0x304402201d021808ce93dd8574cc4f99ae4f11b44305528b0aecbd9f156f08315173643802200944a0ea5c884bd86180aef76d8b1e444860776b251e47d2d6c651a1c6f9930801 0x47 0x30440220446336d7b7de05ebb5683b82b05248ec7d78e88ae8d6125985f5776c887a4cf90220674ab2b2c2f954ba1cf35457d273c90d0c0c1c224d0ae128628740e81129486801", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3"], +["0 0x47 0x30440220288b06d057cf0eac434ed0c3be9257cc0ca144dd99c11cc8f1a49467a37d8e8002203c496c72253c528e6bc81c42e683aba974d46041a96ef7b00915c863eb2a702901 0x47 0x304402207ffb4da33f40cac839a43000a187bd76a1ee5bf95e46dc1534b38bb7bd0321db022038c078f29d1831f8eb68ffdc2634c654fb01c3467b6457b98ad220653bb2478501 0x4c69 0x52210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179821038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f515082103363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff464053ae", "HASH160 0x14 0xc9e4a896d149702d0d1695434feddd52e24ad78d EQUAL", "P2SH", "P2SH(2-of-3)"], +["0x47 0x304402200001cae94b795baaafb05db38cf24cd75560cab2c36c91e29fac7d0fd2a723a3022058e2e56e568ce7c4b2b106210d114e1faa079407a6ed4154f230667c7d3583bc01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too much R padding but no STRICTENC"], +["0x48 0x304502206d01de7c2a40ac2bb1231ed97f3890a1782f421d4c28b97166deff317990288f0221005e720213b089355be2cf785d81a82c59307d30e1624f450ed9ca1ebbc11cca6d01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too much S padding but no STRICTENC"], +["0x47 0x30440220f3d8889602147d60d26c1d3b21b8db183eac02bf6d2fec1424c0ef377ca6fd7b02202bae8bfe39d00a432d4538a592e338b0ffc44c17d4b7056043d55063cf91f5ef01", "0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 CHECKSIG", "", "P2PK with too little R padding but no STRICTENC"], +["0x48 0x3045022021bf9184d94f208ac9f4757ebca9b1cbebf008cfc244fe5be1360b1b9aba0e92022100e55074f72f3a1bfddf2ea4ea7ba984f78822e136fe04c8f9c1363238e0233bd801", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "STRICTENC", "P2PK with high S but no LOW_S"], +["0x48 0x304502205c3e81aaf2aad0673f349035b180eba783eba7797af91c979920dea6b17a16d6022100d1d46825c68da1b325f320a3503dad27bb818227f64a38d153554bfd360c0e5301", "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG", "LOW_S", "P2PK with high S but no STRICTENC"], +["0x01 0x01 0x47 0x3044022046ce33d1771b0127dd4c4cef8fdc3218ebdfa60e3793ed700292d8ebd93fb1f402201029d47a414db83e96e31443c2d8b552f971469c4800f5eff7df2f0648521aed01 0x47 0x304402205c53911ad55b054920043962bbda98cf6e57e2db1cd5611138251490baabaa8702201dc80dfceae6007e7772dc13ff6e7ca66a983cb017fe5d46d30118462d83bcf801 0x47 0x304402201937e44a4ec12364f9d32f9d25e7ecbc68aee9ef90069af80efef4c05f6ace9602206c515101c00c75710b32ff7ff8dbaf7c9a0be6e86ed14a0755b47626604f31fd01", "3 0x21 0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 3 CHECKMULTISIG", "", "3-of-3 with nonzero dummy but no NULLDUMMY"], ["The End"] ] diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 8cadcdd716..8a984304f4 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -16,7 +16,8 @@ BOOST_AUTO_TEST_SUITE(getarg_tests) static void ResetArgs(const std::string& strArg) { std::vector<std::string> vecArg; - boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); + if (strArg.size()) + boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); // Insert dummy executable name: vecArg.insert(vecArg.begin(), "testbitcoin"); diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp index 8863ba4004..70a800af51 100644 --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -11,9 +11,9 @@ BOOST_AUTO_TEST_SUITE(main_tests) BOOST_AUTO_TEST_CASE(subsidy_limit_test) { - uint64_t nSum = 0; + CAmount nSum = 0; for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) { - uint64_t nSubsidy = GetBlockValue(nHeight, 0); + CAmount nSubsidy = GetBlockValue(nHeight, 0); BOOST_CHECK(nSubsidy <= 50 * COIN); nSum += nSubsidy * 1000; BOOST_CHECK(MoneyRange(nSum)); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 9e4669eba9..bad5c13ac2 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -253,6 +253,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) chainActive.Tip()->nHeight--; SetMockTime(0); + mempool.clear(); BOOST_FOREACH(CTransaction *tx, txFirst) delete tx; diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 178b35fa2d..7f09b3daa1 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -5,12 +5,13 @@ #include "data/script_invalid.json.h" #include "data/script_valid.json.h" +#include "core_io.h" #include "key.h" #include "keystore.h" #include "main.h" #include "script/script.h" #include "script/sign.h" -#include "core_io.h" +#include "util.h" #include <fstream> #include <stdint.h> @@ -36,6 +37,7 @@ using namespace boost::algorithm; static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(string strFlags); +string FormatScriptFlags(unsigned int flags); Array read_json(const std::string& jsondata) @@ -68,10 +70,8 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey) return txCredit; } -CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScript& scriptPubKey) +CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CTransaction& txCredit) { - CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey); - CMutableTransaction txSpend; txSpend.nVersion = 1; txSpend.nLockTime = 0; @@ -87,6 +87,317 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CSc return txSpend; } +void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message) +{ + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0, flags) == expect, message); +} + +namespace +{ +const unsigned char vchKey0[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; +const unsigned char vchKey1[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0}; +const unsigned char vchKey2[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0}; + +struct KeyData +{ + CKey key0, key0C, key1, key1C, key2, key2C; + CPubKey pubkey0, pubkey0C, pubkey0H; + CPubKey pubkey1, pubkey1C; + CPubKey pubkey2, pubkey2C; + + KeyData() + { + + key0.Set(vchKey0, vchKey0 + 32, false); + key0C.Set(vchKey0, vchKey0 + 32, true); + pubkey0 = key0.GetPubKey(); + pubkey0H = key0.GetPubKey(); + pubkey0C = key0C.GetPubKey(); + *const_cast<unsigned char*>(&pubkey0H[0]) = 0x06 | (pubkey0H[64] & 1); + + key1.Set(vchKey1, vchKey1 + 32, false); + key1C.Set(vchKey1, vchKey1 + 32, true); + pubkey1 = key1.GetPubKey(); + pubkey1C = key1C.GetPubKey(); + + key2.Set(vchKey2, vchKey2 + 32, false); + key2C.Set(vchKey2, vchKey2 + 32, true); + pubkey2 = key2.GetPubKey(); + pubkey2C = key2C.GetPubKey(); + } +}; + +const KeyData keys; + +class TestBuilder +{ +private: + CScript scriptPubKey; + CTransaction creditTx; + CMutableTransaction spendTx; + bool havePush; + std::vector<unsigned char> push; + std::string comment; + int flags; + + void DoPush() + { + if (havePush) { + spendTx.vin[0].scriptSig << push; + havePush = false; + } + } + + void DoPush(const std::vector<unsigned char>& data) + { + DoPush(); + push = data; + havePush = true; + } + +public: + TestBuilder(const CScript& redeemScript, const std::string& comment_, int flags_, bool P2SH = false) : scriptPubKey(redeemScript), havePush(false), comment(comment_), flags(flags_) + { + if (P2SH) { + creditTx = BuildCreditingTransaction(CScript() << OP_HASH160 << redeemScript.GetID() << OP_EQUAL); + } else { + creditTx = BuildCreditingTransaction(redeemScript); + } + spendTx = BuildSpendingTransaction(CScript(), creditTx); + } + + TestBuilder& Add(const CScript& script) + { + spendTx.vin[0].scriptSig += script; + return *this; + } + + TestBuilder& Num(int num) + { + spendTx.vin[0].scriptSig << CScriptNum(num); + return *this; + } + + TestBuilder& Push(const std::string& hex) + { + DoPush(ParseHex(hex)); + return *this; + } + + TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32) + { + uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType); + std::vector<unsigned char> vchSig, r, s; + do { + key.Sign(hash, vchSig, lenS <= 32); + r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]); + s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]); + } while (lenR != r.size() || lenS != s.size()); + vchSig.push_back(static_cast<unsigned char>(nHashType)); + DoPush(vchSig); + return *this; + } + + TestBuilder& Push(const CPubKey& pubkey) + { + DoPush(std::vector<unsigned char>(pubkey.begin(), pubkey.end())); + return *this; + } + + TestBuilder& PushRedeem() + { + DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey)); + return *this; + } + + TestBuilder& EditPush(unsigned int pos, const std::string& hexin, const std::string& hexout) + { + assert(havePush); + std::vector<unsigned char> datain = ParseHex(hexin); + std::vector<unsigned char> dataout = ParseHex(hexout); + assert(pos + datain.size() <= push.size()); + BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment); + push.erase(push.begin() + pos, push.begin() + pos + datain.size()); + push.insert(push.begin() + pos, dataout.begin(), dataout.end()); + return *this; + } + + TestBuilder& DamagePush(unsigned int pos) + { + assert(havePush); + assert(pos < push.size()); + push[pos] ^= 1; + return *this; + } + + TestBuilder& Test(bool expect) + { + TestBuilder copy = *this; // Make a copy so we can rollback the push. + DoPush(); + DoTest(creditTx.vout[0].scriptPubKey, spendTx.vin[0].scriptSig, flags, expect, comment); + *this = copy; + return *this; + } + + operator std::string() + { + DoPush(); + return "[\"" + + FormatScript(spendTx.vin[0].scriptSig) + "\", \"" + + FormatScript(creditTx.vout[0].scriptPubKey) + "\", \"" + + FormatScriptFlags(flags) + "\", \"" + + comment + "\"],\n"; + } + + std::string GetComment() + { + return comment; + } + + const CScript& GetScriptPubKey() + { + return creditTx.vout[0].scriptPubKey; + } +}; +} + +BOOST_AUTO_TEST_CASE(script_build) +{ + std::vector<TestBuilder> good; + std::vector<TestBuilder> bad; + + good.push_back(TestBuilder(CScript() << keys.pubkey0 << OP_CHECKSIG, + "P2PK", 0 + ).PushSig(keys.key0)); + bad.push_back(TestBuilder(CScript() << keys.pubkey0 << OP_CHECKSIG, + "P2PK, bad sig", 0 + ).PushSig(keys.key0).DamagePush(10)); + + good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey1C.GetID() << OP_EQUALVERIFY << OP_CHECKSIG, + "P2PKH", 0 + ).PushSig(keys.key1).Push(keys.pubkey1C)); + bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey2C.GetID() << OP_EQUALVERIFY << OP_CHECKSIG, + "P2PKH, bad pubkey", 0 + ).PushSig(keys.key2).Push(keys.pubkey2C).DamagePush(5)); + + good.push_back(TestBuilder(CScript() << keys.pubkey1 << OP_CHECKSIG, + "P2PK anyonecanpay", 0 + ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY)); + bad.push_back(TestBuilder(CScript() << keys.pubkey1 << OP_CHECKSIG, + "P2PK anyonecanpay marked with normal hashtype", 0 + ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01")); + + good.push_back(TestBuilder(CScript() << keys.pubkey0C << OP_CHECKSIG, + "P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem()); + bad.push_back(TestBuilder(CScript() << keys.pubkey0C << OP_CHECKSIG, + "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).PushRedeem().DamagePush(10)); + + good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey1.GetID() << OP_EQUALVERIFY << OP_CHECKSIG, + "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true + ).PushSig(keys.key0).DamagePush(10).PushRedeem()); + bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << keys.pubkey1.GetID() << OP_EQUALVERIFY << OP_CHECKSIG, + "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true + ).PushSig(keys.key0).DamagePush(10).PushRedeem()); + + good.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG, + "3-of-3", 0 + ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG, + "3-of-3, 2 sigs", 0 + ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0)); + + good.push_back(TestBuilder(CScript() << OP_2 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG, + "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true + ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem()); + bad.push_back(TestBuilder(CScript() << OP_2 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG, + "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true + ).Num(0).PushSig(keys.key1).Num(0).PushRedeem()); + + good.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG, + "P2PK with too much R padding but no STRICTENC", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + bad.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG, + "P2PK with too much R padding", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); + good.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG, + "P2PK with too much S padding but no STRICTENC", 0 + ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); + bad.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG, + "P2PK with too much S padding", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); + good.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG, + "P2PK with too little R padding but no STRICTENC", 0 + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + bad.push_back(TestBuilder(CScript() << keys.pubkey1C << OP_CHECKSIG, + "P2PK with too little R padding", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); + + good.push_back(TestBuilder(CScript() << keys.pubkey2C << OP_CHECKSIG, + "P2PK with high S but no LOW_S", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); + good.push_back(TestBuilder(CScript() << keys.pubkey2C << OP_CHECKSIG, + "P2PK with high S but no STRICTENC", SCRIPT_VERIFY_LOW_S + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); + bad.push_back(TestBuilder(CScript() << keys.pubkey2C << OP_CHECKSIG, + "P2PK with high S", SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); + + good.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG, + "3-of-3 with nonzero dummy but no NULLDUMMY", 0 + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + bad.push_back(TestBuilder(CScript() << OP_3 << keys.pubkey0C << keys.pubkey1C << keys.pubkey2C << OP_3 << OP_CHECKMULTISIG, + "3-of-3 with nonzero dummy", SCRIPT_VERIFY_NULLDUMMY + ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2)); + + std::map<std::string, Array> tests_good; + std::map<std::string, Array> tests_bad; + + { + Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); + Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + + BOOST_FOREACH(Value& tv, json_good) { + Array test = tv.get_array(); + if (test.size() >= 4) { + tests_good[test[3].get_str()] = test; + } + } + BOOST_FOREACH(Value& tv, json_bad) { + Array test = tv.get_array(); + if (test.size() >= 4) { + tests_bad[test[3].get_str()] = test; + } + } + } + + std::string strGood; + std::string strBad; + + BOOST_FOREACH(TestBuilder& test, good) { + test.Test(true); + BOOST_CHECK_MESSAGE(tests_good.count(test.GetComment()) > 0, "Missing auto script_valid test: " + test.GetComment()); + BOOST_CHECK_MESSAGE(ParseScript(tests_good[test.GetComment()][1].get_str()) == test.GetScriptPubKey(), "ScriptPubKey mismatch in auto script_valid test: " + test.GetComment()); + strGood += test; + } + BOOST_FOREACH(TestBuilder& test, bad) { + test.Test(false); + BOOST_CHECK_MESSAGE(tests_bad.count(test.GetComment()) > 0, "Missing auto script_invalid test: " + test.GetComment()); + BOOST_CHECK_MESSAGE(ParseScript(tests_bad[test.GetComment()][1].get_str()) == test.GetScriptPubKey(), "ScriptPubKey mismatch in auto script_invalid test: " + test.GetComment()); + strBad += test; + } + +#if 0 + FILE* valid = fopen("script_valid.json.gen", "w"); + fputs(strGood.c_str(), valid); + fclose(valid); + FILE* invalid = fopen("script_invalid.json.gen", "w"); + fputs(strBad.c_str(), invalid); + fclose(invalid); +#endif +} + BOOST_AUTO_TEST_CASE(script_valid) { // Read tests from test/data/script_valid.json @@ -113,8 +424,7 @@ BOOST_AUTO_TEST_CASE(script_valid) CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - CTransaction tx; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, scriptPubKey), 0, scriptflags), strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, true, strTest); } } @@ -140,8 +450,7 @@ BOOST_AUTO_TEST_CASE(script_invalid) CScript scriptPubKey = ParseScript(scriptPubKeyString); unsigned int scriptflags = ParseScriptFlags(test[2].get_str()); - CTransaction tx; - BOOST_CHECK_MESSAGE(!VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, scriptPubKey), 0, scriptflags), strTest); + DoTest(scriptPubKey, scriptSig, scriptflags, false, strTest); } } diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 68fad8d038..6e5f0e3fac 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -31,7 +31,7 @@ struct TestingSetup { TestingSetup() { fPrintToDebugLog = false; // don't want to write to debug.log file - SelectParams(CBaseChainParams::MAIN); + SelectParams(CBaseChainParams::UNITTEST); noui_connect(); #ifdef ENABLE_WALLET bitdb.MakeMock(); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 41d8ee9f19..83116b51e5 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -17,6 +17,7 @@ #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/test/unit_test.hpp> +#include <boost/assign/list_of.hpp> #include "json/json_spirit_writer_template.h" using namespace std; @@ -26,22 +27,23 @@ using namespace boost::algorithm; // In script_tests.cpp extern Array read_json(const std::string& jsondata); -unsigned int ParseScriptFlags(string strFlags){ +// Note how NOCACHE is not included as it is a runtime-only flag. +static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of + (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) + (string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH) + (string("STRICTENC"), (unsigned int)SCRIPT_VERIFY_STRICTENC) + (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S) + (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY); + +unsigned int ParseScriptFlags(string strFlags) +{ + if (strFlags.empty()) { + return 0; + } unsigned int flags = 0; vector<string> words; split(words, strFlags, is_any_of(",")); - // Note how NOCACHE is not included as it is a runtime-only flag. - static map<string, unsigned int> mapFlagNames; - if (mapFlagNames.size() == 0) - { - mapFlagNames["NONE"] = SCRIPT_VERIFY_NONE; - mapFlagNames["P2SH"] = SCRIPT_VERIFY_P2SH; - mapFlagNames["STRICTENC"] = SCRIPT_VERIFY_STRICTENC; - mapFlagNames["LOW_S"] = SCRIPT_VERIFY_LOW_S; - mapFlagNames["NULLDUMMY"] = SCRIPT_VERIFY_NULLDUMMY; - } - BOOST_FOREACH(string word, words) { if (!mapFlagNames.count(word)) @@ -52,6 +54,22 @@ unsigned int ParseScriptFlags(string strFlags){ return flags; } +string FormatScriptFlags(unsigned int flags) +{ + if (flags == 0) { + return ""; + } + string ret; + std::map<string, unsigned int>::const_iterator it = mapFlagNames.begin(); + while (it != mapFlagNames.end()) { + if (flags & it->second) { + ret += it->first + ","; + } + it++; + } + return ret.substr(0, ret.size() - 1); +} + BOOST_AUTO_TEST_SUITE(transaction_tests) BOOST_AUTO_TEST_CASE(tx_valid) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index e077c9de3b..6378bd0941 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(util_FormatMoney) BOOST_AUTO_TEST_CASE(util_ParseMoney) { - int64_t ret = 0; + CAmount ret = 0; BOOST_CHECK(ParseMoney("0.0", ret)); BOOST_CHECK_EQUAL(ret, 0); diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp index 3887efbd0d..90fc470e06 100644 --- a/src/test/wallet_tests.cpp +++ b/src/test/wallet_tests.cpp @@ -28,7 +28,7 @@ BOOST_AUTO_TEST_SUITE(wallet_tests) static CWallet wallet; static vector<COutput> vCoins; -static void add_coin(int64_t nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) +static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) { static int nextLockTime = 0; CMutableTransaction tx; @@ -66,7 +66,7 @@ static bool equal_sets(CoinSet a, CoinSet b) BOOST_AUTO_TEST_CASE(coin_selection_tests) { CoinSet setCoinsRet, setCoinsRet2; - int64_t nValueRet; + CAmount nValueRet; LOCK(wallet.cs_wallet); diff --git a/src/txdb.cpp b/src/txdb.cpp index 79838b6116..d5f424fabd 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -117,7 +117,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) const { CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); stats.hashBlock = GetBestBlock(); ss << stats.hashBlock; - int64_t nTotalAmount = 0; + CAmount nTotalAmount = 0; while (pcursor->Valid()) { boost::this_thread::interruption_point(); try { diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 52d07bf6a0..d923c2204a 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -7,6 +7,7 @@ #include "core.h" #include "util.h" +#include "utilmoneystr.h" #include <boost/circular_buffer.hpp> @@ -18,7 +19,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(): nHeight = MEMPOOL_HEIGHT; } -CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, int64_t _nFee, +CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, unsigned int _nHeight): tx(_tx), nFee(_nFee), nTime(_nTime), dPriority(_dPriority), nHeight(_nHeight) @@ -36,7 +37,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) double CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const { - int64_t nValueIn = tx.GetValueOut()+nFee; + CAmount nValueIn = tx.GetValueOut()+nFee; double deltaPriority = ((double)(currentHeight-nHeight)*nValueIn)/nModSize; double dResult = dPriority + deltaPriority; return dResult; @@ -601,24 +602,24 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) return true; } -void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, int64_t nFeeDelta) +void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, const CAmount& nFeeDelta) { { LOCK(cs); - std::pair<double, int64_t> &deltas = mapDeltas[hash]; + std::pair<double, CAmount> &deltas = mapDeltas[hash]; deltas.first += dPriorityDelta; deltas.second += nFeeDelta; } - LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, nFeeDelta); + LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash, dPriorityDelta, FormatMoney(nFeeDelta)); } -void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta) +void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) { LOCK(cs); - std::map<uint256, std::pair<double, int64_t> >::iterator pos = mapDeltas.find(hash); + std::map<uint256, std::pair<double, CAmount> >::iterator pos = mapDeltas.find(hash); if (pos == mapDeltas.end()) return; - const std::pair<double, int64_t> &deltas = pos->second; + const std::pair<double, CAmount> &deltas = pos->second; dPriorityDelta += deltas.first; nFeeDelta += deltas.second; } diff --git a/src/txmempool.h b/src/txmempool.h index b9d50ee0bc..c35ea52d4e 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -29,7 +29,7 @@ class CTxMemPoolEntry { private: CTransaction tx; - int64_t nFee; // Cached to avoid expensive parent-transaction lookups + CAmount nFee; // Cached to avoid expensive parent-transaction lookups size_t nTxSize; // ... and avoid recomputing tx size size_t nModSize; // ... and modified size for priority int64_t nTime; // Local time when entering the mempool @@ -37,14 +37,14 @@ private: unsigned int nHeight; // Chain height when entering the mempool public: - CTxMemPoolEntry(const CTransaction& _tx, int64_t _nFee, + CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, int64_t _nTime, double _dPriority, unsigned int _nHeight); CTxMemPoolEntry(); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return this->tx; } double GetPriority(unsigned int currentHeight) const; - int64_t GetFee() const { return nFee; } + CAmount GetFee() const { return nFee; } size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } unsigned int GetHeight() const { return nHeight; } @@ -76,7 +76,7 @@ public: mutable CCriticalSection cs; std::map<uint256, CTxMemPoolEntry> mapTx; std::map<COutPoint, CInPoint> mapNextTx; - std::map<uint256, std::pair<double, int64_t> > mapDeltas; + std::map<uint256, std::pair<double, CAmount> > mapDeltas; CTxMemPool(const CFeeRate& _minRelayFee); ~CTxMemPool(); @@ -102,8 +102,8 @@ public: void AddTransactionsUpdated(unsigned int n); /** Affect CreateNewBlock prioritisation of transactions */ - void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, int64_t nFeeDelta); - void ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta); + void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, const CAmount& nFeeDelta); + void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta); void ClearPrioritisation(const uint256 hash); unsigned long size() diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp index c169355f05..1a5635bfb8 100644 --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -10,7 +10,7 @@ using namespace std; -string FormatMoney(int64_t n, bool fPlus) +string FormatMoney(const CAmount& n, bool fPlus) { // Note: not using straight sprintf here because we do NOT want // localized number formatting. @@ -34,12 +34,12 @@ string FormatMoney(int64_t n, bool fPlus) } -bool ParseMoney(const string& str, int64_t& nRet) +bool ParseMoney(const string& str, CAmount& nRet) { return ParseMoney(str.c_str(), nRet); } -bool ParseMoney(const char* pszIn, int64_t& nRet) +bool ParseMoney(const char* pszIn, CAmount& nRet) { string strWhole; int64_t nUnits = 0; @@ -73,7 +73,7 @@ bool ParseMoney(const char* pszIn, int64_t& nRet) if (nUnits < 0 || nUnits > COIN) return false; int64_t nWhole = atoi64(strWhole); - int64_t nValue = nWhole*COIN + nUnits; + CAmount nValue = nWhole*COIN + nUnits; nRet = nValue; return true; diff --git a/src/utilmoneystr.h b/src/utilmoneystr.h index f0c61aa138..65415afd3f 100644 --- a/src/utilmoneystr.h +++ b/src/utilmoneystr.h @@ -12,8 +12,10 @@ #include <stdint.h> #include <string> -std::string FormatMoney(int64_t n, bool fPlus=false); -bool ParseMoney(const std::string& str, int64_t& nRet); -bool ParseMoney(const char* pszIn, int64_t& nRet); +#include "amount.h" + +std::string FormatMoney(const CAmount& n, bool fPlus=false); +bool ParseMoney(const std::string& str, CAmount& nRet); +bool ParseMoney(const char* pszIn, CAmount& nRet); #endif // BITCOIN_UTILMONEYSTR_H diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 2cec3023b5..b9e64c5fe1 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -16,7 +16,7 @@ using namespace std; // safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything // even possibly remotely dangerous like & or > -static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@"); +static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()"); string SanitizeString(const string& str) { string strResult; diff --git a/src/wallet.cpp b/src/wallet.cpp index e69f59aacd..b20b0007ce 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -35,8 +35,8 @@ CFeeRate CWallet::minTxFee = CFeeRate(10000); // Override with -mintxfee struct CompareValueOnly { - bool operator()(const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t1, - const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t2) const + bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1, + const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const { return t1.first < t2.first; } @@ -697,7 +697,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const return ISMINE_NO; } -int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const +CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const { { LOCK(cs_wallet); @@ -781,7 +781,7 @@ int CWalletTx::GetRequestCount() const } void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, - list<COutputEntry>& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const + list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const { nFee = 0; listReceived.clear(); @@ -789,10 +789,10 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, strSentAccount = strFromAccount; // Compute fee: - int64_t nDebit = GetDebit(filter); + CAmount nDebit = GetDebit(filter); if (nDebit > 0) // debit>0 means we signed/sent this transaction { - int64_t nValueOut = GetValueOut(); + CAmount nValueOut = GetValueOut(); nFee = nDebit - nValueOut; } @@ -835,12 +835,12 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived, } -void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived, - int64_t& nSent, int64_t& nFee, const isminefilter& filter) const +void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived, + CAmount& nSent, CAmount& nFee, const isminefilter& filter) const { nReceived = nSent = nFee = 0; - int64_t allFee; + CAmount allFee; string strSentAccount; list<COutputEntry> listReceived; list<COutputEntry> listSent; @@ -1011,9 +1011,9 @@ void CWallet::ResendWalletTransactions() // -int64_t CWallet::GetBalance() const +CAmount CWallet::GetBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1027,9 +1027,9 @@ int64_t CWallet::GetBalance() const return nTotal; } -int64_t CWallet::GetUnconfirmedBalance() const +CAmount CWallet::GetUnconfirmedBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1042,9 +1042,9 @@ int64_t CWallet::GetUnconfirmedBalance() const return nTotal; } -int64_t CWallet::GetImmatureBalance() const +CAmount CWallet::GetImmatureBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1056,9 +1056,9 @@ int64_t CWallet::GetImmatureBalance() const return nTotal; } -int64_t CWallet::GetWatchOnlyBalance() const +CAmount CWallet::GetWatchOnlyBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1072,9 +1072,9 @@ int64_t CWallet::GetWatchOnlyBalance() const return nTotal; } -int64_t CWallet::GetUnconfirmedWatchOnlyBalance() const +CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1087,9 +1087,9 @@ int64_t CWallet::GetUnconfirmedWatchOnlyBalance() const return nTotal; } -int64_t CWallet::GetImmatureWatchOnlyBalance() const +CAmount CWallet::GetImmatureWatchOnlyBalance() const { - int64_t nTotal = 0; + CAmount nTotal = 0; { LOCK2(cs_main, cs_wallet); for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) @@ -1137,8 +1137,8 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const } } -static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > >vValue, int64_t nTotalLower, int64_t nTargetValue, - vector<char>& vfBest, int64_t& nBest, int iterations = 1000) +static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue, + vector<char>& vfBest, CAmount& nBest, int iterations = 1000) { vector<char> vfIncluded; @@ -1150,7 +1150,7 @@ static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,uns for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++) { vfIncluded.assign(vValue.size(), false); - int64_t nTotal = 0; + CAmount nTotal = 0; bool fReachedTarget = false; for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) { @@ -1183,18 +1183,18 @@ static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,uns } } -bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins, - set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const +bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins, + set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const { setCoinsRet.clear(); nValueRet = 0; // List of values less than target - pair<int64_t, pair<const CWalletTx*,unsigned int> > coinLowestLarger; - coinLowestLarger.first = std::numeric_limits<int64_t>::max(); + pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger; + coinLowestLarger.first = std::numeric_limits<CAmount>::max(); coinLowestLarger.second.first = NULL; - vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > > vValue; - int64_t nTotalLower = 0; + vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue; + CAmount nTotalLower = 0; random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); @@ -1209,9 +1209,9 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT continue; int i = output.i; - int64_t n = pcoin->vout[i].nValue; + CAmount n = pcoin->vout[i].nValue; - pair<int64_t,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i)); + pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i)); if (n == nTargetValue) { @@ -1252,7 +1252,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT // Solve subset sum by stochastic approximation sort(vValue.rbegin(), vValue.rend(), CompareValueOnly()); vector<char> vfBest; - int64_t nBest; + CAmount nBest; ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT) @@ -1284,7 +1284,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT return true; } -bool CWallet::SelectCoins(int64_t nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl) const +bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const { vector<COutput> vCoins; AvailableCoins(vCoins, true, coinControl); @@ -1310,11 +1310,11 @@ bool CWallet::SelectCoins(int64_t nTargetValue, set<pair<const CWalletTx*,unsign -bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) +bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) { - int64_t nValue = 0; - BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend) + CAmount nValue = 0; + BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend) { if (nValue < 0) { @@ -1343,10 +1343,10 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, txNew.vout.clear(); wtxNew.fFromMe = true; - int64_t nTotalValue = nValue + nFeeRet; + CAmount nTotalValue = nValue + nFeeRet; double dPriority = 0; // vouts to the payees - BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend) + BOOST_FOREACH (const PAIRTYPE(CScript, CAmount)& s, vecSend) { CTxOut txout(s.second, s.first); if (txout.IsDust(::minRelayTxFee)) @@ -1359,7 +1359,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, // Choose coins to use set<pair<const CWalletTx*,unsigned int> > setCoins; - int64_t nValueIn = 0; + CAmount nValueIn = 0; if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl)) { strFailReason = _("Insufficient funds"); @@ -1367,14 +1367,14 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, } BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { - int64_t nCredit = pcoin.first->vout[pcoin.second].nValue; + CAmount nCredit = pcoin.first->vout[pcoin.second].nValue; //The priority after the next block (depth+1) is used instead of the current, //reflecting an assumption the user would accept a bit more delay for //a chance at a free transaction. dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1); } - int64_t nChange = nValueIn - nValue - nFeeRet; + CAmount nChange = nValueIn - nValue - nFeeRet; if (nChange > 0) { @@ -1450,7 +1450,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, } dPriority = wtxNew.ComputePriority(dPriority, nBytes); - int64_t nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); + CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool); if (nFeeRet >= nFeeNeeded) break; // Done, enough fee included. @@ -1481,10 +1481,10 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, return true; } -bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) +bool CWallet::CreateTransaction(CScript scriptPubKey, const CAmount& nValue, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl) { - vector< pair<CScript, int64_t> > vecSend; + vector< pair<CScript, CAmount> > vecSend; vecSend.push_back(make_pair(scriptPubKey, nValue)); return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl); } @@ -1539,7 +1539,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) -string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew) +string CWallet::SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew) { // Check amount if (nValue <= 0) @@ -1560,7 +1560,7 @@ string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWallet // Create and send the transaction CReserveKey reservekey(this); - int64_t nFeeRequired; + CAmount nFeeRequired; if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) { if (nValue + nFeeRequired > GetBalance()) @@ -1576,10 +1576,10 @@ string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWallet -int64_t CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool) +CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool) { // payTxFee is user-set "I want to pay this much" - int64_t nFeeNeeded = payTxFee.GetFee(nTxBytes); + CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes); // User didn't set: use -txconfirmtarget to estimate... if (nFeeNeeded == 0) nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes); @@ -1838,9 +1838,9 @@ int64_t CWallet::GetOldestKeyPoolTime() return keypool.nTime; } -std::map<CTxDestination, int64_t> CWallet::GetAddressBalances() +std::map<CTxDestination, CAmount> CWallet::GetAddressBalances() { - map<CTxDestination, int64_t> balances; + map<CTxDestination, CAmount> balances; { LOCK(cs_wallet); @@ -1866,7 +1866,7 @@ std::map<CTxDestination, int64_t> CWallet::GetAddressBalances() if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr)) continue; - int64_t n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue; + CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue; if (!balances.count(addr)) balances[addr] = 0; diff --git a/src/wallet.h b/src/wallet.h index fde87a8a2f..f3fffb2253 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -30,9 +30,9 @@ extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; // -paytxfee default -static const int64_t DEFAULT_TRANSACTION_FEE = 0; +static const CAmount DEFAULT_TRANSACTION_FEE = 0; // -paytxfee will warn if called with a higher fee than this amount (in satoshis) per KB -static const int nHighTransactionFeeWarning = 0.01 * COIN; +static const CAmount nHighTransactionFeeWarning = 0.01 * COIN; // Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; @@ -98,7 +98,7 @@ public: class CWallet : public CCryptoKeyStore, public CWalletInterface { private: - bool SelectCoins(int64_t nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl *coinControl = NULL) const; + bool SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = NULL) const; CWalletDB *pwalletdbEncryption; @@ -182,7 +182,7 @@ public: bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const; - bool SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const; + bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const; bool IsSpent(const uint256& hash, unsigned int n) const; @@ -253,21 +253,21 @@ public: int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); void ReacceptWalletTransactions(); void ResendWalletTransactions(); - int64_t GetBalance() const; - int64_t GetUnconfirmedBalance() const; - int64_t GetImmatureBalance() const; - int64_t GetWatchOnlyBalance() const; - int64_t GetUnconfirmedWatchOnlyBalance() const; - int64_t GetImmatureWatchOnlyBalance() const; - bool CreateTransaction(const std::vector<std::pair<CScript, int64_t> >& vecSend, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); - bool CreateTransaction(CScript scriptPubKey, int64_t nValue, - CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); + CAmount GetBalance() const; + CAmount GetUnconfirmedBalance() const; + CAmount GetImmatureBalance() const; + CAmount GetWatchOnlyBalance() const; + CAmount GetUnconfirmedWatchOnlyBalance() const; + CAmount GetImmatureWatchOnlyBalance() const; + bool CreateTransaction(const std::vector<std::pair<CScript, CAmount> >& vecSend, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); + bool CreateTransaction(CScript scriptPubKey, const CAmount& nValue, + CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl *coinControl = NULL); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); - std::string SendMoney(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew); + std::string SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew); static CFeeRate minTxFee; - static int64_t GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); + static CAmount GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool); bool NewKeyPool(); bool TopUpKeyPool(unsigned int kpSize = 0); @@ -279,24 +279,24 @@ public: void GetAllReserveKeys(std::set<CKeyID>& setAddress) const; std::set< std::set<CTxDestination> > GetAddressGroupings(); - std::map<CTxDestination, int64_t> GetAddressBalances(); + std::map<CTxDestination, CAmount> GetAddressBalances(); std::set<CTxDestination> GetAccountAddresses(std::string strAccount) const; isminetype IsMine(const CTxIn& txin) const; - int64_t GetDebit(const CTxIn& txin, const isminefilter& filter) const; + CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; isminetype IsMine(const CTxOut& txout) const { return ::IsMine(*this, txout.scriptPubKey); } - int64_t GetCredit(const CTxOut& txout, const isminefilter& filter) const + 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); } bool IsChange(const CTxOut& txout) const; - int64_t GetChange(const CTxOut& txout) const + CAmount GetChange(const CTxOut& txout) const { if (!MoneyRange(txout.nValue)) throw std::runtime_error("CWallet::GetChange() : value out of range"); @@ -313,9 +313,9 @@ public: { return (GetDebit(tx, ISMINE_ALL) > 0); } - int64_t GetDebit(const CTransaction& tx, const isminefilter& filter) const + CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const { - int64_t nDebit = 0; + CAmount nDebit = 0; BOOST_FOREACH(const CTxIn& txin, tx.vin) { nDebit += GetDebit(txin, filter); @@ -324,9 +324,9 @@ public: } return nDebit; } - int64_t GetCredit(const CTransaction& tx, const isminefilter& filter) const + CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const { - int64_t nCredit = 0; + CAmount nCredit = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { nCredit += GetCredit(txout, filter); @@ -335,9 +335,9 @@ public: } return nCredit; } - int64_t GetChange(const CTransaction& tx) const + CAmount GetChange(const CTransaction& tx) const { - int64_t nChange = 0; + CAmount nChange = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { nChange += GetChange(txout); @@ -457,7 +457,7 @@ static void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue) struct COutputEntry { CTxDestination destination; - int64_t amount; + CAmount amount; int vout; }; @@ -545,15 +545,15 @@ public: mutable bool fImmatureWatchCreditCached; mutable bool fAvailableWatchCreditCached; mutable bool fChangeCached; - mutable int64_t nDebitCached; - mutable int64_t nCreditCached; - mutable int64_t nImmatureCreditCached; - mutable int64_t nAvailableCreditCached; - mutable int64_t nWatchDebitCached; - mutable int64_t nWatchCreditCached; - mutable int64_t nImmatureWatchCreditCached; - mutable int64_t nAvailableWatchCreditCached; - mutable int64_t nChangeCached; + mutable CAmount nDebitCached; + mutable CAmount nCreditCached; + mutable CAmount nImmatureCreditCached; + mutable CAmount nAvailableCreditCached; + mutable CAmount nWatchDebitCached; + mutable CAmount nWatchCreditCached; + mutable CAmount nImmatureWatchCreditCached; + mutable CAmount nAvailableWatchCreditCached; + mutable CAmount nChangeCached; CWalletTx() { @@ -670,12 +670,12 @@ public: } // filter decides which addresses will count towards the debit - int64_t GetDebit(const isminefilter& filter) const + CAmount GetDebit(const isminefilter& filter) const { if (vin.empty()) return 0; - int64_t debit = 0; + CAmount debit = 0; if(filter & ISMINE_SPENDABLE) { if (fDebitCached) @@ -701,7 +701,7 @@ public: return debit; } - int64_t GetCredit(bool fUseCache=true) const + CAmount GetCredit(bool fUseCache=true) const { // Must wait until coinbase is safely deep enough in the chain before valuing it if (IsCoinBase() && GetBlocksToMaturity() > 0) @@ -715,7 +715,7 @@ public: return nCreditCached; } - int64_t GetImmatureCredit(bool fUseCache=true) const + CAmount GetImmatureCredit(bool fUseCache=true) const { if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) { @@ -729,7 +729,7 @@ public: return 0; } - int64_t GetAvailableCredit(bool fUseCache=true) const + CAmount GetAvailableCredit(bool fUseCache=true) const { if (pwallet == 0) return 0; @@ -741,7 +741,7 @@ public: if (fUseCache && fAvailableCreditCached) return nAvailableCreditCached; - int64_t nCredit = 0; + CAmount nCredit = 0; uint256 hashTx = GetHash(); for (unsigned int i = 0; i < vout.size(); i++) { @@ -759,7 +759,7 @@ public: return nCredit; } - int64_t GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const + CAmount GetImmatureWatchOnlyCredit(const bool& fUseCache=true) const { if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain()) { @@ -773,7 +773,7 @@ public: return 0; } - int64_t GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const + CAmount GetAvailableWatchOnlyCredit(const bool& fUseCache=true) const { if (pwallet == 0) return 0; @@ -785,7 +785,7 @@ public: if (fUseCache && fAvailableWatchCreditCached) return nAvailableWatchCreditCached; - int64_t nCredit = 0; + CAmount nCredit = 0; for (unsigned int i = 0; i < vout.size(); i++) { if (!pwallet->IsSpent(GetHash(), i)) @@ -802,7 +802,7 @@ public: return nCredit; } - int64_t GetChange() const + CAmount GetChange() const { if (fChangeCached) return nChangeCached; @@ -812,10 +812,10 @@ public: } void GetAmounts(std::list<COutputEntry>& listReceived, - std::list<COutputEntry>& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const; + std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const; - void GetAccountAmounts(const std::string& strAccount, int64_t& nReceived, - int64_t& nSent, int64_t& nFee, const isminefilter& filter) const; + void GetAccountAmounts(const std::string& strAccount, CAmount& nReceived, + CAmount& nSent, CAmount& nFee, const isminefilter& filter) const; bool IsFromMe(const isminefilter& filter) const { @@ -949,7 +949,7 @@ class CAccountingEntry { public: std::string strAccount; - int64_t nCreditDebit; + CAmount nCreditDebit; int64_t nTime; std::string strOtherAccount; std::string strComment; diff --git a/src/walletdb.cpp b/src/walletdb.cpp index a84f44db01..3e5a664a5d 100644 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -187,12 +187,12 @@ bool CWalletDB::WriteAccountingEntry(const CAccountingEntry& acentry) return WriteAccountingEntry(++nAccountingEntryNumber, acentry); } -int64_t CWalletDB::GetAccountCreditDebit(const string& strAccount) +CAmount CWalletDB::GetAccountCreditDebit(const string& strAccount) { list<CAccountingEntry> entries; ListAccountCreditDebit(strAccount, entries); - int64_t nCreditDebit = 0; + CAmount nCreditDebit = 0; BOOST_FOREACH (const CAccountingEntry& entry, entries) nCreditDebit += entry.nCreditDebit; @@ -391,13 +391,6 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, wss.fAnyUnordered = true; pwallet->AddToWallet(wtx, true); - //// debug print - //LogPrintf("LoadWallet %s\n", wtx.GetHash().ToString()); - //LogPrintf(" %12d %s %s %s\n", - // wtx.vout[0].nValue, - // DateTimeStrFormat("%Y-%m-%d %H:%M:%S", wtx.GetBlockTime()), - // wtx.hashBlock.ToString(), - // wtx.mapValue["message"]); } else if (strType == "acentry") { @@ -708,7 +701,6 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) DBErrors CWalletDB::FindWalletTx(CWallet* pwallet, vector<uint256>& vTxHash, vector<CWalletTx>& vWtx) { pwallet->vchDefaultKey = CPubKey(); - CWalletScanState wss; bool fNoncriticalErrors = false; DBErrors result = DB_LOAD_OK; diff --git a/src/walletdb.h b/src/walletdb.h index 2c5b608f3d..f3d6e61f8b 100644 --- a/src/walletdb.h +++ b/src/walletdb.h @@ -6,6 +6,7 @@ #ifndef BITCOIN_WALLETDB_H #define BITCOIN_WALLETDB_H +#include "amount.h" #include "db.h" #include "key.h" #include "keystore.h" @@ -118,7 +119,7 @@ public: bool EraseDestData(const std::string &address, const std::string &key); bool WriteAccountingEntry(const CAccountingEntry& acentry); - int64_t GetAccountCreditDebit(const std::string& strAccount); + CAmount GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); DBErrors ReorderTransactions(CWallet* pwallet); |