diff options
author | MarcoFalke <falke.marco@gmail.com> | 2019-10-10 09:18:25 -0400 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2019-10-10 09:18:34 -0400 |
commit | 2352aec9fc8222303f90784593949816357e43f6 (patch) | |
tree | 4826f579cb10e8fff55890e79e1e89632d15c596 /src | |
parent | b67ca4ee73d1e7e6d4eaa2c3b6eae507c62bbdbb (diff) | |
parent | 5c2987636faa5bc175b37b81fd98ab48e576da0b (diff) |
Merge #17076: tests: Add fuzzing harness for CheckTransaction(...), IsStandardTx(...) and other CTransaction related functions
5c2987636faa5bc175b37b81fd98ab48e576da0b tests: Remove TRANSACTION_DESERIALIZE (replaced by transaction fuzzer) (practicalswift)
0a573682f24d20cb178b8b6f97c35ec46901c4db tests: Add fuzzing harness for CheckTransaction(...), IsStandardTx(...) and other CTransaction related functions (practicalswift)
Pull request description:
Add fuzzing harness for `CheckTransaction(...)`, `IsStandardTx(...)` and other `CTransaction` related functions.
**Testing this PR**
Run:
```
$ CC=clang CXX=clang++ ./configure --enable-fuzz --with-sanitizers=address,fuzzer,undefined
$ make
$ src/test/fuzz/transaction
…
# And to to quickly verify that the relevant code regions are triggered, that the
# fuzzing throughput seems reasonable, etc.
$ contrib/devtools/test_fuzzing_harnesses.sh '^transaction$'
```
`test_fuzzing_harnesses.sh` can be found in PR #17000.
ACKs for top commit:
MarcoFalke:
ACK 5c2987636faa5bc175b37b81fd98ab48e576da0b
Tree-SHA512: 2f422df795c9dca13c98209ca9ce0fe5a0d4a71fb052fa33d599cc9c9f1d637fee27d58d02ed17b956b3e3d40931cbc1367fc99aa2e882473e54d95dee04d6b7
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.test.include | 15 | ||||
-rw-r--r-- | src/test/fuzz/deserialize.cpp | 5 | ||||
-rw-r--r-- | src/test/fuzz/transaction.cpp | 81 |
3 files changed, 89 insertions, 12 deletions
diff --git a/src/Makefile.test.include b/src/Makefile.test.include index d3fe138133..48df50d100 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -22,7 +22,7 @@ FUZZ_TARGETS = \ test/fuzz/netaddr_deserialize \ test/fuzz/script_flags \ test/fuzz/service_deserialize \ - test/fuzz/transaction_deserialize \ + test/fuzz/transaction \ test/fuzz/txoutcompressor_deserialize \ test/fuzz/txundo_deserialize @@ -202,12 +202,6 @@ test_fuzz_block_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_block_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) test_fuzz_block_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) -test_fuzz_transaction_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp -test_fuzz_transaction_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DTRANSACTION_DESERIALIZE=1 -test_fuzz_transaction_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) -test_fuzz_transaction_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -test_fuzz_transaction_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) - test_fuzz_blocklocator_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp test_fuzz_blocklocator_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DBLOCKLOCATOR_DESERIALIZE=1 test_fuzz_blocklocator_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) @@ -321,6 +315,13 @@ test_fuzz_blocktransactionsrequest_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCO test_fuzz_blocktransactionsrequest_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) test_fuzz_blocktransactionsrequest_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) test_fuzz_blocktransactionsrequest_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON) + +test_fuzz_transaction_SOURCES = $(FUZZ_SUITE) test/fuzz/transaction.cpp +test_fuzz_transaction_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) +test_fuzz_transaction_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) +test_fuzz_transaction_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) +test_fuzz_transaction_LDADD = $(FUZZ_SUITE_LD_COMMON) + endif # ENABLE_FUZZ nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index 3a74143dc2..3a6876ad39 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -40,11 +40,6 @@ void test_one_input(const std::vector<uint8_t>& buffer) CBlock block; ds >> block; } catch (const std::ios_base::failure& e) {return;} -#elif TRANSACTION_DESERIALIZE - try - { - CTransaction tx(deserialize, ds); - } catch (const std::ios_base::failure& e) {return;} #elif BLOCKLOCATOR_DESERIALIZE try { diff --git a/src/test/fuzz/transaction.cpp b/src/test/fuzz/transaction.cpp new file mode 100644 index 0000000000..96d7947b07 --- /dev/null +++ b/src/test/fuzz/transaction.cpp @@ -0,0 +1,81 @@ +// Copyright (c) 2019 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 <coins.h> +#include <consensus/tx_check.h> +#include <consensus/tx_verify.h> +#include <consensus/validation.h> +#include <core_io.h> +#include <core_memusage.h> +#include <policy/policy.h> +#include <policy/settings.h> +#include <primitives/transaction.h> +#include <streams.h> +#include <test/fuzz/fuzz.h> +#include <util/rbf.h> +#include <validation.h> +#include <version.h> + +#include <cassert> + +void test_one_input(const std::vector<uint8_t>& buffer) +{ + CDataStream ds(buffer, SER_NETWORK, INIT_PROTO_VERSION); + try { + int nVersion; + ds >> nVersion; + ds.SetVersion(nVersion); + } catch (const std::ios_base::failure& e) { + return; + } + bool valid = true; + const CTransaction tx = [&] { + try { + return CTransaction(deserialize, ds); + } catch (const std::ios_base::failure& e) { + valid = false; + return CTransaction(); + } + }(); + if (!valid) { + return; + } + + CValidationState state_with_dupe_check; + const bool valid_with_dupe_check = CheckTransaction(tx, state_with_dupe_check, /* fCheckDuplicateInputs= */ true); + CValidationState state_without_dupe_check; + const bool valid_without_dupe_check = CheckTransaction(tx, state_without_dupe_check, /* fCheckDuplicateInputs= */ false); + if (valid_with_dupe_check) { + assert(valid_without_dupe_check); + } + + const CFeeRate dust_relay_fee{DUST_RELAY_TX_FEE}; + std::string reason; + const bool is_standard_with_permit_bare_multisig = IsStandardTx(tx, /* permit_bare_multisig= */ true, dust_relay_fee, reason); + const bool is_standard_without_permit_bare_multisig = IsStandardTx(tx, /* permit_bare_multisig= */ false, dust_relay_fee, reason); + if (is_standard_without_permit_bare_multisig) { + assert(is_standard_with_permit_bare_multisig); + } + + (void)tx.GetHash(); + (void)tx.GetTotalSize(); + try { + (void)tx.GetValueOut(); + } catch (const std::runtime_error&) { + } + (void)tx.GetWitnessHash(); + (void)tx.HasWitness(); + (void)tx.IsCoinBase(); + (void)tx.IsNull(); + (void)tx.ToString(); + + (void)EncodeHexTx(tx); + (void)GetLegacySigOpCount(tx); + (void)GetTransactionWeight(tx); + (void)GetVirtualTransactionSize(tx); + (void)IsFinalTx(tx, /* nBlockHeight= */ 1024, /* nBlockTime= */ 1024); + (void)IsStandardTx(tx, reason); + (void)RecursiveDynamicUsage(tx); + (void)SignalsOptInRBF(tx); +} |