mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Format first-party source according to .clang-format
This commit is contained in:
committed by
manojsdoshi
parent
65dfc5d19e
commit
50760c6935
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user