aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp2
-rw-r--r--src/serialize.h55
-rw-r--r--src/test/script_tests.cpp37
3 files changed, 48 insertions, 46 deletions
diff --git a/src/main.cpp b/src/main.cpp
index f49c4dcede..83848bf849 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3085,6 +3085,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
int nLoaded = 0;
try {
+ // This takes over fileIn and calls fclose() on it in the CBufferedFile destructor
CBufferedFile blkdat(fileIn, 2*MAX_BLOCK_SIZE, MAX_BLOCK_SIZE+8, SER_DISK, CLIENT_VERSION);
uint64_t nStartByte = 0;
if (dbp) {
@@ -3141,7 +3142,6 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
LogPrintf("%s : Deserialize or I/O error - %s", __func__, e.what());
}
}
- fclose(fileIn);
} catch(std::runtime_error &e) {
AbortNode(_("Error: system error: ") + e.what());
}
diff --git a/src/serialize.h b/src/serialize.h
index 68501facf2..ff11edc06c 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -1154,7 +1154,7 @@ public:
-/** Non-refcounted 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().
@@ -1166,12 +1166,13 @@ private:
// Disallow copies
CAutoFile(const CAutoFile&);
CAutoFile& operator=(const CAutoFile&);
-protected:
- FILE* file;
-public:
+
int nType;
int nVersion;
+
+ FILE* file;
+public:
CAutoFile(FILE* filenew, int nTypeIn, int nVersionIn)
{
file = filenew;
@@ -1186,9 +1187,10 @@ public:
void fclose()
{
- if (file != NULL && file != stdin && file != stdout && file != stderr)
+ if (file) {
::fclose(file);
- file = NULL;
+ file = NULL;
+ }
}
FILE* release() { FILE* ret = file; file = NULL; return ret; }
@@ -1256,13 +1258,23 @@ public:
}
};
-/** Wrapper around a FILE* that implements a ring buffer to
- * deserialize from. It guarantees the ability to rewind
- * a given number of bytes. */
+/** Non-refcounted RAII wrapper around a FILE* that implements a ring buffer to
+ * deserialize from. It guarantees the ability to rewind a given number of bytes.
+ *
+ * Will automatically close the file when it goes out of scope if not null.
+ * If you need to close the file early, use file.fclose() instead of fclose(file).
+ */
class CBufferedFile
{
private:
- FILE *src; // source file
+ // Disallow copies
+ CBufferedFile(const CBufferedFile&);
+ CBufferedFile& operator=(const CBufferedFile&);
+
+ int nType;
+ int nVersion;
+
+ FILE *src; // source file
uint64_t nSrcPos; // how many bytes have been read from source
uint64_t nReadPos; // how many bytes have been read from this
uint64_t nReadLimit; // up to which position we're allowed to read
@@ -1289,12 +1301,25 @@ protected:
}
public:
- int nType;
- int nVersion;
-
CBufferedFile(FILE *fileIn, uint64_t nBufSize, uint64_t nRewindIn, int nTypeIn, int nVersionIn) :
- src(fileIn), nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0),
- nType(nTypeIn), nVersion(nVersionIn) {
+ nSrcPos(0), nReadPos(0), nReadLimit((uint64_t)(-1)), nRewind(nRewindIn), vchBuf(nBufSize, 0)
+ {
+ src = fileIn;
+ nType = nTypeIn;
+ nVersion = nVersionIn;
+ }
+
+ ~CBufferedFile()
+ {
+ fclose();
+ }
+
+ void fclose()
+ {
+ if (src) {
+ ::fclose(src);
+ src = NULL;
+ }
}
// check whether we're at the end of the source file
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 7f09b3daa1..48a5635d8f 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -70,7 +70,7 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey)
return txCredit;
}
-CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CTransaction& txCredit)
+CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMutableTransaction& txCredit)
{
CMutableTransaction txSpend;
txSpend.nVersion = 1;
@@ -521,16 +521,8 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
CScript scriptPubKey12;
scriptPubKey12 << OP_1 << key1.GetPubKey() << key2.GetPubKey() << OP_2 << OP_CHECKMULTISIG;
- CMutableTransaction txFrom12;
- txFrom12.vout.resize(1);
- txFrom12.vout[0].scriptPubKey = scriptPubKey12;
-
- CMutableTransaction txTo12;
- txTo12.vin.resize(1);
- txTo12.vout.resize(1);
- txTo12.vin[0].prevout.n = 0;
- txTo12.vin[0].prevout.hash = txFrom12.GetHash();
- txTo12.vout[0].nValue = 1;
+ CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12);
+ CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags));
@@ -555,16 +547,8 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
CScript scriptPubKey23;
scriptPubKey23 << OP_2 << key1.GetPubKey() << key2.GetPubKey() << key3.GetPubKey() << OP_3 << OP_CHECKMULTISIG;
- CMutableTransaction txFrom23;
- txFrom23.vout.resize(1);
- txFrom23.vout[0].scriptPubKey = scriptPubKey23;
-
- CMutableTransaction txTo23;
- txTo23.vin.resize(1);
- txTo23.vout.resize(1);
- txTo23.vin[0].prevout.n = 0;
- txTo23.vin[0].prevout.hash = txFrom23.GetHash();
- txTo23.vout[0].nValue = 1;
+ CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23);
+ CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23);
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
@@ -626,17 +610,10 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
keystore.AddKey(key);
}
- CMutableTransaction txFrom;
- txFrom.vout.resize(1);
- txFrom.vout[0].scriptPubKey = GetScriptForDestination(keys[0].GetPubKey().GetID());
+ CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID()));
+ CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom);
CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
- CMutableTransaction txTo;
- txTo.vin.resize(1);
- txTo.vout.resize(1);
- txTo.vin[0].prevout.n = 0;
- txTo.vin[0].prevout.hash = txFrom.GetHash();
CScript& scriptSig = txTo.vin[0].scriptSig;
- txTo.vout[0].nValue = 1;
CScript empty;
CScript combined = CombineSignatures(scriptPubKey, txTo, 0, empty, empty);