diff options
Diffstat (limited to 'src/test')
42 files changed, 2554 insertions, 530 deletions
diff --git a/src/test/Checkpoints_tests.cpp b/src/test/Checkpoints_tests.cpp index b14e9f7057..78b0236b74 100644 --- a/src/test/Checkpoints_tests.cpp +++ b/src/test/Checkpoints_tests.cpp @@ -1,12 +1,12 @@ // // Unit tests for block-chain checkpoints // -#include <boost/assign/list_of.hpp> // for 'map_list_of()' -#include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> -#include "../checkpoints.h" -#include "../util.h" +#include "checkpoints.h" + +#include "uint256.h" + +#include <boost/test/unit_test.hpp> using namespace std; diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index b1e98f65ed..fbca09b4dc 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -1,31 +1,35 @@ // // Unit tests for denial-of-service detection/prevention code // -#include <algorithm> -#include <boost/assign/list_of.hpp> // for 'map_list_of()' -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> + +#include "bignum.h" +#include "keystore.h" #include "main.h" -#include "wallet.h" #include "net.h" -#include "util.h" +#include "script.h" +#include "serialize.h" #include <stdint.h> +#include <boost/assign/list_of.hpp> // for 'map_list_of()' +#include <boost/date_time/posix_time/posix_time_types.hpp> +#include <boost/foreach.hpp> +#include <boost/test/unit_test.hpp> + // Tests this internal-to-main.cpp method: -extern bool AddOrphanTx(const CDataStream& vMsg); +extern bool AddOrphanTx(const CTransaction& tx); extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans); -extern std::map<uint256, CDataStream*> mapOrphanTransactions; -extern std::map<uint256, std::map<uint256, CDataStream*> > mapOrphanTransactionsByPrev; +extern void Misbehaving(NodeId nodeid, int howmuch); +extern std::map<uint256, CTransaction> mapOrphanTransactions; +extern std::map<uint256, std::set<uint256> > mapOrphanTransactionsByPrev; CService ip(uint32_t i) { struct in_addr s; s.s_addr = i; - return CService(CNetAddr(s), GetDefaultPort()); + return CService(CNetAddr(s), Params().GetDefaultPort()); } BOOST_AUTO_TEST_SUITE(DoS_tests) @@ -35,16 +39,21 @@ BOOST_AUTO_TEST_CASE(DoS_banning) CNode::ClearBanned(); CAddress addr1(ip(0xa0b0c001)); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); - dummyNode1.Misbehaving(100); // Should get banned + dummyNode1.nVersion = 1; + Misbehaving(dummyNode1.GetId(), 100); // Should get banned + SendMessages(&dummyNode1, false); BOOST_CHECK(CNode::IsBanned(addr1)); BOOST_CHECK(!CNode::IsBanned(ip(0xa0b0c001|0x0000ff00))); // Different IP, not banned CAddress addr2(ip(0xa0b0c002)); CNode dummyNode2(INVALID_SOCKET, addr2, "", true); - dummyNode2.Misbehaving(50); + dummyNode2.nVersion = 1; + Misbehaving(dummyNode2.GetId(), 50); + SendMessages(&dummyNode2, false); BOOST_CHECK(!CNode::IsBanned(addr2)); // 2 not banned yet... BOOST_CHECK(CNode::IsBanned(addr1)); // ... but 1 still should be - dummyNode2.Misbehaving(50); + Misbehaving(dummyNode2.GetId(), 50); + SendMessages(&dummyNode2, false); BOOST_CHECK(CNode::IsBanned(addr2)); } @@ -54,11 +63,15 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) mapArgs["-banscore"] = "111"; // because 11 is my favorite number CAddress addr1(ip(0xa0b0c001)); CNode dummyNode1(INVALID_SOCKET, addr1, "", true); - dummyNode1.Misbehaving(100); + dummyNode1.nVersion = 1; + Misbehaving(dummyNode1.GetId(), 100); + SendMessages(&dummyNode1, false); BOOST_CHECK(!CNode::IsBanned(addr1)); - dummyNode1.Misbehaving(10); + Misbehaving(dummyNode1.GetId(), 10); + SendMessages(&dummyNode1, false); BOOST_CHECK(!CNode::IsBanned(addr1)); - dummyNode1.Misbehaving(1); + Misbehaving(dummyNode1.GetId(), 1); + SendMessages(&dummyNode1, false); BOOST_CHECK(CNode::IsBanned(addr1)); mapArgs.erase("-banscore"); } @@ -66,13 +79,15 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) BOOST_AUTO_TEST_CASE(DoS_bantime) { CNode::ClearBanned(); - int64 nStartTime = GetTime(); + int64_t nStartTime = GetTime(); SetMockTime(nStartTime); // Overrides future calls to GetTime() CAddress addr(ip(0xa0b0c001)); CNode dummyNode(INVALID_SOCKET, addr, "", true); + dummyNode.nVersion = 1; - dummyNode.Misbehaving(100); + Misbehaving(dummyNode.GetId(), 100); + SendMessages(&dummyNode, false); BOOST_CHECK(CNode::IsBanned(addr)); SetMockTime(nStartTime+60*60); @@ -82,11 +97,11 @@ BOOST_AUTO_TEST_CASE(DoS_bantime) BOOST_CHECK(!CNode::IsBanned(addr)); } -static bool CheckNBits(unsigned int nbits1, int64 time1, unsigned int nbits2, int64 time2)\ +static bool CheckNBits(unsigned int nbits1, int64_t time1, unsigned int nbits2, int64_t time2)\ { if (time1 > time2) return CheckNBits(nbits2, time2, nbits1, time1); - int64 deltaTime = time2-time1; + int64_t deltaTime = time2-time1; CBigNum required; required.SetCompact(ComputeMinWork(nbits1, deltaTime)); @@ -101,7 +116,7 @@ BOOST_AUTO_TEST_CASE(DoS_checknbits) // Timestamps,nBits from the bitcoin block chain. // These are the block-chain checkpoint blocks - typedef std::map<int64, unsigned int> BlockData; + typedef std::map<int64_t, unsigned int> BlockData; BlockData chainData = map_list_of(1239852051,486604799)(1262749024,486594666) (1279305360,469854461)(1280200847,469830746)(1281678674,469809688) @@ -133,14 +148,11 @@ BOOST_AUTO_TEST_CASE(DoS_checknbits) CTransaction RandomOrphan() { - std::map<uint256, CDataStream*>::iterator it; + std::map<uint256, CTransaction>::iterator it; it = mapOrphanTransactions.lower_bound(GetRandHash()); if (it == mapOrphanTransactions.end()) it = mapOrphanTransactions.begin(); - const CDataStream* pvMsg = it->second; - CTransaction tx; - CDataStream(*pvMsg) >> tx; - return tx; + return it->second; } BOOST_AUTO_TEST_CASE(DoS_mapOrphans) @@ -162,9 +174,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); - CDataStream ds(SER_DISK, CLIENT_VERSION); - ds << tx; - AddOrphanTx(ds); + AddOrphanTx(tx); } // ... and 50 that depend on other orphans: @@ -181,9 +191,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); SignSignature(keystore, txPrev, tx, 0); - CDataStream ds(SER_DISK, CLIENT_VERSION); - ds << tx; - AddOrphanTx(ds); + AddOrphanTx(tx); } // This really-big orphan should be ignored: @@ -207,9 +215,7 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans) for (unsigned int j = 1; j < tx.vin.size(); j++) tx.vin[j].scriptSig = tx.vin[0].scriptSig; - CDataStream ds(SER_DISK, CLIENT_VERSION); - ds << tx; - BOOST_CHECK(!AddOrphanTx(ds)); + BOOST_CHECK(!AddOrphanTx(tx)); } // Test LimitOrphanTxSize() function: @@ -246,9 +252,7 @@ BOOST_AUTO_TEST_CASE(DoS_checkSig) tx.vout[0].nValue = 1*CENT; tx.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); - CDataStream ds(SER_DISK, CLIENT_VERSION); - ds << tx; - AddOrphanTx(ds); + AddOrphanTx(tx); } // Create a transaction that depends on orphans: diff --git a/src/test/Makefile.am b/src/test/Makefile.am new file mode 100644 index 0000000000..667e53c6b4 --- /dev/null +++ b/src/test/Makefile.am @@ -0,0 +1,74 @@ +include $(top_srcdir)/src/Makefile.include + +AM_CPPFLAGS += -I$(top_srcdir)/src + +bin_PROGRAMS = test_bitcoin + +TESTS = test_bitcoin + +JSON_TEST_FILES = \ + data/script_valid.json \ + data/base58_keys_valid.json \ + data/sig_canonical.json \ + data/sig_noncanonical.json \ + data/base58_encode_decode.json \ + data/base58_keys_invalid.json \ + data/script_invalid.json \ + data/tx_invalid.json \ + data/tx_valid.json + +RAW_TEST_FILES = data/alertTests.raw + +BUILT_SOURCES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.raw.h) + +# test_bitcoin binary # +test_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(TESTDEFS) +test_bitcoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBLEVELDB) $(LIBMEMENV) \ + $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) +if ENABLE_WALLET +test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) +endif +test_bitcoin_LDADD += $(BDB_LIBS) + +test_bitcoin_SOURCES = \ + alert_tests.cpp \ + allocator_tests.cpp \ + base32_tests.cpp \ + base58_tests.cpp \ + base64_tests.cpp \ + bignum_tests.cpp \ + bloom_tests.cpp \ + canonical_tests.cpp \ + checkblock_tests.cpp \ + Checkpoints_tests.cpp \ + compress_tests.cpp \ + DoS_tests.cpp \ + getarg_tests.cpp \ + key_tests.cpp \ + miner_tests.cpp \ + mruset_tests.cpp \ + multisig_tests.cpp \ + netbase_tests.cpp \ + pmt_tests.cpp \ + rpc_tests.cpp \ + script_P2SH_tests.cpp \ + script_tests.cpp \ + serialize_tests.cpp \ + sigopcount_tests.cpp \ + test_bitcoin.cpp \ + transaction_tests.cpp \ + uint256_tests.cpp \ + util_tests.cpp \ + sighash_tests.cpp \ + $(JSON_TEST_FILES) $(RAW_TEST_FILES) + +if ENABLE_WALLET +test_bitcoin_SOURCES += \ + accounting_tests.cpp \ + wallet_tests.cpp \ + rpc_wallet_tests.cpp +endif + +nodist_test_bitcoin_SOURCES = $(BUILT_SOURCES) + +CLEANFILES = *.gcda *.gcno $(BUILT_SOURCES) diff --git a/src/test/accounting_tests.cpp b/src/test/accounting_tests.cpp index 8ac657288b..bfdb95927b 100644 --- a/src/test/accounting_tests.cpp +++ b/src/test/accounting_tests.cpp @@ -1,15 +1,19 @@ -#include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> -#include "init.h" #include "wallet.h" #include "walletdb.h" +#include <stdint.h> + +#include <boost/foreach.hpp> +#include <boost/test/unit_test.hpp> + +extern CWallet* pwalletMain; + BOOST_AUTO_TEST_SUITE(accounting_tests) static void -GetResults(CWalletDB& walletdb, std::map<int64, CAccountingEntry>& results) +GetResults(CWalletDB& walletdb, std::map<int64_t, CAccountingEntry>& results) { std::list<CAccountingEntry> aes; @@ -28,7 +32,9 @@ BOOST_AUTO_TEST_CASE(acc_orderupgrade) std::vector<CWalletTx*> vpwtx; CWalletTx wtx; CAccountingEntry ae; - std::map<int64, CAccountingEntry> results; + std::map<int64_t, CAccountingEntry> results; + + LOCK(pwalletMain->cs_wallet); ae.strAccount = ""; ae.nCreditDebit = 1; diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp new file mode 100644 index 0000000000..a7e668222d --- /dev/null +++ b/src/test/alert_tests.cpp @@ -0,0 +1,179 @@ +// +// Unit tests for alert system +// + +#include "alert.h" +#include "data/alertTests.raw.h" + +#include "serialize.h" +#include "util.h" +#include "version.h" + +#include <fstream> + +#include <boost/filesystem/operations.hpp> +#include <boost/foreach.hpp> +#include <boost/test/unit_test.hpp> + +#if 0 +// +// alertTests contains 7 alerts, generated with this code: +// (SignAndSave code not shown, alert signing key is secret) +// +{ + CAlert alert; + alert.nRelayUntil = 60; + alert.nExpiration = 24 * 60 * 60; + alert.nID = 1; + alert.nCancel = 0; // cancels previous messages up to this ID number + alert.nMinVer = 0; // These versions are protocol versions + alert.nMaxVer = 999001; + alert.nPriority = 1; + alert.strComment = "Alert comment"; + alert.strStatusBar = "Alert 1"; + + SignAndSave(alert, "test/alertTests"); + + alert.setSubVer.insert(std::string("/Satoshi:0.1.0/")); + alert.strStatusBar = "Alert 1 for Satoshi 0.1.0"; + SignAndSave(alert, "test/alertTests"); + + alert.setSubVer.insert(std::string("/Satoshi:0.2.0/")); + alert.strStatusBar = "Alert 1 for Satoshi 0.1.0, 0.2.0"; + SignAndSave(alert, "test/alertTests"); + + alert.setSubVer.clear(); + ++alert.nID; + alert.nCancel = 1; + alert.nPriority = 100; + alert.strStatusBar = "Alert 2, cancels 1"; + SignAndSave(alert, "test/alertTests"); + + alert.nExpiration += 60; + ++alert.nID; + SignAndSave(alert, "test/alertTests"); + + ++alert.nID; + alert.nMinVer = 11; + alert.nMaxVer = 22; + SignAndSave(alert, "test/alertTests"); + + ++alert.nID; + alert.strStatusBar = "Alert 2 for Satoshi 0.1.0"; + alert.setSubVer.insert(std::string("/Satoshi:0.1.0/")); + SignAndSave(alert, "test/alertTests"); + + ++alert.nID; + alert.nMinVer = 0; + alert.nMaxVer = 999999; + alert.strStatusBar = "Evil Alert'; /bin/ls; echo '"; + alert.setSubVer.clear(); + SignAndSave(alert, "test/alertTests"); +} +#endif + +struct ReadAlerts +{ + ReadAlerts() + { + std::vector<unsigned char> vch(alert_tests::alertTests, alert_tests::alertTests + sizeof(alert_tests::alertTests)); + CDataStream stream(vch, SER_DISK, CLIENT_VERSION); + try { + while (stream.good()) + { + CAlert alert; + stream >> alert; + alerts.push_back(alert); + } + } + catch (std::exception) { } + } + ~ReadAlerts() { } + + static std::vector<std::string> read_lines(boost::filesystem::path filepath) + { + std::vector<std::string> result; + + std::ifstream f(filepath.string().c_str()); + std::string line; + while (std::getline(f,line)) + result.push_back(line); + + return result; + } + + std::vector<CAlert> alerts; +}; + +BOOST_FIXTURE_TEST_SUITE(Alert_tests, ReadAlerts) + + +BOOST_AUTO_TEST_CASE(AlertApplies) +{ + SetMockTime(11); + + BOOST_FOREACH(const CAlert& alert, alerts) + { + BOOST_CHECK(alert.CheckSignature()); + } + + BOOST_CHECK(alerts.size() >= 3); + + // Matches: + BOOST_CHECK(alerts[0].AppliesTo(1, "")); + BOOST_CHECK(alerts[0].AppliesTo(999001, "")); + BOOST_CHECK(alerts[0].AppliesTo(1, "/Satoshi:11.11.11/")); + + BOOST_CHECK(alerts[1].AppliesTo(1, "/Satoshi:0.1.0/")); + BOOST_CHECK(alerts[1].AppliesTo(999001, "/Satoshi:0.1.0/")); + + BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.1.0/")); + BOOST_CHECK(alerts[2].AppliesTo(1, "/Satoshi:0.2.0/")); + + // Don't match: + BOOST_CHECK(!alerts[0].AppliesTo(-1, "")); + BOOST_CHECK(!alerts[0].AppliesTo(999002, "")); + + BOOST_CHECK(!alerts[1].AppliesTo(1, "")); + BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0")); + BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.1.0")); + BOOST_CHECK(!alerts[1].AppliesTo(1, "Satoshi:0.1.0/")); + BOOST_CHECK(!alerts[1].AppliesTo(-1, "/Satoshi:0.1.0/")); + BOOST_CHECK(!alerts[1].AppliesTo(999002, "/Satoshi:0.1.0/")); + BOOST_CHECK(!alerts[1].AppliesTo(1, "/Satoshi:0.2.0/")); + + BOOST_CHECK(!alerts[2].AppliesTo(1, "/Satoshi:0.3.0/")); + + SetMockTime(0); +} + + +// This uses sh 'echo' to test the -alertnotify function, writing to a +// /tmp file. So skip it on Windows: +#ifndef WIN32 +BOOST_AUTO_TEST_CASE(AlertNotify) +{ + SetMockTime(11); + + boost::filesystem::path temp = GetTempPath() / "alertnotify.txt"; + boost::filesystem::remove(temp); + + mapArgs["-alertnotify"] = std::string("echo %s >> ") + temp.string(); + + BOOST_FOREACH(CAlert alert, alerts) + alert.ProcessAlert(false); + + std::vector<std::string> r = read_lines(temp); + BOOST_CHECK_EQUAL(r.size(), 4u); + BOOST_CHECK_EQUAL(r[0], "Alert 1"); + BOOST_CHECK_EQUAL(r[1], "Alert 2, cancels 1"); + BOOST_CHECK_EQUAL(r[2], "Alert 2, cancels 1"); + BOOST_CHECK_EQUAL(r[3], "Evil Alert; /bin/ls; echo "); // single-quotes should be removed + + boost::filesystem::remove(temp); + + SetMockTime(0); +} +#endif + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/allocator_tests.cpp b/src/test/allocator_tests.cpp index d5cb8e8101..490dff87e5 100644 --- a/src/test/allocator_tests.cpp +++ b/src/test/allocator_tests.cpp @@ -1,9 +1,9 @@ -#include <boost/test/unit_test.hpp> -#include "init.h" -#include "main.h" + #include "util.h" +#include <boost/test/unit_test.hpp> + BOOST_AUTO_TEST_SUITE(allocator_tests) // Dummy memory page locker for platform independent tests diff --git a/src/test/base32_tests.cpp b/src/test/base32_tests.cpp index fdf3285913..580e87f65f 100644 --- a/src/test/base32_tests.cpp +++ b/src/test/base32_tests.cpp @@ -1,7 +1,9 @@ -#include <boost/test/unit_test.hpp> + #include "util.h" +#include <boost/test/unit_test.hpp> + BOOST_AUTO_TEST_SUITE(base32_tests) BOOST_AUTO_TEST_CASE(base32_testvectors) diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 0c51e4f69b..94e84049be 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -1,21 +1,29 @@ +#include "base58.h" + +#include "data/base58_encode_decode.json.h" +#include "data/base58_keys_invalid.json.h" +#include "data/base58_keys_valid.json.h" + +#include "key.h" +#include "script.h" +#include "uint256.h" +#include "util.h" + +#include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> #include "json/json_spirit_reader_template.h" -#include "json/json_spirit_writer_template.h" #include "json/json_spirit_utils.h" - -#include "base58.h" -#include "util.h" +#include "json/json_spirit_writer_template.h" using namespace json_spirit; -extern Array read_json(const std::string& filename); +extern Array read_json(const std::string& jsondata); BOOST_AUTO_TEST_SUITE(base58_tests) // Goal: test low-level base58 encoding functionality BOOST_AUTO_TEST_CASE(base58_EncodeBase58) { - Array tests = read_json("base58_encode_decode.json"); - + Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); @@ -36,7 +44,7 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58) // Goal: test low-level base58 decoding functionality BOOST_AUTO_TEST_CASE(base58_DecodeBase58) { - Array tests = read_json("base58_encode_decode.json"); + Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); std::vector<unsigned char> result; BOOST_FOREACH(Value& tv, tests) @@ -110,12 +118,10 @@ public: // Goal: check that parsed keys match test payload BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) { - Array tests = read_json("base58_keys_valid.json"); + Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector<unsigned char> result; CBitcoinSecret secret; CBitcoinAddress addr; - // Save global state - bool fTestNet_stored = fTestNet; BOOST_FOREACH(Value& tv, tests) { @@ -131,7 +137,10 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) const Object &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); - fTestNet = isTestnet; // Override testnet flag + if (isTestnet) + SelectParams(CChainParams::TESTNET); + else + SelectParams(CChainParams::MAIN); if(isPrivkey) { bool isCompressed = find_value(metadata, "isCompressed").get_bool(); @@ -139,9 +148,8 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) // Note: CBitcoinSecret::SetString tests isValid, whereas CBitcoinAddress does not! BOOST_CHECK_MESSAGE(secret.SetString(exp_base58string), "!SetString:"+ strTest); BOOST_CHECK_MESSAGE(secret.IsValid(), "!IsValid:" + strTest); - bool fCompressedOut = false; - CSecret privkey = secret.GetSecret(fCompressedOut); - BOOST_CHECK_MESSAGE(fCompressedOut == isCompressed, "compressed mismatch:" + strTest); + CKey privkey = secret.GetKey(); + BOOST_CHECK_MESSAGE(privkey.IsCompressed() == isCompressed, "compressed mismatch:" + strTest); BOOST_CHECK_MESSAGE(privkey.size() == exp_payload.size() && std::equal(privkey.begin(), privkey.end(), exp_payload.begin()), "key mismatch:" + strTest); // Private key must be invalid public key @@ -163,18 +171,14 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) BOOST_CHECK_MESSAGE(!secret.IsValid(), "IsValid pubkey as privkey:" + strTest); } } - // Restore global state - fTestNet = fTestNet_stored; + SelectParams(CChainParams::MAIN); } // Goal: check that generated keys match test vectors BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) { - Array tests = read_json("base58_keys_valid.json"); + Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector<unsigned char> result; - // Save global state - bool fTestNet_stored = fTestNet; - BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); @@ -189,12 +193,18 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) const Object &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); - fTestNet = isTestnet; // Override testnet flag + if (isTestnet) + SelectParams(CChainParams::TESTNET); + else + SelectParams(CChainParams::MAIN); if(isPrivkey) { bool isCompressed = find_value(metadata, "isCompressed").get_bool(); + CKey key; + key.Set(exp_payload.begin(), exp_payload.end(), isCompressed); + assert(key.IsValid()); CBitcoinSecret secret; - secret.SetSecret(CSecret(exp_payload.begin(), exp_payload.end()), isCompressed); + secret.SetKey(key); BOOST_CHECK_MESSAGE(secret.ToString() == exp_base58string, "result mismatch: " + strTest); } else @@ -229,14 +239,13 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) CTxDestination nodest = CNoDestination(); BOOST_CHECK(!boost::apply_visitor(CBitcoinAddressVisitor(&dummyAddr), nodest)); - // Restore global state - fTestNet = fTestNet_stored; + SelectParams(CChainParams::MAIN); } // Goal: check that base58 parsing code is robust against a variety of corrupted data BOOST_AUTO_TEST_CASE(base58_keys_invalid) { - Array tests = read_json("base58_keys_invalid.json"); // Negative testcases + Array tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases std::vector<unsigned char> result; CBitcoinSecret secret; CBitcoinAddress addr; diff --git a/src/test/base64_tests.cpp b/src/test/base64_tests.cpp index c5a053e2eb..c59c290669 100644 --- a/src/test/base64_tests.cpp +++ b/src/test/base64_tests.cpp @@ -1,9 +1,9 @@ -#include <boost/test/unit_test.hpp> -#include "main.h" -#include "wallet.h" + #include "util.h" +#include <boost/test/unit_test.hpp> + BOOST_AUTO_TEST_SUITE(base64_tests) BOOST_AUTO_TEST_CASE(base64_testvectors) diff --git a/src/test/bignum_tests.cpp b/src/test/bignum_tests.cpp index 5b898d1499..9d67324c76 100644 --- a/src/test/bignum_tests.cpp +++ b/src/test/bignum_tests.cpp @@ -1,8 +1,9 @@ -#include <boost/test/unit_test.hpp> +#include "bignum.h" + #include <limits> +#include <stdint.h> -#include "bignum.h" -#include "util.h" +#include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_SUITE(bignum_tests) @@ -46,7 +47,7 @@ BOOST_AUTO_TEST_SUITE(bignum_tests) // Let's force this code not to be inlined, in order to actually // test a generic version of the function. This increases the chance // that -ftrapv will detect overflows. -NOINLINE void mysetint64(CBigNum& num, int64 n) +NOINLINE void mysetint64(CBigNum& num, int64_t n) { num.setint64(n); } @@ -55,7 +56,7 @@ NOINLINE void mysetint64(CBigNum& num, int64 n) // value to 0, then the second one with a non-inlined function. BOOST_AUTO_TEST_CASE(bignum_setint64) { - int64 n; + int64_t n; { n = 0; @@ -103,7 +104,7 @@ BOOST_AUTO_TEST_CASE(bignum_setint64) BOOST_CHECK(num.ToString() == "-5"); } { - n = std::numeric_limits<int64>::min(); + n = std::numeric_limits<int64_t>::min(); CBigNum num(n); BOOST_CHECK(num.ToString() == "-9223372036854775808"); num.setulong(0); @@ -112,7 +113,7 @@ BOOST_AUTO_TEST_CASE(bignum_setint64) BOOST_CHECK(num.ToString() == "-9223372036854775808"); } { - n = std::numeric_limits<int64>::max(); + n = std::numeric_limits<int64_t>::max(); CBigNum num(n); BOOST_CHECK(num.ToString() == "9223372036854775807"); num.setulong(0); @@ -128,51 +129,59 @@ BOOST_AUTO_TEST_CASE(bignum_SetCompact) CBigNum num; num.SetCompact(0); BOOST_CHECK_EQUAL(num.GetHex(), "0"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0); + BOOST_CHECK_EQUAL(num.GetCompact(), 0U); num.SetCompact(0x00123456); BOOST_CHECK_EQUAL(num.GetHex(), "0"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0); + BOOST_CHECK_EQUAL(num.GetCompact(), 0U); num.SetCompact(0x01123456); BOOST_CHECK_EQUAL(num.GetHex(), "12"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x01120000U); // Make sure that we don't generate compacts with the 0x00800000 bit set num = 0x80; - BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x02008000U); num.SetCompact(0x01fedcba); BOOST_CHECK_EQUAL(num.GetHex(), "-7e"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x01fe0000); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x01fe0000U); num.SetCompact(0x02123456); BOOST_CHECK_EQUAL(num.GetHex(), "1234"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x02123400U); num.SetCompact(0x03123456); BOOST_CHECK_EQUAL(num.GetHex(), "123456"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x03123456U); num.SetCompact(0x04123456); BOOST_CHECK_EQUAL(num.GetHex(), "12345600"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x04123456U); num.SetCompact(0x04923456); BOOST_CHECK_EQUAL(num.GetHex(), "-12345600"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x04923456); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x04923456U); num.SetCompact(0x05009234); BOOST_CHECK_EQUAL(num.GetHex(), "92340000"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x05009234U); num.SetCompact(0x20123456); BOOST_CHECK_EQUAL(num.GetHex(), "1234560000000000000000000000000000000000000000000000000000000000"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456); + BOOST_CHECK_EQUAL(num.GetCompact(), 0x20123456U); num.SetCompact(0xff123456); BOOST_CHECK_EQUAL(num.GetHex(), "123456000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); - BOOST_CHECK_EQUAL(num.GetCompact(), 0xff123456); + BOOST_CHECK_EQUAL(num.GetCompact(), 0xff123456U); +} + +BOOST_AUTO_TEST_CASE(bignum_SetHex) +{ + std::string hexStr = "deecf97fd890808b9cc0f1b6a3e7a60b400f52710e6ad075b1340755bfa58cc9"; + CBigNum num; + num.SetHex(hexStr); + BOOST_CHECK_EQUAL(num.GetHex(), hexStr); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp new file mode 100644 index 0000000000..2bcca24336 --- /dev/null +++ b/src/test/bip32_tests.cpp @@ -0,0 +1,116 @@ +#include <boost/test/unit_test.hpp> + +#include "base58.h" +#include "key.h" +#include "uint256.h" +#include "util.h" + +#include <string> +#include <vector> + +struct TestDerivation { + std::string pub; + std::string prv; + unsigned int nChild; +}; + +struct TestVector { + std::string strHexMaster; + std::vector<TestDerivation> vDerive; + + TestVector(std::string strHexMasterIn) : strHexMaster(strHexMasterIn) {} + + TestVector& operator()(std::string pub, std::string prv, unsigned int nChild) { + vDerive.push_back(TestDerivation()); + TestDerivation &der = vDerive.back(); + der.pub = pub; + der.prv = prv; + der.nChild = nChild; + return *this; + } +}; + +TestVector test1 = + TestVector("000102030405060708090a0b0c0d0e0f") + ("xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8", + "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi", + 0x80000000) + ("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw", + "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7", + 1) + ("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ", + "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs", + 0x80000002) + ("xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5", + "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM", + 2) + ("xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV", + "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334", + 1000000000) + ("xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy", + "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76", + 0); + +TestVector test2 = + TestVector("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542") + ("xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB", + "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U", + 0) + ("xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH", + "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt", + 0xFFFFFFFF) + ("xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a", + "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9", + 1) + ("xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon", + "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef", + 0xFFFFFFFE) + ("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL", + "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc", + 2) + ("xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt", + "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j", + 0); + +void RunTest(const TestVector &test) { + std::vector<unsigned char> seed = ParseHex(test.strHexMaster); + CExtKey key; + CExtPubKey pubkey; + key.SetMaster(&seed[0], seed.size()); + pubkey = key.Neuter(); + BOOST_FOREACH(const TestDerivation &derive, test.vDerive) { + unsigned char data[74]; + key.Encode(data); + pubkey.Encode(data); + // Test private key + CBitcoinExtKey b58key; b58key.SetKey(key); + BOOST_CHECK(b58key.ToString() == derive.prv); + // Test public key + CBitcoinExtPubKey b58pubkey; b58pubkey.SetKey(pubkey); + BOOST_CHECK(b58pubkey.ToString() == derive.pub); + // Derive new keys + CExtKey keyNew; + BOOST_CHECK(key.Derive(keyNew, derive.nChild)); + CExtPubKey pubkeyNew = keyNew.Neuter(); + if (!(derive.nChild & 0x80000000)) { + // Compare with public derivation + CExtPubKey pubkeyNew2; + BOOST_CHECK(pubkey.Derive(pubkeyNew2, derive.nChild)); + BOOST_CHECK(pubkeyNew == pubkeyNew2); + } + key = keyNew; + pubkey = pubkeyNew; + } +} + +BOOST_AUTO_TEST_SUITE(bip32_tests) + +BOOST_AUTO_TEST_CASE(bip32_test1) { + RunTest(test1); +} + +BOOST_AUTO_TEST_CASE(bip32_test2) { + RunTest(test2); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/bloom_tests.cpp b/src/test/bloom_tests.cpp index 4a2851cf46..c4e4403b70 100644 --- a/src/test/bloom_tests.cpp +++ b/src/test/bloom_tests.cpp @@ -1,11 +1,15 @@ -#include <boost/test/unit_test.hpp> -#include <vector> - #include "bloom.h" -#include "util.h" -#include "key.h" + #include "base58.h" +#include "key.h" #include "main.h" +#include "serialize.h" +#include "uint256.h" +#include "util.h" + +#include <vector> + +#include <boost/test/unit_test.hpp> using namespace std; using namespace boost::tuples; @@ -73,14 +77,13 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key) CBitcoinSecret vchSecret; BOOST_CHECK(vchSecret.SetString(strSecret)); - CKey key; - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.SetSecret(secret, fCompressed); + CKey key = vchSecret.GetKey(); + CPubKey pubkey = key.GetPubKey(); + vector<unsigned char> vchPubKey(pubkey.begin(), pubkey.end()); CBloomFilter filter(2, 0.001, 0, BLOOM_UPDATE_ALL); - filter.insert(key.GetPubKey().Raw()); - uint160 hash = key.GetPubKey().GetID(); + filter.insert(vchPubKey); + uint160 hash = pubkey.GetID(); filter.insert(vector<unsigned char>(hash.begin(), hash.end())); CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/test/canonical_tests.cpp b/src/test/canonical_tests.cpp index 42d21f8ac5..c521f2cf9c 100644 --- a/src/test/canonical_tests.cpp +++ b/src/test/canonical_tests.cpp @@ -1,20 +1,25 @@ // // Unit tests for canonical signatures +// + -#include "json/json_spirit_writer_template.h" -#include <boost/test/unit_test.hpp> -#include <openssl/ecdsa.h> -#include "key.h" #include "script.h" #include "util.h" +#include "data/sig_noncanonical.json.h" +#include "data/sig_canonical.json.h" + +#include <boost/foreach.hpp> +#include <boost/test/unit_test.hpp> +#include "json/json_spirit_writer_template.h" +#include <openssl/ecdsa.h> using namespace std; using namespace json_spirit; // In script_tests.cpp -extern Array read_json(const std::string& filename); +extern Array read_json(const std::string& jsondata); BOOST_AUTO_TEST_SUITE(canonical_tests) @@ -58,13 +63,13 @@ bool static IsCanonicalSignature_OpenSSL(const std::vector<unsigned char> &vchSi BOOST_AUTO_TEST_CASE(script_canon) { - Array tests = read_json("sig_canonical.json"); + Array tests = read_json(std::string(json_tests::sig_canonical, json_tests::sig_canonical + sizeof(json_tests::sig_canonical))); BOOST_FOREACH(Value &tv, tests) { string test = tv.get_str(); if (IsHex(test)) { std::vector<unsigned char> sig = ParseHex(test); - BOOST_CHECK_MESSAGE(IsCanonicalSignature(sig), test); + BOOST_CHECK_MESSAGE(IsCanonicalSignature(sig, SCRIPT_VERIFY_STRICTENC), test); BOOST_CHECK_MESSAGE(IsCanonicalSignature_OpenSSL(sig), test); } } @@ -72,13 +77,13 @@ BOOST_AUTO_TEST_CASE(script_canon) BOOST_AUTO_TEST_CASE(script_noncanon) { - Array tests = read_json("sig_noncanonical.json"); + Array tests = read_json(std::string(json_tests::sig_noncanonical, json_tests::sig_noncanonical + sizeof(json_tests::sig_noncanonical))); BOOST_FOREACH(Value &tv, tests) { string test = tv.get_str(); if (IsHex(test)) { std::vector<unsigned char> sig = ParseHex(test); - BOOST_CHECK_MESSAGE(!IsCanonicalSignature(sig), test); + BOOST_CHECK_MESSAGE(!IsCanonicalSignature(sig, SCRIPT_VERIFY_STRICTENC), test); BOOST_CHECK_MESSAGE(!IsCanonicalSignature_OpenSSL(sig), test); } } diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp new file mode 100644 index 0000000000..d47a33fd46 --- /dev/null +++ b/src/test/checkblock_tests.cpp @@ -0,0 +1,64 @@ +// +// Unit tests for block.CheckBlock() +// + + + +#include "main.h" + +#include <cstdio> + +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> +#include <boost/test/unit_test.hpp> + + +BOOST_AUTO_TEST_SUITE(CheckBlock_tests) + +bool +read_block(const std::string& filename, CBlock& block) +{ + namespace fs = boost::filesystem; + fs::path testFile = fs::current_path() / "data" / filename; +#ifdef TEST_DATA_DIR + if (!fs::exists(testFile)) + { + testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename; + } +#endif + FILE* fp = fopen(testFile.string().c_str(), "rb"); + if (!fp) return false; + + fseek(fp, 8, SEEK_SET); // skip msgheader/size + + CAutoFile filein = CAutoFile(fp, SER_DISK, CLIENT_VERSION); + if (!filein) return false; + + filein >> block; + + return true; +} + +BOOST_AUTO_TEST_CASE(May15) +{ + // Putting a 1MB binary file in the git repository is not a great + // idea, so this test is only run if you manually download + // test/data/Mar12Fork.dat from + // http://sourceforge.net/projects/bitcoin/files/Bitcoin/blockchain/Mar12Fork.dat/download + unsigned int tMay15 = 1368576000; + SetMockTime(tMay15); // Test as if it was right at May 15 + + CBlock forkingBlock; + if (read_block("Mar12Fork.dat", forkingBlock)) + { + CValidationState state; + + // After May 15'th, big blocks are OK: + forkingBlock.nTime = tMay15; // Invalidates PoW + BOOST_CHECK(CheckBlock(forkingBlock, state, false, false)); + } + + SetMockTime(0); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp index 71b86bcb41..4d16914774 100644 --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -1,9 +1,11 @@ -#include <boost/test/unit_test.hpp> -#include <string> -#include <vector> #include "main.h" +#include "util.h" + +#include <stdint.h> + +#include <boost/test/unit_test.hpp> // amounts 0.00000001 .. 0.00100000 #define NUM_MULTIPLES_UNIT 100000 @@ -17,19 +19,17 @@ // amounts 50 .. 21000000 #define NUM_MULTIPLES_50BTC 420000 -using namespace std; - BOOST_AUTO_TEST_SUITE(compress_tests) -bool static TestEncode(uint64 in) { +bool static TestEncode(uint64_t in) { return in == CTxOutCompressor::DecompressAmount(CTxOutCompressor::CompressAmount(in)); } -bool static TestDecode(uint64 in) { +bool static TestDecode(uint64_t in) { return in == CTxOutCompressor::CompressAmount(CTxOutCompressor::DecompressAmount(in)); } -bool static TestPair(uint64 dec, uint64 enc) { +bool static TestPair(uint64_t dec, uint64_t enc) { return CTxOutCompressor::CompressAmount(dec) == enc && CTxOutCompressor::DecompressAmount(enc) == dec; } @@ -43,19 +43,19 @@ BOOST_AUTO_TEST_CASE(compress_amounts) BOOST_CHECK(TestPair( 50*COIN, 0x32)); BOOST_CHECK(TestPair(21000000*COIN, 0x1406f40)); - for (uint64 i = 1; i <= NUM_MULTIPLES_UNIT; i++) + for (uint64_t i = 1; i <= NUM_MULTIPLES_UNIT; i++) BOOST_CHECK(TestEncode(i)); - for (uint64 i = 1; i <= NUM_MULTIPLES_CENT; i++) + for (uint64_t i = 1; i <= NUM_MULTIPLES_CENT; i++) BOOST_CHECK(TestEncode(i * CENT)); - for (uint64 i = 1; i <= NUM_MULTIPLES_1BTC; i++) + for (uint64_t i = 1; i <= NUM_MULTIPLES_1BTC; i++) BOOST_CHECK(TestEncode(i * COIN)); - for (uint64 i = 1; i <= NUM_MULTIPLES_50BTC; i++) + for (uint64_t i = 1; i <= NUM_MULTIPLES_50BTC; i++) BOOST_CHECK(TestEncode(i * 50 * COIN)); - for (uint64 i = 0; i < 100000; i++) + for (uint64_t i = 0; i < 100000; i++) BOOST_CHECK(TestDecode(i)); } diff --git a/src/test/data/alertTests.raw b/src/test/data/alertTests.raw Binary files differnew file mode 100644 index 0000000000..01f50680b9 --- /dev/null +++ b/src/test/data/alertTests.raw diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index d413eaee8d..761cc4a008 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -13,7 +13,9 @@ ["0","NOP"], ["1", "IF VER ELSE 1 ENDIF", "VER non-functional"], ["0", "IF VERIF ELSE 1 ENDIF", "VERIF illegal everywhere"], -["0", "IF VERNOTIF ELSE 1 ENDIF", "VERNOT illegal everywhere"], +["0", "IF ELSE 1 ELSE VERIF ENDIF", "VERIF illegal everywhere"], +["0", "IF VERNOTIF ELSE 1 ENDIF", "VERNOTIF illegal everywhere"], +["0", "IF ELSE 1 ELSE VERNOTIF ENDIF", "VERNOTIF illegal everywhere"], ["1 IF", "1 ENDIF", "IF/ENDIF can't span scriptSig/scriptPubKey"], ["1 IF 0 ENDIF", "1 ENDIF"], @@ -36,9 +38,24 @@ ["1 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], ["0 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["1", "IF RETURN ELSE ELSE 1 ENDIF", "Multiple ELSEs"], +["1", "IF 1 ELSE ELSE RETURN ENDIF"], + +["1", "ENDIF", "Malformed IF/ELSE/ENDIF sequence"], +["1", "ELSE ENDIF"], +["1", "ENDIF ELSE"], +["1", "ENDIF ELSE IF"], +["1", "IF ELSE ENDIF ELSE"], +["1", "IF ELSE ENDIF ELSE ENDIF"], +["1", "IF ENDIF ENDIF"], +["1", "IF ELSE ELSE ENDIF ENDIF"], + ["1", "RETURN"], ["1", "DUP IF RETURN ENDIF"], +["1", "RETURN 'data'", "canonical prunable txout format"], +["0 IF", "RETURN ENDIF 1", "still prunable because IF/ENDIF can't span scriptSig/scriptPubKey"], + ["0", "VERIFY 1"], ["1", "VERIFY"], ["1", "VERIFY 0"], @@ -128,13 +145,79 @@ ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL"], ["0x50","1", "opcode 0x50 is reserved"], -["1", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid"], +["1", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid if executed"], +["1", "IF 0xbb ELSE 1 ENDIF"], +["1", "IF 0xbc ELSE 1 ENDIF"], +["1", "IF 0xbd ELSE 1 ENDIF"], +["1", "IF 0xbe ELSE 1 ENDIF"], +["1", "IF 0xbf ELSE 1 ENDIF"], ["1", "IF 0xc0 ELSE 1 ENDIF"], +["1", "IF 0xc1 ELSE 1 ENDIF"], +["1", "IF 0xc2 ELSE 1 ENDIF"], +["1", "IF 0xc3 ELSE 1 ENDIF"], +["1", "IF 0xc4 ELSE 1 ENDIF"], +["1", "IF 0xc5 ELSE 1 ENDIF"], +["1", "IF 0xc6 ELSE 1 ENDIF"], +["1", "IF 0xc7 ELSE 1 ENDIF"], +["1", "IF 0xc8 ELSE 1 ENDIF"], +["1", "IF 0xc9 ELSE 1 ENDIF"], +["1", "IF 0xca ELSE 1 ENDIF"], +["1", "IF 0xcb ELSE 1 ENDIF"], +["1", "IF 0xcc ELSE 1 ENDIF"], +["1", "IF 0xcd ELSE 1 ENDIF"], +["1", "IF 0xce ELSE 1 ENDIF"], +["1", "IF 0xcf ELSE 1 ENDIF"], +["1", "IF 0xd0 ELSE 1 ENDIF"], ["1", "IF 0xd1 ELSE 1 ENDIF"], +["1", "IF 0xd2 ELSE 1 ENDIF"], +["1", "IF 0xd3 ELSE 1 ENDIF"], +["1", "IF 0xd4 ELSE 1 ENDIF"], +["1", "IF 0xd5 ELSE 1 ENDIF"], +["1", "IF 0xd6 ELSE 1 ENDIF"], +["1", "IF 0xd7 ELSE 1 ENDIF"], +["1", "IF 0xd8 ELSE 1 ENDIF"], +["1", "IF 0xd9 ELSE 1 ENDIF"], +["1", "IF 0xda ELSE 1 ENDIF"], +["1", "IF 0xdb ELSE 1 ENDIF"], +["1", "IF 0xdc ELSE 1 ENDIF"], +["1", "IF 0xdd ELSE 1 ENDIF"], +["1", "IF 0xde ELSE 1 ENDIF"], +["1", "IF 0xdf ELSE 1 ENDIF"], +["1", "IF 0xe0 ELSE 1 ENDIF"], +["1", "IF 0xe1 ELSE 1 ENDIF"], +["1", "IF 0xe2 ELSE 1 ENDIF"], +["1", "IF 0xe3 ELSE 1 ENDIF"], +["1", "IF 0xe4 ELSE 1 ENDIF"], +["1", "IF 0xe5 ELSE 1 ENDIF"], +["1", "IF 0xe6 ELSE 1 ENDIF"], +["1", "IF 0xe7 ELSE 1 ENDIF"], +["1", "IF 0xe8 ELSE 1 ENDIF"], +["1", "IF 0xe9 ELSE 1 ENDIF"], +["1", "IF 0xea ELSE 1 ENDIF"], +["1", "IF 0xeb ELSE 1 ENDIF"], +["1", "IF 0xec ELSE 1 ENDIF"], +["1", "IF 0xed ELSE 1 ENDIF"], ["1", "IF 0xee ELSE 1 ENDIF"], +["1", "IF 0xef ELSE 1 ENDIF"], +["1", "IF 0xf0 ELSE 1 ENDIF"], +["1", "IF 0xf1 ELSE 1 ENDIF"], +["1", "IF 0xf2 ELSE 1 ENDIF"], +["1", "IF 0xf3 ELSE 1 ENDIF"], +["1", "IF 0xf4 ELSE 1 ENDIF"], +["1", "IF 0xf5 ELSE 1 ENDIF"], +["1", "IF 0xf6 ELSE 1 ENDIF"], +["1", "IF 0xf7 ELSE 1 ENDIF"], +["1", "IF 0xf8 ELSE 1 ENDIF"], +["1", "IF 0xf9 ELSE 1 ENDIF"], +["1", "IF 0xfa ELSE 1 ENDIF"], +["1", "IF 0xfb ELSE 1 ENDIF"], +["1", "IF 0xfc ELSE 1 ENDIF"], ["1", "IF 0xfd ELSE 1 ENDIF"], +["1", "IF 0xfe ELSE 1 ENDIF"], ["1", "IF 0xff ELSE 1 ENDIF"], +["1 IF 1 ELSE", "0xff ENDIF", "invalid because scriptSig and scriptPubKey are processed separately"], + ["NOP", "RIPEMD160"], ["NOP", "SHA1"], ["NOP", "SHA256"], @@ -168,6 +251,7 @@ ["1","VER", "OP_VER is reserved"], ["1","VERIF", "OP_VERIF is reserved"], ["1","VERNOTIF", "OP_VERNOTIF is reserved"], +["1","RESERVED", "OP_RESERVED is reserved"], ["1","RESERVED1", "OP_RESERVED1 is reserved"], ["1","RESERVED2", "OP_RESERVED2 is reserved"], ["1","0xba", "0xba == OP_NOP10 + 1"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index c33a3c7c66..e4c181cae8 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -16,7 +16,7 @@ ["0x51", "0x5f ADD 0x60 EQUAL", "0x51 through 0x60 push 1 through 16 onto stack"], ["1","NOP"], ["0", "IF VER ELSE 1 ENDIF", "VER non-functional (ok if not executed)"], -["0", "IF RESERVED1 RESERVED2 ELSE 1 ENDIF", "RESERVED ok in un-executed IF"], +["0", "IF RESERVED RESERVED1 RESERVED2 ELSE 1 ENDIF", "RESERVED ok in un-executed IF"], ["1", "DUP IF ENDIF"], ["1", "IF 1 ENDIF"], @@ -34,6 +34,23 @@ ["1 0", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], ["0 1", "NOTIF IF 1 ELSE 0 ENDIF ELSE IF 0 ELSE 1 ENDIF ENDIF"], +["0", "IF 0 ELSE 1 ELSE 0 ENDIF", "Multiple ELSE's are valid and executed inverts on each ELSE encountered"], +["1", "IF 1 ELSE 0 ELSE ENDIF"], +["1", "IF ELSE 0 ELSE 1 ENDIF"], +["1", "IF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL"], +["'' 1", "IF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL"], + +["1", "NOTIF 0 ELSE 1 ELSE 0 ENDIF", "Multiple ELSE's are valid and execution inverts on each ELSE encountered"], +["0", "NOTIF 1 ELSE 0 ELSE ENDIF"], +["0", "NOTIF ELSE 0 ELSE 1 ENDIF"], +["0", "NOTIF 1 ELSE 0 ELSE 1 ENDIF ADD 2 EQUAL"], +["'' 0", "NOTIF SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ELSE ELSE SHA1 ENDIF 0x14 0x68ca4fec736264c13b859bac43d5173df6871682 EQUAL"], + +["0", "IF 1 IF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 1 IF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL", "Nested ELSE ELSE"], +["1", "NOTIF 0 NOTIF RETURN ELSE RETURN ELSE RETURN ENDIF ELSE 0 NOTIF 1 ELSE RETURN ELSE 1 ENDIF ELSE RETURN ENDIF ADD 2 EQUAL"], + +["0", "IF RETURN ENDIF 1", "RETURN only works if executed"], + ["1 1", "VERIFY"], ["10 0 11 TOALTSTACK DROP FROMALTSTACK", "ADD 21 EQUAL"], @@ -188,10 +205,74 @@ ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL"], ["0", "IF 0xba ELSE 1 ENDIF", "opcodes above NOP10 invalid if executed"], +["0", "IF 0xbb ELSE 1 ENDIF"], +["0", "IF 0xbc ELSE 1 ENDIF"], +["0", "IF 0xbd ELSE 1 ENDIF"], +["0", "IF 0xbe ELSE 1 ENDIF"], +["0", "IF 0xbf ELSE 1 ENDIF"], ["0", "IF 0xc0 ELSE 1 ENDIF"], +["0", "IF 0xc1 ELSE 1 ENDIF"], +["0", "IF 0xc2 ELSE 1 ENDIF"], +["0", "IF 0xc3 ELSE 1 ENDIF"], +["0", "IF 0xc4 ELSE 1 ENDIF"], +["0", "IF 0xc5 ELSE 1 ENDIF"], +["0", "IF 0xc6 ELSE 1 ENDIF"], +["0", "IF 0xc7 ELSE 1 ENDIF"], +["0", "IF 0xc8 ELSE 1 ENDIF"], +["0", "IF 0xc9 ELSE 1 ENDIF"], +["0", "IF 0xca ELSE 1 ENDIF"], +["0", "IF 0xcb ELSE 1 ENDIF"], +["0", "IF 0xcc ELSE 1 ENDIF"], +["0", "IF 0xcd ELSE 1 ENDIF"], +["0", "IF 0xce ELSE 1 ENDIF"], +["0", "IF 0xcf ELSE 1 ENDIF"], +["0", "IF 0xd0 ELSE 1 ENDIF"], ["0", "IF 0xd1 ELSE 1 ENDIF"], +["0", "IF 0xd2 ELSE 1 ENDIF"], +["0", "IF 0xd3 ELSE 1 ENDIF"], +["0", "IF 0xd4 ELSE 1 ENDIF"], +["0", "IF 0xd5 ELSE 1 ENDIF"], +["0", "IF 0xd6 ELSE 1 ENDIF"], +["0", "IF 0xd7 ELSE 1 ENDIF"], +["0", "IF 0xd8 ELSE 1 ENDIF"], +["0", "IF 0xd9 ELSE 1 ENDIF"], +["0", "IF 0xda ELSE 1 ENDIF"], +["0", "IF 0xdb ELSE 1 ENDIF"], +["0", "IF 0xdc ELSE 1 ENDIF"], +["0", "IF 0xdd ELSE 1 ENDIF"], +["0", "IF 0xde ELSE 1 ENDIF"], +["0", "IF 0xdf ELSE 1 ENDIF"], +["0", "IF 0xe0 ELSE 1 ENDIF"], +["0", "IF 0xe1 ELSE 1 ENDIF"], +["0", "IF 0xe2 ELSE 1 ENDIF"], +["0", "IF 0xe3 ELSE 1 ENDIF"], +["0", "IF 0xe4 ELSE 1 ENDIF"], +["0", "IF 0xe5 ELSE 1 ENDIF"], +["0", "IF 0xe6 ELSE 1 ENDIF"], +["0", "IF 0xe7 ELSE 1 ENDIF"], +["0", "IF 0xe8 ELSE 1 ENDIF"], +["0", "IF 0xe9 ELSE 1 ENDIF"], +["0", "IF 0xea ELSE 1 ENDIF"], +["0", "IF 0xeb ELSE 1 ENDIF"], +["0", "IF 0xec ELSE 1 ENDIF"], +["0", "IF 0xed ELSE 1 ENDIF"], ["0", "IF 0xee ELSE 1 ENDIF"], +["0", "IF 0xef ELSE 1 ENDIF"], +["0", "IF 0xf0 ELSE 1 ENDIF"], +["0", "IF 0xf1 ELSE 1 ENDIF"], +["0", "IF 0xf2 ELSE 1 ENDIF"], +["0", "IF 0xf3 ELSE 1 ENDIF"], +["0", "IF 0xf4 ELSE 1 ENDIF"], +["0", "IF 0xf5 ELSE 1 ENDIF"], +["0", "IF 0xf6 ELSE 1 ENDIF"], +["0", "IF 0xf7 ELSE 1 ENDIF"], +["0", "IF 0xf8 ELSE 1 ENDIF"], +["0", "IF 0xf9 ELSE 1 ENDIF"], +["0", "IF 0xfa ELSE 1 ENDIF"], +["0", "IF 0xfb ELSE 1 ENDIF"], +["0", "IF 0xfc ELSE 1 ENDIF"], ["0", "IF 0xfd ELSE 1 ENDIF"], +["0", "IF 0xfe ELSE 1 ENDIF"], ["0", "IF 0xff ELSE 1 ENDIF"], ["NOP", @@ -210,6 +291,10 @@ "'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' 0x6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f 2DUP 0x616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161", "Max-size (10,000-byte), max-push(520 bytes), max-opcodes(201), max stack size(1,000 items). 0x6f is 3DUP, 0x61 is NOP"], +["0", +"IF 0x5050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050 ENDIF 1", +">201 opcodes, but RESERVED (0x50) doesn't count towards opcode limit."], + ["NOP","1"], ["1", "0x01 0x01 EQUAL", "The following is useful for checking implementations of BN_bn2mpi"], @@ -235,6 +320,15 @@ ["2147483647", "1ADD 1"], ["-2147483647", "1ADD 1"], +["1", "0x02 0x0100 EQUAL NOT", "Not the same byte array..."], +["1", "0x02 0x0100 NUMEQUAL", "... but they are numerically equal"], +["11", "0x4c 0x03 0x0b0000 NUMEQUAL"], +["0", "0x01 0x80 EQUAL NOT"], +["0", "0x01 0x80 NUMEQUAL", "Zero numerically equals negative zero"], +["0", "0x02 0x0080 NUMEQUAL"], +["0x03 0x000080", "0x04 0x00000080 NUMEQUAL"], +["0x03 0x100080", "0x04 0x10000080 NUMEQUAL"], +["0x03 0x100000", "0x04 0x10000000 NUMEQUAL"], ["NOP", "NOP 1", "The following tests check the if(stack.size() < N) tests in each opcode"], ["1", "IF 1 ENDIF", "They are here to catch copy-and-paste errors"], @@ -309,5 +403,13 @@ ["NOP", "NOP10 1"], ["0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "Very basic P2SH"], -["0x4c 0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL"] +["0x4c 0 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL"], + +["0x40 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242", +"0x4d 0x4000 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 EQUAL", +"Basic PUSH signedness check"], + +["0x4c 0x40 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242", +"0x4d 0x4000 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 EQUAL", +"Basic PUSHDATA1 signedness check"] ] diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index f01ee06cfa..faf40ef23d 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -23,7 +23,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", true], -["Tests for CTransaction::CheckTransaction()"], +["Tests for CheckTransaction()"], ["No inputs"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]], "0100000000010000000000000000015100000000", true], @@ -60,5 +60,21 @@ ["Null txin"], [[["0000000000000000000000000000000000000000000000000000000000000000", -1, "HASH160 0x14 0x02dae7dbbda56097959cba59b1989dd3e47937bf EQUAL"]], -"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", true] +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6e49304602210086f39e028e46dafa8e1e3be63906465f4cf038fbe5ed6403dc3e74ae876e6431022100c4625c675cfc5c7e3a0e0d7eaec92ac24da20c73a88eb40d09253e51ac6def5201232103a183ddc41e84753aca47723c965d1b5c8b0e2b537963518355e6dd6cf8415e50acffffffff010000000000000000015100000000", true], + +["Same as the transactions in valid with one input SIGHASH_ALL and one SIGHASH_ANYONECANPAY, but we set the _ANYONECANPAY sequence number, invalidating the SIGHASH_ALL signature"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"], + ["0000000000000000000000000000000000000000000000000000000000000200", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"]], + "01000000020001000000000000000000000000000000000000000000000000000000000000000000004948304502203a0f5f0e1f2bdbcd04db3061d18f3af70e07f4f467cbc1b8116f267025f5360b022100c792b6e215afc5afc721a351ec413e714305cb749aae3d7fee76621313418df10101000000000200000000000000000000000000000000000000000000000000000000000000000000484730440220201dc2d030e380e8f9cfb41b442d930fa5a685bb2c8db5906671f865507d0670022018d9e7a8d4c8d86a73c2a724ee38ef983ec249827e0e464841735955c707ece98101000000010100000000000000015100000000", true], + +["Incorrect signature order"], +["Note the input is just required to make the tester happy"], +[[["b3da01dd4aae683c7aee4d5d8b52a540a508e1115f77cd7fa9a291243f501223", 0, "HASH160 0x14 0xb1ce99298d5f07364b57b1e5c9cc00be0b04a954 EQUAL"]], +"01000000012312503f2491a2a97fcd775f11e108a540a5528b5d4dee7a3c68ae4add01dab300000000fdfe000048304502207aacee820e08b0b174e248abd8d7a34ed63b5da3abedb99934df9fddd65c05c4022100dfe87896ab5ee3df476c2655f9fbe5bd089dccbef3e4ea05b5d121169fe7f5f401483045022100f6649b0eddfdfd4ad55426663385090d51ee86c3481bdc6b0c18ea6c0ece2c0b0220561c315b07cffa6f7dd9df96dbae9200c2dee09bf93cc35ca05e6cdf613340aa014c695221031d11db38972b712a9fe1fc023577c7ae3ddb4a3004187d41c45121eecfdbb5b7210207ec36911b6ad2382860d32989c7b8728e9489d7bbc94a6b5509ef0029be128821024ea9fac06f666a4adc3fc1357b7bec1fd0bdece2b9d08579226a8ebde53058e453aeffffffff0180380100000000001976a914c9b99cddf847d10685a4fabaa0baf505f7c3dfab88ac00000000", true], + +["Empty stack when we try to run CHECKSIG"], +[[["ad503f72c18df5801ee64d76090afe4c607fb2b822e9b7b63c5826c50e22fc3b", 0, "0x21 0x027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5 CHECKSIG NOT"]], +"01000000013bfc220ec526583cb6b7e922b8b27f604cfe0a09764de61e80f58dc1723f50ad0000000000ffffffff0101000000000000002321027c3a97665bf283a102a587a62a30a0c102d4d3b141015e2cae6f64e2543113e5ac00000000", true], + +["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 5528ae7243..c206f7a722 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -50,7 +50,7 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x8febbed40483661de6958d957412f82deed8e2f7 EQUAL"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100c66c9cdf4c43609586d15424c54707156e316d88b0a1534c9e6b0d4f311406310221009c0fe51dbc9c4ab7cc25d3fdbeccf6679fe6827f08edf2b4a9f16ee3eb0e438a0123210338e8034509af564c62644c07691942e0c056752008a173c89f60ab2a88ac2ebfacffffffff010000000000000000015100000000", true], -["Tests for CTransaction::CheckTransaction()"], +["Tests for CheckTransaction()"], ["MAX_MONEY output"], [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x32afac281462b822adbec5094b8d4d337dd5bd6a EQUAL"]], "01000000010001000000000000000000000000000000000000000000000000000000000000000000006e493046022100e1eadba00d9296c743cb6ecc703fd9ddc9b3cd12906176a226ae4c18d6b00796022100a71aef7d2874deff681ba6080f1b278bac7bb99c61b08a85f4311970ffe7f63f012321030c0588dc44d92bdcbf8e72093466766fdc265ead8db64517b0c542275b70fffbacffffffff010040075af0750700015100000000", true], @@ -67,5 +67,56 @@ ["Coinbase of size 100"], ["Note the input is just required to make the tester happy"], [[["0000000000000000000000000000000000000000000000000000000000000000", -1, "1"]], -"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6451515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true] +"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff6451515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151ffffffff010000000000000000015100000000", true], + +["Simple transaction with first input is signed with SIGHASH_ALL, second with SIGHASH_ANYONECANPAY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"], + ["0000000000000000000000000000000000000000000000000000000000000200", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"]], + "010000000200010000000000000000000000000000000000000000000000000000000000000000000049483045022100d180fd2eb9140aeb4210c9204d3f358766eb53842b2a9473db687fa24b12a3cc022079781799cd4f038b85135bbe49ec2b57f306b2bb17101b17f71f000fcab2b6fb01ffffffff0002000000000000000000000000000000000000000000000000000000000000000000004847304402205f7530653eea9b38699e476320ab135b74771e1c48b81a5d041e2ca84b9be7a802200ac8d1f40fb026674fe5a5edd3dea715c27baa9baca51ed45ea750ac9dc0a55e81ffffffff010100000000000000015100000000", true], + +["Same as above, but we change the sequence number of the first input to check that SIGHASH_ANYONECANPAY is being followed"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"], + ["0000000000000000000000000000000000000000000000000000000000000200", 0, "0x21 0x035e7f0d4d0841bcd56c39337ed086b1a633ee770c1ffdd94ac552a95ac2ce0efc CHECKSIG"]], + "01000000020001000000000000000000000000000000000000000000000000000000000000000000004948304502203a0f5f0e1f2bdbcd04db3061d18f3af70e07f4f467cbc1b8116f267025f5360b022100c792b6e215afc5afc721a351ec413e714305cb749aae3d7fee76621313418df101010000000002000000000000000000000000000000000000000000000000000000000000000000004847304402205f7530653eea9b38699e476320ab135b74771e1c48b81a5d041e2ca84b9be7a802200ac8d1f40fb026674fe5a5edd3dea715c27baa9baca51ed45ea750ac9dc0a55e81ffffffff010100000000000000015100000000", true], + +["afd9c17f8913577ec3509520bd6e5d63e9c0fd2a5f70c787993b097ba6ca9fae which has several SIGHASH_SINGLE signatures"], +[[["63cfa5a09dc540bf63e53713b82d9ea3692ca97cd608c384f2aa88e51a0aac70", 0, "DUP HASH160 0x14 0xdcf72c4fd02f5a987cf9b02f2fabfcac3341a87d EQUALVERIFY CHECKSIG"], + ["04e8d0fcf3846c6734477b98f0f3d4badfb78f020ee097a0be5fe347645b817d", 1, "DUP HASH160 0x14 0xdcf72c4fd02f5a987cf9b02f2fabfcac3341a87d EQUALVERIFY CHECKSIG"], + ["ee1377aff5d0579909e11782e1d2f5f7b84d26537be7f5516dd4e43373091f3f", 1, "DUP HASH160 0x14 0xdcf72c4fd02f5a987cf9b02f2fabfcac3341a87d EQUALVERIFY CHECKSIG"]], + "010000000370ac0a1ae588aaf284c308d67ca92c69a39e2db81337e563bf40c59da0a5cf63000000006a4730440220360d20baff382059040ba9be98947fd678fb08aab2bb0c172efa996fd8ece9b702201b4fb0de67f015c90e7ac8a193aeab486a1f587e0f54d0fb9552ef7f5ce6caec032103579ca2e6d107522f012cd00b52b9a65fb46f0c57b9b8b6e377c48f526a44741affffffff7d815b6447e35fbea097e00e028fb7dfbad4f3f0987b4734676c84f3fcd0e804010000006b483045022100c714310be1e3a9ff1c5f7cacc65c2d8e781fc3a88ceb063c6153bf950650802102200b2d0979c76e12bb480da635f192cc8dc6f905380dd4ac1ff35a4f68f462fffd032103579ca2e6d107522f012cd00b52b9a65fb46f0c57b9b8b6e377c48f526a44741affffffff3f1f097333e4d46d51f5e77b53264db8f7f5d2e18217e1099957d0f5af7713ee010000006c493046022100b663499ef73273a3788dea342717c2640ac43c5a1cf862c9e09b206fcb3f6bb8022100b09972e75972d9148f2bdd462e5cb69b57c1214b88fc55ca638676c07cfc10d8032103579ca2e6d107522f012cd00b52b9a65fb46f0c57b9b8b6e377c48f526a44741affffffff0380841e00000000001976a914bfb282c70c4191f45b5a6665cad1682f2c9cfdfb88ac80841e00000000001976a9149857cc07bed33a5cf12b9c5e0500b675d500c81188ace0fd1c00000000001976a91443c52850606c872403c0601e69fa34b26f62db4a88ac00000000", true], + + ["ddc454a1c0c35c188c98976b17670f69e586d9c0f3593ea879928332f0a069e7, which spends an input that pushes using a PUSHDATA1 that is negative when read as signed"], + [[["c5510a5dd97a25f43175af1fe649b707b1df8e1a41489bac33a23087027a2f48", 0, "0x4c 0xae 0x606563686f2022553246736447566b58312b5a536e587574356542793066794778625456415675534a6c376a6a334878416945325364667657734f53474f36633338584d7439435c6e543249584967306a486956304f376e775236644546673d3d22203e20743b206f70656e73736c20656e63202d7061737320706173733a5b314a564d7751432d707269766b65792d6865785d202d64202d6165732d3235362d636263202d61202d696e207460 DROP DUP HASH160 0x14 0xbfd7436b6265aa9de506f8a994f881ff08cc2872 EQUALVERIFY CHECKSIG"]], + "0100000001482f7a028730a233ac9b48411a8edfb107b749e61faf7531f4257ad95d0a51c5000000008b483045022100bf0bbae9bde51ad2b222e87fbf67530fbafc25c903519a1e5dcc52a32ff5844e022028c4d9ad49b006dd59974372a54291d5764be541574bb0c4dc208ec51f80b7190141049dd4aad62741dc27d5f267f7b70682eee22e7e9c1923b9c0957bdae0b96374569b460eb8d5b40d972e8c7c0ad441de3d94c4a29864b212d56050acb980b72b2bffffffff0180969800000000001976a914e336d0017a9d28de99d16472f6ca6d5a3a8ebc9988ac00000000", true], + +["Correct signature order"], +["Note the input is just required to make the tester happy"], +[[["b3da01dd4aae683c7aee4d5d8b52a540a508e1115f77cd7fa9a291243f501223", 0, "HASH160 0x14 0xb1ce99298d5f07364b57b1e5c9cc00be0b04a954 EQUAL"]], +"01000000012312503f2491a2a97fcd775f11e108a540a5528b5d4dee7a3c68ae4add01dab300000000fdfe0000483045022100f6649b0eddfdfd4ad55426663385090d51ee86c3481bdc6b0c18ea6c0ece2c0b0220561c315b07cffa6f7dd9df96dbae9200c2dee09bf93cc35ca05e6cdf613340aa0148304502207aacee820e08b0b174e248abd8d7a34ed63b5da3abedb99934df9fddd65c05c4022100dfe87896ab5ee3df476c2655f9fbe5bd089dccbef3e4ea05b5d121169fe7f5f4014c695221031d11db38972b712a9fe1fc023577c7ae3ddb4a3004187d41c45121eecfdbb5b7210207ec36911b6ad2382860d32989c7b8728e9489d7bbc94a6b5509ef0029be128821024ea9fac06f666a4adc3fc1357b7bec1fd0bdece2b9d08579226a8ebde53058e453aeffffffff0180380100000000001976a914c9b99cddf847d10685a4fabaa0baf505f7c3dfab88ac00000000", true], + +["cc60b1f899ec0a69b7c3f25ddf32c4524096a9c5b01cbd84c6d0312a0c478984, which is a fairly strange transaction which relies on OP_CHECKSIG returning 0 when checking a completely invalid sig of length 0"], +[[["cbebc4da731e8995fe97f6fadcd731b36ad40e5ecb31e38e904f6e5982fa09f7", 0, "0x2102085c6600657566acc2d6382a47bc3f324008d2aa10940dd7705a48aa2a5a5e33ac7c2103f5d0fb955f95dd6be6115ce85661db412ec6a08abcbfce7da0ba8297c6cc0ec4ac7c5379a820d68df9e32a147cffa36193c6f7c43a1c8c69cda530e1c6db354bfabdcfefaf3c875379a820f531f3041d3136701ea09067c53e7159c8f9b2746a56c3d82966c54bbc553226879a5479827701200122a59a5379827701200122a59a6353798277537982778779679a68"]], +"0100000001f709fa82596e4f908ee331cb5e0ed46ab331d7dcfaf697fe95891e73dac4ebcb000000008c20ca42095840735e89283fec298e62ac2ddea9b5f34a8cbb7097ad965b87568100201b1b01dc829177da4a14551d2fc96a9db00c6501edfa12f22cd9cefd335c227f483045022100a9df60536df5733dd0de6bc921fab0b3eee6426501b43a228afa2c90072eb5ca02201c78b74266fac7d1db5deff080d8a403743203f109fbcabf6d5a760bf87386d20100ffffffff01c075790000000000232103611f9a45c18f28f06f19076ad571c344c82ce8fcfe34464cf8085217a2d294a6ac00000000", true], + +["Empty pubkey"], +[[["229257c295e7f555421c1bfec8538dd30a4b5c37c1c8810bbe83cafa7811652c", 0, "0x00 CHECKSIG NOT"]], +"01000000012c651178faca83be0b81c8c1375c4b0ad38d53c8fe1b1c4255f5e795c25792220000000049483045022100d6044562284ac76c985018fc4a90127847708c9edb280996c507b28babdc4b2a02203d74eca3f1a4d1eea7ff77b528fde6d5dc324ec2dbfdb964ba885f643b9704cd01ffffffff010100000000000000232102c2410f8891ae918cab4ffc4bb4a3b0881be67c7a1e7faa8b5acf9ab8932ec30cac00000000", true], + +["Empty signature"], +[[["9ca93cfd8e3806b9d9e2ba1cf64e3cc6946ee0119670b1796a09928d14ea25f7", 0, "0x21 0x028a1d66975dbdf97897e3a4aef450ebeb5b5293e4a0b4a6d3a2daaa0b2b110e02 CHECKSIG NOT"]], +"0100000001f725ea148d92096a79b1709611e06e94c63c4ef61cbae2d9b906388efd3ca99c000000000100ffffffff0101000000000000002321028a1d66975dbdf97897e3a4aef450ebeb5b5293e4a0b4a6d3a2daaa0b2b110e02ac00000000", true], + +[[["444e00ed7840d41f20ecd9c11d3f91982326c731a02f3c05748414a4fa9e59be", 0, "1 0x00 0x21 0x02136b04758b0b6e363e7a6fbe83aaf527a153db2b060d36cc29f7f8309ba6e458 2 CHECKMULTISIG"]], +"0100000001be599efaa4148474053c2fa031c7262398913f1dc1d9ec201fd44078ed004e44000000004900473044022022b29706cb2ed9ef0cb3c97b72677ca2dfd7b4160f7b4beb3ba806aa856c401502202d1e52582412eba2ed474f1f437a427640306fd3838725fab173ade7fe4eae4a01ffffffff010100000000000000232103ac4bba7e7ca3e873eea49e08132ad30c7f03640b6539e9b59903cf14fd016bbbac00000000", true], + +[[["e16abbe80bf30c080f63830c8dbf669deaef08957446e95940227d8c5e6db612", 0, "1 0x21 0x03905380c7013e36e6e19d305311c1b81fce6581f5ee1c86ef0627c68c9362fc9f 0x00 2 CHECKMULTISIG"]], +"010000000112b66d5e8c7d224059e946749508efea9d66bf8d0c83630f080cf30be8bb6ae100000000490047304402206ffe3f14caf38ad5c1544428e99da76ffa5455675ec8d9780fac215ca17953520220779502985e194d84baa36b9bd40a0dbd981163fa191eb884ae83fc5bd1c86b1101ffffffff010100000000000000232103905380c7013e36e6e19d305311c1b81fce6581f5ee1c86ef0627c68c9362fc9fac00000000", true], + +[[["ebbcf4bfce13292bd791d6a65a2a858d59adbf737e387e40370d4e64cc70efb0", 0, "2 0x21 0x033bcaa0a602f0d44cc9d5637c6e515b0471db514c020883830b7cefd73af04194 0x21 0x03a88b326f8767f4f192ce252afe33c94d25ab1d24f27f159b3cb3aa691ffe1423 2 CHECKMULTISIG NOT"]], +"0100000001b0ef70cc644e0d37407e387e73bfad598d852a5aa6d691d72b2913cebff4bceb000000004a00473044022068cd4851fc7f9a892ab910df7a24e616f293bcb5c5fbdfbc304a194b26b60fba022078e6da13d8cb881a22939b952c24f88b97afd06b4c47a47d7f804c9a352a6d6d0100ffffffff0101000000000000002321033bcaa0a602f0d44cc9d5637c6e515b0471db514c020883830b7cefd73af04194ac00000000", true], + +[[["ba4cd7ae2ad4d4d13ebfc8ab1d93a63e4a6563f25089a18bf0fc68f282aa88c1", 0, "2 0x21 0x037c615d761e71d38903609bf4f46847266edc2fb37532047d747ba47eaae5ffe1 0x21 0x02edc823cd634f2c4033d94f5755207cb6b60c4b1f1f056ad7471c47de5f2e4d50 2 CHECKMULTISIG NOT"]], +"0100000001c188aa82f268fcf08ba18950f263654a3ea6931dabc8bf3ed1d4d42aaed74cba000000004b0000483045022100940378576e069aca261a6b26fb38344e4497ca6751bb10905c76bb689f4222b002204833806b014c26fd801727b792b1260003c55710f87c5adbd7a9cb57446dbc9801ffffffff0101000000000000002321037c615d761e71d38903609bf4f46847266edc2fb37532047d747ba47eaae5ffe1ac00000000", true], + +["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/getarg_tests.cpp b/src/test/getarg_tests.cpp index 78953d296f..d76124885b 100644 --- a/src/test/getarg_tests.cpp +++ b/src/test/getarg_tests.cpp @@ -1,13 +1,17 @@ + + +#include "util.h" + +#include <string> +#include <vector> + #include <boost/algorithm/string.hpp> #include <boost/foreach.hpp> #include <boost/test/unit_test.hpp> -#include "util.h" - BOOST_AUTO_TEST_SUITE(getarg_tests) -static void -ResetArgs(const std::string& strArg) +static void ResetArgs(const std::string& strArg) { std::vector<std::string> vecArg; boost::split(vecArg, strArg, boost::is_space(), boost::token_compress_on); @@ -26,62 +30,50 @@ ResetArgs(const std::string& strArg) BOOST_AUTO_TEST_CASE(boolarg) { ResetArgs("-foo"); - BOOST_CHECK(GetBoolArg("-foo")); BOOST_CHECK(GetBoolArg("-foo", false)); BOOST_CHECK(GetBoolArg("-foo", true)); - BOOST_CHECK(!GetBoolArg("-fo")); BOOST_CHECK(!GetBoolArg("-fo", false)); BOOST_CHECK(GetBoolArg("-fo", true)); - BOOST_CHECK(!GetBoolArg("-fooo")); BOOST_CHECK(!GetBoolArg("-fooo", false)); BOOST_CHECK(GetBoolArg("-fooo", true)); ResetArgs("-foo=0"); - BOOST_CHECK(!GetBoolArg("-foo")); BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); ResetArgs("-foo=1"); - BOOST_CHECK(GetBoolArg("-foo")); BOOST_CHECK(GetBoolArg("-foo", false)); BOOST_CHECK(GetBoolArg("-foo", true)); // New 0.6 feature: auto-map -nosomething to !-something: ResetArgs("-nofoo"); - BOOST_CHECK(!GetBoolArg("-foo")); BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); ResetArgs("-nofoo=1"); - BOOST_CHECK(!GetBoolArg("-foo")); BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); ResetArgs("-foo -nofoo"); // -foo should win - BOOST_CHECK(GetBoolArg("-foo")); BOOST_CHECK(GetBoolArg("-foo", false)); BOOST_CHECK(GetBoolArg("-foo", true)); ResetArgs("-foo=1 -nofoo=1"); // -foo should win - BOOST_CHECK(GetBoolArg("-foo")); BOOST_CHECK(GetBoolArg("-foo", false)); BOOST_CHECK(GetBoolArg("-foo", true)); ResetArgs("-foo=0 -nofoo=0"); // -foo should win - BOOST_CHECK(!GetBoolArg("-foo")); BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); // New 0.6 feature: treat -- same as -: ResetArgs("--foo=1"); - BOOST_CHECK(GetBoolArg("-foo")); BOOST_CHECK(GetBoolArg("-foo", false)); BOOST_CHECK(GetBoolArg("-foo", true)); ResetArgs("--nofoo=1"); - BOOST_CHECK(!GetBoolArg("-foo")); BOOST_CHECK(!GetBoolArg("-foo", false)); BOOST_CHECK(!GetBoolArg("-foo", true)); @@ -133,7 +125,7 @@ BOOST_AUTO_TEST_CASE(intarg) BOOST_AUTO_TEST_CASE(doubledash) { ResetArgs("--foo"); - BOOST_CHECK_EQUAL(GetBoolArg("-foo"), true); + BOOST_CHECK_EQUAL(GetBoolArg("-foo", false), true); ResetArgs("--foo=verbose --bar=1"); BOOST_CHECK_EQUAL(GetArg("-foo", ""), "verbose"); @@ -143,25 +135,24 @@ BOOST_AUTO_TEST_CASE(doubledash) BOOST_AUTO_TEST_CASE(boolargno) { ResetArgs("-nofoo"); - BOOST_CHECK(!GetBoolArg("-foo")); BOOST_CHECK(!GetBoolArg("-foo", true)); BOOST_CHECK(!GetBoolArg("-foo", false)); ResetArgs("-nofoo=1"); - BOOST_CHECK(!GetBoolArg("-foo")); BOOST_CHECK(!GetBoolArg("-foo", true)); BOOST_CHECK(!GetBoolArg("-foo", false)); ResetArgs("-nofoo=0"); - BOOST_CHECK(GetBoolArg("-foo")); BOOST_CHECK(GetBoolArg("-foo", true)); BOOST_CHECK(GetBoolArg("-foo", false)); ResetArgs("-foo --nofoo"); - BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(GetBoolArg("-foo", false)); ResetArgs("-nofoo -foo"); // foo always wins: - BOOST_CHECK(GetBoolArg("-foo")); + BOOST_CHECK(GetBoolArg("-foo", true)); + BOOST_CHECK(GetBoolArg("-foo", false)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp new file mode 100644 index 0000000000..28410f0fed --- /dev/null +++ b/src/test/hash_tests.cpp @@ -0,0 +1,47 @@ + + +#include "hash.h" +#include "util.h" + +#include <vector> + +#include <boost/test/unit_test.hpp> + +using namespace std; + +BOOST_AUTO_TEST_SUITE(hash_tests) + +BOOST_AUTO_TEST_CASE(murmurhash3) +{ + +#define T(expected, seed, data) BOOST_CHECK_EQUAL(MurmurHash3(seed, ParseHex(data)), expected) + + // Test MurmurHash3 with various inputs. Of course this is retested in the + // bloom filter tests - they would fail if MurmurHash3() had any problems - + // but is useful for those trying to implement Bitcoin libraries as a + // source of test data for their MurmurHash3() primitive during + // development. + // + // The magic number 0xFBA4C795 comes from CBloomFilter::Hash() + + T(0x00000000, 0x00000000, ""); + T(0x6a396f08, 0xFBA4C795, ""); + T(0x81f16f39, 0xffffffff, ""); + + T(0x514e28b7, 0x00000000, "00"); + T(0xea3f0b17, 0xFBA4C795, "00"); + T(0xfd6cf10d, 0x00000000, "ff"); + + T(0x16c6b7ab, 0x00000000, "0011"); + T(0x8eb51c3d, 0x00000000, "001122"); + T(0xb4471bf8, 0x00000000, "00112233"); + T(0xe2301fa8, 0x00000000, "0011223344"); + T(0xfc2e4a15, 0x00000000, "001122334455"); + T(0xb074502c, 0x00000000, "00112233445566"); + T(0x8034d2a0, 0x00000000, "0011223344556677"); + T(0xb4698def, 0x00000000, "001122334455667788"); + +#undef T +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/hmac_tests.cpp b/src/test/hmac_tests.cpp new file mode 100644 index 0000000000..68868866aa --- /dev/null +++ b/src/test/hmac_tests.cpp @@ -0,0 +1,127 @@ + + +#include "hash.h" +#include "util.h" + +#include <boost/test/unit_test.hpp> + +using namespace std; + +BOOST_AUTO_TEST_SUITE(hmac_tests) + +typedef struct { + const char *pszKey; + const char *pszData; + const char *pszMAC; +} testvec_t; + +// test cases 1, 2, 3, 4, 6 and 7 of RFC 4231 +static const testvec_t vtest[] = { + { + "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" + "0b0b0b0b", + "4869205468657265", + "87aa7cdea5ef619d4ff0b4241a1d6cb0" + "2379f4e2ce4ec2787ad0b30545e17cde" + "daa833b7d6b8a702038b274eaea3f4e4" + "be9d914eeb61f1702e696c203a126854" + }, + { + "4a656665", + "7768617420646f2079612077616e7420" + "666f72206e6f7468696e673f", + "164b7a7bfcf819e2e395fbe73b56e0a3" + "87bd64222e831fd610270cd7ea250554" + "9758bf75c05a994a6d034f65f8f0e6fd" + "caeab1a34d4a6b4b636e070a38bce737" + }, + { + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaa", + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddddddddddddddddddddddddddddddd" + "dddd", + "fa73b0089d56a284efb0f0756c890be9" + "b1b5dbdd8ee81a3655f83e33b2279d39" + "bf3e848279a722c806b485a47e67c807" + "b946a337bee8942674278859e13292fb" + }, + { + "0102030405060708090a0b0c0d0e0f10" + "111213141516171819", + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" + "cdcd", + "b0ba465637458c6990e5a8c5f61d4af7" + "e576d97ff94b872de76f8050361ee3db" + "a91ca5c11aa25eb4d679275cc5788063" + "a5f19741120c4f2de2adebeb10a298dd" + }, + { + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa", + "54657374205573696e67204c61726765" + "72205468616e20426c6f636b2d53697a" + "65204b6579202d2048617368204b6579" + "204669727374", + "80b24263c7c1a3ebb71493c1dd7be8b4" + "9b46d1f41b4aeec1121b013783f8f352" + "6b56d037e05f2598bd0fd2215d6a1e52" + "95e64f73f63f0aec8b915a985d786598" + }, + { + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaa", + "54686973206973206120746573742075" + "73696e672061206c6172676572207468" + "616e20626c6f636b2d73697a65206b65" + "7920616e642061206c61726765722074" + "68616e20626c6f636b2d73697a652064" + "6174612e20546865206b6579206e6565" + "647320746f2062652068617368656420" + "6265666f7265206265696e6720757365" + "642062792074686520484d414320616c" + "676f726974686d2e", + "e37b6a775dc87dbaa4dfa9f96e5e3ffd" + "debd71f8867289865df5a32d20cdc944" + "b6022cac3c4982b10d5eeb55c3e4de15" + "134676fb6de0446065c97440fa8c6a58" + } +}; + +BOOST_AUTO_TEST_CASE(hmacsha512_testvectors) +{ + for (unsigned int n=0; n<sizeof(vtest)/sizeof(vtest[0]); n++) + { + vector<unsigned char> vchKey = ParseHex(vtest[n].pszKey); + vector<unsigned char> vchData = ParseHex(vtest[n].pszData); + vector<unsigned char> vchMAC = ParseHex(vtest[n].pszMAC); + unsigned char vchTemp[64]; + + HMAC_SHA512_CTX ctx; + HMAC_SHA512_Init(&ctx, &vchKey[0], vchKey.size()); + HMAC_SHA512_Update(&ctx, &vchData[0], vchData.size()); + HMAC_SHA512_Final(&vchTemp[0], &ctx); + + BOOST_CHECK(memcmp(&vchTemp[0], &vchMAC[0], 64) == 0); + + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 0a6df88fef..421ffeac45 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -1,13 +1,15 @@ -#include <boost/test/unit_test.hpp> - -#include <string> -#include <vector> - #include "key.h" + #include "base58.h" +#include "script.h" #include "uint256.h" #include "util.h" +#include <string> +#include <vector> + +#include <boost/test/unit_test.hpp> + using namespace std; static const string strSecret1 ("5HxWvvfubhXpYYpS3tJkw6fq9jE9j18THftkZjHHfmFiWtmAbrj"); @@ -26,8 +28,8 @@ static const string strAddressBad("1HV9Lc3sNHZxwj4Zk6fB38tEmBryq2cBiF"); #ifdef KEY_TESTS_DUMPINFO void dumpKeyInfo(uint256 privkey) { - CSecret secret; - secret.resize(32); + CKey key; + key.resize(32); memcpy(&secret[0], &privkey, 32); vector<unsigned char> sec; sec.resize(32); @@ -62,29 +64,24 @@ BOOST_AUTO_TEST_CASE(key_test1) BOOST_CHECK( bsecret2C.SetString(strSecret2C)); BOOST_CHECK(!baddress1.SetString(strAddressBad)); - bool fCompressed; - CSecret secret1 = bsecret1.GetSecret (fCompressed); - BOOST_CHECK(fCompressed == false); - CSecret secret2 = bsecret2.GetSecret (fCompressed); - BOOST_CHECK(fCompressed == false); - CSecret secret1C = bsecret1C.GetSecret(fCompressed); - BOOST_CHECK(fCompressed == true); - CSecret secret2C = bsecret2C.GetSecret(fCompressed); - BOOST_CHECK(fCompressed == true); - - BOOST_CHECK(secret1 == secret1C); - BOOST_CHECK(secret2 == secret2C); - - CKey key1, key2, key1C, key2C; - key1.SetSecret(secret1, false); - key2.SetSecret(secret2, false); - key1C.SetSecret(secret1, true); - key2C.SetSecret(secret2, true); - - BOOST_CHECK(addr1.Get() == CTxDestination(key1.GetPubKey().GetID())); - BOOST_CHECK(addr2.Get() == CTxDestination(key2.GetPubKey().GetID())); - BOOST_CHECK(addr1C.Get() == CTxDestination(key1C.GetPubKey().GetID())); - BOOST_CHECK(addr2C.Get() == CTxDestination(key2C.GetPubKey().GetID())); + CKey key1 = bsecret1.GetKey(); + BOOST_CHECK(key1.IsCompressed() == false); + CKey key2 = bsecret2.GetKey(); + BOOST_CHECK(key2.IsCompressed() == false); + CKey key1C = bsecret1C.GetKey(); + BOOST_CHECK(key1C.IsCompressed() == true); + CKey key2C = bsecret2C.GetKey(); + BOOST_CHECK(key1C.IsCompressed() == true); + + CPubKey pubkey1 = key1. GetPubKey(); + CPubKey pubkey2 = key2. GetPubKey(); + CPubKey pubkey1C = key1C.GetPubKey(); + CPubKey pubkey2C = key2C.GetPubKey(); + + BOOST_CHECK(addr1.Get() == CTxDestination(pubkey1.GetID())); + BOOST_CHECK(addr2.Get() == CTxDestination(pubkey2.GetID())); + BOOST_CHECK(addr1C.Get() == CTxDestination(pubkey1C.GetID())); + BOOST_CHECK(addr2C.Get() == CTxDestination(pubkey2C.GetID())); for (int n=0; n<16; n++) { @@ -100,25 +97,25 @@ BOOST_AUTO_TEST_CASE(key_test1) BOOST_CHECK(key1C.Sign(hashMsg, sign1C)); BOOST_CHECK(key2C.Sign(hashMsg, sign2C)); - BOOST_CHECK( key1.Verify(hashMsg, sign1)); - BOOST_CHECK(!key1.Verify(hashMsg, sign2)); - BOOST_CHECK( key1.Verify(hashMsg, sign1C)); - BOOST_CHECK(!key1.Verify(hashMsg, sign2C)); + BOOST_CHECK( pubkey1.Verify(hashMsg, sign1)); + BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2)); + BOOST_CHECK( pubkey1.Verify(hashMsg, sign1C)); + BOOST_CHECK(!pubkey1.Verify(hashMsg, sign2C)); - BOOST_CHECK(!key2.Verify(hashMsg, sign1)); - BOOST_CHECK( key2.Verify(hashMsg, sign2)); - BOOST_CHECK(!key2.Verify(hashMsg, sign1C)); - BOOST_CHECK( key2.Verify(hashMsg, sign2C)); + BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1)); + BOOST_CHECK( pubkey2.Verify(hashMsg, sign2)); + BOOST_CHECK(!pubkey2.Verify(hashMsg, sign1C)); + BOOST_CHECK( pubkey2.Verify(hashMsg, sign2C)); - BOOST_CHECK( key1C.Verify(hashMsg, sign1)); - BOOST_CHECK(!key1C.Verify(hashMsg, sign2)); - BOOST_CHECK( key1C.Verify(hashMsg, sign1C)); - BOOST_CHECK(!key1C.Verify(hashMsg, sign2C)); + BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1)); + BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2)); + BOOST_CHECK( pubkey1C.Verify(hashMsg, sign1C)); + BOOST_CHECK(!pubkey1C.Verify(hashMsg, sign2C)); - BOOST_CHECK(!key2C.Verify(hashMsg, sign1)); - BOOST_CHECK( key2C.Verify(hashMsg, sign2)); - BOOST_CHECK(!key2C.Verify(hashMsg, sign1C)); - BOOST_CHECK( key2C.Verify(hashMsg, sign2C)); + BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1)); + BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2)); + BOOST_CHECK(!pubkey2C.Verify(hashMsg, sign1C)); + BOOST_CHECK( pubkey2C.Verify(hashMsg, sign2C)); // compact signatures (with key recovery) @@ -129,18 +126,17 @@ BOOST_AUTO_TEST_CASE(key_test1) BOOST_CHECK(key1C.SignCompact(hashMsg, csign1C)); BOOST_CHECK(key2C.SignCompact(hashMsg, csign2C)); - CKey rkey1, rkey2, rkey1C, rkey2C; - - BOOST_CHECK(rkey1.SetCompactSignature (hashMsg, csign1)); - BOOST_CHECK(rkey2.SetCompactSignature (hashMsg, csign2)); - BOOST_CHECK(rkey1C.SetCompactSignature(hashMsg, csign1C)); - BOOST_CHECK(rkey2C.SetCompactSignature(hashMsg, csign2C)); + CPubKey rkey1, rkey2, rkey1C, rkey2C; + BOOST_CHECK(rkey1.RecoverCompact (hashMsg, csign1)); + BOOST_CHECK(rkey2.RecoverCompact (hashMsg, csign2)); + BOOST_CHECK(rkey1C.RecoverCompact(hashMsg, csign1C)); + BOOST_CHECK(rkey2C.RecoverCompact(hashMsg, csign2C)); - BOOST_CHECK(rkey1.GetPubKey() == key1.GetPubKey()); - BOOST_CHECK(rkey2.GetPubKey() == key2.GetPubKey()); - BOOST_CHECK(rkey1C.GetPubKey() == key1C.GetPubKey()); - BOOST_CHECK(rkey2C.GetPubKey() == key2C.GetPubKey()); + BOOST_CHECK(rkey1 == pubkey1); + BOOST_CHECK(rkey2 == pubkey2); + BOOST_CHECK(rkey1C == pubkey1C); + BOOST_CHECK(rkey2C == pubkey2C); } } diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index af284653dd..d35137a663 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -1,10 +1,11 @@ -#include <boost/test/unit_test.hpp> -#include "init.h" + #include "main.h" +#include "miner.h" #include "uint256.h" #include "util.h" -#include "wallet.h" + +#include <boost/test/unit_test.hpp> extern void SHA256Transform(void* pstate, void* pinput, const void* pinit); @@ -48,14 +49,16 @@ struct { // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { - CReserveKey reservekey(pwalletMain); + CScript scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlockTemplate *pblocktemplate; - CTransaction tx; + CTransaction tx,tx2; CScript script; uint256 hash; + LOCK(cs_main); + // Simple block creation, nothing special yet: - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); // We can't make transactions until we have inputs // Therefore, load 100 blocks :) @@ -64,10 +67,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { CBlock *pblock = &pblocktemplate->block; // pointer for convenience pblock->nVersion = 1; - pblock->nTime = pindexBest->GetMedianTimePast()+1; + pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1; pblock->vtx[0].vin[0].scriptSig = CScript(); pblock->vtx[0].vin[0].scriptSig.push_back(blockinfo[i].extranonce); - pblock->vtx[0].vin[0].scriptSig.push_back(pindexBest->nHeight); + pblock->vtx[0].vin[0].scriptSig.push_back(chainActive.Height()); pblock->vtx[0].vout[0].scriptPubKey = CScript(); if (txFirst.size() < 2) txFirst.push_back(new CTransaction(pblock->vtx[0])); @@ -81,7 +84,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) delete pblocktemplate; // Just to make sure we can still make simple blocks - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + delete pblocktemplate; // block sigops > limit: 1000 CHECKMULTISIG + 1 tx.vin.resize(1); @@ -95,10 +99,10 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -115,17 +119,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { tx.vout[0].nValue -= 10000000; hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; } - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); // orphan in mempool hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -134,7 +138,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = 4900000000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; tx.vin.resize(2); tx.vin[1].scriptSig = CScript() << OP_1; @@ -142,8 +146,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[1].prevout.n = 0; tx.vout[0].nValue = 5900000000LL; hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -153,8 +157,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vin[0].scriptSig = CScript() << OP_0 << OP_1; tx.vout[0].nValue = 0; hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -166,13 +170,13 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) script = CScript() << OP_0; tx.vout[0].scriptPubKey.SetDestination(script.GetID()); hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vin[0].prevout.hash = hash; tx.vin[0].scriptSig = CScript() << (std::vector<unsigned char>)script; tx.vout[0].nValue -= 1000000; hash = tx.GetHash(); - mempool.addUnchecked(hash,tx); - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); @@ -182,23 +186,75 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) tx.vout[0].nValue = 4900000000LL; tx.vout[0].scriptPubKey = CScript() << OP_1; hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); tx.vout[0].scriptPubKey = CScript() << OP_2; hash = tx.GetHash(); - mempool.addUnchecked(hash, tx); - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); delete pblocktemplate; mempool.clear(); // subsidy changing - int nHeight = pindexBest->nHeight; - pindexBest->nHeight = 209999; - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + int nHeight = chainActive.Height(); + chainActive.Tip()->nHeight = 209999; + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + delete pblocktemplate; + chainActive.Tip()->nHeight = 210000; + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + delete pblocktemplate; + chainActive.Tip()->nHeight = nHeight; + + // non-final txs in mempool + SetMockTime(chainActive.Tip()->GetMedianTimePast()+1); + + // height locked + tx.vin[0].prevout.hash = txFirst[0]->GetHash(); + tx.vin[0].scriptSig = CScript() << OP_1; + tx.vin[0].nSequence = 0; + tx.vout[0].nValue = 4900000000LL; + tx.vout[0].scriptPubKey = CScript() << OP_1; + tx.nLockTime = chainActive.Tip()->nHeight+1; + hash = tx.GetHash(); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx, 11, GetTime(), 111.0, 11)); + BOOST_CHECK(!IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); + + // time locked + tx2.vin.resize(1); + tx2.vin[0].prevout.hash = txFirst[1]->GetHash(); + tx2.vin[0].prevout.n = 0; + tx2.vin[0].scriptSig = CScript() << OP_1; + tx2.vin[0].nSequence = 0; + tx2.vout.resize(1); + tx2.vout[0].nValue = 4900000000LL; + tx2.vout[0].scriptPubKey = CScript() << OP_1; + tx2.nLockTime = chainActive.Tip()->GetMedianTimePast()+1; + hash = tx2.GetHash(); + mempool.addUnchecked(hash, CTxMemPoolEntry(tx2, 11, GetTime(), 111.0, 11)); + BOOST_CHECK(!IsFinalTx(tx2)); + + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + + // Neither tx should have make it into the template. + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 1); delete pblocktemplate; - pindexBest->nHeight = 210000; - BOOST_CHECK(pblocktemplate = CreateNewBlock(reservekey)); + + // However if we advance height and time by one, both will. + chainActive.Tip()->nHeight++; + SetMockTime(chainActive.Tip()->GetMedianTimePast()+2); + + BOOST_CHECK(IsFinalTx(tx, chainActive.Tip()->nHeight + 1)); + BOOST_CHECK(IsFinalTx(tx2)); + + BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); + BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3); delete pblocktemplate; - pindexBest->nHeight = nHeight; + + chainActive.Tip()->nHeight--; + SetMockTime(0); + + BOOST_FOREACH(CTransaction *tx, txFirst) + delete tx; + } BOOST_AUTO_TEST_CASE(sha256transform_equality) diff --git a/src/test/mruset_tests.cpp b/src/test/mruset_tests.cpp index 64a6678a73..638c88fabe 100644 --- a/src/test/mruset_tests.cpp +++ b/src/test/mruset_tests.cpp @@ -1,13 +1,16 @@ -#include <boost/test/unit_test.hpp> - -using namespace std; - #include "mruset.h" + #include "util.h" +#include <set> + +#include <boost/test/unit_test.hpp> + #define NUM_TESTS 16 #define MAX_SIZE 100 +using namespace std; + class mrutester { private: diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp index 7297bb9a75..772217b888 100644 --- a/src/test/multisig_tests.cpp +++ b/src/test/multisig_tests.cpp @@ -1,25 +1,21 @@ -#include <boost/assert.hpp> -#include <boost/assign/list_of.hpp> -#include <boost/assign/list_inserter.hpp> -#include <boost/assign/std/vector.hpp> -#include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> -#include <boost/tuple/tuple.hpp> -#include <openssl/ec.h> -#include <openssl/err.h> +#include "key.h" #include "keystore.h" #include "main.h" #include "script.h" -#include "wallet.h" +#include "uint256.h" + +#include <boost/assign/std/vector.hpp> +#include <boost/foreach.hpp> +#include <boost/test/unit_test.hpp> using namespace std; using namespace boost::assign; typedef vector<unsigned char> valtype; -extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); BOOST_AUTO_TEST_SUITE(multisig_tests) @@ -30,7 +26,7 @@ sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, CScript result; result << OP_0; // CHECKMULTISIG bug workaround - BOOST_FOREACH(CKey key, keys) + BOOST_FOREACH(const CKey &key, keys) { vector<unsigned char> vchSig; BOOST_CHECK(key.Sign(hash, vchSig)); @@ -133,21 +129,23 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard) for (int i = 0; i < 4; i++) key[i].MakeNewKey(true); + txnouttype whichType; + CScript a_and_b; a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; - BOOST_CHECK(::IsStandard(a_and_b)); + BOOST_CHECK(::IsStandard(a_and_b, whichType)); CScript a_or_b; a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; - BOOST_CHECK(::IsStandard(a_or_b)); + BOOST_CHECK(::IsStandard(a_or_b, whichType)); CScript escrow; escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; - BOOST_CHECK(::IsStandard(escrow)); + BOOST_CHECK(::IsStandard(escrow, whichType)); CScript one_of_four; one_of_four << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << key[3].GetPubKey() << OP_4 << OP_CHECKMULTISIG; - BOOST_CHECK(!::IsStandard(one_of_four)); + BOOST_CHECK(!::IsStandard(one_of_four, whichType)); CScript malformed[6]; malformed[0] << OP_3 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; @@ -158,7 +156,7 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard) malformed[5] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey(); for (int i = 0; i < 6; i++) - BOOST_CHECK(!::IsStandard(malformed[i])); + BOOST_CHECK(!::IsStandard(malformed[i], whichType)); } BOOST_AUTO_TEST_CASE(multisig_Solver1) @@ -216,7 +214,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CScript s; s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(solutions.size(), 4); + BOOST_CHECK_EQUAL(solutions.size(), 4U); CTxDestination addr; BOOST_CHECK(!ExtractDestination(s, addr)); BOOST_CHECK(IsMine(keystore, s)); @@ -229,7 +227,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1) CScript s; s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; BOOST_CHECK(Solver(s, whichType, solutions)); - BOOST_CHECK_EQUAL(solutions.size(), 4); + BOOST_CHECK_EQUAL(solutions.size(), 4U); vector<CTxDestination> addrs; int nRequired; BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired)); diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index e5a7562d97..412ba04910 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -1,9 +1,8 @@ -#include <boost/test/unit_test.hpp> +#include "netbase.h" #include <string> -#include <vector> -#include "netbase.h" +#include <boost/test/unit_test.hpp> using namespace std; diff --git a/src/test/pmt_tests.cpp b/src/test/pmt_tests.cpp index cf09421617..dea5e1b824 100644 --- a/src/test/pmt_tests.cpp +++ b/src/test/pmt_tests.cpp @@ -1,7 +1,12 @@ -#include <boost/test/unit_test.hpp> -#include "uint256.h" + #include "main.h" +#include "serialize.h" +#include "uint256.h" + +#include <vector> + +#include <boost/test/unit_test.hpp> using namespace std; diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index f8fe443b87..29195545da 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -1,17 +1,15 @@ -#include <boost/algorithm/string.hpp> -#include <boost/foreach.hpp> -#include <boost/test/unit_test.hpp> +#include "rpcserver.h" +#include "rpcclient.h" #include "base58.h" -#include "util.h" -#include "bitcoinrpc.h" + +#include <boost/algorithm/string.hpp> +#include <boost/test/unit_test.hpp> using namespace std; using namespace json_spirit; -BOOST_AUTO_TEST_SUITE(rpc_tests) - -static Array +Array createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) { Array result; @@ -23,44 +21,7 @@ createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) return result; } -BOOST_AUTO_TEST_CASE(rpc_addmultisig) -{ - rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; - - // old, 65-byte-long: - const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8"; - // new, compressed: - const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; - - Value v; - CBitcoinAddress address; - BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); - - BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); - - BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false)); - address.SetString(v.get_str()); - BOOST_CHECK(address.IsValid() && address.IsScript()); - - BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error); - BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error); - BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error); - - BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error); - BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error); - - string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing - BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error); - - string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing - BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); -} - -static Value CallRPC(string args) +Value CallRPC(string args) { vector<string> vArgs; boost::split(vArgs, args, boost::is_any_of(" \t")); @@ -79,6 +40,9 @@ static Value CallRPC(string args) } } + +BOOST_AUTO_TEST_SUITE(rpc_tests) + BOOST_AUTO_TEST_CASE(rpc_rawparams) { // Test raw transaction API argument handling @@ -88,14 +52,6 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), runtime_error); BOOST_CHECK_THROW(CallRPC("getrawtransaction a3b807410df0b60fcb9736768df5823938b2f838694939ba45f3c0a1bff150ed not_int"), runtime_error); - BOOST_CHECK_NO_THROW(CallRPC("listunspent")); - BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error); - BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error); - BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error); - BOOST_CHECK_NO_THROW(r=CallRPC("listunspent 0 1 []")); - BOOST_CHECK_THROW(r=CallRPC("listunspent 0 1 [] extra"), runtime_error); - BOOST_CHECK(r.get_array().empty()); - BOOST_CHECK_THROW(CallRPC("createrawtransaction"), runtime_error); BOOST_CHECK_THROW(CallRPC("createrawtransaction null null"), runtime_error); BOOST_CHECK_THROW(CallRPC("createrawtransaction not_array"), runtime_error); @@ -147,4 +103,35 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) BOOST_CHECK(find_value(r.get_obj(), "complete").get_bool() == true); } +BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) +{ + BOOST_CHECK(write_string(ValueFromAmount(0LL), false) == "0.00000000"); + BOOST_CHECK(write_string(ValueFromAmount(1LL), false) == "0.00000001"); + BOOST_CHECK(write_string(ValueFromAmount(17622195LL), false) == "0.17622195"); + BOOST_CHECK(write_string(ValueFromAmount(50000000LL), false) == "0.50000000"); + BOOST_CHECK(write_string(ValueFromAmount(89898989LL), false) == "0.89898989"); + BOOST_CHECK(write_string(ValueFromAmount(100000000LL), false) == "1.00000000"); + BOOST_CHECK(write_string(ValueFromAmount(2099999999999990LL), false) == "20999999.99999990"); + BOOST_CHECK(write_string(ValueFromAmount(2099999999999999LL), false) == "20999999.99999999"); +} + +static Value ValueFromString(const std::string &str) +{ + Value value; + BOOST_CHECK(read_string(str, value)); + return value; +} + +BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) +{ + BOOST_CHECK(AmountFromValue(ValueFromString("0.00000001")) == 1LL); + BOOST_CHECK(AmountFromValue(ValueFromString("0.17622195")) == 17622195LL); + BOOST_CHECK(AmountFromValue(ValueFromString("0.5")) == 50000000LL); + BOOST_CHECK(AmountFromValue(ValueFromString("0.50000000")) == 50000000LL); + BOOST_CHECK(AmountFromValue(ValueFromString("0.89898989")) == 89898989LL); + BOOST_CHECK(AmountFromValue(ValueFromString("1.00000000")) == 100000000LL); + BOOST_CHECK(AmountFromValue(ValueFromString("20999999.9999999")) == 2099999999999990LL); + BOOST_CHECK(AmountFromValue(ValueFromString("20999999.99999999")) == 2099999999999999LL); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp new file mode 100644 index 0000000000..628ba95067 --- /dev/null +++ b/src/test/rpc_wallet_tests.cpp @@ -0,0 +1,89 @@ +#include "rpcserver.h" +#include "rpcclient.h" + +#include "base58.h" +#include "wallet.h" + +#include <boost/algorithm/string.hpp> +#include <boost/test/unit_test.hpp> + +using namespace std; +using namespace json_spirit; + +extern Array createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL); +extern Value CallRPC(string args); + +extern CWallet* pwalletMain; + +BOOST_AUTO_TEST_SUITE(rpc_wallet_tests) + +BOOST_AUTO_TEST_CASE(rpc_addmultisig) +{ + LOCK(pwalletMain->cs_wallet); + + rpcfn_type addmultisig = tableRPC["addmultisigaddress"]->actor; + + // old, 65-byte-long: + const char address1Hex[] = "0434e3e09f49ea168c5bbf53f877ff4206923858aab7c7e1df25bc263978107c95e35065a27ef6f1b27222db0ec97e0e895eaca603d3ee0d4c060ce3d8a00286c8"; + // new, compressed: + const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; + + Value v; + CBitcoinAddress address; + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex, address2Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(2, address1Hex, address2Hex), false)); + address.SetString(v.get_str()); + BOOST_CHECK(address.IsValid() && address.IsScript()); + + BOOST_CHECK_THROW(addmultisig(createArgs(0), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(1), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(2, address1Hex), false), runtime_error); + + BOOST_CHECK_THROW(addmultisig(createArgs(1, ""), false), runtime_error); + BOOST_CHECK_THROW(addmultisig(createArgs(1, "NotAValidPubkey"), false), runtime_error); + + string short1(address1Hex, address1Hex+sizeof(address1Hex)-2); // last byte missing + BOOST_CHECK_THROW(addmultisig(createArgs(2, short1.c_str()), false), runtime_error); + + string short2(address1Hex+1, address1Hex+sizeof(address1Hex)); // first byte missing + BOOST_CHECK_THROW(addmultisig(createArgs(2, short2.c_str()), false), runtime_error); +} + +BOOST_AUTO_TEST_CASE(rpc_wallet) +{ + // Test RPC calls for various wallet statistics + Value r; + + LOCK(pwalletMain->cs_wallet); + + BOOST_CHECK_NO_THROW(CallRPC("listunspent")); + BOOST_CHECK_THROW(CallRPC("listunspent string"), runtime_error); + BOOST_CHECK_THROW(CallRPC("listunspent 0 string"), runtime_error); + BOOST_CHECK_THROW(CallRPC("listunspent 0 1 not_array"), runtime_error); + BOOST_CHECK_THROW(CallRPC("listunspent 0 1 [] extra"), runtime_error); + BOOST_CHECK_NO_THROW(r=CallRPC("listunspent 0 1 []")); + BOOST_CHECK(r.get_array().empty()); + + BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress")); + BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0")); + BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress not_int"), runtime_error); + BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 not_bool"), runtime_error); + BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaddress 0 true")); + BOOST_CHECK_THROW(CallRPC("listreceivedbyaddress 0 true extra"), runtime_error); + + BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount")); + BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0")); + BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount not_int"), runtime_error); + BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 not_bool"), runtime_error); + BOOST_CHECK_NO_THROW(CallRPC("listreceivedbyaccount 0 true")); + BOOST_CHECK_THROW(CallRPC("listreceivedbyaccount 0 true extra"), runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp index b5107193fd..e57dc9bbba 100644 --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -1,13 +1,13 @@ -#include <boost/assert.hpp> -#include <boost/assign/list_of.hpp> -#include <boost/assign/list_inserter.hpp> -#include <boost/assign/std/vector.hpp> -#include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> +#include "script.h" + +#include "key.h" +#include "keystore.h" +#include "main.h" +#include "script.h" -#include "../main.h" -#include "../script.h" -#include "../wallet.h" +#include <vector> + +#include <boost/test/unit_test.hpp> using namespace std; @@ -74,13 +74,16 @@ BOOST_AUTO_TEST_CASE(sign) } CTransaction txFrom; // Funding transaction: + string reason; txFrom.vout.resize(8); for (int i = 0; i < 4; i++) { txFrom.vout[i].scriptPubKey = evalScripts[i]; + txFrom.vout[i].nValue = COIN; txFrom.vout[i+4].scriptPubKey = standardScripts[i]; + txFrom.vout[i+4].nValue = COIN; } - BOOST_CHECK(txFrom.IsStandard()); + BOOST_CHECK(IsStandardTx(txFrom, reason)); CTransaction txTo[8]; // Spending transactions for (int i = 0; i < 8; i++) @@ -143,19 +146,19 @@ BOOST_AUTO_TEST_CASE(set) // Test the CScript::Set* methods CBasicKeyStore keystore; CKey key[4]; - std::vector<CKey> keys; + std::vector<CPubKey> keys; for (int i = 0; i < 4; i++) { key[i].MakeNewKey(true); keystore.AddKey(key[i]); - keys.push_back(key[i]); + keys.push_back(key[i].GetPubKey()); } CScript inner[4]; inner[0].SetDestination(key[0].GetPubKey().GetID()); - inner[1].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+2)); - inner[2].SetMultisig(1, std::vector<CKey>(keys.begin(), keys.begin()+2)); - inner[3].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+3)); + inner[1].SetMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2)); + inner[2].SetMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2)); + inner[3].SetMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3)); CScript outer[4]; for (int i = 0; i < 4; i++) @@ -165,12 +168,14 @@ BOOST_AUTO_TEST_CASE(set) } CTransaction txFrom; // Funding transaction: + string reason; txFrom.vout.resize(4); for (int i = 0; i < 4; i++) { txFrom.vout[i].scriptPubKey = outer[i]; + txFrom.vout[i].nValue = CENT; } - BOOST_CHECK(txFrom.IsStandard()); + BOOST_CHECK(IsStandardTx(txFrom, reason)); CTransaction txTo[4]; // Spending transactions for (int i = 0; i < 4; i++) @@ -179,14 +184,14 @@ BOOST_AUTO_TEST_CASE(set) txTo[i].vout.resize(1); txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.hash = txFrom.GetHash(); - txTo[i].vout[0].nValue = 1; + txTo[i].vout[0].nValue = 1*CENT; txTo[i].vout[0].scriptPubKey = inner[i]; BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); } for (int i = 0; i < 4; i++) { BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); - BOOST_CHECK_MESSAGE(txTo[i].IsStandard(), strprintf("txTo[%d].IsStandard", i)); + BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i)); } } @@ -245,12 +250,12 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) CCoinsViewCache coins(coinsDummy); CBasicKeyStore keystore; CKey key[3]; - vector<CKey> keys; + vector<CPubKey> keys; for (int i = 0; i < 3; i++) { key[i].MakeNewKey(true); keystore.AddKey(key[i]); - keys.push_back(key[i]); + keys.push_back(key[i].GetPubKey()); } CTransaction txFrom; @@ -302,15 +307,15 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txTo.vin[2].prevout.hash = txFrom.GetHash(); BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2)); - BOOST_CHECK(txTo.AreInputsStandard(coins)); - BOOST_CHECK_EQUAL(txTo.GetP2SHSigOpCount(coins), 1); + BOOST_CHECK(::AreInputsStandard(txTo, coins)); + BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo, coins), 1U); // Make sure adding crap to the scriptSigs makes them non-standard: for (int i = 0; i < 3; i++) { CScript t = txTo.vin[i].scriptSig; txTo.vin[i].scriptSig = (CScript() << 11) + t; - BOOST_CHECK(!txTo.AreInputsStandard(coins)); + BOOST_CHECK(!::AreInputsStandard(txTo, coins)); txTo.vin[i].scriptSig = t; } @@ -326,11 +331,11 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard) txToNonStd.vin[1].prevout.hash = txFrom.GetHash(); txToNonStd.vin[1].scriptSig << OP_0 << Serialize(oneOfEleven); - BOOST_CHECK(!txToNonStd.AreInputsStandard(coins)); - BOOST_CHECK_EQUAL(txToNonStd.GetP2SHSigOpCount(coins), 11); + BOOST_CHECK(!::AreInputsStandard(txToNonStd, coins)); + BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd, coins), 11U); txToNonStd.vin[0].scriptSig.clear(); - BOOST_CHECK(!txToNonStd.AreInputsStandard(coins)); + BOOST_CHECK(!::AreInputsStandard(txToNonStd, coins)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 5d5a1525f7..dd1b613047 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -1,25 +1,34 @@ -#include <iostream> +#include "script.h" + +#include "data/script_invalid.json.h" +#include "data/script_valid.json.h" + +#include "key.h" +#include "keystore.h" +#include "main.h" + #include <fstream> +#include <stdint.h> +#include <string> #include <vector> + #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/split.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> #include <boost/foreach.hpp> -#include <boost/preprocessor/stringize.hpp> #include <boost/test/unit_test.hpp> #include "json/json_spirit_reader_template.h" -#include "json/json_spirit_writer_template.h" #include "json/json_spirit_utils.h" - -#include "main.h" -#include "wallet.h" +#include "json/json_spirit_writer_template.h" using namespace std; using namespace json_spirit; using namespace boost::algorithm; -extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); +extern uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; @@ -32,8 +41,12 @@ ParseScript(string s) if (mapOpNames.size() == 0) { - for (int op = OP_NOP; op <= OP_NOP10; op++) + for (int op = 0; op <= OP_NOP10; op++) { + // Allow OP_RESERVED to get into mapOpNames + if (op < OP_NOP && op != OP_RESERVED) + continue; + const char* name = GetOpName((opcodetype)op); if (strcmp(name, "OP_UNKNOWN") == 0) continue; @@ -54,7 +67,7 @@ ParseScript(string s) (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit()))) { // Number - int64 n = atoi64(w); + int64_t n = atoi64(w); result << n; } else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end()))) @@ -72,7 +85,7 @@ ParseScript(string s) } else if (mapOpNames.count(w)) { - // opcode, e.g. OP_ADD or OP_1: + // opcode, e.g. OP_ADD or ADD: result << mapOpNames[w]; } else @@ -86,34 +99,15 @@ ParseScript(string s) } Array -read_json(const std::string& filename) +read_json(const std::string& jsondata) { - namespace fs = boost::filesystem; - fs::path testFile = fs::current_path() / "test" / "data" / filename; - -#ifdef TEST_DATA_DIR - if (!fs::exists(testFile)) - { - testFile = fs::path(BOOST_PP_STRINGIZE(TEST_DATA_DIR)) / filename; - } -#endif - - ifstream ifs(testFile.string().c_str(), ifstream::in); Value v; - if (!read_stream(ifs, v)) - { - if (ifs.fail()) - BOOST_ERROR("Cound not find/open " << filename); - else - BOOST_ERROR("JSON syntax error in " << filename); - return Array(); - } - if (v.type() != array_type) + + if (!read_string(jsondata, v) || v.type() != array_type) { - BOOST_ERROR(filename << " does not contain a json array"); + BOOST_ERROR("Parse error."); return Array(); } - return v.get_array(); } @@ -126,7 +120,7 @@ BOOST_AUTO_TEST_CASE(script_valid) // Inner arrays are [ "scriptSig", "scriptPubKey" ] // ... where scriptSig and scriptPubKey are stringified // scripts. - Array tests = read_json("script_valid.json"); + Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); BOOST_FOREACH(Value& tv, tests) { @@ -150,7 +144,7 @@ BOOST_AUTO_TEST_CASE(script_valid) BOOST_AUTO_TEST_CASE(script_invalid) { // Scripts that should evaluate as invalid - Array tests = read_json("script_invalid.json"); + Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); BOOST_FOREACH(Value& tv, tests) { @@ -211,7 +205,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac // and vice-versa) // result << OP_0; - BOOST_FOREACH(CKey key, keys) + BOOST_FOREACH(const CKey &key, keys) { vector<unsigned char> vchSig; BOOST_CHECK(key.Sign(hash, vchSig)); @@ -221,7 +215,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac return result; } CScript -sign_multisig(CScript scriptPubKey, CKey key, CTransaction transaction) +sign_multisig(CScript scriptPubKey, const CKey &key, CTransaction transaction) { std::vector<CKey> keys; keys.push_back(key); @@ -333,11 +327,13 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) // Test the CombineSignatures function CBasicKeyStore keystore; vector<CKey> keys; + vector<CPubKey> pubkeys; for (int i = 0; i < 3; i++) { CKey key; key.MakeNewKey(i%2 == 1); keys.push_back(key); + pubkeys.push_back(key.GetPubKey()); keystore.AddKey(key); } @@ -390,7 +386,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_CHECK(combined == scriptSig); // Hardest case: Multisig 2-of-3 - scriptPubKey.SetMultisig(2, keys); + scriptPubKey.SetMultisig(2, pubkeys); keystore.AddCScript(scriptPubKey); SignSignature(keystore, txFrom, txTo, 0); combined = CombineSignatures(scriptPubKey, txTo, 0, scriptSig, empty); @@ -442,4 +438,22 @@ BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_CHECK(combined == partial3c); } +BOOST_AUTO_TEST_CASE(script_standard_push) +{ + for (int i=0; i<1000; i++) { + CScript script; + script << i; + BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Number " << i << " is not pure push."); + BOOST_CHECK_MESSAGE(script.HasCanonicalPushes(), "Number " << i << " push is not canonical."); + } + + for (int i=0; i<1000; i++) { + std::vector<unsigned char> data(i, '\111'); + CScript script; + script << data; + BOOST_CHECK_MESSAGE(script.IsPushOnly(), "Length " << i << " is not pure push."); + BOOST_CHECK_MESSAGE(script.HasCanonicalPushes(), "Length " << i << " push is not canonical."); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 90ac89f8c5..415f957811 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -1,9 +1,8 @@ -#include <boost/test/unit_test.hpp> +#include "serialize.h" -#include <string> -#include <vector> +#include <stdint.h> -#include "serialize.h" +#include <boost/test/unit_test.hpp> using namespace std; @@ -21,7 +20,7 @@ BOOST_AUTO_TEST_CASE(varints) BOOST_CHECK(size == ss.size()); } - for (uint64 i = 0; i < 100000000000ULL; i += 999999937) { + for (uint64_t i = 0; i < 100000000000ULL; i += 999999937) { ss << VARINT(i); size += ::GetSerializeSize(VARINT(i), 0, 0); BOOST_CHECK(size == ss.size()); @@ -29,17 +28,132 @@ BOOST_AUTO_TEST_CASE(varints) // decode for (int i = 0; i < 100000; i++) { - int j; + int j = -1; ss >> VARINT(j); BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); } - for (uint64 i = 0; i < 100000000000ULL; i += 999999937) { - uint64 j; + for (uint64_t i = 0; i < 100000000000ULL; i += 999999937) { + uint64_t j = -1; ss >> VARINT(j); BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); } +} + +BOOST_AUTO_TEST_CASE(compactsize) +{ + CDataStream ss(SER_DISK, 0); + vector<char>::size_type i, j; + + for (i = 1; i <= MAX_SIZE; i *= 2) + { + WriteCompactSize(ss, i-1); + WriteCompactSize(ss, i); + } + for (i = 1; i <= MAX_SIZE; i *= 2) + { + j = ReadCompactSize(ss); + BOOST_CHECK_MESSAGE((i-1) == j, "decoded:" << j << " expected:" << (i-1)); + j = ReadCompactSize(ss); + BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i); + } +} + +static bool isCanonicalException(const std::ios_base::failure& ex) +{ + std::ios_base::failure expectedException("non-canonical ReadCompactSize()"); + + // The string returned by what() can be different for different platforms. + // Instead of directly comparing the ex.what() with an expected string, + // create an instance of exception to see if ex.what() matches + // the expected explanatory string returned by the exception instance. + return strcmp(expectedException.what(), ex.what()) == 0; +} + + +BOOST_AUTO_TEST_CASE(noncanonical) +{ + // Write some non-canonical CompactSize encodings, and + // make sure an exception is thrown when read back. + CDataStream ss(SER_DISK, 0); + vector<char>::size_type n; + + // zero encoded with three bytes: + ss.write("\xfd\x00\x00", 3); + BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); + + // 0xfc encoded with three bytes: + ss.write("\xfd\xfc\x00", 3); + BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); + + // 0xfd encoded with three bytes is OK: + ss.write("\xfd\xfd\x00", 3); + n = ReadCompactSize(ss); + BOOST_CHECK(n == 0xfd); + + // zero encoded with five bytes: + ss.write("\xfe\x00\x00\x00\x00", 5); + BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); + + // 0xffff encoded with five bytes: + ss.write("\xfe\xff\xff\x00\x00", 5); + BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); + + // zero encoded with nine bytes: + ss.write("\xff\x00\x00\x00\x00\x00\x00\x00\x00", 9); + BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); + + // 0x01ffffff encoded with nine bytes: + ss.write("\xff\xff\xff\xff\x01\x00\x00\x00\x00", 9); + BOOST_CHECK_EXCEPTION(ReadCompactSize(ss), std::ios_base::failure, isCanonicalException); +} + +BOOST_AUTO_TEST_CASE(insert_delete) +{ + // Test inserting/deleting bytes. + CDataStream ss(SER_DISK, 0); + BOOST_CHECK_EQUAL(ss.size(), 0); + + ss.write("\x00\x01\x02\xff", 4); + BOOST_CHECK_EQUAL(ss.size(), 4); + + char c = (char)11; + + // Inserting at beginning/end/middle: + ss.insert(ss.begin(), c); + BOOST_CHECK_EQUAL(ss.size(), 5); + BOOST_CHECK_EQUAL(ss[0], c); + BOOST_CHECK_EQUAL(ss[1], 0); + + ss.insert(ss.end(), c); + BOOST_CHECK_EQUAL(ss.size(), 6); + BOOST_CHECK_EQUAL(ss[4], (char)0xff); + BOOST_CHECK_EQUAL(ss[5], c); + + ss.insert(ss.begin()+2, c); + BOOST_CHECK_EQUAL(ss.size(), 7); + BOOST_CHECK_EQUAL(ss[2], c); + + // Delete at beginning/end/middle + ss.erase(ss.begin()); + BOOST_CHECK_EQUAL(ss.size(), 6); + BOOST_CHECK_EQUAL(ss[0], 0); + + ss.erase(ss.begin()+ss.size()-1); + BOOST_CHECK_EQUAL(ss.size(), 5); + BOOST_CHECK_EQUAL(ss[4], (char)0xff); + + ss.erase(ss.begin()+1); + BOOST_CHECK_EQUAL(ss.size(), 4); + BOOST_CHECK_EQUAL(ss[0], 0); + BOOST_CHECK_EQUAL(ss[1], 1); + BOOST_CHECK_EQUAL(ss[2], 2); + BOOST_CHECK_EQUAL(ss[3], (char)0xff); + // Make sure GetAndClear does the right thing: + CSerializeData d; + ss.GetAndClear(d); + BOOST_CHECK_EQUAL(ss.size(), 0); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp new file mode 100644 index 0000000000..f098d46186 --- /dev/null +++ b/src/test/sighash_tests.cpp @@ -0,0 +1,120 @@ +#include <boost/test/unit_test.hpp> + +#include "main.h" +#include "util.h" + +extern uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); + +// Old script.cpp SignatureHash function +uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) +{ + if (nIn >= txTo.vin.size()) + { + printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn); + return 1; + } + CTransaction txTmp(txTo); + + // In case concatenating two scripts ends up with two codeseparators, + // or an extra one at the end, this prevents all those possible incompatibilities. + scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); + + // Blank out other inputs' signatures + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + txTmp.vin[i].scriptSig = CScript(); + txTmp.vin[nIn].scriptSig = scriptCode; + + // Blank out some of the outputs + if ((nHashType & 0x1f) == SIGHASH_NONE) + { + // Wildcard payee + txTmp.vout.clear(); + + // Let the others update at will + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + else if ((nHashType & 0x1f) == SIGHASH_SINGLE) + { + // Only lock-in the txout payee at same index as txin + unsigned int nOut = nIn; + if (nOut >= txTmp.vout.size()) + { + printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut); + return 1; + } + txTmp.vout.resize(nOut+1); + for (unsigned int i = 0; i < nOut; i++) + txTmp.vout[i].SetNull(); + + // Let the others update at will + for (unsigned int i = 0; i < txTmp.vin.size(); i++) + if (i != nIn) + txTmp.vin[i].nSequence = 0; + } + + // Blank out other inputs completely, not recommended for open transactions + if (nHashType & SIGHASH_ANYONECANPAY) + { + txTmp.vin[0] = txTmp.vin[nIn]; + txTmp.vin.resize(1); + } + + // Serialize and hash + CHashWriter ss(SER_GETHASH, 0); + ss << txTmp << nHashType; + return ss.GetHash(); +} + +void static RandomScript(CScript &script) { + static const opcodetype oplist[] = {OP_FALSE, OP_1, OP_2, OP_3, OP_CHECKSIG, OP_IF, OP_VERIF, OP_RETURN, OP_CODESEPARATOR}; + script = CScript(); + int ops = (insecure_rand() % 10); + for (int i=0; i<ops; i++) + script << oplist[insecure_rand() % (sizeof(oplist)/sizeof(oplist[0]))]; +} + +void static RandomTransaction(CTransaction &tx, bool fSingle) { + tx.nVersion = insecure_rand(); + tx.vin.clear(); + tx.vout.clear(); + tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0; + int ins = (insecure_rand() % 4) + 1; + int outs = fSingle ? ins : (insecure_rand() % 4) + 1; + for (int in = 0; in < ins; in++) { + tx.vin.push_back(CTxIn()); + CTxIn &txin = tx.vin.back(); + txin.prevout.hash = GetRandHash(); + txin.prevout.n = insecure_rand() % 4; + RandomScript(txin.scriptSig); + txin.nSequence = (insecure_rand() % 2) ? insecure_rand() : (unsigned int)-1; + } + for (int out = 0; out < outs; out++) { + tx.vout.push_back(CTxOut()); + CTxOut &txout = tx.vout.back(); + txout.nValue = insecure_rand() % 100000000; + RandomScript(txout.scriptPubKey); + } +} + +BOOST_AUTO_TEST_SUITE(sighash_tests) + +BOOST_AUTO_TEST_CASE(sighash_test) +{ + seed_insecure_rand(false); + + for (int i=0; i<50000; i++) { + int nHashType = insecure_rand(); + CTransaction txTo; + RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE); + CScript scriptCode; + RandomScript(scriptCode); + int nIn = insecure_rand() % txTo.vin.size(); + BOOST_CHECK(SignatureHash(scriptCode, txTo, nIn, nHashType) == + SignatureHashOld(scriptCode, txTo, nIn, nHashType)); + } +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/test/sigopcount_tests.cpp b/src/test/sigopcount_tests.cpp index 59673f9b3d..96f663ccef 100644 --- a/src/test/sigopcount_tests.cpp +++ b/src/test/sigopcount_tests.cpp @@ -1,9 +1,13 @@ -#include <vector> -#include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> -#include "script.h" + #include "key.h" +#include "script.h" +#include "uint256.h" + +#include <vector> + +#include <boost/foreach.hpp> +#include <boost/test/unit_test.hpp> using namespace std; @@ -21,40 +25,40 @@ BOOST_AUTO_TEST_CASE(GetSigOpCount) { // Test CScript::GetSigOpCount() CScript s1; - BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0); - BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 0U); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 0U); uint160 dummy; s1 << OP_1 << dummy << dummy << OP_2 << OP_CHECKMULTISIG; - BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 2U); s1 << OP_IF << OP_CHECKSIG << OP_ENDIF; - BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3); - BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(true), 3U); + BOOST_CHECK_EQUAL(s1.GetSigOpCount(false), 21U); CScript p2sh; p2sh.SetDestination(s1.GetID()); CScript scriptSig; scriptSig << OP_0 << Serialize(s1); - BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig), 3U); - std::vector<CKey> keys; + std::vector<CPubKey> keys; for (int i = 0; i < 3; i++) { CKey k; k.MakeNewKey(true); - keys.push_back(k); + keys.push_back(k.GetPubKey()); } CScript s2; s2.SetMultisig(1, keys); - BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3); - BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20); + BOOST_CHECK_EQUAL(s2.GetSigOpCount(true), 3U); + BOOST_CHECK_EQUAL(s2.GetSigOpCount(false), 20U); p2sh.SetDestination(s2.GetID()); - BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0); - BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(true), 0U); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(false), 0U); CScript scriptSig2; scriptSig2 << OP_1 << dummy << dummy << Serialize(s2); - BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3); + BOOST_CHECK_EQUAL(p2sh.GetSigOpCount(scriptSig2), 3U); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 1116507a34..96d0712403 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -1,15 +1,21 @@ #define BOOST_TEST_MODULE Bitcoin Test Suite -#include <boost/test/unit_test.hpp> -#include <boost/filesystem.hpp> -#include "db.h" -#include "txdb.h" + + #include "main.h" -#include "wallet.h" +#include "txdb.h" +#include "ui_interface.h" #include "util.h" +#ifdef ENABLE_WALLET +#include "db.h" +#include "wallet.h" +#endif + +#include <boost/filesystem.hpp> +#include <boost/test/unit_test.hpp> + CWallet* pwalletMain; -CClientUIInterface uiInterface; extern bool fPrintToConsole; extern void noui_connect(); @@ -17,11 +23,14 @@ extern void noui_connect(); struct TestingSetup { CCoinsViewDB *pcoinsdbview; boost::filesystem::path pathTemp; + boost::thread_group threadGroup; TestingSetup() { - fPrintToDebugger = true; // don't want to write to debug.log file + fPrintToDebugLog = false; // don't want to write to debug.log file noui_connect(); +#ifdef ENABLE_WALLET bitdb.MakeMock(); +#endif pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); mapArgs["-datadir"] = pathTemp.string(); @@ -29,23 +38,32 @@ struct TestingSetup { pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(*pcoinsdbview); InitBlockIndex(); +#ifdef ENABLE_WALLET bool fFirstRun; pwalletMain = new CWallet("wallet.dat"); pwalletMain->LoadWallet(fFirstRun); RegisterWallet(pwalletMain); +#endif nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) - NewThread(ThreadScriptCheck, NULL); + threadGroup.create_thread(&ThreadScriptCheck); + RegisterNodeSignals(GetNodeSignals()); } ~TestingSetup() { - ThreadScriptCheckQuit(); + threadGroup.interrupt_all(); + threadGroup.join_all(); + UnregisterNodeSignals(GetNodeSignals()); +#ifdef ENABLE_WALLET delete pwalletMain; pwalletMain = NULL; +#endif delete pcoinsTip; delete pcoinsdbview; delete pblocktree; +#ifdef ENABLE_WALLET bitdb.Flush(true); +#endif boost::filesystem::remove_all(pathTemp); } }; diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index f44d46fdb8..5212dfc70d 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -1,16 +1,24 @@ + + +#include "data/tx_invalid.json.h" +#include "data/tx_valid.json.h" + +#include "key.h" +#include "keystore.h" +#include "main.h" +#include "script.h" + #include <map> #include <string> + #include <boost/test/unit_test.hpp> #include "json/json_spirit_writer_template.h" -#include "main.h" -#include "wallet.h" - using namespace std; using namespace json_spirit; // In script_tests.cpp -extern Array read_json(const std::string& filename); +extern Array read_json(const std::string& jsondata); extern CScript ParseScript(string s); BOOST_AUTO_TEST_SUITE(transaction_tests) @@ -22,7 +30,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) // Inner arrays are either [ "comment" ] // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH // ... where all scripts are stringified scripts. - Array tests = read_json("tx_valid.json"); + Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); BOOST_FOREACH(Value& tv, tests) { @@ -67,7 +75,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) stream >> tx; CValidationState state; - BOOST_CHECK_MESSAGE(tx.CheckTransaction(state), strTest); + BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest); BOOST_CHECK(state.IsValid()); for (unsigned int i = 0; i < tx.vin.size(); i++) @@ -91,7 +99,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // Inner arrays are either [ "comment" ] // or [[[prevout hash, prevout index, prevout scriptPubKey], [input 2], ...],"], serializedTransaction, enforceP2SH // ... where all scripts are stringified scripts. - Array tests = read_json("tx_invalid.json"); + Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); BOOST_FOREACH(Value& tv, tests) { @@ -136,7 +144,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) stream >> tx; CValidationState state; - fValid = tx.CheckTransaction(state) && state.IsValid(); + fValid = CheckTransaction(tx, state) && state.IsValid(); for (unsigned int i = 0; i < tx.vin.size() && fValid; i++) { @@ -163,11 +171,11 @@ BOOST_AUTO_TEST_CASE(basic_transaction_tests) CTransaction tx; stream >> tx; CValidationState state; - BOOST_CHECK_MESSAGE(tx.CheckTransaction(state) && state.IsValid(), "Simple deserialized transaction should be valid."); + BOOST_CHECK_MESSAGE(CheckTransaction(tx, state) && state.IsValid(), "Simple deserialized transaction should be valid."); // Check that duplicate txins fail tx.vin.push_back(tx.vin[0]); - BOOST_CHECK_MESSAGE(!tx.CheckTransaction(state) || !state.IsValid(), "Transaction with duplicate txins should be invalid."); + BOOST_CHECK_MESSAGE(!CheckTransaction(tx, state) || !state.IsValid(), "Transaction with duplicate txins should be invalid."); } // @@ -230,36 +238,74 @@ BOOST_AUTO_TEST_CASE(test_Get) t1.vout[0].nValue = 90*CENT; t1.vout[0].scriptPubKey << OP_1; - BOOST_CHECK(t1.AreInputsStandard(coins)); - BOOST_CHECK_EQUAL(t1.GetValueIn(coins), (50+21+22)*CENT); + BOOST_CHECK(AreInputsStandard(t1, coins)); + BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50+21+22)*CENT); // Adding extra junk to the scriptSig should make it non-standard: t1.vin[0].scriptSig << OP_11; - BOOST_CHECK(!t1.AreInputsStandard(coins)); + BOOST_CHECK(!AreInputsStandard(t1, coins)); // ... as should not having enough: t1.vin[0].scriptSig = CScript(); - BOOST_CHECK(!t1.AreInputsStandard(coins)); + BOOST_CHECK(!AreInputsStandard(t1, coins)); } -BOOST_AUTO_TEST_CASE(test_GetThrow) +BOOST_AUTO_TEST_CASE(test_IsStandard) { CBasicKeyStore keystore; CCoinsView coinsDummy; CCoinsViewCache coins(coinsDummy); std::vector<CTransaction> dummyTransactions = SetupDummyInputs(keystore, coins); - CTransaction t1; - t1.vin.resize(3); - t1.vin[0].prevout.hash = dummyTransactions[0].GetHash(); - t1.vin[0].prevout.n = 0; - t1.vin[1].prevout.hash = dummyTransactions[1].GetHash();; - t1.vin[1].prevout.n = 0; - t1.vin[2].prevout.hash = dummyTransactions[1].GetHash();; - t1.vin[2].prevout.n = 1; - t1.vout.resize(2); - t1.vout[0].nValue = 90*CENT; - t1.vout[0].scriptPubKey << OP_1; + CTransaction t; + t.vin.resize(1); + t.vin[0].prevout.hash = dummyTransactions[0].GetHash(); + t.vin[0].prevout.n = 1; + t.vin[0].scriptSig << std::vector<unsigned char>(65, 0); + t.vout.resize(1); + t.vout[0].nValue = 90*CENT; + CKey key; + key.MakeNewKey(true); + t.vout[0].scriptPubKey.SetDestination(key.GetPubKey().GetID()); + + string reason; + BOOST_CHECK(IsStandardTx(t, reason)); + + t.vout[0].nValue = 501; // dust + BOOST_CHECK(!IsStandardTx(t, reason)); + + t.vout[0].nValue = 601; // 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) + t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); + BOOST_CHECK(IsStandardTx(t, reason)); + + // 81-byte TX_NULL_DATA (non-standard) + t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800"); + BOOST_CHECK(!IsStandardTx(t, reason)); + + // TX_NULL_DATA w/o PUSHDATA + t.vout.resize(1); + t.vout[0].scriptPubKey = CScript() << OP_RETURN; + BOOST_CHECK(IsStandardTx(t, reason)); + + // Only one TX_NULL_DATA permitted in all cases + t.vout.resize(2); + t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); + t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); + BOOST_CHECK(!IsStandardTx(t, reason)); + + t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); + t.vout[1].scriptPubKey = CScript() << OP_RETURN; + BOOST_CHECK(!IsStandardTx(t, reason)); + + t.vout[0].scriptPubKey = CScript() << OP_RETURN; + t.vout[1].scriptPubKey = CScript() << OP_RETURN; + BOOST_CHECK(!IsStandardTx(t, reason)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint160_tests.cpp b/src/test/uint160_tests.cpp deleted file mode 100644 index 35cb35b25a..0000000000 --- a/src/test/uint160_tests.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include <boost/test/unit_test.hpp> - -#include "uint256.h" - -BOOST_AUTO_TEST_SUITE(uint160_tests) - -BOOST_AUTO_TEST_CASE(uint160_equality) -{ - uint160 num1 = 10; - uint160 num2 = 11; - BOOST_CHECK(num1+1 == num2); - - uint64 num3 = 10; - BOOST_CHECK(num1 == num3); - BOOST_CHECK(num1+num2 == num3+num2); -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/uint256_tests.cpp b/src/test/uint256_tests.cpp index efdc8a6aeb..368484fdff 100644 --- a/src/test/uint256_tests.cpp +++ b/src/test/uint256_tests.cpp @@ -1,18 +1,633 @@ #include <boost/test/unit_test.hpp> - +#include <stdint.h> +#include <sstream> +#include <iomanip> +#include <limits> +#include <cmath> #include "uint256.h" +#include <string> +#include "version.h" BOOST_AUTO_TEST_SUITE(uint256_tests) + +const unsigned char R1Array[] = + "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2" + "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"; +const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c"; +const double R1Ldouble = 0.4887374590559308955; // R1L equals roughly R1Ldouble * 2^256 +const double R1Sdouble = 0.7096329412477836074; +const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32)); +const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20)); +const uint64_t R1LLow64 = 0x121156cfdb4a529cULL; + +const unsigned char R2Array[] = + "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf" + "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"; +const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32)); +const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20)); + +const char R1LplusR2L[] = "549FB09FEA236A1EA3E31D4D58F1B1369288D204211CA751527CFC175767850C"; + +const unsigned char ZeroArray[] = + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32)); +const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20)); + +const unsigned char OneArray[] = + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; +const uint256 OneL = uint256(std::vector<unsigned char>(OneArray,OneArray+32)); +const uint160 OneS = uint160(std::vector<unsigned char>(OneArray,OneArray+20)); + +const unsigned char MaxArray[] = + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; +const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32)); +const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20)); -BOOST_AUTO_TEST_CASE(uint256_equality) +const uint256 HalfL = (OneL << 255); +const uint160 HalfS = (OneS << 159); +std::string ArrayToString(const unsigned char A[], unsigned int width) { - uint256 num1 = 10; - uint256 num2 = 11; - BOOST_CHECK(num1+1 == num2); + std::stringstream Stream; + Stream << std::hex; + for (unsigned int i = 0; i < width; ++i) + { + Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1]; + } + return Stream.str(); +} + +BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality +{ + BOOST_CHECK(1 == 0+1); + // constructor uint256(vector<char>): + BOOST_CHECK(R1L.ToString() == ArrayToString(R1Array,32)); + BOOST_CHECK(R1S.ToString() == ArrayToString(R1Array,20)); + BOOST_CHECK(R2L.ToString() == ArrayToString(R2Array,32)); + BOOST_CHECK(R2S.ToString() == ArrayToString(R2Array,20)); + BOOST_CHECK(ZeroL.ToString() == ArrayToString(ZeroArray,32)); + BOOST_CHECK(ZeroS.ToString() == ArrayToString(ZeroArray,20)); + BOOST_CHECK(OneL.ToString() == ArrayToString(OneArray,32)); + BOOST_CHECK(OneS.ToString() == ArrayToString(OneArray,20)); + BOOST_CHECK(MaxL.ToString() == ArrayToString(MaxArray,32)); + BOOST_CHECK(MaxS.ToString() == ArrayToString(MaxArray,20)); + BOOST_CHECK(OneL.ToString() != ArrayToString(ZeroArray,32)); + BOOST_CHECK(OneS.ToString() != ArrayToString(ZeroArray,20)); + + // == and != + BOOST_CHECK(R1L != R2L && R1S != R2S); + BOOST_CHECK(ZeroL != OneL && ZeroS != OneS); + BOOST_CHECK(OneL != ZeroL && OneS != ZeroS); + BOOST_CHECK(MaxL != ZeroL && MaxS != ZeroS); + BOOST_CHECK(~MaxL == ZeroL && ~MaxS == ZeroS); + BOOST_CHECK( ((R1L ^ R2L) ^ R1L) == R2L); + BOOST_CHECK( ((R1S ^ R2S) ^ R1S) == R2S); + + uint64_t Tmp64 = 0xc4dab720d9c7acaaULL; + for (unsigned int i = 0; i < 256; ++i) + { + BOOST_CHECK(ZeroL != (OneL << i)); + BOOST_CHECK((OneL << i) != ZeroL); + BOOST_CHECK(R1L != (R1L ^ (OneL << i))); + BOOST_CHECK(((uint256(Tmp64) ^ (OneL << i) ) != Tmp64 )); + } + BOOST_CHECK(ZeroL == (OneL << 256)); - uint64 num3 = 10; - BOOST_CHECK(num1 == num3); - BOOST_CHECK(num1+num2 == num3+num2); + for (unsigned int i = 0; i < 160; ++i) + { + BOOST_CHECK(ZeroS != (OneS << i)); + BOOST_CHECK((OneS << i) != ZeroS); + BOOST_CHECK(R1S != (R1S ^ (OneS << i))); + BOOST_CHECK(((uint160(Tmp64) ^ (OneS << i) ) != Tmp64 )); + } + BOOST_CHECK(ZeroS == (OneS << 256)); + + // String Constructor and Copy Constructor + BOOST_CHECK(uint256("0x"+R1L.ToString()) == R1L); + BOOST_CHECK(uint256("0x"+R2L.ToString()) == R2L); + BOOST_CHECK(uint256("0x"+ZeroL.ToString()) == ZeroL); + BOOST_CHECK(uint256("0x"+OneL.ToString()) == OneL); + BOOST_CHECK(uint256("0x"+MaxL.ToString()) == MaxL); + BOOST_CHECK(uint256(R1L.ToString()) == R1L); + BOOST_CHECK(uint256(" 0x"+R1L.ToString()+" ") == R1L); + BOOST_CHECK(uint256("") == ZeroL); + BOOST_CHECK(R1L == uint256(R1ArrayHex)); + BOOST_CHECK(uint256(R1L) == R1L); + BOOST_CHECK((uint256(R1L^R2L)^R2L) == R1L); + BOOST_CHECK(uint256(ZeroL) == ZeroL); + BOOST_CHECK(uint256(OneL) == OneL); + + BOOST_CHECK(uint160("0x"+R1S.ToString()) == R1S); + BOOST_CHECK(uint160("0x"+R2S.ToString()) == R2S); + BOOST_CHECK(uint160("0x"+ZeroS.ToString()) == ZeroS); + BOOST_CHECK(uint160("0x"+OneS.ToString()) == OneS); + BOOST_CHECK(uint160("0x"+MaxS.ToString()) == MaxS); + BOOST_CHECK(uint160(R1S.ToString()) == R1S); + BOOST_CHECK(uint160(" 0x"+R1S.ToString()+" ") == R1S); + BOOST_CHECK(uint160("") == ZeroS); + BOOST_CHECK(R1S == uint160(R1ArrayHex)); + + BOOST_CHECK(uint160(R1S) == R1S); + BOOST_CHECK((uint160(R1S^R2S)^R2S) == R1S); + BOOST_CHECK(uint160(ZeroS) == ZeroS); + BOOST_CHECK(uint160(OneS) == OneS); + + // uint64_t constructor + BOOST_CHECK( (R1L & uint256("0xffffffffffffffff")) == uint256(R1LLow64)); + BOOST_CHECK(ZeroL == uint256(0)); + BOOST_CHECK(OneL == uint256(1)); + BOOST_CHECK(uint256("0xffffffffffffffff") = uint256(0xffffffffffffffffULL)); + BOOST_CHECK( (R1S & uint160("0xffffffffffffffff")) == uint160(R1LLow64)); + BOOST_CHECK(ZeroS == uint160(0)); + BOOST_CHECK(OneS == uint160(1)); + BOOST_CHECK(uint160("0xffffffffffffffff") = uint160(0xffffffffffffffffULL)); + + // Assignment (from base_uint) + uint256 tmpL = ~ZeroL; BOOST_CHECK(tmpL == ~ZeroL); + tmpL = ~OneL; BOOST_CHECK(tmpL == ~OneL); + tmpL = ~R1L; BOOST_CHECK(tmpL == ~R1L); + tmpL = ~R2L; BOOST_CHECK(tmpL == ~R2L); + tmpL = ~MaxL; BOOST_CHECK(tmpL == ~MaxL); + uint160 tmpS = ~ZeroS; BOOST_CHECK(tmpS == ~ZeroS); + tmpS = ~OneS; BOOST_CHECK(tmpS == ~OneS); + tmpS = ~R1S; BOOST_CHECK(tmpS == ~R1S); + tmpS = ~R2S; BOOST_CHECK(tmpS == ~R2S); + tmpS = ~MaxS; BOOST_CHECK(tmpS == ~MaxS); + + // Wrong length must give 0 + BOOST_CHECK(uint256(std::vector<unsigned char>(OneArray,OneArray+31)) == 0); + BOOST_CHECK(uint256(std::vector<unsigned char>(OneArray,OneArray+20)) == 0); + BOOST_CHECK(uint160(std::vector<unsigned char>(OneArray,OneArray+32)) == 0); + BOOST_CHECK(uint160(std::vector<unsigned char>(OneArray,OneArray+19)) == 0); +} + +void shiftArrayRight(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) +{ + for (unsigned int T=0; T < arrayLength; ++T) + { + unsigned int F = (T+bitsToShift/8); + if (F < arrayLength) + to[T] = from[F] >> (bitsToShift%8); + else + to[T] = 0; + if (F + 1 < arrayLength) + to[T] |= from[(F+1)] << (8-bitsToShift%8); + } +} + +void shiftArrayLeft(unsigned char* to, const unsigned char* from, unsigned int arrayLength, unsigned int bitsToShift) +{ + for (unsigned int T=0; T < arrayLength; ++T) + { + if (T >= bitsToShift/8) + { + unsigned int F = T-bitsToShift/8; + to[T] = from[F] << (bitsToShift%8); + if (T >= bitsToShift/8+1) + to[T] |= from[F-1] >> (8-bitsToShift%8); + } + else { + to[T] = 0; + } + } +} + +BOOST_AUTO_TEST_CASE( shifts ) { // "<<" ">>" "<<=" ">>=" + unsigned char TmpArray[32]; + uint256 TmpL; + for (unsigned int i = 0; i < 256; ++i) + { + shiftArrayLeft(TmpArray, OneArray, 32, i); + BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (OneL << i)); + TmpL = OneL; TmpL <<= i; + BOOST_CHECK(TmpL == (OneL << i)); + BOOST_CHECK((HalfL >> (255-i)) == (OneL << i)); + TmpL = HalfL; TmpL >>= (255-i); + BOOST_CHECK(TmpL == (OneL << i)); + + shiftArrayLeft(TmpArray, R1Array, 32, i); + BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L << i)); + TmpL = R1L; TmpL <<= i; + BOOST_CHECK(TmpL == (R1L << i)); + + shiftArrayRight(TmpArray, R1Array, 32, i); + BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (R1L >> i)); + TmpL = R1L; TmpL >>= i; + BOOST_CHECK(TmpL == (R1L >> i)); + + shiftArrayLeft(TmpArray, MaxArray, 32, i); + BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL << i)); + TmpL = MaxL; TmpL <<= i; + BOOST_CHECK(TmpL == (MaxL << i)); + + shiftArrayRight(TmpArray, MaxArray, 32, i); + BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (MaxL >> i)); + TmpL = MaxL; TmpL >>= i; + BOOST_CHECK(TmpL == (MaxL >> i)); + } + uint256 c1L = uint256(0x0123456789abcdefULL); + uint256 c2L = c1L << 128; + for (unsigned int i = 0; i < 128; ++i) { + BOOST_CHECK((c1L << i) == (c2L >> (128-i))); + } + for (unsigned int i = 128; i < 256; ++i) { + BOOST_CHECK((c1L << i) == (c2L << (i-128))); + } + + uint160 TmpS; + for (unsigned int i = 0; i < 160; ++i) + { + shiftArrayLeft(TmpArray, OneArray, 20, i); + BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (OneS << i)); + TmpS = OneS; TmpS <<= i; + BOOST_CHECK(TmpS == (OneS << i)); + BOOST_CHECK((HalfS >> (159-i)) == (OneS << i)); + TmpS = HalfS; TmpS >>= (159-i); + BOOST_CHECK(TmpS == (OneS << i)); + + shiftArrayLeft(TmpArray, R1Array, 20, i); + BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (R1S << i)); + TmpS = R1S; TmpS <<= i; + BOOST_CHECK(TmpS == (R1S << i)); + + shiftArrayRight(TmpArray, R1Array, 20, i); + BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (R1S >> i)); + TmpS = R1S; TmpS >>= i; + BOOST_CHECK(TmpS == (R1S >> i)); + + shiftArrayLeft(TmpArray, MaxArray, 20, i); + BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS << i)); + TmpS = MaxS; TmpS <<= i; + BOOST_CHECK(TmpS == (MaxS << i)); + + shiftArrayRight(TmpArray, MaxArray, 20, i); + BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (MaxS >> i)); + TmpS = MaxS; TmpS >>= i; + BOOST_CHECK(TmpS == (MaxS >> i)); + } + uint160 c1S = uint160(0x0123456789abcdefULL); + uint160 c2S = c1S << 80; + for (unsigned int i = 0; i < 80; ++i) { + BOOST_CHECK((c1S << i) == (c2S >> (80-i))); + } + for (unsigned int i = 80; i < 160; ++i) { + BOOST_CHECK((c1S << i) == (c2S << (i-80))); + } +} + +BOOST_AUTO_TEST_CASE( unaryOperators ) // ! ~ - +{ + BOOST_CHECK(!ZeroL); BOOST_CHECK(!ZeroS); + BOOST_CHECK(!(!OneL));BOOST_CHECK(!(!OneS)); + for (unsigned int i = 0; i < 256; ++i) + BOOST_CHECK(!(!(OneL<<i))); + for (unsigned int i = 0; i < 160; ++i) + BOOST_CHECK(!(!(OneS<<i))); + BOOST_CHECK(!(!R1L));BOOST_CHECK(!(!R1S)); + BOOST_CHECK(!(!R2S));BOOST_CHECK(!(!R2S)); + BOOST_CHECK(!(!MaxL));BOOST_CHECK(!(!MaxS)); + + BOOST_CHECK(~ZeroL == MaxL); BOOST_CHECK(~ZeroS == MaxS); + + unsigned char TmpArray[32]; + for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = ~R1Array[i]; } + BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (~R1L)); + BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (~R1S)); + + BOOST_CHECK(-ZeroL == ZeroL); BOOST_CHECK(-ZeroS == ZeroS); + BOOST_CHECK(-R1L == (~R1L)+1); + BOOST_CHECK(-R1S == (~R1S)+1); + for (unsigned int i = 0; i < 256; ++i) + BOOST_CHECK(-(OneL<<i) == (MaxL << i)); + for (unsigned int i = 0; i < 160; ++i) + BOOST_CHECK(-(OneS<<i) == (MaxS << i)); +} + + +// Check if doing _A_ _OP_ _B_ results in the same as applying _OP_ onto each +// element of Aarray and Barray, and then converting the result into a uint256. +#define CHECKBITWISEOPERATOR(_A_,_B_,_OP_) \ + for (unsigned int i = 0; i < 32; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ + BOOST_CHECK(uint256(std::vector<unsigned char>(TmpArray,TmpArray+32)) == (_A_##L _OP_ _B_##L)); \ + for (unsigned int i = 0; i < 20; ++i) { TmpArray[i] = _A_##Array[i] _OP_ _B_##Array[i]; } \ + BOOST_CHECK(uint160(std::vector<unsigned char>(TmpArray,TmpArray+20)) == (_A_##S _OP_ _B_##S)); + +#define CHECKASSIGNMENTOPERATOR(_A_,_B_,_OP_) \ + TmpL = _A_##L; TmpL _OP_##= _B_##L; BOOST_CHECK(TmpL == (_A_##L _OP_ _B_##L)); \ + TmpS = _A_##S; TmpS _OP_##= _B_##S; BOOST_CHECK(TmpS == (_A_##S _OP_ _B_##S)); + +BOOST_AUTO_TEST_CASE( bitwiseOperators ) +{ + unsigned char TmpArray[32]; + + CHECKBITWISEOPERATOR(R1,R2,|) + CHECKBITWISEOPERATOR(R1,R2,^) + CHECKBITWISEOPERATOR(R1,R2,&) + CHECKBITWISEOPERATOR(R1,Zero,|) + CHECKBITWISEOPERATOR(R1,Zero,^) + CHECKBITWISEOPERATOR(R1,Zero,&) + CHECKBITWISEOPERATOR(R1,Max,|) + CHECKBITWISEOPERATOR(R1,Max,^) + CHECKBITWISEOPERATOR(R1,Max,&) + CHECKBITWISEOPERATOR(Zero,R1,|) + CHECKBITWISEOPERATOR(Zero,R1,^) + CHECKBITWISEOPERATOR(Zero,R1,&) + CHECKBITWISEOPERATOR(Max,R1,|) + CHECKBITWISEOPERATOR(Max,R1,^) + CHECKBITWISEOPERATOR(Max,R1,&) + + uint256 TmpL; + uint160 TmpS; + CHECKASSIGNMENTOPERATOR(R1,R2,|) + CHECKASSIGNMENTOPERATOR(R1,R2,^) + CHECKASSIGNMENTOPERATOR(R1,R2,&) + CHECKASSIGNMENTOPERATOR(R1,Zero,|) + CHECKASSIGNMENTOPERATOR(R1,Zero,^) + CHECKASSIGNMENTOPERATOR(R1,Zero,&) + CHECKASSIGNMENTOPERATOR(R1,Max,|) + CHECKASSIGNMENTOPERATOR(R1,Max,^) + CHECKASSIGNMENTOPERATOR(R1,Max,&) + CHECKASSIGNMENTOPERATOR(Zero,R1,|) + CHECKASSIGNMENTOPERATOR(Zero,R1,^) + CHECKASSIGNMENTOPERATOR(Zero,R1,&) + CHECKASSIGNMENTOPERATOR(Max,R1,|) + CHECKASSIGNMENTOPERATOR(Max,R1,^) + CHECKASSIGNMENTOPERATOR(Max,R1,&) + + uint64_t Tmp64 = 0xe1db685c9a0b47a2ULL; + TmpL = R1L; TmpL |= Tmp64; BOOST_CHECK(TmpL == (R1L | uint256(Tmp64))); + TmpS = R1S; TmpS |= Tmp64; BOOST_CHECK(TmpS == (R1S | uint160(Tmp64))); + TmpL = R1L; TmpL |= 0; BOOST_CHECK(TmpL == R1L); + TmpS = R1S; TmpS |= 0; BOOST_CHECK(TmpS == R1S); + TmpL ^= 0; BOOST_CHECK(TmpL == R1L); + TmpS ^= 0; BOOST_CHECK(TmpS == R1S); + TmpL ^= Tmp64; BOOST_CHECK(TmpL == (R1L ^ uint256(Tmp64))); + TmpS ^= Tmp64; BOOST_CHECK(TmpS == (R1S ^ uint160(Tmp64))); +} + +BOOST_AUTO_TEST_CASE( comparison ) // <= >= < > +{ + uint256 TmpL; + for (unsigned int i = 0; i < 256; ++i) { + TmpL= OneL<< i; + BOOST_CHECK( TmpL >= ZeroL && TmpL > ZeroL && ZeroL < TmpL && ZeroL <= TmpL); + BOOST_CHECK( TmpL >= 0 && TmpL > 0 && 0 < TmpL && 0 <= TmpL); + TmpL |= R1L; + BOOST_CHECK( TmpL >= R1L ); BOOST_CHECK( (TmpL == R1L) != (TmpL > R1L)); BOOST_CHECK( (TmpL == R1L) || !( TmpL <= R1L)); + BOOST_CHECK( R1L <= TmpL ); BOOST_CHECK( (R1L == TmpL) != (R1L < TmpL)); BOOST_CHECK( (TmpL == R1L) || !( R1L >= TmpL)); + BOOST_CHECK(! (TmpL < R1L)); BOOST_CHECK(! (R1L > TmpL)); + } + uint160 TmpS; + for (unsigned int i = 0; i < 160; ++i) { + TmpS= OneS<< i; + BOOST_CHECK( TmpS >= ZeroS && TmpS > ZeroS && ZeroS < TmpS && ZeroS <= TmpS); + BOOST_CHECK( TmpS >= 0 && TmpS > 0 && 0 < TmpS && 0 <= TmpS); + TmpS |= R1S; + BOOST_CHECK( TmpS >= R1S ); BOOST_CHECK( (TmpS == R1S) != (TmpS > R1S)); BOOST_CHECK( (TmpS == R1S) || !( TmpS <= R1S)); + BOOST_CHECK( R1S <= TmpS ); BOOST_CHECK( (R1S == TmpS) != (R1S < TmpS)); BOOST_CHECK( (TmpS == R1S) || !( R1S >= TmpS)); + BOOST_CHECK(! (TmpS < R1S)); BOOST_CHECK(! (R1S > TmpS)); + } +} + +BOOST_AUTO_TEST_CASE( plusMinus ) +{ + uint256 TmpL = 0; + BOOST_CHECK(R1L+R2L == uint256(R1LplusR2L)); + TmpL += R1L; + BOOST_CHECK(TmpL == R1L); + TmpL += R2L; + BOOST_CHECK(TmpL == R1L + R2L); + BOOST_CHECK(OneL+MaxL == ZeroL); + BOOST_CHECK(MaxL+OneL == ZeroL); + for (unsigned int i = 1; i < 256; ++i) { + BOOST_CHECK( (MaxL >> i) + OneL == (HalfL >> (i-1)) ); + BOOST_CHECK( OneL + (MaxL >> i) == (HalfL >> (i-1)) ); + TmpL = (MaxL>>i); TmpL += OneL; + BOOST_CHECK( TmpL == (HalfL >> (i-1)) ); + TmpL = (MaxL>>i); TmpL += 1; + BOOST_CHECK( TmpL == (HalfL >> (i-1)) ); + TmpL = (MaxL>>i); + BOOST_CHECK( TmpL++ == (MaxL>>i) ); + BOOST_CHECK( TmpL == (HalfL >> (i-1))); + } + BOOST_CHECK(uint256(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint256(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); + TmpL = uint256(0xbedc77e27940a7ULL); TmpL += 0xee8d836fce66fbULL; + BOOST_CHECK(TmpL == uint256(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); + TmpL -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpL == 0xbedc77e27940a7ULL); + TmpL = R1L; + BOOST_CHECK(++TmpL == R1L+1); + + BOOST_CHECK(R1L -(-R2L) == R1L+R2L); + BOOST_CHECK(R1L -(-OneL) == R1L+OneL); + BOOST_CHECK(R1L - OneL == R1L+(-OneL)); + for (unsigned int i = 1; i < 256; ++i) { + BOOST_CHECK((MaxL>>i) - (-OneL) == (HalfL >> (i-1))); + BOOST_CHECK((HalfL >> (i-1)) - OneL == (MaxL>>i)); + TmpL = (HalfL >> (i-1)); + BOOST_CHECK(TmpL-- == (HalfL >> (i-1))); + BOOST_CHECK(TmpL == (MaxL >> i)); + TmpL = (HalfL >> (i-1)); + BOOST_CHECK(--TmpL == (MaxL >> i)); + } + TmpL = R1L; + BOOST_CHECK(--TmpL == R1L-1); + + // 160-bit; copy-pasted + uint160 TmpS = 0; + BOOST_CHECK(R1S+R2S == uint160(R1LplusR2L)); + TmpS += R1S; + BOOST_CHECK(TmpS == R1S); + TmpS += R2S; + BOOST_CHECK(TmpS == R1S + R2S); + BOOST_CHECK(OneS+MaxS == ZeroS); + BOOST_CHECK(MaxS+OneS == ZeroS); + for (unsigned int i = 1; i < 160; ++i) { + BOOST_CHECK( (MaxS >> i) + OneS == (HalfS >> (i-1)) ); + BOOST_CHECK( OneS + (MaxS >> i) == (HalfS >> (i-1)) ); + TmpS = (MaxS>>i); TmpS += OneS; + BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); + TmpS = (MaxS>>i); TmpS += 1; + BOOST_CHECK( TmpS == (HalfS >> (i-1)) ); + TmpS = (MaxS>>i); + BOOST_CHECK( TmpS++ == (MaxS>>i) ); + BOOST_CHECK( TmpS == (HalfS >> (i-1))); + } + BOOST_CHECK(uint160(0xbedc77e27940a7ULL) + 0xee8d836fce66fbULL == uint160(0xbedc77e27940a7ULL + 0xee8d836fce66fbULL)); + TmpS = uint160(0xbedc77e27940a7ULL); TmpS += 0xee8d836fce66fbULL; + BOOST_CHECK(TmpS == uint160(0xbedc77e27940a7ULL+0xee8d836fce66fbULL)); + TmpS -= 0xee8d836fce66fbULL; BOOST_CHECK(TmpS == 0xbedc77e27940a7ULL); + TmpS = R1S; + BOOST_CHECK(++TmpS == R1S+1); + + BOOST_CHECK(R1S -(-R2S) == R1S+R2S); + BOOST_CHECK(R1S -(-OneS) == R1S+OneS); + BOOST_CHECK(R1S - OneS == R1S+(-OneS)); + for (unsigned int i = 1; i < 160; ++i) { + BOOST_CHECK((MaxS>>i) - (-OneS) == (HalfS >> (i-1))); + BOOST_CHECK((HalfS >> (i-1)) - OneS == (MaxS>>i)); + TmpS = (HalfS >> (i-1)); + BOOST_CHECK(TmpS-- == (HalfS >> (i-1))); + BOOST_CHECK(TmpS == (MaxS >> i)); + TmpS = (HalfS >> (i-1)); + BOOST_CHECK(--TmpS == (MaxS >> i)); + } + TmpS = R1S; + BOOST_CHECK(--TmpS == R1S-1); + +} + +bool almostEqual(double d1, double d2) +{ + return fabs(d1-d2) <= 4*fabs(d1)*std::numeric_limits<double>::epsilon(); +} + +BOOST_AUTO_TEST_CASE( methods ) // GetHex SetHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize +{ + BOOST_CHECK(R1L.GetHex() == R1L.ToString()); + BOOST_CHECK(R2L.GetHex() == R2L.ToString()); + BOOST_CHECK(OneL.GetHex() == OneL.ToString()); + BOOST_CHECK(MaxL.GetHex() == MaxL.ToString()); + uint256 TmpL(R1L); + BOOST_CHECK(TmpL == R1L); + TmpL.SetHex(R2L.ToString()); BOOST_CHECK(TmpL == R2L); + TmpL.SetHex(ZeroL.ToString()); BOOST_CHECK(TmpL == 0); + TmpL.SetHex(HalfL.ToString()); BOOST_CHECK(TmpL == HalfL); + + TmpL.SetHex(R1L.ToString()); + BOOST_CHECK(memcmp(R1L.begin(), R1Array, 32)==0); + BOOST_CHECK(memcmp(TmpL.begin(), R1Array, 32)==0); + BOOST_CHECK(memcmp(R2L.begin(), R2Array, 32)==0); + BOOST_CHECK(memcmp(ZeroL.begin(), ZeroArray, 32)==0); + BOOST_CHECK(memcmp(OneL.begin(), OneArray, 32)==0); + BOOST_CHECK(R1L.size() == 32); + BOOST_CHECK(R2L.size() == 32); + BOOST_CHECK(ZeroL.size() == 32); + BOOST_CHECK(MaxL.size() == 32); + BOOST_CHECK(R1L.begin() + 32 == R1L.end()); + BOOST_CHECK(R2L.begin() + 32 == R2L.end()); + BOOST_CHECK(OneL.begin() + 32 == OneL.end()); + BOOST_CHECK(MaxL.begin() + 32 == MaxL.end()); + BOOST_CHECK(TmpL.begin() + 32 == TmpL.end()); + BOOST_CHECK(R1L.GetLow64() == R1LLow64); + BOOST_CHECK(HalfL.GetLow64() ==0x0000000000000000ULL); + BOOST_CHECK(OneL.GetLow64() ==0x0000000000000001ULL); + BOOST_CHECK(R1L.GetSerializeSize(0,PROTOCOL_VERSION) == 32); + BOOST_CHECK(ZeroL.GetSerializeSize(0,PROTOCOL_VERSION) == 32); + + std::stringstream ss; + R1L.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(R1L == TmpL); + ss.str(""); + ZeroL.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ZeroL == TmpL); + ss.str(""); + MaxL.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+32)); + TmpL.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(MaxL == TmpL); + ss.str(""); + + BOOST_CHECK(R1S.GetHex() == R1S.ToString()); + BOOST_CHECK(R2S.GetHex() == R2S.ToString()); + BOOST_CHECK(OneS.GetHex() == OneS.ToString()); + BOOST_CHECK(MaxS.GetHex() == MaxS.ToString()); + uint160 TmpS(R1S); + BOOST_CHECK(TmpS == R1S); + TmpS.SetHex(R2S.ToString()); BOOST_CHECK(TmpS == R2S); + TmpS.SetHex(ZeroS.ToString()); BOOST_CHECK(TmpS == 0); + TmpS.SetHex(HalfS.ToString()); BOOST_CHECK(TmpS == HalfS); + + TmpS.SetHex(R1S.ToString()); + BOOST_CHECK(memcmp(R1S.begin(), R1Array, 20)==0); + BOOST_CHECK(memcmp(TmpS.begin(), R1Array, 20)==0); + BOOST_CHECK(memcmp(R2S.begin(), R2Array, 20)==0); + BOOST_CHECK(memcmp(ZeroS.begin(), ZeroArray, 20)==0); + BOOST_CHECK(memcmp(OneS.begin(), OneArray, 20)==0); + BOOST_CHECK(R1S.size() == 20); + BOOST_CHECK(R2S.size() == 20); + BOOST_CHECK(ZeroS.size() == 20); + BOOST_CHECK(MaxS.size() == 20); + BOOST_CHECK(R1S.begin() + 20 == R1S.end()); + BOOST_CHECK(R2S.begin() + 20 == R2S.end()); + BOOST_CHECK(OneS.begin() + 20 == OneS.end()); + BOOST_CHECK(MaxS.begin() + 20 == MaxS.end()); + BOOST_CHECK(TmpS.begin() + 20 == TmpS.end()); + BOOST_CHECK(R1S.GetLow64() == R1LLow64); + BOOST_CHECK(HalfS.GetLow64() ==0x0000000000000000ULL); + BOOST_CHECK(OneS.GetLow64() ==0x0000000000000001ULL); + BOOST_CHECK(R1S.GetSerializeSize(0,PROTOCOL_VERSION) == 20); + BOOST_CHECK(ZeroS.GetSerializeSize(0,PROTOCOL_VERSION) == 20); + + R1S.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(R1Array,R1Array+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(R1S == TmpS); + ss.str(""); + ZeroS.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(ZeroArray,ZeroArray+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ZeroS == TmpS); + ss.str(""); + MaxS.Serialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(ss.str() == std::string(MaxArray,MaxArray+20)); + TmpS.Unserialize(ss,0,PROTOCOL_VERSION); + BOOST_CHECK(MaxS == TmpS); + ss.str(""); + + for (unsigned int i = 0; i < 255; ++i) + { + BOOST_CHECK((OneL << i).getdouble() == ldexp(1.0,i)); + if (i < 160) BOOST_CHECK((OneS << i).getdouble() == ldexp(1.0,i)); + } + BOOST_CHECK(ZeroL.getdouble() == 0.0); + BOOST_CHECK(ZeroS.getdouble() == 0.0); + for (int i = 256; i > 53; --i) + BOOST_CHECK(almostEqual((R1L>>(256-i)).getdouble(), ldexp(R1Ldouble,i))); + for (int i = 160; i > 53; --i) + BOOST_CHECK(almostEqual((R1S>>(160-i)).getdouble(), ldexp(R1Sdouble,i))); + uint64_t R1L64part = (R1L>>192).GetLow64(); + uint64_t R1S64part = (R1S>>96).GetLow64(); + for (int i = 53; i > 0; --i) // doubles can store all integers in {0,...,2^54-1} exactly + { + BOOST_CHECK((R1L>>(256-i)).getdouble() == (double)(R1L64part >> (64-i))); + BOOST_CHECK((R1S>>(160-i)).getdouble() == (double)(R1S64part >> (64-i))); + } +} + +BOOST_AUTO_TEST_CASE( getmaxcoverage ) // some more tests just to get 100% coverage +{ + // ~R1L give a base_uint<256> + BOOST_CHECK((~~R1L >> 10) == (R1L >> 10)); BOOST_CHECK((~~R1S >> 10) == (R1S >> 10)); + BOOST_CHECK((~~R1L << 10) == (R1L << 10)); BOOST_CHECK((~~R1S << 10) == (R1S << 10)); + BOOST_CHECK(!(~~R1L < R1L)); BOOST_CHECK(!(~~R1S < R1S)); + BOOST_CHECK(~~R1L <= R1L); BOOST_CHECK(~~R1S <= R1S); + BOOST_CHECK(!(~~R1L > R1L)); BOOST_CHECK(!(~~R1S > R1S)); + BOOST_CHECK(~~R1L >= R1L); BOOST_CHECK(~~R1S >= R1S); + BOOST_CHECK(!(R1L < ~~R1L)); BOOST_CHECK(!(R1S < ~~R1S)); + BOOST_CHECK(R1L <= ~~R1L); BOOST_CHECK(R1S <= ~~R1S); + BOOST_CHECK(!(R1L > ~~R1L)); BOOST_CHECK(!(R1S > ~~R1S)); + BOOST_CHECK(R1L >= ~~R1L); BOOST_CHECK(R1S >= ~~R1S); + + BOOST_CHECK(~~R1L + R2L == R1L + ~~R2L); + BOOST_CHECK(~~R1S + R2S == R1S + ~~R2S); + BOOST_CHECK(~~R1L - R2L == R1L - ~~R2L); + BOOST_CHECK(~~R1S - R2S == R1S - ~~R2S); + BOOST_CHECK(~R1L != R1L); BOOST_CHECK(R1L != ~R1L); + BOOST_CHECK(~R1S != R1S); BOOST_CHECK(R1S != ~R1S); + unsigned char TmpArray[32]; + CHECKBITWISEOPERATOR(~R1,R2,|) + CHECKBITWISEOPERATOR(~R1,R2,^) + CHECKBITWISEOPERATOR(~R1,R2,&) + CHECKBITWISEOPERATOR(R1,~R2,|) + CHECKBITWISEOPERATOR(R1,~R2,^) + CHECKBITWISEOPERATOR(R1,~R2,&) } BOOST_AUTO_TEST_SUITE_END() + diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index f56969cba6..691f02a9d7 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1,10 +1,11 @@ +#include "util.h" + +#include "sync.h" + +#include <stdint.h> #include <vector> -#include <boost/test/unit_test.hpp> -#include <boost/foreach.hpp> -#include "main.h" -#include "wallet.h" -#include "util.h" +#include <boost/test/unit_test.hpp> using namespace std; @@ -31,7 +32,7 @@ BOOST_AUTO_TEST_CASE(util_criticalsection) } BOOST_AUTO_TEST_CASE(util_MedianFilter) -{ +{ CMedianFilter<int> filter(5, 15); BOOST_CHECK_EQUAL(filter.median(), 15); @@ -56,10 +57,10 @@ BOOST_AUTO_TEST_CASE(util_MedianFilter) } static const unsigned char ParseHex_expected[65] = { - 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, - 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, - 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, - 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, + 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, + 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, + 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, + 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f }; BOOST_AUTO_TEST_CASE(util_ParseHex) @@ -123,13 +124,13 @@ BOOST_AUTO_TEST_CASE(util_ParseParameters) BOOST_CHECK(mapArgs.empty() && mapMultiArgs.empty()); ParseParameters(5, (char**)argv_test); - // expectation: -ignored is ignored (program name argument), + // expectation: -ignored is ignored (program name argument), // -a, -b and -ccc end up in map, -d ignored because it is after // a non-option argument (non-GNU option parsing) BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); - BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc") + BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc") && !mapArgs.count("f") && !mapArgs.count("-d")); - BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") + BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); @@ -154,10 +155,10 @@ BOOST_AUTO_TEST_CASE(util_GetArg) BOOST_CHECK_EQUAL(GetArg("inttest1", -1), 12345); BOOST_CHECK_EQUAL(GetArg("inttest2", -1), 81985529216486895LL); BOOST_CHECK_EQUAL(GetArg("inttest3", -1), -1); - BOOST_CHECK_EQUAL(GetBoolArg("booltest1"), true); - BOOST_CHECK_EQUAL(GetBoolArg("booltest2"), false); - BOOST_CHECK_EQUAL(GetBoolArg("booltest3"), false); - BOOST_CHECK_EQUAL(GetBoolArg("booltest4"), true); + BOOST_CHECK_EQUAL(GetBoolArg("booltest1", false), true); + BOOST_CHECK_EQUAL(GetBoolArg("booltest2", false), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest3", false), false); + BOOST_CHECK_EQUAL(GetBoolArg("booltest4", false), true); } BOOST_AUTO_TEST_CASE(util_WildcardMatch) @@ -200,7 +201,7 @@ BOOST_AUTO_TEST_CASE(util_FormatMoney) BOOST_AUTO_TEST_CASE(util_ParseMoney) { - int64 ret = 0; + int64_t ret = 0; BOOST_CHECK(ParseMoney("0.0", ret)); BOOST_CHECK_EQUAL(ret, 0); @@ -261,4 +262,80 @@ BOOST_AUTO_TEST_CASE(util_IsHex) BOOST_CHECK(!IsHex("0x0000")); } +BOOST_AUTO_TEST_CASE(util_seed_insecure_rand) +{ + int i; + int count=0; + + seed_insecure_rand(true); + + for (int mod=2;mod<11;mod++) + { + int mask = 1; + // Really rough binomal confidence approximation. + int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.); + //mask is 2^ceil(log2(mod))-1 + while(mask<mod-1)mask=(mask<<1)+1; + + count = 0; + //How often does it get a zero from the uniform range [0,mod)? + for (i=0;i<10000;i++) + { + uint32_t rval; + do{ + rval=insecure_rand()&mask; + }while(rval>=(uint32_t)mod); + count += rval==0; + } + BOOST_CHECK(count<=10000/mod+err); + BOOST_CHECK(count>=10000/mod-err); + } +} + +BOOST_AUTO_TEST_CASE(util_TimingResistantEqual) +{ + BOOST_CHECK(TimingResistantEqual(std::string(""), std::string(""))); + BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string(""))); + BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc"))); + BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa"))); + BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a"))); + BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc"))); + BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba"))); +} + +/* Test strprintf formatting directives. + * Put a string before and after to ensure sanity of element sizes on stack. */ +#define B "check_prefix" +#define E "check_postfix" +BOOST_AUTO_TEST_CASE(strprintf_numbers) +{ + int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */ + uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */ + BOOST_CHECK(strprintf("%s %"PRId64" %s", B, s64t, E) == B" -9223372036854775807 "E); + BOOST_CHECK(strprintf("%s %"PRIu64" %s", B, u64t, E) == B" 18446744073709551615 "E); + BOOST_CHECK(strprintf("%s %"PRIx64" %s", B, u64t, E) == B" ffffffffffffffff "E); + + size_t st = 12345678; /* unsigned size_t test value */ + ssize_t sst = -12345678; /* signed size_t test value */ + BOOST_CHECK(strprintf("%s %"PRIszd" %s", B, sst, E) == B" -12345678 "E); + BOOST_CHECK(strprintf("%s %"PRIszu" %s", B, st, E) == B" 12345678 "E); + BOOST_CHECK(strprintf("%s %"PRIszx" %s", B, st, E) == B" bc614e "E); + + ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */ + ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */ + BOOST_CHECK(strprintf("%s %"PRIpdd" %s", B, spt, E) == B" -87654321 "E); + BOOST_CHECK(strprintf("%s %"PRIpdu" %s", B, pt, E) == B" 87654321 "E); + BOOST_CHECK(strprintf("%s %"PRIpdx" %s", B, pt, E) == B" 5397fb1 "E); +} +#undef B +#undef E + +/* Check for mingw/wine issue #3494 + * Remove this test before time.ctime(0xffffffff) == 'Sun Feb 7 07:28:15 2106' + */ +BOOST_AUTO_TEST_CASE(gettime) +{ + BOOST_CHECK((GetTime() & ~0xFFFFFFFFLL) == 0); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp index b0b3c47967..bd0517ae08 100644 --- a/src/test/wallet_tests.cpp +++ b/src/test/wallet_tests.cpp @@ -1,8 +1,13 @@ -#include <boost/test/unit_test.hpp> - -#include "main.h" #include "wallet.h" +#include <set> +#include <stdint.h> +#include <utility> +#include <vector> + +#include <boost/foreach.hpp> +#include <boost/test/unit_test.hpp> + // how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles #define RUN_TESTS 100 @@ -19,15 +24,14 @@ BOOST_AUTO_TEST_SUITE(wallet_tests) static CWallet wallet; static vector<COutput> vCoins; -static void add_coin(int64 nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) +static void add_coin(int64_t nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0) { - static int i; - CTransaction* tx = new CTransaction; - tx->nLockTime = i++; // so all transactions get different hashes - tx->vout.resize(nInput+1); - tx->vout[nInput].nValue = nValue; - CWalletTx* wtx = new CWalletTx(&wallet, *tx); - delete tx; + static int nextLockTime = 0; + CTransaction tx; + tx.nLockTime = nextLockTime++; // so all transactions get different hashes + tx.vout.resize(nInput+1); + tx.vout[nInput].nValue = nValue; + CWalletTx* wtx = new CWalletTx(&wallet, tx); if (fIsFromMe) { // IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if vin.empty(), @@ -55,8 +59,10 @@ static bool equal_sets(CoinSet a, CoinSet b) BOOST_AUTO_TEST_CASE(coin_selection_tests) { - static CoinSet setCoinsRet, setCoinsRet2; - static int64 nValueRet; + CoinSet setCoinsRet, setCoinsRet2; + int64_t nValueRet; + + LOCK(wallet.cs_wallet); // test multiple times to allow for differences in the shuffle order for (int i = 0; i < RUN_TESTS; i++) @@ -104,22 +110,22 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // try making 34 cents from 1,2,5,10,20 - we can't do it exactly BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents - BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); - BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // when we try making 8 cents, the smaller coins (1,2,5) are exactly enough. BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK(nValueRet == 8 * CENT); - BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10) BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); - BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // now clear out the wallet and start again to test choosing between subsets of smaller coins and the next biggest coin empty_wallet(); @@ -137,26 +143,26 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20 BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin - BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total // now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20 BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins - BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 // and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18 BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin - BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); // because in the event of a tie, the biggest coin wins + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // because in the event of a tie, the biggest coin wins // now try making 11 cents. we should get 5+6 BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); - BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // check that the smallest bigger coin is used add_coin( 1*COIN); @@ -165,11 +171,11 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin - BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin - BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance empty_wallet(); @@ -207,7 +213,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount - BOOST_CHECK_EQUAL(setCoinsRet.size(), 10); // in ten coins + BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins // if there's not enough in the smaller coins to make at least 1 cent change (0.5+0.6+0.7 < 1.0+1.0), // we need to try finding an exact subset anyway @@ -220,7 +226,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(1111 * CENT); BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin - BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); @@ -230,7 +236,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) add_coin(1111 * CENT); BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount - BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); // in two coins 0.4+0.6 + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6 // test avoiding sub-cent change empty_wallet(); @@ -241,12 +247,12 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // trying to make 1.0001 from these three coins BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins - BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01 - BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); + BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // test randomness { @@ -290,6 +296,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) BOOST_CHECK_NE(fails, RANDOM_REPEATS); } } + empty_wallet(); } BOOST_AUTO_TEST_SUITE_END() |