Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ripple/protocol/impl/Indexes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ enum class LedgerNameSpace : std::uint16_t {
URI_TOKEN = 'U',
IMPORT_VLSEQ = 'I',
UNL_REPORT = 'R',
CRON = 'A',
CRON = 'L',

// No longer used or supported. Left here to reserve the space
// to avoid accidental reuse.
Expand Down
1 change: 1 addition & 0 deletions src/ripple/protocol/jss.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ JSS(coins);
JSS(children);
JSS(ctid); // in/out: Tx RPC
JSS(cres);
JSS(cron);
JSS(currency_a); // out: BookChanges
JSS(currency_b); // out: BookChanges
JSS(currentShard); // out: NodeToShardStatus
Expand Down
30 changes: 30 additions & 0 deletions src/ripple/rpc/handlers/LedgerEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,36 @@ doLedgerEntry(RPC::JsonContext& context)
jvResult[jss::error] = "malformedRequest";
}
}
else if (context.params.isMember(jss::cron))
{
expectedType = ltCRON;
if (!context.params[jss::cron].isObject())
{
if (!uNodeIndex.parseHex(context.params[jss::cron].asString()))
{
uNodeIndex = beast::zero;
jvResult[jss::error] = "malformedRequest";
}
}
else if (
!context.params[jss::cron].isMember(jss::owner) ||
!context.params[jss::cron].isMember(jss::time))
{
jvResult[jss::error] = "malformedRequest";
}
else
{
auto const id = parseBase58<AccountID>(
context.params[jss::cron][jss::owner].asString());
if (!id)
jvResult[jss::error] = "malformedAddress";
else
uNodeIndex =
keylet::cron(
context.params[jss::cron][jss::time].asUInt(), *id)
.key;
}
}
else
{
if (context.params.isMember("params") &&
Expand Down
83 changes: 83 additions & 0 deletions src/test/rpc/LedgerRPC_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,88 @@ class LedgerRPC_test : public beast::unit_test::suite
}
}

void
testLedgerEntryCron()
{
testcase("ledger_entry Request Cron");
using namespace test::jtx;

Env env{*this};

Account const alice{"alice"};
env.fund(XRP(10000), alice);
env.close();

auto const startTime =
env.current()->parentCloseTime().time_since_epoch().count() + 100;
env(cron::set(alice),
cron::startTime(startTime),
cron::delay(100),
cron::repeat(200),
fee(XRP(1)),
ter(tesSUCCESS));
env.close();

std::string const ledgerHash{to_string(env.closed()->info().hash)};

uint256 const cronIndex{keylet::cron(startTime, alice).key};
{
// Request the cron using its index.
Json::Value jvParams;
jvParams[jss::cron] = to_string(cronIndex);
jvParams[jss::ledger_hash] = ledgerHash;
Json::Value const jrr = env.rpc(
"json", "ledger_entry", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.human());
BEAST_EXPECT(jrr[jss::node][sfStartTime.jsonName] == startTime);
BEAST_EXPECT(jrr[jss::node][sfDelaySeconds.jsonName] == 100);
BEAST_EXPECT(jrr[jss::node][sfRepeatCount.jsonName] == 200);
}
{
// Request the cron using its owner and time.
Json::Value jvParams;
jvParams[jss::cron] = Json::objectValue;
jvParams[jss::cron][jss::owner] = alice.human();
jvParams[jss::cron][jss::time] = startTime;
jvParams[jss::ledger_hash] = ledgerHash;
Json::Value const jrr = env.rpc(
"json", "ledger_entry", to_string(jvParams))[jss::result];
BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.human());
BEAST_EXPECT(jrr[jss::node][sfStartTime.jsonName] == startTime);
BEAST_EXPECT(jrr[jss::node][sfDelaySeconds.jsonName] == 100);
BEAST_EXPECT(jrr[jss::node][sfRepeatCount.jsonName] == 200);
}
{
// Malformed uritoken object. Missing owner member.
Json::Value jvParams;
jvParams[jss::cron] = Json::objectValue;
jvParams[jss::cron][jss::time] = startTime;
jvParams[jss::ledger_hash] = ledgerHash;
Json::Value const jrr = env.rpc(
"json", "ledger_entry", to_string(jvParams))[jss::result];
checkErrorValue(jrr, "malformedRequest", "");
}
{
// Malformed uritoken object. Missing time member.
Json::Value jvParams;
jvParams[jss::cron] = Json::objectValue;
jvParams[jss::cron][jss::owner] = alice.human();
jvParams[jss::ledger_hash] = ledgerHash;
Json::Value const jrr = env.rpc(
"json", "ledger_entry", to_string(jvParams))[jss::result];
checkErrorValue(jrr, "malformedRequest", "");
}
{
// Request an index that is not a uritoken.
Json::Value jvParams;
jvParams[jss::cron] = ledgerHash;
jvParams[jss::ledger_hash] = ledgerHash;
Json::Value const jrr = env.rpc(
"json", "ledger_entry", to_string(jvParams))[jss::result];
checkErrorValue(jrr, "entryNotFound", "");
}
}

void
testLedgerEntryUnknownOption()
{
Expand Down Expand Up @@ -2365,6 +2447,7 @@ class LedgerRPC_test : public beast::unit_test::suite
testLedgerEntryTicket();
testLedgerEntryURIToken();
testLedgerEntryImportVLSeq();
testLedgerEntryCron();
testLedgerEntryUnknownOption();
testLookupLedger();
testNoQueue();
Expand Down
Loading