aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp154
1 files changed, 65 insertions, 89 deletions
diff --git a/src/main.cpp b/src/main.cpp
index a5c1103ef4..c7ba15ef13 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,10 +20,10 @@
#include <sstream>
-#include <boost/dynamic_bitset.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
+#include <boost/thread.hpp>
using namespace std;
using namespace boost;
@@ -644,7 +644,7 @@ bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
// 2. P2SH scripts with a crazy number of expensive
// CHECKSIG/CHECKMULTISIG operations
//
-bool AreInputsStandard(const CTransaction& tx, CCoinsViewCache& mapInputs)
+bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
{
if (tx.IsCoinBase())
return true; // Coinbases don't use vin normally
@@ -717,7 +717,7 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx)
return nSigOps;
}
-unsigned int GetP2SHSigOpCount(const CTransaction& tx, CCoinsViewCache& inputs)
+unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs)
{
if (tx.IsCoinBase())
return 0;
@@ -1470,7 +1470,7 @@ bool VerifySignature(const CCoins& txFrom, const CTransaction& txTo, unsigned in
return CScriptCheck(txFrom, txTo, nIn, flags, nHashType)();
}
-bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
+bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
{
if (!tx.IsCoinBase())
{
@@ -3527,75 +3527,6 @@ void static ProcessGetData(CNode* pfrom)
}
}
-struct CCoin {
- uint32_t nTxVer; // Don't call this nVersion, that name has a special meaning inside IMPLEMENT_SERIALIZE
- uint32_t nHeight;
- CTxOut out;
-
- IMPLEMENT_SERIALIZE(
- READWRITE(nTxVer);
- READWRITE(nHeight);
- READWRITE(out);
- )
-};
-
-bool ProcessGetUTXOs(const vector<COutPoint> &vOutPoints, bool fCheckMemPool, vector<unsigned char> *result, vector<CCoin> *resultCoins)
-{
- // Defined by BIP 64.
- //
- // Allows a peer to retrieve the CTxOut structures corresponding to the given COutPoints.
- // Note that this data is not authenticated by anything: this code could just invent any
- // old rubbish and hand it back, with the peer being unable to tell unless they are checking
- // the outpoints against some out of band data.
- //
- // Also the answer could change the moment after we give it. However some apps can tolerate
- // this, because they're only using the result as a hint or are willing to trust the results
- // based on something else. For example we may be a "trusted node" for the peer, or it may
- // be checking the results given by several nodes for consistency, it may
- // run the UTXOs returned against scriptSigs of transactions obtained elsewhere (after checking
- // for a standard script form), and because the height in which the UTXO was defined is provided
- // a client that has a map of heights to block headers (as SPV clients do, for recent blocks)
- // can request the creating block via hash.
- //
- // IMPORTANT: Clients expect ordering to be preserved!
- if (vOutPoints.size() > MAX_INV_SZ)
- return error("message getutxos size() = %u", vOutPoints.size());
-
- LogPrint("net", "getutxos for %d queries %s mempool\n", vOutPoints.size(), fCheckMemPool ? "with" : "without");
-
- boost::dynamic_bitset<unsigned char> hits(vOutPoints.size());
- {
- LOCK2(cs_main, mempool.cs);
- CCoinsViewMemPool cvMemPool(*pcoinsTip, mempool);
- CCoinsViewCache view(fCheckMemPool ? cvMemPool : *pcoinsTip);
- for (size_t i = 0; i < vOutPoints.size(); i++)
- {
- CCoins coins;
- uint256 hash = vOutPoints[i].hash;
- if (view.GetCoins(hash, coins))
- {
- mempool.pruneSpent(hash, coins);
- if (coins.IsAvailable(vOutPoints[i].n))
- {
- hits[i] = true;
- // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if
- // n is valid but points to an already spent output (IsNull).
- CCoin coin;
- coin.nTxVer = coins.nVersion;
- coin.nHeight = coins.nHeight;
- coin.out = coins.vout.at(vOutPoints[i].n);
- assert(!coin.out.IsNull());
- resultCoins->push_back(coin);
- }
- }
- }
- }
-
- boost::to_block_range(hits, std::back_inserter(*result));
- return true;
-}
-
-
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();
@@ -3944,22 +3875,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
}
- else if (strCommand == "getutxos")
- {
- bool fCheckMemPool;
- vector<COutPoint> vOutPoints;
- vRecv >> fCheckMemPool;
- vRecv >> vOutPoints;
-
- vector<unsigned char> bitmap;
- vector<CCoin> outs;
- if (ProcessGetUTXOs(vOutPoints, fCheckMemPool, &bitmap, &outs))
- pfrom->PushMessage("utxos", chainActive.Height(), chainActive.Tip()->GetBlockHash(), bitmap, outs);
- else
- Misbehaving(pfrom->GetId(), 20);
- }
-
-
else if (strCommand == "tx")
{
vector<uint256> vWorkQueue;
@@ -4664,7 +4579,68 @@ 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);
+ if (!fileout)
+ return error("CBlockUndo::WriteToDisk : OpenUndoFile failed");
+
+ // Write index header
+ unsigned int nSize = fileout.GetSerializeSize(*this);
+ fileout << FLATDATA(Params().MessageStart()) << nSize;
+
+ // Write undo data
+ long fileOutPos = ftell(fileout);
+ if (fileOutPos < 0)
+ return error("CBlockUndo::WriteToDisk : ftell failed");
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << *this;
+
+ // calculate & write checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << *this;
+ fileout << hasher.GetHash();
+
+ // Flush stdio buffers and commit to disk before returning
+ fflush(fileout);
+ if (!IsInitialBlockDownload())
+ FileCommit(fileout);
+
+ return true;
+}
+
+bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock)
+{
+ // Open history file to read
+ CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (!filein)
+ return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed");
+
+ // Read block
+ uint256 hashChecksum;
+ try {
+ filein >> *this;
+ filein >> hashChecksum;
+ }
+ catch (std::exception &e) {
+ return error("%s : Deserialize or I/O error - %s", __func__, e.what());
+ }
+
+ // Verify checksum
+ CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
+ hasher << hashBlock;
+ hasher << *this;
+ if (hashChecksum != hasher.GetHash())
+ return error("CBlockUndo::ReadFromDisk : Checksum mismatch");
+
+ return true;
+}
+ std::string CBlockFileInfo::ToString() const {
+ return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, DateTimeStrFormat("%Y-%m-%d", nTimeFirst).c_str(), DateTimeStrFormat("%Y-%m-%d", nTimeLast).c_str());
+ }