19 #include <boost/test/unit_test.hpp> 33 static unsigned fac(
unsigned _i)
35 return _i > 2 ? _i * fac(_i - 1) : _i;
38 using dev::operator <<;
40 BOOST_AUTO_TEST_SUITE(Crypto)
51 ft.
insert(
h256(
"69", h256::FromHex, h256::AlignRight).
ref(),
h256(
"414243", h256::FromHex, h256::AlignRight).
ref());
53 cnote << i.first << i.second;
60 cnote << i.first << i.second;
68 testPath +=
"/TrieTests";
70 cnote <<
"Testing Secure Trie...";
72 string s =
contentsString(testPath +
"/hex_encoded_securetrie_test.json");
73 BOOST_REQUIRE_MESSAGE(s.length() > 0,
"Contents of 'hex_encoded_securetrie_test.json' is empty. Have you cloned the 'tests' repo branch develop?");
79 vector<pair<string, string>> ss;
80 for (
auto i: o[
"in"].get_obj())
82 ss.push_back(make_pair(i.first, i.second.get_str()));
83 if (!ss.back().first.find(
"0x"))
85 if (!ss.back().second.find(
"0x"))
88 for (
unsigned j = 0; j <
min(1000000000u, fac((
unsigned)ss.size())); ++j)
90 next_permutation(ss.begin(), ss.end());
103 BOOST_REQUIRE(t.
check(
true));
104 BOOST_REQUIRE(ht.
check(
true));
105 BOOST_REQUIRE(ft.
check(
true));
106 for (
auto const& k: ss)
108 t.
insert(k.first, k.second);
109 ht.
insert(k.first, k.second);
110 ft.
insert(k.first, k.second);
111 BOOST_REQUIRE(t.
check(
true));
112 BOOST_REQUIRE(ht.
check(
true));
113 BOOST_REQUIRE(ft.
check(
true));
116 for (; i != ft.
end() && j != t.
end(); ++i, ++j)
119 BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes());
120 BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes());
124 BOOST_REQUIRE(!o[
"root"].is_null());
135 testPath +=
"/TrieTests";
137 cnote <<
"Testing Trie...";
140 BOOST_REQUIRE_MESSAGE(s.length() > 0,
"Contents of 'trieanyorder.json' is empty. Have you cloned the 'tests' repo branch develop?");
146 vector<pair<string, string>> ss;
147 for (
auto i: o[
"in"].get_obj())
149 ss.push_back(make_pair(i.first, i.second.get_str()));
150 if (!ss.back().first.find(
"0x"))
152 if (!ss.back().second.find(
"0x"))
155 for (
unsigned j = 0; j <
min(1000u, fac((
unsigned)ss.size())); ++j)
157 next_permutation(ss.begin(), ss.end());
170 BOOST_REQUIRE(t.
check(
true));
171 BOOST_REQUIRE(ht.
check(
true));
172 BOOST_REQUIRE(ft.
check(
true));
173 for (
auto const& k: ss)
175 t.
insert(k.first, k.second);
176 ht.
insert(k.first, k.second);
177 ft.
insert(k.first, k.second);
178 BOOST_REQUIRE(t.
check(
true));
179 BOOST_REQUIRE(ht.
check(
true));
180 BOOST_REQUIRE(ft.
check(
true));
183 for (; i != ft.
end() && j != t.
end(); ++i, ++j)
186 BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes());
187 BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes());
191 BOOST_REQUIRE(!o[
"root"].is_null());
202 testPath +=
"/TrieTests";
204 cnote <<
"Testing Trie...";
207 BOOST_REQUIRE_MESSAGE(s.length() > 0,
"Contents of 'trietest.json' is empty. Have you cloned the 'tests' repo branch develop?");
214 vector<pair<string, string>> ss;
215 vector<string> keysToBeDeleted;
216 for (
auto& i: o[
"in"].get_array())
218 vector<string> values;
219 for (
auto& s: i.get_array())
222 values.push_back(s.get_str());
226 values.push_back(
"");
227 if (!values[0].find(
"0x"))
229 keysToBeDeleted.push_back(values[0]);
232 BOOST_FAIL(
"Bad type (expected string)");
235 BOOST_REQUIRE(values.size() == 2);
236 ss.push_back(make_pair(values[0], values[1]));
237 if (!ss.back().first.find(
"0x"))
239 if (!ss.back().second.find(
"0x"))
255 BOOST_REQUIRE(t.
check(
true));
256 BOOST_REQUIRE(ht.
check(
true));
257 BOOST_REQUIRE(ft.
check(
true));
259 for (
auto const& k: ss)
261 if (find(keysToBeDeleted.begin(), keysToBeDeleted.end(), k.first) != keysToBeDeleted.end() && k.second.empty())
264 t.
insert(k.first, k.second), ht.
insert(k.first, k.second), ft.
insert(k.first, k.second);
265 BOOST_REQUIRE(t.
check(
true));
266 BOOST_REQUIRE(ht.
check(
true));
267 BOOST_REQUIRE(ft.
check(
true));
270 for (; i != ft.
end() && j != t.
end(); ++i, ++j)
273 BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes());
274 BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes());
279 BOOST_REQUIRE(!o[
"root"].is_null());
287 for (
auto const& _v: _s)
288 bytesMap.insert(std::make_pair(
bytes(_v.first.begin(), _v.first.end()),
bytes(_v.second.begin(), _v.second.end())));
295 for (
auto const& _v: _s)
296 bytesMap.insert(std::make_pair(
bytes(_v.first.begin(), _v.first.end()),
bytes(_v.second.begin(), _v.second.end())));
302 cnote <<
"Testing Trie more...";
313 t.insert(
string(
"tesz"),
string(
"test"));
319 t.insert(
string(
"tesa"),
string(
"testy"));
324 cnote << t.at(
string(
"test"));
325 cnote << t.at(
string(
"te"));
326 cnote << t.at(
string(
"t"));
328 t.remove(
string(
"te"));
333 t.remove(
string(
"test"));
342 t.
insert(
string(
"a"),
string(
"A"));
343 t.
insert(
string(
"b"),
string(
"B"));
370 t.insert(
"doe",
"reindeer");
371 cnote << hex << t.hash256();
384 auto add = [&](
char const*
a,
char const*
b)
386 d.
insert(
string(a),
string(
b));
390 cnote <<
"/n-------------------------------";
391 cnote << a <<
" -> " <<
b;
397 BOOST_REQUIRE(d.check(
true));
400 for (
auto const& i: s)
403 BOOST_REQUIRE_EQUAL(t.
at(i.first), i.second);
404 BOOST_REQUIRE_EQUAL(d.at(i.first), i.second);
408 auto remove = [&](
char const*
a)
421 BOOST_REQUIRE(d.
check(
true));
422 BOOST_REQUIRE(t.
at(a).empty());
423 BOOST_REQUIRE(d.
at(
string(a)).empty());
426 for (
auto const& i: s)
429 BOOST_REQUIRE_EQUAL(t.
at(i.first), i.second);
430 BOOST_REQUIRE_EQUAL(d.
at(i.first), i.second);
434 add(
"dogglesworth",
"cat");
435 add(
"doe",
"reindeer");
436 remove(
"dogglesworth");
437 add(
"horse",
"stallion");
449 cnote <<
"Stress-testing Trie.lower_bound...";
456 for (
int a = 0;
a < 20; ++
a)
459 for (
int i = 0; i < 50; ++i)
469 auto it = d.lower_bound(i.first);
470 for (
auto iit = d.begin(); iit != d.end(); ++iit)
471 if ((*iit).first.toString() >= i.first.toString())
473 BOOST_REQUIRE(it == iit);
477 for (
unsigned i = 0; i < 100; ++i)
480 auto it = d.lower_bound(k);
481 for (
auto iit = d.begin(); iit != d.end(); ++iit)
482 if ((*iit).first.toString() >= k)
484 BOOST_REQUIRE(it == iit);
495 cnote <<
"Stress-testing Trie...";
503 BOOST_REQUIRE(d.
check(
true));
504 for (
int a = 0;
a < 20; ++
a)
507 for (
int i = 0; i < 50; ++i)
516 BOOST_REQUIRE(d.
check(
true));
520 auto k = m.begin()->first;
521 auto v = m.begin()->second;
529 cwarn << i.first.toString() << i.second.toString();
536 d2.
insert(i.first, i.second);
542 cwarn <<
"Broken:" << d.root();
545 d.debugStructure(cerr);
560 BOOST_REQUIRE(d.
check(
true));
570 for (
size_t p = 1000; p != 1000000; p*=10)
575 cnote <<
"TriePerf " << _name << p;
576 std::vector<h256> keys(1000);
579 for (
size_t i = 0; i < p; ++i)
581 auto k = h256::random();
585 if (i % (p / 1000) == 0)
595 for (
auto it = d.begin(); i < 1000 && it != d.end(); ++it, ++i)
607 if (test::Options::get().performance)
609 perfTestTrie<SpecificTrieDB<GenericTrieDB<MemoryDB>,
h256>>(
"GenericTrieDB");
610 perfTestTrie<SpecificTrieDB<HashedGenericTrieDB<MemoryDB>,
h256>>(
"HashedGenericTrieDB");
611 perfTestTrie<SpecificTrieDB<FatGenericTrieDB<MemoryDB>,
h256>>(
"FatGenericTrieDB");
Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
bool check(bool _requireNoLeftOvers) const
Used for debugging, scans the whole trie.
const Object & get_obj() const
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
std::map< bytes, bytes > BytesMap
vector_ref< _T const > ref(_T const &_t)
void debugStructure(std::ostream &_out) const
Used for debugging, scans the whole trie.
Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2)
std::string randomWord()
Creates a random, printable, word.
std::hash for asio::adress
std::string contentsString(std::string const &_file)
Retrieve and returns the contents of the given file as a std::string.
void perfTestTrie(char const *_name)
void insert(bytesConstRef _key, bytesConstRef _value)
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
void insert(bytesConstRef _key, bytesConstRef _value)
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
bool read_string(const String_type &s, Value_type &value)
h256 stringMapHash256(StringMap const &_s)
h256 const & root() const
void remove(std::string const &_key)
std::vector< byte > bytes
std::string getTestPath()
std::string at(bytes const &_key) const
void remove(bytesConstRef _key)
mConfig::Object_type mObject
bytes stringMapRlp256(StringMap const &_s)
int g_logVerbosity
The logging system's current verbosity.
#define BOOST_FIXTURE_TEST_SUITE(a, b)
bytes rlp256(BytesMap const &_s)
#define BOOST_CHECK_EQUAL(v1, v2)
void insert(std::string const &_key, std::string const &_value)
void remove(bytes const &_key)
std::string const & at(std::string const &_key) const
#define BOOST_AUTO_TEST_SUITE_END()
void setRoot(h256 const &_root, Verification _v=Verification::Normal)
std::array< byte, N > & asArray()
void insert(bytes const &_key, bytes const &_value)
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
std::map< std::string, std::string > StringMap
Class for interpreting Recursive Linear-Prefix Data.
std::string asString(bytes const &_b)
Converts byte array to a string containing the same (binary) data.
BOOST_AUTO_TEST_CASE(fat_trie)
Helper functions to work with json::spirit and test files.
void remove(bytesConstRef _key)