Files
rippled/src/test/rpc/ReportingETL_test.cpp

1141 lines
41 KiB
C++

//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2020 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/reporting/P2pProxy.h>
#include <ripple/beast/unit_test.h>
#include <ripple/rpc/impl/Tuning.h>
#include <test/jtx.h>
#include <test/jtx/Env.h>
#include <test/jtx/envconfig.h>
#include <test/rpc/GRPCTestClientBase.h>
namespace ripple {
namespace test {
class ReportingETL_test : public beast::unit_test::suite
{
// gRPC stuff
class GrpcLedgerClient : public GRPCTestClientBase
{
public:
org::xrpl::rpc::v1::GetLedgerRequest request;
org::xrpl::rpc::v1::GetLedgerResponse reply;
explicit GrpcLedgerClient(std::string const& port)
: GRPCTestClientBase(port)
{
}
void
GetLedger()
{
status = stub_->GetLedger(&context, request, &reply);
}
};
void
testGetLedger()
{
testcase("GetLedger");
using namespace test::jtx;
std::unique_ptr<Config> config = envconfig(addGrpcConfig);
std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
env.close();
auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
BEAST_EXPECT(env.current()->info().seq == 4);
auto grpcLedger = [&grpcPort](
auto sequence,
bool transactions,
bool expand,
bool get_objects,
bool get_object_neighbors) {
GrpcLedgerClient grpcClient{grpcPort};
grpcClient.request.mutable_ledger()->set_sequence(sequence);
grpcClient.request.set_transactions(transactions);
grpcClient.request.set_expand(expand);
grpcClient.request.set_get_objects(get_objects);
grpcClient.request.set_get_object_neighbors(get_object_neighbors);
grpcClient.GetLedger();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
{
auto [status, reply] = grpcLedger(3, false, false, false, false);
BEAST_EXPECT(status.ok());
BEAST_EXPECT(reply.validated());
BEAST_EXPECT(!reply.has_hashes_list());
BEAST_EXPECT(!reply.has_transactions_list());
BEAST_EXPECT(!reply.skiplist_included());
BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
Serializer s;
addRaw(ledger->info(), s, true);
BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
}
Account const alice{"alice"};
Account const bob{"bob"};
env.fund(XRP(10000), alice);
env.fund(XRP(10000), bob);
env.close();
ledger = env.app().getLedgerMaster().getLedgerBySeq(4);
std::vector<uint256> hashes;
std::vector<std::shared_ptr<const STTx>> transactions;
std::vector<std::shared_ptr<const STObject>> metas;
for (auto& [sttx, meta] : ledger->txs)
{
hashes.push_back(sttx->getTransactionID());
transactions.push_back(sttx);
metas.push_back(meta);
}
Serializer s;
addRaw(ledger->info(), s, true);
{
auto [status, reply] = grpcLedger(4, true, false, false, false);
BEAST_EXPECT(status.ok());
BEAST_EXPECT(reply.validated());
BEAST_EXPECT(reply.has_hashes_list());
BEAST_EXPECT(reply.hashes_list().hashes_size() == hashes.size());
BEAST_EXPECT(
uint256::fromVoid(reply.hashes_list().hashes(0).data()) ==
hashes[0]);
BEAST_EXPECT(
uint256::fromVoid(reply.hashes_list().hashes(1).data()) ==
hashes[1]);
BEAST_EXPECT(
uint256::fromVoid(reply.hashes_list().hashes(2).data()) ==
hashes[2]);
BEAST_EXPECT(
uint256::fromVoid(reply.hashes_list().hashes(3).data()) ==
hashes[3]);
BEAST_EXPECT(!reply.has_transactions_list());
BEAST_EXPECT(!reply.skiplist_included());
BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
}
{
auto [status, reply] = grpcLedger(4, true, true, false, false);
BEAST_EXPECT(status.ok());
BEAST_EXPECT(reply.validated());
BEAST_EXPECT(!reply.has_hashes_list());
BEAST_EXPECT(reply.has_transactions_list());
BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(0)
.transaction_blob()) ==
transactions[0]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(0)
.metadata_blob()) ==
metas[0]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(1)
.transaction_blob()) ==
transactions[1]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(1)
.metadata_blob()) ==
metas[1]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(2)
.transaction_blob()) ==
transactions[2]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(2)
.metadata_blob()) ==
metas[2]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(3)
.transaction_blob()) ==
transactions[3]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(3)
.metadata_blob()) ==
metas[3]->getSerializer().slice());
BEAST_EXPECT(!reply.skiplist_included());
BEAST_EXPECT(reply.ledger_objects().objects_size() == 0);
BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
}
{
auto [status, reply] = grpcLedger(4, true, true, true, false);
BEAST_EXPECT(status.ok());
BEAST_EXPECT(reply.validated());
BEAST_EXPECT(!reply.has_hashes_list());
BEAST_EXPECT(reply.has_transactions_list());
BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(0)
.transaction_blob()) ==
transactions[0]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(0)
.metadata_blob()) ==
metas[0]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(1)
.transaction_blob()) ==
transactions[1]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(1)
.metadata_blob()) ==
metas[1]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(2)
.transaction_blob()) ==
transactions[2]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(2)
.metadata_blob()) ==
metas[2]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(3)
.transaction_blob()) ==
transactions[3]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(3)
.metadata_blob()) ==
metas[3]->getSerializer().slice());
BEAST_EXPECT(reply.skiplist_included());
BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
SHAMap::Delta differences;
int maxDifferences = std::numeric_limits<int>::max();
bool res = parent->stateMap().compare(
ledger->stateMap(), differences, maxDifferences);
BEAST_EXPECT(res);
size_t idx = 0;
for (auto& [k, v] : differences)
{
BEAST_EXPECT(
k ==
uint256::fromVoid(
reply.ledger_objects().objects(idx).key().data()));
if (v.second)
{
BEAST_EXPECT(
v.second->slice() ==
makeSlice(reply.ledger_objects().objects(idx).data()));
}
++idx;
}
}
{
auto [status, reply] = grpcLedger(4, true, true, true, true);
BEAST_EXPECT(status.ok());
BEAST_EXPECT(reply.validated());
BEAST_EXPECT(!reply.has_hashes_list());
BEAST_EXPECT(reply.object_neighbors_included());
BEAST_EXPECT(reply.has_transactions_list());
BEAST_EXPECT(reply.transactions_list().transactions_size() == 4);
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(0)
.transaction_blob()) ==
transactions[0]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(0)
.metadata_blob()) ==
metas[0]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(1)
.transaction_blob()) ==
transactions[1]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(1)
.metadata_blob()) ==
metas[1]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(2)
.transaction_blob()) ==
transactions[2]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(2)
.metadata_blob()) ==
metas[2]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(3)
.transaction_blob()) ==
transactions[3]->getSerializer().slice());
BEAST_EXPECT(
makeSlice(reply.transactions_list()
.transactions(3)
.metadata_blob()) ==
metas[3]->getSerializer().slice());
BEAST_EXPECT(reply.skiplist_included());
BEAST_EXPECT(s.slice() == makeSlice(reply.ledger_header()));
auto parent = env.app().getLedgerMaster().getLedgerBySeq(3);
SHAMap::Delta differences;
int maxDifferences = std::numeric_limits<int>::max();
bool res = parent->stateMap().compare(
ledger->stateMap(), differences, maxDifferences);
BEAST_EXPECT(res);
size_t idx = 0;
for (auto& [k, v] : differences)
{
auto obj = reply.ledger_objects().objects(idx);
BEAST_EXPECT(k == uint256::fromVoid(obj.key().data()));
if (v.second)
{
BEAST_EXPECT(v.second->slice() == makeSlice(obj.data()));
}
else
BEAST_EXPECT(obj.data().size() == 0);
if (!(v.first && v.second))
{
auto succ = ledger->stateMap().upper_bound(k);
auto pred = ledger->stateMap().lower_bound(k);
if (succ != ledger->stateMap().end())
BEAST_EXPECT(
succ->key() ==
uint256::fromVoid(obj.successor().data()));
else
BEAST_EXPECT(obj.successor().size() == 0);
if (pred != ledger->stateMap().end())
BEAST_EXPECT(
pred->key() ==
uint256::fromVoid(obj.predecessor().data()));
else
BEAST_EXPECT(obj.predecessor().size() == 0);
}
++idx;
}
}
// Delete an account
env(noop(alice));
std::uint32_t const ledgerCount{
env.current()->seq() + 257 - env.seq(alice)};
for (std::uint32_t i = 0; i < ledgerCount; ++i)
env.close();
auto const acctDelFee{drops(env.current()->fees().increment)};
env(acctdelete(alice, bob), fee(acctDelFee));
env.close();
{
auto [status, reply] =
grpcLedger(env.closed()->seq(), true, true, true, true);
BEAST_EXPECT(status.ok());
BEAST_EXPECT(reply.validated());
auto base =
env.app().getLedgerMaster().getLedgerBySeq(env.closed()->seq());
auto parent = env.app().getLedgerMaster().getLedgerBySeq(
env.closed()->seq() - 1);
SHAMap::Delta differences;
int maxDifferences = std::numeric_limits<int>::max();
bool res = parent->stateMap().compare(
base->stateMap(), differences, maxDifferences);
BEAST_EXPECT(res);
size_t idx = 0;
for (auto& [k, v] : differences)
{
auto obj = reply.ledger_objects().objects(idx);
BEAST_EXPECT(k == uint256::fromVoid(obj.key().data()));
if (v.second)
{
BEAST_EXPECT(
v.second->slice() ==
makeSlice(reply.ledger_objects().objects(idx).data()));
}
else
BEAST_EXPECT(obj.data().size() == 0);
if (!(v.first && v.second))
{
auto succ = base->stateMap().upper_bound(k);
auto pred = base->stateMap().lower_bound(k);
if (succ != base->stateMap().end())
BEAST_EXPECT(
succ->key() ==
uint256::fromVoid(obj.successor().data()));
else
BEAST_EXPECT(obj.successor().size() == 0);
if (pred != base->stateMap().end())
BEAST_EXPECT(
pred->key() ==
uint256::fromVoid(obj.predecessor().data()));
else
BEAST_EXPECT(obj.predecessor().size() == 0);
}
++idx;
}
}
}
// gRPC stuff
class GrpcLedgerDataClient : public GRPCTestClientBase
{
public:
org::xrpl::rpc::v1::GetLedgerDataRequest request;
org::xrpl::rpc::v1::GetLedgerDataResponse reply;
explicit GrpcLedgerDataClient(std::string const& port)
: GRPCTestClientBase(port)
{
}
void
GetLedgerData()
{
status = stub_->GetLedgerData(&context, request, &reply);
}
};
void
testGetLedgerData()
{
testcase("GetLedgerData");
using namespace test::jtx;
std::unique_ptr<Config> config = envconfig(addGrpcConfig);
std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
auto grpcLedgerData = [&grpcPort](
auto sequence, std::string marker = "") {
GrpcLedgerDataClient grpcClient{grpcPort};
grpcClient.request.mutable_ledger()->set_sequence(sequence);
if (marker.size())
{
grpcClient.request.set_marker(marker);
}
grpcClient.GetLedgerData();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
Account const alice{"alice"};
env.fund(XRP(100000), alice);
int num_accounts = 10;
for (auto i = 0; i < num_accounts; i++)
{
Account const bob{std::string("bob") + std::to_string(i)};
env.fund(XRP(1000), bob);
}
env.close();
{
auto [status, reply] = grpcLedgerData(env.closed()->seq());
BEAST_EXPECT(status.ok());
BEAST_EXPECT(
reply.ledger_objects().objects_size() == num_accounts + 3);
BEAST_EXPECT(reply.marker().size() == 0);
auto ledger = env.closed();
size_t idx = 0;
for (auto& sle : ledger->sles)
{
BEAST_EXPECT(
sle->getSerializer().slice() ==
makeSlice(reply.ledger_objects().objects(idx).data()));
++idx;
}
}
{
auto [status, reply] =
grpcLedgerData(env.closed()->seq(), "bad marker");
BEAST_EXPECT(!status.ok());
BEAST_EXPECT(
status.error_code() == grpc::StatusCode::INVALID_ARGUMENT);
}
num_accounts = 3000;
for (auto i = 0; i < num_accounts; i++)
{
Account const cat{std::string("cat") + std::to_string(i)};
env.fund(XRP(1000), cat);
if (i % 100 == 0)
env.close();
}
env.close();
{
auto [status, reply] = grpcLedgerData(env.closed()->seq());
BEAST_EXPECT(status.ok());
int maxLimit = RPC::Tuning::pageLength(true);
BEAST_EXPECT(reply.ledger_objects().objects_size() == maxLimit);
BEAST_EXPECT(reply.marker().size() != 0);
auto [status2, reply2] =
grpcLedgerData(env.closed()->seq(), reply.marker());
BEAST_EXPECT(status2.ok());
BEAST_EXPECT(reply2.marker().size() == 0);
auto ledger = env.closed();
size_t idx = 0;
for (auto& sle : ledger->sles)
{
auto& obj = idx < maxLimit
? reply.ledger_objects().objects(idx)
: reply2.ledger_objects().objects(idx - maxLimit);
BEAST_EXPECT(
sle->getSerializer().slice() == makeSlice(obj.data()));
++idx;
}
BEAST_EXPECT(
idx ==
reply.ledger_objects().objects_size() +
reply2.ledger_objects().objects_size());
}
}
// gRPC stuff
class GrpcLedgerDiffClient : public GRPCTestClientBase
{
public:
org::xrpl::rpc::v1::GetLedgerDiffRequest request;
org::xrpl::rpc::v1::GetLedgerDiffResponse reply;
explicit GrpcLedgerDiffClient(std::string const& port)
: GRPCTestClientBase(port)
{
}
void
GetLedgerDiff()
{
status = stub_->GetLedgerDiff(&context, request, &reply);
}
};
void
testGetLedgerDiff()
{
testcase("GetLedgerDiff");
using namespace test::jtx;
std::unique_ptr<Config> config = envconfig(addGrpcConfig);
std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
auto grpcLedgerDiff = [&grpcPort](
auto baseSequence, auto desiredSequence) {
GrpcLedgerDiffClient grpcClient{grpcPort};
grpcClient.request.mutable_base_ledger()->set_sequence(
baseSequence);
grpcClient.request.mutable_desired_ledger()->set_sequence(
desiredSequence);
grpcClient.request.set_include_blobs(true);
grpcClient.GetLedgerDiff();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
int num_accounts = 20;
for (auto i = 0; i < num_accounts; i++)
{
Account const cat{std::string("cat") + std::to_string(i)};
env.fund(XRP(1000), cat);
if (i % 2 == 0)
env.close();
}
env.close();
auto compareDiffs = [&](auto baseSequence, auto desiredSequence) {
auto [status, reply] =
grpcLedgerDiff(baseSequence, desiredSequence);
BEAST_EXPECT(status.ok());
auto desired =
env.app().getLedgerMaster().getLedgerBySeq(desiredSequence);
auto base =
env.app().getLedgerMaster().getLedgerBySeq(baseSequence);
SHAMap::Delta differences;
int maxDifferences = std::numeric_limits<int>::max();
bool res = base->stateMap().compare(
desired->stateMap(), differences, maxDifferences);
if (!BEAST_EXPECT(res))
return false;
size_t idx = 0;
for (auto& [k, v] : differences)
{
if (!BEAST_EXPECT(
k ==
uint256::fromVoid(
reply.ledger_objects().objects(idx).key().data())))
return false;
if (v.second)
{
if (!BEAST_EXPECT(
v.second->slice() ==
makeSlice(
reply.ledger_objects().objects(idx).data())))
return false;
}
++idx;
}
return true;
};
// Adjacent ledgers
BEAST_EXPECT(
compareDiffs(env.closed()->seq() - 1, env.closed()->seq()));
// Adjacent ledgers further in the past
BEAST_EXPECT(
compareDiffs(env.closed()->seq() - 3, env.closed()->seq() - 2));
// Non-adjacent ledgers
BEAST_EXPECT(
compareDiffs(env.closed()->seq() - 5, env.closed()->seq() - 1));
// Adjacent ledgers but in reverse order
BEAST_EXPECT(
compareDiffs(env.closed()->seq(), env.closed()->seq() - 1));
// Non-adjacent ledgers in reverse order
BEAST_EXPECT(
compareDiffs(env.closed()->seq() - 1, env.closed()->seq() - 5));
}
// gRPC stuff
class GrpcLedgerEntryClient : public GRPCTestClientBase
{
public:
org::xrpl::rpc::v1::GetLedgerEntryRequest request;
org::xrpl::rpc::v1::GetLedgerEntryResponse reply;
explicit GrpcLedgerEntryClient(std::string const& port)
: GRPCTestClientBase(port)
{
}
void
GetLedgerEntry()
{
status = stub_->GetLedgerEntry(&context, request, &reply);
}
};
void
testGetLedgerEntry()
{
testcase("GetLedgerDiff");
using namespace test::jtx;
std::unique_ptr<Config> config = envconfig(addGrpcConfig);
std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
auto grpcLedgerEntry = [&grpcPort](auto sequence, auto key) {
GrpcLedgerEntryClient grpcClient{grpcPort};
grpcClient.request.mutable_ledger()->set_sequence(sequence);
grpcClient.request.set_key(key.data(), key.size());
grpcClient.GetLedgerEntry();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
Account const alice{"alice"};
env.fund(XRP(1000), alice);
env.close();
for (auto& sle : env.closed()->sles)
{
auto [status, reply] =
grpcLedgerEntry(env.closed()->seq(), sle->key());
BEAST_EXPECT(status.ok());
BEAST_EXPECT(
uint256::fromVoid(reply.ledger_object().key().data()) ==
sle->key());
BEAST_EXPECT(
makeSlice(reply.ledger_object().data()) ==
sle->getSerializer().slice());
}
}
void
testNeedCurrentOrClosed()
{
testcase("NeedCurrentOrClosed");
{
org::xrpl::rpc::v1::GetLedgerRequest request;
request.mutable_ledger()->set_sequence(1);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_hash("");
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
BEAST_EXPECT(needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
BEAST_EXPECT(needCurrentOrClosed(request));
}
{
org::xrpl::rpc::v1::GetLedgerDataRequest request;
request.mutable_ledger()->set_sequence(1);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_hash("");
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
BEAST_EXPECT(needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
BEAST_EXPECT(needCurrentOrClosed(request));
}
{
org::xrpl::rpc::v1::GetLedgerEntryRequest request;
request.mutable_ledger()->set_sequence(1);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_hash("");
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
BEAST_EXPECT(needCurrentOrClosed(request));
request.mutable_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
BEAST_EXPECT(needCurrentOrClosed(request));
}
{
org::xrpl::rpc::v1::GetLedgerDiffRequest request;
// set desired ledger, so desired ledger does not need current or
// closed
request.mutable_base_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
request.mutable_base_ledger()->set_sequence(1);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_base_ledger()->set_hash("");
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_base_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_base_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_base_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
BEAST_EXPECT(needCurrentOrClosed(request));
request.mutable_base_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
BEAST_EXPECT(needCurrentOrClosed(request));
// reset base ledger, so base ledger doesn't need current or closed
request.mutable_base_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
request.mutable_desired_ledger()->set_sequence(1);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_desired_ledger()->set_hash("");
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_desired_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_desired_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_UNSPECIFIED);
BEAST_EXPECT(!needCurrentOrClosed(request));
request.mutable_desired_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
BEAST_EXPECT(needCurrentOrClosed(request));
request.mutable_desired_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED);
BEAST_EXPECT(needCurrentOrClosed(request));
// both base and desired need current or closed
request.mutable_base_ledger()->set_shortcut(
org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT);
BEAST_EXPECT(needCurrentOrClosed(request));
}
}
void
testSecureGateway()
{
testcase("SecureGateway");
using namespace test::jtx;
{
std::unique_ptr<Config> config = envconfig(
addGrpcConfigWithSecureGateway, getEnvLocalhostAddr());
std::string grpcPort =
*(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
env.close();
auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
BEAST_EXPECT(env.current()->info().seq == 4);
auto grpcLedger = [&grpcPort](
auto sequence,
std::string const& clientIp,
std::string const& user) {
GrpcLedgerClient grpcClient{grpcPort};
grpcClient.request.mutable_ledger()->set_sequence(sequence);
grpcClient.request.set_client_ip(clientIp);
grpcClient.request.set_user(user);
grpcClient.GetLedger();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, "", "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, "", "ETL");
BEAST_EXPECT(reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, "", "Reporting");
BEAST_EXPECT(reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, "127.0.0.1", "ETL");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, "127.0.0.1", "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
}
{
std::string secureGatewayIp = "44.124.234.79";
std::unique_ptr<Config> config =
envconfig(addGrpcConfigWithSecureGateway, secureGatewayIp);
std::string grpcPort =
*(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
env.close();
auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
BEAST_EXPECT(env.current()->info().seq == 4);
auto grpcLedger = [&grpcPort](
auto sequence,
std::string const& clientIp,
std::string const& user) {
GrpcLedgerClient grpcClient{grpcPort};
grpcClient.request.mutable_ledger()->set_sequence(sequence);
grpcClient.request.set_client_ip(clientIp);
grpcClient.request.set_user(user);
grpcClient.GetLedger();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, "", "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, "", "ETL");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] = grpcLedger(
env.current()->info().seq, secureGatewayIp, "ETL");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedger(env.current()->info().seq, secureGatewayIp, "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
}
{
std::unique_ptr<Config> config = envconfig(
addGrpcConfigWithSecureGateway, getEnvLocalhostAddr());
std::string grpcPort =
*(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
env.close();
auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
BEAST_EXPECT(env.current()->info().seq == 4);
auto grpcLedgerData = [&grpcPort](
auto sequence,
std::string const& clientIp,
std::string const& user) {
GrpcLedgerDataClient grpcClient{grpcPort};
grpcClient.request.mutable_ledger()->set_sequence(sequence);
grpcClient.request.set_client_ip(clientIp);
grpcClient.request.set_user(user);
grpcClient.GetLedgerData();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
{
auto [status, reply] =
grpcLedgerData(env.current()->info().seq, "", "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedgerData(env.current()->info().seq, "", "ETL");
BEAST_EXPECT(reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedgerData(env.current()->info().seq, "", "Reporting");
BEAST_EXPECT(reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] = grpcLedgerData(
env.current()->info().seq, "127.0.0.1", "ETL");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedgerData(env.current()->info().seq, "127.0.0.1", "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
}
{
std::string secureGatewayIp = "44.124.234.79";
std::unique_ptr<Config> config =
envconfig(addGrpcConfigWithSecureGateway, secureGatewayIp);
std::string grpcPort =
*(*config)["port_grpc"].get<std::string>("port");
Env env(*this, std::move(config));
env.close();
auto ledger = env.app().getLedgerMaster().getLedgerBySeq(3);
BEAST_EXPECT(env.current()->info().seq == 4);
auto grpcLedgerData = [&grpcPort](
auto sequence,
std::string const& clientIp,
std::string const& user) {
GrpcLedgerDataClient grpcClient{grpcPort};
grpcClient.request.mutable_ledger()->set_sequence(sequence);
grpcClient.request.set_client_ip(clientIp);
grpcClient.request.set_user(user);
grpcClient.GetLedgerData();
return std::make_pair(grpcClient.status, grpcClient.reply);
};
{
auto [status, reply] =
grpcLedgerData(env.current()->info().seq, "", "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] =
grpcLedgerData(env.current()->info().seq, "", "ETL");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] = grpcLedgerData(
env.current()->info().seq, secureGatewayIp, "ETL");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
{
auto [status, reply] = grpcLedgerData(
env.current()->info().seq, secureGatewayIp, "");
BEAST_EXPECT(!reply.is_unlimited());
BEAST_EXPECT(status.ok());
}
}
}
public:
void
run() override
{
testGetLedger();
testGetLedgerData();
testGetLedgerDiff();
testGetLedgerEntry();
testNeedCurrentOrClosed();
testSecureGateway();
}
};
BEAST_DEFINE_TESTSUITE_PRIO(ReportingETL, app, ripple, 2);
} // namespace test
} // namespace ripple