Auto merge of #3180 - str4d:transaction-serialization, r=ebfull
Upstream serialization improvements Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#5264 - bitcoin/bitcoin#6914 - bitcoin/bitcoin#6215 - bitcoin/bitcoin#8068 - Only the `COMPACTSIZE` wrapper commit - bitcoin/bitcoin#8658 - bitcoin/bitcoin#8708 - Only the serializer variadics commit - bitcoin/bitcoin#9039 - bitcoin/bitcoin#9125 - Only the first two commits (the last two block on other upstream PRs) Part of #2074.
This commit is contained in:
@@ -117,6 +117,22 @@ void RunTest(const TestVector &test) {
|
||||
}
|
||||
key = keyNew;
|
||||
pubkey = pubkeyNew;
|
||||
|
||||
CDataStream ssPub(SER_DISK, CLIENT_VERSION);
|
||||
ssPub << pubkeyNew;
|
||||
BOOST_CHECK(ssPub.size() == 75);
|
||||
|
||||
CDataStream ssPriv(SER_DISK, CLIENT_VERSION);
|
||||
ssPriv << keyNew;
|
||||
BOOST_CHECK(ssPriv.size() == 75);
|
||||
|
||||
CExtPubKey pubCheck;
|
||||
CExtKey privCheck;
|
||||
ssPub >> pubCheck;
|
||||
ssPriv >> privCheck;
|
||||
|
||||
BOOST_CHECK(pubCheck == pubkeyNew);
|
||||
BOOST_CHECK(privCheck == keyNew);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
|
||||
BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "BloomFilter doesn't contain just-inserted object (3)!");
|
||||
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
filter.Serialize(stream, SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << filter;
|
||||
|
||||
vector<unsigned char> vch = ParseHex("03614e9b050000000000000001");
|
||||
vector<char> expected(vch.size());
|
||||
@@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
|
||||
BOOST_CHECK_MESSAGE(filter.contains(ParseHex("b9300670b4c5366e95b2699e8b18bc75e5f729c5")), "BloomFilter doesn't contain just-inserted object (3)!");
|
||||
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
filter.Serialize(stream, SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << filter;
|
||||
|
||||
vector<unsigned char> vch = ParseHex("03ce4299050000000100008001");
|
||||
vector<char> expected(vch.size());
|
||||
@@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
|
||||
filter.insert(vector<unsigned char>(hash.begin(), hash.end()));
|
||||
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
filter.Serialize(stream, SER_NETWORK, PROTOCOL_VERSION);
|
||||
stream << filter;
|
||||
|
||||
vector<unsigned char> vch = ParseHex("038fc16b080000000000000001");
|
||||
vector<char> expected(vch.size());
|
||||
|
||||
@@ -163,7 +163,7 @@ struct StringContentsSerializer {
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
if (ser_action.ForRead()) {
|
||||
str.clear();
|
||||
char c = 0;
|
||||
|
||||
@@ -360,7 +360,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
|
||||
tx.vin[0].prevout.hash = hash;
|
||||
tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script;
|
||||
tx.vin[0].scriptSig = CScript() << std::vector<unsigned char>(script.begin(), script.end());
|
||||
tx.vout[0].nValue -= 10000;
|
||||
hash = tx.GetHash();
|
||||
mempool.addUnchecked(hash, entry.Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
|
||||
|
||||
217
src/test/prevector_tests.cpp
Normal file
217
src/test/prevector_tests.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
// Copyright (c) 2015 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <vector>
|
||||
#include "prevector.h"
|
||||
#include "random.h"
|
||||
|
||||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
|
||||
#include "test/test_bitcoin.h"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(PrevectorTests, TestingSetup)
|
||||
|
||||
template<unsigned int N, typename T>
|
||||
class prevector_tester {
|
||||
typedef std::vector<T> realtype;
|
||||
realtype real_vector;
|
||||
|
||||
typedef prevector<N, T> pretype;
|
||||
pretype pre_vector;
|
||||
|
||||
typedef typename pretype::size_type Size;
|
||||
|
||||
void test() {
|
||||
const pretype& const_pre_vector = pre_vector;
|
||||
BOOST_CHECK_EQUAL(real_vector.size(), pre_vector.size());
|
||||
BOOST_CHECK_EQUAL(real_vector.empty(), pre_vector.empty());
|
||||
for (Size s = 0; s < real_vector.size(); s++) {
|
||||
BOOST_CHECK(real_vector[s] == pre_vector[s]);
|
||||
BOOST_CHECK(&(pre_vector[s]) == &(pre_vector.begin()[s]));
|
||||
BOOST_CHECK(&(pre_vector[s]) == &*(pre_vector.begin() + s));
|
||||
BOOST_CHECK(&(pre_vector[s]) == &*((pre_vector.end() + s) - real_vector.size()));
|
||||
}
|
||||
// BOOST_CHECK(realtype(pre_vector) == real_vector);
|
||||
BOOST_CHECK(pretype(real_vector.begin(), real_vector.end()) == pre_vector);
|
||||
BOOST_CHECK(pretype(pre_vector.begin(), pre_vector.end()) == pre_vector);
|
||||
size_t pos = 0;
|
||||
BOOST_FOREACH(const T& v, pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[pos++]);
|
||||
}
|
||||
BOOST_REVERSE_FOREACH(const T& v, pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[--pos]);
|
||||
}
|
||||
BOOST_FOREACH(const T& v, const_pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[pos++]);
|
||||
}
|
||||
BOOST_REVERSE_FOREACH(const T& v, const_pre_vector) {
|
||||
BOOST_CHECK(v == real_vector[--pos]);
|
||||
}
|
||||
CDataStream ss1(SER_DISK, 0);
|
||||
CDataStream ss2(SER_DISK, 0);
|
||||
ss1 << real_vector;
|
||||
ss2 << pre_vector;
|
||||
BOOST_CHECK_EQUAL(ss1.size(), ss2.size());
|
||||
for (Size s = 0; s < ss1.size(); s++) {
|
||||
BOOST_CHECK_EQUAL(ss1[s], ss2[s]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void resize(Size s) {
|
||||
real_vector.resize(s);
|
||||
BOOST_CHECK_EQUAL(real_vector.size(), s);
|
||||
pre_vector.resize(s);
|
||||
BOOST_CHECK_EQUAL(pre_vector.size(), s);
|
||||
test();
|
||||
}
|
||||
|
||||
void reserve(Size s) {
|
||||
real_vector.reserve(s);
|
||||
BOOST_CHECK(real_vector.capacity() >= s);
|
||||
pre_vector.reserve(s);
|
||||
BOOST_CHECK(pre_vector.capacity() >= s);
|
||||
test();
|
||||
}
|
||||
|
||||
void insert(Size position, const T& value) {
|
||||
real_vector.insert(real_vector.begin() + position, value);
|
||||
pre_vector.insert(pre_vector.begin() + position, value);
|
||||
test();
|
||||
}
|
||||
|
||||
void insert(Size position, Size count, const T& value) {
|
||||
real_vector.insert(real_vector.begin() + position, count, value);
|
||||
pre_vector.insert(pre_vector.begin() + position, count, value);
|
||||
test();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void insert_range(Size position, I first, I last) {
|
||||
real_vector.insert(real_vector.begin() + position, first, last);
|
||||
pre_vector.insert(pre_vector.begin() + position, first, last);
|
||||
test();
|
||||
}
|
||||
|
||||
void erase(Size position) {
|
||||
real_vector.erase(real_vector.begin() + position);
|
||||
pre_vector.erase(pre_vector.begin() + position);
|
||||
test();
|
||||
}
|
||||
|
||||
void erase(Size first, Size last) {
|
||||
real_vector.erase(real_vector.begin() + first, real_vector.begin() + last);
|
||||
pre_vector.erase(pre_vector.begin() + first, pre_vector.begin() + last);
|
||||
test();
|
||||
}
|
||||
|
||||
void update(Size pos, const T& value) {
|
||||
real_vector[pos] = value;
|
||||
pre_vector[pos] = value;
|
||||
test();
|
||||
}
|
||||
|
||||
void push_back(const T& value) {
|
||||
real_vector.push_back(value);
|
||||
pre_vector.push_back(value);
|
||||
test();
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
real_vector.pop_back();
|
||||
pre_vector.pop_back();
|
||||
test();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
real_vector.clear();
|
||||
pre_vector.clear();
|
||||
}
|
||||
|
||||
void assign(Size n, const T& value) {
|
||||
real_vector.assign(n, value);
|
||||
pre_vector.assign(n, value);
|
||||
}
|
||||
|
||||
Size size() {
|
||||
return real_vector.size();
|
||||
}
|
||||
|
||||
Size capacity() {
|
||||
return pre_vector.capacity();
|
||||
}
|
||||
|
||||
void shrink_to_fit() {
|
||||
pre_vector.shrink_to_fit();
|
||||
test();
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PrevectorTestInt)
|
||||
{
|
||||
for (int j = 0; j < 64; j++) {
|
||||
prevector_tester<8, int> test;
|
||||
for (int i = 0; i < 2048; i++) {
|
||||
int r = insecure_rand();
|
||||
if ((r % 4) == 0) {
|
||||
test.insert(insecure_rand() % (test.size() + 1), insecure_rand());
|
||||
}
|
||||
if (test.size() > 0 && ((r >> 2) % 4) == 1) {
|
||||
test.erase(insecure_rand() % test.size());
|
||||
}
|
||||
if (((r >> 4) % 8) == 2) {
|
||||
int new_size = std::max<int>(0, std::min<int>(30, test.size() + (insecure_rand() % 5) - 2));
|
||||
test.resize(new_size);
|
||||
}
|
||||
if (((r >> 7) % 8) == 3) {
|
||||
test.insert(insecure_rand() % (test.size() + 1), 1 + (insecure_rand() % 2), insecure_rand());
|
||||
}
|
||||
if (((r >> 10) % 8) == 4) {
|
||||
int del = std::min<int>(test.size(), 1 + (insecure_rand() % 2));
|
||||
int beg = insecure_rand() % (test.size() + 1 - del);
|
||||
test.erase(beg, beg + del);
|
||||
}
|
||||
if (((r >> 13) % 16) == 5) {
|
||||
test.push_back(insecure_rand());
|
||||
}
|
||||
if (test.size() > 0 && ((r >> 17) % 16) == 6) {
|
||||
test.pop_back();
|
||||
}
|
||||
if (((r >> 21) % 32) == 7) {
|
||||
int values[4];
|
||||
int num = 1 + (insecure_rand() % 4);
|
||||
for (int i = 0; i < num; i++) {
|
||||
values[i] = insecure_rand();
|
||||
}
|
||||
test.insert_range(insecure_rand() % (test.size() + 1), values, values + num);
|
||||
}
|
||||
if (((r >> 26) % 32) == 8) {
|
||||
int del = std::min<int>(test.size(), 1 + (insecure_rand() % 4));
|
||||
int beg = insecure_rand() % (test.size() + 1 - del);
|
||||
test.erase(beg, beg + del);
|
||||
}
|
||||
r = insecure_rand();
|
||||
if (r % 32 == 9) {
|
||||
test.reserve(insecure_rand() % 32);
|
||||
}
|
||||
if ((r >> 5) % 64 == 10) {
|
||||
test.shrink_to_fit();
|
||||
}
|
||||
if (test.size() > 0) {
|
||||
test.update(insecure_rand() % test.size(), insecure_rand());
|
||||
}
|
||||
if (((r >> 11) & 1024) == 11) {
|
||||
test.clear();
|
||||
}
|
||||
if (((r >> 21) & 512) == 12) {
|
||||
test.assign(insecure_rand() % 32, insecure_rand());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -27,7 +27,7 @@ using namespace std;
|
||||
static std::vector<unsigned char>
|
||||
Serialize(const CScript& s)
|
||||
{
|
||||
std::vector<unsigned char> sSerialized(s);
|
||||
std::vector<unsigned char> sSerialized(s.begin(), s.end());
|
||||
return sSerialized;
|
||||
}
|
||||
|
||||
@@ -355,8 +355,8 @@ BOOST_DATA_TEST_CASE(AreInputsStandard, boost::unit_test::data::xrange(static_ca
|
||||
// SignSignature doesn't know how to sign these. We're
|
||||
// not testing validating signatures, so just create
|
||||
// dummy signatures that DO include the correct P2SH scripts:
|
||||
txTo.vin[3].scriptSig << OP_11 << OP_11 << static_cast<vector<unsigned char> >(oneAndTwo);
|
||||
txTo.vin[4].scriptSig << static_cast<vector<unsigned char> >(fifteenSigops);
|
||||
txTo.vin[3].scriptSig << OP_11 << OP_11 << vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
|
||||
txTo.vin[4].scriptSig << vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());
|
||||
|
||||
BOOST_CHECK(::AreInputsStandard(txTo, coins, consensusBranchId));
|
||||
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
|
||||
@@ -378,7 +378,7 @@ BOOST_DATA_TEST_CASE(AreInputsStandard, boost::unit_test::data::xrange(static_ca
|
||||
txToNonStd1.vin.resize(1);
|
||||
txToNonStd1.vin[0].prevout.n = 5;
|
||||
txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
|
||||
txToNonStd1.vin[0].scriptSig << static_cast<vector<unsigned char> >(sixteenSigops);
|
||||
txToNonStd1.vin[0].scriptSig << vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());
|
||||
|
||||
BOOST_CHECK(!::AreInputsStandard(txToNonStd1, coins, consensusBranchId));
|
||||
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1, coins), 16U);
|
||||
@@ -390,7 +390,7 @@ BOOST_DATA_TEST_CASE(AreInputsStandard, boost::unit_test::data::xrange(static_ca
|
||||
txToNonStd2.vin.resize(1);
|
||||
txToNonStd2.vin[0].prevout.n = 6;
|
||||
txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
|
||||
txToNonStd2.vin[0].scriptSig << static_cast<vector<unsigned char> >(twentySigops);
|
||||
txToNonStd2.vin[0].scriptSig << vector<unsigned char>(twentySigops.begin(), twentySigops.end());
|
||||
|
||||
BOOST_CHECK(!::AreInputsStandard(txToNonStd2, coins, consensusBranchId));
|
||||
BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2, coins), 20U);
|
||||
|
||||
@@ -264,7 +264,7 @@ public:
|
||||
|
||||
TestBuilder& PushRedeem()
|
||||
{
|
||||
DoPush(static_cast<std::vector<unsigned char> >(scriptPubKey));
|
||||
DoPush(std::vector<unsigned char>(scriptPubKey.begin(), scriptPubKey.end()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -808,7 +808,7 @@ BOOST_DATA_TEST_CASE(script_CHECKMULTISIG23, boost::unit_test::data::xrange(stat
|
||||
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
|
||||
}
|
||||
}
|
||||
|
||||
// Parameterized testing over consensus branch ids
|
||||
BOOST_DATA_TEST_CASE(script_combineSigs, boost::unit_test::data::xrange(static_cast<int>(Consensus::MAX_NETWORK_UPGRADES)))
|
||||
@@ -864,7 +864,7 @@ BOOST_DATA_TEST_CASE(script_combineSigs, boost::unit_test::data::xrange(static_c
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig);
|
||||
// dummy scriptSigCopy with placeholder, should always choose non-placeholder:
|
||||
scriptSigCopy = CScript() << OP_0 << static_cast<vector<unsigned char> >(pkSingle);
|
||||
scriptSigCopy = CScript() << OP_0 << vector<unsigned char>(pkSingle.begin(), pkSingle.end());
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), SignatureData(scriptSigCopy), consensusBranchId);
|
||||
@@ -958,4 +958,34 @@ BOOST_AUTO_TEST_CASE(script_IsPushOnly_on_invalid_scripts)
|
||||
BOOST_CHECK(!CScript(direct, direct+sizeof(direct)).IsPushOnly());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(script_GetScriptAsm)
|
||||
{
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2, true));
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY, true));
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_NOP2));
|
||||
BOOST_CHECK_EQUAL("OP_NOP2", ScriptToAsmStr(CScript() << OP_CHECKLOCKTIMEVERIFY));
|
||||
|
||||
string derSig("304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
|
||||
string pubKey("03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
|
||||
vector<unsigned char> vchPubKey = ToByteVector(ParseHex(pubKey));
|
||||
|
||||
BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey, true));
|
||||
BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey, true));
|
||||
BOOST_CHECK_EQUAL(derSig + "[ALL] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey, true));
|
||||
BOOST_CHECK_EQUAL(derSig + "[NONE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey, true));
|
||||
BOOST_CHECK_EQUAL(derSig + "[SINGLE] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey, true));
|
||||
BOOST_CHECK_EQUAL(derSig + "[ALL|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey, true));
|
||||
BOOST_CHECK_EQUAL(derSig + "[NONE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey, true));
|
||||
BOOST_CHECK_EQUAL(derSig + "[SINGLE|ANYONECANPAY] " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey, true));
|
||||
|
||||
BOOST_CHECK_EQUAL(derSig + "00 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "00")) << vchPubKey));
|
||||
BOOST_CHECK_EQUAL(derSig + "80 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "80")) << vchPubKey));
|
||||
BOOST_CHECK_EQUAL(derSig + "01 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "01")) << vchPubKey));
|
||||
BOOST_CHECK_EQUAL(derSig + "02 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "02")) << vchPubKey));
|
||||
BOOST_CHECK_EQUAL(derSig + "03 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "03")) << vchPubKey));
|
||||
BOOST_CHECK_EQUAL(derSig + "81 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "81")) << vchPubKey));
|
||||
BOOST_CHECK_EQUAL(derSig + "82 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "82")) << vchPubKey));
|
||||
BOOST_CHECK_EQUAL(derSig + "83 " + pubKey, ScriptToAsmStr(CScript() << ToByteVector(ParseHex(derSig + "83")) << vchPubKey));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -36,6 +36,50 @@ void check_ser_rep(T thing, std::vector<unsigned char> expected)
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
|
||||
|
||||
class CSerializeMethodsTestSingle
|
||||
{
|
||||
protected:
|
||||
int intval;
|
||||
bool boolval;
|
||||
std::string stringval;
|
||||
const char* charstrval;
|
||||
CTransaction txval;
|
||||
public:
|
||||
CSerializeMethodsTestSingle() = default;
|
||||
CSerializeMethodsTestSingle(int intvalin, bool boolvalin, std::string stringvalin, const char* charstrvalin, CTransaction txvalin) : intval(intvalin), boolval(boolvalin), stringval(std::move(stringvalin)), charstrval(charstrvalin), txval(txvalin){}
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITE(intval);
|
||||
READWRITE(boolval);
|
||||
READWRITE(stringval);
|
||||
READWRITE(FLATDATA(charstrval));
|
||||
READWRITE(txval);
|
||||
}
|
||||
|
||||
bool operator==(const CSerializeMethodsTestSingle& rhs)
|
||||
{
|
||||
return intval == rhs.intval && \
|
||||
boolval == rhs.boolval && \
|
||||
stringval == rhs.stringval && \
|
||||
strcmp(charstrval, rhs.charstrval) == 0 && \
|
||||
txval == rhs.txval;
|
||||
}
|
||||
};
|
||||
|
||||
class CSerializeMethodsTestMany : public CSerializeMethodsTestSingle
|
||||
{
|
||||
public:
|
||||
using CSerializeMethodsTestSingle::CSerializeMethodsTestSingle;
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action) {
|
||||
READWRITEMANY(intval, boolval, stringval, FLATDATA(charstrval), txval);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(boost_optional)
|
||||
{
|
||||
check_ser_rep<boost::optional<unsigned char>>(0xff, {0x01, 0xff});
|
||||
@@ -346,4 +390,30 @@ BOOST_AUTO_TEST_CASE(insert_delete)
|
||||
BOOST_CHECK_EQUAL(ss.size(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(class_methods)
|
||||
{
|
||||
int intval(100);
|
||||
bool boolval(true);
|
||||
std::string stringval("testing");
|
||||
const char* charstrval("testing charstr");
|
||||
CMutableTransaction txval;
|
||||
CSerializeMethodsTestSingle methodtest1(intval, boolval, stringval, charstrval, txval);
|
||||
CSerializeMethodsTestMany methodtest2(intval, boolval, stringval, charstrval, txval);
|
||||
CSerializeMethodsTestSingle methodtest3;
|
||||
CSerializeMethodsTestMany methodtest4;
|
||||
CDataStream ss(SER_DISK, PROTOCOL_VERSION);
|
||||
BOOST_CHECK(methodtest1 == methodtest2);
|
||||
ss << methodtest1;
|
||||
ss >> methodtest4;
|
||||
ss << methodtest2;
|
||||
ss >> methodtest3;
|
||||
BOOST_CHECK(methodtest1 == methodtest2);
|
||||
BOOST_CHECK(methodtest2 == methodtest3);
|
||||
BOOST_CHECK(methodtest3 == methodtest4);
|
||||
|
||||
CDataStream ss2(SER_DISK, PROTOCOL_VERSION, intval, boolval, stringval, FLATDATA(charstrval), txval);
|
||||
ss2 >> methodtest3;
|
||||
BOOST_CHECK(methodtest3 == methodtest4);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -20,7 +20,7 @@ using namespace std;
|
||||
static std::vector<unsigned char>
|
||||
Serialize(const CScript& s)
|
||||
{
|
||||
std::vector<unsigned char> sSerialized(s);
|
||||
std::vector<unsigned char> sSerialized(s.begin(), s.end());
|
||||
return sSerialized;
|
||||
}
|
||||
|
||||
|
||||
@@ -184,25 +184,25 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
|
||||
BOOST_CHECK(OneL.begin() + 32 == OneL.end());
|
||||
BOOST_CHECK(MaxL.begin() + 32 == MaxL.end());
|
||||
BOOST_CHECK(TmpL.begin() + 32 == TmpL.end());
|
||||
BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
|
||||
BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32);
|
||||
BOOST_CHECK(GetSerializeSize(R1L, 0, PROTOCOL_VERSION) == 32);
|
||||
BOOST_CHECK(GetSerializeSize(ZeroL, 0, PROTOCOL_VERSION) == 32);
|
||||
|
||||
std::stringstream ss;
|
||||
R1L.Serialize(ss,0,PROTOCOL_VERSION);
|
||||
CDataStream ss(0, PROTOCOL_VERSION);
|
||||
ss << R1L;
|
||||
BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+32));
|
||||
TmpL.Unserialize(ss,0,PROTOCOL_VERSION);
|
||||
ss >> TmpL;
|
||||
BOOST_CHECK(R1L == TmpL);
|
||||
ss.str("");
|
||||
ZeroL.Serialize(ss,0,PROTOCOL_VERSION);
|
||||
ss.clear();
|
||||
ss << ZeroL;
|
||||
BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+32));
|
||||
TmpL.Unserialize(ss,0,PROTOCOL_VERSION);
|
||||
ss >> TmpL;
|
||||
BOOST_CHECK(ZeroL == TmpL);
|
||||
ss.str("");
|
||||
MaxL.Serialize(ss,0,PROTOCOL_VERSION);
|
||||
ss.clear();
|
||||
ss << MaxL;
|
||||
BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+32));
|
||||
TmpL.Unserialize(ss,0,PROTOCOL_VERSION);
|
||||
ss >> TmpL;
|
||||
BOOST_CHECK(MaxL == TmpL);
|
||||
ss.str("");
|
||||
ss.clear();
|
||||
|
||||
BOOST_CHECK(R1S.GetHex() == R1S.ToString());
|
||||
BOOST_CHECK(R2S.GetHex() == R2S.ToString());
|
||||
@@ -230,24 +230,24 @@ BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 G
|
||||
BOOST_CHECK(OneS.begin() + 20 == OneS.end());
|
||||
BOOST_CHECK(MaxS.begin() + 20 == MaxS.end());
|
||||
BOOST_CHECK(TmpS.begin() + 20 == TmpS.end());
|
||||
BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
|
||||
BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20);
|
||||
BOOST_CHECK(GetSerializeSize(R1S, 0, PROTOCOL_VERSION) == 20);
|
||||
BOOST_CHECK(GetSerializeSize(ZeroS, 0, PROTOCOL_VERSION) == 20);
|
||||
|
||||
R1S.Serialize(ss,0,PROTOCOL_VERSION);
|
||||
ss << R1S;
|
||||
BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20));
|
||||
TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
|
||||
ss >> TmpS;
|
||||
BOOST_CHECK(R1S == TmpS);
|
||||
ss.str("");
|
||||
ZeroS.Serialize(ss,0,PROTOCOL_VERSION);
|
||||
ss.clear();
|
||||
ss << ZeroS;
|
||||
BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+20));
|
||||
TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
|
||||
ss >> TmpS;
|
||||
BOOST_CHECK(ZeroS == TmpS);
|
||||
ss.str("");
|
||||
MaxS.Serialize(ss,0,PROTOCOL_VERSION);
|
||||
ss.clear();
|
||||
ss << MaxS;
|
||||
BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+20));
|
||||
TmpS.Unserialize(ss,0,PROTOCOL_VERSION);
|
||||
ss >> TmpS;
|
||||
BOOST_CHECK(MaxS == TmpS);
|
||||
ss.str("");
|
||||
ss.clear();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( conversion )
|
||||
|
||||
Reference in New Issue
Block a user