Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ jobs:
- stage: test
env: >-
HOST=x86_64-unknown-linux-gnu
PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev"
DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1"
PACKAGES="python3-zmq cmake qtbase5-dev qttools5-dev-tools protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev"
DEP_OPTS="NO_QT=1 RAPIDCHECK=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1"
GOAL="install"
BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --enable-debug CXXFLAGS=\"-g0 -O2\""
# x86_64 Linux (no depends, only system libs)
Expand Down
18 changes: 16 additions & 2 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,25 @@ BITCOIN_TESTS =\

if ENABLE_PROPERTY_TESTS
BITCOIN_TESTS += \
test/key_properties.cpp
test/block_properties.cpp \
test/bloom_properties.cpp \
test/key_properties.cpp \
test/merkleblock_properties.cpp \
test/script_properties.cpp \
test/transaction_properties.cpp

BITCOIN_TEST_SUITE += \
test/gen/block_gen.cpp \
test/gen/block_gen.h \
test/gen/bloom_gen.cpp \
test/gen/bloom_gen.h \
test/gen/crypto_gen.cpp \
test/gen/crypto_gen.h
test/gen/crypto_gen.h \
test/gen/merkleblock_gen.h \
test/gen/script_gen.cpp \
test/gen/script_gen.h \
test/gen/transaction_gen.cpp \
test/gen/transaction_gen.h
endif

if ENABLE_WALLET
Expand Down
34 changes: 34 additions & 0 deletions src/test/block_properties.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <boost/test/unit_test.hpp>
#include <rapidcheck/boost_test.h>
#include <rapidcheck/gen/Arbitrary.h>
#include <rapidcheck/Gen.h>

#include <test/test_bitcoin.h>
#include <primitives/block.h>
#include <test/gen/block_gen.h>


BOOST_FIXTURE_TEST_SUITE(block_properties, BasicTestingSetup)

RC_BOOST_PROP(blockheader_serialization_symmetry, (const CBlockHeader& header))
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << header;
CBlockHeader header2;
ss >> header2;
CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION);
ss << header;
ss1 << header2;
RC_ASSERT(ss.str() == ss1.str());
}

RC_BOOST_PROP(block_serialization_symmetry, (const CBlock& block))
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << block;
CBlock block2;
ss >> block2;
RC_ASSERT(block.GetHash() == block2.GetHash());
}

BOOST_AUTO_TEST_SUITE_END()
35 changes: 35 additions & 0 deletions src/test/bloom_properties.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2012-2016 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 <test/gen/bloom_gen.h>
#include <test/gen/crypto_gen.h>

#include <test/test_bitcoin.h>

#include <boost/test/unit_test.hpp>
#include <rapidcheck/boost_test.h>
#include <rapidcheck/gen/Arbitrary.h>
#include <rapidcheck/Gen.h>


BOOST_FIXTURE_TEST_SUITE(bloom_properties, BasicTestingSetup)

RC_BOOST_PROP(no_false_negatives, (CBloomFilter bloom_filter, const uint256& hash))
{
bloom_filter.insert(hash);
bool result = bloom_filter.contains(hash);
RC_ASSERT(result);
}

RC_BOOST_PROP(serialization_symmetry, (const CBloomFilter& bloom_filter))
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << bloom_filter;
CBloomFilter bloom_filter2;
ss >> bloom_filter2;
CDataStream ss1(SER_NETWORK, PROTOCOL_VERSION);
ss << bloom_filter;
ss1 << bloom_filter2;
RC_ASSERT(ss.str() == ss1.str());
}
BOOST_AUTO_TEST_SUITE_END()
12 changes: 12 additions & 0 deletions src/test/gen/block_gen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <test/gen/block_gen.h>

#include <rapidcheck/Gen.h>

/** Generator for the primitives of a block header */
rc::Gen<BlockHeaderTup> BlockHeaderPrimitives()
{
return rc::gen::tuple(rc::gen::arbitrary<int32_t>(),
rc::gen::arbitrary<uint256>(), rc::gen::arbitrary<uint256>(),
rc::gen::arbitrary<uint32_t>(), rc::gen::arbitrary<uint32_t>(),
rc::gen::arbitrary<uint32_t>());
}
58 changes: 58 additions & 0 deletions src/test/gen/block_gen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef BITCOIN_TEST_GEN_BLOCK_GEN_H
#define BITCOIN_TEST_GEN_BLOCK_GEN_H

#include <test/gen/crypto_gen.h>
#include <test/gen/transaction_gen.h>
#include <uint256.h>
#include <primitives/block.h>

#include <rapidcheck/gen/Arbitrary.h>
#include <rapidcheck/Gen.h>


typedef std::tuple<int32_t, uint256, uint256, uint32_t, uint32_t, uint32_t> BlockHeaderTup;

/** Generator for the primitives of a block header */
rc::Gen<BlockHeaderTup> BlockHeaderPrimitives();

namespace rc
{
/** Generator for a new CBlockHeader */
template <>
struct Arbitrary<CBlockHeader> {
static Gen<CBlockHeader> arbitrary()
{
return gen::map(BlockHeaderPrimitives(), [](const BlockHeaderTup& primitives) {
int32_t nVersion;
uint256 hashPrevBlock;
uint256 hashMerkleRoot;
uint32_t nTime;
uint32_t nBits;
uint32_t nNonce;
std::tie(nVersion, hashPrevBlock, hashMerkleRoot, nTime, nBits, nNonce) = primitives;
CBlockHeader header;
header.nVersion = nVersion;
header.hashPrevBlock = hashPrevBlock;
header.hashMerkleRoot = hashMerkleRoot;
header.nTime = nTime;
header.nBits = nBits;
header.nNonce = nNonce;
return header;
});
};
};

/** Generator for a new CBlock */
template <>
struct Arbitrary<CBlock> {
static Gen<CBlock> arbitrary()
{
return gen::map(gen::nonEmpty<std::vector<CTransactionRef>>(), [](const std::vector<CTransactionRef>& refs) {
CBlock block;
block.vtx = refs;
return block;
});
}
};
} //namespace rc
#endif
59 changes: 59 additions & 0 deletions src/test/gen/bloom_gen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <test/gen/bloom_gen.h>
#include <test/gen/crypto_gen.h>

#include <bloom.h>
#include <math.h>

#include <rapidcheck/gen/Arbitrary.h>
#include <rapidcheck/Gen.h>
#include <rapidcheck/gen/Tuple.h>
#include <rapidcheck/gen/Predicate.h>
#include <rapidcheck/gen/Numeric.h>
#include <rapidcheck/gen/Container.h>

/** Generates a double between [0,1) */
rc::Gen<double> BetweenZeroAndOne()
{
return rc::gen::map(rc::gen::arbitrary<double>(), [](double x) {
double result = abs(fmod(x, 1));
assert(result >= 0 && result < 1);
return result;
});
}

rc::Gen<unsigned int> Between1And100()
{
return rc::gen::inRange<unsigned int>(1, 100);
}
/** Generates the C++ primitives used to create a bloom filter */
rc::Gen<std::tuple<unsigned int, double, unsigned int, unsigned int>> BloomFilterPrimitives()
{
return rc::gen::tuple(Between1And100(),
BetweenZeroAndOne(), rc::gen::arbitrary<unsigned int>(),
rc::gen::inRange<unsigned int>(0, 3));
}

/** Returns a bloom filter loaded with the given uint256s */
rc::Gen<std::pair<CBloomFilter, std::vector<uint256>>> LoadedBloomFilter()
{
return rc::gen::map(rc::gen::pair(rc::gen::arbitrary<CBloomFilter>(), rc::gen::arbitrary<std::vector<uint256>>()),
[](const std::pair<CBloomFilter, const std::vector<uint256>&>& primitives) {
CBloomFilter bloomFilter = primitives.first;
std::vector<uint256> hashes = primitives.second;
for (unsigned int i = 0; i < hashes.size(); i++) {
bloomFilter.insert(hashes[i]);
}
return std::make_pair(bloomFilter, hashes);
});
}

/** Loads an arbitrary bloom filter with the given hashes */
rc::Gen<std::pair<CBloomFilter, std::vector<uint256>>> LoadBloomFilter(const std::vector<uint256>& hashes)
{
return rc::gen::map(rc::gen::arbitrary<CBloomFilter>(), [&hashes](CBloomFilter bloomFilter) {
for (unsigned int i = 0; i < hashes.size(); i++) {
bloomFilter.insert(hashes[i]);
}
return std::make_pair(bloomFilter, hashes);
});
}
42 changes: 42 additions & 0 deletions src/test/gen/bloom_gen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef BITCOIN_TEST_GEN_BLOOM_GEN_H
#define BITCOIN_TEST_GEN_BLOOM_GEN_H

#include <bloom.h>
#include <merkleblock.h>

#include <math.h>

#include <rapidcheck/Gen.h>
#include <rapidcheck/gen/Arbitrary.h>

/** Generates a double between [0,1) */
rc::Gen<double> BetweenZeroAndOne();

rc::Gen<std::tuple<unsigned int, double, unsigned int, unsigned int>> BloomFilterPrimitives();

namespace rc
{
/** Generator for a new CBloomFilter*/
template <>
struct Arbitrary<CBloomFilter> {
static Gen<CBloomFilter> arbitrary()
{
return gen::map(BloomFilterPrimitives(), [](const std::tuple<unsigned int, double, unsigned int, unsigned int>& primitives) {
unsigned int num_elements;
double fp_rate;
unsigned int n_tweak_in;
unsigned int bloom_flag;
std::tie(num_elements, fp_rate, n_tweak_in, bloom_flag) = primitives;
return CBloomFilter(num_elements, fp_rate, n_tweak_in, bloom_flag);
});
};
};
} //namespace rc

/** Returns a bloom filter loaded with the returned uint256s */
rc::Gen<std::pair<CBloomFilter, std::vector<uint256>>> LoadedBloomFilter();

/** Loads an arbitrary bloom filter with the given hashes */
rc::Gen<std::pair<CBloomFilter, std::vector<uint256>>> LoadBloomFilter(const std::vector<uint256>& hashes);

#endif
10 changes: 7 additions & 3 deletions src/test/gen/crypto_gen.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Copyright (c) 2018 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 <test/gen/crypto_gen.h>

#include <key.h>
Expand All @@ -14,6 +11,13 @@
rc::Gen<std::vector<CKey>> MultisigKeys()
{
return rc::gen::suchThat(rc::gen::arbitrary<std::vector<CKey>>(), [](const std::vector<CKey>& keys) {
//TODO: Investigate why we can only allow 15 keys. Consensus rules
// dictate we can up to 20 keys
//https://github.com/bitcoin/bitcoin/blob/10bee0dd4f37eb6cb7a0f1d565fa0fecf8109c35/src/script/script.h#L29
//needs to be <= 16 keys because this assertion fails
//https://github.com/bitcoin/bitcoin/blob/10bee0dd4f37eb6cb7a0f1d565fa0fecf8109c35/src/script/script.h#L585
//ProduceSignature() fails for p2sh(multisig) if there are >= 16 keys
//this is why we are currently limited to the range >= 1 && <= 15
return keys.size() >= 1 && keys.size() <= 15;
});
};
3 changes: 0 additions & 3 deletions src/test/gen/crypto_gen.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_TEST_GEN_CRYPTO_GEN_H
#define BITCOIN_TEST_GEN_CRYPTO_GEN_H

Expand Down
Loading