Format first-party source according to .clang-format

This commit is contained in:
Pretty Printer
2020-04-17 09:56:34 -05:00
committed by manojsdoshi
parent 65dfc5d19e
commit 50760c6935
1076 changed files with 86161 additions and 77449 deletions

View File

@@ -18,17 +18,16 @@
//==============================================================================
#include <ripple/basics/contract.h>
#include <ripple/protocol/InnerObjectFormats.h>
#include <ripple/protocol/ErrorCodes.h> // RPC::containsError
#include <ripple/json/json_reader.h> // Json::Reader
#include <ripple/protocol/STParsedJSON.h> // STParsedJSONObject
#include <ripple/beast/unit_test.h>
#include <ripple/json/json_reader.h> // Json::Reader
#include <ripple/protocol/ErrorCodes.h> // RPC::containsError
#include <ripple/protocol/InnerObjectFormats.h>
#include <ripple/protocol/STParsedJSON.h> // STParsedJSONObject
#include <test/jtx.h>
namespace ripple {
namespace InnerObjectFormatsUnitTestDetail
{
namespace InnerObjectFormatsUnitTestDetail {
struct TestJSONTxt
{
@@ -36,11 +35,10 @@ struct TestJSONTxt
bool const expectFail;
};
static TestJSONTxt const testArray[] =
{
static TestJSONTxt const testArray[] = {
// Valid SignerEntry
{R"({
// Valid SignerEntry
{R"({
"Account" : "rDg53Haik2475DJx8bjMDSDPj4VX7htaMd",
"SignerEntries" :
[
@@ -61,11 +59,11 @@ static TestJSONTxt const testArray[] =
],
"SignerQuorum" : 7,
"TransactionType" : "SignerListSet"
})", false
},
})",
false},
// SignerEntry missing Account
{R"({
// SignerEntry missing Account
{R"({
"Account" : "rDg53Haik2475DJx8bjMDSDPj4VX7htaMd",
"SignerEntries" :
[
@@ -85,11 +83,11 @@ static TestJSONTxt const testArray[] =
],
"SignerQuorum" : 7,
"TransactionType" : "SignerListSet"
})", true
},
})",
true},
// SignerEntry missing SignerWeight
{R"({
// SignerEntry missing SignerWeight
{R"({
"Account" : "rDg53Haik2475DJx8bjMDSDPj4VX7htaMd",
"SignerEntries" :
[
@@ -109,11 +107,11 @@ static TestJSONTxt const testArray[] =
],
"SignerQuorum" : 7,
"TransactionType" : "SignerListSet"
})", true
},
})",
true},
// SignerEntry with unexpected Amount
{R"({
// SignerEntry with unexpected Amount
{R"({
"Account" : "rDg53Haik2475DJx8bjMDSDPj4VX7htaMd",
"SignerEntries" :
[
@@ -135,11 +133,11 @@ static TestJSONTxt const testArray[] =
],
"SignerQuorum" : 7,
"TransactionType" : "SignerListSet"
})", true
},
})",
true},
// SignerEntry with no Account and unexpected Amount
{R"({
// SignerEntry with no Account and unexpected Amount
{R"({
"Account" : "rDg53Haik2475DJx8bjMDSDPj4VX7htaMd",
"SignerEntries" :
[
@@ -160,49 +158,49 @@ static TestJSONTxt const testArray[] =
],
"SignerQuorum" : 7,
"TransactionType" : "SignerListSet"
})", true
},
})",
true},
};
} // namespace InnerObjectFormatsUnitTestDetail
} // namespace InnerObjectFormatsUnitTestDetail
class InnerObjectFormatsParsedJSON_test : public beast::unit_test::suite
{
public:
void run() override
void
run() override
{
using namespace InnerObjectFormatsUnitTestDetail;
// Instantiate a jtx::Env so debugLog writes are exercised.
test::jtx::Env env (*this);
test::jtx::Env env(*this);
for (auto const& test : testArray)
{
Json::Value req;
Json::Reader ().parse (test.txt, req);
if (RPC::contains_error (req))
Json::Reader().parse(test.txt, req);
if (RPC::contains_error(req))
{
Throw<std::runtime_error> (
Throw<std::runtime_error>(
"Internal InnerObjectFormatsParsedJSON error. Bad JSON.");
}
STParsedJSONObject parsed ("request", req);
STParsedJSONObject parsed("request", req);
bool const noObj = parsed.object == boost::none;
if ( noObj == test.expectFail )
if (noObj == test.expectFail)
{
pass ();
pass();
}
else
{
std::string errStr ("Unexpected STParsedJSON result on:\n");
std::string errStr("Unexpected STParsedJSON result on:\n");
errStr += test.txt;
fail (errStr);
fail(errStr);
}
}
}
};
BEAST_DEFINE_TESTSUITE(InnerObjectFormatsParsedJSON,ripple_app,ripple);
BEAST_DEFINE_TESTSUITE(InnerObjectFormatsParsedJSON, ripple_app, ripple);
} // ripple
} // namespace ripple

View File

@@ -18,26 +18,26 @@
//==============================================================================
#include <ripple/basics/UnorderedContainers.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/Book.h>
#include <ripple/protocol/Issue.h>
#include <ripple/beast/unit_test.h>
#include <map>
#include <set>
#include <typeinfo>
#include <unordered_set>
#if BEAST_MSVC
# define STL_SET_HAS_EMPLACE 1
#define STL_SET_HAS_EMPLACE 1
#else
# define STL_SET_HAS_EMPLACE 0
#define STL_SET_HAS_EMPLACE 0
#endif
#ifndef RIPPLE_ASSETS_ENABLE_STD_HASH
# if BEAST_MAC || BEAST_IOS
# define RIPPLE_ASSETS_ENABLE_STD_HASH 0
# else
# define RIPPLE_ASSETS_ENABLE_STD_HASH 1
# endif
#if BEAST_MAC || BEAST_IOS
#define RIPPLE_ASSETS_ENABLE_STD_HASH 0
#else
#define RIPPLE_ASSETS_ENABLE_STD_HASH 1
#endif
#endif
namespace ripple {
@@ -47,207 +47,242 @@ class Issue_test : public beast::unit_test::suite
public:
// Comparison, hash tests for uint60 (via base_uint)
template <typename Unsigned>
void testUnsigned ()
void
testUnsigned()
{
Unsigned const u1 (1);
Unsigned const u2 (2);
Unsigned const u3 (3);
Unsigned const u1(1);
Unsigned const u2(2);
Unsigned const u3(3);
BEAST_EXPECT(u1 != u2);
BEAST_EXPECT(u1 < u2);
BEAST_EXPECT(u1 < u2);
BEAST_EXPECT(u1 <= u2);
BEAST_EXPECT(u2 <= u2);
BEAST_EXPECT(u2 == u2);
BEAST_EXPECT(u2 >= u2);
BEAST_EXPECT(u3 >= u2);
BEAST_EXPECT(u3 > u2);
BEAST_EXPECT(u3 > u2);
std::hash <Unsigned> hash;
std::hash<Unsigned> hash;
BEAST_EXPECT(hash (u1) == hash (u1));
BEAST_EXPECT(hash (u2) == hash (u2));
BEAST_EXPECT(hash (u3) == hash (u3));
BEAST_EXPECT(hash (u1) != hash (u2));
BEAST_EXPECT(hash (u1) != hash (u3));
BEAST_EXPECT(hash (u2) != hash (u3));
BEAST_EXPECT(hash(u1) == hash(u1));
BEAST_EXPECT(hash(u2) == hash(u2));
BEAST_EXPECT(hash(u3) == hash(u3));
BEAST_EXPECT(hash(u1) != hash(u2));
BEAST_EXPECT(hash(u1) != hash(u3));
BEAST_EXPECT(hash(u2) != hash(u3));
}
//--------------------------------------------------------------------------
// Comparison, hash tests for Issue
template <class Issue>
void testIssue ()
void
testIssue()
{
Currency const c1 (1); AccountID const i1 (1);
Currency const c2 (2); AccountID const i2 (2);
Currency const c3 (3); AccountID const i3 (3);
Currency const c1(1);
AccountID const i1(1);
Currency const c2(2);
AccountID const i2(2);
Currency const c3(3);
AccountID const i3(3);
BEAST_EXPECT(Issue (c1, i1) != Issue (c2, i1));
BEAST_EXPECT(Issue (c1, i1) < Issue (c2, i1));
BEAST_EXPECT(Issue (c1, i1) <= Issue (c2, i1));
BEAST_EXPECT(Issue (c2, i1) <= Issue (c2, i1));
BEAST_EXPECT(Issue (c2, i1) == Issue (c2, i1));
BEAST_EXPECT(Issue (c2, i1) >= Issue (c2, i1));
BEAST_EXPECT(Issue (c3, i1) >= Issue (c2, i1));
BEAST_EXPECT(Issue (c3, i1) > Issue (c2, i1));
BEAST_EXPECT(Issue (c1, i1) != Issue (c1, i2));
BEAST_EXPECT(Issue (c1, i1) < Issue (c1, i2));
BEAST_EXPECT(Issue (c1, i1) <= Issue (c1, i2));
BEAST_EXPECT(Issue (c1, i2) <= Issue (c1, i2));
BEAST_EXPECT(Issue (c1, i2) == Issue (c1, i2));
BEAST_EXPECT(Issue (c1, i2) >= Issue (c1, i2));
BEAST_EXPECT(Issue (c1, i3) >= Issue (c1, i2));
BEAST_EXPECT(Issue (c1, i3) > Issue (c1, i2));
BEAST_EXPECT(Issue(c1, i1) != Issue(c2, i1));
BEAST_EXPECT(Issue(c1, i1) < Issue(c2, i1));
BEAST_EXPECT(Issue(c1, i1) <= Issue(c2, i1));
BEAST_EXPECT(Issue(c2, i1) <= Issue(c2, i1));
BEAST_EXPECT(Issue(c2, i1) == Issue(c2, i1));
BEAST_EXPECT(Issue(c2, i1) >= Issue(c2, i1));
BEAST_EXPECT(Issue(c3, i1) >= Issue(c2, i1));
BEAST_EXPECT(Issue(c3, i1) > Issue(c2, i1));
BEAST_EXPECT(Issue(c1, i1) != Issue(c1, i2));
BEAST_EXPECT(Issue(c1, i1) < Issue(c1, i2));
BEAST_EXPECT(Issue(c1, i1) <= Issue(c1, i2));
BEAST_EXPECT(Issue(c1, i2) <= Issue(c1, i2));
BEAST_EXPECT(Issue(c1, i2) == Issue(c1, i2));
BEAST_EXPECT(Issue(c1, i2) >= Issue(c1, i2));
BEAST_EXPECT(Issue(c1, i3) >= Issue(c1, i2));
BEAST_EXPECT(Issue(c1, i3) > Issue(c1, i2));
std::hash <Issue> hash;
std::hash<Issue> hash;
BEAST_EXPECT(hash (Issue (c1, i1)) == hash (Issue (c1, i1)));
BEAST_EXPECT(hash (Issue (c1, i2)) == hash (Issue (c1, i2)));
BEAST_EXPECT(hash (Issue (c1, i3)) == hash (Issue (c1, i3)));
BEAST_EXPECT(hash (Issue (c2, i1)) == hash (Issue (c2, i1)));
BEAST_EXPECT(hash (Issue (c2, i2)) == hash (Issue (c2, i2)));
BEAST_EXPECT(hash (Issue (c2, i3)) == hash (Issue (c2, i3)));
BEAST_EXPECT(hash (Issue (c3, i1)) == hash (Issue (c3, i1)));
BEAST_EXPECT(hash (Issue (c3, i2)) == hash (Issue (c3, i2)));
BEAST_EXPECT(hash (Issue (c3, i3)) == hash (Issue (c3, i3)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c1, i2)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c1, i3)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c2, i1)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c2, i2)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c2, i3)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c3, i1)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c3, i2)));
BEAST_EXPECT(hash (Issue (c1, i1)) != hash (Issue (c3, i3)));
BEAST_EXPECT(hash(Issue(c1, i1)) == hash(Issue(c1, i1)));
BEAST_EXPECT(hash(Issue(c1, i2)) == hash(Issue(c1, i2)));
BEAST_EXPECT(hash(Issue(c1, i3)) == hash(Issue(c1, i3)));
BEAST_EXPECT(hash(Issue(c2, i1)) == hash(Issue(c2, i1)));
BEAST_EXPECT(hash(Issue(c2, i2)) == hash(Issue(c2, i2)));
BEAST_EXPECT(hash(Issue(c2, i3)) == hash(Issue(c2, i3)));
BEAST_EXPECT(hash(Issue(c3, i1)) == hash(Issue(c3, i1)));
BEAST_EXPECT(hash(Issue(c3, i2)) == hash(Issue(c3, i2)));
BEAST_EXPECT(hash(Issue(c3, i3)) == hash(Issue(c3, i3)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i2)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c1, i3)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i1)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i2)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c2, i3)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i1)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i2)));
BEAST_EXPECT(hash(Issue(c1, i1)) != hash(Issue(c3, i3)));
}
template <class Set>
void testIssueSet ()
void
testIssueSet()
{
Currency const c1 (1);
AccountID const i1 (1);
Currency const c2 (2);
AccountID const i2 (2);
Issue const a1 (c1, i1);
Issue const a2 (c2, i2);
Currency const c1(1);
AccountID const i1(1);
Currency const c2(2);
AccountID const i2(2);
Issue const a1(c1, i1);
Issue const a2(c2, i2);
{
Set c;
c.insert (a1);
if (! BEAST_EXPECT(c.size () == 1)) return;
c.insert (a2);
if (! BEAST_EXPECT(c.size () == 2)) return;
c.insert(a1);
if (!BEAST_EXPECT(c.size() == 1))
return;
c.insert(a2);
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
}
{
Set c;
c.insert (a1);
if (! BEAST_EXPECT(c.size () == 1)) return;
c.insert (a2);
if (! BEAST_EXPECT(c.size () == 2)) return;
c.insert(a1);
if (!BEAST_EXPECT(c.size() == 1))
return;
c.insert(a2);
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
#if STL_SET_HAS_EMPLACE
c.emplace (c1, i1);
if (! BEAST_EXPECT(c.size() == 1)) return;
c.emplace (c2, i2);
if (! BEAST_EXPECT(c.size() == 2)) return;
#endif
#if STL_SET_HAS_EMPLACE
c.emplace(c1, i1);
if (!BEAST_EXPECT(c.size() == 1))
return;
c.emplace(c2, i2);
if (!BEAST_EXPECT(c.size() == 2))
return;
#endif
}
}
template <class Map>
void testIssueMap ()
void
testIssueMap()
{
Currency const c1 (1);
AccountID const i1 (1);
Currency const c2 (2);
AccountID const i2 (2);
Issue const a1 (c1, i1);
Issue const a2 (c2, i2);
Currency const c1(1);
AccountID const i1(1);
Currency const c2(2);
AccountID const i2(2);
Issue const a1(c1, i1);
Issue const a2(c2, i2);
{
Map c;
c.insert (std::make_pair (a1, 1));
if (! BEAST_EXPECT(c.size () == 1)) return;
c.insert (std::make_pair (a2, 2));
if (! BEAST_EXPECT(c.size () == 2)) return;
c.insert(std::make_pair(a1, 1));
if (!BEAST_EXPECT(c.size() == 1))
return;
c.insert(std::make_pair(a2, 2));
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
}
{
Map c;
c.insert (std::make_pair (a1, 1));
if (! BEAST_EXPECT(c.size () == 1)) return;
c.insert (std::make_pair (a2, 2));
if (! BEAST_EXPECT(c.size () == 2)) return;
c.insert(std::make_pair(a1, 1));
if (!BEAST_EXPECT(c.size() == 1))
return;
c.insert(std::make_pair(a2, 2));
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i2)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Issue (c1, i1)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Issue (c2, i2)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i2)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Issue(c1, i1)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Issue(c2, i2)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
}
}
void testIssueSets ()
void
testIssueSets()
{
testcase ("std::set <Issue>");
testIssueSet <std::set <Issue>> ();
testcase("std::set <Issue>");
testIssueSet<std::set<Issue>>();
testcase ("std::set <Issue>");
testIssueSet <std::set <Issue>> ();
testcase("std::set <Issue>");
testIssueSet<std::set<Issue>>();
#if RIPPLE_ASSETS_ENABLE_STD_HASH
testcase ("std::unordered_set <Issue>");
testIssueSet <std::unordered_set <Issue>> ();
testcase("std::unordered_set <Issue>");
testIssueSet<std::unordered_set<Issue>>();
testcase ("std::unordered_set <Issue>");
testIssueSet <std::unordered_set <Issue>> ();
testcase("std::unordered_set <Issue>");
testIssueSet<std::unordered_set<Issue>>();
#endif
testcase ("hash_set <Issue>");
testIssueSet <hash_set <Issue>> ();
testcase("hash_set <Issue>");
testIssueSet<hash_set<Issue>>();
testcase ("hash_set <Issue>");
testIssueSet <hash_set <Issue>> ();
testcase("hash_set <Issue>");
testIssueSet<hash_set<Issue>>();
}
void testIssueMaps ()
void
testIssueMaps()
{
testcase ("std::map <Issue, int>");
testIssueMap <std::map <Issue, int>> ();
testcase("std::map <Issue, int>");
testIssueMap<std::map<Issue, int>>();
testcase ("std::map <Issue, int>");
testIssueMap <std::map <Issue, int>> ();
testcase("std::map <Issue, int>");
testIssueMap<std::map<Issue, int>>();
#if RIPPLE_ASSETS_ENABLE_STD_HASH
testcase ("std::unordered_map <Issue, int>");
testIssueMap <std::unordered_map <Issue, int>> ();
testcase("std::unordered_map <Issue, int>");
testIssueMap<std::unordered_map<Issue, int>>();
testcase ("std::unordered_map <Issue, int>");
testIssueMap <std::unordered_map <Issue, int>> ();
testcase("std::unordered_map <Issue, int>");
testIssueMap<std::unordered_map<Issue, int>>();
testcase ("hash_map <Issue, int>");
testIssueMap <hash_map <Issue, int>> ();
testcase("hash_map <Issue, int>");
testIssueMap<hash_map<Issue, int>>();
testcase ("hash_map <Issue, int>");
testIssueMap <hash_map <Issue, int>> ();
testcase("hash_map <Issue, int>");
testIssueMap<hash_map<Issue, int>>();
#endif
}
@@ -256,238 +291,273 @@ public:
// Comparison, hash tests for Book
template <class Book>
void testBook ()
void
testBook()
{
Currency const c1 (1); AccountID const i1 (1);
Currency const c2 (2); AccountID const i2 (2);
Currency const c3 (3); AccountID const i3 (3);
Currency const c1(1);
AccountID const i1(1);
Currency const c2(2);
AccountID const i2(2);
Currency const c3(3);
AccountID const i3(3);
Issue a1 (c1, i1);
Issue a2 (c1, i2);
Issue a3 (c2, i2);
Issue a4 (c3, i2);
Issue a1(c1, i1);
Issue a2(c1, i2);
Issue a3(c2, i2);
Issue a4(c3, i2);
BEAST_EXPECT(Book (a1, a2) != Book (a2, a3));
BEAST_EXPECT(Book (a1, a2) < Book (a2, a3));
BEAST_EXPECT(Book (a1, a2) <= Book (a2, a3));
BEAST_EXPECT(Book (a2, a3) <= Book (a2, a3));
BEAST_EXPECT(Book (a2, a3) == Book (a2, a3));
BEAST_EXPECT(Book (a2, a3) >= Book (a2, a3));
BEAST_EXPECT(Book (a3, a4) >= Book (a2, a3));
BEAST_EXPECT(Book (a3, a4) > Book (a2, a3));
BEAST_EXPECT(Book(a1, a2) != Book(a2, a3));
BEAST_EXPECT(Book(a1, a2) < Book(a2, a3));
BEAST_EXPECT(Book(a1, a2) <= Book(a2, a3));
BEAST_EXPECT(Book(a2, a3) <= Book(a2, a3));
BEAST_EXPECT(Book(a2, a3) == Book(a2, a3));
BEAST_EXPECT(Book(a2, a3) >= Book(a2, a3));
BEAST_EXPECT(Book(a3, a4) >= Book(a2, a3));
BEAST_EXPECT(Book(a3, a4) > Book(a2, a3));
std::hash <Book> hash;
std::hash<Book> hash;
// log << std::hex << hash (Book (a1, a2));
// log << std::hex << hash (Book (a1, a2));
//
// log << std::hex << hash (Book (a1, a3));
// log << std::hex << hash (Book (a1, a3));
//
// log << std::hex << hash (Book (a1, a4));
// log << std::hex << hash (Book (a1, a4));
//
// log << std::hex << hash (Book (a2, a3));
// log << std::hex << hash (Book (a2, a3));
//
// log << std::hex << hash (Book (a2, a4));
// log << std::hex << hash (Book (a2, a4));
//
// log << std::hex << hash (Book (a3, a4));
// log << std::hex << hash (Book (a3, a4));
// log << std::hex << hash (Book (a1, a2));
// log << std::hex << hash (Book (a1, a2));
//
// log << std::hex << hash (Book (a1, a3));
// log << std::hex << hash (Book (a1, a3));
//
// log << std::hex << hash (Book (a1, a4));
// log << std::hex << hash (Book (a1, a4));
//
// log << std::hex << hash (Book (a2, a3));
// log << std::hex << hash (Book (a2, a3));
//
// log << std::hex << hash (Book (a2, a4));
// log << std::hex << hash (Book (a2, a4));
//
// log << std::hex << hash (Book (a3, a4));
// log << std::hex << hash (Book (a3, a4));
BEAST_EXPECT(hash (Book (a1, a2)) == hash (Book (a1, a2)));
BEAST_EXPECT(hash (Book (a1, a3)) == hash (Book (a1, a3)));
BEAST_EXPECT(hash (Book (a1, a4)) == hash (Book (a1, a4)));
BEAST_EXPECT(hash (Book (a2, a3)) == hash (Book (a2, a3)));
BEAST_EXPECT(hash (Book (a2, a4)) == hash (Book (a2, a4)));
BEAST_EXPECT(hash (Book (a3, a4)) == hash (Book (a3, a4)));
BEAST_EXPECT(hash(Book(a1, a2)) == hash(Book(a1, a2)));
BEAST_EXPECT(hash(Book(a1, a3)) == hash(Book(a1, a3)));
BEAST_EXPECT(hash(Book(a1, a4)) == hash(Book(a1, a4)));
BEAST_EXPECT(hash(Book(a2, a3)) == hash(Book(a2, a3)));
BEAST_EXPECT(hash(Book(a2, a4)) == hash(Book(a2, a4)));
BEAST_EXPECT(hash(Book(a3, a4)) == hash(Book(a3, a4)));
BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a1, a3)));
BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a1, a4)));
BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a2, a3)));
BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a2, a4)));
BEAST_EXPECT(hash (Book (a1, a2)) != hash (Book (a3, a4)));
BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a1, a3)));
BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a1, a4)));
BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a2, a3)));
BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a2, a4)));
BEAST_EXPECT(hash(Book(a1, a2)) != hash(Book(a3, a4)));
}
//--------------------------------------------------------------------------
template <class Set>
void testBookSet ()
void
testBookSet()
{
Currency const c1 (1);
AccountID const i1 (1);
Currency const c2 (2);
AccountID const i2 (2);
Issue const a1 (c1, i1);
Issue const a2 (c2, i2);
Book const b1 (a1, a2);
Book const b2 (a2, a1);
Currency const c1(1);
AccountID const i1(1);
Currency const c2(2);
AccountID const i2(2);
Issue const a1(c1, i1);
Issue const a2(c2, i2);
Book const b1(a1, a2);
Book const b2(a2, a1);
{
Set c;
c.insert (b1);
if (! BEAST_EXPECT(c.size () == 1)) return;
c.insert (b2);
if (! BEAST_EXPECT(c.size () == 2)) return;
c.insert(b1);
if (!BEAST_EXPECT(c.size() == 1))
return;
c.insert(b2);
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
}
{
Set c;
c.insert (b1);
if (! BEAST_EXPECT(c.size () == 1)) return;
c.insert (b2);
if (! BEAST_EXPECT(c.size () == 2)) return;
c.insert(b1);
if (!BEAST_EXPECT(c.size() == 1))
return;
c.insert(b2);
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
#if STL_SET_HAS_EMPLACE
c.emplace (a1, a2);
if (! BEAST_EXPECT(c.size() == 1)) return;
c.emplace (a2, a1);
if (! BEAST_EXPECT(c.size() == 2)) return;
#endif
#if STL_SET_HAS_EMPLACE
c.emplace(a1, a2);
if (!BEAST_EXPECT(c.size() == 1))
return;
c.emplace(a2, a1);
if (!BEAST_EXPECT(c.size() == 2))
return;
#endif
}
}
template <class Map>
void testBookMap ()
void
testBookMap()
{
Currency const c1 (1);
AccountID const i1 (1);
Currency const c2 (2);
AccountID const i2 (2);
Issue const a1 (c1, i1);
Issue const a2 (c2, i2);
Book const b1 (a1, a2);
Book const b2 (a2, a1);
Currency const c1(1);
AccountID const i1(1);
Currency const c2(2);
AccountID const i2(2);
Issue const a1(c1, i1);
Issue const a2(c2, i2);
Book const b1(a1, a2);
Book const b2(a2, a1);
//typename Map::value_type value_type;
//std::pair <Book const, int> value_type;
// typename Map::value_type value_type;
// std::pair <Book const, int> value_type;
{
Map c;
//c.insert (value_type (b1, 1));
c.insert (std::make_pair (b1, 1));
if (! BEAST_EXPECT(c.size () == 1)) return;
//c.insert (value_type (b2, 2));
c.insert (std::make_pair (b2, 1));
if (! BEAST_EXPECT(c.size () == 2)) return;
// c.insert (value_type (b1, 1));
c.insert(std::make_pair(b1, 1));
if (!BEAST_EXPECT(c.size() == 1))
return;
// c.insert (value_type (b2, 2));
c.insert(std::make_pair(b2, 1));
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
}
{
Map c;
//c.insert (value_type (b1, 1));
c.insert (std::make_pair (b1, 1));
if (! BEAST_EXPECT(c.size () == 1)) return;
//c.insert (value_type (b2, 2));
c.insert (std::make_pair (b2, 1));
if (! BEAST_EXPECT(c.size () == 2)) return;
// c.insert (value_type (b1, 1));
c.insert(std::make_pair(b1, 1));
if (!BEAST_EXPECT(c.size() == 1))
return;
// c.insert (value_type (b2, 2));
c.insert(std::make_pair(b2, 1));
if (!BEAST_EXPECT(c.size() == 2))
return;
if (! BEAST_EXPECT(c.erase (Book (a1, a1)) == 0)) return;
if (! BEAST_EXPECT(c.erase (Book (a1, a2)) == 1)) return;
if (! BEAST_EXPECT(c.erase (Book (a2, a1)) == 1)) return;
if (! BEAST_EXPECT(c.empty ())) return;
if (!BEAST_EXPECT(c.erase(Book(a1, a1)) == 0))
return;
if (!BEAST_EXPECT(c.erase(Book(a1, a2)) == 1))
return;
if (!BEAST_EXPECT(c.erase(Book(a2, a1)) == 1))
return;
if (!BEAST_EXPECT(c.empty()))
return;
}
}
void testBookSets ()
void
testBookSets()
{
testcase ("std::set <Book>");
testBookSet <std::set <Book>> ();
testcase("std::set <Book>");
testBookSet<std::set<Book>>();
testcase ("std::set <Book>");
testBookSet <std::set <Book>> ();
testcase("std::set <Book>");
testBookSet<std::set<Book>>();
#if RIPPLE_ASSETS_ENABLE_STD_HASH
testcase ("std::unordered_set <Book>");
testBookSet <std::unordered_set <Book>> ();
testcase("std::unordered_set <Book>");
testBookSet<std::unordered_set<Book>>();
testcase ("std::unordered_set <Book>");
testBookSet <std::unordered_set <Book>> ();
testcase("std::unordered_set <Book>");
testBookSet<std::unordered_set<Book>>();
#endif
testcase ("hash_set <Book>");
testBookSet <hash_set <Book>> ();
testcase("hash_set <Book>");
testBookSet<hash_set<Book>>();
testcase ("hash_set <Book>");
testBookSet <hash_set <Book>> ();
testcase("hash_set <Book>");
testBookSet<hash_set<Book>>();
}
void testBookMaps ()
void
testBookMaps()
{
testcase ("std::map <Book, int>");
testBookMap <std::map <Book, int>> ();
testcase("std::map <Book, int>");
testBookMap<std::map<Book, int>>();
testcase ("std::map <Book, int>");
testBookMap <std::map <Book, int>> ();
testcase("std::map <Book, int>");
testBookMap<std::map<Book, int>>();
#if RIPPLE_ASSETS_ENABLE_STD_HASH
testcase ("std::unordered_map <Book, int>");
testBookMap <std::unordered_map <Book, int>> ();
testcase("std::unordered_map <Book, int>");
testBookMap<std::unordered_map<Book, int>>();
testcase ("std::unordered_map <Book, int>");
testBookMap <std::unordered_map <Book, int>> ();
testcase("std::unordered_map <Book, int>");
testBookMap<std::unordered_map<Book, int>>();
testcase ("hash_map <Book, int>");
testBookMap <hash_map <Book, int>> ();
testcase("hash_map <Book, int>");
testBookMap<hash_map<Book, int>>();
testcase ("hash_map <Book, int>");
testBookMap <hash_map <Book, int>> ();
testcase("hash_map <Book, int>");
testBookMap<hash_map<Book, int>>();
#endif
}
//--------------------------------------------------------------------------
void run() override
void
run() override
{
testcase ("Currency");
testUnsigned <Currency> ();
testcase("Currency");
testUnsigned<Currency>();
testcase ("AccountID");
testUnsigned <AccountID> ();
testcase("AccountID");
testUnsigned<AccountID>();
// ---
testcase ("Issue");
testIssue <Issue> ();
testcase("Issue");
testIssue<Issue>();
testcase ("Issue");
testIssue <Issue> ();
testcase("Issue");
testIssue<Issue>();
testIssueSets ();
testIssueMaps ();
testIssueSets();
testIssueMaps();
// ---
testcase ("Book");
testBook <Book> ();
testcase("Book");
testBook<Book>();
testcase ("Book");
testBook <Book> ();
testcase("Book");
testBook<Book>();
testBookSets ();
testBookMaps ();
testBookSets();
testBookMaps();
}
};
BEAST_DEFINE_TESTSUITE(Issue,protocol,ripple);
BEAST_DEFINE_TESTSUITE(Issue, protocol, ripple);
}
} // namespace ripple

View File

@@ -17,9 +17,9 @@
*/
//==============================================================================
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/beast/unit_test.h>
#include <vector>
namespace ripple {
@@ -30,215 +30,293 @@ public:
using blob = std::vector<std::uint8_t>;
template <class FwdIter, class Container>
static
void
hex_to_binary (FwdIter first, FwdIter last, Container& out)
static void
hex_to_binary(FwdIter first, FwdIter last, Container& out)
{
struct Table
{
int val[256];
Table ()
Table()
{
std::fill (val, val+256, 0);
std::fill(val, val + 256, 0);
for (int i = 0; i < 10; ++i)
val ['0'+i] = i;
val['0' + i] = i;
for (int i = 0; i < 6; ++i)
{
val ['A'+i] = 10 + i;
val ['a'+i] = 10 + i;
val['A' + i] = 10 + i;
val['a' + i] = 10 + i;
}
}
int operator[] (int i)
int
operator[](int i)
{
return val[i];
return val[i];
}
};
static Table lut;
out.reserve (std::distance (first, last) / 2);
out.reserve(std::distance(first, last) / 2);
while (first != last)
{
auto const hi (lut[(*first++)]);
auto const lo (lut[(*first++)]);
out.push_back ((hi*16)+lo);
auto const hi(lut[(*first++)]);
auto const lo(lut[(*first++)]);
out.push_back((hi * 16) + lo);
}
}
blob
sig (std::string const& hex)
sig(std::string const& hex)
{
blob b;
hex_to_binary (hex.begin (), hex.end (), b);
hex_to_binary(hex.begin(), hex.end(), b);
return b;
}
bool
check (boost::optional<ECDSACanonicality> answer,
std::string const& s)
check(boost::optional<ECDSACanonicality> answer, std::string const& s)
{
return ecdsaCanonicality(makeSlice(sig(s))) ==
answer;
return ecdsaCanonicality(makeSlice(sig(s))) == answer;
}
void testCanonical()
void
testCanonical()
{
testcase ("Canonical");
testcase("Canonical");
// Fully canonical
BEAST_EXPECT(check(ECDSACanonicality::fullyCanonical,
BEAST_EXPECT(check(
ECDSACanonicality::fullyCanonical,
"3045"
"022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EEE905"
"0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F28"));
BEAST_EXPECT(check(ECDSACanonicality::fullyCanonical,
"022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EE"
"E905"
"0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F"
"28"));
BEAST_EXPECT(check(
ECDSACanonicality::fullyCanonical,
"3045"
"0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF1D2D"
"022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B454"));
BEAST_EXPECT(check(ECDSACanonicality::fullyCanonical,
"0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF"
"1D2D"
"022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B4"
"54"));
BEAST_EXPECT(check(
ECDSACanonicality::fullyCanonical,
"3044"
"02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B7581"
"022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D96B"));
BEAST_EXPECT(check(ECDSACanonicality::fullyCanonical,
"02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B75"
"81"
"022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D9"
"6B"));
BEAST_EXPECT(check(
ECDSACanonicality::fullyCanonical,
"3044"
"022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D04E"
"02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C71879F"));
BEAST_EXPECT(check(ECDSACanonicality::fullyCanonical,
"022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D0"
"4E"
"02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C7187"
"9F"));
BEAST_EXPECT(check(
ECDSACanonicality::fullyCanonical,
"3045"
"022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C2F12"
"0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA18"));
"022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C"
"2F12"
"0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA"
"18"));
// Canonical but not fully canonical
BEAST_EXPECT(check(ECDSACanonicality::canonical,
BEAST_EXPECT(check(
ECDSACanonicality::canonical,
"3046"
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
"022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF597A1"));
BEAST_EXPECT(check(ECDSACanonicality::canonical,
"022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC"
"0A1B"
"022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF5"
"97A1"));
BEAST_EXPECT(check(
ECDSACanonicality::canonical,
"3045"
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
"0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB254C"));
BEAST_EXPECT(check(ECDSACanonicality::canonical,
"022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230"
"B6"
"0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB"
"254C"));
BEAST_EXPECT(check(
ECDSACanonicality::canonical,
"3046"
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
"022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F286EA"));
BEAST_EXPECT(check(ECDSACanonicality::canonical,
"02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32"
"625F"
"022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F2"
"86EA"));
BEAST_EXPECT(check(
ECDSACanonicality::canonical,
"3045"
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
"022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869AE35"));
"02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AE"
"C0"
"022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869"
"AE35"));
// valid
BEAST_EXPECT(check(ECDSACanonicality::fullyCanonical,
BEAST_EXPECT(check(
ECDSACanonicality::fullyCanonical,
"3006"
"020101"
"020102"));
BEAST_EXPECT(check(ECDSACanonicality::fullyCanonical,
BEAST_EXPECT(check(
ECDSACanonicality::fullyCanonical,
"3044"
"02203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df0c"
"022030b61dd36543125d56b9f9f3a1f53189e5af33cdda8d77a5209aec03978fa001"));
BEAST_EXPECT(check(ECDSACanonicality::canonical,
"02203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df"
"0c"
"022030b61dd36543125d56b9f9f3a1f53189e5af33cdda8d77a5209aec03978fa0"
"01"));
BEAST_EXPECT(check(
ECDSACanonicality::canonical,
"3045"
"0220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
"0221008fffd599910eefe00bc803c688eca1d2ba7f6b180620eaa03488e6585db6ba01"));
BEAST_EXPECT(check(ECDSACanonicality::canonical,
"0220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f9"
"0a"
"0221008fffd599910eefe00bc803c688eca1d2ba7f6b180620eaa03488e6585db6"
"ba01"));
BEAST_EXPECT(check(
ECDSACanonicality::canonical,
"3046"
"022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
"0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba"));
"022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40"
"f90a"
"0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585d"
"b6ba"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3005"
"0201FF"
"0200"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3006"
"020101"
"020202"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3006"
"020701"
"020102"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3006"
"020401"
"020102"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3006"
"020501"
"020102"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3006"
"020201"
"020102"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3006"
"020301"
"020202"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3006"
"020401"
"020202"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3047"
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
"6105"
"022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e56"
"6695ed"));
BEAST_EXPECT(check(
boost::none,
"3144"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed"));
BEAST_EXPECT(check(
boost::none,
"3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed"));
BEAST_EXPECT(check(
boost::none,
"301F"
"01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed00"));
BEAST_EXPECT(check(boost::none,
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed00"));
BEAST_EXPECT(check(
boost::none,
"3044"
"01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed"));
BEAST_EXPECT(check(
boost::none,
"3024"
"0200"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed"));
BEAST_EXPECT(check(
boost::none,
"3044"
"02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed"));
BEAST_EXPECT(check(
boost::none,
"3045"
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
"6105"
"02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed"));
BEAST_EXPECT(check(
boost::none,
"3044"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105012"
"02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05012"
"02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695e"
"d"));
BEAST_EXPECT(check(
boost::none,
"3024"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"0200"));
BEAST_EXPECT(check(boost::none,
BEAST_EXPECT(check(
boost::none,
"3044"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
BEAST_EXPECT(check(boost::none,
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
"ed"));
BEAST_EXPECT(check(
boost::none,
"3045"
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
"0221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
"02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
"05"
"0221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e5666"
"95ed"));
}
void testBase58 (KeyType keyType)
void
testBase58(KeyType keyType)
{
// Try converting short, long and malformed data
BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, ""));
BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, " "));
BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, "!ty89234gh45"));
BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, ""));
BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, " "));
BEAST_EXPECT(
!parseBase58<PublicKey>(TokenType::NodePublic, "!ty89234gh45"));
auto const good = toBase58 (
TokenType::NodePublic,
derivePublicKey (
keyType,
randomSecretKey()));
auto const good = toBase58(
TokenType::NodePublic, derivePublicKey(keyType, randomSecretKey()));
// Short (non-empty) strings
{
@@ -249,8 +327,8 @@ public:
while (!s.empty())
{
s.erase (r(s) % s.size(), 1);
BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
s.erase(r(s) % s.size(), 1);
BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
}
}
@@ -258,18 +336,18 @@ public:
for (std::size_t i = 1; i != 16; i++)
{
auto s = good;
s.resize (s.size() + i, s[i % s.size()]);
BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
s.resize(s.size() + i, s[i % s.size()]);
BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
}
// Strings with invalid Base58 characters
for (auto c : std::string ("0IOl"))
for (auto c : std::string("0IOl"))
{
for (std::size_t i = 0; i != good.size(); ++i)
{
auto s = good;
s[i % s.size()] = c;
BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
}
}
@@ -280,39 +358,34 @@ public:
for (auto c : std::string("apsrJqtv7"))
{
s[0] = c;
BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
}
}
// Try some random secret keys
std::array <PublicKey, 32> keys;
std::array<PublicKey, 32> keys;
for (std::size_t i = 0; i != keys.size(); ++i)
keys[i] = derivePublicKey (keyType, randomSecretKey());
keys[i] = derivePublicKey(keyType, randomSecretKey());
for (std::size_t i = 0; i != keys.size(); ++i)
{
auto const si = toBase58 (
TokenType::NodePublic,
keys[i]);
auto const si = toBase58(TokenType::NodePublic, keys[i]);
BEAST_EXPECT(!si.empty());
auto const ski = parseBase58<PublicKey> (
TokenType::NodePublic, si);
auto const ski = parseBase58<PublicKey>(TokenType::NodePublic, si);
BEAST_EXPECT(ski && (keys[i] == *ski));
for (std::size_t j = i; j != keys.size(); ++j)
{
BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
auto const sj = toBase58 (
TokenType::NodePublic,
keys[j]);
auto const sj = toBase58(TokenType::NodePublic, keys[j]);
BEAST_EXPECT((si == sj) == (i == j));
auto const skj = parseBase58<PublicKey> (
TokenType::NodePublic, sj);
auto const skj =
parseBase58<PublicKey>(TokenType::NodePublic, sj);
BEAST_EXPECT(skj && (keys[j] == *skj));
BEAST_EXPECT((*ski == *skj) == (i == j));
@@ -320,18 +393,18 @@ public:
}
}
void testBase58 ()
void
testBase58()
{
testcase ("Base58: secp256k1");
testcase("Base58: secp256k1");
{
auto const pk1 = derivePublicKey (
auto const pk1 = derivePublicKey(
KeyType::secp256k1,
generateSecretKey (
KeyType::secp256k1,
generateSeed ("masterpassphrase")));
generateSecretKey(
KeyType::secp256k1, generateSeed("masterpassphrase")));
auto const pk2 = parseBase58<PublicKey> (
auto const pk2 = parseBase58<PublicKey>(
TokenType::NodePublic,
"n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
BEAST_EXPECT(pk2);
@@ -339,18 +412,17 @@ public:
BEAST_EXPECT(pk1 == *pk2);
}
testBase58 (KeyType::secp256k1);
testBase58(KeyType::secp256k1);
testcase ("Base58: ed25519");
testcase("Base58: ed25519");
{
auto const pk1 = derivePublicKey (
auto const pk1 = derivePublicKey(
KeyType::ed25519,
generateSecretKey (
KeyType::ed25519,
generateSeed ("masterpassphrase")));
generateSecretKey(
KeyType::ed25519, generateSeed("masterpassphrase")));
auto const pk2 = parseBase58<PublicKey> (
auto const pk2 = parseBase58<PublicKey>(
TokenType::NodePublic,
"nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
BEAST_EXPECT(pk2);
@@ -358,20 +430,20 @@ public:
BEAST_EXPECT(pk1 == *pk2);
}
testBase58 (KeyType::ed25519);
testBase58(KeyType::ed25519);
}
void testMiscOperations ()
void
testMiscOperations()
{
testcase ("Miscellaneous operations");
testcase("Miscellaneous operations");
auto const pk1 = derivePublicKey (
auto const pk1 = derivePublicKey(
KeyType::secp256k1,
generateSecretKey (
KeyType::secp256k1,
generateSeed ("masterpassphrase")));
generateSecretKey(
KeyType::secp256k1, generateSeed("masterpassphrase")));
PublicKey pk2 (pk1);
PublicKey pk2(pk1);
BEAST_EXPECT(pk1 == pk2);
BEAST_EXPECT(pk2 == pk1);
@@ -381,7 +453,8 @@ public:
BEAST_EXPECT(pk1 == pk3);
}
void run() override
void
run() override
{
testBase58();
testCanonical();
@@ -389,6 +462,6 @@ public:
}
};
BEAST_DEFINE_TESTSUITE(PublicKey,protocol,ripple);
BEAST_DEFINE_TESTSUITE(PublicKey, protocol, ripple);
} // ripple
} // namespace ripple

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#include <ripple/protocol/Quality.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/Quality.h>
#include <type_traits>
namespace ripple {
@@ -27,212 +27,271 @@ class Quality_test : public beast::unit_test::suite
{
public:
// Create a raw, non-integral amount from mantissa and exponent
STAmount
static raw (std::uint64_t mantissa, int exponent)
STAmount static raw(std::uint64_t mantissa, int exponent)
{
return STAmount ({Currency(3), AccountID(3)}, mantissa, exponent);
return STAmount({Currency(3), AccountID(3)}, mantissa, exponent);
}
template <class Integer>
static
STAmount
amount (Integer integer,
std::enable_if_t <std::is_signed <Integer>::value>* = 0)
static STAmount
amount(
Integer integer,
std::enable_if_t<std::is_signed<Integer>::value>* = 0)
{
static_assert (std::is_integral <Integer>::value, "");
return STAmount (integer, false);
static_assert(std::is_integral<Integer>::value, "");
return STAmount(integer, false);
}
template <class Integer>
static
STAmount
amount (Integer integer,
std::enable_if_t <! std::is_signed <Integer>::value>* = 0)
static STAmount
amount(
Integer integer,
std::enable_if_t<!std::is_signed<Integer>::value>* = 0)
{
static_assert (std::is_integral <Integer>::value, "");
static_assert(std::is_integral<Integer>::value, "");
if (integer < 0)
return STAmount (-integer, true);
return STAmount (integer, false);
return STAmount(-integer, true);
return STAmount(integer, false);
}
template <class In, class Out>
static
Amounts
amounts (In in, Out out)
static Amounts
amounts(In in, Out out)
{
return Amounts (amount(in), amount(out));
return Amounts(amount(in), amount(out));
}
template <class In1, class Out1, class Int, class In2, class Out2>
void
ceil_in (Quality const& q,
In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected)
ceil_in(
Quality const& q,
In1 in,
Out1 out,
Int limit,
In2 in_expected,
Out2 out_expected)
{
auto expect_result (amounts (in_expected, out_expected));
auto actual_result (q.ceil_in (
amounts (in, out), amount (limit)));
auto expect_result(amounts(in_expected, out_expected));
auto actual_result(q.ceil_in(amounts(in, out), amount(limit)));
BEAST_EXPECT(actual_result == expect_result);
}
template <class In1, class Out1, class Int, class In2, class Out2>
void
ceil_out (Quality const& q,
In1 in, Out1 out, Int limit, In2 in_expected, Out2 out_expected)
ceil_out(
Quality const& q,
In1 in,
Out1 out,
Int limit,
In2 in_expected,
Out2 out_expected)
{
auto const expect_result (amounts (in_expected, out_expected));
auto const actual_result (q.ceil_out (
amounts (in, out), amount (limit)));
auto const expect_result(amounts(in_expected, out_expected));
auto const actual_result(q.ceil_out(amounts(in, out), amount(limit)));
BEAST_EXPECT(actual_result == expect_result);
}
void
test_ceil_in ()
test_ceil_in()
{
testcase ("ceil_in");
testcase("ceil_in");
{
// 1 in, 1 out:
Quality q (Amounts (amount(1), amount(1)));
Quality q(Amounts(amount(1), amount(1)));
ceil_in (q,
1, 1, // 1 in, 1 out
1, // limit: 1
1, 1); // 1 in, 1 out
ceil_in(
q,
1,
1, // 1 in, 1 out
1, // limit: 1
1,
1); // 1 in, 1 out
ceil_in (q,
10, 10, // 10 in, 10 out
5, // limit: 5
5, 5); // 5 in, 5 out
ceil_in(
q,
10,
10, // 10 in, 10 out
5, // limit: 5
5,
5); // 5 in, 5 out
ceil_in (q,
5, 5, // 5 in, 5 out
10, // limit: 10
5, 5); // 5 in, 5 out
ceil_in(
q,
5,
5, // 5 in, 5 out
10, // limit: 10
5,
5); // 5 in, 5 out
}
{
// 1 in, 2 out:
Quality q (Amounts (amount(1), amount(2)));
Quality q(Amounts(amount(1), amount(2)));
ceil_in (q,
40, 80, // 40 in, 80 out
40, // limit: 40
40, 80); // 40 in, 20 out
ceil_in(
q,
40,
80, // 40 in, 80 out
40, // limit: 40
40,
80); // 40 in, 20 out
ceil_in (q,
40, 80, // 40 in, 80 out
20, // limit: 20
20, 40); // 20 in, 40 out
ceil_in(
q,
40,
80, // 40 in, 80 out
20, // limit: 20
20,
40); // 20 in, 40 out
ceil_in (q,
40, 80, // 40 in, 80 out
60, // limit: 60
40, 80); // 40 in, 80 out
ceil_in(
q,
40,
80, // 40 in, 80 out
60, // limit: 60
40,
80); // 40 in, 80 out
}
{
// 2 in, 1 out:
Quality q (Amounts (amount(2), amount(1)));
Quality q(Amounts(amount(2), amount(1)));
ceil_in (q,
40, 20, // 40 in, 20 out
20, // limit: 20
20, 10); // 20 in, 10 out
ceil_in(
q,
40,
20, // 40 in, 20 out
20, // limit: 20
20,
10); // 20 in, 10 out
ceil_in (q,
40, 20, // 40 in, 20 out
40, // limit: 40
40, 20); // 40 in, 20 out
ceil_in(
q,
40,
20, // 40 in, 20 out
40, // limit: 40
40,
20); // 40 in, 20 out
ceil_in (q,
40, 20, // 40 in, 20 out
50, // limit: 40
40, 20); // 40 in, 20 out
ceil_in(
q,
40,
20, // 40 in, 20 out
50, // limit: 40
40,
20); // 40 in, 20 out
}
}
void
test_ceil_out ()
test_ceil_out()
{
testcase ("ceil_out");
testcase("ceil_out");
{
// 1 in, 1 out:
Quality q (Amounts (amount(1),amount(1)));
Quality q(Amounts(amount(1), amount(1)));
ceil_out (q,
1, 1, // 1 in, 1 out
1, // limit 1
1, 1); // 1 in, 1 out
ceil_out(
q,
1,
1, // 1 in, 1 out
1, // limit 1
1,
1); // 1 in, 1 out
ceil_out (q,
10, 10, // 10 in, 10 out
5, // limit 5
5, 5); // 5 in, 5 out
ceil_out(
q,
10,
10, // 10 in, 10 out
5, // limit 5
5,
5); // 5 in, 5 out
ceil_out (q,
10, 10, // 10 in, 10 out
20, // limit 20
10, 10); // 10 in, 10 out
ceil_out(
q,
10,
10, // 10 in, 10 out
20, // limit 20
10,
10); // 10 in, 10 out
}
{
// 1 in, 2 out:
Quality q (Amounts (amount(1),amount(2)));
Quality q(Amounts(amount(1), amount(2)));
ceil_out (q,
40, 80, // 40 in, 80 out
40, // limit 40
20, 40); // 20 in, 40 out
ceil_out(
q,
40,
80, // 40 in, 80 out
40, // limit 40
20,
40); // 20 in, 40 out
ceil_out (q,
40, 80, // 40 in, 80 out
80, // limit 80
40, 80); // 40 in, 80 out
ceil_out(
q,
40,
80, // 40 in, 80 out
80, // limit 80
40,
80); // 40 in, 80 out
ceil_out (q,
40, 80, // 40 in, 80 out
100, // limit 100
40, 80); // 40 in, 80 out
ceil_out(
q,
40,
80, // 40 in, 80 out
100, // limit 100
40,
80); // 40 in, 80 out
}
{
// 2 in, 1 out:
Quality q (Amounts (amount(2),amount(1)));
Quality q(Amounts(amount(2), amount(1)));
ceil_out (q,
40, 20, // 40 in, 20 out
20, // limit 20
40, 20); // 40 in, 20 out
ceil_out(
q,
40,
20, // 40 in, 20 out
20, // limit 20
40,
20); // 40 in, 20 out
ceil_out (q,
40, 20, // 40 in, 20 out
40, // limit 40
40, 20); // 40 in, 20 out
ceil_out(
q,
40,
20, // 40 in, 20 out
40, // limit 40
40,
20); // 40 in, 20 out
ceil_out (q,
40, 20, // 40 in, 20 out
10, // limit 10
20, 10); // 20 in, 10 out
ceil_out(
q,
40,
20, // 40 in, 20 out
10, // limit 10
20,
10); // 20 in, 10 out
}
}
void
test_raw()
{
testcase ("raw");
testcase("raw");
{
Quality q (0x5d048191fb9130daull); // 126836389.7680090
Amounts const value (
amount(349469768), // 349.469768 XRP
raw (2755280000000000ull, -15)); // 2.75528
STAmount const limit (
raw (4131113916555555, -16)); // .4131113916555555
Amounts const result (
q.ceil_out (value, limit));
Quality q(0x5d048191fb9130daull); // 126836389.7680090
Amounts const value(
amount(349469768), // 349.469768 XRP
raw(2755280000000000ull, -15)); // 2.75528
STAmount const limit(
raw(4131113916555555, -16)); // .4131113916555555
Amounts const result(q.ceil_out(value, limit));
BEAST_EXPECT(result.in != beast::zero);
}
}
@@ -240,9 +299,9 @@ public:
void
test_round()
{
testcase ("round");
testcase("round");
Quality q (0x59148191fb913522ull); // 57719.63525051682
Quality q(0x59148191fb913522ull); // 57719.63525051682
BEAST_EXPECT(q.round(3).rate().getText() == "57800");
BEAST_EXPECT(q.round(4).rate().getText() == "57720");
BEAST_EXPECT(q.round(5).rate().getText() == "57720");
@@ -262,17 +321,17 @@ public:
void
test_comparisons()
{
testcase ("comparisons");
testcase("comparisons");
STAmount const amount1 (noIssue(), 231);
STAmount const amount2 (noIssue(), 462);
STAmount const amount3 (noIssue(), 924);
STAmount const amount1(noIssue(), 231);
STAmount const amount2(noIssue(), 462);
STAmount const amount3(noIssue(), 924);
Quality const q11 (Amounts (amount1, amount1));
Quality const q12 (Amounts (amount1, amount2));
Quality const q13 (Amounts (amount1, amount3));
Quality const q21 (Amounts (amount2, amount1));
Quality const q31 (Amounts (amount3, amount1));
Quality const q11(Amounts(amount1, amount1));
Quality const q12(Amounts(amount1, amount2));
Quality const q13(Amounts(amount1, amount3));
Quality const q21(Amounts(amount2, amount1));
Quality const q31(Amounts(amount3, amount1));
BEAST_EXPECT(q11 == q11);
BEAST_EXPECT(q11 < q12);
@@ -297,43 +356,39 @@ public:
}
void
test_composition ()
test_composition()
{
testcase ("composition");
testcase("composition");
STAmount const amount1 (noIssue(), 231);
STAmount const amount2 (noIssue(), 462);
STAmount const amount3 (noIssue(), 924);
STAmount const amount1(noIssue(), 231);
STAmount const amount2(noIssue(), 462);
STAmount const amount3(noIssue(), 924);
Quality const q11 (Amounts (amount1, amount1));
Quality const q12 (Amounts (amount1, amount2));
Quality const q13 (Amounts (amount1, amount3));
Quality const q21 (Amounts (amount2, amount1));
Quality const q31 (Amounts (amount3, amount1));
Quality const q11(Amounts(amount1, amount1));
Quality const q12(Amounts(amount1, amount2));
Quality const q13(Amounts(amount1, amount3));
Quality const q21(Amounts(amount2, amount1));
Quality const q31(Amounts(amount3, amount1));
BEAST_EXPECT(
composed_quality (q12, q21) == q11);
BEAST_EXPECT(composed_quality(q12, q21) == q11);
Quality const q13_31 (
composed_quality (q13, q31));
Quality const q31_13 (
composed_quality (q31, q13));
Quality const q13_31(composed_quality(q13, q31));
Quality const q31_13(composed_quality(q31, q13));
BEAST_EXPECT(q13_31 == q31_13);
BEAST_EXPECT(q13_31 == q11);
}
void
test_operations ()
test_operations()
{
testcase ("operations");
testcase("operations");
Quality const q11 (Amounts (
STAmount (noIssue(), 731),
STAmount (noIssue(), 731)));
Quality const q11(
Amounts(STAmount(noIssue(), 731), STAmount(noIssue(), 731)));
Quality qa (q11);
Quality qb (q11);
Quality qa(q11);
Quality qb(q11);
BEAST_EXPECT(qa == qb);
BEAST_EXPECT(++qa != q11);
@@ -349,16 +404,16 @@ public:
void
run() override
{
test_comparisons ();
test_composition ();
test_operations ();
test_ceil_in ();
test_ceil_out ();
test_raw ();
test_round ();
test_comparisons();
test_composition();
test_operations();
test_ceil_in();
test_ceil_out();
test_raw();
test_round();
}
};
BEAST_DEFINE_TESTSUITE(Quality,protocol,ripple);
BEAST_DEFINE_TESTSUITE(Quality, protocol, ripple);
}
} // namespace ripple

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#include <ripple/protocol/STAccount.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/STAccount.h>
namespace ripple {
@@ -33,91 +33,92 @@ struct STAccount_test : public beast::unit_test::suite
BEAST_EXPECT(defaultAcct.getSType() == STI_ACCOUNT);
BEAST_EXPECT(defaultAcct.getText() == "");
BEAST_EXPECT(defaultAcct.isDefault() == true);
BEAST_EXPECT(defaultAcct.value() == AccountID {});
BEAST_EXPECT(defaultAcct.value() == AccountID{});
{
#ifdef NDEBUG // Qualified because the serialization asserts in a debug build.
#ifdef NDEBUG // Qualified because the serialization asserts in a debug build.
Serializer s;
defaultAcct.add (s); // Asserts in debug build
defaultAcct.add(s); // Asserts in debug build
BEAST_EXPECT(s.size() == 1);
BEAST_EXPECT(s.getHex() == "00");
SerialIter sit (s.slice ());
STAccount const deserializedDefault (sit, sfAccount);
BEAST_EXPECT(deserializedDefault.isEquivalent (defaultAcct));
#endif // NDEBUG
SerialIter sit(s.slice());
STAccount const deserializedDefault(sit, sfAccount);
BEAST_EXPECT(deserializedDefault.isEquivalent(defaultAcct));
#endif // NDEBUG
}
{
// Construct a deserialized default STAccount.
Serializer s;
s.addVL (nullptr, 0);
SerialIter sit (s.slice ());
STAccount const deserializedDefault (sit, sfAccount);
BEAST_EXPECT(deserializedDefault.isEquivalent (defaultAcct));
s.addVL(nullptr, 0);
SerialIter sit(s.slice());
STAccount const deserializedDefault(sit, sfAccount);
BEAST_EXPECT(deserializedDefault.isEquivalent(defaultAcct));
}
// Test constructor from SField.
STAccount const sfAcct {sfAccount};
STAccount const sfAcct{sfAccount};
BEAST_EXPECT(sfAcct.getSType() == STI_ACCOUNT);
BEAST_EXPECT(sfAcct.getText() == "");
BEAST_EXPECT(sfAcct.isDefault());
BEAST_EXPECT(sfAcct.value() == AccountID {});
BEAST_EXPECT(sfAcct.isEquivalent (defaultAcct));
BEAST_EXPECT(sfAcct.value() == AccountID{});
BEAST_EXPECT(sfAcct.isEquivalent(defaultAcct));
{
Serializer s;
sfAcct.add (s);
sfAcct.add(s);
BEAST_EXPECT(s.size() == 1);
BEAST_EXPECT(s.getHex() == "00");
SerialIter sit (s.slice ());
STAccount const deserializedSf (sit, sfAccount);
SerialIter sit(s.slice());
STAccount const deserializedSf(sit, sfAccount);
BEAST_EXPECT(deserializedSf.isEquivalent(sfAcct));
}
// Test constructor from SField and AccountID.
STAccount const zeroAcct {sfAccount, AccountID{}};
STAccount const zeroAcct{sfAccount, AccountID{}};
BEAST_EXPECT(zeroAcct.getText() == "rrrrrrrrrrrrrrrrrrrrrhoLvTp");
BEAST_EXPECT(! zeroAcct.isDefault());
BEAST_EXPECT(zeroAcct.value() == AccountID {0});
BEAST_EXPECT(! zeroAcct.isEquivalent (defaultAcct));
BEAST_EXPECT(! zeroAcct.isEquivalent (sfAcct));
BEAST_EXPECT(!zeroAcct.isDefault());
BEAST_EXPECT(zeroAcct.value() == AccountID{0});
BEAST_EXPECT(!zeroAcct.isEquivalent(defaultAcct));
BEAST_EXPECT(!zeroAcct.isEquivalent(sfAcct));
{
Serializer s;
zeroAcct.add (s);
zeroAcct.add(s);
BEAST_EXPECT(s.size() == 21);
BEAST_EXPECT(s.getHex() ==
"140000000000000000000000000000000000000000");
SerialIter sit (s.slice ());
STAccount const deserializedZero (sit, sfAccount);
BEAST_EXPECT(deserializedZero.isEquivalent (zeroAcct));
BEAST_EXPECT(
s.getHex() == "140000000000000000000000000000000000000000");
SerialIter sit(s.slice());
STAccount const deserializedZero(sit, sfAccount);
BEAST_EXPECT(deserializedZero.isEquivalent(zeroAcct));
}
{
// Construct from a VL that is not exactly 160 bits.
Serializer s;
const std::uint8_t bits128[] {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
s.addVL (bits128, sizeof (bits128));
SerialIter sit (s.slice ());
const std::uint8_t bits128[]{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
s.addVL(bits128, sizeof(bits128));
SerialIter sit(s.slice());
try
{
// Constructing an STAccount with a bad size should throw.
STAccount const deserializedBadSize (sit, sfAccount);
STAccount const deserializedBadSize(sit, sfAccount);
}
catch (std::runtime_error const& ex)
{
BEAST_EXPECT(ex.what() == std::string("Invalid STAccount size"));
BEAST_EXPECT(
ex.what() == std::string("Invalid STAccount size"));
}
}
// Interestingly, equal values but different types are equivalent!
STAccount const regKey {sfRegularKey, AccountID{}};
BEAST_EXPECT(regKey.isEquivalent (zeroAcct));
STAccount const regKey{sfRegularKey, AccountID{}};
BEAST_EXPECT(regKey.isEquivalent(zeroAcct));
// Test assignment.
STAccount assignAcct;
BEAST_EXPECT(assignAcct.isEquivalent (defaultAcct));
BEAST_EXPECT(assignAcct.isEquivalent(defaultAcct));
BEAST_EXPECT(assignAcct.isDefault());
assignAcct = AccountID{};
BEAST_EXPECT(! assignAcct.isEquivalent (defaultAcct));
BEAST_EXPECT(assignAcct.isEquivalent (zeroAcct));
BEAST_EXPECT(! assignAcct.isDefault());
BEAST_EXPECT(!assignAcct.isEquivalent(defaultAcct));
BEAST_EXPECT(assignAcct.isEquivalent(zeroAcct));
BEAST_EXPECT(!assignAcct.isDefault());
}
}
@@ -128,6 +129,6 @@ struct STAccount_test : public beast::unit_test::suite
}
};
BEAST_DEFINE_TESTSUITE(STAccount,protocol,ripple);
BEAST_DEFINE_TESTSUITE(STAccount, protocol, ripple);
}
} // namespace ripple

View File

@@ -19,30 +19,32 @@
#include <ripple/basics/Log.h>
#include <ripple/basics/random.h>
#include <ripple/protocol/STAmount.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/STAmount.h>
namespace ripple {
class STAmount_test : public beast::unit_test::suite
{
public:
static STAmount serializeAndDeserialize (STAmount const& s)
static STAmount
serializeAndDeserialize(STAmount const& s)
{
Serializer ser;
s.add (ser);
s.add(ser);
SerialIter sit (ser.slice());
SerialIter sit(ser.slice());
return STAmount(sit, sfGeneric);
}
//--------------------------------------------------------------------------
STAmount roundSelf (STAmount const& amount)
STAmount
roundSelf(STAmount const& amount)
{
if (amount.native ())
if (amount.native())
return amount;
std::uint64_t mantissa = amount.mantissa ();
std::uint64_t mantissa = amount.mantissa();
std::uint64_t valueDigits = mantissa % 1000000000;
if (valueDigits == 1)
@@ -50,11 +52,19 @@ public:
mantissa--;
if (mantissa < STAmount::cMinValue)
return { amount.issue (), mantissa, amount.exponent (),
amount.negative () };
return {
amount.issue(),
mantissa,
amount.exponent(),
amount.negative()};
return { amount.issue (), mantissa, amount.exponent (),
amount.native(), amount.negative (), STAmount::unchecked {} };
return {
amount.issue(),
mantissa,
amount.exponent(),
amount.native(),
amount.negative(),
STAmount::unchecked{}};
}
if (valueDigits == 999999999)
@@ -62,72 +72,86 @@ public:
mantissa++;
if (mantissa > STAmount::cMaxValue)
return { amount.issue (), mantissa, amount.exponent (),
amount.negative () };
return {
amount.issue(),
mantissa,
amount.exponent(),
amount.negative()};
return { amount.issue (), mantissa, amount.exponent (),
amount.native(), amount.negative (), STAmount::unchecked {} };
return {
amount.issue(),
mantissa,
amount.exponent(),
amount.native(),
amount.negative(),
STAmount::unchecked{}};
}
return amount;
}
void roundTest (int n, int d, int m)
void
roundTest(int n, int d, int m)
{
// check STAmount rounding
STAmount num (noIssue(), n);
STAmount den (noIssue(), d);
STAmount mul (noIssue(), m);
STAmount num(noIssue(), n);
STAmount den(noIssue(), d);
STAmount mul(noIssue(), m);
STAmount quot = divide(STAmount(n), STAmount(d), noIssue());
STAmount res = roundSelf (multiply (quot, mul, noIssue()));
STAmount res = roundSelf(multiply(quot, mul, noIssue()));
BEAST_EXPECT(! res.native ());
BEAST_EXPECT(!res.native());
STAmount cmp (noIssue(), (n * m) / d);
STAmount cmp(noIssue(), (n * m) / d);
BEAST_EXPECT(! cmp.native ());
BEAST_EXPECT(!cmp.native());
BEAST_EXPECT(cmp.issue().currency == res.issue().currency);
if (res != cmp)
{
log <<
"(" << num.getText () << "/" << den.getText () <<
") X " << mul.getText () << " = " << res.getText () <<
" not " << cmp.getText ();
fail ("Rounding");
log << "(" << num.getText() << "/" << den.getText() << ") X "
<< mul.getText() << " = " << res.getText() << " not "
<< cmp.getText();
fail("Rounding");
return;
}
}
void mulTest (int a, int b)
void
mulTest(int a, int b)
{
STAmount aa (noIssue(), a);
STAmount bb (noIssue(), b);
STAmount prod1 (multiply (aa, bb, noIssue()));
STAmount aa(noIssue(), a);
STAmount bb(noIssue(), b);
STAmount prod1(multiply(aa, bb, noIssue()));
BEAST_EXPECT(! prod1.native ());
BEAST_EXPECT(!prod1.native());
STAmount prod2 (noIssue(), static_cast<std::uint64_t> (a) * static_cast<std::uint64_t> (b));
STAmount prod2(
noIssue(),
static_cast<std::uint64_t>(a) * static_cast<std::uint64_t>(b));
if (prod1 != prod2)
{
log <<
"nn(" << aa.getFullText () << " * " << bb.getFullText () <<
") = " << prod1.getFullText () << " not " << prod2.getFullText ();
fail ("Multiplication result is not exact");
log << "nn(" << aa.getFullText() << " * " << bb.getFullText()
<< ") = " << prod1.getFullText() << " not "
<< prod2.getFullText();
fail("Multiplication result is not exact");
}
}
//--------------------------------------------------------------------------
void testSetValue (
std::string const& value, Issue const& issue, bool success = true)
void
testSetValue(
std::string const& value,
Issue const& issue,
bool success = true)
{
try
{
STAmount const amount = amountFromString (issue, value);
BEAST_EXPECT(amount.getText () == value);
STAmount const amount = amountFromString(issue, value);
BEAST_EXPECT(amount.getText() == value);
}
catch (std::exception const&)
{
@@ -135,361 +159,405 @@ public:
}
}
void testSetValue ()
void
testSetValue()
{
{
testcase ("set value (native)");
testcase("set value (native)");
Issue const xrp (xrpIssue ());
Issue const xrp(xrpIssue());
// fractional XRP (i.e. drops)
testSetValue ("1", xrp);
testSetValue ("22", xrp);
testSetValue ("333", xrp);
testSetValue ("4444", xrp);
testSetValue ("55555", xrp);
testSetValue ("666666", xrp);
testSetValue("1", xrp);
testSetValue("22", xrp);
testSetValue("333", xrp);
testSetValue("4444", xrp);
testSetValue("55555", xrp);
testSetValue("666666", xrp);
// 1 XRP up to 100 billion, in powers of 10 (in drops)
testSetValue ("1000000", xrp);
testSetValue ("10000000", xrp);
testSetValue ("100000000", xrp);
testSetValue ("1000000000", xrp);
testSetValue ("10000000000", xrp);
testSetValue ("100000000000", xrp);
testSetValue ("1000000000000", xrp);
testSetValue ("10000000000000", xrp);
testSetValue ("100000000000000", xrp);
testSetValue ("1000000000000000", xrp);
testSetValue ("10000000000000000", xrp);
testSetValue ("100000000000000000", xrp);
testSetValue("1000000", xrp);
testSetValue("10000000", xrp);
testSetValue("100000000", xrp);
testSetValue("1000000000", xrp);
testSetValue("10000000000", xrp);
testSetValue("100000000000", xrp);
testSetValue("1000000000000", xrp);
testSetValue("10000000000000", xrp);
testSetValue("100000000000000", xrp);
testSetValue("1000000000000000", xrp);
testSetValue("10000000000000000", xrp);
testSetValue("100000000000000000", xrp);
// Invalid native values:
testSetValue ("1.1", xrp, false);
testSetValue ("100000000000000001", xrp, false);
testSetValue ("1000000000000000000", xrp, false);
testSetValue("1.1", xrp, false);
testSetValue("100000000000000001", xrp, false);
testSetValue("1000000000000000000", xrp, false);
}
{
testcase ("set value (iou)");
testcase("set value (iou)");
Issue const usd (Currency (0x5553440000000000), AccountID (0x4985601));
Issue const usd(Currency(0x5553440000000000), AccountID(0x4985601));
testSetValue ("1", usd);
testSetValue ("10", usd);
testSetValue ("100", usd);
testSetValue ("1000", usd);
testSetValue ("10000", usd);
testSetValue ("100000", usd);
testSetValue ("1000000", usd);
testSetValue ("10000000", usd);
testSetValue ("100000000", usd);
testSetValue ("1000000000", usd);
testSetValue ("10000000000", usd);
testSetValue("1", usd);
testSetValue("10", usd);
testSetValue("100", usd);
testSetValue("1000", usd);
testSetValue("10000", usd);
testSetValue("100000", usd);
testSetValue("1000000", usd);
testSetValue("10000000", usd);
testSetValue("100000000", usd);
testSetValue("1000000000", usd);
testSetValue("10000000000", usd);
testSetValue ("1234567.1", usd);
testSetValue ("1234567.12", usd);
testSetValue ("1234567.123", usd);
testSetValue ("1234567.1234", usd);
testSetValue ("1234567.12345", usd);
testSetValue ("1234567.123456", usd);
testSetValue ("1234567.1234567", usd);
testSetValue ("1234567.12345678", usd);
testSetValue ("1234567.123456789", usd);
testSetValue("1234567.1", usd);
testSetValue("1234567.12", usd);
testSetValue("1234567.123", usd);
testSetValue("1234567.1234", usd);
testSetValue("1234567.12345", usd);
testSetValue("1234567.123456", usd);
testSetValue("1234567.1234567", usd);
testSetValue("1234567.12345678", usd);
testSetValue("1234567.123456789", usd);
}
}
//--------------------------------------------------------------------------
void testNativeCurrency ()
void
testNativeCurrency()
{
testcase ("native currency");
STAmount zeroSt, one (1), hundred (100);
testcase("native currency");
STAmount zeroSt, one(1), hundred(100);
// VFALCO NOTE Why repeat "STAmount fail" so many times??
unexpected (serializeAndDeserialize (zeroSt) != zeroSt, "STAmount fail");
unexpected (serializeAndDeserialize (one) != one, "STAmount fail");
unexpected (serializeAndDeserialize (hundred) != hundred, "STAmount fail");
unexpected (!zeroSt.native (), "STAmount fail");
unexpected (!hundred.native (), "STAmount fail");
unexpected (zeroSt != beast::zero, "STAmount fail");
unexpected (one == beast::zero, "STAmount fail");
unexpected (hundred == beast::zero, "STAmount fail");
unexpected ((zeroSt < zeroSt), "STAmount fail");
unexpected (! (zeroSt < one), "STAmount fail");
unexpected (! (zeroSt < hundred), "STAmount fail");
unexpected ((one < zeroSt), "STAmount fail");
unexpected ((one < one), "STAmount fail");
unexpected (! (one < hundred), "STAmount fail");
unexpected ((hundred < zeroSt), "STAmount fail");
unexpected ((hundred < one), "STAmount fail");
unexpected ((hundred < hundred), "STAmount fail");
unexpected ((zeroSt > zeroSt), "STAmount fail");
unexpected ((zeroSt > one), "STAmount fail");
unexpected ((zeroSt > hundred), "STAmount fail");
unexpected (! (one > zeroSt), "STAmount fail");
unexpected ((one > one), "STAmount fail");
unexpected ((one > hundred), "STAmount fail");
unexpected (! (hundred > zeroSt), "STAmount fail");
unexpected (! (hundred > one), "STAmount fail");
unexpected ((hundred > hundred), "STAmount fail");
unexpected (! (zeroSt <= zeroSt), "STAmount fail");
unexpected (! (zeroSt <= one), "STAmount fail");
unexpected (! (zeroSt <= hundred), "STAmount fail");
unexpected ((one <= zeroSt), "STAmount fail");
unexpected (! (one <= one), "STAmount fail");
unexpected (! (one <= hundred), "STAmount fail");
unexpected ((hundred <= zeroSt), "STAmount fail");
unexpected ((hundred <= one), "STAmount fail");
unexpected (! (hundred <= hundred), "STAmount fail");
unexpected (! (zeroSt >= zeroSt), "STAmount fail");
unexpected ((zeroSt >= one), "STAmount fail");
unexpected ((zeroSt >= hundred), "STAmount fail");
unexpected (! (one >= zeroSt), "STAmount fail");
unexpected (! (one >= one), "STAmount fail");
unexpected ((one >= hundred), "STAmount fail");
unexpected (! (hundred >= zeroSt), "STAmount fail");
unexpected (! (hundred >= one), "STAmount fail");
unexpected (! (hundred >= hundred), "STAmount fail");
unexpected (! (zeroSt == zeroSt), "STAmount fail");
unexpected ((zeroSt == one), "STAmount fail");
unexpected ((zeroSt == hundred), "STAmount fail");
unexpected ((one == zeroSt), "STAmount fail");
unexpected (! (one == one), "STAmount fail");
unexpected ((one == hundred), "STAmount fail");
unexpected ((hundred == zeroSt), "STAmount fail");
unexpected ((hundred == one), "STAmount fail");
unexpected (! (hundred == hundred), "STAmount fail");
unexpected ((zeroSt != zeroSt), "STAmount fail");
unexpected (! (zeroSt != one), "STAmount fail");
unexpected (! (zeroSt != hundred), "STAmount fail");
unexpected (! (one != zeroSt), "STAmount fail");
unexpected ((one != one), "STAmount fail");
unexpected (! (one != hundred), "STAmount fail");
unexpected (! (hundred != zeroSt), "STAmount fail");
unexpected (! (hundred != one), "STAmount fail");
unexpected ((hundred != hundred), "STAmount fail");
unexpected (STAmount ().getText () != "0", "STAmount fail");
unexpected (STAmount (31).getText () != "31", "STAmount fail");
unexpected (STAmount (310).getText () != "310", "STAmount fail");
unexpected (to_string (Currency ()) != "XRP", "cHC(XRP)");
unexpected(serializeAndDeserialize(zeroSt) != zeroSt, "STAmount fail");
unexpected(serializeAndDeserialize(one) != one, "STAmount fail");
unexpected(
serializeAndDeserialize(hundred) != hundred, "STAmount fail");
unexpected(!zeroSt.native(), "STAmount fail");
unexpected(!hundred.native(), "STAmount fail");
unexpected(zeroSt != beast::zero, "STAmount fail");
unexpected(one == beast::zero, "STAmount fail");
unexpected(hundred == beast::zero, "STAmount fail");
unexpected((zeroSt < zeroSt), "STAmount fail");
unexpected(!(zeroSt < one), "STAmount fail");
unexpected(!(zeroSt < hundred), "STAmount fail");
unexpected((one < zeroSt), "STAmount fail");
unexpected((one < one), "STAmount fail");
unexpected(!(one < hundred), "STAmount fail");
unexpected((hundred < zeroSt), "STAmount fail");
unexpected((hundred < one), "STAmount fail");
unexpected((hundred < hundred), "STAmount fail");
unexpected((zeroSt > zeroSt), "STAmount fail");
unexpected((zeroSt > one), "STAmount fail");
unexpected((zeroSt > hundred), "STAmount fail");
unexpected(!(one > zeroSt), "STAmount fail");
unexpected((one > one), "STAmount fail");
unexpected((one > hundred), "STAmount fail");
unexpected(!(hundred > zeroSt), "STAmount fail");
unexpected(!(hundred > one), "STAmount fail");
unexpected((hundred > hundred), "STAmount fail");
unexpected(!(zeroSt <= zeroSt), "STAmount fail");
unexpected(!(zeroSt <= one), "STAmount fail");
unexpected(!(zeroSt <= hundred), "STAmount fail");
unexpected((one <= zeroSt), "STAmount fail");
unexpected(!(one <= one), "STAmount fail");
unexpected(!(one <= hundred), "STAmount fail");
unexpected((hundred <= zeroSt), "STAmount fail");
unexpected((hundred <= one), "STAmount fail");
unexpected(!(hundred <= hundred), "STAmount fail");
unexpected(!(zeroSt >= zeroSt), "STAmount fail");
unexpected((zeroSt >= one), "STAmount fail");
unexpected((zeroSt >= hundred), "STAmount fail");
unexpected(!(one >= zeroSt), "STAmount fail");
unexpected(!(one >= one), "STAmount fail");
unexpected((one >= hundred), "STAmount fail");
unexpected(!(hundred >= zeroSt), "STAmount fail");
unexpected(!(hundred >= one), "STAmount fail");
unexpected(!(hundred >= hundred), "STAmount fail");
unexpected(!(zeroSt == zeroSt), "STAmount fail");
unexpected((zeroSt == one), "STAmount fail");
unexpected((zeroSt == hundred), "STAmount fail");
unexpected((one == zeroSt), "STAmount fail");
unexpected(!(one == one), "STAmount fail");
unexpected((one == hundred), "STAmount fail");
unexpected((hundred == zeroSt), "STAmount fail");
unexpected((hundred == one), "STAmount fail");
unexpected(!(hundred == hundred), "STAmount fail");
unexpected((zeroSt != zeroSt), "STAmount fail");
unexpected(!(zeroSt != one), "STAmount fail");
unexpected(!(zeroSt != hundred), "STAmount fail");
unexpected(!(one != zeroSt), "STAmount fail");
unexpected((one != one), "STAmount fail");
unexpected(!(one != hundred), "STAmount fail");
unexpected(!(hundred != zeroSt), "STAmount fail");
unexpected(!(hundred != one), "STAmount fail");
unexpected((hundred != hundred), "STAmount fail");
unexpected(STAmount().getText() != "0", "STAmount fail");
unexpected(STAmount(31).getText() != "31", "STAmount fail");
unexpected(STAmount(310).getText() != "310", "STAmount fail");
unexpected(to_string(Currency()) != "XRP", "cHC(XRP)");
Currency c;
unexpected (!to_currency (c, "USD"), "create USD currency");
unexpected (to_string (c) != "USD", "check USD currency");
unexpected(!to_currency(c, "USD"), "create USD currency");
unexpected(to_string(c) != "USD", "check USD currency");
const std::string cur = "015841551A748AD2C1F76FF6ECB0CCCD00000000";
unexpected (!to_currency (c, cur), "create custom currency");
unexpected (to_string (c) != cur, "check custom currency");
unexpected (c != Currency (
from_hex_text<Currency>(cur)), "check custom currency");
unexpected(!to_currency(c, cur), "create custom currency");
unexpected(to_string(c) != cur, "check custom currency");
unexpected(
c != Currency(from_hex_text<Currency>(cur)),
"check custom currency");
}
//--------------------------------------------------------------------------
void testCustomCurrency ()
void
testCustomCurrency()
{
testcase ("custom currency");
STAmount zeroSt (noIssue()), one (noIssue(), 1), hundred (noIssue(), 100);
unexpected (serializeAndDeserialize (zeroSt) != zeroSt, "STAmount fail");
unexpected (serializeAndDeserialize (one) != one, "STAmount fail");
unexpected (serializeAndDeserialize (hundred) != hundred, "STAmount fail");
unexpected (zeroSt.native (), "STAmount fail");
unexpected (hundred.native (), "STAmount fail");
unexpected (zeroSt != beast::zero, "STAmount fail");
unexpected (one == beast::zero, "STAmount fail");
unexpected (hundred == beast::zero, "STAmount fail");
unexpected ((zeroSt < zeroSt), "STAmount fail");
unexpected (! (zeroSt < one), "STAmount fail");
unexpected (! (zeroSt < hundred), "STAmount fail");
unexpected ((one < zeroSt), "STAmount fail");
unexpected ((one < one), "STAmount fail");
unexpected (! (one < hundred), "STAmount fail");
unexpected ((hundred < zeroSt), "STAmount fail");
unexpected ((hundred < one), "STAmount fail");
unexpected ((hundred < hundred), "STAmount fail");
unexpected ((zeroSt > zeroSt), "STAmount fail");
unexpected ((zeroSt > one), "STAmount fail");
unexpected ((zeroSt > hundred), "STAmount fail");
unexpected (! (one > zeroSt), "STAmount fail");
unexpected ((one > one), "STAmount fail");
unexpected ((one > hundred), "STAmount fail");
unexpected (! (hundred > zeroSt), "STAmount fail");
unexpected (! (hundred > one), "STAmount fail");
unexpected ((hundred > hundred), "STAmount fail");
unexpected (! (zeroSt <= zeroSt), "STAmount fail");
unexpected (! (zeroSt <= one), "STAmount fail");
unexpected (! (zeroSt <= hundred), "STAmount fail");
unexpected ((one <= zeroSt), "STAmount fail");
unexpected (! (one <= one), "STAmount fail");
unexpected (! (one <= hundred), "STAmount fail");
unexpected ((hundred <= zeroSt), "STAmount fail");
unexpected ((hundred <= one), "STAmount fail");
unexpected (! (hundred <= hundred), "STAmount fail");
unexpected (! (zeroSt >= zeroSt), "STAmount fail");
unexpected ((zeroSt >= one), "STAmount fail");
unexpected ((zeroSt >= hundred), "STAmount fail");
unexpected (! (one >= zeroSt), "STAmount fail");
unexpected (! (one >= one), "STAmount fail");
unexpected ((one >= hundred), "STAmount fail");
unexpected (! (hundred >= zeroSt), "STAmount fail");
unexpected (! (hundred >= one), "STAmount fail");
unexpected (! (hundred >= hundred), "STAmount fail");
unexpected (! (zeroSt == zeroSt), "STAmount fail");
unexpected ((zeroSt == one), "STAmount fail");
unexpected ((zeroSt == hundred), "STAmount fail");
unexpected ((one == zeroSt), "STAmount fail");
unexpected (! (one == one), "STAmount fail");
unexpected ((one == hundred), "STAmount fail");
unexpected ((hundred == zeroSt), "STAmount fail");
unexpected ((hundred == one), "STAmount fail");
unexpected (! (hundred == hundred), "STAmount fail");
unexpected ((zeroSt != zeroSt), "STAmount fail");
unexpected (! (zeroSt != one), "STAmount fail");
unexpected (! (zeroSt != hundred), "STAmount fail");
unexpected (! (one != zeroSt), "STAmount fail");
unexpected ((one != one), "STAmount fail");
unexpected (! (one != hundred), "STAmount fail");
unexpected (! (hundred != zeroSt), "STAmount fail");
unexpected (! (hundred != one), "STAmount fail");
unexpected ((hundred != hundred), "STAmount fail");
unexpected (STAmount (noIssue()).getText () != "0", "STAmount fail");
unexpected (STAmount (noIssue(), 31).getText () != "31", "STAmount fail");
unexpected (STAmount (noIssue(), 31, 1).getText () != "310", "STAmount fail");
unexpected (STAmount (noIssue(), 31, -1).getText () != "3.1", "STAmount fail");
unexpected (STAmount (noIssue(), 31, -2).getText () != "0.31", "STAmount fail");
unexpected (multiply (STAmount (noIssue(), 20), STAmount (3), noIssue()).getText () != "60",
testcase("custom currency");
STAmount zeroSt(noIssue()), one(noIssue(), 1), hundred(noIssue(), 100);
unexpected(serializeAndDeserialize(zeroSt) != zeroSt, "STAmount fail");
unexpected(serializeAndDeserialize(one) != one, "STAmount fail");
unexpected(
serializeAndDeserialize(hundred) != hundred, "STAmount fail");
unexpected(zeroSt.native(), "STAmount fail");
unexpected(hundred.native(), "STAmount fail");
unexpected(zeroSt != beast::zero, "STAmount fail");
unexpected(one == beast::zero, "STAmount fail");
unexpected(hundred == beast::zero, "STAmount fail");
unexpected((zeroSt < zeroSt), "STAmount fail");
unexpected(!(zeroSt < one), "STAmount fail");
unexpected(!(zeroSt < hundred), "STAmount fail");
unexpected((one < zeroSt), "STAmount fail");
unexpected((one < one), "STAmount fail");
unexpected(!(one < hundred), "STAmount fail");
unexpected((hundred < zeroSt), "STAmount fail");
unexpected((hundred < one), "STAmount fail");
unexpected((hundred < hundred), "STAmount fail");
unexpected((zeroSt > zeroSt), "STAmount fail");
unexpected((zeroSt > one), "STAmount fail");
unexpected((zeroSt > hundred), "STAmount fail");
unexpected(!(one > zeroSt), "STAmount fail");
unexpected((one > one), "STAmount fail");
unexpected((one > hundred), "STAmount fail");
unexpected(!(hundred > zeroSt), "STAmount fail");
unexpected(!(hundred > one), "STAmount fail");
unexpected((hundred > hundred), "STAmount fail");
unexpected(!(zeroSt <= zeroSt), "STAmount fail");
unexpected(!(zeroSt <= one), "STAmount fail");
unexpected(!(zeroSt <= hundred), "STAmount fail");
unexpected((one <= zeroSt), "STAmount fail");
unexpected(!(one <= one), "STAmount fail");
unexpected(!(one <= hundred), "STAmount fail");
unexpected((hundred <= zeroSt), "STAmount fail");
unexpected((hundred <= one), "STAmount fail");
unexpected(!(hundred <= hundred), "STAmount fail");
unexpected(!(zeroSt >= zeroSt), "STAmount fail");
unexpected((zeroSt >= one), "STAmount fail");
unexpected((zeroSt >= hundred), "STAmount fail");
unexpected(!(one >= zeroSt), "STAmount fail");
unexpected(!(one >= one), "STAmount fail");
unexpected((one >= hundred), "STAmount fail");
unexpected(!(hundred >= zeroSt), "STAmount fail");
unexpected(!(hundred >= one), "STAmount fail");
unexpected(!(hundred >= hundred), "STAmount fail");
unexpected(!(zeroSt == zeroSt), "STAmount fail");
unexpected((zeroSt == one), "STAmount fail");
unexpected((zeroSt == hundred), "STAmount fail");
unexpected((one == zeroSt), "STAmount fail");
unexpected(!(one == one), "STAmount fail");
unexpected((one == hundred), "STAmount fail");
unexpected((hundred == zeroSt), "STAmount fail");
unexpected((hundred == one), "STAmount fail");
unexpected(!(hundred == hundred), "STAmount fail");
unexpected((zeroSt != zeroSt), "STAmount fail");
unexpected(!(zeroSt != one), "STAmount fail");
unexpected(!(zeroSt != hundred), "STAmount fail");
unexpected(!(one != zeroSt), "STAmount fail");
unexpected((one != one), "STAmount fail");
unexpected(!(one != hundred), "STAmount fail");
unexpected(!(hundred != zeroSt), "STAmount fail");
unexpected(!(hundred != one), "STAmount fail");
unexpected((hundred != hundred), "STAmount fail");
unexpected(STAmount(noIssue()).getText() != "0", "STAmount fail");
unexpected(STAmount(noIssue(), 31).getText() != "31", "STAmount fail");
unexpected(
STAmount(noIssue(), 31, 1).getText() != "310", "STAmount fail");
unexpected(
STAmount(noIssue(), 31, -1).getText() != "3.1", "STAmount fail");
unexpected(
STAmount(noIssue(), 31, -2).getText() != "0.31", "STAmount fail");
unexpected(
multiply(STAmount(noIssue(), 20), STAmount(3), noIssue())
.getText() != "60",
"STAmount multiply fail 1");
unexpected (multiply (STAmount (noIssue(), 20), STAmount (3), xrpIssue ()).getText () != "60",
unexpected(
multiply(STAmount(noIssue(), 20), STAmount(3), xrpIssue())
.getText() != "60",
"STAmount multiply fail 2");
unexpected (multiply (STAmount (20), STAmount (3), noIssue()).getText () != "60",
unexpected(
multiply(STAmount(20), STAmount(3), noIssue()).getText() != "60",
"STAmount multiply fail 3");
unexpected (multiply (STAmount (20), STAmount (3), xrpIssue ()).getText () != "60",
unexpected(
multiply(STAmount(20), STAmount(3), xrpIssue()).getText() != "60",
"STAmount multiply fail 4");
if (divide (STAmount (noIssue(), 60), STAmount (3), noIssue()).getText () != "20")
if (divide(STAmount(noIssue(), 60), STAmount(3), noIssue()).getText() !=
"20")
{
log << "60/3 = " <<
divide (STAmount (noIssue(), 60),
STAmount (3), noIssue()).getText ();
fail ("STAmount divide fail");
log << "60/3 = "
<< divide(STAmount(noIssue(), 60), STAmount(3), noIssue())
.getText();
fail("STAmount divide fail");
}
else
{
pass ();
pass();
}
unexpected (divide (STAmount (noIssue(), 60), STAmount (3), xrpIssue ()).getText () != "20",
unexpected(
divide(STAmount(noIssue(), 60), STAmount(3), xrpIssue())
.getText() != "20",
"STAmount divide fail");
unexpected (divide (STAmount (noIssue(), 60), STAmount (noIssue(), 3), noIssue()).getText () != "20",
unexpected(
divide(STAmount(noIssue(), 60), STAmount(noIssue(), 3), noIssue())
.getText() != "20",
"STAmount divide fail");
unexpected (divide (STAmount (noIssue(), 60), STAmount (noIssue(), 3), xrpIssue ()).getText () != "20",
unexpected(
divide(STAmount(noIssue(), 60), STAmount(noIssue(), 3), xrpIssue())
.getText() != "20",
"STAmount divide fail");
STAmount a1 (noIssue(), 60), a2 (noIssue(), 10, -1);
STAmount a1(noIssue(), 60), a2(noIssue(), 10, -1);
unexpected (divide (a2, a1, noIssue()) != amountFromQuality (getRate (a1, a2)),
unexpected(
divide(a2, a1, noIssue()) != amountFromQuality(getRate(a1, a2)),
"STAmount setRate(getRate) fail");
unexpected (divide (a1, a2, noIssue()) != amountFromQuality (getRate (a2, a1)),
unexpected(
divide(a1, a2, noIssue()) != amountFromQuality(getRate(a2, a1)),
"STAmount setRate(getRate) fail");
}
//--------------------------------------------------------------------------
void testArithmetic ()
void
testArithmetic()
{
testcase ("arithmetic");
testcase("arithmetic");
// Test currency multiplication and division operations such as
// convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed, and getNeeded
// convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed,
// and getNeeded
unexpected (getRate (STAmount (1), STAmount (10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(1), STAmount(10)) !=
(((100ull - 14) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 1");
unexpected (getRate (STAmount (10), STAmount (1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(10), STAmount(1)) !=
(((100ull - 16) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 2");
unexpected (getRate (STAmount (noIssue(), 1), STAmount (noIssue(), 10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(noIssue(), 1), STAmount(noIssue(), 10)) !=
(((100ull - 14) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 3");
unexpected (getRate (STAmount (noIssue(), 10), STAmount (noIssue(), 1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(noIssue(), 10), STAmount(noIssue(), 1)) !=
(((100ull - 16) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 4");
unexpected (getRate (STAmount (noIssue(), 1), STAmount (10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(noIssue(), 1), STAmount(10)) !=
(((100ull - 14) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 5");
unexpected (getRate (STAmount (noIssue(), 10), STAmount (1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(noIssue(), 10), STAmount(1)) !=
(((100ull - 16) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 6");
unexpected (getRate (STAmount (1), STAmount (noIssue(), 10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(1), STAmount(noIssue(), 10)) !=
(((100ull - 14) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 7");
unexpected (getRate (STAmount (10), STAmount (noIssue(), 1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
unexpected(
getRate(STAmount(10), STAmount(noIssue(), 1)) !=
(((100ull - 16) << (64 - 8)) | 1000000000000000ull),
"STAmount getRate fail 8");
roundTest (1, 3, 3);
roundTest (2, 3, 9);
roundTest (1, 7, 21);
roundTest (1, 2, 4);
roundTest (3, 9, 18);
roundTest (7, 11, 44);
roundTest(1, 3, 3);
roundTest(2, 3, 9);
roundTest(1, 7, 21);
roundTest(1, 2, 4);
roundTest(3, 9, 18);
roundTest(7, 11, 44);
for (int i = 0; i <= 100000; ++i)
{
mulTest (
rand_int(10000000),
rand_int(10000000));
mulTest(rand_int(10000000), rand_int(10000000));
}
}
//--------------------------------------------------------------------------
void testUnderflow ()
void
testUnderflow()
{
testcase ("underflow");
testcase("underflow");
STAmount bigNative (STAmount::cMaxNative / 2);
STAmount bigValue (noIssue(),
STAmount bigNative(STAmount::cMaxNative / 2);
STAmount bigValue(
noIssue(),
(STAmount::cMinValue + STAmount::cMaxValue) / 2,
STAmount::cMaxOffset - 1);
STAmount smallValue (noIssue(),
STAmount smallValue(
noIssue(),
(STAmount::cMinValue + STAmount::cMaxValue) / 2,
STAmount::cMinOffset + 1);
STAmount zeroSt (noIssue(), 0);
STAmount zeroSt(noIssue(), 0);
STAmount smallXsmall = multiply (smallValue, smallValue, noIssue());
STAmount smallXsmall = multiply(smallValue, smallValue, noIssue());
BEAST_EXPECT(smallXsmall == beast::zero);
STAmount bigDsmall = divide (smallValue, bigValue, noIssue());
STAmount bigDsmall = divide(smallValue, bigValue, noIssue());
BEAST_EXPECT(bigDsmall == beast::zero);
BEAST_EXPECT(bigDsmall == beast::zero);
bigDsmall = divide (smallValue, bigValue, xrpIssue ());
bigDsmall = divide(smallValue, bigValue, xrpIssue());
BEAST_EXPECT(bigDsmall == beast::zero);
bigDsmall = divide (smallValue, bigNative, xrpIssue ());
bigDsmall = divide(smallValue, bigNative, xrpIssue());
BEAST_EXPECT(bigDsmall == beast::zero);
// very bad offer
std::uint64_t r = getRate (smallValue, bigValue);
std::uint64_t r = getRate(smallValue, bigValue);
BEAST_EXPECT(r == 0);
// very good offer
r = getRate (bigValue, smallValue);
r = getRate(bigValue, smallValue);
BEAST_EXPECT(r == 0);
}
//--------------------------------------------------------------------------
void testRounding ()
void
testRounding()
{
// VFALCO TODO There are no actual tests here, just printed output?
// Change this to actually do something.
@@ -541,84 +609,87 @@ public:
}
void
testConvertXRP ()
testConvertXRP()
{
testcase ("STAmount to XRPAmount conversions");
testcase("STAmount to XRPAmount conversions");
Issue const usd { Currency (0x5553440000000000), AccountID (0x4985601) };
Issue const xrp { xrpIssue () };
Issue const usd{Currency(0x5553440000000000), AccountID(0x4985601)};
Issue const xrp{xrpIssue()};
for (std::uint64_t drops = 100000000000000000; drops != 1; drops = drops / 10)
for (std::uint64_t drops = 100000000000000000; drops != 1;
drops = drops / 10)
{
auto const t = amountFromString (xrp, std::to_string (drops));
auto const s = t.xrp ();
auto const t = amountFromString(xrp, std::to_string(drops));
auto const s = t.xrp();
BEAST_EXPECT(s.drops() == drops);
BEAST_EXPECT(t == STAmount (XRPAmount (drops)));
BEAST_EXPECT(s == XRPAmount (drops));
BEAST_EXPECT(t == STAmount(XRPAmount(drops)));
BEAST_EXPECT(s == XRPAmount(drops));
}
try
{
auto const t = amountFromString (usd, "136500");
fail (to_string (t.xrp ()));
auto const t = amountFromString(usd, "136500");
fail(to_string(t.xrp()));
}
catch (std::logic_error const&)
{
pass ();
pass();
}
catch (std::exception const&)
{
fail ("wrong exception");
fail("wrong exception");
}
}
void
testConvertIOU ()
testConvertIOU()
{
testcase ("STAmount to IOUAmount conversions");
testcase("STAmount to IOUAmount conversions");
Issue const usd { Currency (0x5553440000000000), AccountID (0x4985601) };
Issue const xrp { xrpIssue () };
Issue const usd{Currency(0x5553440000000000), AccountID(0x4985601)};
Issue const xrp{xrpIssue()};
for (std::uint64_t dollars = 10000000000; dollars != 1; dollars = dollars / 10)
for (std::uint64_t dollars = 10000000000; dollars != 1;
dollars = dollars / 10)
{
auto const t = amountFromString (usd, std::to_string (dollars));
auto const s = t.iou ();
BEAST_EXPECT(t == STAmount (s, usd));
BEAST_EXPECT(s.mantissa () == t.mantissa ());
BEAST_EXPECT(s.exponent () == t.exponent ());
auto const t = amountFromString(usd, std::to_string(dollars));
auto const s = t.iou();
BEAST_EXPECT(t == STAmount(s, usd));
BEAST_EXPECT(s.mantissa() == t.mantissa());
BEAST_EXPECT(s.exponent() == t.exponent());
}
try
{
auto const t = amountFromString (xrp, "136500");
fail (to_string (t.iou ()));
auto const t = amountFromString(xrp, "136500");
fail(to_string(t.iou()));
}
catch (std::logic_error const&)
{
pass ();
pass();
}
catch (std::exception const&)
{
fail ("wrong exception");
fail("wrong exception");
}
}
//--------------------------------------------------------------------------
void run () override
void
run() override
{
testSetValue ();
testNativeCurrency ();
testCustomCurrency ();
testArithmetic ();
testUnderflow ();
testRounding ();
testConvertXRP ();
testConvertIOU ();
testSetValue();
testNativeCurrency();
testCustomCurrency();
testArithmetic();
testUnderflow();
testRounding();
testConvertXRP();
testConvertIOU();
}
};
BEAST_DEFINE_TESTSUITE(STAmount,ripple_data,ripple);
BEAST_DEFINE_TESTSUITE(STAmount, ripple_data, ripple);
} // ripple
} // namespace ripple

View File

@@ -18,12 +18,12 @@
//==============================================================================
#include <ripple/basics/Log.h>
#include <ripple/protocol/jss.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/st.h>
#include <ripple/beast/unit_test.h>
#include <ripple/json/json_reader.h>
#include <ripple/json/to_string.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/jss.h>
#include <ripple/protocol/st.h>
#include <test/jtx.h>
#include <array>
@@ -35,15 +35,17 @@ namespace ripple {
class STObject_test : public beast::unit_test::suite
{
public:
bool parseJSONString (std::string const& json, Json::Value& to)
bool
parseJSONString(std::string const& json, Json::Value& to)
{
Json::Reader reader;
return reader.parse(json, to) && to.isObject();
}
void testParseJSONArrayWithInvalidChildrenObjects ()
void
testParseJSONArrayWithInvalidChildrenObjects()
{
testcase ("parse json array invalid children");
testcase("parse json array invalid children");
try
{
/*
@@ -57,55 +59,57 @@ public:
fidelity, it will take TWO json objects to represent them.
*/
std::string faulty ("{\"Template\":[{"
"\"ModifiedNode\":{\"Sequence\":1}, "
"\"DeletedNode\":{\"Sequence\":1}"
"}]}");
std::string faulty(
"{\"Template\":[{"
"\"ModifiedNode\":{\"Sequence\":1}, "
"\"DeletedNode\":{\"Sequence\":1}"
"}]}");
std::unique_ptr<STObject> so;
Json::Value faultyJson;
bool parsedOK (parseJSONString(faulty, faultyJson));
bool parsedOK(parseJSONString(faulty, faultyJson));
unexpected(!parsedOK, "failed to parse");
STParsedJSONObject parsed ("test", faultyJson);
BEAST_EXPECT(! parsed.object);
STParsedJSONObject parsed("test", faultyJson);
BEAST_EXPECT(!parsed.object);
}
catch(std::runtime_error& e)
catch (std::runtime_error& e)
{
std::string what(e.what());
unexpected (what.find("First level children of `Template`") != 0);
unexpected(what.find("First level children of `Template`") != 0);
}
}
void testParseJSONArray ()
void
testParseJSONArray()
{
testcase ("parse json array");
std::string const json (
testcase("parse json array");
std::string const json(
"{\"Template\":[{\"ModifiedNode\":{\"Sequence\":1}}]}");
Json::Value jsonObject;
bool parsedOK (parseJSONString(json, jsonObject));
bool parsedOK(parseJSONString(json, jsonObject));
if (parsedOK)
{
STParsedJSONObject parsed ("test", jsonObject);
STParsedJSONObject parsed("test", jsonObject);
BEAST_EXPECT(parsed.object);
std::string const& serialized (
to_string (parsed.object->getJson(JsonOptions::none)));
std::string const& serialized(
to_string(parsed.object->getJson(JsonOptions::none)));
BEAST_EXPECT(serialized == json);
}
else
{
fail ("Couldn't parse json: " + json);
fail("Couldn't parse json: " + json);
}
}
void testParseJSONEdgeCases()
void
testParseJSONEdgeCases()
{
testcase("parse json object");
{
std::string const goodJson(
R"({"CloseResolution":19,"Method":250,)"
R"("TransactionResult":"tecFROZEN"})");
std::string const goodJson(R"({"CloseResolution":19,"Method":250,)"
R"("TransactionResult":"tecFROZEN"})");
Json::Value jv;
if (BEAST_EXPECT(parseJSONString(goodJson, jv)))
@@ -145,9 +149,8 @@ public:
}
{
std::string const json(
R"({"CloseResolution":19,"Method":250,)"
R"("TransactionResult":"terQUEUED"})");
std::string const json(R"({"CloseResolution":19,"Method":250,)"
R"("TransactionResult":"terQUEUED"})");
Json::Value jv;
if (BEAST_EXPECT(parseJSONString(json, jv)))
@@ -156,15 +159,15 @@ public:
BEAST_EXPECT(!parsed.object);
BEAST_EXPECT(parsed.error);
BEAST_EXPECT(parsed.error[jss::error] == "invalidParams");
BEAST_EXPECT(parsed.error[jss::error_message] ==
BEAST_EXPECT(
parsed.error[jss::error_message] ==
"Field 'test.TransactionResult' is out of range.");
}
}
{
std::string const json(
R"({"CloseResolution":19,"Method":"pony",)"
R"("TransactionResult":"tesSUCCESS"})");
std::string const json(R"({"CloseResolution":19,"Method":"pony",)"
R"("TransactionResult":"tesSUCCESS"})");
Json::Value jv;
if (BEAST_EXPECT(parseJSONString(json, jv)))
@@ -173,7 +176,8 @@ public:
BEAST_EXPECT(!parsed.object);
BEAST_EXPECT(parsed.error);
BEAST_EXPECT(parsed.error[jss::error] == "invalidParams");
BEAST_EXPECT(parsed.error[jss::error_message] ==
BEAST_EXPECT(
parsed.error[jss::error_message] ==
"Field 'test.Method' has bad type.");
}
}
@@ -190,15 +194,15 @@ public:
BEAST_EXPECT(!parsed.object);
BEAST_EXPECT(parsed.error);
BEAST_EXPECT(parsed.error[jss::error] == "invalidParams");
BEAST_EXPECT(parsed.error[jss::error_message] ==
BEAST_EXPECT(
parsed.error[jss::error_message] ==
"Field 'test.Method' is out of range.");
}
}
{
std::string const json(
R"({"CloseResolution":-10,"Method":42,)"
R"("TransactionResult":"tesSUCCESS"})");
std::string const json(R"({"CloseResolution":-10,"Method":42,)"
R"("TransactionResult":"tesSUCCESS"})");
Json::Value jv;
if (BEAST_EXPECT(parseJSONString(json, jv)))
@@ -207,7 +211,8 @@ public:
BEAST_EXPECT(!parsed.object);
BEAST_EXPECT(parsed.error);
BEAST_EXPECT(parsed.error[jss::error] == "invalidParams");
BEAST_EXPECT(parsed.error[jss::error_message] ==
BEAST_EXPECT(
parsed.error[jss::error_message] ==
"Field 'test.CloseResolution' is out of range.");
}
}
@@ -224,55 +229,53 @@ public:
BEAST_EXPECT(!parsed.object);
BEAST_EXPECT(parsed.error);
BEAST_EXPECT(parsed.error[jss::error] == "invalidParams");
BEAST_EXPECT(parsed.error[jss::error_message] ==
BEAST_EXPECT(
parsed.error[jss::error_message] ==
"Field 'test.Method' has bad type.");
}
}
}
void testSerialization ()
void
testSerialization()
{
testcase ("serialization");
testcase("serialization");
unexpected (sfGeneric.isUseful (), "sfGeneric must not be useful");
unexpected(sfGeneric.isUseful(), "sfGeneric must not be useful");
{
// Try to put sfGeneric in an SOTemplate.
except<std::runtime_error>( [&]()
{
SOTemplate elements {{ sfGeneric, soeREQUIRED }};
});
except<std::runtime_error>([&]() {
SOTemplate elements{{sfGeneric, soeREQUIRED}};
});
}
unexpected (sfInvalid.isUseful (), "sfInvalid must not be useful");
unexpected(sfInvalid.isUseful(), "sfInvalid must not be useful");
{
// Test return of sfInvalid.
auto testInvalid = [this] (SerializedTypeID tid, int fv)
{
SField const& shouldBeInvalid {SField::getField (tid, fv)};
BEAST_EXPECT (shouldBeInvalid == sfInvalid);
auto testInvalid = [this](SerializedTypeID tid, int fv) {
SField const& shouldBeInvalid{SField::getField(tid, fv)};
BEAST_EXPECT(shouldBeInvalid == sfInvalid);
};
testInvalid (STI_VL, 255);
testInvalid (STI_HASH256, 255);
testInvalid (STI_UINT32, 255);
testInvalid (STI_VECTOR256, 255);
testInvalid (STI_OBJECT, 255);
testInvalid(STI_VL, 255);
testInvalid(STI_HASH256, 255);
testInvalid(STI_UINT32, 255);
testInvalid(STI_VECTOR256, 255);
testInvalid(STI_OBJECT, 255);
}
{
// Try to put sfInvalid in an SOTemplate.
except<std::runtime_error>( [&]()
{
SOTemplate elements {{ sfInvalid, soeREQUIRED }};
});
except<std::runtime_error>([&]() {
SOTemplate elements{{sfInvalid, soeREQUIRED}};
});
}
{
// Try to put the same SField into an SOTemplate twice.
except<std::runtime_error>( [&]()
{
SOTemplate elements {
{ sfAccount, soeREQUIRED },
{ sfAccount, soeREQUIRED },
};
});
except<std::runtime_error>([&]() {
SOTemplate elements{
{sfAccount, soeREQUIRED},
{sfAccount, soeREQUIRED},
};
});
}
// Put a variety of SFields of different types in an SOTemplate.
@@ -282,82 +285,85 @@ public:
SField const& sfTestV256 = sfAmendments;
SField const& sfTestObject = sfMajority;
SOTemplate const elements{
{sfFlags, soeREQUIRED},
{sfTestVL, soeREQUIRED},
{sfTestH256, soeOPTIONAL},
{sfTestU32, soeREQUIRED},
{sfTestV256, soeOPTIONAL},
};
SOTemplate const elements
{
{ sfFlags, soeREQUIRED },
{ sfTestVL, soeREQUIRED },
{ sfTestH256, soeOPTIONAL },
{ sfTestU32, soeREQUIRED },
{ sfTestV256, soeOPTIONAL },
};
STObject object1(elements, sfTestObject);
STObject object2(object1);
STObject object1 (elements, sfTestObject);
STObject object2 (object1);
unexpected (object1.getSerializer () != object2.getSerializer (),
unexpected(
object1.getSerializer() != object2.getSerializer(),
"STObject error 1");
unexpected (object1.isFieldPresent (sfTestH256) ||
!object1.isFieldPresent (sfTestVL), "STObject error");
unexpected(
object1.isFieldPresent(sfTestH256) ||
!object1.isFieldPresent(sfTestVL),
"STObject error");
object1.makeFieldPresent (sfTestH256);
object1.makeFieldPresent(sfTestH256);
unexpected (!object1.isFieldPresent (sfTestH256), "STObject Error 2");
unexpected(!object1.isFieldPresent(sfTestH256), "STObject Error 2");
unexpected (object1.getFieldH256 (sfTestH256) != uint256 (),
"STObject error 3");
unexpected(
object1.getFieldH256(sfTestH256) != uint256(), "STObject error 3");
if (object1.getSerializer () == object2.getSerializer ())
if (object1.getSerializer() == object2.getSerializer())
{
log <<
"O1: " << object1.getJson (JsonOptions::none) << '\n' <<
"O2: " << object2.getJson (JsonOptions::none) << std::endl;
fail ("STObject error 4");
log << "O1: " << object1.getJson(JsonOptions::none) << '\n'
<< "O2: " << object2.getJson(JsonOptions::none) << std::endl;
fail("STObject error 4");
}
else
{
pass ();
pass();
}
object1.makeFieldAbsent (sfTestH256);
object1.makeFieldAbsent(sfTestH256);
unexpected (object1.isFieldPresent (sfTestH256), "STObject error 5");
unexpected(object1.isFieldPresent(sfTestH256), "STObject error 5");
unexpected (object1.getFlags () != 0, "STObject error 6");
unexpected(object1.getFlags() != 0, "STObject error 6");
unexpected (object1.getSerializer () != object2.getSerializer (),
unexpected(
object1.getSerializer() != object2.getSerializer(),
"STObject error 7");
STObject copy (object1);
STObject copy(object1);
unexpected (object1.isFieldPresent (sfTestH256), "STObject error 8");
unexpected(object1.isFieldPresent(sfTestH256), "STObject error 8");
unexpected (copy.isFieldPresent (sfTestH256), "STObject error 9");
unexpected(copy.isFieldPresent(sfTestH256), "STObject error 9");
unexpected (object1.getSerializer () != copy.getSerializer (),
unexpected(
object1.getSerializer() != copy.getSerializer(),
"STObject error 10");
copy.setFieldU32 (sfTestU32, 1);
copy.setFieldU32(sfTestU32, 1);
unexpected (object1.getSerializer () == copy.getSerializer (),
unexpected(
object1.getSerializer() == copy.getSerializer(),
"STObject error 11");
for (int i = 0; i < 1000; i++)
{
Blob j (i, 2);
Blob j(i, 2);
object1.setFieldVL (sfTestVL, j);
object1.setFieldVL(sfTestVL, j);
Serializer s;
object1.add (s);
SerialIter it (s.slice());
object1.add(s);
SerialIter it(s.slice());
STObject object3 (elements, it, sfTestObject);
STObject object3(elements, it, sfTestObject);
unexpected (object1.getFieldVL (sfTestVL) != j, "STObject error");
unexpected(object1.getFieldVL(sfTestVL) != j, "STObject error");
unexpected (object3.getFieldVL (sfTestVL) != j, "STObject error");
unexpected(object3.getFieldVL(sfTestVL) != j, "STObject error");
}
{
@@ -386,7 +392,7 @@ public:
void
testFields()
{
testcase ("fields");
testcase("fields");
auto const& sf1Outer = sfSequence;
auto const& sf2Outer = sfExpiration;
@@ -397,8 +403,7 @@ public:
// read free object
{
auto const st = [&]()
{
auto const st = [&]() {
STObject s(sfGeneric);
s.setFieldU32(sf1Outer, 1);
s.setFieldU32(sf2Outer, 2);
@@ -407,31 +412,28 @@ public:
BEAST_EXPECT(st[sf1Outer] == 1);
BEAST_EXPECT(st[sf2Outer] == 2);
except<STObject::FieldErr>([&]()
{ st[sf3Outer]; });
except<STObject::FieldErr>([&]() { st[sf3Outer]; });
BEAST_EXPECT(*st[~sf1Outer] == 1);
BEAST_EXPECT(*st[~sf2Outer] == 2);
BEAST_EXPECT(st[~sf3Outer] == boost::none);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!! st[~sf2Outer]);
BEAST_EXPECT(! st[~sf3Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
BEAST_EXPECT(!!st[~sf2Outer]);
BEAST_EXPECT(!st[~sf3Outer]);
BEAST_EXPECT(st[sf1Outer] != st[sf2Outer]);
BEAST_EXPECT(st[~sf1Outer] != st[~sf2Outer]);
}
// read templated object
SOTemplate const sotOuter
{
{ sf1Outer, soeREQUIRED },
{ sf2Outer, soeOPTIONAL },
{ sf3Outer, soeDEFAULT },
{ sf4, soeOPTIONAL },
{ sf5, soeDEFAULT },
};
SOTemplate const sotOuter{
{sf1Outer, soeREQUIRED},
{sf2Outer, soeOPTIONAL},
{sf3Outer, soeDEFAULT},
{sf4, soeOPTIONAL},
{sf5, soeDEFAULT},
};
{
auto const st = [&]()
{
auto const st = [&]() {
STObject s(sotOuter, sfGeneric);
s.setFieldU32(sf1Outer, 1);
s.setFieldU32(sf2Outer, 2);
@@ -444,9 +446,9 @@ public:
BEAST_EXPECT(*st[~sf1Outer] == 1);
BEAST_EXPECT(*st[~sf2Outer] == 2);
BEAST_EXPECT(*st[~sf3Outer] == 0);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!! st[~sf2Outer]);
BEAST_EXPECT(!! st[~sf3Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
BEAST_EXPECT(!!st[~sf2Outer]);
BEAST_EXPECT(!!st[~sf3Outer]);
}
// write free object
@@ -454,35 +456,35 @@ public:
{
STObject st(sfGeneric);
unexcept([&]() { st[sf1Outer]; });
except([&](){ return st[sf1Outer] == 0; });
except([&]() { return st[sf1Outer] == 0; });
BEAST_EXPECT(st[~sf1Outer] == boost::none);
BEAST_EXPECT(st[~sf1Outer] == boost::optional<std::uint32_t>{});
BEAST_EXPECT(st[~sf1Outer] != boost::optional<std::uint32_t>(1));
BEAST_EXPECT(! st[~sf1Outer]);
BEAST_EXPECT(!st[~sf1Outer]);
st[sf1Outer] = 2;
BEAST_EXPECT(st[sf1Outer] == 2);
BEAST_EXPECT(st[~sf1Outer] != boost::none);
BEAST_EXPECT(st[~sf1Outer] == boost::optional<std::uint32_t>(2));
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
st[sf1Outer] = 1;
BEAST_EXPECT(st[sf1Outer] == 1);
BEAST_EXPECT(!! st[sf1Outer]);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!!st[sf1Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
st[sf1Outer] = 0;
BEAST_EXPECT(! st[sf1Outer]);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!st[sf1Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
st[~sf1Outer] = boost::none;
BEAST_EXPECT(! st[~sf1Outer]);
BEAST_EXPECT(!st[~sf1Outer]);
BEAST_EXPECT(st[~sf1Outer] == boost::none);
BEAST_EXPECT(st[~sf1Outer] == boost::optional<std::uint32_t>{});
st[~sf1Outer] = boost::none;
BEAST_EXPECT(! st[~sf1Outer]);
BEAST_EXPECT(!st[~sf1Outer]);
except([&]() { return st[sf1Outer] == 0; });
except([&]() { return *st[~sf1Outer]; });
st[sf1Outer] = 1;
BEAST_EXPECT(st[sf1Outer] == 1);
BEAST_EXPECT(!! st[sf1Outer]);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!!st[sf1Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
st[sf1Outer] = 3;
st[sf2Outer] = st[sf1Outer];
BEAST_EXPECT(st[sf1Outer] == 3);
@@ -499,48 +501,48 @@ public:
{
STObject st(sotOuter, sfGeneric);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
BEAST_EXPECT(st[~sf1Outer] != boost::none);
BEAST_EXPECT(st[sf1Outer] == 0);
BEAST_EXPECT(*st[~sf1Outer] == 0);
BEAST_EXPECT(! st[~sf2Outer]);
BEAST_EXPECT(!st[~sf2Outer]);
BEAST_EXPECT(st[~sf2Outer] == boost::none);
except([&]() { return st[sf2Outer] == 0; });
BEAST_EXPECT(!! st[~sf3Outer]);
BEAST_EXPECT(!!st[~sf3Outer]);
BEAST_EXPECT(st[~sf3Outer] != boost::none);
BEAST_EXPECT(st[sf3Outer] == 0);
except([&]() { st[~sf1Outer] = boost::none; });
st[sf1Outer] = 1;
BEAST_EXPECT(st[sf1Outer] == 1);
BEAST_EXPECT(*st[~sf1Outer] == 1);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
st[sf1Outer] = 0;
BEAST_EXPECT(st[sf1Outer] == 0);
BEAST_EXPECT(*st[~sf1Outer] == 0);
BEAST_EXPECT(!! st[~sf1Outer]);
BEAST_EXPECT(!!st[~sf1Outer]);
st[sf2Outer] = 2;
BEAST_EXPECT(st[sf2Outer] == 2);
BEAST_EXPECT(*st[~sf2Outer] == 2);
BEAST_EXPECT(!! st[~sf2Outer]);
BEAST_EXPECT(!!st[~sf2Outer]);
st[~sf2Outer] = boost::none;
except([&]() { return *st[~sf2Outer]; });
BEAST_EXPECT(! st[~sf2Outer]);
BEAST_EXPECT(!st[~sf2Outer]);
st[sf3Outer] = 3;
BEAST_EXPECT(st[sf3Outer] == 3);
BEAST_EXPECT(*st[~sf3Outer] == 3);
BEAST_EXPECT(!! st[~sf3Outer]);
BEAST_EXPECT(!!st[~sf3Outer]);
st[sf3Outer] = 2;
BEAST_EXPECT(st[sf3Outer] == 2);
BEAST_EXPECT(*st[~sf3Outer] == 2);
BEAST_EXPECT(!! st[~sf3Outer]);
BEAST_EXPECT(!!st[~sf3Outer]);
st[sf3Outer] = 0;
BEAST_EXPECT(st[sf3Outer] == 0);
BEAST_EXPECT(*st[~sf3Outer] == 0);
BEAST_EXPECT(!! st[~sf3Outer]);
BEAST_EXPECT(!!st[~sf3Outer]);
except([&]() { st[~sf3Outer] = boost::none; });
BEAST_EXPECT(st[sf3Outer] == 0);
BEAST_EXPECT(*st[~sf3Outer] == 0);
BEAST_EXPECT(!! st[~sf3Outer]);
BEAST_EXPECT(!!st[~sf3Outer]);
}
// coercion operator to boost::optional
@@ -548,9 +550,11 @@ public:
{
STObject st(sfGeneric);
auto const v = ~st[~sf1Outer];
static_assert(std::is_same<
std::decay_t<decltype(v)>,
boost::optional<std::uint32_t>>::value, "");
static_assert(
std::is_same<
std::decay_t<decltype(v)>,
boost::optional<std::uint32_t>>::value,
"");
}
// UDT scalar fields
@@ -560,163 +564,162 @@ public:
st[sfAmount] = STAmount{};
st[sfAccount] = AccountID{};
st[sfDigest] = uint256{};
[&](STAmount){}(st[sfAmount]);
[&](AccountID){}(st[sfAccount]);
[&](uint256){}(st[sfDigest]);
[&](STAmount) {}(st[sfAmount]);
[&](AccountID) {}(st[sfAccount]);
[&](uint256) {}(st[sfDigest]);
}
// STBlob and slice
{
{
STObject st(sfGeneric);
Buffer b(1);
BEAST_EXPECT(! b.empty());
st[sf4] = std::move(b);
BEAST_EXPECT(b.empty());
BEAST_EXPECT(Slice(st[sf4]).size() == 1);
st[~sf4] = boost::none;
BEAST_EXPECT(! ~st[~sf4]);
b = Buffer{2};
st[sf4] = Slice(b);
BEAST_EXPECT(b.size() == 2);
BEAST_EXPECT(Slice(st[sf4]).size() == 2);
st[sf5] = st[sf4];
BEAST_EXPECT(Slice(st[sf4]).size() == 2);
BEAST_EXPECT(Slice(st[sf5]).size() == 2);
}
{
STObject st(sotOuter, sfGeneric);
BEAST_EXPECT(st[sf5] == Slice{});
BEAST_EXPECT(!! st[~sf5]);
BEAST_EXPECT(!! ~st[~sf5]);
Buffer b(1);
st[sf5] = std::move(b);
BEAST_EXPECT(b.empty());
BEAST_EXPECT(Slice(st[sf5]).size() == 1);
st[~sf4] = boost::none;
BEAST_EXPECT(! ~st[~sf4]);
}
}
{{STObject st(sfGeneric);
Buffer b(1);
BEAST_EXPECT(!b.empty());
st[sf4] = std::move(b);
BEAST_EXPECT(b.empty());
BEAST_EXPECT(Slice(st[sf4]).size() == 1);
st[~sf4] = boost::none;
BEAST_EXPECT(!~st[~sf4]);
b = Buffer{2};
st[sf4] = Slice(b);
BEAST_EXPECT(b.size() == 2);
BEAST_EXPECT(Slice(st[sf4]).size() == 2);
st[sf5] = st[sf4];
BEAST_EXPECT(Slice(st[sf4]).size() == 2);
BEAST_EXPECT(Slice(st[sf5]).size() == 2);
}
{
STObject st(sotOuter, sfGeneric);
BEAST_EXPECT(st[sf5] == Slice{});
BEAST_EXPECT(!!st[~sf5]);
BEAST_EXPECT(!!~st[~sf5]);
Buffer b(1);
st[sf5] = std::move(b);
BEAST_EXPECT(b.empty());
BEAST_EXPECT(Slice(st[sf5]).size() == 1);
st[~sf4] = boost::none;
BEAST_EXPECT(!~st[~sf4]);
}
}
// UDT blobs
// UDT blobs
{
STObject st(sfGeneric);
BEAST_EXPECT(! st[~sf5]);
auto const kp = generateKeyPair(
KeyType::secp256k1,
generateSeed("masterpassphrase"));
st[sf5] = kp.first;
BEAST_EXPECT(st[sf5] != PublicKey{});
st[~sf5] = boost::none;
{
STObject st(sfGeneric);
BEAST_EXPECT(!st[~sf5]);
auto const kp =
generateKeyPair(KeyType::secp256k1, generateSeed("masterpassphrase"));
st[sf5] = kp.first;
BEAST_EXPECT(st[sf5] != PublicKey{});
st[~sf5] = boost::none;
#if 0
pk = st[sf5];
BEAST_EXPECT(pk.size() == 0);
#endif
}
}
// By reference fields
// By reference fields
{
auto const& sf = sfIndexes;
STObject st(sfGeneric);
std::vector<uint256> v;
v.emplace_back(1);
v.emplace_back(2);
st[sf] = v;
st[sf] = std::move(v);
auto const& cst = st;
BEAST_EXPECT(cst[sf].size() == 2);
BEAST_EXPECT(cst[~sf]->size() == 2);
BEAST_EXPECT(cst[sf][0] == 1);
BEAST_EXPECT(cst[sf][1] == 2);
static_assert(std::is_same<decltype(cst[sfIndexes]),
std::vector<uint256> const&>::value, "");
}
{
auto const& sf = sfIndexes;
STObject st(sfGeneric);
std::vector<uint256> v;
v.emplace_back(1);
v.emplace_back(2);
st[sf] = v;
st[sf] = std::move(v);
auto const& cst = st;
BEAST_EXPECT(cst[sf].size() == 2);
BEAST_EXPECT(cst[~sf]->size() == 2);
BEAST_EXPECT(cst[sf][0] == 1);
BEAST_EXPECT(cst[sf][1] == 2);
static_assert(
std::is_same<decltype(cst[sfIndexes]), std::vector<uint256> const&>::
value,
"");
}
// Default by reference field
// Default by reference field
{
auto const& sf1 = sfIndexes;
auto const& sf2 = sfHashes;
auto const& sf3 = sfAmendments;
SOTemplate const sot
{
{ sf1, soeREQUIRED },
{ sf2, soeOPTIONAL },
{ sf3, soeDEFAULT },
};
{
auto const& sf1 = sfIndexes;
auto const& sf2 = sfHashes;
auto const& sf3 = sfAmendments;
SOTemplate const sot{
{sf1, soeREQUIRED},
{sf2, soeOPTIONAL},
{sf3, soeDEFAULT},
};
STObject st(sot, sfGeneric);
auto const& cst(st);
BEAST_EXPECT(cst[sf1].size() == 0);
BEAST_EXPECT(! cst[~sf2]);
BEAST_EXPECT(cst[sf3].size() == 0);
std::vector<uint256> v;
v.emplace_back(1);
st[sf1] = v;
BEAST_EXPECT(cst[sf1].size() == 1);
BEAST_EXPECT(cst[sf1][0] == uint256{1});
st[sf2] = v;
BEAST_EXPECT(cst[sf2].size() == 1);
BEAST_EXPECT(cst[sf2][0] == uint256{1});
st[~sf2] = boost::none;
BEAST_EXPECT(! st[~sf2]);
st[sf3] = v;
BEAST_EXPECT(cst[sf3].size() == 1);
BEAST_EXPECT(cst[sf3][0] == uint256{1});
st[sf3] = std::vector<uint256>{};
BEAST_EXPECT(cst[sf3].size() == 0);
}
}
STObject st(sot, sfGeneric);
auto const& cst(st);
BEAST_EXPECT(cst[sf1].size() == 0);
BEAST_EXPECT(!cst[~sf2]);
BEAST_EXPECT(cst[sf3].size() == 0);
std::vector<uint256> v;
v.emplace_back(1);
st[sf1] = v;
BEAST_EXPECT(cst[sf1].size() == 1);
BEAST_EXPECT(cst[sf1][0] == uint256{1});
st[sf2] = v;
BEAST_EXPECT(cst[sf2].size() == 1);
BEAST_EXPECT(cst[sf2][0] == uint256{1});
st[~sf2] = boost::none;
BEAST_EXPECT(!st[~sf2]);
st[sf3] = v;
BEAST_EXPECT(cst[sf3].size() == 1);
BEAST_EXPECT(cst[sf3][0] == uint256{1});
st[sf3] = std::vector<uint256>{};
BEAST_EXPECT(cst[sf3].size() == 0);
}
} // namespace ripple
void
testMalformed()
void
testMalformed()
{
testcase("Malformed serialized forms");
try
{
testcase ("Malformed serialized forms");
try
{
std::array<std::uint8_t, 7> const payload {
{ 0xe9, 0x12, 0xab, 0xcd, 0x12, 0xfe, 0xdc }};
SerialIter sit{makeSlice(payload)};
auto obj = std::make_shared<STArray>(sit, sfMetadata);
BEAST_EXPECT(!obj);
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(), "Duplicate field detected") == 0);
}
try
{
std::array<std::uint8_t, 3> const payload {{ 0xe2, 0xe1, 0xe2 }};
SerialIter sit{makeSlice(payload)};
auto obj = std::make_shared<STObject>(sit, sfMetadata);
BEAST_EXPECT(!obj);
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(), "Duplicate field detected") == 0);
}
std::array<std::uint8_t, 7> const payload{
{0xe9, 0x12, 0xab, 0xcd, 0x12, 0xfe, 0xdc}};
SerialIter sit{makeSlice(payload)};
auto obj = std::make_shared<STArray>(sit, sfMetadata);
BEAST_EXPECT(!obj);
}
void
run() override
catch (std::exception const& e)
{
// Instantiate a jtx::Env so debugLog writes are exercised.
test::jtx::Env env (*this);
testFields();
testSerialization();
testParseJSONArray();
testParseJSONArrayWithInvalidChildrenObjects();
testParseJSONEdgeCases();
testMalformed();
BEAST_EXPECT(strcmp(e.what(), "Duplicate field detected") == 0);
}
};
BEAST_DEFINE_TESTSUITE(STObject,protocol,ripple);
try
{
std::array<std::uint8_t, 3> const payload{{0xe2, 0xe1, 0xe2}};
SerialIter sit{makeSlice(payload)};
auto obj = std::make_shared<STObject>(sit, sfMetadata);
BEAST_EXPECT(!obj);
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(), "Duplicate field detected") == 0);
}
}
} // ripple
void
run() override
{
// Instantiate a jtx::Env so debugLog writes are exercised.
test::jtx::Env env(*this);
testFields();
testSerialization();
testParseJSONArray();
testParseJSONArrayWithInvalidChildrenObjects();
testParseJSONEdgeCases();
testMalformed();
}
}
;
BEAST_DEFINE_TESTSUITE(STObject, protocol, ripple);
} // ripple

File diff suppressed because it is too large Load Diff

View File

@@ -18,12 +18,12 @@
//==============================================================================
#include <ripple/basics/Log.h>
#include <ripple/protocol/jss.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/st.h>
#include <ripple/beast/unit_test.h>
#include <ripple/json/json_reader.h>
#include <ripple/json/to_string.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/jss.h>
#include <ripple/protocol/st.h>
#include <test/jtx.h>
#include <memory>
@@ -34,87 +34,78 @@ namespace ripple {
class STValidation_test : public beast::unit_test::suite
{
public:
void testDeserialization ()
void
testDeserialization()
{
testcase ("Deserialization");
testcase("Deserialization");
constexpr std::uint8_t payload1[] =
{
constexpr std::uint8_t payload1[] = {
// specifies an Ed25519 public key.
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x51,
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, 0x2a, 0x73,
0x21, 0xed, 0x78, 0x00, 0xe6, 0x73, 0x00, 0x72, 0x00, 0x3c, 0x00,
0x00, 0x00, 0x88, 0x00, 0xe6, 0x73, 0x38, 0x00, 0x00, 0x8a, 0x00,
0x88, 0x4e, 0x31, 0x30, 0x5f, 0x5f, 0x63, 0x78, 0x78, 0x61, 0x62,
0x69
};
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00,
0x51, 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, 0x2a, 0x73, 0x21, 0xed, 0x78, 0x00, 0xe6, 0x73,
0x00, 0x72, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x88, 0x00, 0xe6,
0x73, 0x38, 0x00, 0x00, 0x8a, 0x00, 0x88, 0x4e, 0x31, 0x30,
0x5f, 0x5f, 0x63, 0x78, 0x78, 0x61, 0x62, 0x69};
constexpr std::uint8_t payload2[] =
{
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x51,
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, 0x2a, 0x73,
0x21, 0xed, 0xff, 0x03, 0x1c, 0xbe, 0x65, 0x22, 0x61, 0x9c, 0x5e,
0x13, 0x12, 0x00, 0x3b, 0x43, 0x00, 0x00, 0x00, 0xf7, 0x3f, 0x3f,
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x13, 0x13, 0x13, 0x3a, 0x27,
0xff
};
constexpr std::uint8_t payload2[] = {
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00,
0x51, 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, 0x2a, 0x73, 0x21, 0xed, 0xff, 0x03, 0x1c, 0xbe,
0x65, 0x22, 0x61, 0x9c, 0x5e, 0x13, 0x12, 0x00, 0x3b, 0x43,
0x00, 0x00, 0x00, 0xf7, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
0x3f, 0x3f, 0x13, 0x13, 0x13, 0x3a, 0x27, 0xff};
constexpr std::uint8_t payload3[] =
{
constexpr std::uint8_t payload3[] = {
// Has no public key at all
0x22, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x51,
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, 0x2a
};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a};
try
{
SerialIter sit {payload1};
auto stx = std::make_shared<ripple::STValidation>(sit,
[](PublicKey const& pk) {
return calcNodeID(pk);
}, false);
SerialIter sit{payload1};
auto stx = std::make_shared<ripple::STValidation>(
sit, [](PublicKey const& pk) { return calcNodeID(pk); }, false);
fail("An exception should have been thrown");
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(),
"Invalid public key in validation") == 0);
BEAST_EXPECT(
strcmp(e.what(), "Invalid public key in validation") == 0);
}
try
{
SerialIter sit {payload2};
auto stx = std::make_shared<ripple::STValidation>(sit,
[](PublicKey const& pk) {
return calcNodeID(pk);
}, false);
SerialIter sit{payload2};
auto stx = std::make_shared<ripple::STValidation>(
sit, [](PublicKey const& pk) { return calcNodeID(pk); }, false);
fail("An exception should have been thrown");
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(),
"Invalid public key in validation") == 0);
BEAST_EXPECT(
strcmp(e.what(), "Invalid public key in validation") == 0);
}
try
{
SerialIter sit {payload3};
auto stx = std::make_shared<ripple::STValidation>(sit,
[](PublicKey const& pk) {
return calcNodeID(pk);
}, false);
SerialIter sit{payload3};
auto stx = std::make_shared<ripple::STValidation>(
sit, [](PublicKey const& pk) { return calcNodeID(pk); }, false);
fail("An exception should have been thrown");
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(),
"Field 'SigningPubKey' is required but missing.") == 0);
BEAST_EXPECT(
strcmp(
e.what(),
"Field 'SigningPubKey' is required but missing.") == 0);
}
}
@@ -125,6 +116,6 @@ public:
}
};
BEAST_DEFINE_TESTSUITE(STValidation,protocol,ripple);
BEAST_DEFINE_TESTSUITE(STValidation, protocol, ripple);
} // ripple
} // namespace ripple

View File

@@ -17,12 +17,12 @@
*/
//==============================================================================
#include <ripple/beast/unit_test.h>
#include <ripple/beast/utility/rngfill.h>
#include <ripple/crypto/csprng.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/Seed.h>
#include <ripple/beast/unit_test.h>
#include <ripple/beast/utility/rngfill.h>
#include <algorithm>
#include <string>
#include <vector>
@@ -37,73 +37,69 @@ public:
using blob = std::vector<std::uint8_t>;
template <class FwdIter, class Container>
static
void
hex_to_binary (FwdIter first, FwdIter last, Container& out)
static void
hex_to_binary(FwdIter first, FwdIter last, Container& out)
{
struct Table
{
int val[256];
Table ()
Table()
{
std::fill (val, val+256, 0);
std::fill(val, val + 256, 0);
for (int i = 0; i < 10; ++i)
val ['0'+i] = i;
val['0' + i] = i;
for (int i = 0; i < 6; ++i)
{
val ['A'+i] = 10 + i;
val ['a'+i] = 10 + i;
val['A' + i] = 10 + i;
val['a' + i] = 10 + i;
}
}
int operator[] (int i)
int
operator[](int i)
{
return val[i];
return val[i];
}
};
static Table lut;
out.reserve (std::distance (first, last) / 2);
out.reserve(std::distance(first, last) / 2);
while (first != last)
{
auto const hi (lut[(*first++)]);
auto const lo (lut[(*first++)]);
out.push_back ((hi*16)+lo);
auto const hi(lut[(*first++)]);
auto const lo(lut[(*first++)]);
out.push_back((hi * 16) + lo);
}
}
static
uint256
static uint256
hex_to_digest(std::string const& s)
{
blob b;
hex_to_binary (s.begin (), s.end (), b);
hex_to_binary(s.begin(), s.end(), b);
return uint256{b};
}
static
PublicKey
static PublicKey
hex_to_pk(std::string const& s)
{
blob b;
hex_to_binary (s.begin (), s.end (), b);
hex_to_binary(s.begin(), s.end(), b);
return PublicKey{Slice{b.data(), b.size()}};
}
static
SecretKey
static SecretKey
hex_to_sk(std::string const& s)
{
blob b;
hex_to_binary (s.begin (), s.end (), b);
hex_to_binary(s.begin(), s.end(), b);
return SecretKey{Slice{b.data(), b.size()}};
}
static
Buffer
static Buffer
hex_to_sig(std::string const& s)
{
blob b;
hex_to_binary (s.begin (), s.end (), b);
hex_to_binary(s.begin(), s.end(), b);
return Buffer{Slice{b.data(), b.size()}};
}
@@ -181,16 +177,26 @@ public:
void
testCanonicality()
{
testcase ("secp256k1 canonicality");
testcase("secp256k1 canonicality");
#if 0
makeCanonicalityTestVectors();
#else
auto const digest = hex_to_digest("34C19028C80D21F3F48C9354895F8D5BF0D5EE7FF457647CF655F5530A3022A7");
auto const pk = hex_to_pk("025096EB12D3E924234E7162369C11D8BF877EDA238778E7A31FF0AAC5D0DBCF37");
auto const sk = hex_to_sk("AA921417E7E5C299DA4EEC16D1CAA92F19B19F2A68511F68EC73BBB2F5236F3D");
auto const sig = hex_to_sig("3045022100B49D07F0E934BA468C0EFC78117791408D1FB8B63A6492AD395AC2F360F246600220508739DB0A2EF81676E39F459C8BBB07A09C3E9F9BEB696294D524D479D62740");
auto const non = hex_to_sig("3046022100B49D07F0E934BA468C0EFC78117791408D1FB8B63A6492AD395AC2F360F24660022100AF78C624F5D107E9891C60BA637444F71A129E47135D36D92AFD39B856601A01");
auto const digest = hex_to_digest(
"34C19028C80D21F3F48C9354895F8D5BF0D5EE7FF457647CF655F5530A3022A7");
auto const pk = hex_to_pk(
"025096EB12D3E924234E7162369C11D8BF877EDA238778E7A31FF0AAC5D0DBCF3"
"7");
auto const sk = hex_to_sk(
"AA921417E7E5C299DA4EEC16D1CAA92F19B19F2A68511F68EC73BBB2F5236F3D");
auto const sig = hex_to_sig(
"3045022100B49D07F0E934BA468C0EFC78117791408D1FB8B63A6492AD395AC2F3"
"60F246600220508739DB0A2EF81676E39F459C8BBB07A09C3E9F9BEB696294D524"
"D479D62740");
auto const non = hex_to_sig(
"3046022100B49D07F0E934BA468C0EFC78117791408D1FB8B63A6492AD395AC2F3"
"60F24660022100AF78C624F5D107E9891C60BA637444F71A129E47135D36D92AFD"
"39B856601A01");
{
auto const canonicality = ecdsaCanonicality(sig);
@@ -207,118 +213,103 @@ public:
BEAST_EXPECT(verifyDigest(pk, digest, sig, false));
BEAST_EXPECT(verifyDigest(pk, digest, sig, true));
BEAST_EXPECT(verifyDigest(pk, digest, non, false));
BEAST_EXPECT(! verifyDigest(pk, digest, non, true));
BEAST_EXPECT(!verifyDigest(pk, digest, non, true));
#endif
}
void testDigestSigning()
void
testDigestSigning()
{
testcase ("secp256k1 digest");
testcase("secp256k1 digest");
for (std::size_t i = 0; i < 32; i++)
{
auto const [pk, sk] = randomKeyPair (KeyType::secp256k1);
auto const [pk, sk] = randomKeyPair(KeyType::secp256k1);
BEAST_EXPECT(pk == derivePublicKey (KeyType::secp256k1, sk));
BEAST_EXPECT(*publicKeyType (pk) == KeyType::secp256k1);
BEAST_EXPECT(pk == derivePublicKey(KeyType::secp256k1, sk));
BEAST_EXPECT(*publicKeyType(pk) == KeyType::secp256k1);
for (std::size_t j = 0; j < 32; j++)
{
uint256 digest;
beast::rngfill (
digest.data(),
digest.size(),
crypto_prng());
beast::rngfill(digest.data(), digest.size(), crypto_prng());
auto sig = signDigest (
pk, sk, digest);
auto sig = signDigest(pk, sk, digest);
BEAST_EXPECT(sig.size() != 0);
BEAST_EXPECT(verifyDigest (pk,
digest, sig, true));
BEAST_EXPECT(verifyDigest(pk, digest, sig, true));
// Wrong digest:
BEAST_EXPECT(!verifyDigest (pk,
~digest, sig, true));
BEAST_EXPECT(!verifyDigest(pk, ~digest, sig, true));
// Slightly change the signature:
if (auto ptr = sig.data())
ptr[j % sig.size()]++;
// Wrong signature:
BEAST_EXPECT(!verifyDigest (pk,
digest, sig, true));
BEAST_EXPECT(!verifyDigest(pk, digest, sig, true));
// Wrong digest and signature:
BEAST_EXPECT(!verifyDigest (pk,
~digest, sig, true));
BEAST_EXPECT(!verifyDigest(pk, ~digest, sig, true));
}
}
}
void testSigning (KeyType type)
void
testSigning(KeyType type)
{
for (std::size_t i = 0; i < 32; i++)
{
auto const [pk, sk] = randomKeyPair (type);
auto const [pk, sk] = randomKeyPair(type);
BEAST_EXPECT(pk == derivePublicKey (type, sk));
BEAST_EXPECT(*publicKeyType (pk) == type);
BEAST_EXPECT(pk == derivePublicKey(type, sk));
BEAST_EXPECT(*publicKeyType(pk) == type);
for (std::size_t j = 0; j < 32; j++)
{
std::vector<std::uint8_t> data (64 + (8 * i) + j);
beast::rngfill (
data.data(),
data.size(),
crypto_prng());
std::vector<std::uint8_t> data(64 + (8 * i) + j);
beast::rngfill(data.data(), data.size(), crypto_prng());
auto sig = sign (
pk, sk,
makeSlice (data));
auto sig = sign(pk, sk, makeSlice(data));
BEAST_EXPECT(sig.size() != 0);
BEAST_EXPECT(verify(pk,
makeSlice(data), sig, true));
BEAST_EXPECT(verify(pk, makeSlice(data), sig, true));
// Construct wrong data:
auto badData = data;
// swaps the smallest and largest elements in buffer
std::iter_swap (
std::min_element (badData.begin(), badData.end()),
std::max_element (badData.begin(), badData.end()));
std::iter_swap(
std::min_element(badData.begin(), badData.end()),
std::max_element(badData.begin(), badData.end()));
// Wrong data: should fail
BEAST_EXPECT(!verify (pk,
makeSlice(badData), sig, true));
BEAST_EXPECT(!verify(pk, makeSlice(badData), sig, true));
// Slightly change the signature:
if (auto ptr = sig.data())
ptr[j % sig.size()]++;
// Wrong signature: should fail
BEAST_EXPECT(!verify (pk,
makeSlice(data), sig, true));
BEAST_EXPECT(!verify(pk, makeSlice(data), sig, true));
// Wrong data and signature: should fail
BEAST_EXPECT(!verify (pk,
makeSlice(badData), sig, true));
BEAST_EXPECT(!verify(pk, makeSlice(badData), sig, true));
}
}
}
void testBase58 ()
void
testBase58()
{
testcase ("Base58");
testcase("Base58");
// Ensure that parsing some well-known secret keys works
{
auto const sk1 = generateSecretKey (
KeyType::secp256k1,
generateSeed ("masterpassphrase"));
auto const sk1 = generateSecretKey(
KeyType::secp256k1, generateSeed("masterpassphrase"));
auto const sk2 = parseBase58<SecretKey> (
auto const sk2 = parseBase58<SecretKey>(
TokenType::NodePrivate,
"pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe");
BEAST_EXPECT(sk2);
@@ -327,11 +318,10 @@ public:
}
{
auto const sk1 = generateSecretKey (
KeyType::ed25519,
generateSeed ("masterpassphrase"));
auto const sk1 = generateSecretKey(
KeyType::ed25519, generateSeed("masterpassphrase"));
auto const sk2 = parseBase58<SecretKey> (
auto const sk2 = parseBase58<SecretKey>(
TokenType::NodePrivate,
"paKv46LztLqK3GaKz1rG2nQGN6M4JLyRtxFBYFTw4wAVHtGys36");
BEAST_EXPECT(sk2);
@@ -340,13 +330,12 @@ public:
}
// Try converting short, long and malformed data
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, ""));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, " "));
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, "!35gty9mhju8nfjl"));
BEAST_EXPECT(!parseBase58<SecretKey>(TokenType::NodePrivate, ""));
BEAST_EXPECT(!parseBase58<SecretKey>(TokenType::NodePrivate, " "));
BEAST_EXPECT(!parseBase58<SecretKey>(
TokenType::NodePrivate, "!35gty9mhju8nfjl"));
auto const good = toBase58 (
TokenType::NodePrivate,
randomSecretKey());
auto const good = toBase58(TokenType::NodePrivate, randomSecretKey());
// Short (non-empty) strings
{
@@ -357,8 +346,9 @@ public:
while (!s.empty())
{
s.erase (r(s) % s.size(), 1);
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
s.erase(r(s) % s.size(), 1);
BEAST_EXPECT(
!parseBase58<SecretKey>(TokenType::NodePrivate, s));
}
}
@@ -366,18 +356,19 @@ public:
for (std::size_t i = 1; i != 16; i++)
{
auto s = good;
s.resize (s.size() + i, s[i % s.size()]);
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
s.resize(s.size() + i, s[i % s.size()]);
BEAST_EXPECT(!parseBase58<SecretKey>(TokenType::NodePrivate, s));
}
// Strings with invalid Base58 characters
for (auto c : std::string ("0IOl"))
for (auto c : std::string("0IOl"))
{
for (std::size_t i = 0; i != good.size(); ++i)
{
auto s = good;
s[i % s.size()] = c;
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
BEAST_EXPECT(
!parseBase58<SecretKey>(TokenType::NodePrivate, s));
}
}
@@ -388,39 +379,35 @@ public:
for (auto c : std::string("ansrJqtv7"))
{
s[0] = c;
BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
BEAST_EXPECT(
!parseBase58<SecretKey>(TokenType::NodePrivate, s));
}
}
// Try some random secret keys
std::array <SecretKey, 32> keys;
std::array<SecretKey, 32> keys;
for (std::size_t i = 0; i != keys.size(); ++i)
keys[i] = randomSecretKey();
for (std::size_t i = 0; i != keys.size(); ++i)
{
auto const si = toBase58 (
TokenType::NodePrivate,
keys[i]);
auto const si = toBase58(TokenType::NodePrivate, keys[i]);
BEAST_EXPECT(!si.empty());
auto const ski = parseBase58<SecretKey> (
TokenType::NodePrivate, si);
auto const ski = parseBase58<SecretKey>(TokenType::NodePrivate, si);
BEAST_EXPECT(ski && keys[i] == *ski);
for (std::size_t j = i; j != keys.size(); ++j)
{
BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
auto const sj = toBase58 (
TokenType::NodePrivate,
keys[j]);
auto const sj = toBase58(TokenType::NodePrivate, keys[j]);
BEAST_EXPECT((si == sj) == (i == j));
auto const skj = parseBase58<SecretKey> (
TokenType::NodePrivate, sj);
auto const skj =
parseBase58<SecretKey>(TokenType::NodePrivate, sj);
BEAST_EXPECT(skj && keys[j] == *skj);
BEAST_EXPECT((*ski == *skj) == (i == j));
@@ -428,15 +415,15 @@ public:
}
}
void testMiscOperations ()
void
testMiscOperations()
{
testcase ("Miscellaneous operations");
testcase("Miscellaneous operations");
auto const sk1 = generateSecretKey (
KeyType::secp256k1,
generateSeed ("masterpassphrase"));
auto const sk1 = generateSecretKey(
KeyType::secp256k1, generateSeed("masterpassphrase"));
SecretKey sk2 (sk1);
SecretKey sk2(sk1);
BEAST_EXPECT(sk1 == sk2);
SecretKey sk3;
@@ -445,21 +432,22 @@ public:
BEAST_EXPECT(sk3 == sk2);
}
void run() override
void
run() override
{
testBase58();
testDigestSigning();
testMiscOperations();
testCanonicality();
testcase ("secp256k1");
testcase("secp256k1");
testSigning(KeyType::secp256k1);
testcase ("ed25519");
testcase("ed25519");
testSigning(KeyType::ed25519);
}
};
BEAST_DEFINE_TESTSUITE(SecretKey,protocol,ripple);
BEAST_DEFINE_TESTSUITE(SecretKey, protocol, ripple);
} // ripple
} // namespace ripple

View File

@@ -18,82 +18,84 @@
//==============================================================================
#include <ripple/basics/random.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/Seed.h>
#include <ripple/beast/unit_test.h>
#include <ripple/beast/utility/rngfill.h>
#include <ripple/beast/xor_shift_engine.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/Seed.h>
#include <algorithm>
namespace ripple {
class Seed_test : public beast::unit_test::suite
{
static
bool equal(Seed const& lhs, Seed const& rhs)
static bool
equal(Seed const& lhs, Seed const& rhs)
{
return std::equal (
lhs.data(), lhs.data() + lhs.size(),
rhs.data(), rhs.data() + rhs.size());
return std::equal(
lhs.data(),
lhs.data() + lhs.size(),
rhs.data(),
rhs.data() + rhs.size());
}
public:
void testConstruction ()
void
testConstruction()
{
testcase ("construction");
testcase("construction");
{
std::uint8_t src[16];
for (std::uint8_t i = 0; i < 64; i++)
{
beast::rngfill (
src,
sizeof(src),
default_prng());
Seed const seed ({ src, sizeof(src) });
BEAST_EXPECT(memcmp (seed.data(), src, sizeof(src)) == 0);
beast::rngfill(src, sizeof(src), default_prng());
Seed const seed({src, sizeof(src)});
BEAST_EXPECT(memcmp(seed.data(), src, sizeof(src)) == 0);
}
}
for (int i = 0; i < 64; i++)
{
uint128 src;
beast::rngfill (
src.data(),
src.size(),
default_prng());
Seed const seed (src);
BEAST_EXPECT(memcmp (seed.data(), src.data(), src.size()) == 0);
beast::rngfill(src.data(), src.size(), default_prng());
Seed const seed(src);
BEAST_EXPECT(memcmp(seed.data(), src.data(), src.size()) == 0);
}
}
std::string testPassphrase(std::string passphrase)
std::string
testPassphrase(std::string passphrase)
{
auto const seed1 = generateSeed (passphrase);
auto const seed1 = generateSeed(passphrase);
auto const seed2 = parseBase58<Seed>(toBase58(seed1));
BEAST_EXPECT(static_cast<bool>(seed2));
BEAST_EXPECT(equal (seed1, *seed2));
BEAST_EXPECT(equal(seed1, *seed2));
return toBase58(seed1);
}
void testPassphrase()
void
testPassphrase()
{
testcase ("generation from passphrase");
BEAST_EXPECT(testPassphrase ("masterpassphrase") ==
testcase("generation from passphrase");
BEAST_EXPECT(
testPassphrase("masterpassphrase") ==
"snoPBrXtMeMyMHUVTgbuqAfg1SUTb");
BEAST_EXPECT(testPassphrase ("Non-Random Passphrase") ==
BEAST_EXPECT(
testPassphrase("Non-Random Passphrase") ==
"snMKnVku798EnBwUfxeSD8953sLYA");
BEAST_EXPECT(testPassphrase ("cookies excitement hand public") ==
BEAST_EXPECT(
testPassphrase("cookies excitement hand public") ==
"sspUXGrmjQhq6mgc24jiRuevZiwKT");
}
void testBase58()
void
testBase58()
{
testcase ("base58 operations");
testcase("base58 operations");
// Success:
BEAST_EXPECT(parseBase58<Seed>("snoPBrXtMeMyMHUVTgbuqAfg1SUTb"));
@@ -108,56 +110,60 @@ public:
BEAST_EXPECT(!parseBase58<Seed>("ssp/XGrmjQhq6mgc24jiRuevZiwKT"));
}
void testRandom()
void
testRandom()
{
testcase ("random generation");
testcase("random generation");
for (int i = 0; i < 32; i++)
{
auto const seed1 = randomSeed ();
auto const seed1 = randomSeed();
auto const seed2 = parseBase58<Seed>(toBase58(seed1));
BEAST_EXPECT(static_cast<bool>(seed2));
BEAST_EXPECT(equal (seed1, *seed2));
BEAST_EXPECT(equal(seed1, *seed2));
}
}
void testKeypairGenerationAndSigning ()
void
testKeypairGenerationAndSigning()
{
std::string const message1 = "http://www.ripple.com";
std::string const message2 = "https://www.ripple.com";
{
testcase ("Node keypair generation & signing (secp256k1)");
testcase("Node keypair generation & signing (secp256k1)");
auto const secretKey = generateSecretKey (
KeyType::secp256k1, generateSeed ("masterpassphrase"));
auto const publicKey = derivePublicKey (
KeyType::secp256k1, secretKey);
auto const secretKey = generateSecretKey(
KeyType::secp256k1, generateSeed("masterpassphrase"));
auto const publicKey =
derivePublicKey(KeyType::secp256k1, secretKey);
BEAST_EXPECT(toBase58(TokenType::NodePublic, publicKey) ==
BEAST_EXPECT(
toBase58(TokenType::NodePublic, publicKey) ==
"n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
BEAST_EXPECT(toBase58(TokenType::NodePrivate, secretKey) ==
BEAST_EXPECT(
toBase58(TokenType::NodePrivate, secretKey) ==
"pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe");
BEAST_EXPECT(to_string(calcNodeID(publicKey)) ==
BEAST_EXPECT(
to_string(calcNodeID(publicKey)) ==
"7E59C17D50F5959C7B158FEC95C8F815BF653DC8");
auto sig = sign (publicKey, secretKey, makeSlice(message1));
auto sig = sign(publicKey, secretKey, makeSlice(message1));
BEAST_EXPECT(sig.size() != 0);
BEAST_EXPECT(verify (publicKey, makeSlice(message1), sig));
BEAST_EXPECT(verify(publicKey, makeSlice(message1), sig));
// Correct public key but wrong message
BEAST_EXPECT(!verify (publicKey, makeSlice(message2), sig));
BEAST_EXPECT(!verify(publicKey, makeSlice(message2), sig));
// Verify with incorrect public key
{
auto const otherPublicKey = derivePublicKey (
auto const otherPublicKey = derivePublicKey(
KeyType::secp256k1,
generateSecretKey (
KeyType::secp256k1,
generateSeed ("otherpassphrase")));
generateSecretKey(
KeyType::secp256k1, generateSeed("otherpassphrase")));
BEAST_EXPECT(!verify (otherPublicKey, makeSlice(message1), sig));
BEAST_EXPECT(!verify(otherPublicKey, makeSlice(message1), sig));
}
// Correct public key but wrong signature
@@ -166,41 +172,42 @@ public:
if (auto ptr = sig.data())
ptr[sig.size() / 2]++;
BEAST_EXPECT(!verify (publicKey, makeSlice(message1), sig));
BEAST_EXPECT(!verify(publicKey, makeSlice(message1), sig));
}
}
{
testcase ("Node keypair generation & signing (ed25519)");
testcase("Node keypair generation & signing (ed25519)");
auto const secretKey = generateSecretKey (
KeyType::ed25519, generateSeed ("masterpassphrase"));
auto const publicKey = derivePublicKey (
KeyType::ed25519, secretKey);
auto const secretKey = generateSecretKey(
KeyType::ed25519, generateSeed("masterpassphrase"));
auto const publicKey = derivePublicKey(KeyType::ed25519, secretKey);
BEAST_EXPECT(toBase58(TokenType::NodePublic, publicKey) ==
BEAST_EXPECT(
toBase58(TokenType::NodePublic, publicKey) ==
"nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
BEAST_EXPECT(toBase58(TokenType::NodePrivate, secretKey) ==
BEAST_EXPECT(
toBase58(TokenType::NodePrivate, secretKey) ==
"paKv46LztLqK3GaKz1rG2nQGN6M4JLyRtxFBYFTw4wAVHtGys36");
BEAST_EXPECT(to_string(calcNodeID(publicKey)) ==
BEAST_EXPECT(
to_string(calcNodeID(publicKey)) ==
"AA066C988C712815CC37AF71472B7CBBBD4E2A0A");
auto sig = sign (publicKey, secretKey, makeSlice(message1));
auto sig = sign(publicKey, secretKey, makeSlice(message1));
BEAST_EXPECT(sig.size() != 0);
BEAST_EXPECT(verify (publicKey, makeSlice(message1), sig));
BEAST_EXPECT(verify(publicKey, makeSlice(message1), sig));
// Correct public key but wrong message
BEAST_EXPECT(!verify (publicKey, makeSlice(message2), sig));
BEAST_EXPECT(!verify(publicKey, makeSlice(message2), sig));
// Verify with incorrect public key
{
auto const otherPublicKey = derivePublicKey (
auto const otherPublicKey = derivePublicKey(
KeyType::ed25519,
generateSecretKey (
KeyType::ed25519,
generateSeed ("otherpassphrase")));
generateSecretKey(
KeyType::ed25519, generateSeed("otherpassphrase")));
BEAST_EXPECT(!verify (otherPublicKey, makeSlice(message1), sig));
BEAST_EXPECT(!verify(otherPublicKey, makeSlice(message1), sig));
}
// Correct public key but wrong signature
@@ -209,38 +216,40 @@ public:
if (auto ptr = sig.data())
ptr[sig.size() / 2]++;
BEAST_EXPECT(!verify (publicKey, makeSlice(message1), sig));
BEAST_EXPECT(!verify(publicKey, makeSlice(message1), sig));
}
}
{
testcase ("Account keypair generation & signing (secp256k1)");
testcase("Account keypair generation & signing (secp256k1)");
auto const [pk, sk] = generateKeyPair (
KeyType::secp256k1,
generateSeed ("masterpassphrase"));
auto const [pk, sk] = generateKeyPair(
KeyType::secp256k1, generateSeed("masterpassphrase"));
BEAST_EXPECT(toBase58(calcAccountID(pk)) ==
BEAST_EXPECT(
toBase58(calcAccountID(pk)) ==
"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
BEAST_EXPECT(toBase58(TokenType::AccountPublic, pk) ==
BEAST_EXPECT(
toBase58(TokenType::AccountPublic, pk) ==
"aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw");
BEAST_EXPECT(toBase58(TokenType::AccountSecret, sk) ==
BEAST_EXPECT(
toBase58(TokenType::AccountSecret, sk) ==
"p9JfM6HHi64m6mvB6v5k7G2b1cXzGmYiCNJf6GHPKvFTWdeRVjh");
auto sig = sign (pk, sk, makeSlice(message1));
auto sig = sign(pk, sk, makeSlice(message1));
BEAST_EXPECT(sig.size() != 0);
BEAST_EXPECT(verify (pk, makeSlice(message1), sig));
BEAST_EXPECT(verify(pk, makeSlice(message1), sig));
// Correct public key but wrong message
BEAST_EXPECT(!verify (pk, makeSlice(message2), sig));
BEAST_EXPECT(!verify(pk, makeSlice(message2), sig));
// Verify with incorrect public key
{
auto const otherKeyPair = generateKeyPair (
KeyType::secp256k1,
generateSeed ("otherpassphrase"));
auto const otherKeyPair = generateKeyPair(
KeyType::secp256k1, generateSeed("otherpassphrase"));
BEAST_EXPECT(!verify (otherKeyPair.first, makeSlice(message1), sig));
BEAST_EXPECT(
!verify(otherKeyPair.first, makeSlice(message1), sig));
}
// Correct public key but wrong signature
@@ -249,38 +258,40 @@ public:
if (auto ptr = sig.data())
ptr[sig.size() / 2]++;
BEAST_EXPECT(!verify (pk, makeSlice(message1), sig));
BEAST_EXPECT(!verify(pk, makeSlice(message1), sig));
}
}
{
testcase ("Account keypair generation & signing (ed25519)");
testcase("Account keypair generation & signing (ed25519)");
auto const [pk, sk] = generateKeyPair (
KeyType::ed25519,
generateSeed ("masterpassphrase"));
auto const [pk, sk] = generateKeyPair(
KeyType::ed25519, generateSeed("masterpassphrase"));
BEAST_EXPECT(to_string(calcAccountID(pk)) ==
BEAST_EXPECT(
to_string(calcAccountID(pk)) ==
"rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf");
BEAST_EXPECT(toBase58(TokenType::AccountPublic, pk) ==
BEAST_EXPECT(
toBase58(TokenType::AccountPublic, pk) ==
"aKGheSBjmCsKJVuLNKRAKpZXT6wpk2FCuEZAXJupXgdAxX5THCqR");
BEAST_EXPECT(toBase58(TokenType::AccountSecret, sk) ==
BEAST_EXPECT(
toBase58(TokenType::AccountSecret, sk) ==
"pwDQjwEhbUBmPuEjFpEG75bFhv2obkCB7NxQsfFxM7xGHBMVPu9");
auto sig = sign (pk, sk, makeSlice(message1));
auto sig = sign(pk, sk, makeSlice(message1));
BEAST_EXPECT(sig.size() != 0);
BEAST_EXPECT(verify (pk, makeSlice(message1), sig));
BEAST_EXPECT(verify(pk, makeSlice(message1), sig));
// Correct public key but wrong message
BEAST_EXPECT(!verify (pk, makeSlice(message2), sig));
BEAST_EXPECT(!verify(pk, makeSlice(message2), sig));
// Verify with incorrect public key
{
auto const otherKeyPair = generateKeyPair (
KeyType::ed25519,
generateSeed ("otherpassphrase"));
auto const otherKeyPair = generateKeyPair(
KeyType::ed25519, generateSeed("otherpassphrase"));
BEAST_EXPECT(!verify (otherKeyPair.first, makeSlice(message1), sig));
BEAST_EXPECT(
!verify(otherKeyPair.first, makeSlice(message1), sig));
}
// Correct public key but wrong signature
@@ -289,64 +300,64 @@ public:
if (auto ptr = sig.data())
ptr[sig.size() / 2]++;
BEAST_EXPECT(!verify (pk, makeSlice(message1), sig));
BEAST_EXPECT(!verify(pk, makeSlice(message1), sig));
}
}
}
void testSeedParsing ()
void
testSeedParsing()
{
testcase ("Parsing");
testcase("Parsing");
// account IDs and node and account public and private
// keys should not be parseable as seeds.
auto const node1 = randomKeyPair(KeyType::secp256k1);
BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::NodePublic, node1.first)));
BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::NodePrivate, node1.second)));
BEAST_EXPECT(
!parseGenericSeed(toBase58(TokenType::NodePublic, node1.first)));
BEAST_EXPECT(
!parseGenericSeed(toBase58(TokenType::NodePrivate, node1.second)));
auto const node2 = randomKeyPair(KeyType::ed25519);
BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::NodePublic, node2.first)));
BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::NodePrivate, node2.second)));
BEAST_EXPECT(
!parseGenericSeed(toBase58(TokenType::NodePublic, node2.first)));
BEAST_EXPECT(
!parseGenericSeed(toBase58(TokenType::NodePrivate, node2.second)));
auto const account1 = generateKeyPair(
KeyType::secp256k1, randomSeed ());
auto const account1 = generateKeyPair(KeyType::secp256k1, randomSeed());
BEAST_EXPECT(!parseGenericSeed (
toBase58(calcAccountID(account1.first))));
BEAST_EXPECT(!parseGenericSeed (
BEAST_EXPECT(
!parseGenericSeed(toBase58(calcAccountID(account1.first))));
BEAST_EXPECT(!parseGenericSeed(
toBase58(TokenType::AccountPublic, account1.first)));
BEAST_EXPECT(!parseGenericSeed (
BEAST_EXPECT(!parseGenericSeed(
toBase58(TokenType::AccountSecret, account1.second)));
auto const account2 = generateKeyPair(
KeyType::ed25519, randomSeed ());
auto const account2 = generateKeyPair(KeyType::ed25519, randomSeed());
BEAST_EXPECT(!parseGenericSeed (
toBase58(calcAccountID(account2.first))));
BEAST_EXPECT(!parseGenericSeed (
BEAST_EXPECT(
!parseGenericSeed(toBase58(calcAccountID(account2.first))));
BEAST_EXPECT(!parseGenericSeed(
toBase58(TokenType::AccountPublic, account2.first)));
BEAST_EXPECT(!parseGenericSeed (
BEAST_EXPECT(!parseGenericSeed(
toBase58(TokenType::AccountSecret, account2.second)));
}
void run() override
void
run() override
{
testConstruction();
testPassphrase();
testBase58();
testRandom();
testKeypairGenerationAndSigning();
testSeedParsing ();
testSeedParsing();
}
};
BEAST_DEFINE_TESTSUITE(Seed,protocol,ripple);
BEAST_DEFINE_TESTSUITE(Seed, protocol, ripple);
} // ripple
} // namespace ripple

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#include <ripple/protocol/TER.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/TER.h>
#include <tuple>
#include <type_traits>
@@ -32,12 +32,9 @@ struct TER_test : public beast::unit_test::suite
{
for (auto i = -400; i < 400; ++i)
{
TER t = TER::fromInt (i);
auto inRange = isTelLocal(t) ||
isTemMalformed(t) ||
isTefFailure(t) ||
isTerRetry(t) ||
isTesSuccess(t) ||
TER t = TER::fromInt(i);
auto inRange = isTelLocal(t) || isTemMalformed(t) ||
isTefFailure(t) || isTerRetry(t) || isTesSuccess(t) ||
isTecClaim(t);
std::string token, text;
@@ -59,133 +56,156 @@ struct TER_test : public beast::unit_test::suite
// o Tup is expected to be a tuple.
// It's a functor, rather than a function template, since a class template
// can be a template argument without being full specified.
template<std::size_t I1, std::size_t I2>
template <std::size_t I1, std::size_t I2>
class NotConvertible
{
public:
template<typename Tup>
void operator()(Tup const& tup, beast::unit_test::suite&) const
template <typename Tup>
void
operator()(Tup const& tup, beast::unit_test::suite&) const
{
// Entries in the tuple should not be convertible or assignable
// unless they are the same types.
using To_t = std::decay_t<decltype (std::get<I1>(tup))>;
using From_t = std::decay_t<decltype (std::get<I2>(tup))>;
static_assert (std::is_same<From_t, To_t>::value ==
std::is_convertible<From_t, To_t>::value, "Convert err");
static_assert (std::is_same<To_t, From_t>::value ==
std::is_constructible<To_t, From_t>::value, "Construct err");
static_assert (std::is_same <To_t, From_t>::value ==
std::is_assignable<To_t&, From_t const&>::value, "Assign err");
using To_t = std::decay_t<decltype(std::get<I1>(tup))>;
using From_t = std::decay_t<decltype(std::get<I2>(tup))>;
static_assert(
std::is_same<From_t, To_t>::value ==
std::is_convertible<From_t, To_t>::value,
"Convert err");
static_assert(
std::is_same<To_t, From_t>::value ==
std::is_constructible<To_t, From_t>::value,
"Construct err");
static_assert(
std::is_same<To_t, From_t>::value ==
std::is_assignable<To_t&, From_t const&>::value,
"Assign err");
// Assignment or conversion from integer to type should never work.
static_assert (
! std::is_convertible<int, To_t>::value, "Convert err");
static_assert (
! std::is_constructible<To_t, int>::value, "Construct err");
static_assert (
! std::is_assignable<To_t&, int const&>::value, "Assign err");
static_assert(
!std::is_convertible<int, To_t>::value, "Convert err");
static_assert(
!std::is_constructible<To_t, int>::value, "Construct err");
static_assert(
!std::is_assignable<To_t&, int const&>::value, "Assign err");
}
};
// Fast iteration over the tuple.
template<std::size_t I1, std::size_t I2,
template<std::size_t, std::size_t> class Func, typename Tup>
template <
std::size_t I1,
std::size_t I2,
template <std::size_t, std::size_t>
class Func,
typename Tup>
std::enable_if_t<I1 != 0>
testIterate (Tup const& tup, beast::unit_test::suite& s)
testIterate(Tup const& tup, beast::unit_test::suite& s)
{
Func<I1, I2> func;
func (tup, s);
func(tup, s);
testIterate<I1 - 1, I2, Func>(tup, s);
}
// Slow iteration over the tuple.
template<std::size_t I1, std::size_t I2,
template<std::size_t, std::size_t> class Func, typename Tup>
template <
std::size_t I1,
std::size_t I2,
template <std::size_t, std::size_t>
class Func,
typename Tup>
std::enable_if_t<I1 == 0 && I2 != 0>
testIterate (Tup const& tup, beast::unit_test::suite& s)
testIterate(Tup const& tup, beast::unit_test::suite& s)
{
Func<I1, I2> func;
func (tup, s);
func(tup, s);
testIterate<std::tuple_size<Tup>::value - 1, I2 - 1, Func>(tup, s);
}
// Finish iteration over the tuple.
template<std::size_t I1, std::size_t I2,
template<std::size_t, std::size_t> class Func, typename Tup>
template <
std::size_t I1,
std::size_t I2,
template <std::size_t, std::size_t>
class Func,
typename Tup>
std::enable_if_t<I1 == 0 && I2 == 0>
testIterate (Tup const& tup, beast::unit_test::suite& s)
testIterate(Tup const& tup, beast::unit_test::suite& s)
{
Func<I1, I2> func;
func (tup, s);
func(tup, s);
}
void testConversion()
void
testConversion()
{
// Verify that valid conversions are valid and invalid conversions
// are not valid.
// Examples of each kind of enum.
static auto const terEnums = std::make_tuple (telLOCAL_ERROR,
temMALFORMED, tefFAILURE, terRETRY, tesSUCCESS, tecCLAIM);
static const int hiIndex {
std::tuple_size<decltype (terEnums)>::value - 1};
static auto const terEnums = std::make_tuple(
telLOCAL_ERROR,
temMALFORMED,
tefFAILURE,
terRETRY,
tesSUCCESS,
tecCLAIM);
static const int hiIndex{
std::tuple_size<decltype(terEnums)>::value - 1};
// Verify that enums cannot be converted to other enum types.
testIterate<hiIndex, hiIndex, NotConvertible> (terEnums, *this);
testIterate<hiIndex, hiIndex, NotConvertible>(terEnums, *this);
// Lambda that verifies assignability and convertibility.
auto isConvertable = [] (auto from, auto to)
{
using From_t = std::decay_t<decltype (from)>;
using To_t = std::decay_t<decltype (to)>;
static_assert (
auto isConvertable = [](auto from, auto to) {
using From_t = std::decay_t<decltype(from)>;
using To_t = std::decay_t<decltype(to)>;
static_assert(
std::is_convertible<From_t, To_t>::value, "Convert err");
static_assert (
static_assert(
std::is_constructible<To_t, From_t>::value, "Construct err");
static_assert (
static_assert(
std::is_assignable<To_t&, From_t const&>::value, "Assign err");
};
// Verify the right types convert to NotTEC.
NotTEC const notTec;
isConvertable (telLOCAL_ERROR, notTec);
isConvertable (temMALFORMED, notTec);
isConvertable (tefFAILURE, notTec);
isConvertable (terRETRY, notTec);
isConvertable (tesSUCCESS, notTec);
isConvertable (notTec, notTec);
isConvertable(telLOCAL_ERROR, notTec);
isConvertable(temMALFORMED, notTec);
isConvertable(tefFAILURE, notTec);
isConvertable(terRETRY, notTec);
isConvertable(tesSUCCESS, notTec);
isConvertable(notTec, notTec);
// Lambda that verifies types and not assignable or convertible.
auto notConvertible = [] (auto from, auto to)
{
using To_t = std::decay_t<decltype (to)>;
using From_t = std::decay_t<decltype (from)>;
static_assert (
auto notConvertible = [](auto from, auto to) {
using To_t = std::decay_t<decltype(to)>;
using From_t = std::decay_t<decltype(from)>;
static_assert(
!std::is_convertible<From_t, To_t>::value, "Convert err");
static_assert (
static_assert(
!std::is_constructible<To_t, From_t>::value, "Construct err");
static_assert (
static_assert(
!std::is_assignable<To_t&, From_t const&>::value, "Assign err");
};
// Verify types that shouldn't convert to NotTEC.
TER const ter;
notConvertible (tecCLAIM, notTec);
notConvertible (ter, notTec);
notConvertible (4, notTec);
notConvertible(tecCLAIM, notTec);
notConvertible(ter, notTec);
notConvertible(4, notTec);
// Verify the right types convert to TER.
isConvertable (telLOCAL_ERROR, ter);
isConvertable (temMALFORMED, ter);
isConvertable (tefFAILURE, ter);
isConvertable (terRETRY, ter);
isConvertable (tesSUCCESS, ter);
isConvertable (tecCLAIM, ter);
isConvertable (notTec, ter);
isConvertable (ter, ter);
isConvertable(telLOCAL_ERROR, ter);
isConvertable(temMALFORMED, ter);
isConvertable(tefFAILURE, ter);
isConvertable(terRETRY, ter);
isConvertable(tesSUCCESS, ter);
isConvertable(tecCLAIM, ter);
isConvertable(notTec, ter);
isConvertable(ter, ter);
// Verify that you can't convert from int to ter.
notConvertible (4, ter);
notConvertible(4, ter);
}
// Helper template that makes sure two types are comparable. Also
@@ -195,60 +215,73 @@ struct TER_test : public beast::unit_test::suite
// o Tup is expected to be a tuple.
// It's a functor, rather than a function template, since a class template
// can be a template argument without being full specified.
template<std::size_t I1, std::size_t I2>
template <std::size_t I1, std::size_t I2>
class CheckComparable
{
public:
template<typename Tup>
void operator()(Tup const& tup, beast::unit_test::suite& s) const
template <typename Tup>
void
operator()(Tup const& tup, beast::unit_test::suite& s) const
{
// All entries in the tuple should be comparable one to the other.
auto const lhs = std::get<I1>(tup);
auto const rhs = std::get<I2>(tup);
static_assert (std::is_same<
decltype (operator== (lhs, rhs)), bool>::value, "== err");
static_assert(
std::is_same<decltype(operator==(lhs, rhs)), bool>::value,
"== err");
static_assert (std::is_same<
decltype (operator!= (lhs, rhs)), bool>::value, "!= err");
static_assert(
std::is_same<decltype(operator!=(lhs, rhs)), bool>::value,
"!= err");
static_assert (std::is_same<
decltype (operator< (lhs, rhs)), bool>::value, "< err");
static_assert(
std::is_same<decltype(operator<(lhs, rhs)), bool>::value,
"< err");
static_assert (std::is_same<
decltype (operator<= (lhs, rhs)), bool>::value, "<= err");
static_assert(
std::is_same<decltype(operator<=(lhs, rhs)), bool>::value,
"<= err");
static_assert (std::is_same<
decltype (operator> (lhs, rhs)), bool>::value, "> err");
static_assert(
std::is_same<decltype(operator>(lhs, rhs)), bool>::value,
"> err");
static_assert (std::is_same<
decltype (operator>= (lhs, rhs)), bool>::value, ">= err");
static_assert(
std::is_same<decltype(operator>=(lhs, rhs)), bool>::value,
">= err");
// Make sure a sampling of TER types exhibit the expected behavior
// for all comparison operators.
s.expect ((lhs == rhs) == (TERtoInt (lhs) == TERtoInt (rhs)));
s.expect ((lhs != rhs) == (TERtoInt (lhs) != TERtoInt (rhs)));
s.expect ((lhs < rhs) == (TERtoInt (lhs) < TERtoInt (rhs)));
s.expect ((lhs <= rhs) == (TERtoInt (lhs) <= TERtoInt (rhs)));
s.expect ((lhs > rhs) == (TERtoInt (lhs) > TERtoInt (rhs)));
s.expect ((lhs >= rhs) == (TERtoInt (lhs) >= TERtoInt (rhs)));
s.expect((lhs == rhs) == (TERtoInt(lhs) == TERtoInt(rhs)));
s.expect((lhs != rhs) == (TERtoInt(lhs) != TERtoInt(rhs)));
s.expect((lhs < rhs) == (TERtoInt(lhs) < TERtoInt(rhs)));
s.expect((lhs <= rhs) == (TERtoInt(lhs) <= TERtoInt(rhs)));
s.expect((lhs > rhs) == (TERtoInt(lhs) > TERtoInt(rhs)));
s.expect((lhs >= rhs) == (TERtoInt(lhs) >= TERtoInt(rhs)));
}
};
void testComparison()
void
testComparison()
{
// All of the TER-related types should be comparable.
// Examples of all the types we expect to successfully compare.
static auto const ters = std::make_tuple (telLOCAL_ERROR, temMALFORMED,
tefFAILURE, terRETRY, tesSUCCESS, tecCLAIM,
NotTEC {telLOCAL_ERROR}, TER {tecCLAIM});
static const int hiIndex {
std::tuple_size<decltype (ters)>::value - 1};
static auto const ters = std::make_tuple(
telLOCAL_ERROR,
temMALFORMED,
tefFAILURE,
terRETRY,
tesSUCCESS,
tecCLAIM,
NotTEC{telLOCAL_ERROR},
TER{tecCLAIM});
static const int hiIndex{std::tuple_size<decltype(ters)>::value - 1};
// Verify that all types in the ters tuple can be compared with all
// the other types in ters.
testIterate<hiIndex, hiIndex, CheckComparable> (ters, *this);
testIterate<hiIndex, hiIndex, CheckComparable>(ters, *this);
}
void
@@ -260,6 +293,6 @@ struct TER_test : public beast::unit_test::suite
}
};
BEAST_DEFINE_TESTSUITE(TER,protocol,ripple);
BEAST_DEFINE_TESTSUITE(TER, protocol, ripple);
} //namespace ripple
} // namespace ripple

View File

@@ -17,10 +17,10 @@
*/
//==============================================================================
#include <ripple/protocol/digest.h>
#include <ripple/beast/unit_test.h>
#include <ripple/beast/utility/rngfill.h>
#include <ripple/beast/xor_shift_engine.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/digest.h>
#include <algorithm>
#include <array>
#include <chrono>
@@ -35,7 +35,8 @@ class digest_test : public beast::unit_test::suite
std::vector<uint256> dataset1;
template <class Hasher>
void test (char const* name)
void
test(char const* name)
{
using namespace std::chrono;
@@ -45,8 +46,8 @@ class digest_test : public beast::unit_test::suite
for (auto const& x : dataset1)
{
Hasher h;
h (x.data (), x.size ());
(void) static_cast<typename Hasher::result_type>(h);
h(x.data(), x.size());
(void)static_cast<typename Hasher::result_type>(h);
}
}
@@ -54,109 +55,106 @@ class digest_test : public beast::unit_test::suite
for (auto& result : results)
{
auto const start = high_resolution_clock::now ();
auto const start = high_resolution_clock::now();
for (auto const& x : dataset1)
{
Hasher h;
h (x.data (), x.size ());
(void) static_cast<typename Hasher::result_type>(h);
h(x.data(), x.size());
(void)static_cast<typename Hasher::result_type>(h);
}
auto const d = high_resolution_clock::now () - start;
auto const d = high_resolution_clock::now() - start;
result = d;
}
log << " " << name << ":" << '\n';
auto const sum = std::accumulate(
results.begin(), results.end(),
nanoseconds{0});
auto const sum =
std::accumulate(results.begin(), results.end(), nanoseconds{0});
{
auto s = duration_cast<seconds>(sum);
auto ms = duration_cast<milliseconds>(sum) - s;
log <<
" Total Time = " << s.count() <<
"." << ms.count() << " seconds" << std::endl;
log << " Total Time = " << s.count() << "." << ms.count()
<< " seconds" << std::endl;
}
auto const mean = sum / results.size();
{
auto s = duration_cast<seconds>(mean);
auto ms = duration_cast<milliseconds>(mean) - s;
log <<
" Mean Time = " << s.count() <<
"." << ms.count() << " seconds" << std::endl;
log << " Mean Time = " << s.count() << "." << ms.count()
<< " seconds" << std::endl;
}
std::vector<nanoseconds::rep> diff(results.size());
std::transform(
results.begin(), results.end(), diff.begin(),
[&mean](nanoseconds trial)
{
return (trial - mean).count();
});
auto const sq_sum = std::inner_product(
diff.begin(), diff.end(), diff.begin(), 0.0);
results.begin(),
results.end(),
diff.begin(),
[&mean](nanoseconds trial) { return (trial - mean).count(); });
auto const sq_sum =
std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
{
nanoseconds const stddev {
static_cast<nanoseconds::rep>(
std::sqrt(sq_sum / results.size()))
};
nanoseconds const stddev{static_cast<nanoseconds::rep>(
std::sqrt(sq_sum / results.size()))};
auto s = duration_cast<seconds>(stddev);
auto ms = duration_cast<milliseconds>(stddev) - s;
log <<
" Std Dev = " << s.count() <<
"." << ms.count() << " seconds" << std::endl;
log << " Std Dev = " << s.count() << "." << ms.count()
<< " seconds" << std::endl;
}
}
public:
digest_test ()
digest_test()
{
beast::xor_shift_engine g(19207813);
std::array<std::uint8_t, 32> buf;
for (int i = 0; i < 1000000; i++)
{
beast::rngfill (buf.data(), buf.size(), g);
dataset1.push_back (uint256{buf});
beast::rngfill(buf.data(), buf.size(), g);
dataset1.push_back(uint256{buf});
}
}
void testSHA512 ()
void
testSHA512()
{
testcase ("SHA512");
test<openssl_ripemd160_hasher> ("OpenSSL");
test<beast::ripemd160_hasher> ("Beast");
pass ();
testcase("SHA512");
test<openssl_ripemd160_hasher>("OpenSSL");
test<beast::ripemd160_hasher>("Beast");
pass();
}
void testSHA256 ()
void
testSHA256()
{
testcase ("SHA256");
test<openssl_sha256_hasher> ("OpenSSL");
test<beast::sha256_hasher> ("Beast");
pass ();
testcase("SHA256");
test<openssl_sha256_hasher>("OpenSSL");
test<beast::sha256_hasher>("Beast");
pass();
}
void testRIPEMD160 ()
void
testRIPEMD160()
{
testcase ("RIPEMD160");
test<openssl_ripemd160_hasher> ("OpenSSL");
test<beast::ripemd160_hasher> ("Beast");
pass ();
testcase("RIPEMD160");
test<openssl_ripemd160_hasher>("OpenSSL");
test<beast::ripemd160_hasher>("Beast");
pass();
}
void run () override
void
run() override
{
testSHA512 ();
testSHA256 ();
testRIPEMD160 ();
testSHA512();
testSHA256();
testRIPEMD160();
}
};
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(digest,ripple_data,ripple,20);
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(digest, ripple_data, ripple, 20);
} // ripple
} // namespace ripple

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#include <ripple/protocol/UintTypes.h>
#include <ripple/beast/unit_test.h>
#include <ripple/protocol/UintTypes.h>
namespace ripple {
@@ -27,11 +27,9 @@ struct types_test : public beast::unit_test::suite
void
testAccountID()
{
auto const s =
"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
auto const s = "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh";
if (BEAST_EXPECT(parseBase58<AccountID>(s)))
BEAST_EXPECT(toBase58(
*parseBase58<AccountID>(s)) == s);
BEAST_EXPECT(toBase58(*parseBase58<AccountID>(s)) == s);
}
void
@@ -41,6 +39,6 @@ struct types_test : public beast::unit_test::suite
}
};
BEAST_DEFINE_TESTSUITE(types,protocol,ripple);
BEAST_DEFINE_TESTSUITE(types, protocol, ripple);
}
} // namespace ripple