moved all stuff to github

This commit is contained in:
Antonio Juarez 2014-03-03 22:07:58 +00:00
parent 095fbeeb67
commit 296ae46ed8
388 changed files with 95937 additions and 469 deletions

502
tests/unit_tests/base58.cpp Normal file
View file

@ -0,0 +1,502 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include <cstdint>
#include "common/base58.cpp"
#include "cryptonote_core/cryptonote_basic_impl.h"
#include "serialization/binary_utils.h"
using namespace tools;
#define MAKE_STR(arr) std::string(arr, sizeof(arr) - 1)
namespace
{
void do_test_uint_8be_to_64(uint64_t expected, const uint8_t* data, size_t size)
{
uint64_t val = base58::uint_8be_to_64(data, size);
ASSERT_EQ(val, expected);
}
void do_test_uint_64_to_8be(uint64_t num, const std::string& expected_str)
{
std::string data(expected_str.size(), '\x0');
base58::uint_64_to_8be(num, data.size(), reinterpret_cast<uint8_t*>(&data[0]));
ASSERT_EQ(data, expected_str);
}
void do_test_encode_block(const std::string& block, const std::string& expected)
{
ASSERT_TRUE(1 <= block.size() && block.size() <= base58::full_block_size);
std::string enc(base58::encoded_block_sizes[block.size()], base58::alphabet[0]);
base58::encode_block(block.data(), block.size(), &enc[0]);
ASSERT_EQ(enc, expected);
std::string dec(block.size(), '\0');
ASSERT_TRUE(base58::decode_block(enc.data(), enc.size(), &dec[0]));
ASSERT_EQ(block, dec);
}
void do_test_decode_block_pos(const std::string& enc, const std::string& expected)
{
std::string data(base58::decoded_block_sizes::instance(enc.size()), '\0');
ASSERT_TRUE(base58::decode_block(enc.data(), enc.size(), &data[0]));
ASSERT_EQ(data, expected);
}
void do_test_decode_block_neg(const std::string& enc)
{
std::string data(base58::full_block_size, '\0');
ASSERT_FALSE(base58::decode_block(enc.data(), enc.size(), &data[0]));
}
void do_test_encode(const std::string& data, const std::string& expected)
{
std::string enc = base58::encode(data);
ASSERT_EQ(enc, expected);
std::string dec;
ASSERT_TRUE(base58::decode(enc, dec));
ASSERT_EQ(dec, data);
}
void do_test_decode_pos(const std::string& enc, const std::string& expected)
{
std::string dec;
ASSERT_TRUE(base58::decode(enc, dec));
ASSERT_EQ(dec, expected);
}
void do_test_decode_neg(const std::string& enc)
{
std::string dec;
ASSERT_FALSE(base58::decode(enc, dec));
}
void do_test_encode_decode_addr(uint64_t tag, const std::string& data, const std::string& expected)
{
std::string addr = base58::encode_addr(tag, data);
ASSERT_EQ(addr, expected);
uint64_t dec_tag;
std::string dec_data;
ASSERT_TRUE(base58::decode_addr(addr, dec_tag, dec_data));
ASSERT_EQ(tag, dec_tag);
ASSERT_EQ(data, dec_data);
}
}
#define TEST_uint_8be_to_64(expected, str) \
TEST(base58_uint_8be_to_64, handles_bytes_##expected) \
{ \
std::string data = str; \
do_test_uint_8be_to_64(expected, reinterpret_cast<const uint8_t*>(data.data()), data.size()); \
}
TEST_uint_8be_to_64(0x0000000000000001, "\x1");
TEST_uint_8be_to_64(0x0000000000000102, "\x1\x2");
TEST_uint_8be_to_64(0x0000000000010203, "\x1\x2\x3");
TEST_uint_8be_to_64(0x0000000001020304, "\x1\x2\x3\x4");
TEST_uint_8be_to_64(0x0000000102030405, "\x1\x2\x3\x4\x5");
TEST_uint_8be_to_64(0x0000010203040506, "\x1\x2\x3\x4\x5\x6");
TEST_uint_8be_to_64(0x0001020304050607, "\x1\x2\x3\x4\x5\x6\x7");
TEST_uint_8be_to_64(0x0102030405060708, "\x1\x2\x3\x4\x5\x6\x7\x8");
#define TEST_uint_64_to_8be(num, expected_str) \
TEST(base58_uint_64_to_8be, handles_bytes_##num) \
{ \
do_test_uint_64_to_8be(num, expected_str); \
}
TEST_uint_64_to_8be(0x0000000000000001, "\x1");
TEST_uint_64_to_8be(0x0000000000000102, "\x1\x2");
TEST_uint_64_to_8be(0x0000000000010203, "\x1\x2\x3");
TEST_uint_64_to_8be(0x0000000001020304, "\x1\x2\x3\x4");
TEST_uint_64_to_8be(0x0000000102030405, "\x1\x2\x3\x4\x5");
TEST_uint_64_to_8be(0x0000010203040506, "\x1\x2\x3\x4\x5\x6");
TEST_uint_64_to_8be(0x0001020304050607, "\x1\x2\x3\x4\x5\x6\x7");
TEST_uint_64_to_8be(0x0102030405060708, "\x1\x2\x3\x4\x5\x6\x7\x8");
TEST(reverse_alphabet, is_correct)
{
ASSERT_EQ(-1, base58::reverse_alphabet::instance(0));
ASSERT_EQ(-1, base58::reverse_alphabet::instance(std::numeric_limits<char>::min()));
ASSERT_EQ(-1, base58::reverse_alphabet::instance(std::numeric_limits<char>::max()));
ASSERT_EQ(-1, base58::reverse_alphabet::instance('1' - 1));
ASSERT_EQ(-1, base58::reverse_alphabet::instance('z' + 1));
ASSERT_EQ(-1, base58::reverse_alphabet::instance('0'));
ASSERT_EQ(-1, base58::reverse_alphabet::instance('I'));
ASSERT_EQ(-1, base58::reverse_alphabet::instance('O'));
ASSERT_EQ(-1, base58::reverse_alphabet::instance('l'));
ASSERT_EQ(0, base58::reverse_alphabet::instance('1'));
ASSERT_EQ(8, base58::reverse_alphabet::instance('9'));
ASSERT_EQ(base58::alphabet_size - 1, base58::reverse_alphabet::instance('z'));
}
#define TEST_encode_block(block, expected) \
TEST(base58_encode_block, handles_##expected) \
{ \
do_test_encode_block(MAKE_STR(block), #expected); \
}
TEST_encode_block("\x00", 11);
TEST_encode_block("\x39", 1z);
TEST_encode_block("\xFF", 5Q);
TEST_encode_block("\x00\x00", 111);
TEST_encode_block("\x00\x39", 11z);
TEST_encode_block("\x01\x00", 15R);
TEST_encode_block("\xFF\xFF", LUv);
TEST_encode_block("\x00\x00\x00", 11111);
TEST_encode_block("\x00\x00\x39", 1111z);
TEST_encode_block("\x01\x00\x00", 11LUw);
TEST_encode_block("\xFF\xFF\xFF", 2UzHL);
TEST_encode_block("\x00\x00\x00\x39", 11111z);
TEST_encode_block("\xFF\xFF\xFF\xFF", 7YXq9G);
TEST_encode_block("\x00\x00\x00\x00\x39", 111111z);
TEST_encode_block("\xFF\xFF\xFF\xFF\xFF", VtB5VXc);
TEST_encode_block("\x00\x00\x00\x00\x00\x39", 11111111z);
TEST_encode_block("\xFF\xFF\xFF\xFF\xFF\xFF", 3CUsUpv9t);
TEST_encode_block("\x00\x00\x00\x00\x00\x00\x39", 111111111z);
TEST_encode_block("\xFF\xFF\xFF\xFF\xFF\xFF\xFF", Ahg1opVcGW);
TEST_encode_block("\x00\x00\x00\x00\x00\x00\x00\x39", 1111111111z);
TEST_encode_block("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", jpXCZedGfVQ);
TEST_encode_block("\x00\x00\x00\x00\x00\x00\x00\x00", 11111111111);
TEST_encode_block("\x00\x00\x00\x00\x00\x00\x00\x01", 11111111112);
TEST_encode_block("\x00\x00\x00\x00\x00\x00\x00\x08", 11111111119);
TEST_encode_block("\x00\x00\x00\x00\x00\x00\x00\x09", 1111111111A);
TEST_encode_block("\x00\x00\x00\x00\x00\x00\x00\x3A", 11111111121);
TEST_encode_block("\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 1Ahg1opVcGW);
TEST_encode_block("\x06\x15\x60\x13\x76\x28\x79\xF7", 22222222222);
TEST_encode_block("\x05\xE0\x22\xBA\x37\x4B\x2A\x00", 1z111111111);
#define TEST_decode_block_pos(enc, expected) \
TEST(base58_decode_block, handles_pos_##enc) \
{ \
do_test_decode_block_pos(#enc, MAKE_STR(expected)); \
}
#define TEST_decode_block_neg(enc) \
TEST(base58_decode_block, handles_neg_##enc) \
{ \
do_test_decode_block_neg(#enc); \
}
// 1-byte block
TEST_decode_block_neg(1);
TEST_decode_block_neg(z);
// 2-bytes block
TEST_decode_block_pos(11, "\x00");
TEST_decode_block_pos(5Q, "\xFF");
TEST_decode_block_neg(5R);
TEST_decode_block_neg(zz);
// 3-bytes block
TEST_decode_block_pos(111, "\x00\x00");
TEST_decode_block_pos(LUv, "\xFF\xFF");
TEST_decode_block_neg(LUw);
TEST_decode_block_neg(zzz);
// 4-bytes block
TEST_decode_block_neg(1111);
TEST_decode_block_neg(zzzz);
// 5-bytes block
TEST_decode_block_pos(11111, "\x00\x00\x00");
TEST_decode_block_pos(2UzHL, "\xFF\xFF\xFF");
TEST_decode_block_neg(2UzHM);
TEST_decode_block_neg(zzzzz);
// 6-bytes block
TEST_decode_block_pos(111111, "\x00\x00\x00\x00");
TEST_decode_block_pos(7YXq9G, "\xFF\xFF\xFF\xFF");
TEST_decode_block_neg(7YXq9H);
TEST_decode_block_neg(zzzzzz);
// 7-bytes block
TEST_decode_block_pos(1111111, "\x00\x00\x00\x00\x00");
TEST_decode_block_pos(VtB5VXc, "\xFF\xFF\xFF\xFF\xFF");
TEST_decode_block_neg(VtB5VXd);
TEST_decode_block_neg(zzzzzzz);
// 8-bytes block
TEST_decode_block_neg(11111111);
TEST_decode_block_neg(zzzzzzzz);
// 9-bytes block
TEST_decode_block_pos(111111111, "\x00\x00\x00\x00\x00\x00");
TEST_decode_block_pos(3CUsUpv9t, "\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_block_neg(3CUsUpv9u);
TEST_decode_block_neg(zzzzzzzzz);
// 10-bytes block
TEST_decode_block_pos(1111111111, "\x00\x00\x00\x00\x00\x00\x00");
TEST_decode_block_pos(Ahg1opVcGW, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_block_neg(Ahg1opVcGX);
TEST_decode_block_neg(zzzzzzzzzz);
// 11-bytes block
TEST_decode_block_pos(11111111111, "\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_decode_block_pos(jpXCZedGfVQ, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_block_neg(jpXCZedGfVR);
TEST_decode_block_neg(zzzzzzzzzzz);
// Invalid symbols
TEST_decode_block_neg(01111111111);
TEST_decode_block_neg(11111111110);
TEST_decode_block_neg(11111011111);
TEST_decode_block_neg(I1111111111);
TEST_decode_block_neg(O1111111111);
TEST_decode_block_neg(l1111111111);
TEST_decode_block_neg(_1111111111);
#define TEST_encode(expected, data) \
TEST(base58_encode, handles_##expected) \
{ \
do_test_encode(MAKE_STR(data), #expected); \
}
TEST_encode(11, "\x00");
TEST_encode(111, "\x00\x00");
TEST_encode(11111, "\x00\x00\x00");
TEST_encode(111111, "\x00\x00\x00\x00");
TEST_encode(1111111, "\x00\x00\x00\x00\x00");
TEST_encode(111111111, "\x00\x00\x00\x00\x00\x00");
TEST_encode(1111111111, "\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(11111111111, "\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(1111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(11111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(1111111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(11111111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(111111111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(11111111111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(111111111111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(1111111111111111111111, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
TEST_encode(22222222222VtB5VXc, "\x06\x15\x60\x13\x76\x28\x79\xF7\xFF\xFF\xFF\xFF\xFF");
#define TEST_decode_pos(enc, expected) \
TEST(base58_decode_pos, handles_pos_##enc) \
{ \
do_test_decode_pos(#enc, MAKE_STR(expected)); \
}
#define TEST_decode_neg(enc) \
TEST(base58_decode_neg, handles_neg_##enc) \
{ \
do_test_decode_neg(#enc); \
}
TEST_decode_pos(, "");
TEST_decode_pos(5Q, "\xFF");
TEST_decode_pos(LUv, "\xFF\xFF");
TEST_decode_pos(2UzHL, "\xFF\xFF\xFF");
TEST_decode_pos(7YXq9G, "\xFF\xFF\xFF\xFF");
TEST_decode_pos(VtB5VXc, "\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(3CUsUpv9t, "\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(Ahg1opVcGW, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQ, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQ5Q, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQLUv, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQ2UzHL, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQ7YXq9G, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQVtB5VXc, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQ3CUsUpv9t, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQAhg1opVcGW, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
TEST_decode_pos(jpXCZedGfVQjpXCZedGfVQ, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
// Invalid length
TEST_decode_neg(1);
TEST_decode_neg(z);
TEST_decode_neg(1111);
TEST_decode_neg(zzzz);
TEST_decode_neg(11111111);
TEST_decode_neg(zzzzzzzz);
TEST_decode_neg(123456789AB1);
TEST_decode_neg(123456789ABz);
TEST_decode_neg(123456789AB1111);
TEST_decode_neg(123456789ABzzzz);
TEST_decode_neg(123456789AB11111111);
TEST_decode_neg(123456789ABzzzzzzzz);
// Overflow
TEST_decode_neg(5R);
TEST_decode_neg(zz);
TEST_decode_neg(LUw);
TEST_decode_neg(zzz);
TEST_decode_neg(2UzHM);
TEST_decode_neg(zzzzz);
TEST_decode_neg(7YXq9H);
TEST_decode_neg(zzzzzz);
TEST_decode_neg(VtB5VXd);
TEST_decode_neg(zzzzzzz);
TEST_decode_neg(3CUsUpv9u);
TEST_decode_neg(zzzzzzzzz);
TEST_decode_neg(Ahg1opVcGX);
TEST_decode_neg(zzzzzzzzzz);
TEST_decode_neg(jpXCZedGfVR);
TEST_decode_neg(zzzzzzzzzzz);
TEST_decode_neg(123456789AB5R);
TEST_decode_neg(123456789ABzz);
TEST_decode_neg(123456789ABLUw);
TEST_decode_neg(123456789ABzzz);
TEST_decode_neg(123456789AB2UzHM);
TEST_decode_neg(123456789ABzzzzz);
TEST_decode_neg(123456789AB7YXq9H);
TEST_decode_neg(123456789ABzzzzzz);
TEST_decode_neg(123456789ABVtB5VXd);
TEST_decode_neg(123456789ABzzzzzzz);
TEST_decode_neg(123456789AB3CUsUpv9u);
TEST_decode_neg(123456789ABzzzzzzzzz);
TEST_decode_neg(123456789ABAhg1opVcGX);
TEST_decode_neg(123456789ABzzzzzzzzzz);
TEST_decode_neg(123456789ABjpXCZedGfVR);
TEST_decode_neg(123456789ABzzzzzzzzzzz);
TEST_decode_neg(zzzzzzzzzzz11);
// Invalid symbols
TEST_decode_neg(10);
TEST_decode_neg(11I);
TEST_decode_neg(11O11);
TEST_decode_neg(11l111);
TEST_decode_neg(11_11111111);
TEST_decode_neg(1101111111111);
TEST_decode_neg(11I11111111111111);
TEST_decode_neg(11O1111111111111111111);
TEST_decode_neg(1111111111110);
TEST_decode_neg(111111111111l1111);
TEST_decode_neg(111111111111_111111111);
#define TEST_encode_decode_addr(addr, tag, data) \
TEST(base58_encode_decode_addr, handles_##addr) \
{ \
do_test_encode_decode_addr(UINT64_C(tag), MAKE_STR(data), #addr); \
}
TEST_encode_decode_addr(21D35quxec71111111111111111111111111111111111111111111111111111111111111111111111111111116Q5tCH, 6,
"\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"
"\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");
TEST_encode_decode_addr(2Aui6ejTFscjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQVqegMoV, 6,
"\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"
"\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");
TEST_encode_decode_addr(1119XrkPuSmLzdHXgVgrZKjepg5hZAxffLzdHXgVgrZKjepg5hZAxffLzdHXgVgrZKjepg5hZAxffLzdHXgVgrZKVphZRvn, 0,
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF");
TEST_encode_decode_addr(111111111111111111111111111111111111111111111111111111111111111111111111111111111111111115TXfiA, 0,
"\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"
"\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");
TEST_encode_decode_addr(PuT7GAdgbA83qvSEivPLYo11111111111111111111111111111111111111111111111111111111111111111111111111111169tWrH, 0x1122334455667788,
"\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"
"\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");
TEST_encode_decode_addr(PuT7GAdgbA841d7FXjswpJjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQjpXCZedGfVQVq4LL1v, 0x1122334455667788,
"\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"
"\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");
TEST_encode_decode_addr(PuT7GAdgbA819VwdWVDP, 0x1122334455667788, "\x11");
TEST_encode_decode_addr(PuT7GAdgbA81efAfdCjPg, 0x1122334455667788, "\x22\x22");
TEST_encode_decode_addr(PuT7GAdgbA83sryEt3YC8Q, 0x1122334455667788, "\x33\x33\x33");
TEST_encode_decode_addr(PuT7GAdgbA83tWUuc54PFP3b, 0x1122334455667788, "\x44\x44\x44\x44");
TEST_encode_decode_addr(PuT7GAdgbA83u9zaKrtRKZ1J6, 0x1122334455667788, "\x55\x55\x55\x55\x55");
TEST_encode_decode_addr(PuT7GAdgbA83uoWF3eanGG1aRoG, 0x1122334455667788, "\x66\x66\x66\x66\x66\x66");
TEST_encode_decode_addr(PuT7GAdgbA83vT1umSHMYJ4oNVdu, 0x1122334455667788, "\x77\x77\x77\x77\x77\x77\x77");
TEST_encode_decode_addr(PuT7GAdgbA83w6XaVDyvpoGQBEWbB, 0x1122334455667788, "\x88\x88\x88\x88\x88\x88\x88\x88");
TEST_encode_decode_addr(PuT7GAdgbA83wk3FD1gW7J2KVGofA1r, 0x1122334455667788, "\x99\x99\x99\x99\x99\x99\x99\x99\x99");
TEST_encode_decode_addr(11efCaY6UjG7JrxuB, 0, "\x11\x22\x33\x44\x55\x66\x77");
TEST_encode_decode_addr(21rhHRT48LN4PriP9, 6, "\x11\x22\x33\x44\x55\x66\x77");
TEST_encode_decode_addr(3BzAD7n3y, 0xFF, "");
#define TEST_decode_addr_neg(addr, test_name) \
TEST(base58_decode_addr_neg, test_name) \
{ \
uint64_t tag; \
std::string data; \
ASSERT_FALSE(base58::decode_addr(MAKE_STR(addr), tag, data)); \
}
TEST_decode_addr_neg("zuT7GAdgbA819VwdWVDP", decode_fails_due_overflow);
TEST_decode_addr_neg("0uT7GAdgbA819VwdWVDP", decode_fails_due_invalid_char_0);
TEST_decode_addr_neg("IuT7GAdgbA819VwdWVDP", decode_fails_due_invalid_char_I);
TEST_decode_addr_neg("OuT7GAdgbA819VwdWVDP", decode_fails_due_invalid_char_O);
TEST_decode_addr_neg("luT7GAdgbA819VwdWVDP", decode_fails_due_invalid_char_l);
TEST_decode_addr_neg("\0uT7GAdgbA819VwdWVDP", decode_fails_due_invalid_char_00);
TEST_decode_addr_neg("PuT7GAdgbA819VwdWVD", decode_fails_due_invalid_lenght);
TEST_decode_addr_neg("11efCaY6UjG7JrxuC", handles_invalid_checksum);
TEST_decode_addr_neg("jerj2e4mESo", handles_non_correct_tag); // "jerj2e4mESo" == "\xFF\x00\xFF\xFF\x5A\xD9\xF1\x1C"
namespace
{
std::string test_serialized_keys = MAKE_STR(
"\xf7\x24\xbc\x5c\x6c\xfb\xb9\xd9\x76\x02\xc3\x00\x42\x3a\x2f\x28"
"\x64\x18\x74\x51\x3a\x03\x57\x78\xa0\xc1\x77\x8d\x83\x32\x01\xe9"
"\x22\x09\x39\x68\x9e\xdf\x1a\xbd\x5b\xc1\xd0\x31\xf7\x3e\xcd\x6c"
"\x99\x3a\xdd\x66\xd6\x80\x88\x70\x45\x6a\xfe\xb8\xe7\xee\xb6\x8d");
std::string test_keys_addr_str = "2AaF4qEmER6dNeM6dfiBFL7kqund3HYGvMBF3ttsNd9SfzgYB6L7ep1Yg1osYJzLdaKAYSLVh6e6jKnAuzj3bw1oGyd1x7Z";
}
TEST(get_account_address_as_str, works_correctly)
{
cryptonote::account_public_address addr;
ASSERT_TRUE(serialization::parse_binary(test_serialized_keys, addr));
std::string addr_str = cryptonote::get_account_address_as_str(addr);
ASSERT_EQ(addr_str, test_keys_addr_str);
}
TEST(get_account_address_from_str, handles_valid_address)
{
cryptonote::account_public_address addr;
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, test_keys_addr_str));
std::string blob;
ASSERT_TRUE(serialization::dump_binary(addr, blob));
ASSERT_EQ(blob, test_serialized_keys);
}
TEST(get_account_address_from_str, fails_on_invalid_address_format)
{
cryptonote::account_public_address addr;
std::string addr_str = test_keys_addr_str;
addr_str[0] = '0';
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
}
TEST(get_account_address_from_str, fails_on_invalid_address_prefix)
{
std::string addr_str = base58::encode_addr(0, test_serialized_keys);
cryptonote::account_public_address addr;
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
}
TEST(get_account_address_from_str, fails_on_invalid_address_content)
{
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, test_serialized_keys.substr(1));
cryptonote::account_public_address addr;
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
}
TEST(get_account_address_from_str, fails_on_invalid_address_spend_key)
{
std::string serialized_keys_copy = test_serialized_keys;
serialized_keys_copy[0] = '\0';
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
cryptonote::account_public_address addr;
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
}
TEST(get_account_address_from_str, fails_on_invalid_address_view_key)
{
std::string serialized_keys_copy = test_serialized_keys;
serialized_keys_copy.back() = '\x01';
std::string addr_str = base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, serialized_keys_copy);
cryptonote::account_public_address addr;
ASSERT_FALSE(cryptonote::get_account_address_from_str(addr, addr_str));
}
TEST(get_account_address_from_str, parses_old_address_format)
{
cryptonote::account_public_address addr;
ASSERT_TRUE(cryptonote::get_account_address_from_str(addr, "002391bbbb24dea6fd95232e97594a27769d0153d053d2102b789c498f57a2b00b69cd6f2f5c529c1660f2f4a2b50178d6640c20ce71fe26373041af97c5b10236fc"));
}

View file

@ -0,0 +1,226 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include "cryptonote_core/cryptonote_basic_impl.h"
using namespace cryptonote;
namespace
{
//--------------------------------------------------------------------------------------------------------------------
class block_reward_and_already_generated_coins : public ::testing::Test
{
protected:
static const size_t current_block_size = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE / 2;
std::vector<size_t> m_last_block_sizes;
bool m_block_too_big;
uint64_t m_block_reward;
};
#define TEST_ALREADY_GENERATED_COINS(already_generated_coins, expected_reward) \
m_block_reward = get_block_reward(m_last_block_sizes, current_block_size, m_block_too_big, already_generated_coins); \
ASSERT_FALSE(m_block_too_big); \
ASSERT_EQ(m_block_reward, UINT64_C(expected_reward));
TEST_F(block_reward_and_already_generated_coins, handles_first_values)
{
TEST_ALREADY_GENERATED_COINS(0, 70368744177663);
TEST_ALREADY_GENERATED_COINS(m_block_reward, 70368475742208);
TEST_ALREADY_GENERATED_COINS(UINT64_C(2756434948434199641), 59853779316998);
}
TEST_F(block_reward_and_already_generated_coins, correctly_steps_from_2_to_1)
{
TEST_ALREADY_GENERATED_COINS(MONEY_SUPPLY - ((2 << 18) + 1), 2);
TEST_ALREADY_GENERATED_COINS(MONEY_SUPPLY - (2 << 18) , 2);
TEST_ALREADY_GENERATED_COINS(MONEY_SUPPLY - ((2 << 18) - 1), 1);
}
TEST_F(block_reward_and_already_generated_coins, handles_max)
{
TEST_ALREADY_GENERATED_COINS(MONEY_SUPPLY - ((1 << 18) + 1), 1);
TEST_ALREADY_GENERATED_COINS(MONEY_SUPPLY - (1 << 18) , 1);
TEST_ALREADY_GENERATED_COINS(MONEY_SUPPLY - ((1 << 18) - 1), 0);
}
//--------------------------------------------------------------------------------------------------------------------
class block_reward_and_current_block_size : public ::testing::Test
{
protected:
virtual void SetUp()
{
m_standard_block_reward = get_block_reward(m_last_block_sizes, 0, m_block_too_big, already_generated_coins);
ASSERT_FALSE(m_block_too_big);
ASSERT_LT(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE, m_standard_block_reward);
}
void do_test(size_t current_block_size)
{
m_block_reward = get_block_reward(m_last_block_sizes, current_block_size, m_block_too_big, already_generated_coins);
}
static const uint64_t already_generated_coins = 0;
std::vector<size_t> m_last_block_sizes;
bool m_block_too_big;
uint64_t m_block_reward;
uint64_t m_standard_block_reward;
};
TEST_F(block_reward_and_current_block_size, handles_block_size_less_relevance_level)
{
do_test(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE - 1);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(m_block_reward, m_standard_block_reward);
}
TEST_F(block_reward_and_current_block_size, handles_block_size_eq_relevance_level)
{
do_test(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(m_block_reward, m_standard_block_reward);
}
TEST_F(block_reward_and_current_block_size, handles_block_size_gt_relevance_level)
{
do_test(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE + 1);
ASSERT_FALSE(m_block_too_big);
ASSERT_LT(m_block_reward, m_standard_block_reward);
}
TEST_F(block_reward_and_current_block_size, handles_block_size_less_2_relevance_level)
{
do_test(2 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE - 1);
ASSERT_FALSE(m_block_too_big);
ASSERT_LT(m_block_reward, m_standard_block_reward);
ASSERT_LT(0, m_block_reward);
}
TEST_F(block_reward_and_current_block_size, handles_block_size_eq_2_relevance_level)
{
do_test(2 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(0, m_block_reward);
}
TEST_F(block_reward_and_current_block_size, handles_block_size_gt_2_relevance_level)
{
do_test(2 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE + 1);
ASSERT_TRUE(m_block_too_big);
}
TEST_F(block_reward_and_current_block_size, fails_on_huge_median_size)
{
#if !defined(NDEBUG)
size_t huge_size = std::numeric_limits<uint32_t>::max() + UINT64_C(2);
m_last_block_sizes.push_back(huge_size);
ASSERT_DEATH(do_test(huge_size + 1), "");
#endif
}
TEST_F(block_reward_and_current_block_size, fails_on_huge_block_size)
{
#if !defined(NDEBUG)
size_t huge_size = std::numeric_limits<uint32_t>::max() + UINT64_C(2);
m_last_block_sizes.push_back(huge_size - 2);
ASSERT_DEATH(do_test(huge_size), "");
#endif
}
//--------------------------------------------------------------------------------------------------------------------
class block_reward_and_last_block_sizes : public ::testing::Test
{
protected:
virtual void SetUp()
{
m_last_block_sizes.push_back(3 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
m_last_block_sizes.push_back(5 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
m_last_block_sizes.push_back(7 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
m_last_block_sizes.push_back(11 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
m_last_block_sizes.push_back(13 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
m_last_block_sizes_median = 7 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE;
m_standard_block_reward = get_block_reward(m_last_block_sizes, 0, m_block_too_big, already_generated_coins);
ASSERT_FALSE(m_block_too_big);
ASSERT_LT(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE, m_standard_block_reward);
}
void do_test(size_t current_block_size)
{
m_block_reward = get_block_reward(m_last_block_sizes, current_block_size, m_block_too_big, already_generated_coins);
}
static const uint64_t already_generated_coins = 0;
std::vector<size_t> m_last_block_sizes;
uint64_t m_last_block_sizes_median;
bool m_block_too_big;
uint64_t m_block_reward;
uint64_t m_standard_block_reward;
};
TEST_F(block_reward_and_last_block_sizes, handles_block_size_less_median)
{
do_test(m_last_block_sizes_median - 1);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(m_block_reward, m_standard_block_reward);
}
TEST_F(block_reward_and_last_block_sizes, handles_block_size_eq_median)
{
do_test(m_last_block_sizes_median);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(m_block_reward, m_standard_block_reward);
}
TEST_F(block_reward_and_last_block_sizes, handles_block_size_gt_median)
{
do_test(m_last_block_sizes_median + 1);
ASSERT_FALSE(m_block_too_big);
ASSERT_LT(m_block_reward, m_standard_block_reward);
}
TEST_F(block_reward_and_last_block_sizes, handles_block_size_less_2_medians)
{
do_test(2 * m_last_block_sizes_median - 1);
ASSERT_FALSE(m_block_too_big);
ASSERT_LT(m_block_reward, m_standard_block_reward);
ASSERT_LT(0, m_block_reward);
}
TEST_F(block_reward_and_last_block_sizes, handles_block_size_eq_2_medians)
{
do_test(2 * m_last_block_sizes_median);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(0, m_block_reward);
}
TEST_F(block_reward_and_last_block_sizes, handles_block_size_gt_2_medians)
{
do_test(2 * m_last_block_sizes_median + 1);
ASSERT_TRUE(m_block_too_big);
}
TEST_F(block_reward_and_last_block_sizes, calculates_correctly)
{
ASSERT_EQ(0, m_last_block_sizes_median % 8);
do_test(m_last_block_sizes_median * 9 / 8);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(m_block_reward, m_standard_block_reward * 63 / 64);
// 3/2 = 12/8
do_test(m_last_block_sizes_median * 3 / 2);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(m_block_reward, m_standard_block_reward * 3 / 4);
do_test(m_last_block_sizes_median * 15 / 8);
ASSERT_FALSE(m_block_too_big);
ASSERT_EQ(m_block_reward, m_standard_block_reward * 15 / 64);
}
}

View file

@ -0,0 +1,84 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>
#include "gtest/gtest.h"
#include "crypto/chacha8.h"
namespace
{
struct test_data {
const uint8_t* key;
const uint8_t* iv;
const size_t text_length;
const uint8_t* plain_text;
const uint8_t* cipher_text;
};
#define ARR(...) __VA_ARGS__
#define MAKE_TEST_DATA(index, key, iv, plain_text, cipher_text) \
static const uint8_t test_key_##index[] = key; \
static const uint8_t test_iv_##index[] = iv; \
static const uint8_t test_plain_text_##index[] = plain_text; \
static const uint8_t test_cipher_text_##index[] = cipher_text; \
static const test_data test_##index = {test_key_##index, test_iv_##index, sizeof(test_plain_text_##index), test_plain_text_##index, test_cipher_text_##index};
MAKE_TEST_DATA(
0,
ARR({0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
ARR({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
ARR({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
ARR({0x65, 0x3f, 0x4a, 0x18, 0xe3, 0xd2, 0x7d, 0xaf, 0x51, 0xf8, 0x41, 0xa0, 0x0b, 0x6c, 0x1a, 0x2b, 0xd2, 0x48, 0x98, 0x52, 0xd4, 0xae, 0x07, 0x11, 0xe1, 0xa4, 0xa3, 0x2a, 0xd1, 0x66, 0xfa, 0x6f, 0x88, 0x1a, 0x28, 0x43, 0x23, 0x8c, 0x7e, 0x17, 0x78, 0x6b, 0xa5, 0x16, 0x2b, 0xc0, 0x19, 0xd5, 0x73, 0x84, 0x9c, 0x16, 0x76, 0x68, 0x51, 0x0a, 0xda, 0x2f, 0x62, 0xb4, 0xff, 0x31, 0xad, 0x04})
)
MAKE_TEST_DATA(
1,
ARR({0x0f, 0x62, 0xb5, 0x08, 0x5b, 0xae, 0x01, 0x54, 0xa7, 0xfa, 0x4d, 0xa0, 0xf3, 0x46, 0x99, 0xec, 0x3f, 0x92, 0xe5, 0x38, 0x8b, 0xde, 0x31, 0x84, 0xd7, 0x2a, 0x7d, 0xd0, 0x23, 0x76, 0xc9, 0x1c}),
ARR({0x28, 0x8f, 0xf6, 0x5d, 0xc4, 0x2b, 0x92, 0xf9}),
ARR({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
ARR({0xdb, 0x16, 0x58, 0x14, 0xf6, 0x67, 0x33, 0xb7, 0xa8, 0xe3, 0x4d, 0x1f, 0xfc, 0x12, 0x34, 0x27, 0x12, 0x56, 0xd3, 0xbf, 0x8d, 0x8d, 0xa2, 0x16, 0x69, 0x22, 0xe5, 0x98, 0xac, 0xac, 0x70, 0xf4, 0x12, 0xb3, 0xfe, 0x35, 0xa9, 0x41, 0x90, 0xad, 0x0a, 0xe2, 0xe8, 0xec, 0x62, 0x13, 0x48, 0x19, 0xab, 0x61, 0xad, 0xdc, 0xcc, 0xfe, 0x99, 0xd8, 0x67, 0xca, 0x3d, 0x73, 0x18, 0x3f, 0xa3, 0xfd})
)
MAKE_TEST_DATA(
2,
ARR({0x0f, 0x62, 0xb5, 0x08, 0x5b, 0xae, 0x01, 0x54, 0xa7, 0xfa, 0x4d, 0xa0, 0xf3, 0x46, 0x99, 0xec, 0x3f, 0x92, 0xe5, 0x38, 0x8b, 0xde, 0x31, 0x84, 0xd7, 0x2a, 0x7d, 0xd0, 0x23, 0x76, 0xc9, 0x1c}),
ARR({0x28, 0x8f, 0xf6, 0x5d, 0xc4, 0x2b, 0x92, 0xf9}),
ARR({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
ARR({0xdb, 0x16, 0x58, 0x14, 0xf6, 0x67, 0x33, 0xb7, 0xa8, 0xe3, 0x4d, 0x1f, 0xfc, 0x12, 0x34, 0x27, 0x12, 0x56, 0xd3, 0xbf, 0x8d, 0x8d, 0xa2, 0x16, 0x69, 0x22, 0xe5, 0x98, 0xac, 0xac, 0x70, 0xf4, 0x12, 0xb3, 0xfe, 0x35, 0xa9, 0x41, 0x90, 0xad, 0x0a, 0xe2, 0xe8, 0xec, 0x62, 0x13, 0x48, 0x19, 0xab, 0x61, 0xad, 0xdc, 0xcc, 0xfe, 0x99, 0xd8, 0x67, 0xca, 0x3d, 0x73, 0x18, 0x3f, 0xa3, 0xfd, 0x82, 0x87, 0x0F})
)
MAKE_TEST_DATA(
3,
ARR({0x0f, 0x62, 0xb5, 0x08, 0x5b, 0xae, 0x01, 0x54, 0xa7, 0xfa, 0x4d, 0xa0, 0xf3, 0x46, 0x99, 0xec, 0x3f, 0x92, 0xe5, 0x38, 0x8b, 0xde, 0x31, 0x84, 0xd7, 0x2a, 0x7d, 0xd0, 0x23, 0x76, 0xc9, 0x1c}),
ARR({0x28, 0x8f, 0xf6, 0x5d, 0xc4, 0x2b, 0x92, 0xf9}),
ARR({0x00}),
ARR({0xdb})
)
void run_test(const test_data* test)
{
std::string buf;
buf.resize(test->text_length);
crypto::chacha8(test->plain_text, test->text_length, test->key, test->iv, &buf[0]);
ASSERT_EQ(buf, std::string(reinterpret_cast<const char*>(test->cipher_text), test->text_length));
crypto::chacha8(test->cipher_text, test->text_length, test->key, test->iv, &buf[0]);
ASSERT_EQ(buf, std::string(reinterpret_cast<const char*>(test->plain_text), test->text_length));
}
}
#define TEST_CHACHA8(test_no) \
TEST(chacha8, is_correct_##test_no) \
{ \
run_test(&test_##test_no); \
}
TEST_CHACHA8(0)
TEST_CHACHA8(1)
TEST_CHACHA8(2)
TEST_CHACHA8(3)

View file

@ -0,0 +1,119 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include <cstdint>
#include <vector>
#include "cryptonote_core/cryptonote_format_utils.h"
#define VEC_FROM_ARR(vec) \
std::vector<uint64_t> vec; \
for (size_t i = 0; i < sizeof(vec##_arr) / sizeof(vec##_arr[0]); ++i) \
{ \
vec.push_back(vec##_arr[i]); \
}
namespace
{
struct chunk_handler_t
{
void operator()(uint64_t chunk) const
{
m_chunks.push_back(chunk);
}
mutable std::vector<uint64_t> m_chunks;
};
struct dust_handler_t
{
dust_handler_t()
: m_dust(0)
, m_has_dust(false)
{
}
void operator()(uint64_t dust) const
{
m_dust = dust;
m_has_dust = true;
}
mutable uint64_t m_dust;
mutable bool m_has_dust;
};
class decompose_amount_into_digits_test : public ::testing::Test
{
protected:
chunk_handler_t m_chunk_handler;
dust_handler_t m_dust_handler;
};
}
TEST_F(decompose_amount_into_digits_test, is_correct_0)
{
uint64_t expected_chunks_arr[] = {0};
VEC_FROM_ARR(expected_chunks);
cryptonote::decompose_amount_into_digits(0, 0, m_chunk_handler, m_dust_handler);
ASSERT_EQ(m_chunk_handler.m_chunks, expected_chunks);
ASSERT_EQ(m_dust_handler.m_has_dust, false);
}
TEST_F(decompose_amount_into_digits_test, is_correct_1)
{
uint64_t expected_chunks_arr[] = {0};
VEC_FROM_ARR(expected_chunks);
cryptonote::decompose_amount_into_digits(0, 10, m_chunk_handler, m_dust_handler);
ASSERT_EQ(m_chunk_handler.m_chunks, expected_chunks);
ASSERT_EQ(m_dust_handler.m_has_dust, false);
}
TEST_F(decompose_amount_into_digits_test, is_correct_2)
{
uint64_t expected_chunks_arr[] = {10};
VEC_FROM_ARR(expected_chunks);
cryptonote::decompose_amount_into_digits(10, 0, m_chunk_handler, m_dust_handler);
ASSERT_EQ(m_chunk_handler.m_chunks, expected_chunks);
ASSERT_EQ(m_dust_handler.m_has_dust, false);
}
TEST_F(decompose_amount_into_digits_test, is_correct_3)
{
std::vector<uint64_t> expected_chunks;
uint64_t expected_dust = 10;
cryptonote::decompose_amount_into_digits(10, 10, m_chunk_handler, m_dust_handler);
ASSERT_EQ(m_chunk_handler.m_chunks, expected_chunks);
ASSERT_EQ(m_dust_handler.m_dust, expected_dust);
}
TEST_F(decompose_amount_into_digits_test, is_correct_4)
{
uint64_t expected_dust = 8100;
std::vector<uint64_t> expected_chunks;
cryptonote::decompose_amount_into_digits(8100, 1000000, m_chunk_handler, m_dust_handler);
ASSERT_EQ(m_chunk_handler.m_chunks, expected_chunks);
ASSERT_EQ(m_dust_handler.m_dust, expected_dust);
}
TEST_F(decompose_amount_into_digits_test, is_correct_5)
{
uint64_t expected_chunks_arr[] = {100, 900000, 8000000};
VEC_FROM_ARR(expected_chunks);
cryptonote::decompose_amount_into_digits(8900100, 10, m_chunk_handler, m_dust_handler);
ASSERT_EQ(m_chunk_handler.m_chunks, expected_chunks);
ASSERT_EQ(m_dust_handler.m_has_dust, false);
}
TEST_F(decompose_amount_into_digits_test, is_correct_6)
{
uint64_t expected_chunks_arr[] = {900000, 8000000};
VEC_FROM_ARR(expected_chunks);
uint64_t expected_dust = 100;
cryptonote::decompose_amount_into_digits(8900100, 1000, m_chunk_handler, m_dust_handler);
ASSERT_EQ(m_chunk_handler.m_chunks, expected_chunks);
ASSERT_EQ(m_dust_handler.m_dust, expected_dust);
}

View file

@ -0,0 +1,109 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <condition_variable>
#include <chrono>
#include <mutex>
#include <thread>
#include "gtest/gtest.h"
#include "include_base_utils.h"
#include "string_tools.h"
#include "net/abstract_tcp_server2.h"
namespace
{
const uint32_t test_server_port = 5626;
const std::string test_server_host("127.0.0.1");
struct test_connection_context : public epee::net_utils::connection_context_base
{
};
struct test_protocol_handler_config
{
};
struct test_protocol_handler
{
typedef test_connection_context connection_context;
typedef test_protocol_handler_config config_type;
test_protocol_handler(epee::net_utils::i_service_endpoint* /*psnd_hndlr*/, config_type& /*config*/, connection_context& /*conn_context*/)
{
}
void after_init_connection()
{
}
void handle_qued_callback()
{
}
bool release_protocol()
{
return true;
}
bool handle_recv(const void* /*data*/, size_t /*size*/)
{
return false;
}
};
typedef epee::net_utils::boosted_tcp_server<test_protocol_handler> test_tcp_server;
}
TEST(boosted_tcp_server, worker_threads_are_exception_resistant)
{
test_tcp_server srv;
ASSERT_TRUE(srv.init_server(test_server_port, test_server_host));
std::mutex mtx;
std::condition_variable cond;
int counter = 0;
auto counter_incrementer = [&counter, &cond, &mtx]()
{
std::unique_lock<std::mutex> lock(mtx);
++counter;
if (4 <= counter)
{
cond.notify_one();
}
};
// 2 theads, but 4 exceptions
ASSERT_TRUE(srv.run_server(2, false));
ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw std::runtime_error("test 1"); }));
ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw std::string("test 2"); }));
ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw "test 3"; }));
ASSERT_TRUE(srv.async_call([&counter_incrementer]() { counter_incrementer(); throw 4; }));
{
std::unique_lock<std::mutex> lock(mtx);
ASSERT_NE(std::cv_status::timeout, cond.wait_for(lock, std::chrono::seconds(5)));
ASSERT_EQ(4, counter);
}
// Check if threads are alive
counter = 0;
//auto counter_incrementer = [&counter]() { counter.fetch_add(1); epee::misc_utils::sleep_no_w(counter.load() * 10); };
ASSERT_TRUE(srv.async_call(counter_incrementer));
ASSERT_TRUE(srv.async_call(counter_incrementer));
ASSERT_TRUE(srv.async_call(counter_incrementer));
ASSERT_TRUE(srv.async_call(counter_incrementer));
{
std::unique_lock<std::mutex> lock(mtx);
ASSERT_NE(std::cv_status::timeout, cond.wait_for(lock, std::chrono::seconds(5)));
ASSERT_EQ(4, counter);
}
srv.send_stop_signal();
ASSERT_TRUE(srv.timed_wait_server_stop(5 * 1000));
ASSERT_TRUE(srv.deinit_server());
}

View file

@ -0,0 +1,506 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <mutex>
#include <thread>
#include "gtest/gtest.h"
#include "include_base_utils.h"
#include "string_tools.h"
#include "net/levin_protocol_handler_async.h"
#include "net/net_utils_base.h"
#include "unit_tests_utils.h"
namespace
{
struct test_levin_connection_context : public epee::net_utils::connection_context_base
{
};
typedef epee::levin::async_protocol_handler_config<test_levin_connection_context> test_levin_protocol_handler_config;
typedef epee::levin::async_protocol_handler<test_levin_connection_context> test_levin_protocol_handler;
struct test_levin_commands_handler : public epee::levin::levin_commands_handler<test_levin_connection_context>
{
test_levin_commands_handler()
: m_return_code(LEVIN_OK)
, m_last_command(-1)
{
}
virtual int invoke(int command, const std::string& in_buff, std::string& buff_out, test_levin_connection_context& context)
{
m_invoke_counter.inc();
std::unique_lock<std::mutex> lock(m_mutex);
m_last_command = command;
m_last_in_buf = in_buff;
buff_out = m_invoke_out_buf;
return m_return_code;
}
virtual int notify(int command, const std::string& in_buff, test_levin_connection_context& context)
{
m_notify_counter.inc();
std::unique_lock<std::mutex> lock(m_mutex);
m_last_command = command;
m_last_in_buf = in_buff;
return m_return_code;
}
virtual void callback(test_levin_connection_context& context)
{
m_callback_counter.inc();
//std::cout << "test_levin_commands_handler::callback()" << std::endl;
}
virtual void on_connection_new(test_levin_connection_context& context)
{
m_new_connection_counter.inc();
//std::cout << "test_levin_commands_handler::on_connection_new()" << std::endl;
}
virtual void on_connection_close(test_levin_connection_context& context)
{
m_close_connection_counter.inc();
//std::cout << "test_levin_commands_handler::on_connection_close()" << std::endl;
}
size_t invoke_counter() const { return m_invoke_counter.get(); }
size_t notify_counter() const { return m_notify_counter.get(); }
size_t callback_counter() const { return m_callback_counter.get(); }
size_t new_connection_counter() const { return m_new_connection_counter.get(); }
size_t close_connection_counter() const { return m_close_connection_counter.get(); }
int return_code() const { return m_return_code; }
void return_code(int v) { m_return_code = v; }
const std::string& invoke_out_buf() const { return m_invoke_out_buf; }
void invoke_out_buf(const std::string& v) { m_invoke_out_buf = v; }
int last_command() const { return m_last_command; }
const std::string& last_in_buf() const { return m_last_in_buf; }
private:
unit_test::call_counter m_invoke_counter;
unit_test::call_counter m_notify_counter;
unit_test::call_counter m_callback_counter;
unit_test::call_counter m_new_connection_counter;
unit_test::call_counter m_close_connection_counter;
std::mutex m_mutex;
int m_return_code;
std::string m_invoke_out_buf;
int m_last_command;
std::string m_last_in_buf;
};
class test_connection : public epee::net_utils::i_service_endpoint
{
public:
test_connection(boost::asio::io_service& io_service, test_levin_protocol_handler_config& protocol_config)
: m_io_service(io_service)
, m_protocol_handler(this, protocol_config, m_context)
, m_send_return(true)
{
}
void start()
{
ASSERT_TRUE(m_protocol_handler.after_init_connection());
}
// Implement epee::net_utils::i_service_endpoint interface
virtual bool do_send(const void* ptr, size_t cb)
{
//std::cout << "test_connection::do_send()" << std::endl;
m_send_counter.inc();
std::unique_lock<std::mutex> lock(m_mutex);
m_last_send_data.append(reinterpret_cast<const char*>(ptr), cb);
return m_send_return;
}
virtual bool close() { /*std::cout << "test_connection::close()" << std::endl; */return true; }
virtual bool call_run_once_service_io() { std::cout << "test_connection::call_run_once_service_io()" << std::endl; return true; }
virtual bool request_callback() { std::cout << "test_connection::request_callback()" << std::endl; return true; }
virtual boost::asio::io_service& get_io_service() { std::cout << "test_connection::get_io_service()" << std::endl; return m_io_service; }
virtual bool add_ref() { std::cout << "test_connection::add_ref()" << std::endl; return true; }
virtual bool release() { std::cout << "test_connection::release()" << std::endl; return true; }
size_t send_counter() const { return m_send_counter.get(); }
const std::string& last_send_data() const { return m_last_send_data; }
void reset_last_send_data() { std::unique_lock<std::mutex> lock(m_mutex); m_last_send_data.clear(); }
bool send_return() const { return m_send_return; }
void send_return(bool v) { m_send_return = v; }
public:
test_levin_protocol_handler m_protocol_handler;
private:
boost::asio::io_service& m_io_service;
test_levin_connection_context m_context;
unit_test::call_counter m_send_counter;
std::mutex m_mutex;
std::string m_last_send_data;
bool m_send_return;
};
class async_protocol_handler_test : public ::testing::Test
{
public:
const static uint64_t invoke_timeout = 5 * 1000;
const static size_t max_packet_size = 10 * 1024 * 1024;
typedef std::unique_ptr<test_connection> test_connection_ptr;
async_protocol_handler_test()
{
m_handler_config.m_pcommands_handler = &m_commands_handler;
m_handler_config.m_invoke_timeout = invoke_timeout;
m_handler_config.m_max_packet_size = max_packet_size;
}
virtual void SetUp()
{
}
protected:
test_connection_ptr create_connection(bool start = true)
{
test_connection_ptr conn(new test_connection(m_io_service, m_handler_config));
if (start)
{
conn->start();
}
return conn;
}
protected:
boost::asio::io_service m_io_service;
test_levin_protocol_handler_config m_handler_config;
test_levin_commands_handler m_commands_handler;
};
class positive_test_connection_to_levin_protocol_handler_calls : public async_protocol_handler_test
{
};
class test_levin_protocol_handler__hanle_recv_with_invalid_data : public async_protocol_handler_test
{
public:
static const int expected_command = 5615871;
static const int expected_return_code = 782546;
test_levin_protocol_handler__hanle_recv_with_invalid_data()
: m_expected_invoke_out_buf(512, 'y')
{
}
virtual void SetUp()
{
async_protocol_handler_test::SetUp();
m_conn = create_connection();
m_in_data.assign(256, 't');
m_req_head.m_signature = LEVIN_SIGNATURE;
m_req_head.m_cb = m_in_data.size();
m_req_head.m_have_to_return_data = true;
m_req_head.m_command = expected_command;
m_req_head.m_flags = LEVIN_PACKET_REQUEST;
m_req_head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
m_commands_handler.return_code(expected_return_code);
m_commands_handler.invoke_out_buf(m_expected_invoke_out_buf);
}
protected:
void prepare_buf()
{
m_buf.assign(reinterpret_cast<const char*>(&m_req_head), sizeof(m_req_head));
m_buf += m_in_data;
}
protected:
test_connection_ptr m_conn;
epee::levin::bucket_head2 m_req_head;
std::string m_in_data;
std::string m_buf;
std::string m_expected_invoke_out_buf;
};
}
TEST_F(positive_test_connection_to_levin_protocol_handler_calls, new_handler_is_not_initialized)
{
test_connection_ptr conn = create_connection(false);
ASSERT_FALSE(conn->m_protocol_handler.m_connection_initialized);
ASSERT_EQ(0, m_handler_config.get_connections_count());
ASSERT_EQ(0, m_commands_handler.new_connection_counter());
conn.reset();
ASSERT_EQ(0, m_handler_config.get_connections_count());
ASSERT_EQ(0, m_commands_handler.close_connection_counter());
}
TEST_F(positive_test_connection_to_levin_protocol_handler_calls, handler_initialization_and_destruction_is_correct)
{
test_connection_ptr conn = create_connection();
ASSERT_TRUE(conn->m_protocol_handler.m_connection_initialized);
ASSERT_EQ(1, m_handler_config.get_connections_count());
ASSERT_EQ(1, m_commands_handler.new_connection_counter());
conn.reset();
ASSERT_EQ(0, m_handler_config.get_connections_count());
ASSERT_EQ(1, m_commands_handler.close_connection_counter());
}
TEST_F(positive_test_connection_to_levin_protocol_handler_calls, concurent_handler_initialization_and_destruction_is_correct)
{
const size_t connection_count = 10000;
auto create_and_destroy_connections = [this, connection_count]()
{
std::vector<test_connection_ptr> connections(connection_count);
for (size_t i = 0; i < connection_count; ++i)
{
connections[i] = create_connection();
}
for (size_t i = 0; i < connection_count; ++i)
{
connections[i].reset();
}
};
const size_t thread_count = std::thread::hardware_concurrency();
std::vector<std::thread> threads(thread_count);
for (std::thread& th : threads)
{
th = std::thread(create_and_destroy_connections);
}
for (std::thread& th : threads)
{
th.join();
}
ASSERT_EQ(0, m_handler_config.get_connections_count());
ASSERT_EQ(connection_count * thread_count, m_commands_handler.new_connection_counter());
ASSERT_EQ(connection_count * thread_count, m_commands_handler.close_connection_counter());
}
TEST_F(positive_test_connection_to_levin_protocol_handler_calls, handler_processes_handle_read_as_invoke)
{
// Setup
const int expected_command = 2634981;
const int expected_return_code = 6732;
const std::string expected_out_data(128, 'w');
test_connection_ptr conn = create_connection();
std::string in_data(256, 'q');
epee::levin::bucket_head2 req_head;
req_head.m_signature = LEVIN_SIGNATURE;
req_head.m_cb = in_data.size();
req_head.m_have_to_return_data = true;
req_head.m_command = expected_command;
req_head.m_flags = LEVIN_PACKET_REQUEST;
req_head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
std::string buf(reinterpret_cast<const char*>(&req_head), sizeof(req_head));
buf += in_data;
m_commands_handler.invoke_out_buf(expected_out_data);
m_commands_handler.return_code(expected_return_code);
// Test
ASSERT_TRUE(conn->m_protocol_handler.handle_recv(buf.data(), buf.size()));
//
// Check
//
// Check connection and levin_commands_handler states
ASSERT_EQ(1, m_commands_handler.invoke_counter());
ASSERT_EQ(0, m_commands_handler.notify_counter());
ASSERT_EQ(expected_command, m_commands_handler.last_command());
ASSERT_EQ(in_data, m_commands_handler.last_in_buf());
ASSERT_LE(1, conn->send_counter());
// Parse send data
std::string send_data = conn->last_send_data();
epee::levin::bucket_head2 resp_head;
resp_head = *reinterpret_cast<const epee::levin::bucket_head2*>(send_data.data());
ASSERT_LT(sizeof(resp_head), send_data.size());
std::string out_data = send_data.substr(sizeof(resp_head));
// Check sent response
ASSERT_EQ(expected_out_data, out_data);
ASSERT_EQ(LEVIN_SIGNATURE, resp_head.m_signature);
ASSERT_EQ(expected_command, resp_head.m_command);
ASSERT_EQ(expected_return_code, resp_head.m_return_code);
ASSERT_EQ(expected_out_data.size(), resp_head.m_cb);
ASSERT_FALSE(resp_head.m_have_to_return_data);
ASSERT_EQ(LEVIN_PROTOCOL_VER_1, resp_head.m_protocol_version);
ASSERT_TRUE(0 != (resp_head.m_flags | LEVIN_PACKET_RESPONSE));
}
TEST_F(positive_test_connection_to_levin_protocol_handler_calls, handler_processes_handle_read_as_notify)
{
// Setup
const int expected_command = 4673261;
test_connection_ptr conn = create_connection();
std::string in_data(256, 'e');
epee::levin::bucket_head2 req_head;
req_head.m_signature = LEVIN_SIGNATURE;
req_head.m_cb = in_data.size();
req_head.m_have_to_return_data = false;
req_head.m_command = expected_command;
req_head.m_flags = LEVIN_PACKET_REQUEST;
req_head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
std::string buf(reinterpret_cast<const char*>(&req_head), sizeof(req_head));
buf += in_data;
// Test
ASSERT_TRUE(conn->m_protocol_handler.handle_recv(buf.data(), buf.size()));
// Check connection and levin_commands_handler states
ASSERT_EQ(1, m_commands_handler.notify_counter());
ASSERT_EQ(0, m_commands_handler.invoke_counter());
ASSERT_EQ(expected_command, m_commands_handler.last_command());
ASSERT_EQ(in_data, m_commands_handler.last_in_buf());
ASSERT_LE(0, conn->send_counter());
ASSERT_TRUE(conn->last_send_data().empty());
}
TEST_F(positive_test_connection_to_levin_protocol_handler_calls, handler_processes_qued_callback)
{
test_connection_ptr conn = create_connection();
conn->m_protocol_handler.handle_qued_callback();
conn->m_protocol_handler.handle_qued_callback();
conn->m_protocol_handler.handle_qued_callback();
ASSERT_EQ(3, m_commands_handler.callback_counter());
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_big_packet_1)
{
std::string buf("yyyyyy");
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(buf.data(), max_packet_size + 1));
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_big_packet_2)
{
prepare_buf();
const size_t first_packet_size = sizeof(m_req_head) - 1;
m_buf.resize(first_packet_size);
ASSERT_TRUE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), max_packet_size - m_buf.size() + 1));
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_invalid_signature_for_full_header)
{
m_req_head.m_signature = LEVIN_SIGNATURE ^ 1;
prepare_buf();
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_invalid_signature_for_partial_header)
{
m_req_head.m_signature = LEVIN_SIGNATURE ^ 1;
prepare_buf();
m_buf.resize(sizeof(m_req_head.m_signature));
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_big_cb)
{
m_req_head.m_cb = max_packet_size + 1;
prepare_buf();
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, does_not_handle_data_after_close)
{
prepare_buf();
ASSERT_TRUE(m_conn->m_protocol_handler.close());
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_network_error)
{
prepare_buf();
m_conn->send_return(false);
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_chunked_header)
{
prepare_buf();
size_t buf1_size = sizeof(m_req_head) / 2;
std::string buf1 = m_buf.substr(0, buf1_size);
std::string buf2 = m_buf.substr(buf1_size);
ASSERT_EQ(m_buf, buf1 + buf2);
ASSERT_TRUE(m_conn->m_protocol_handler.handle_recv(buf1.data(), buf1.size()));
ASSERT_EQ(0, m_commands_handler.invoke_counter());
ASSERT_TRUE(m_conn->m_protocol_handler.handle_recv(buf2.data(), buf2.size()));
ASSERT_EQ(1, m_commands_handler.invoke_counter());
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_chunked_body)
{
prepare_buf();
size_t buf1_size = sizeof(m_req_head) + (m_buf.size() - sizeof(m_req_head)) / 2;
std::string buf1 = m_buf.substr(0, buf1_size);
std::string buf2 = m_buf.substr(buf1_size);
ASSERT_EQ(m_buf, buf1 + buf2);
ASSERT_TRUE(m_conn->m_protocol_handler.handle_recv(buf1.data(), buf1.size()));
ASSERT_EQ(0, m_commands_handler.invoke_counter());
ASSERT_TRUE(m_conn->m_protocol_handler.handle_recv(buf2.data(), buf2.size()));
ASSERT_EQ(1, m_commands_handler.invoke_counter());
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_two_requests_at_once)
{
prepare_buf();
m_buf.append(m_buf);
ASSERT_TRUE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
ASSERT_EQ(2, m_commands_handler.invoke_counter());
}
TEST_F(test_levin_protocol_handler__hanle_recv_with_invalid_data, handles_unexpected_response)
{
m_req_head.m_flags = LEVIN_PACKET_RESPONSE;
prepare_buf();
ASSERT_FALSE(m_conn->m_protocol_handler.handle_recv(m_buf.data(), m_buf.size()));
}

15
tests/unit_tests/main.cpp Normal file
View file

@ -0,0 +1,15 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include "include_base_utils.h"
int main(int argc, char** argv)
{
epee::debug::get_set_enable_assert(true, false);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View file

@ -0,0 +1,179 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include "common/int-util.h"
namespace
{
TEST(mul128, handles_zero)
{
uint64_t hi, lo;
lo = mul128(0, 0, &hi);
ASSERT_EQ(lo, 0);
ASSERT_EQ(hi, 0);
lo = mul128(7, 0, &hi);
ASSERT_EQ(lo, 0);
ASSERT_EQ(hi, 0);
lo = mul128(0, 7, &hi);
ASSERT_EQ(lo, 0);
ASSERT_EQ(hi, 0);
}
TEST(mul128, handles_one)
{
uint64_t hi, lo;
lo = mul128(1, 1, &hi);
ASSERT_EQ(lo, 1);
ASSERT_EQ(hi, 0);
lo = mul128(7, 1, &hi);
ASSERT_EQ(lo, 7);
ASSERT_EQ(hi, 0);
lo = mul128(1, 7, &hi);
ASSERT_EQ(lo, 7);
ASSERT_EQ(hi, 0);
}
TEST(mul128_without_carry, multiplies_correctly)
{
uint64_t hi, lo;
lo = mul128(0x3333333333333333, 5, &hi);
ASSERT_EQ(lo, 0xffffffffffffffff);
ASSERT_EQ(hi, 0);
lo = mul128(5, 0x3333333333333333, &hi);
ASSERT_EQ(lo, 0xffffffffffffffff);
ASSERT_EQ(hi, 0);
lo = mul128(0x1111111111111111, 0x1111111111111111, &hi);
ASSERT_EQ(lo, 0x0fedcba987654321);
ASSERT_EQ(hi, 0x0123456789abcdf0);;
}
TEST(mul128_with_carry_1_only, multiplies_correctly)
{
uint64_t hi, lo;
lo = mul128(0xe0000000e0000000, 0xe0000000e0000000, &hi);
ASSERT_EQ(lo, 0xc400000000000000);
ASSERT_EQ(hi, 0xc400000188000000);
}
TEST(mul128_with_carry_2_only, multiplies_correctly)
{
uint64_t hi, lo;
lo = mul128(0x10000000ffffffff, 0x10000000ffffffff, &hi);
ASSERT_EQ(lo, 0xdffffffe00000001);
ASSERT_EQ(hi, 0x0100000020000000);
}
TEST(mul128_with_carry_1_and_2, multiplies_correctly)
{
uint64_t hi, lo;
lo = mul128(0xf1f2f3f4f5f6f7f8, 0xf9f0fafbfcfdfeff, &hi);
ASSERT_EQ(lo, 0x52118e5f3b211008);
ASSERT_EQ(hi, 0xec39104363716e59);
lo = mul128(0xffffffffffffffff, 0xffffffffffffffff, &hi);
ASSERT_EQ(lo, 0x0000000000000001);
ASSERT_EQ(hi, 0xfffffffffffffffe);
}
TEST(div128_32, handles_zero)
{
uint32_t reminder;
uint64_t hi;
uint64_t lo;
reminder = div128_32(0, 0, 7, &hi, &lo);
ASSERT_EQ(reminder, 0);
ASSERT_EQ(hi, 0);
ASSERT_EQ(lo, 0);
// Division by zero is UB, so can be tested correctly
}
TEST(div128_32, handles_one)
{
uint32_t reminder;
uint64_t hi;
uint64_t lo;
reminder = div128_32(0, 7, 1, &hi, &lo);
ASSERT_EQ(reminder, 0);
ASSERT_EQ(hi, 0);
ASSERT_EQ(lo, 7);
reminder = div128_32(7, 0, 1, &hi, &lo);
ASSERT_EQ(reminder, 0);
ASSERT_EQ(hi, 7);
ASSERT_EQ(lo, 0);
}
TEST(div128_32, handles_if_dividend_less_divider)
{
uint32_t reminder;
uint64_t hi;
uint64_t lo;
reminder = div128_32(0, 1383746, 1645825, &hi, &lo);
ASSERT_EQ(reminder, 1383746);
ASSERT_EQ(hi, 0);
ASSERT_EQ(lo, 0);
}
TEST(div128_32, handles_if_dividend_dwords_less_divider)
{
uint32_t reminder;
uint64_t hi;
uint64_t lo;
reminder = div128_32(0x5AD629E441074F28, 0x0DBCAB2B231081F1, 0xFE735CD6, &hi, &lo);
ASSERT_EQ(reminder, 0xB9C924E9);
ASSERT_EQ(hi, 0x000000005B63C274);
ASSERT_EQ(lo, 0x9084FC024383E48C);
}
TEST(div128_32, works_correctly)
{
uint32_t reminder;
uint64_t hi;
uint64_t lo;
reminder = div128_32(2, 0, 2, &hi, &lo);
ASSERT_EQ(reminder, 0);
ASSERT_EQ(hi, 1);
ASSERT_EQ(lo, 0);
reminder = div128_32(0xffffffffffffffff, 0, 0xffffffff, &hi, &lo);
ASSERT_EQ(reminder, 0);
ASSERT_EQ(hi, 0x0000000100000001);
ASSERT_EQ(lo, 0);
reminder = div128_32(0xffffffffffffffff, 5846, 0xffffffff, &hi, &lo);
ASSERT_EQ(reminder, 5846);
ASSERT_EQ(hi, 0x0000000100000001);
ASSERT_EQ(lo, 0);
reminder = div128_32(0xffffffffffffffff - 1, 0, 0xffffffff, &hi, &lo);
ASSERT_EQ(reminder, 0xfffffffe);
ASSERT_EQ(hi, 0x0000000100000000);
ASSERT_EQ(lo, 0xfffffffefffffffe);
reminder = div128_32(0x2649372534875028, 0xaedbfedc5adbc739, 0x27826534, &hi, &lo);
ASSERT_EQ(reminder, 0x1a6dc2e5);
ASSERT_EQ(hi, 0x00000000f812c1f8);
ASSERT_EQ(lo, 0xddf2fdb09bc2e2e9);
}
}

View file

@ -0,0 +1,418 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <cstring>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <vector>
#include <boost/foreach.hpp>
#include "cryptonote_core/cryptonote_basic.h"
#include "cryptonote_core/cryptonote_basic_impl.h"
#include "serialization/serialization.h"
#include "serialization/binary_archive.h"
#include "serialization/json_archive.h"
#include "serialization/debug_archive.h"
#include "serialization/variant.h"
#include "serialization/vector.h"
#include "serialization/binary_utils.h"
#include "gtest/gtest.h"
using namespace std;
struct Struct
{
int32_t a;
int32_t b;
char blob[8];
};
template <class Archive>
struct serializer<Archive, Struct>
{
static bool serialize(Archive &ar, Struct &s) {
ar.begin_object();
ar.tag("a");
ar.serialize_int(s.a);
ar.tag("b");
ar.serialize_int(s.b);
ar.tag("blob");
ar.serialize_blob(s.blob, sizeof(s.blob));
ar.end_object();
return true;
}
};
struct Struct1
{
vector<boost::variant<Struct, int32_t>> si;
vector<int16_t> vi;
BEGIN_SERIALIZE_OBJECT()
FIELD(si)
FIELD(vi)
END_SERIALIZE()
/*template <bool W, template <bool> class Archive>
bool do_serialize(Archive<W> &ar)
{
ar.begin_object();
ar.tag("si");
::do_serialize(ar, si);
ar.tag("vi");
::do_serialize(ar, vi);
ar.end_object();
}*/
};
struct Blob
{
uint64_t a;
uint32_t b;
bool operator==(const Blob& rhs) const
{
return a == rhs.a;
}
};
VARIANT_TAG(binary_archive, Struct, 0xe0);
VARIANT_TAG(binary_archive, int, 0xe1);
VARIANT_TAG(json_archive, Struct, "struct");
VARIANT_TAG(json_archive, int, "int");
VARIANT_TAG(debug_archive, Struct1, "struct1");
VARIANT_TAG(debug_archive, Struct, "struct");
VARIANT_TAG(debug_archive, int, "int");
BLOB_SERIALIZER(Blob);
bool try_parse(const string &blob)
{
Struct1 s1;
return serialization::parse_binary(blob, s1);
}
TEST(Serialization, BinaryArchiveInts) {
uint64_t x = 0xff00000000, x1;
ostringstream oss;
binary_archive<true> oar(oss);
oar.serialize_int(x);
ASSERT_TRUE(oss.good());
ASSERT_EQ(8, oss.str().size());
ASSERT_EQ(string("\0\0\0\0\xff\0\0\0", 8), oss.str());
istringstream iss(oss.str());
binary_archive<false> iar(iss);
iar.serialize_int(x1);
ASSERT_EQ(8, iss.tellg());
ASSERT_TRUE(iss.good());
ASSERT_EQ(x, x1);
}
TEST(Serialization, BinaryArchiveVarInts) {
uint64_t x = 0xff00000000, x1;
ostringstream oss;
binary_archive<true> oar(oss);
oar.serialize_varint(x);
ASSERT_TRUE(oss.good());
ASSERT_EQ(6, oss.str().size());
ASSERT_EQ(string("\x80\x80\x80\x80\xF0\x1F", 6), oss.str());
istringstream iss(oss.str());
binary_archive<false> iar(iss);
iar.serialize_varint(x1);
ASSERT_TRUE(iss.good());
ASSERT_EQ(x, x1);
}
TEST(Serialization, Test1) {
ostringstream str;
binary_archive<true> ar(str);
Struct1 s1;
s1.si.push_back(0);
{
Struct s;
s.a = 5;
s.b = 65539;
std::memcpy(s.blob, "12345678", 8);
s1.si.push_back(s);
}
s1.si.push_back(1);
s1.vi.push_back(10);
s1.vi.push_back(22);
string blob;
ASSERT_TRUE(serialization::dump_binary(s1, blob));
ASSERT_TRUE(try_parse(blob));
ASSERT_EQ('\xE0', blob[6]);
blob[6] = '\xE1';
ASSERT_FALSE(try_parse(blob));
blob[6] = '\xE2';
ASSERT_FALSE(try_parse(blob));
}
TEST(Serialization, Overflow) {
Blob x = { 0xff00000000 };
Blob x1;
string blob;
ASSERT_TRUE(serialization::dump_binary(x, blob));
ASSERT_EQ(sizeof(Blob), blob.size());
ASSERT_TRUE(serialization::parse_binary(blob, x1));
ASSERT_EQ(x, x1);
vector<Blob> bigvector;
ASSERT_FALSE(serialization::parse_binary(blob, bigvector));
ASSERT_EQ(0, bigvector.size());
}
TEST(Serialization, serializes_vector_uint64_as_varint)
{
std::vector<uint64_t> v;
string blob;
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(1, blob.size());
// +1 byte
v.push_back(0);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(2, blob.size());
// +1 byte
v.push_back(1);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(3, blob.size());
// +2 bytes
v.push_back(0x80);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(5, blob.size());
// +2 bytes
v.push_back(0xFF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(7, blob.size());
// +2 bytes
v.push_back(0x3FFF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(9, blob.size());
// +3 bytes
v.push_back(0x40FF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(12, blob.size());
// +10 bytes
v.push_back(0xFFFFFFFFFFFFFFFF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(22, blob.size());
}
TEST(Serialization, serializes_vector_int64_as_fixed_int)
{
std::vector<int64_t> v;
string blob;
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(1, blob.size());
// +8 bytes
v.push_back(0);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(9, blob.size());
// +8 bytes
v.push_back(1);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(17, blob.size());
// +8 bytes
v.push_back(0x80);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(25, blob.size());
// +8 bytes
v.push_back(0xFF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(33, blob.size());
// +8 bytes
v.push_back(0x3FFF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(41, blob.size());
// +8 bytes
v.push_back(0x40FF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(49, blob.size());
// +8 bytes
v.push_back(0xFFFFFFFFFFFFFFFF);
ASSERT_TRUE(serialization::dump_binary(v, blob));
ASSERT_EQ(57, blob.size());
}
namespace
{
template<typename T>
std::vector<T> linearize_vector2(const std::vector< std::vector<T> >& vec_vec)
{
std::vector<T> res;
BOOST_FOREACH(const auto& vec, vec_vec)
{
res.insert(res.end(), vec.begin(), vec.end());
}
return res;
}
}
TEST(Serialization, serializes_transacion_signatures_correctly)
{
using namespace cryptonote;
transaction tx;
transaction tx1;
string blob;
// Empty tx
tx.set_null();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(5, blob.size()); // 5 bytes + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
// Miner tx without signatures
txin_gen txin_gen1;
txin_gen1.height = 0;
tx.set_null();
tx.vin.push_back(txin_gen1);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(7, blob.size()); // 5 bytes + 2 bytes vin[0] + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
// Miner tx with empty signatures 2nd vector
tx.signatures.resize(1);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(7, blob.size()); // 5 bytes + 2 bytes vin[0] + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
// Miner tx with one signature
tx.signatures[0].resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Miner tx with 2 empty vectors
tx.signatures.resize(2);
tx.signatures[0].resize(0);
tx.signatures[1].resize(0);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Miner tx with 2 signatures
tx.signatures[0].resize(1);
tx.signatures[1].resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, no signatures
tx.vin.push_back(txin_gen1);
tx.signatures.resize(0);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(9, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
// Two txin_gen, signatures vector contains only one empty element
tx.signatures.resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, signatures vector contains two empty elements
tx.signatures.resize(2);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_EQ(9, blob.size()); // 5 bytes + 2 * 2 bytes vins + 0 bytes extra + 0 bytes signatures
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
// Two txin_gen, signatures vector contains three empty elements
tx.signatures.resize(3);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Two txin_gen, signatures vector contains two non empty elements
tx.signatures.resize(2);
tx.signatures[0].resize(1);
tx.signatures[1].resize(1);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// A few bytes instead of signature
tx.vin.clear();
tx.vin.push_back(txin_gen1);
tx.signatures.clear();
ASSERT_TRUE(serialization::dump_binary(tx, blob));
blob.append(std::string(sizeof(crypto::signature) / 2, 'x'));
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
// blob contains one signature
blob.append(std::string(sizeof(crypto::signature) / 2, 'y'));
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
// Not enough signature vectors for all inputs
txin_to_key txin_to_key1;
txin_to_key1.key_offsets.resize(2);
tx.vin.clear();
tx.vin.push_back(txin_to_key1);
tx.vin.push_back(txin_to_key1);
tx.signatures.resize(1);
tx.signatures[0].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// Too much signatures for two inputs
tx.signatures.resize(3);
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
tx.signatures[2].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too little elements
tx.signatures.resize(2);
tx.signatures[0].resize(1);
tx.signatures[1].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// First signatures vector contains too much elements
tx.signatures.resize(2);
tx.signatures[0].resize(3);
tx.signatures[1].resize(2);
ASSERT_FALSE(serialization::dump_binary(tx, blob));
// There are signatures for each input
tx.signatures.resize(2);
tx.signatures[0].resize(2);
tx.signatures[1].resize(2);
ASSERT_TRUE(serialization::dump_binary(tx, blob));
ASSERT_TRUE(serialization::parse_binary(blob, tx1));
ASSERT_EQ(tx, tx1);
ASSERT_EQ(linearize_vector2(tx.signatures), linearize_vector2(tx1.signatures));
// Blob doesn't contain enough data
blob.resize(blob.size() - sizeof(crypto::signature) / 2);
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
// Blob contains too much data
blob.resize(blob.size() + sizeof(crypto::signature));
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
// Blob contains one excess signature
blob.resize(blob.size() + sizeof(crypto::signature) / 2);
ASSERT_FALSE(serialization::parse_binary(blob, tx1));
}

View file

@ -0,0 +1,97 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include "common/util.h"
#include "cryptonote_core/cryptonote_format_utils.h"
TEST(parse_and_validate_tx_extra, is_correct_parse_and_validate_tx_extra)
{
cryptonote::transaction tx = AUTO_VAL_INIT(tx);
cryptonote::account_base acc;
acc.generate();
std::vector<size_t> bss;
cryptonote::blobdata b = "dsdsdfsdfsf";
bool r = cryptonote::construct_miner_tx(0, 10000000000000, acc.get_keys().m_account_address, tx, DEFAULT_FEE, bss, 1000, b, 1);
ASSERT_TRUE(r);
crypto::public_key tx_pub_key;
r = cryptonote::parse_and_validate_tx_extra(tx, tx_pub_key);
ASSERT_TRUE(r);
}
TEST(parse_and_validate_tx_extra, is_correct_extranonce_too_big)
{
cryptonote::transaction tx = AUTO_VAL_INIT(tx);
cryptonote::account_base acc;
acc.generate();
std::vector<size_t> bss;
cryptonote::blobdata b(260, 0);
bool r = cryptonote::construct_miner_tx(0, 10000000000000, acc.get_keys().m_account_address, tx, DEFAULT_FEE, bss, 1000, b, 1);
ASSERT_FALSE(r);
}
TEST(parse_and_validate_tx_extra, is_correct_wrong_extra_couner_too_big)
{
cryptonote::transaction tx = AUTO_VAL_INIT(tx);
tx.extra.resize(20, 0);
tx.extra[0] = TX_EXTRA_NONCE;
tx.extra[1] = 255;
crypto::public_key tx_pub_key;
bool r = parse_and_validate_tx_extra(tx, tx_pub_key);
ASSERT_FALSE(r);
}
TEST(parse_and_validate_tx_extra, is_correct_wrong_extra_nonce_double_entry)
{
cryptonote::transaction tx = AUTO_VAL_INIT(tx);
tx.extra.resize(20, 0);
cryptonote::blobdata v = "asasdasd";
cryptonote::add_tx_extra_nonce(tx, v);
cryptonote::add_tx_extra_nonce(tx, v);
crypto::public_key tx_pub_key;
bool r = parse_and_validate_tx_extra(tx, tx_pub_key);
ASSERT_FALSE(r);
}
TEST(validate_parse_amount_case, validate_parse_amount)
{
uint64_t res = 0;
bool r = cryptonote::parse_amount(res, "0.0001");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000);
r = cryptonote::parse_amount(res, "100.0001");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000010000);
r = cryptonote::parse_amount(res, "000.0000");
ASSERT_TRUE(r);
ASSERT_EQ(res, 0);
r = cryptonote::parse_amount(res, "0");
ASSERT_TRUE(r);
ASSERT_EQ(res, 0);
r = cryptonote::parse_amount(res, " 100.0001 ");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000010000);
r = cryptonote::parse_amount(res, " 100.0000 ");
ASSERT_TRUE(r);
ASSERT_EQ(res, 10000000000);
r = cryptonote::parse_amount(res, " 100. 0000 ");
ASSERT_FALSE(r);
r = cryptonote::parse_amount(res, "100. 0000");
ASSERT_FALSE(r);
r = cryptonote::parse_amount(res, "100 . 0000");
ASSERT_FALSE(r);
r = cryptonote::parse_amount(res, "100.00 00");
ASSERT_FALSE(r);
r = cryptonote::parse_amount(res, "1 00.00 00");
ASSERT_FALSE(r);
}

View file

@ -0,0 +1,58 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include "common/util.h"
#include "p2p/net_peerlist.h"
#include "net/net_utils_base.h"
TEST(peer_list, peer_list_general)
{
nodetool::peerlist_manager plm;
plm.init(false);
#define ADD_GRAY_NODE(ip_, port_, id_, last_seen_) { nodetool::peerlist_entry ple; ple.last_seen=last_seen_;ple.adr.ip = ip_; ple.adr.port = port_; ple.id = id_;plm.append_with_peer_gray(ple);}
#define ADD_WHITE_NODE(ip_, port_, id_, last_seen_) { nodetool::peerlist_entry ple;ple.last_seen=last_seen_; ple.adr.ip = ip_; ple.adr.port = port_; ple.id = id_;plm.append_with_peer_white(ple);}
#define PRINT_HEAD(step) {std::list<nodetool::peerlist_entry> bs_head; bool r = plm.get_peerlist_head(bs_head, 100);std::cout << "step " << step << ": " << bs_head.size() << std::endl;}
ADD_GRAY_NODE(MAKE_IP(123,43,12,1), 8080, 121241, 34345);
ADD_GRAY_NODE(MAKE_IP(123,43,12,2), 8080, 121241, 34345);
ADD_GRAY_NODE(MAKE_IP(123,43,12,3), 8080, 121241, 34345);
ADD_GRAY_NODE(MAKE_IP(123,43,12,4), 8080, 121241, 34345);
ADD_GRAY_NODE(MAKE_IP(123,43,12,5), 8080, 121241, 34345);
ADD_WHITE_NODE(MAKE_IP(123,43,12,1), 8080, 121241, 34345);
ADD_WHITE_NODE(MAKE_IP(123,43,12,2), 8080, 121241, 34345);
ADD_WHITE_NODE(MAKE_IP(123,43,12,3), 8080, 121241, 34345);
ADD_WHITE_NODE(MAKE_IP(123,43,12,4), 8080, 121241, 34345);
size_t gray_list_size = plm.get_gray_peers_count();
ASSERT_EQ(gray_list_size, 1);
std::list<nodetool::peerlist_entry> bs_head;
bool r = plm.get_peerlist_head(bs_head, 100);
std::cout << bs_head.size() << std::endl;
ASSERT_TRUE(r);
ASSERT_EQ(bs_head.size(), 4);
ADD_GRAY_NODE(MAKE_IP(123,43,12,5), 8080, 121241, 34345);
ASSERT_EQ(plm.get_gray_peers_count(), 1);
ASSERT_EQ(plm.get_white_peers_count(), 4);
}
TEST(peer_list, merge_peer_lists)
{
//([^ \t]*)\t([^ \t]*):([^ \t]*) \tlast_seen: d(\d+)\.h(\d+)\.m(\d+)\.s(\d+)\n
//ADD_NODE_TO_PL("\2", \3, 0x\1, (1353346618 -(\4*60*60*24+\5*60*60+\6*60+\7 )));\n
nodetool::peerlist_manager plm;
plm.init(false);
std::list<nodetool::peerlist_entry> outer_bs;
#define ADD_NODE_TO_PL(ip_, port_, id_, timestamp_) { nodetool::peerlist_entry ple; epee::string_tools::get_ip_int32_from_string(ple.adr.ip, ip_); ple.last_seen = timestamp_; ple.adr.port = port_; ple.id = id_;outer_bs.push_back(ple);}
}

View file

@ -0,0 +1,29 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include "include_base_utils.h"
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
#include "storages/portable_storage_template_helper.h"
TEST(protocol_pack, protocol_pack_command)
{
std::string buff;
cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request r;
r.start_height = 1;
r.total_height = 3;
for(int i = 1; i < 10000; i += i*10)
{
r.m_block_ids.resize(i, boost::value_initialized<crypto::hash>());
bool res = epee::serialization::store_t_to_binary(r, buff);
ASSERT_TRUE(res);
cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request r2;
res = epee::serialization::load_t_from_binary(r2, buff);
ASSERT_TRUE(r.m_block_ids.size() == i);
ASSERT_TRUE(r.start_height == 1);
ASSERT_TRUE(r.total_height == 3);
}
}

View file

@ -0,0 +1,38 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <atomic>
namespace unit_test
{
class call_counter
{
public:
call_counter()
: m_counter(0)
{
}
void inc() volatile
{
// memory_order_relaxed is enough for call counter
m_counter.fetch_add(1, std::memory_order_relaxed);
}
size_t get() volatile const
{
return m_counter.load(std::memory_order_relaxed);
}
void reset() volatile
{
m_counter.store(0, std::memory_order_relaxed);
}
private:
std::atomic<size_t> m_counter;
};
}