aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/README.md2
-rw-r--r--src/test/addrman_tests.cpp180
-rw-r--r--src/test/base58_tests.cpp2
-rw-r--r--src/test/leveldbwrapper_tests.cpp207
-rw-r--r--src/test/mempool_tests.cpp181
-rw-r--r--src/test/miner_tests.cpp2
-rw-r--r--src/test/netbase_tests.cpp82
-rw-r--r--src/test/pmt_tests.cpp2
-rw-r--r--src/test/reverselock_tests.cpp64
-rw-r--r--src/test/rpc_tests.cpp31
-rw-r--r--src/test/rpc_wallet_tests.cpp2
-rw-r--r--src/test/script_tests.cpp34
-rw-r--r--src/test/sighash_tests.cpp2
-rw-r--r--src/test/streams_tests.cpp67
-rw-r--r--src/test/transaction_tests.cpp25
-rw-r--r--src/test/univalue_tests.cpp17
-rw-r--r--src/test/util_tests.cpp4
17 files changed, 865 insertions, 39 deletions
diff --git a/src/test/README.md b/src/test/README.md
index e36112bd4f..b2d6be14f1 100644
--- a/src/test/README.md
+++ b/src/test/README.md
@@ -16,6 +16,8 @@ their tests in a test suite called "<source_filename>_tests". For an
examples of this pattern, examine uint160_tests.cpp and
uint256_tests.cpp.
+Add the source files to /src/Makefile.test.include to add them to the build.
+
For further reading, I found the following website to be helpful in
explaining how the boost unit test framework works:
[http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/).
diff --git a/src/test/addrman_tests.cpp b/src/test/addrman_tests.cpp
new file mode 100644
index 0000000000..cfcdd9abb2
--- /dev/null
+++ b/src/test/addrman_tests.cpp
@@ -0,0 +1,180 @@
+// Copyright (c) 2012-2013 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 "addrman.h"
+#include "test/test_bitcoin.h"
+#include <string>
+#include <boost/test/unit_test.hpp>
+
+#include "random.h"
+
+using namespace std;
+
+class CAddrManTest : public CAddrMan{};
+
+BOOST_FIXTURE_TEST_SUITE(addrman_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(addrman_simple)
+{
+ CAddrManTest addrman;
+
+ // Set addrman addr placement to be deterministic.
+ addrman.MakeDeterministic();
+
+ CNetAddr source = CNetAddr("252.2.2.2:8333");
+
+ // Test 1: Does Addrman respond correctly when empty.
+ BOOST_CHECK(addrman.size() == 0);
+ CAddrInfo addr_null = addrman.Select();
+ BOOST_CHECK(addr_null.ToString() == "[::]:0");
+
+ // Test 2: Does Addrman::Add work as expected.
+ CService addr1 = CService("250.1.1.1:8333");
+ addrman.Add(CAddress(addr1), source);
+ BOOST_CHECK(addrman.size() == 1);
+ CAddrInfo addr_ret1 = addrman.Select();
+ BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");
+
+ // Test 3: Does IP address deduplication work correctly.
+ // Expected dup IP should not be added.
+ CService addr1_dup = CService("250.1.1.1:8333");
+ addrman.Add(CAddress(addr1_dup), source);
+ BOOST_CHECK(addrman.size() == 1);
+
+
+ // Test 5: New table has one addr and we add a diff addr we should
+ // have two addrs.
+ CService addr2 = CService("250.1.1.2:8333");
+ addrman.Add(CAddress(addr2), source);
+ BOOST_CHECK(addrman.size() == 2);
+
+ // Test 6: AddrMan::Clear() should empty the new table.
+ addrman.Clear();
+ BOOST_CHECK(addrman.size() == 0);
+ CAddrInfo addr_null2 = addrman.Select();
+ BOOST_CHECK(addr_null2.ToString() == "[::]:0");
+}
+
+BOOST_AUTO_TEST_CASE(addrman_ports)
+{
+ CAddrManTest addrman;
+
+ // Set addrman addr placement to be deterministic.
+ addrman.MakeDeterministic();
+
+ CNetAddr source = CNetAddr("252.2.2.2:8333");
+
+ BOOST_CHECK(addrman.size() == 0);
+
+ // Test 7; Addr with same IP but diff port does not replace existing addr.
+ CService addr1 = CService("250.1.1.1:8333");
+ addrman.Add(CAddress(addr1), source);
+ BOOST_CHECK(addrman.size() == 1);
+
+ CService addr1_port = CService("250.1.1.1:8334");
+ addrman.Add(CAddress(addr1_port), source);
+ BOOST_CHECK(addrman.size() == 1);
+ CAddrInfo addr_ret2 = addrman.Select();
+ BOOST_CHECK(addr_ret2.ToString() == "250.1.1.1:8333");
+
+ // Test 8: Add same IP but diff port to tried table, it doesn't get added.
+ // Perhaps this is not ideal behavior but it is the current behavior.
+ addrman.Good(CAddress(addr1_port));
+ BOOST_CHECK(addrman.size() == 1);
+ bool newOnly = true;
+ CAddrInfo addr_ret3 = addrman.Select(newOnly);
+ BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333");
+}
+
+
+BOOST_AUTO_TEST_CASE(addrman_select)
+{
+ CAddrManTest addrman;
+
+ // Set addrman addr placement to be deterministic.
+ addrman.MakeDeterministic();
+
+ CNetAddr source = CNetAddr("252.2.2.2:8333");
+
+ // Test 9: Select from new with 1 addr in new.
+ CService addr1 = CService("250.1.1.1:8333");
+ addrman.Add(CAddress(addr1), source);
+ BOOST_CHECK(addrman.size() == 1);
+
+ bool newOnly = true;
+ CAddrInfo addr_ret1 = addrman.Select(newOnly);
+ BOOST_CHECK(addr_ret1.ToString() == "250.1.1.1:8333");
+
+
+ // Test 10: move addr to tried, select from new expected nothing returned.
+ addrman.Good(CAddress(addr1));
+ BOOST_CHECK(addrman.size() == 1);
+ CAddrInfo addr_ret2 = addrman.Select(newOnly);
+ BOOST_CHECK(addr_ret2.ToString() == "[::]:0");
+
+ CAddrInfo addr_ret3 = addrman.Select();
+ BOOST_CHECK(addr_ret3.ToString() == "250.1.1.1:8333");
+}
+
+BOOST_AUTO_TEST_CASE(addrman_new_collisions)
+{
+ CAddrManTest addrman;
+
+ // Set addrman addr placement to be deterministic.
+ addrman.MakeDeterministic();
+
+ CNetAddr source = CNetAddr("252.2.2.2:8333");
+
+ BOOST_CHECK(addrman.size() == 0);
+
+ for (unsigned int i = 1; i < 4; i++){
+ CService addr = CService("250.1.1."+boost::to_string(i));
+ addrman.Add(CAddress(addr), source);
+
+ //Test 11: No collision in new table yet.
+ BOOST_CHECK(addrman.size() == i);
+ }
+
+ //Test 12: new table collision!
+ CService addr1 = CService("250.1.1.4");
+ addrman.Add(CAddress(addr1), source);
+ BOOST_CHECK(addrman.size() == 3);
+
+ CService addr2 = CService("250.1.1.5");
+ addrman.Add(CAddress(addr2), source);
+ BOOST_CHECK(addrman.size() == 4);
+}
+
+BOOST_AUTO_TEST_CASE(addrman_tried_collisions)
+{
+ CAddrManTest addrman;
+
+ // Set addrman addr placement to be deterministic.
+ addrman.MakeDeterministic();
+
+ CNetAddr source = CNetAddr("252.2.2.2:8333");
+
+ BOOST_CHECK(addrman.size() == 0);
+
+ for (unsigned int i = 1; i < 75; i++){
+ CService addr = CService("250.1.1."+boost::to_string(i));
+ addrman.Add(CAddress(addr), source);
+ addrman.Good(CAddress(addr));
+
+ //Test 13: No collision in tried table yet.
+ BOOST_TEST_MESSAGE(addrman.size());
+ BOOST_CHECK(addrman.size() == i);
+ }
+
+ //Test 14: tried table collision!
+ CService addr1 = CService("250.1.1.76");
+ addrman.Add(CAddress(addr1), source);
+ BOOST_CHECK(addrman.size() == 74);
+
+ CService addr2 = CService("250.1.1.77");
+ addrman.Add(CAddress(addr2), source);
+ BOOST_CHECK(addrman.size() == 75);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index 9e74f5f427..9845df697f 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -18,7 +18,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
extern UniValue read_json(const std::string& jsondata);
diff --git a/src/test/leveldbwrapper_tests.cpp b/src/test/leveldbwrapper_tests.cpp
new file mode 100644
index 0000000000..606313b004
--- /dev/null
+++ b/src/test/leveldbwrapper_tests.cpp
@@ -0,0 +1,207 @@
+// Copyright (c) 2012-2013 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 "leveldbwrapper.h"
+#include "uint256.h"
+#include "random.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/assign/std/vector.hpp> // for 'operator+=()'
+#include <boost/assert.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+using namespace boost::assign; // bring 'operator+=()' into scope
+using namespace boost::filesystem;
+
+// Test if a string consists entirely of null characters
+bool is_null_key(const vector<unsigned char>& key) {
+ bool isnull = true;
+
+ for (unsigned int i = 0; i < key.size(); i++)
+ isnull &= (key[i] == '\x00');
+
+ return isnull;
+}
+
+BOOST_FIXTURE_TEST_SUITE(leveldbwrapper_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(leveldbwrapper)
+{
+ // Perform tests both obfuscated and non-obfuscated.
+ for (int i = 0; i < 2; i++) {
+ bool obfuscate = (bool)i;
+ path ph = temp_directory_path() / unique_path();
+ CLevelDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
+ char key = 'k';
+ uint256 in = GetRandHash();
+ uint256 res;
+
+ // Ensure that we're doing real obfuscation when obfuscate=true
+ BOOST_CHECK(obfuscate != is_null_key(dbw.GetObfuscateKey()));
+
+ BOOST_CHECK(dbw.Write(key, in));
+ BOOST_CHECK(dbw.Read(key, res));
+ BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
+ }
+}
+
+// Test batch operations
+BOOST_AUTO_TEST_CASE(leveldbwrapper_batch)
+{
+ // Perform tests both obfuscated and non-obfuscated.
+ for (int i = 0; i < 2; i++) {
+ bool obfuscate = (bool)i;
+ path ph = temp_directory_path() / unique_path();
+ CLevelDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
+
+ char key = 'i';
+ uint256 in = GetRandHash();
+ char key2 = 'j';
+ uint256 in2 = GetRandHash();
+ char key3 = 'k';
+ uint256 in3 = GetRandHash();
+
+ uint256 res;
+ CLevelDBBatch batch(&dbw.GetObfuscateKey());
+
+ batch.Write(key, in);
+ batch.Write(key2, in2);
+ batch.Write(key3, in3);
+
+ // Remove key3 before it's even been written
+ batch.Erase(key3);
+
+ dbw.WriteBatch(batch);
+
+ BOOST_CHECK(dbw.Read(key, res));
+ BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
+ BOOST_CHECK(dbw.Read(key2, res));
+ BOOST_CHECK_EQUAL(res.ToString(), in2.ToString());
+
+ // key3 never should've been written
+ BOOST_CHECK(dbw.Read(key3, res) == false);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(leveldbwrapper_iterator)
+{
+ // Perform tests both obfuscated and non-obfuscated.
+ for (int i = 0; i < 2; i++) {
+ bool obfuscate = (bool)i;
+ path ph = temp_directory_path() / unique_path();
+ CLevelDBWrapper dbw(ph, (1 << 20), true, false, obfuscate);
+
+ // The two keys are intentionally chosen for ordering
+ char key = 'j';
+ uint256 in = GetRandHash();
+ BOOST_CHECK(dbw.Write(key, in));
+ char key2 = 'k';
+ uint256 in2 = GetRandHash();
+ BOOST_CHECK(dbw.Write(key2, in2));
+
+ boost::scoped_ptr<CLevelDBIterator> it(const_cast<CLevelDBWrapper*>(&dbw)->NewIterator());
+
+ // Be sure to seek past the obfuscation key (if it exists)
+ it->Seek(key);
+
+ char key_res;
+ uint256 val_res;
+
+ it->GetKey(key_res);
+ it->GetValue(val_res);
+ BOOST_CHECK_EQUAL(key_res, key);
+ BOOST_CHECK_EQUAL(val_res.ToString(), in.ToString());
+
+ it->Next();
+
+ it->GetKey(key_res);
+ it->GetValue(val_res);
+ BOOST_CHECK_EQUAL(key_res, key2);
+ BOOST_CHECK_EQUAL(val_res.ToString(), in2.ToString());
+
+ it->Next();
+ BOOST_CHECK_EQUAL(it->Valid(), false);
+ }
+}
+
+// Test that we do not obfuscation if there is existing data.
+BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
+{
+ // We're going to share this path between two wrappers
+ path ph = temp_directory_path() / unique_path();
+ create_directories(ph);
+
+ // Set up a non-obfuscated wrapper to write some initial data.
+ CLevelDBWrapper* dbw = new CLevelDBWrapper(ph, (1 << 10), false, false, false);
+ char key = 'k';
+ uint256 in = GetRandHash();
+ uint256 res;
+
+ BOOST_CHECK(dbw->Write(key, in));
+ BOOST_CHECK(dbw->Read(key, res));
+ BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
+
+ // Call the destructor to free leveldb LOCK
+ delete dbw;
+
+ // Now, set up another wrapper that wants to obfuscate the same directory
+ CLevelDBWrapper odbw(ph, (1 << 10), false, false, true);
+
+ // Check that the key/val we wrote with unobfuscated wrapper exists and
+ // is readable.
+ uint256 res2;
+ BOOST_CHECK(odbw.Read(key, res2));
+ BOOST_CHECK_EQUAL(res2.ToString(), in.ToString());
+
+ BOOST_CHECK(!odbw.IsEmpty()); // There should be existing data
+ BOOST_CHECK(is_null_key(odbw.GetObfuscateKey())); // The key should be an empty string
+
+ uint256 in2 = GetRandHash();
+ uint256 res3;
+
+ // Check that we can write successfully
+ BOOST_CHECK(odbw.Write(key, in2));
+ BOOST_CHECK(odbw.Read(key, res3));
+ BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString());
+}
+
+// Ensure that we start obfuscating during a reindex.
+BOOST_AUTO_TEST_CASE(existing_data_reindex)
+{
+ // We're going to share this path between two wrappers
+ path ph = temp_directory_path() / unique_path();
+ create_directories(ph);
+
+ // Set up a non-obfuscated wrapper to write some initial data.
+ CLevelDBWrapper* dbw = new CLevelDBWrapper(ph, (1 << 10), false, false, false);
+ char key = 'k';
+ uint256 in = GetRandHash();
+ uint256 res;
+
+ BOOST_CHECK(dbw->Write(key, in));
+ BOOST_CHECK(dbw->Read(key, res));
+ BOOST_CHECK_EQUAL(res.ToString(), in.ToString());
+
+ // Call the destructor to free leveldb LOCK
+ delete dbw;
+
+ // Simulate a -reindex by wiping the existing data store
+ CLevelDBWrapper odbw(ph, (1 << 10), false, true, true);
+
+ // Check that the key/val we wrote with unobfuscated wrapper doesn't exist
+ uint256 res2;
+ BOOST_CHECK(!odbw.Read(key, res2));
+ BOOST_CHECK(!is_null_key(odbw.GetObfuscateKey()));
+
+ uint256 in2 = GetRandHash();
+ uint256 res3;
+
+ // Check that we can write successfully
+ BOOST_CHECK(odbw.Write(key, in2));
+ BOOST_CHECK(odbw.Read(key, res3));
+ BOOST_CHECK_EQUAL(res3.ToString(), in2.ToString());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp
index 2439689d7f..5bf1e98e8f 100644
--- a/src/test/mempool_tests.cpp
+++ b/src/test/mempool_tests.cpp
@@ -9,6 +9,7 @@
#include <boost/test/unit_test.hpp>
#include <list>
+#include <vector>
BOOST_FIXTURE_TEST_SUITE(mempool_tests, TestingSetup)
@@ -100,4 +101,184 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
removed.clear();
}
+void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder)
+{
+ BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size());
+ CTxMemPool::indexed_transaction_set::nth_index<1>::type::iterator it = pool.mapTx.get<1>().begin();
+ int count=0;
+ for (; it != pool.mapTx.get<1>().end(); ++it, ++count) {
+ BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(MempoolIndexingTest)
+{
+ CTxMemPool pool(CFeeRate(0));
+
+ /* 3rd highest fee */
+ CMutableTransaction tx1 = CMutableTransaction();
+ tx1.vout.resize(1);
+ tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx1.vout[0].nValue = 10 * COIN;
+ pool.addUnchecked(tx1.GetHash(), CTxMemPoolEntry(tx1, 10000LL, 0, 10.0, 1, true));
+
+ /* highest fee */
+ CMutableTransaction tx2 = CMutableTransaction();
+ tx2.vout.resize(1);
+ tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx2.vout[0].nValue = 2 * COIN;
+ pool.addUnchecked(tx2.GetHash(), CTxMemPoolEntry(tx2, 20000LL, 0, 9.0, 1, true));
+
+ /* lowest fee */
+ CMutableTransaction tx3 = CMutableTransaction();
+ tx3.vout.resize(1);
+ tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx3.vout[0].nValue = 5 * COIN;
+ pool.addUnchecked(tx3.GetHash(), CTxMemPoolEntry(tx3, 0LL, 0, 100.0, 1, true));
+
+ /* 2nd highest fee */
+ CMutableTransaction tx4 = CMutableTransaction();
+ tx4.vout.resize(1);
+ tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx4.vout[0].nValue = 6 * COIN;
+ pool.addUnchecked(tx4.GetHash(), CTxMemPoolEntry(tx4, 15000LL, 0, 1.0, 1, true));
+
+ /* equal fee rate to tx1, but newer */
+ CMutableTransaction tx5 = CMutableTransaction();
+ tx5.vout.resize(1);
+ tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx5.vout[0].nValue = 11 * COIN;
+ pool.addUnchecked(tx5.GetHash(), CTxMemPoolEntry(tx5, 10000LL, 1, 10.0, 1, true));
+ BOOST_CHECK_EQUAL(pool.size(), 5);
+
+ std::vector<std::string> sortedOrder;
+ sortedOrder.resize(5);
+ sortedOrder[0] = tx2.GetHash().ToString(); // 20000
+ sortedOrder[1] = tx4.GetHash().ToString(); // 15000
+ sortedOrder[2] = tx1.GetHash().ToString(); // 10000
+ sortedOrder[3] = tx5.GetHash().ToString(); // 10000
+ sortedOrder[4] = tx3.GetHash().ToString(); // 0
+ CheckSort(pool, sortedOrder);
+
+ /* low fee but with high fee child */
+ /* tx6 -> tx7 -> tx8, tx9 -> tx10 */
+ CMutableTransaction tx6 = CMutableTransaction();
+ tx6.vout.resize(1);
+ tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx6.vout[0].nValue = 20 * COIN;
+ pool.addUnchecked(tx6.GetHash(), CTxMemPoolEntry(tx6, 0LL, 1, 10.0, 1, true));
+ BOOST_CHECK_EQUAL(pool.size(), 6);
+ // Check that at this point, tx6 is sorted low
+ sortedOrder.push_back(tx6.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ CTxMemPool::setEntries setAncestors;
+ setAncestors.insert(pool.mapTx.find(tx6.GetHash()));
+ CMutableTransaction tx7 = CMutableTransaction();
+ tx7.vin.resize(1);
+ tx7.vin[0].prevout = COutPoint(tx6.GetHash(), 0);
+ tx7.vin[0].scriptSig = CScript() << OP_11;
+ tx7.vout.resize(2);
+ tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx7.vout[0].nValue = 10 * COIN;
+ tx7.vout[1].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx7.vout[1].nValue = 1 * COIN;
+
+ CTxMemPool::setEntries setAncestorsCalculated;
+ std::string dummy;
+ CTxMemPoolEntry entry7(tx7, 2000000LL, 1, 10.0, 1, true);
+ BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry7, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true);
+ BOOST_CHECK(setAncestorsCalculated == setAncestors);
+
+ pool.addUnchecked(tx7.GetHash(), CTxMemPoolEntry(tx7, 2000000LL, 1, 10.0, 1, true), setAncestors);
+ BOOST_CHECK_EQUAL(pool.size(), 7);
+
+ // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ...
+ sortedOrder.erase(sortedOrder.end()-1);
+ sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString());
+ sortedOrder.insert(sortedOrder.begin(), tx7.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ /* low fee child of tx7 */
+ CMutableTransaction tx8 = CMutableTransaction();
+ tx8.vin.resize(1);
+ tx8.vin[0].prevout = COutPoint(tx7.GetHash(), 0);
+ tx8.vin[0].scriptSig = CScript() << OP_11;
+ tx8.vout.resize(1);
+ tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx8.vout[0].nValue = 10 * COIN;
+ setAncestors.insert(pool.mapTx.find(tx7.GetHash()));
+ pool.addUnchecked(tx8.GetHash(), CTxMemPoolEntry(tx8, 0LL, 2, 10.0, 1, true), setAncestors);
+
+ // Now tx8 should be sorted low, but tx6/tx both high
+ sortedOrder.push_back(tx8.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ /* low fee child of tx7 */
+ CMutableTransaction tx9 = CMutableTransaction();
+ tx9.vin.resize(1);
+ tx9.vin[0].prevout = COutPoint(tx7.GetHash(), 1);
+ tx9.vin[0].scriptSig = CScript() << OP_11;
+ tx9.vout.resize(1);
+ tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx9.vout[0].nValue = 1 * COIN;
+ pool.addUnchecked(tx9.GetHash(), CTxMemPoolEntry(tx9, 0LL, 3, 10.0, 1, true), setAncestors);
+
+ // tx9 should be sorted low
+ BOOST_CHECK_EQUAL(pool.size(), 9);
+ sortedOrder.push_back(tx9.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ std::vector<std::string> snapshotOrder = sortedOrder;
+
+ setAncestors.insert(pool.mapTx.find(tx8.GetHash()));
+ setAncestors.insert(pool.mapTx.find(tx9.GetHash()));
+ /* tx10 depends on tx8 and tx9 and has a high fee*/
+ CMutableTransaction tx10 = CMutableTransaction();
+ tx10.vin.resize(2);
+ tx10.vin[0].prevout = COutPoint(tx8.GetHash(), 0);
+ tx10.vin[0].scriptSig = CScript() << OP_11;
+ tx10.vin[1].prevout = COutPoint(tx9.GetHash(), 0);
+ tx10.vin[1].scriptSig = CScript() << OP_11;
+ tx10.vout.resize(1);
+ tx10.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL;
+ tx10.vout[0].nValue = 10 * COIN;
+
+ setAncestorsCalculated.clear();
+ CTxMemPoolEntry entry10(tx10, 200000LL, 4, 10.0, 1, true);
+ BOOST_CHECK_EQUAL(pool.CalculateMemPoolAncestors(entry10, setAncestorsCalculated, 100, 1000000, 1000, 1000000, dummy), true);
+ BOOST_CHECK(setAncestorsCalculated == setAncestors);
+
+ pool.addUnchecked(tx10.GetHash(), CTxMemPoolEntry(tx10, 200000LL, 4, 10.0, 1, true), setAncestors);
+
+ /**
+ * tx8 and tx9 should both now be sorted higher
+ * Final order after tx10 is added:
+ *
+ * tx7 = 2.2M (4 txs)
+ * tx6 = 2.2M (5 txs)
+ * tx10 = 200k (1 tx)
+ * tx8 = 200k (2 txs)
+ * tx9 = 200k (2 txs)
+ * tx2 = 20000 (1)
+ * tx4 = 15000 (1)
+ * tx1 = 10000 (1)
+ * tx5 = 10000 (1)
+ * tx3 = 0 (1)
+ */
+ sortedOrder.erase(sortedOrder.end()-2, sortedOrder.end()); // take out tx8, tx9 from the end
+ sortedOrder.insert(sortedOrder.begin()+2, tx10.GetHash().ToString()); // tx10 is after tx6
+ sortedOrder.insert(sortedOrder.begin()+3, tx9.GetHash().ToString());
+ sortedOrder.insert(sortedOrder.begin()+3, tx8.GetHash().ToString());
+ CheckSort(pool, sortedOrder);
+
+ // there should be 10 transactions in the mempool
+ BOOST_CHECK_EQUAL(pool.size(), 10);
+
+ // Now try removing tx10 and verify the sort order returns to normal
+ std::list<CTransaction> removed;
+ pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true);
+ CheckSort(pool, snapshotOrder);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index ad79a558c2..91a3a5738e 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
pblock->vtx[0] = CTransaction(txCoinbase);
if (txFirst.size() < 2)
txFirst.push_back(new CTransaction(pblock->vtx[0]));
- pblock->hashMerkleRoot = pblock->BuildMerkleTree();
+ pblock->hashMerkleRoot = pblock->ComputeMerkleRoot();
pblock->nNonce = blockinfo[i].nonce;
CValidationState state;
BOOST_CHECK(ProcessNewBlock(state, NULL, pblock, true, NULL));
diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp
index 3f99dc98d9..b1ef0ed24a 100644
--- a/src/test/netbase_tests.cpp
+++ b/src/test/netbase_tests.cpp
@@ -149,12 +149,90 @@ BOOST_AUTO_TEST_CASE(subnet_test)
BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).IsValid());
BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.1")));
BOOST_CHECK(!CSubNet(CNetAddr("127.0.0.1")).Match(CNetAddr("127.0.0.2")));
- BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/255.255.255.255");
+ BOOST_CHECK(CSubNet(CNetAddr("127.0.0.1")).ToString() == "127.0.0.1/32");
BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).IsValid());
BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:8")));
BOOST_CHECK(!CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).Match(CNetAddr("1:2:3:4:5:6:7:9")));
- BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK(CSubNet(CNetAddr("1:2:3:4:5:6:7:8")).ToString() == "1:2:3:4:5:6:7:8/128");
+
+ CSubNet subnet = CSubNet("1.2.3.4/255.255.255.255");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/32");
+ subnet = CSubNet("1.2.3.4/255.255.255.254");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/31");
+ subnet = CSubNet("1.2.3.4/255.255.255.252");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.4/30");
+ subnet = CSubNet("1.2.3.4/255.255.255.248");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/29");
+ subnet = CSubNet("1.2.3.4/255.255.255.240");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/28");
+ subnet = CSubNet("1.2.3.4/255.255.255.224");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/27");
+ subnet = CSubNet("1.2.3.4/255.255.255.192");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/26");
+ subnet = CSubNet("1.2.3.4/255.255.255.128");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/25");
+ subnet = CSubNet("1.2.3.4/255.255.255.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.3.0/24");
+ subnet = CSubNet("1.2.3.4/255.255.254.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.2.0/23");
+ subnet = CSubNet("1.2.3.4/255.255.252.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/22");
+ subnet = CSubNet("1.2.3.4/255.255.248.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/21");
+ subnet = CSubNet("1.2.3.4/255.255.240.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/20");
+ subnet = CSubNet("1.2.3.4/255.255.224.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/19");
+ subnet = CSubNet("1.2.3.4/255.255.192.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/18");
+ subnet = CSubNet("1.2.3.4/255.255.128.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/17");
+ subnet = CSubNet("1.2.3.4/255.255.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/16");
+ subnet = CSubNet("1.2.3.4/255.254.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/15");
+ subnet = CSubNet("1.2.3.4/255.252.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/14");
+ subnet = CSubNet("1.2.3.4/255.248.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/13");
+ subnet = CSubNet("1.2.3.4/255.240.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/12");
+ subnet = CSubNet("1.2.3.4/255.224.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/11");
+ subnet = CSubNet("1.2.3.4/255.192.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/10");
+ subnet = CSubNet("1.2.3.4/255.128.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/9");
+ subnet = CSubNet("1.2.3.4/255.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.0.0.0/8");
+ subnet = CSubNet("1.2.3.4/254.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/7");
+ subnet = CSubNet("1.2.3.4/252.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/6");
+ subnet = CSubNet("1.2.3.4/248.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/5");
+ subnet = CSubNet("1.2.3.4/240.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/4");
+ subnet = CSubNet("1.2.3.4/224.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/3");
+ subnet = CSubNet("1.2.3.4/192.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/2");
+ subnet = CSubNet("1.2.3.4/128.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/1");
+ subnet = CSubNet("1.2.3.4/0.0.0.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "0.0.0.0/0");
+
+ subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/128");
+ subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:0000:0000:0000:0000:0000:0000:0000");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1::/16");
+ subnet = CSubNet("1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "::/0");
+ subnet = CSubNet("1.2.3.4/255.255.232.0");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/255.255.232.0");
+ subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
+ BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
}
BOOST_AUTO_TEST_CASE(netbase_getgroup)
diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp
index f6d06d6805..d9f3c3e467 100644
--- a/src/test/pmt_tests.cpp
+++ b/src/test/pmt_tests.cpp
@@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
}
// calculate actual merkle root and height
- uint256 merkleRoot1 = block.BuildMerkleTree();
+ uint256 merkleRoot1 = block.ComputeMerkleRoot();
std::vector<uint256> vTxid(nTx, uint256());
for (unsigned int j=0; j<nTx; j++)
vTxid[j] = block.vtx[j].GetHash();
diff --git a/src/test/reverselock_tests.cpp b/src/test/reverselock_tests.cpp
new file mode 100644
index 0000000000..e7e627ae0f
--- /dev/null
+++ b/src/test/reverselock_tests.cpp
@@ -0,0 +1,64 @@
+// 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 "reverselock.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_FIXTURE_TEST_SUITE(reverselock_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(reverselock_basics)
+{
+ boost::mutex mutex;
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ BOOST_CHECK(lock.owns_lock());
+ {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ BOOST_CHECK(!lock.owns_lock());
+ }
+ BOOST_CHECK(lock.owns_lock());
+}
+
+BOOST_AUTO_TEST_CASE(reverselock_errors)
+{
+ boost::mutex mutex;
+ boost::unique_lock<boost::mutex> lock(mutex);
+
+ // Make sure trying to reverse lock an unlocked lock fails
+ lock.unlock();
+
+ BOOST_CHECK(!lock.owns_lock());
+
+ bool failed = false;
+ try {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ } catch(...) {
+ failed = true;
+ }
+
+ BOOST_CHECK(failed);
+ BOOST_CHECK(!lock.owns_lock());
+
+ // Make sure trying to lock a lock after it has been reverse locked fails
+ failed = false;
+ bool locked = false;
+
+ lock.lock();
+ BOOST_CHECK(lock.owns_lock());
+
+ try {
+ reverse_lock<boost::unique_lock<boost::mutex> > rlock(lock);
+ lock.lock();
+ locked = true;
+ } catch(...) {
+ failed = true;
+ }
+
+ BOOST_CHECK(locked && failed);
+ BOOST_CHECK(lock.owns_lock());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
index a65572e6f6..2a486f08e4 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -13,7 +13,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -224,21 +224,6 @@ BOOST_AUTO_TEST_CASE(json_parse_errors)
BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error);
}
-BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr)
-{
- // Check IPv4 addresses
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("1.2.3.4")).ToString(), "1.2.3.4");
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("127.0.0.1")).ToString(), "127.0.0.1");
- // Check IPv6 addresses
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::1")).ToString(), "::1");
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("123:4567:89ab:cdef:123:4567:89ab:cdef")).ToString(),
- "123:4567:89ab:cdef:123:4567:89ab:cdef");
- // v4 compatible must be interpreted as IPv4
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::0:127.0.0.1")).ToString(), "127.0.0.1");
- // v4 mapped must be interpreted as IPv4
- BOOST_CHECK_EQUAL(BoostAsioToCNetAddr(boost::asio::ip::address::from_string("::ffff:127.0.0.1")).ToString(), "127.0.0.1");
-}
-
BOOST_AUTO_TEST_CASE(rpc_ban)
{
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
@@ -250,7 +235,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
UniValue ar = r.get_array();
UniValue o1 = ar[0].get_obj();
UniValue adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.255");
+ BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/32");
BOOST_CHECK_NO_THROW(CallRPC(string("setban 127.0.0.0 remove")));;
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
ar = r.get_array();
@@ -262,7 +247,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
UniValue banned_until = find_value(o1, "banned_until");
- BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0");
+ BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24");
BOOST_CHECK_EQUAL(banned_until.get_int64(), 1607731200); // absolute time check
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
@@ -273,7 +258,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
banned_until = find_value(o1, "banned_until");
- BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0");
+ BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/24");
int64_t now = GetTime();
BOOST_CHECK(banned_until.get_int64() > now);
BOOST_CHECK(banned_until.get_int64()-now <= 200);
@@ -303,15 +288,15 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK_EQUAL(adr.get_str(), "fe80::202:b3ff:fe1e:8329/128");
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
- BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/30 add")));
+ BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:db8::/ffff:fffc:0:0:0:0:0:0 add")));
BOOST_CHECK_NO_THROW(r = CallRPC(string("listbanned")));
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/ffff:fffc:0:0:0:0:0:0");
+ BOOST_CHECK_EQUAL(adr.get_str(), "2001:db8::/30");
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128 add")));
@@ -319,7 +304,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
ar = r.get_array();
o1 = ar[0].get_obj();
adr = find_value(o1, "address");
- BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
+ BOOST_CHECK_EQUAL(adr.get_str(), "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/128");
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp
index 52f41be8ae..2e652f76e2 100644
--- a/src/test/rpc_wallet_tests.cpp
+++ b/src/test/rpc_wallet_tests.cpp
@@ -14,7 +14,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 37c046935f..882f9eb199 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -27,7 +27,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -840,7 +840,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
-}
+}
BOOST_AUTO_TEST_CASE(script_combineSigs)
{
@@ -983,4 +983,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()
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp
index 4b96461562..6fca64d5da 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -20,7 +20,7 @@
#include <boost/test/unit_test.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
extern UniValue read_json(const std::string& jsondata);
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
new file mode 100644
index 0000000000..0ed8f363d7
--- /dev/null
+++ b/src/test/streams_tests.cpp
@@ -0,0 +1,67 @@
+// Copyright (c) 2012-2013 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 "streams.h"
+#include "support/allocators/zeroafterfree.h"
+#include "test/test_bitcoin.h"
+
+#include <boost/assign/std/vector.hpp> // for 'operator+=()'
+#include <boost/assert.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+using namespace boost::assign; // bring 'operator+=()' into scope
+
+BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup)
+
+BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
+{
+ std::vector<char> in;
+ std::vector<char> expected_xor;
+ std::vector<unsigned char> key;
+ CDataStream ds(in, 0, 0);
+
+ // Degenerate case
+
+ key += '\x00','\x00';
+ ds.Xor(key);
+ BOOST_CHECK_EQUAL(
+ std::string(expected_xor.begin(), expected_xor.end()),
+ std::string(ds.begin(), ds.end()));
+
+ in += '\x0f','\xf0';
+ expected_xor += '\xf0','\x0f';
+
+ // Single character key
+
+ ds.clear();
+ ds.insert(ds.begin(), in.begin(), in.end());
+ key.clear();
+
+ key += '\xff';
+ ds.Xor(key);
+ BOOST_CHECK_EQUAL(
+ std::string(expected_xor.begin(), expected_xor.end()),
+ std::string(ds.begin(), ds.end()));
+
+ // Multi character key
+
+ in.clear();
+ expected_xor.clear();
+ in += '\xf0','\x0f';
+ expected_xor += '\x0f','\x00';
+
+ ds.clear();
+ ds.insert(ds.begin(), in.begin(), in.end());
+
+ key.clear();
+ key += '\xff','\x0f';
+
+ ds.Xor(key);
+ BOOST_CHECK_EQUAL(
+ std::string(expected_xor.begin(), expected_xor.end()),
+ std::string(ds.begin(), ds.end()));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index e70ebddc2f..f9423bc0de 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -26,7 +26,7 @@
#include <boost/test/unit_test.hpp>
#include <boost/assign/list_of.hpp>
-#include "univalue/univalue.h"
+#include <univalue.h>
using namespace std;
@@ -345,18 +345,35 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
t.vout[0].nValue = 501; // dust
BOOST_CHECK(!IsStandardTx(t, reason));
- t.vout[0].nValue = 601; // not dust
+ t.vout[0].nValue = 2730; // not dust
BOOST_CHECK(IsStandardTx(t, reason));
t.vout[0].scriptPubKey = CScript() << OP_1;
BOOST_CHECK(!IsStandardTx(t, reason));
- // 80-byte TX_NULL_DATA (standard)
+ // MAX_OP_RETURN_RELAY-byte TX_NULL_DATA (standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
+ BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
BOOST_CHECK(IsStandardTx(t, reason));
- // 81-byte TX_NULL_DATA (non-standard)
+ // MAX_OP_RETURN_RELAY+1-byte TX_NULL_DATA (non-standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
+ BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
+ BOOST_CHECK(!IsStandardTx(t, reason));
+
+ // Data payload can be encoded in any way...
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("");
+ BOOST_CHECK(IsStandardTx(t, reason));
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("00") << ParseHex("01");
+ BOOST_CHECK(IsStandardTx(t, reason));
+ // OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()!
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0 << ParseHex("01") << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10 << 11 << 12 << 13 << 14 << 15 << 16;
+ BOOST_CHECK(IsStandardTx(t, reason));
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << 0 << ParseHex("01") << 2 << ParseHex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
+ BOOST_CHECK(IsStandardTx(t, reason));
+
+ // ...so long as it only contains PUSHDATA's
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RETURN;
BOOST_CHECK(!IsStandardTx(t, reason));
// TX_NULL_DATA w/o PUSHDATA
diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp
index 67cb9b9623..945c1acbeb 100644
--- a/src/test/univalue_tests.cpp
+++ b/src/test/univalue_tests.cpp
@@ -6,7 +6,7 @@
#include <vector>
#include <string>
#include <map>
-#include "univalue/univalue.h"
+#include <univalue.h>
#include "test/test_bitcoin.h"
#include <boost/test/unit_test.hpp>
@@ -314,6 +314,21 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite)
BOOST_CHECK(obj["key3"].isObject());
BOOST_CHECK_EQUAL(strJson1, v.write());
+
+ /* Check for (correctly reporting) a parsing error if the initial
+ JSON construct is followed by more stuff. Note that whitespace
+ is, of course, exempt. */
+
+ BOOST_CHECK(v.read(" {}\n "));
+ BOOST_CHECK(v.isObject());
+ BOOST_CHECK(v.read(" []\n "));
+ BOOST_CHECK(v.isArray());
+
+ BOOST_CHECK(!v.read("@{}"));
+ BOOST_CHECK(!v.read("{} garbage"));
+ BOOST_CHECK(!v.read("[]{}"));
+ BOOST_CHECK(!v.read("{}[]"));
+ BOOST_CHECK(!v.read("{} 42"));
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index e956cc5b90..997dc31931 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -413,10 +413,10 @@ BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
comments.push_back(std::string("comment1"));
std::vector<std::string> comments2;
comments2.push_back(std::string("comment1"));
- comments2.push_back(std::string("comment2"));
+ comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014
BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:0.9.99/"));
BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/"));
- BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; comment2)/"));
+ BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/"));
}
BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)