mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-20 02:25:53 +00:00
3958 lines
181 KiB
C++
3958 lines
181 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
This file is part of rippled: https://github.com/ripple/rippled
|
|
Copyright (c) 2023 XRPLF
|
|
|
|
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/tx/impl/Import.h>
|
|
#include <ripple/app/ledger/LedgerMaster.h>
|
|
#include <ripple/core/ConfigSections.h>
|
|
#include <ripple/json/json_reader.h>
|
|
#include <ripple/json/json_writer.h>
|
|
#include <ripple/ledger/Directory.h>
|
|
#include <ripple/protocol/Feature.h>
|
|
#include <ripple/protocol/Import.h>
|
|
#include <ripple/protocol/jss.h>
|
|
#include <test/jtx.h>
|
|
#include <test/app/Import_json.h>
|
|
|
|
#define BEAST_REQUIRE(x) \
|
|
{ \
|
|
BEAST_EXPECT(!!(x)); \
|
|
if (!(x)) \
|
|
return; \
|
|
}
|
|
namespace ripple {
|
|
namespace test {
|
|
|
|
class Import_test : public beast::unit_test::suite
|
|
{
|
|
std::unique_ptr<Config>
|
|
makeNetworkConfig(uint32_t networkID)
|
|
{
|
|
using namespace jtx;
|
|
std::vector<std::string> const keys = {
|
|
"ED74D4036C6591A4BDF9C54CEFA39B996A"
|
|
"5DCE5F86D11FDA1874481CE9D5A1CDC1"};
|
|
return envconfig([&](std::unique_ptr<Config> cfg) {
|
|
cfg->section(SECTION_RPC_STARTUP)
|
|
.append(
|
|
"{ \"command\": \"log_level\", \"severity\": \"warn\" "
|
|
"}");
|
|
cfg->NETWORK_ID = networkID;
|
|
Section config;
|
|
config.append(
|
|
{"reference_fee = 50",
|
|
"account_reserve = 1000000",
|
|
"owner_reserve = 200000"});
|
|
auto setup = setup_FeeVote(config);
|
|
cfg->FEES = setup;
|
|
|
|
for (auto const& strPk : keys)
|
|
{
|
|
auto pkHex = strUnHex(strPk);
|
|
if (!pkHex)
|
|
Throw<std::runtime_error>(
|
|
"Import VL Key '" + strPk + "' was not valid hex.");
|
|
|
|
auto const pkType = publicKeyType(makeSlice(*pkHex));
|
|
if (!pkType)
|
|
Throw<std::runtime_error>(
|
|
"Import VL Key '" + strPk +
|
|
"' was not a valid key type.");
|
|
|
|
cfg->IMPORT_VL_KEYS.emplace(strPk, makeSlice(*pkHex));
|
|
}
|
|
return cfg;
|
|
});
|
|
}
|
|
|
|
static Json::Value
|
|
import(jtx::Account const& account, Json::Value const& xpop)
|
|
{
|
|
using namespace jtx;
|
|
Json::Value jv;
|
|
std::string strJson = Json::FastWriter().write(xpop);
|
|
jv[jss::TransactionType] = jss::Import;
|
|
jv[jss::Account] = account.human();
|
|
jv[sfBlob.jsonName] = strHex(strJson);
|
|
return jv;
|
|
}
|
|
|
|
static std::pair<uint256, std::shared_ptr<SLE const>>
|
|
accountKeyAndSle(ReadView const& view, jtx::Account const& account)
|
|
{
|
|
auto const k = keylet::account(account);
|
|
return {k.key, view.read(k)};
|
|
}
|
|
|
|
static std::pair<uint256, std::shared_ptr<SLE const>>
|
|
signersKeyAndSle(ReadView const& view, jtx::Account const& account)
|
|
{
|
|
auto const k = keylet::signers(account);
|
|
return {k.key, view.read(k)};
|
|
}
|
|
|
|
static std::size_t
|
|
ownerDirCount(ReadView const& view, jtx::Account const& acct)
|
|
{
|
|
ripple::Dir const ownerDir(view, keylet::ownerDir(acct.id()));
|
|
return std::distance(ownerDir.begin(), ownerDir.end());
|
|
};
|
|
|
|
static Json::Value
|
|
loadXpop(std::string content)
|
|
{
|
|
// If the string is empty, return an empty Json::Value
|
|
if (content.empty())
|
|
{
|
|
std::cout << "JSON string was empty" << "\n";
|
|
return {};
|
|
}
|
|
|
|
Json::Value jsonValue;
|
|
Json::Reader reader;
|
|
reader.parse(content, jsonValue);
|
|
return jsonValue;
|
|
}
|
|
|
|
void
|
|
testComputeStartingBalance(FeatureBitset features)
|
|
{
|
|
testcase("import header - computeStartingBonus");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(11111)};
|
|
|
|
// old fee
|
|
XRPAmount const value = Import::computeStartingBonus(*env.current());
|
|
BEAST_EXPECT(value == drops(2000000));
|
|
|
|
// todo: new fee
|
|
}
|
|
|
|
void
|
|
testIsHex(FeatureBitset features)
|
|
{
|
|
testcase("import utils - isHex");
|
|
bool const result = isHex("DEADBEEF");
|
|
BEAST_EXPECT(result == true);
|
|
bool const result1 = isHex("Hello world");
|
|
BEAST_EXPECT(result1 == false);
|
|
}
|
|
|
|
void
|
|
testIsBase58(FeatureBitset features)
|
|
{
|
|
testcase("import utils - isBase58");
|
|
bool const result = isBase58("hE45rTtDcGvFz");
|
|
BEAST_EXPECT(result == true);
|
|
bool const result1 = isBase58("Hello world");
|
|
BEAST_EXPECT(result1 == false);
|
|
}
|
|
|
|
void
|
|
testIsBase64(FeatureBitset features)
|
|
{
|
|
testcase("import utils - isBase64");
|
|
bool const result = isBase64("SGVsbG8gV29ybGQh");
|
|
BEAST_EXPECT(result == true);
|
|
bool const result1 = isBase64("Hello world");
|
|
BEAST_EXPECT(result1 == false);
|
|
}
|
|
|
|
void
|
|
testParseUint64(FeatureBitset features)
|
|
{
|
|
testcase("import utils - parseUint64");
|
|
std::optional<uint64_t> result1 = parse_uint64("1234");
|
|
BEAST_EXPECT(result1 == 1234);
|
|
|
|
// std::optional<uint64_t> result2 = parse_uint64("0xFFAABBCCDD22");
|
|
// std::cout << "RESULT: " << *result2 << "\n";
|
|
// BEAST_EXPECT(result2 == 0xFFAABBCCDD22);
|
|
|
|
std::optional<uint64_t> result3 = parse_uint64("2147483647");
|
|
BEAST_EXPECT(result3 == 2147483647);
|
|
|
|
std::optional<uint64_t> result4 = parse_uint64("18446744073709551615");
|
|
BEAST_EXPECT(result4 == 18446744073709551615ull);
|
|
}
|
|
|
|
void
|
|
testSyntaxCheckProofArray(FeatureBitset features)
|
|
{
|
|
}
|
|
|
|
void
|
|
testSyntaxCheckProofObject(FeatureBitset features)
|
|
{
|
|
testcase("import utils - syntaxCheckProof: is object");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(11111)};
|
|
|
|
auto const alice = Account("alice");
|
|
env.fund(XRP(1000), alice);
|
|
env.close();
|
|
|
|
std::string strJson = R"json({
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
})json";
|
|
|
|
Json::Value proof;
|
|
Json::Reader reader;
|
|
reader.parse(strJson, proof);
|
|
|
|
// XPOP.transaction.proof list entry has wrong format
|
|
{
|
|
BEAST_EXPECT(syntaxCheckProof(proof, env.journal, 65) == false);
|
|
}
|
|
// XPOP.transaction.proof invalid branch size
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["30"] = tmpProof[jss::children]["3"];
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof child node was not 0-F
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["not a hex"] = tmpProof[jss::children]["3"];
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof tree node has wrong format
|
|
// invalid child (must be object)
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["3"] = "not object";
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof tree node has wrong format
|
|
// invalid hash (must be string)
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["3"][jss::hash] = 1234;
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof tree node has wrong format
|
|
// invalid hash size (must be 64)
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["3"][jss::hash] =
|
|
"00000000000000000000000000000000000000000000000000000000000000"
|
|
"000";
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof tree node has wrong format
|
|
// invalid key (must be string)
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["3"][jss::key] = 1234;
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof tree node has wrong format
|
|
// invalid key size (must be 64)
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["3"][jss::key] =
|
|
"00000000000000000000000000000000000000000000000000000000000000"
|
|
"000";
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof tree node has wrong format
|
|
// invalid node children (must be object)
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["3"][jss::children] = "bad object";
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// XPOP.transaction.proof bad children format
|
|
// invalid node child children (must be hex)
|
|
{
|
|
Json::Value tmpProof = proof;
|
|
tmpProof[jss::children]["3"][jss::children] =
|
|
tmpProof[jss::children]["3"];
|
|
BEAST_EXPECT(syntaxCheckProof(tmpProof, env.journal) == false);
|
|
}
|
|
// success
|
|
{
|
|
BEAST_EXPECT(syntaxCheckProof(proof, env.journal) == true);
|
|
}
|
|
}
|
|
|
|
void
|
|
testSyntaxCheckXPOP(FeatureBitset features)
|
|
{
|
|
testcase("import utils - syntaxCheckXPOP");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(11111)};
|
|
|
|
// blob empty
|
|
{
|
|
Blob raw{};
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// blob string empty
|
|
{
|
|
Blob raw{0};
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP failed to parse string json
|
|
{
|
|
Blob raw{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP is not a JSON object
|
|
{
|
|
std::string strJson = R"json([])json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger is not a JSON object
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": "not object"
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.transaction is not a JSON object
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {},
|
|
"transaction": "not object"
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.validation is not a JSON object
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {},
|
|
"transaction": {},
|
|
"validation": "not object"
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.LEDGER
|
|
|
|
// XPOP.ledger.acroot missing or wrong format
|
|
// invalid xpop.ledger.acroot (must be string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": {}
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.acroot missing or wrong format
|
|
// invalid xpop.ledger.acroot (must be 64)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "00000000000000000000000000000000000000000000000000000000000000000"
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.acroot missing or wrong format
|
|
// invalid xpop.ledger.acroot (must be hex)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "this string will pass a length check but fail when checking hex."
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.txroot missing or wrong format
|
|
// invalid xpop.ledger.txroot (must be string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": {}
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.txroot missing or wrong format
|
|
// invalid xpop.ledger.txroot (must be 64)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "00000000000000000000000000000000000000000000000000000000000000000"
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.txroot missing or wrong format
|
|
// invalid xpop.ledger.txroot (must be hex)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "this string will pass a length check but fail when checking hex."
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.phash missing or wrong format
|
|
// invalid xpop.ledger.phash (must be string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": {}
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.phash missing or wrong format
|
|
// invalid xpop.ledger.phash (must be 64)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "00000000000000000000000000000000000000000000000000000000000000000"
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.phash missing or wrong format
|
|
// invalid xpop.ledger.phash (must be hex)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "this string will pass a length check but fail when checking hex."
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.close missing or wrong format
|
|
// invalid xpop.ledger.close (must be int)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": "738786851"
|
|
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.coins missing or wrong format
|
|
// invalid xpop.ledger.coins (must be int or string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": {}
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.coins missing or wrong format
|
|
// invalid xpop.ledger.coins (must be int or string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "not an int string"
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.cres missing or wrong format
|
|
// invalid xpop.ledger.cres (must be int)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": "not an int"
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.flags missing or wrong format
|
|
// invalid xpop.ledger.flags (must be int)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": "not an int"
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
// XPOP.ledger.pclose missing or wrong format
|
|
// invalid xpop.ledger.pclose (must be int)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": "not an int"
|
|
},
|
|
"transaction": {},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.TRANSACTION
|
|
|
|
// XPOP.transaction.blob missing or wrong format
|
|
// invalid xpop.transaction.blob (must be hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": {}
|
|
},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.transaction.blob missing or wrong format
|
|
// invalid xpop.transaction.blob (must be hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "not a hex"
|
|
},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.transaction.meta missing or wrong format
|
|
// invalid xpop.transaction.meta (must be hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": {}
|
|
},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.transaction.meta missing or wrong format
|
|
// invalid xpop.transaction.meta (must be hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "not a hex"
|
|
},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.transaction.proof failed syntax check
|
|
// invalid xpop.transaction.proof (must pass syntaxCheckProof)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {}
|
|
},
|
|
"validation": {}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.data missing or wrong format
|
|
// invalid xpop.validation.data (must be object)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": "not an object"
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl missing or wrong format
|
|
// invalid xpop.validation.unl (must be object)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": "not an object"
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.TRANSACTION.DATA
|
|
|
|
// XPOP.validation.data entry has wrong format
|
|
// invalid xpop.validation.data key/value (must be base58 hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A"
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"not base 58": "",
|
|
},
|
|
"unl": {}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.public_key missing or
|
|
// invalid xpop.validation.data key/value (must be base58 hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": 1,
|
|
},
|
|
"unl": {}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.public_key invalid key type.
|
|
// invalid xpop.validation.data key/value (must be base58 hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "not a hex",
|
|
},
|
|
"unl": {}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.TRANSACTION.UNL
|
|
|
|
// XPOP.validation.unl.public_key missing or
|
|
// invalid xpop.validation.unl.public_key (must be hex string with valid
|
|
// key type)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": 1
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.public_key missing or
|
|
// invalid xpop.validation.unl.public_key (must be hex string with valid
|
|
// key type)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "not a hex"
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.public_key missing or
|
|
// invalid xpop.validation.unl.public_key (must be hex string with valid
|
|
// key type)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "0074D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1"
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.manifest missing or wrong
|
|
// invalid xpop.validation.unl.manifest (must be string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": 1
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.blob missing or wrong
|
|
// invalid xpop.validation.unl.blob (must be base 64 string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": "JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/ikfgf9SZOlOGcBcBJAw44PLjH+HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+IILJIiIKU/+1Uxx0FRpQbMDA==",
|
|
"blob": 1
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.blob missing or wrong
|
|
// invalid xpop.validation.unl.blob (must be base 64 string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": "JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/ikfgf9SZOlOGcBcBJAw44PLjH+HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+IILJIiIKU/+1Uxx0FRpQbMDA==",
|
|
"blob": "not a base 64 string"
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.signature missing or wrong
|
|
// invalid xpop.validation.unl.signature (must be hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": "JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/ikfgf9SZOlOGcBcBJAw44PLjH+HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+IILJIiIKU/+1Uxx0FRpQbMDA==",
|
|
"blob": "eyJzZXF1ZW5jZSI6MiwiZXhwaXJhdGlvbiI6NzQxMzk4NDAwLCJ2YWxpZGF0b3JzIjpbeyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDM4QkQ0NDVBRkQ2MjE1OTYyMENDMTk2QzI2NjhBMjZCNkZCQjM2QjA5OUVCNTVCMzhBNThDMTFDMTIwNERFNUMiLCJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlETUdXd21hS0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S28raDd6aGFYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2TmRWZnBudkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWGdTMVJMbG9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lOU0RENmJYdlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcDdWRm9YYm5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURCRUUzMEZBRTkyRUVFODhFMUM0OTgwRDA5RUNGREU5OUExMTZEMDc4RUMyMTg1N0RCMUI0N0I0MjY0MThFNDI4IiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeHRIdENaQmprS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VGclU0bnJFcVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3TjZpa1ZFQkk2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQxQVVnOVg4WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RTlTanVMUjZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9jeWNyRi9DdFNBND0ifV19",
|
|
"signature": 1
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.signature missing or wrong
|
|
// invalid xpop.validation.unl.signature (must be hex string)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": "JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/ikfgf9SZOlOGcBcBJAw44PLjH+HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+IILJIiIKU/+1Uxx0FRpQbMDA==",
|
|
"blob": "eyJzZXF1ZW5jZSI6MiwiZXhwaXJhdGlvbiI6NzQxMzk4NDAwLCJ2YWxpZGF0b3JzIjpbeyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDM4QkQ0NDVBRkQ2MjE1OTYyMENDMTk2QzI2NjhBMjZCNkZCQjM2QjA5OUVCNTVCMzhBNThDMTFDMTIwNERFNUMiLCJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlETUdXd21hS0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S28raDd6aGFYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2TmRWZnBudkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWGdTMVJMbG9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lOU0RENmJYdlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcDdWRm9YYm5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURCRUUzMEZBRTkyRUVFODhFMUM0OTgwRDA5RUNGREU5OUExMTZEMDc4RUMyMTg1N0RCMUI0N0I0MjY0MThFNDI4IiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeHRIdENaQmprS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VGclU0bnJFcVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3TjZpa1ZFQkk2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQxQVVnOVg4WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RTlTanVMUjZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9jeWNyRi9DdFNBND0ifV19",
|
|
"signature": "not a hex"
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl.version missing or
|
|
// invalid xpop.validation.unl.version (must be int)
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": "JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/ikfgf9SZOlOGcBcBJAw44PLjH+HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+IILJIiIKU/+1Uxx0FRpQbMDA==",
|
|
"blob": "eyJzZXF1ZW5jZSI6MiwiZXhwaXJhdGlvbiI6NzQxMzk4NDAwLCJ2YWxpZGF0b3JzIjpbeyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDM4QkQ0NDVBRkQ2MjE1OTYyMENDMTk2QzI2NjhBMjZCNkZCQjM2QjA5OUVCNTVCMzhBNThDMTFDMTIwNERFNUMiLCJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlETUdXd21hS0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S28raDd6aGFYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2TmRWZnBudkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWGdTMVJMbG9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lOU0RENmJYdlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcDdWRm9YYm5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURCRUUzMEZBRTkyRUVFODhFMUM0OTgwRDA5RUNGREU5OUExMTZEMDc4RUMyMTg1N0RCMUI0N0I0MjY0MThFNDI4IiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeHRIdENaQmprS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VGclU0bnJFcVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3TjZpa1ZFQkk2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQxQVVnOVg4WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RTlTanVMUjZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9jeWNyRi9DdFNBND0ifV19",
|
|
"signature": "849F6B8DA6E11C213B561659C16F13D35385E8EA9E775483ADC84578F6D578943DE5EB681584B2C03EFFFDFD216F9E0B21576E482F941C7195893B72B5B1F70D",
|
|
"version": "not an int"
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(
|
|
syntaxCheckXPOP(raw, env.journal).has_value() == false);
|
|
}
|
|
|
|
// XPOP.validation.unl entry has wrong format
|
|
|
|
// valid xpop
|
|
{
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": "JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/ikfgf9SZOlOGcBcBJAw44PLjH+HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+IILJIiIKU/+1Uxx0FRpQbMDA==",
|
|
"blob": "eyJzZXF1ZW5jZSI6MiwiZXhwaXJhdGlvbiI6NzQxMzk4NDAwLCJ2YWxpZGF0b3JzIjpbeyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDM4QkQ0NDVBRkQ2MjE1OTYyMENDMTk2QzI2NjhBMjZCNkZCQjM2QjA5OUVCNTVCMzhBNThDMTFDMTIwNERFNUMiLCJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlETUdXd21hS0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S28raDd6aGFYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2TmRWZnBudkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWGdTMVJMbG9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lOU0RENmJYdlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcDdWRm9YYm5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURCRUUzMEZBRTkyRUVFODhFMUM0OTgwRDA5RUNGREU5OUExMTZEMDc4RUMyMTg1N0RCMUI0N0I0MjY0MThFNDI4IiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeHRIdENaQmprS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VGclU0bnJFcVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3TjZpa1ZFQkk2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQxQVVnOVg4WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RTlTanVMUjZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9jeWNyRi9DdFNBND0ifV19",
|
|
"signature": "849F6B8DA6E11C213B561659C16F13D35385E8EA9E775483ADC84578F6D578943DE5EB681584B2C03EFFFDFD216F9E0B21576E482F941C7195893B72B5B1F70D",
|
|
"version": 1
|
|
}
|
|
}
|
|
})json";
|
|
Blob raw = Blob(strJson.begin(), strJson.end());
|
|
BEAST_EXPECT(syntaxCheckXPOP(raw, env.journal).has_value() == true);
|
|
}
|
|
}
|
|
|
|
void
|
|
testGetVLInfo(FeatureBitset features)
|
|
{
|
|
testcase("import utils - getVLInfo");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(11111)};
|
|
|
|
std::string strJson = R"json({
|
|
"ledger": {
|
|
"acroot": "DCE36DCACDCFCB3441866E09A183B7B8064B3F5E06593CD6AA8ACCC1B284B477",
|
|
"txroot": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"phash": "BAB19E13B25251A83493073F424FD986EA7BA49F9F4C83A061700131460D747D",
|
|
"close": 738786851,
|
|
"coins": "99999998999999868",
|
|
"cres": 10,
|
|
"flags": 10,
|
|
"pclose": 738786851
|
|
},
|
|
"transaction": {
|
|
"blob": "12000322000000002400000002201B0000006C201D0000535968400000003B9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519560F81148EA87CA747AF74EE03A7E36C0F8EB1C1568D588A",
|
|
"meta": "201C00000000F8E51100612500000052553CEFE169D8DB251A7757C8A80214D7466E81FB2EF6A91E0970B428326B2134EB56A92E4B1340C656FE01A66D529BB7957EAD34D9E193D190EA62AAE4764B5B08C5E624000000026240000000773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481148EA87CA747AF74EE03A7E36C0F8EB1C1568D588AE1E1F1031000",
|
|
"proof": {
|
|
"children": {
|
|
"3": {
|
|
"children": {},
|
|
"hash": "AA126BA0486ADAE575BBC5335E42E236275A452037CA9A876D1A8CDACA1AE542",
|
|
"key": "39D6F6AB7D0A827DD1502B7B9571626A2B601DBE5BC786EF8ADD00E0CB7FCEB3"
|
|
}
|
|
},
|
|
"hash": "409C8D073DDB5AB07FD2CD4F14467A8F3BC8FFBA16A0032D12D823D8511C12F4",
|
|
"key": "0000000000000000000000000000000000000000000000000000000000000000"
|
|
}
|
|
},
|
|
"validation": {
|
|
"data": {
|
|
"n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN": "22800000012600000059292C08FE225149FB62BB67011E9C3F641848E32A209CEAD98BD4D73A78A11F2F92E4AFA65F6A50177BC1723CF6FEDBE539067FF3EA2CF5ADF8FD611DA22B682617DB782041BCA913732103D4A61C3C4E882313665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76473045022100E53006BDE6CB3ECB7FD08711B103DFD793438751DDFBED5DC421A3C7DE3545C4022045A2332222261A55153A338930545A5F463DAC2E1BF56C4CE5E02726E919A714"
|
|
},
|
|
"unl": {
|
|
"public_key": "ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1CDC1",
|
|
"manifest": "JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/ikfgf9SZOlOGcBcBJAw44PLjH+HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+IILJIiIKU/+1Uxx0FRpQbMDA==",
|
|
"blob": "eyJzZXF1ZW5jZSI6MiwiZXhwaXJhdGlvbiI6NzQxMzk4NDAwLCJ2YWxpZGF0b3JzIjpbeyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDM4QkQ0NDVBRkQ2MjE1OTYyMENDMTk2QzI2NjhBMjZCNkZCQjM2QjA5OUVCNTVCMzhBNThDMTFDMTIwNERFNUMiLCJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlETUdXd21hS0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S28raDd6aGFYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2TmRWZnBudkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWGdTMVJMbG9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lOU0RENmJYdlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcDdWRm9YYm5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRURCRUUzMEZBRTkyRUVFODhFMUM0OTgwRDA5RUNGREU5OUExMTZEMDc4RUMyMTg1N0RCMUI0N0I0MjY0MThFNDI4IiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeHRIdENaQmprS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VGclU0bnJFcVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3TjZpa1ZFQkk2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQxQVVnOVg4WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RTlTanVMUjZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9jeWNyRi9DdFNBND0ifV19",
|
|
"signature": "849F6B8DA6E11C213B561659C16F13D35385E8EA9E775483ADC84578F6D578943DE5EB681584B2C03EFFFDFD216F9E0B21576E482F941C7195893B72B5B1F70D",
|
|
"version": 1
|
|
}
|
|
}
|
|
})json";
|
|
|
|
Json::Value xpop;
|
|
Json::Reader reader;
|
|
reader.parse(strJson, xpop);
|
|
Json::FastWriter writer;
|
|
|
|
// Import: unl blob was not valid json (after base64 decoding)
|
|
{
|
|
Json::Value tmpXpop = xpop;
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] = "YmFkSnNvbg==";
|
|
std::string strJson = writer.write(tmpXpop);
|
|
Blob raw(strJson.begin(), strJson.end());
|
|
auto const xpop = syntaxCheckXPOP(raw, env.journal);
|
|
BEAST_EXPECT(getVLInfo(*xpop, env.journal).has_value() == false);
|
|
}
|
|
|
|
// Import: failed to deserialize manifest
|
|
{
|
|
Json::Value tmpXpop = xpop;
|
|
tmpXpop[jss::validation][jss::unl][jss::manifest] = "YmFkSnNvbg==";
|
|
std::string strJson = writer.write(tmpXpop);
|
|
Blob raw(strJson.begin(), strJson.end());
|
|
auto const xpop = syntaxCheckXPOP(raw, env.journal);
|
|
BEAST_EXPECT(getVLInfo(*xpop, env.journal).has_value() == false);
|
|
}
|
|
|
|
// Import: valid unl blob
|
|
{
|
|
Json::Value tmpXpop = xpop;
|
|
std::string strJson = writer.write(tmpXpop);
|
|
Blob raw(strJson.begin(), strJson.end());
|
|
auto const xpop = syntaxCheckXPOP(raw, env.journal);
|
|
auto const [seq, masterKey] = *getVLInfo(*xpop, env.journal);
|
|
BEAST_EXPECT(std::to_string(seq) == "2");
|
|
BEAST_EXPECT(
|
|
strHex(masterKey) ==
|
|
"ED74D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1"
|
|
"CDC1");
|
|
}
|
|
}
|
|
|
|
void
|
|
testEnabled(FeatureBitset features)
|
|
{
|
|
testcase("enabled");
|
|
using namespace jtx;
|
|
using namespace std::literals::chrono_literals;
|
|
|
|
for (bool const withImport : {false, true})
|
|
{
|
|
// If the Import amendment is not enabled, you should not be able
|
|
// to import.
|
|
auto const amend = withImport ? features : features - featureImport;
|
|
Env env{*this, makeNetworkConfig(21337), amend};
|
|
|
|
// setup env
|
|
auto const alice = Account("alice");
|
|
env.fund(XRP(1000), alice);
|
|
env.close();
|
|
|
|
auto const txResult =
|
|
withImport ? ter(tesSUCCESS) : ter(temDISABLED);
|
|
auto const ownerDir = withImport ? 1 : 0;
|
|
|
|
// IMPORT - Account Set
|
|
env(import(alice, loadXpop(ImportTCAccountSet::w_seed)), txResult);
|
|
env.close();
|
|
|
|
}
|
|
}
|
|
|
|
void
|
|
testInvalidPreflight(FeatureBitset features)
|
|
{
|
|
testcase("import invalid preflight");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
|
|
env.fund(XRP(1000), alice, bob);
|
|
env.close();
|
|
|
|
//----------------------------------------------------------------------
|
|
// preflight
|
|
|
|
// temDISABLED - disabled - CHECKED IN ENABLED
|
|
// return ret; - preflight1 no success
|
|
|
|
// temMALFORMED - sfFee cannot be 0
|
|
{
|
|
Json::Value tx = import(alice, loadXpop(ImportTCAccountSet::w_seed));
|
|
STAmount const& fee = XRP(10);
|
|
tx[jss::Fee] = fee.getJson(JsonOptions::none);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
//* DA: Technically breaking the size throws before preflight
|
|
// temMALFORMED
|
|
// temMALFORMED - Import: blob was more than 512kib
|
|
// {
|
|
// ripple::Blob blob;
|
|
// blob.resize(513 * 1024);
|
|
// env(import(alice, blob), ter(temMALFORMED));
|
|
// }
|
|
|
|
// temMALFORMED - sfAmount field must be in drops
|
|
{
|
|
Json::Value tx = import(alice, loadXpop(ImportTCAccountSet::w_seed));
|
|
STAmount const& amount = XRP(-1);
|
|
tx[jss::Amount] = amount.getJson(JsonOptions::none);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - !xpop | XPOP.validation is not a JSON object
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation] = {}; // one of many ways to throw error
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: validation.unl.public_key was not valid hex
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::public_key] = "not a hex";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: validation.unl.public_key was not a recognised
|
|
// public key type
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::public_key] =
|
|
"0084D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1"
|
|
"CDC1";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// getInnerTxn - !xpop
|
|
// DA: Duplicate -
|
|
|
|
// getInnerTxn - failed to deserialize tx blob inside xpop (invalid hex)
|
|
// DA: Duplicate - "XPOP.transaction.blob missing or wrong format"
|
|
|
|
// getInnerTxn - failed to deserialize tx meta inside xpop (invalid hex)
|
|
// DA: Duplicate - "XPOP.transaction.meta missing or wrong format"
|
|
|
|
// getInnerTxn - failed to deserialize tx blob/meta inside xpop
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] = "DEADBEEF";
|
|
tmpXpop[jss::transaction][jss::meta] = "DEADBEEF";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// // temMALFORMED - !stpTrans
|
|
// // DA: Duplicate - getInnerTxn (Any Failure)
|
|
|
|
// temMALFORMED - Import: attempted to import xpop containing an emitted
|
|
// or pseudo txn.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"12000322000000002400000002201B00000069201D0000535968400000003B"
|
|
"9ACA0073210388935426E0D08083314842EDFBB2D517BD47699F9A4527318A"
|
|
"8E10468C97C0527446304402200E40CA821A7BFE347448FFA6540F67C7FFBF"
|
|
"0287756D324DFBADCEDE2B23782C02207BE1B1294F1A1D5AC21990740B78F9"
|
|
"C0693431237D6E07FE84228082986E50FF8114AE123A8556F3CF9115471137"
|
|
"6AFB0F894F832B3DED202E000000013D00000000000000015B2200676F4B9B"
|
|
"45C5ADE9DE3C8CD01200CB12DFF8C792220DB088FE615BE5C2905C207064D8"
|
|
"1954F6A7225A8BAADF5A3042016BFB87355D1D0AFEDBAA8FB22F98355D745F"
|
|
"398EEE9E6B294BBE6A5681A31A6107243D19384E277B5A7B1F23B8C83DE78A"
|
|
"14AE123A8556F3CF91154711376AFB0F894F832B3DE1";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: inner txn lacked transaction result
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::meta] =
|
|
"201C00000006F8E5110061250000005655463E39A6AFDDA77DBF3591BF3C2A"
|
|
"4BE9BB8D9113BF6D0797EB403C3D0D894FEF5692FA6A9FC8EA6018D5D16532"
|
|
"D7795C91BFB0831355BDFDA177E86C8BF997985FE624000000026240000000"
|
|
"773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481"
|
|
"14AE123A8556F3CF91154711376AFB0F894F832B3DE1E1F1";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: inner txn did not have a tesSUCCESS or tec
|
|
// result
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::meta] =
|
|
"201C00000006F8E5110061250000005655463E39A6AFDDA77DBF3591BF3C2A"
|
|
"4BE9BB8D9113BF6D0797EB403C3D0D894FEF5692FA6A9FC8EA6018D5D16532"
|
|
"D7795C91BFB0831355BDFDA177E86C8BF997985FE624000000026240000000"
|
|
"773593F4E1E7220000000024000000032D0000000162400000003B9AC9F481"
|
|
"14AE123A8556F3CF91154711376AFB0F894F832B3DE1E1F103103C";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: import and txn inside xpop must be signed by
|
|
// the same account
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value tx = import(bob, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: attempted to import xpop containing a txn with
|
|
// a sfNetworkID field.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"120003210000535922000000002400000002201B00000069201D0000535968"
|
|
"400000003B9ACA0073210388935426E0D08083314842EDFBB2D517BD47699F"
|
|
"9A4527318A8E10468C97C0527446304402200E40CA821A7BFE347448FFA654"
|
|
"0F67C7FFBF0287756D324DFBADCEDE2B23782C02207BE1B1294F1A1D5AC219"
|
|
"90740B78F9C0693431237D6E07FE84228082986E50FF8114AE123A8556F3CF"
|
|
"91154711376AFB0F894F832B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: OperationLimit missing from inner xpop txn.
|
|
// outer txid:
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"12000322000000002400000002201B0000006C68400000003B9ACA007321ED"
|
|
"A8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C"
|
|
"747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F"
|
|
"232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C51"
|
|
"77C519560F8114AE123A8556F3CF91154711376AFB0F894F832B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: Wrong network ID for OperationLimit in inner
|
|
// txn. outer txid:
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"12000322000000002400000002201B0000006C201D0000535A68400000003B"
|
|
"9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62"
|
|
"ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593EC"
|
|
"C21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF"
|
|
"3EC206AD3C5177C519560F8114AE123A8556F3CF91154711376AFB0F894F83"
|
|
"2B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(telWRONG_NETWORK));
|
|
}
|
|
|
|
// temMALFORMED - Import: inner txn must be an AccountSet, SetRegularKey
|
|
// or SignerListSet transaction.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"12006322000000002400000002201B0000006C201D0000535968400000003B"
|
|
"9ACA007321EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62"
|
|
"ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593EC"
|
|
"C21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF"
|
|
"3EC206AD3C5177C519560F8114AE123A8556F3CF91154711376AFB0F894F83"
|
|
"2B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: outer and inner txns were (multi) signed with
|
|
// different keys.
|
|
|
|
// temMALFORMED - Import: outer and inner txns were signed with
|
|
// different keys.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"12000322000000002400000002201B0000006C201D0000535968400000003B"
|
|
"9ACA007321EBA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62"
|
|
"ECAD0AE4A96C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593EC"
|
|
"C21B3C79EF0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF"
|
|
"3EC206AD3C5177C519560F8114AE123A8556F3CF91154711376AFB0F894F83"
|
|
"2B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: inner txn signature verify failed
|
|
// DA: TODO: ASK FOR HELP
|
|
|
|
// temMALFORMED - Import: failed to deserialize manifest on txid
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::manifest] = "YmFkSnNvbg==";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: manifest master key did not match top level
|
|
// master key in unl section of xpop
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::manifest] =
|
|
"JAAAAAFxIe2E1ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+"
|
|
"b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkAnUjfY5zOEkhq31tU4338"
|
|
"jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/"
|
|
"ikfgf9SZOlOGcBcBJAw44PLjH+"
|
|
"HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+"
|
|
"IILJIiIKU/+1Uxx0FRpQbMDA==";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: manifest signature invalid
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::manifest] =
|
|
"JAAAAAFxIe101ANsZZGkvfnFTO+jm5lqXc5fhtEf2hh0SBzp1aHNwXMh7TN9+"
|
|
"b62cZqTngaFYU5tbGpYHC8oYuI3G3vwj9OW2Z9gdkA3UjfY5zOEkhq31tU4338"
|
|
"jcyUpVA5/VTsANFce7unDo+JeVoEhfuOb/Y8WA3Diu9XzuOD4U/"
|
|
"ikfgf9SZOlOGcBcBJAw34PLjH+"
|
|
"HUtEnwX45lIRmo0x5aINFMvZsBpE9QteSDBXKwYzLdnSW4e1bs21o+"
|
|
"IILJIiIKU/+1Uxx0FRpQbMDA==";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: unl blob not signed correctly
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::signature] =
|
|
"949F6B8DA6E11C213B561659C16F13D35385E8EA9E775483ADC84578F6D578"
|
|
"943DE5EB681584B2C03EFFFDFD216F9E0B21576E482F941C7195893B72B5B1"
|
|
"F70D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: unl blob not signed correctly
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::signature] = "not a hex";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// DA: GOOD SIGNATURE NOT JSON
|
|
// temMALFORMED - Import: unl blob was not valid json (after base64
|
|
// decoding)
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] = "YmFkSnNvbg==";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// DA: GOOD SIGNATURE GOOD JSON MISSING FIELDS
|
|
// temMALFORMED - Import: unl blob json (after base64 decoding) lacked
|
|
// required fields and/or types
|
|
|
|
// temMALFORMED - Import: unl blob validUntil <= validFrom
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] =
|
|
"eyJzZXF1ZW5jZSI6MSwiZWZmZWN0aXZlIjowLCJleHBpcmF0aW9uIjowLCJ2YW"
|
|
"xpZGF0b3JzIjpbeyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDM4QkQ0NDVB"
|
|
"RkQ2MjE1OTYyMENDMTk2QzI2NjhBMjZCNkZCQjM2QjA5OUVCNTVCMzhBNThDMT"
|
|
"FDMTIwNERFNUMiLCJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlE"
|
|
"TUdXd21hS0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S2"
|
|
"8raDd6aGFYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2"
|
|
"TmRWZnBudkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWG"
|
|
"dTMVJMbG9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lO"
|
|
"U0RENmJYdlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcD"
|
|
"dWRm9YYm5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsidmFsaWRhdGlv"
|
|
"bl9wdWJsaWNfa2V5IjoiRURCRUUzMEZBRTkyRUVFODhFMUM0OTgwRDA5RUNGRE"
|
|
"U5OUExMTZEMDc4RUMyMTg1N0RCMUI0N0I0MjY0MThFNDI4IiwibWFuaWZlc3Qi"
|
|
"OiJKQUFBQUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeH"
|
|
"RIdENaQmprS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VG"
|
|
"clU0bnJFcVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3Tj"
|
|
"Zpa1ZFQkk2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQx"
|
|
"QVVnOVg4WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RT"
|
|
"lTanVMUjZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9j"
|
|
"eWNyRi9DdFNBND0ifV19";
|
|
tmpXpop[jss::validation][jss::unl][jss::signature] =
|
|
"2B3C0ECB63C82454522188337354C480693A9BCD64E776B4DBAD4C61B9E72D"
|
|
"D4CC1DC237B06891E57C623C38506FE8E01B1914C9413471BCC160111E2829"
|
|
"7606";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: unl blob expired
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] =
|
|
"eyJzZXF1ZW5jZSI6MSwiZWZmZWN0aXZlIjowLCJleHBpcmF0aW9uIjoxLCJ2YW"
|
|
"xpZGF0b3JzIjpbeyJ2YWxpZGF0aW9uX3B1YmxpY19rZXkiOiJFRDM4QkQ0NDVB"
|
|
"RkQ2MjE1OTYyMENDMTk2QzI2NjhBMjZCNkZCQjM2QjA5OUVCNTVCMzhBNThDMT"
|
|
"FDMTIwNERFNUMiLCJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlE"
|
|
"TUdXd21hS0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S2"
|
|
"8raDd6aGFYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2"
|
|
"TmRWZnBudkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWG"
|
|
"dTMVJMbG9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lO"
|
|
"U0RENmJYdlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcD"
|
|
"dWRm9YYm5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsidmFsaWRhdGlv"
|
|
"bl9wdWJsaWNfa2V5IjoiRURCRUUzMEZBRTkyRUVFODhFMUM0OTgwRDA5RUNGRE"
|
|
"U5OUExMTZEMDc4RUMyMTg1N0RCMUI0N0I0MjY0MThFNDI4IiwibWFuaWZlc3Qi"
|
|
"OiJKQUFBQUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeH"
|
|
"RIdENaQmprS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VG"
|
|
"clU0bnJFcVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3Tj"
|
|
"Zpa1ZFQkk2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQx"
|
|
"QVVnOVg4WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RT"
|
|
"lTanVMUjZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9j"
|
|
"eWNyRi9DdFNBND0ifV19";
|
|
tmpXpop[jss::validation][jss::unl][jss::signature] =
|
|
"FA82662A23EC78E9644C65F752B7A58F61F35AC36C260F9E9D5CAC7D53D16D"
|
|
"5D615A02A6462F2618C162D089AD2E3BA7D656728392180517A81B4C47F86A"
|
|
"640D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: unl blob not yet valid
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] =
|
|
"eyJzZXF1ZW5jZSI6MSwiZWZmZWN0aXZlIjozNjAwLCJleHBpcmF0aW9uIjo4Nj"
|
|
"QwMCwidmFsaWRhdG9ycyI6W3sidmFsaWRhdGlvbl9wdWJsaWNfa2V5IjoiRUQz"
|
|
"OEJENDQ1QUZENjIxNTk2MjBDQzE5NkMyNjY4QTI2QjZGQkIzNkIwOTlFQjU1Qj"
|
|
"M4QTU4QzExQzEyMDRERTVDIiwibWFuaWZlc3QiOiJKQUFBQUFKeEllMDR2VVJh"
|
|
"L1dJVmxpRE1HV3dtYUtKcmI3czJzSm5yVmJPS1dNRWNFZ1RlWEhNaEFvR01OY3"
|
|
"NnVVVOd0tvK2g3emhhWEtGK0hHdzZYaEVqb0RLcmFsa1luTWpLZGtjd1JRSWhB"
|
|
"SjdjTjRKNk5kVmZwbnZFSS9aZXVXQ1R2bnBhSmlyS05GY0Mzek1Pamd3akFpQW"
|
|
"JLSTBmYlhnUzFSTGxvTmh4ZEhoVnE5b3pFV1ZFOWNJd1hETjNBeHF5WTNBU1FD"
|
|
"dDArdS9pTlNERDZiWHZVVHRkbXQ0TnJ0bGJ4NFZ6dW1UcGZqUllwNGxNb0kvaD"
|
|
"QzcFVUanA3VkZvWGJuS1dqVmhxTmFHbTU3N0s2SjY5N1haN1RRRT0ifSx7InZh"
|
|
"bGlkYXRpb25fcHVibGljX2tleSI6IkVEQkVFMzBGQUU5MkVFRTg4RTFDNDk4ME"
|
|
"QwOUVDRkRFOTlBMTE2RDA3OEVDMjE4NTdEQjFCNDdCNDI2NDE4RTQyOCIsIm1h"
|
|
"bmlmZXN0IjoiSkFBQUFBSnhJZTIrNHcrdWt1N29qaHhKZ05DZXo5NlpvUmJRZU"
|
|
"93aGhYMnh0SHRDWkJqa0tITWhBOVNtSER4T2lDTVRabDVuUnhycDJ5aldaNWdq"
|
|
"eDJEcm9VRnJVNG5yRXFVN2RrY3dSUUloQUxkRUZlalkrcFVuZ2xpN3NUdmliME"
|
|
"JtREhQN042aWtWRUJJNkg3SXdVMXpBaUJkc3lvU3FQY0MyTk1xZ0FuSFhIR2Rr"
|
|
"QUl3QlFEMUFVZzlYOFpKTHlmY3dIQVNRQ3QxYktWek9NeFJRbVIzd05LNGRLZG"
|
|
"9mSUdyeEU5U2p1TFI2UGE4QjVuMDhTWUo4SzYyZ2UrOWE2QnRaYWxFbS9IT2Rj"
|
|
"ejBOQUZPY3ljckYvQ3RTQTQ9In1dfQ";
|
|
tmpXpop[jss::validation][jss::unl][jss::signature] =
|
|
"9CCA07A3EDD1334D5ADCB3730D8F3F9BD1E0C338100384C7B15B6A910F96BE"
|
|
"4F46E3052B37E9FE2E7DC9918BD85B9E871923AE1BDD7144EE2A92F625064C"
|
|
"570C";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: depth > 32
|
|
// temMALFORMED - Import: !proof->isObject() && !proof->isArray()
|
|
// DA: Catchall Error
|
|
// temMALFORMED - Import: return false
|
|
|
|
// temMALFORMED - Import: xpop proof did not contain the specified txn
|
|
// hash
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::proof][jss::children]["D"]
|
|
[jss::children]["7"][jss::hash] =
|
|
"12D47E7D543E15F1EDBA91CDF335722727851BDDA8C2FF8924772AD"
|
|
"C6B522A29";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// // temMALFORMED - Import: depth > 32
|
|
// // temMALFORMED - Import: !proof.isObject() && !proof.isArray()
|
|
// // DA: CatchAll Error
|
|
|
|
// temMALFORMED - Import: computed txroot does not match xpop txroot,
|
|
// invalid xpop.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::proof][jss::children]["3"]
|
|
[jss::hash] =
|
|
"22D47E7D543E15F1EDBA91CDF335722727851BDDA8C2FF8924772AD"
|
|
"C6B522A29";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: error parsing coins | phash | acroot in the
|
|
// ledger section of XPOP.
|
|
|
|
// temMALFORMED - Import: unl blob contained invalid validator entry,
|
|
// skipping
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] =
|
|
"eyJzZXF1ZW5jZSI6MiwiZXhwaXJhdGlvbiI6NzQxMzk4NDAwLCJ2YWxpZGF0b3"
|
|
"JzIjpbeyJtYW5pZmVzdCI6IkpBQUFBQUp4SWUwNHZVUmEvV0lWbGlETUdXd21h"
|
|
"S0pyYjdzMnNKbnJWYk9LV01FY0VnVGVYSE1oQW9HTU5jc2dVVU53S28raDd6aG"
|
|
"FYS0YrSEd3NlhoRWpvREtyYWxrWW5Naktka2N3UlFJaEFKN2NONEo2TmRWZnBu"
|
|
"dkVJL1pldVdDVHZucGFKaXJLTkZjQzN6TU9qZ3dqQWlBYktJMGZiWGdTMVJMbG"
|
|
"9OaHhkSGhWcTlvekVXVkU5Y0l3WEROM0F4cXlZM0FTUUN0MCt1L2lOU0RENmJY"
|
|
"dlVUdGRtdDROcnRsYng0Vnp1bVRwZmpSWXA0bE1vSS9oNDNwVVRqcDdWRm9YYm"
|
|
"5LV2pWaHFOYUdtNTc3SzZKNjk3WFo3VFFFPSJ9LHsibWFuaWZlc3QiOiJKQUFB"
|
|
"QUFKeEllMis0dyt1a3U3b2poeEpnTkNlejk2Wm9SYlFlT3doaFgyeHRIdENaQm"
|
|
"prS0hNaEE5U21IRHhPaUNNVFpsNW5SeHJwMnlqV1o1Z2p4MkRyb1VGclU0bnJF"
|
|
"cVU3ZGtjd1JRSWhBTGRFRmVqWStwVW5nbGk3c1R2aWIwQm1ESFA3TjZpa1ZFQk"
|
|
"k2SDdJd1UxekFpQmRzeW9TcVBjQzJOTXFnQW5IWEhHZGtBSXdCUUQxQVVnOVg4"
|
|
"WkpMeWZjd0hBU1FDdDFiS1Z6T014UlFtUjN3Tks0ZEtkb2ZJR3J4RTlTanVMUj"
|
|
"ZQYThCNW4wOFNZSjhLNjJnZSs5YTZCdFphbEVtL0hPZGN6ME5BRk9jeWNyRi9D"
|
|
"dFNBND0ifV19=";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: unl blob contained an invalid validator key,
|
|
// skipping
|
|
// {
|
|
|
|
// }
|
|
// temMALFORMED - Import: unl blob contained an invalid manifest,
|
|
// skipping
|
|
// {
|
|
|
|
// }
|
|
// // temMALFORMED - Import: unl blob list entry manifest master key did
|
|
// // not match master key, skipping
|
|
// // temMALFORMED - Import: unl blob list entry manifest signature
|
|
// // invalid, skipping
|
|
// // temMALFORMED - Import: validator nodepub did not appear in
|
|
// validator
|
|
// // list but did appear
|
|
// // temMALFORMED - Import: validator nodepub key appears more than
|
|
// once
|
|
// // in data section
|
|
|
|
// temMALFORMED - Import: validation inside xpop was not valid hex
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value valData;
|
|
valData["n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN"] =
|
|
"not a hex";
|
|
tmpXpop[jss::validation][jss::data] = valData;
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: validation message was not for computed ledger
|
|
// hash
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value valData;
|
|
valData["n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN"] =
|
|
"22800000012600000056292C0D012051A0829745427488A59B6525231634DC"
|
|
"327F91589EB03F469ABF1C3CA32070625A501790AD68E9045001FDEED03F0A"
|
|
"C8277F11F6E46E0ABD2DC38B1F8240D56B22E4F2732103D4A61C3C4E882313"
|
|
"665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76463044022072"
|
|
"427336342AE80B7AAE407CEA611B0DA680426B3C5894E52EE2D23641D09A73"
|
|
"02203B131B68D3C5B6C5482312CC7D90D2CE131A9C46458967F2F98688B726"
|
|
"C16719";
|
|
tmpXpop[jss::validation][jss::data] = valData;
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// temMALFORMED - Import: validation inside xpop was not signed with a
|
|
// signing key we recognise
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value valData;
|
|
valData["n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN"] =
|
|
"22800000012600000056292C0D012051B0829745427488A59B6525231634DC"
|
|
"327F91589EB03F469ABF1C3CA32070625A501790BD68E9045001FDEED03F0A"
|
|
"C8277F11F6E46E0ABD2DC38B1F8240D56B22E4F2732103E4A61C3C4E882313"
|
|
"665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76463054022072"
|
|
"427336342AE80B7AAE407CEA611B0DA680426B3C5894E52EE2D23641D09A73"
|
|
"02203B131B68D3C5B6C5482312CC7D90D2CE131A9C46458967F2F98688B726"
|
|
"C16719";
|
|
tmpXpop[jss::validation][jss::data] = valData;
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// temMALFORMED - Import: validation inside xpop was not correctly
|
|
// signed
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value valData;
|
|
valData["n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN"] =
|
|
"22800000012600000056292C0D012051B0829745427488A59B6525231634DC"
|
|
"327F91589EB03F469ABF1C3CA32070625A501790BD68E9045001FDEED03F0A"
|
|
"C8277F11F6E46E0ABD2DC38B1F8240D56B22E4F2732103D4A61C3C4E882313"
|
|
"665E67471AE9DB28D6679823C760EBA1416B5389EB12A53B76463044022072"
|
|
"427336342AE80B7AAE407CEA611B0DA680426B3C5894E52EE2D23641D09A73"
|
|
"02203B131B68D3C5B6C5482312CC7D90D2CE131A9C46458967F2F98688B726"
|
|
"C16719";
|
|
tmpXpop[jss::validation][jss::data] = valData;
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: validation inside xpop was not able to be
|
|
// parsed DA: Unknown Catch All
|
|
|
|
// temMALFORMED - Import: xpop did not contain an 80% quorum for the txn
|
|
// it purports to prove.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value valData;
|
|
valData["n94at1vSdHSBEun25yT4ZfgqD1tVQNsx1nqRZG3T6ygbuvwgcMZN"] =
|
|
"";
|
|
valData["n9KXYzdZD8YpsNiChtMjP6yhvQAhkkh5XeSTbvYyV1waF8wkNnBT"] =
|
|
"";
|
|
tmpXpop[jss::validation][jss::data] = valData;
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// temMALFORMED - Import: xpop inner txn did not contain a sequence
|
|
// number or fee No Sequence
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"1200632200000000201B0000006C201D0000535968400000003B9ACA007321"
|
|
"EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A9"
|
|
"6C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF"
|
|
"0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C"
|
|
"5177C519560F8114AE123A8556F3CF91154711376AFB0F894F832B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// No Fee
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"12006322000000002400000002201B0000006C201D000053597321EDA8D46E"
|
|
"11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A96C747440"
|
|
"549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF0F232EB4"
|
|
"375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C5177C519"
|
|
"560F8114AE123A8556F3CF91154711376AFB0F894F832B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// Bad Fee - TODO
|
|
}
|
|
|
|
void
|
|
testInvalidPreclaim(FeatureBitset features)
|
|
{
|
|
testcase("import invalid preclaim");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
|
|
env.fund(XRP(1000), alice, bob);
|
|
env.close();
|
|
|
|
//----------------------------------------------------------------------
|
|
// preclaim
|
|
|
|
// temDISABLED - disabled - CHECKED IN ENABLED
|
|
// tefINTERNAL/temMALFORMED - during preclaim could not parse xpop,
|
|
// bailing.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation] = {}; // one of many ways to throw error
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// tefINTERNAL/temMALFORMED - during preclaim could not find
|
|
// importSequence, bailing.
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"1200632200000000201B0000006C201D0000535968400000003B9ACA007321"
|
|
"EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A9"
|
|
"6C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF"
|
|
"0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C"
|
|
"5177C519560F8114AE123A8556F3CF91154711376AFB0F894F832B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// tefPAST_IMPORT_SEQ -
|
|
{
|
|
env(import(alice, loadXpop(ImportTCAccountSet::w_seed)),
|
|
ter(tesSUCCESS));
|
|
env(import(alice, loadXpop(ImportTCAccountSet::min)),
|
|
ter(tefPAST_IMPORT_SEQ));
|
|
}
|
|
|
|
// tefINTERNAL/temMALFORMED - !vlInfo
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] = "YmFkSnNvbg==";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// tefPAST_IMPORT_VL_SEQ - sfImportSequence > vlInfo->first
|
|
// {
|
|
// Json::Value tx = import(alice, loadXpop(ImportTCAccountSet::w_seed)); env(tx, ter(tefPAST_IMPORT_SEQ));
|
|
// }
|
|
|
|
// telIMPORT_VL_KEY_NOT_RECOGNISED - Import: (fromchain) key does not
|
|
// match (tochain) key
|
|
// {
|
|
// Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
// tmpXpop[jss::validation][jss::unl][jss::public_key] =
|
|
// "ED84D4036C6591A4BDF9C54CEFA39B996A5DCE5F86D11FDA1874481CE9D5A1"
|
|
// "CDC1";
|
|
// Json::Value tx = import(alice, tmpXpop);
|
|
// env(tx, ter(telIMPORT_VL_KEY_NOT_RECOGNISED));
|
|
// }
|
|
}
|
|
|
|
void
|
|
testInvalidDoApply(FeatureBitset features)
|
|
{
|
|
testcase("import invalid doApply");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
|
|
env.fund(XRP(1000), alice, bob);
|
|
env.close();
|
|
|
|
//----------------------------------------------------------------------
|
|
// doApply
|
|
|
|
// temDISABLED - disabled
|
|
// DA: Sanity Check
|
|
|
|
// tefINTERNAL/temMALFORMED - ctx_.tx.isFieldPresent(sfBlob)
|
|
{
|
|
Json::Value tx;
|
|
tx[jss::TransactionType] = jss::Import;
|
|
tx[jss::Account] = alice.human();
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// tefINTERNAL/temMALFORMED - !xpop
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation] = {}; // one of many ways to throw error
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// tefINTERNAL/temMALFORMED - during apply could not find importSequence
|
|
// or fee, bailing.
|
|
// No Fee
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::transaction][jss::blob] =
|
|
"1200632200000000201B0000006C201D0000535968400000003B9ACA007321"
|
|
"EDA8D46E11FD5D2082A4E6FF3039EB6259FBC2334983D015FC62ECAD0AE4A9"
|
|
"6C747440549A370E68DBB1947419D4CCDF90CAE0BCA9121593ECC21B3C79EF"
|
|
"0F232EB4375F95F1EBCED78B94D09838B5E769D43F041019ADEF3EC206AD3C"
|
|
"5177C519560F8114AE123A8556F3CF91154711376AFB0F894F832B3D";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
// No Sequence
|
|
|
|
// tefINTERNAL - initBal <= beast::zero
|
|
// Sanity Check
|
|
|
|
// tefINTERNAL - ImportSequence passed
|
|
// Sanity Check (tefPAST_IMPORT_SEQ)
|
|
|
|
// tefINTERNAL/temMALFORMED - !infoVL
|
|
{
|
|
Json::Value tmpXpop = loadXpop(ImportTCAccountSet::w_seed);
|
|
tmpXpop[jss::validation][jss::unl][jss::blob] = "YmFkSnNvbg==";
|
|
Json::Value tx = import(alice, tmpXpop);
|
|
env(tx, ter(temMALFORMED));
|
|
}
|
|
|
|
// tefINTERNAL - current > infoVL->first
|
|
// Sanity Check (tefPAST_IMPORT_VL_SEQ)
|
|
}
|
|
|
|
void
|
|
testAccountSet(FeatureBitset features)
|
|
{
|
|
testcase("account set tx");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// w/ seed -> dne (bad signer)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value tx = import(bob, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, bob, ter(temMALFORMED));
|
|
env.close();
|
|
|
|
// confirm fee was not minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice);
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins);
|
|
|
|
// confirm account does not exist
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle == nullptr);
|
|
}
|
|
|
|
// w/ seed -> dne
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
Json::Value tx = import(alice, loadXpop(ImportTCAccountSet::w_seed));
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + XRP(1000) + XRP(2));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// confirm account exists
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle != nullptr);
|
|
env(noop(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ regular key other -> dne (bad signer)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
env.memoize(carol);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx - wrong regular key
|
|
Json::Value txBad =
|
|
import(alice, loadXpop(ImportTCAccountSet::w_regular_key));
|
|
txBad[jss::Sequence] = 0;
|
|
txBad[jss::Fee] = 0;
|
|
env(txBad, alice, sig(carol), ter(temMALFORMED));
|
|
env.close();
|
|
|
|
// confirm fee was not minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice);
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins);
|
|
|
|
// confirm account does not exist
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle == nullptr);
|
|
}
|
|
|
|
// w/ regular key -> dne
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
Json::Value tx =
|
|
import(alice, loadXpop(ImportTCAccountSet::w_regular_key));
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, sig(bob), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + XRP(1000) + XRP(2));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// confirm account exists
|
|
auto const [acct, acctSle1] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle1 != nullptr);
|
|
// alice cannnot sign
|
|
env(noop(alice),
|
|
sig(alice),
|
|
fee(feeDrops),
|
|
ter(tefMASTER_DISABLED));
|
|
// bob cannot sign
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tefBAD_AUTH));
|
|
}
|
|
|
|
// // w/ signers list -> dne
|
|
// {
|
|
// test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
// auto const feeDrops = env.current()->fees().base;
|
|
|
|
// auto const master = Account("masterpassphrase");
|
|
// env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
// env.close();
|
|
|
|
// // init env
|
|
// auto const alice = Account("alice");
|
|
// auto const bob = Account("bob");
|
|
// auto const carol = Account("carol");
|
|
// env.memoize(alice);
|
|
// env.memoize(bob);
|
|
// env.memoize(carol);
|
|
|
|
// // confirm env
|
|
// auto const preCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
// auto const preAlice = env.balance(alice);
|
|
// BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// // import tx
|
|
// auto const xpopJson = loadXpop(ImportTCAccountSet::w_signers);
|
|
// Json::Value tx = import(alice, xpopJson);
|
|
// tx[jss::Sequence] = 0;
|
|
// tx[jss::Fee] = 0;
|
|
// env(
|
|
// tx,
|
|
// alice,
|
|
// msig(bob, carol),
|
|
// fee(3 * feeDrops),
|
|
// ter(tesSUCCESS)
|
|
// );
|
|
// env.close();
|
|
|
|
// // confirm fee was minted
|
|
// auto const postAlice = env.balance(alice);
|
|
// BEAST_EXPECT(postAlice == preAlice + XRP(0.00001) + XRP(2));
|
|
// auto const postCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// // confirm signers not set
|
|
// auto const k = keylet::signers(bob);
|
|
// BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
// // alice cannnot sign
|
|
// env(noop(alice), sig(alice), fee(feeDrops),
|
|
// ter(tefMASTER_DISABLED));
|
|
// }
|
|
|
|
// w/ seed -> funded
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
env.fund(XRP(1000), alice);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'980);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// import tx
|
|
env(import(alice, loadXpop(ImportTCAccountSet::w_seed)),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + XRP(1000) - XRP(0.00001));
|
|
std::cout << "postAlice: " << postAlice << "\n";
|
|
std::cout << "postAlice=: " << (preAlice + XRP(1000) - XRP(0.00001))
|
|
<< "\n";
|
|
env.close();
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'899'970);
|
|
|
|
// confirm account exists
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle != nullptr);
|
|
auto const feeDrops = env.current()->fees().base;
|
|
env(noop(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ regular key -> funded
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.fund(XRP(1000), alice, bob);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'960);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCAccountSet::w_regular_key);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
env(tx, alice, sig(bob), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + XRP(1000) - drops(1));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'899'950);
|
|
std::cout << "postAlice: " << postAlice << "\n";
|
|
std::cout << "postAlice=: " << (preAlice + XRP(1000) - drops(1))
|
|
<< "\n";
|
|
|
|
// confirm account exists bob can sign
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle != nullptr);
|
|
BEAST_EXPECT(!acctSle->isFieldPresent(sfRegularKey));
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tefBAD_AUTH));
|
|
env(noop(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ signers -> funded
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'940);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCAccountSet::w_signers);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
env(tx,
|
|
alice,
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + XRP(1000) - drops(1));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'899'910);
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
}
|
|
}
|
|
|
|
void
|
|
testAccountSetFlags(FeatureBitset features)
|
|
{
|
|
testcase("account set flags");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// account set flags not migrated
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
env.fund(XRP(1000), alice);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'980);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// import tx
|
|
env(import(alice, loadXpop(ImportTCAccountSet::w_flags)),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + drops(11));
|
|
env.close();
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'899'970);
|
|
|
|
// confirm account exists
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle != nullptr);
|
|
env(noop(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
}
|
|
|
|
void
|
|
testSetRegularKey(FeatureBitset features)
|
|
{
|
|
testcase("set regular key tx");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// w/ seed -> dne
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_seed);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + drops(12) + XRP(2));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle->getAccountID(sfRegularKey) == bob.id());
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ regular key -> dne
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
env.memoize(carol);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_regular_key);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, sig(bob), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + drops(12) + XRP(2));
|
|
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins + feeDrops - feeDrops);
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle->getAccountID(sfRegularKey) == carol.id());
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ signers -> dne
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
auto const dave = Account("dave");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
env.memoize(carol);
|
|
env.memoize(dave);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_signers);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(
|
|
tx,
|
|
alice,
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS)
|
|
);
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + XRP(2) + feeDrops +
|
|
XRP(0.000002)); std::cout << "POST ALICE: " << postAlice << "\n";
|
|
std::cout << "POST ALICE CALC: " << (preAlice + XRP(2) + feeDrops
|
|
+ XRP(0.000002)) << "\n";
|
|
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins + feeDrops - feeDrops);
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle && acctSle->isFieldPresent(sfRegularKey) &&
|
|
acctSle->getAccountID(sfRegularKey) == dave.id());
|
|
env(noop(alice), sig(dave), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ seed -> funded
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.fund(XRP(1000), alice, bob);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'960);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_seed);
|
|
env(import(alice, xpopJson), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice - feeDrops + drops(12));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'899'950);
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle->getAccountID(sfRegularKey) == bob.id());
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ seed -> funded (update regular key)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'940);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the regular key
|
|
env(regkey(alice, carol));
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_seed);
|
|
env(import(alice, xpopJson), sig(alice), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice - (3 * feeDrops) + drops(12));
|
|
auto const postCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(postCoins == preCoins - (3 * feeDrops));
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle->getAccountID(sfRegularKey) == bob.id());
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ regular key -> funded (update regular key)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
auto const dave = Account("dave");
|
|
env.fund(XRP(1000), alice, bob, carol, dave);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'920);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the regular key
|
|
env(regkey(alice, dave));
|
|
env(noop(alice), sig(dave), fee(feeDrops), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_regular_key);
|
|
env(import(alice, xpopJson), sig(bob), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice - (3 * feeDrops) + drops(12));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins - (3 * feeDrops));
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle->getAccountID(sfRegularKey) == carol.id());
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// w/ signers list -> funded (update regular key)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
auto const dave = Account("dave");
|
|
auto const elsa = Account("elsa");
|
|
env.fund(XRP(1000), alice, bob, carol, dave, elsa);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'900);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the regular key
|
|
env(regkey(alice, elsa));
|
|
env(noop(alice), sig(elsa), fee(feeDrops), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_signers);
|
|
env(import(alice, xpopJson),
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + drops(12) - feeDrops);
|
|
std::cout << "POST ALICE: " << postAlice << "\n";
|
|
std::cout << "POST ALICE CALC: " << (preAlice + drops(12)) <<
|
|
"\n"; std::cout << "POST ALICE CALC: " << (preAlice + drops(12) -
|
|
(2 * feeDrops)) << "\n";
|
|
auto const postCoins = env.current()->info().drops;
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle->getAccountID(sfRegularKey) == dave.id());
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// seed -> funded (empty regular key)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'940);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the regular key
|
|
env(regkey(alice, carol));
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_seed_empty);
|
|
env(import(alice, xpopJson), sig(alice), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice - (3 * feeDrops) + drops(12));
|
|
auto const postCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(postCoins == preCoins - (3 * feeDrops));
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(!acctSle->isFieldPresent(sfRegularKey));
|
|
}
|
|
|
|
// w/ regular key -> funded (empty regular key)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'940);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the regular key
|
|
env(regkey(alice, carol));
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const xpopJson =
|
|
loadXpop(ImportTCSetRegularKey::w_regular_key_empty);
|
|
env(import(alice, xpopJson), sig(bob), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + drops(12) - (3 * feeDrops));
|
|
auto const postCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(postCoins == preCoins - (3 * feeDrops));
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(!acctSle->isFieldPresent(sfRegularKey));
|
|
env(noop(alice), sig(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tefBAD_AUTH));
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tefBAD_AUTH));
|
|
}
|
|
|
|
// w/ signers -> funded (empty regular key)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
auto const dave = Account("dave");
|
|
env.fund(XRP(1000), alice, bob, carol, dave);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'899'920);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the regular key
|
|
env(regkey(alice, dave));
|
|
env(noop(alice), sig(dave), fee(feeDrops), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const xpopJson =
|
|
loadXpop(ImportTCSetRegularKey::w_signers_empty);
|
|
env(import(alice, xpopJson),
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + drops(12) - (2 * feeDrops));
|
|
std::cout << "postAlice: " << postAlice << "\n";
|
|
std::cout << "postAlice=: " << (preAlice - (2 * feeDrops)) << "\n";
|
|
auto const postCoins = env.current()->info().drops;
|
|
// std::cout << "postCoins: " << postCoins << "\n";
|
|
// std::cout << "postCoins=: " << (preCoins - (5 * feeDrops)) << "\n";
|
|
// BEAST_EXPECT(postCoins == preCoins - (5 * feeDrops));
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(!acctSle->isFieldPresent(sfRegularKey));
|
|
env(noop(alice), sig(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tefBAD_AUTH));
|
|
env(noop(alice), sig(carol), fee(feeDrops), ter(tefBAD_AUTH));
|
|
env(noop(alice), sig(dave), fee(feeDrops), ter(tefBAD_AUTH));
|
|
}
|
|
}
|
|
|
|
void
|
|
testSetRegularKeyFlags(FeatureBitset features)
|
|
{
|
|
testcase("set regular key flags");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// dne -> dont set flag
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_seed);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm lsfPasswordSpent is set
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(
|
|
(acctSle->getFieldU32(sfFlags) & lsfPasswordSpent) == 0);
|
|
}
|
|
|
|
// funded -> set flag
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
env.fund(XRP(1000), alice, bob);
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCSetRegularKey::w_seed_zero);
|
|
env(import(alice, xpopJson), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm lsfPasswordSpent is not set
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(
|
|
(acctSle->getFieldU32(sfFlags) & lsfPasswordSpent) ==
|
|
lsfPasswordSpent);
|
|
}
|
|
}
|
|
|
|
void
|
|
testSignersListSet(FeatureBitset features)
|
|
{
|
|
testcase("signers list set tx");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// w/ seed -> dne w/ seed (Bad Fee)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
env.memoize(carol);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const xpopJson =
|
|
loadXpop(ImportTCSignersListSet::w_seed_bad_fee);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(
|
|
postAlice == preAlice + drops(12) + XRP(2));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
std::cout << "POST COINS: " << postCoins << "\n";
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
}
|
|
|
|
// w/ seed -> dne w/ seed
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
env.memoize(carol);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const burnAmt = XRP(2);
|
|
auto const xpopJson = loadXpop(ImportTCSignersListSet::w_seed);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(
|
|
postAlice ==
|
|
preAlice + drops(12) + burnAmt + XRP(2));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
}
|
|
|
|
// w/ regular key -> dne
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
auto const dave = Account("dave");
|
|
env.memoize(alice);
|
|
env.memoize(bob);
|
|
env.memoize(carol);
|
|
env.memoize(dave);
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const burnAmt = XRP(2);
|
|
auto const xpopJson = loadXpop(ImportTCSignersListSet::w_regular_key);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, sig(bob), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(
|
|
postAlice ==
|
|
preAlice + feeDrops + XRP(2) + XRP(0.000002) + burnAmt);
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
}
|
|
|
|
// // w/ signers -> dne
|
|
// {
|
|
// test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
// auto const feeDrops = env.current()->fees().base;
|
|
|
|
// // burn 100,000 xrp
|
|
// auto const master = Account("masterpassphrase");
|
|
// env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
// env.close();
|
|
|
|
// // init env
|
|
// auto const alice = Account("alice");
|
|
// auto const bob = Account("bob");
|
|
// auto const carol = Account("carol");
|
|
// env.memoize(alice);
|
|
// env.memoize(bob);
|
|
// env.memoize(carol);
|
|
|
|
// // confirm env
|
|
// auto const preCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(preCoins == 99'999'999'999'900'000);
|
|
// auto const preAlice = env.balance(alice);
|
|
// BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// // import tx
|
|
// auto const burnAmt = XRP(2);
|
|
// auto const xpopJson = loadXpop(ImportTCSignersListSet::w_signers);
|
|
// Json::Value tx = import(alice, xpopJson);
|
|
// tx[jss::Sequence] = 0;
|
|
// tx[jss::Fee] = 0;
|
|
// env(tx,
|
|
// alice,
|
|
// msig(bob, carol),
|
|
// fee(3 * feeDrops),
|
|
// ter(tesSUCCESS));
|
|
// env.close();
|
|
|
|
// // confirm fee was minted
|
|
// auto const postAlice = env.balance(alice);
|
|
// BEAST_EXPECT(
|
|
// postAlice ==
|
|
// preAlice + feeDrops + XRP(2) + XRP(0.000002) + burnAmt);
|
|
// auto const postCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// // confirm signers not set
|
|
// auto const k = keylet::signers(alice);
|
|
// BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
// }
|
|
|
|
// w/ seed -> funded
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
// auto const totalCoins = drops(100'000'000'000'000'000);
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(preCoins == totalCoins - drops(100'000) - (3 * (2 *
|
|
// feeDrops)));
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// import tx
|
|
// auto const burnAmt = XRP(2);
|
|
auto const xpopJson = loadXpop(ImportTCSignersListSet::w_seed);
|
|
env(import(alice, xpopJson), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee minted
|
|
auto const postAlice = env.balance(alice);
|
|
// BEAST_EXPECT(postAlice == preAlice + (2 * feeDrops));
|
|
std::cout << "POST ALICE: " << postAlice << "\n";
|
|
std::cout << "POST ALICE CALC: " << (preAlice + (2 * feeDrops))
|
|
<< "\n";
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins - feeDrops);
|
|
|
|
// confirm signers set
|
|
auto const [signers, signersSle] =
|
|
signersKeyAndSle(*env.current(), alice);
|
|
auto const signerEntries =
|
|
signersSle->getFieldArray(sfSignerEntries);
|
|
BEAST_EXPECT(signerEntries.size() == 2);
|
|
BEAST_EXPECT(signerEntries[0u].getFieldU16(sfSignerWeight) == 1);
|
|
BEAST_EXPECT(
|
|
signerEntries[0u].getAccountID(sfAccount) == carol.id());
|
|
BEAST_EXPECT(signerEntries[1u].getFieldU16(sfSignerWeight) == 1);
|
|
BEAST_EXPECT(signerEntries[1u].getAccountID(sfAccount) == bob.id());
|
|
|
|
// confirm multisign tx
|
|
env.close();
|
|
auto const aliceSeq = env.seq(alice);
|
|
env(noop(alice),
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
// BEAST_EXPECT(env.seq(alice) == aliceSeq + 1);
|
|
}
|
|
|
|
// w/ seed (empty) -> funded (has entries)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
// auto const totalCoins = drops(100'000'000'000'000'000);
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(preCoins == totalCoins - drops(100'000) - (3 * (2 *
|
|
// feeDrops)));
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the signers list
|
|
env(signers(alice, 2, {{bob, 1}, {carol, 1}}));
|
|
env(noop(alice),
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const burnAmt = XRP(2);
|
|
auto const xpopJson = loadXpop(ImportTCSignersListSet::w_seed_empty);
|
|
env(import(alice, xpopJson), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(
|
|
postAlice ==
|
|
preAlice + burnAmt - (4 * feeDrops) + XRP(0.000002));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins - (5 * feeDrops));
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
}
|
|
|
|
// w/ regular key (empty) -> funded (has entries)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
// auto const totalCoins = drops(100'000'000'000'000'000);
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(preCoins == totalCoins...);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the regular key
|
|
env(regkey(alice, bob));
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// set the signers list
|
|
env(signers(alice, 2, {{bob, 1}, {carol, 1}}));
|
|
env(noop(alice),
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const burnAmt = XRP(2);
|
|
auto const xpopJson =
|
|
loadXpop(ImportTCSignersListSet::w_regular_key_empty);
|
|
env(import(alice, xpopJson), sig(bob), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(
|
|
postAlice ==
|
|
preAlice + burnAmt - (6 * feeDrops) + XRP(0.000002));
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins - (7 * feeDrops));
|
|
|
|
// confirm regular key
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle->getAccountID(sfRegularKey) == bob.id());
|
|
env(noop(alice), sig(bob), fee(feeDrops), ter(tesSUCCESS));
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
}
|
|
|
|
// w/ signers (empty) -> funded (has entries)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
// auto const totalCoins = drops(100'000'000'000'000'000);
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const alice = Account("alice");
|
|
auto const bob = Account("bob");
|
|
auto const carol = Account("carol");
|
|
env.fund(XRP(1000), alice, bob, carol);
|
|
env.close();
|
|
|
|
// confirm env
|
|
auto const preCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(preCoins == totalCoins...);
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
|
|
// set the signers list
|
|
env(signers(alice, 2, {{bob, 1}, {carol, 1}}));
|
|
env(noop(alice),
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// import tx
|
|
auto const burnAmt = XRP(2);
|
|
auto const xpopJson =
|
|
loadXpop(ImportTCSignersListSet::w_signers_empty);
|
|
env(import(alice, xpopJson),
|
|
msig(bob, carol),
|
|
fee(3 * feeDrops),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(
|
|
postAlice ==
|
|
preAlice + burnAmt - (2 * feeDrops) - XRP(0.000002));
|
|
auto const postCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(postCoins == preCoins - (7 * feeDrops));
|
|
// std::cout << "postCoins: " << postCoins << "\n";
|
|
// std::cout << "postCoins=: " << (preCoins - (7 * feeDrops)) <<
|
|
// "\n";
|
|
|
|
// confirm signers not set
|
|
auto const k = keylet::signers(alice);
|
|
BEAST_EXPECT(env.current()->read(k) == nullptr);
|
|
}
|
|
}
|
|
|
|
void
|
|
testImportSequence(FeatureBitset features)
|
|
{
|
|
testcase("import sequence");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// test tefPAST_IMPORT_SEQ
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
|
|
auto const alice = Account("alice");
|
|
env.fund(XRP(1000), alice);
|
|
env.close();
|
|
|
|
auto preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(1000));
|
|
env(import(alice, loadXpop(ImportTCAccountSet::w_seed)),
|
|
ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + XRP(1000) - feeDrops);
|
|
|
|
env(import(alice, loadXpop(ImportTCAccountSet::w_seed)),
|
|
ter(tefPAST_IMPORT_SEQ));
|
|
env.close();
|
|
auto const failedAlice = env.balance(alice);
|
|
BEAST_EXPECT(failedAlice == postAlice);
|
|
}
|
|
}
|
|
|
|
void
|
|
testMaxSupply(FeatureBitset features)
|
|
{
|
|
testcase("max supply");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// burn 100'000 coins
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
auto const envCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(envCoins == 100'000'000'000'000'000);
|
|
// 100'000'000'000'000'000 - drops
|
|
// 100'000'000'000 - xrp
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000'000'000), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == envCoins - drops(100'000'000'000));
|
|
|
|
auto const alice = Account("alice");
|
|
env.memoize(alice);
|
|
|
|
auto preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
STAmount burnFee = XRP(1000) + XRP(2);
|
|
auto const xpopJson = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + burnFee);
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins + burnFee);
|
|
}
|
|
|
|
// burn all coins
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
auto const envCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(envCoins == 100'000'000'000'000'000);
|
|
|
|
// burn all but 1,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(envCoins - drops(1'000'000'000)), ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == XRP(1000));
|
|
|
|
auto const alice = Account("alice");
|
|
env.memoize(alice);
|
|
|
|
auto preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
STAmount burnFee = XRP(1000) + XRP(2);
|
|
auto const xpopJson = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + burnFee);
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins + burnFee);
|
|
}
|
|
|
|
// burn no coins
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
auto const envCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(envCoins == 100'000'000'000'000'000);
|
|
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == XRP(100'000'000'000));
|
|
|
|
auto const alice = Account("alice");
|
|
env.memoize(alice);
|
|
|
|
auto preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
STAmount burnFee = XRP(1000) + XRP(2);
|
|
auto const xpopJson = loadXpop(ImportTCAccountSet::w_seed);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tefINTERNAL));
|
|
env.close();
|
|
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice);
|
|
auto const postCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(postCoins == preCoins);
|
|
}
|
|
}
|
|
|
|
void
|
|
testMinMax(FeatureBitset features)
|
|
{
|
|
testcase("min max");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
// w/ seed -> dne (min)
|
|
{
|
|
test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
auto const feeDrops = env.current()->fees().base;
|
|
auto const envCoins = env.current()->info().drops;
|
|
auto const totalCoins = drops(100'000'000'000'000'000);
|
|
|
|
// burn 100,000 xrp
|
|
auto const master = Account("masterpassphrase");
|
|
env(noop(master), fee(100'000), ter(tesSUCCESS));
|
|
env.close();
|
|
auto const preCoins = env.current()->info().drops;
|
|
BEAST_EXPECT(preCoins == totalCoins - drops(100'000));
|
|
|
|
// init env
|
|
auto const alice = Account("alice");
|
|
env.memoize(alice);
|
|
|
|
// confirm env
|
|
auto const preAlice = env.balance(alice);
|
|
BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// import tx
|
|
auto const xpopJson = loadXpop(ImportTCAccountSet::min);
|
|
Json::Value tx = import(alice, xpopJson);
|
|
tx[jss::Sequence] = 0;
|
|
tx[jss::Fee] = 0;
|
|
env(tx, alice, ter(tesSUCCESS));
|
|
env.close();
|
|
|
|
// confirm fee was minted
|
|
auto const postAlice = env.balance(alice);
|
|
BEAST_EXPECT(postAlice == preAlice + drops(1) + XRP(2));
|
|
auto const postCoins = env.current()->info().drops;
|
|
std::cout << "POST COINS: " << postCoins << "\n";
|
|
BEAST_EXPECT(postCoins == 99'999'999'999'900'000);
|
|
|
|
// confirm account exists
|
|
auto const [acct, acctSle] =
|
|
accountKeyAndSle(*env.current(), alice);
|
|
BEAST_EXPECT(acctSle != nullptr);
|
|
env(noop(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
}
|
|
|
|
// // w/ seed -> dne (max)
|
|
// {
|
|
// test::jtx::Env env{*this, makeNetworkConfig(21337)};
|
|
|
|
// auto const feeDrops = env.current()->fees().base;
|
|
// auto const envCoins = env.current()->info().drops;
|
|
// auto const totalCoins = drops(100'000'000'000'000'000);
|
|
|
|
// // init env
|
|
// auto const alice = Account("alice");
|
|
// env.memoize(alice);
|
|
|
|
// // confirm env
|
|
// auto const preCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(preCoins == totalCoins);
|
|
// auto const preAlice = env.balance(alice);
|
|
// BEAST_EXPECT(preAlice == XRP(0));
|
|
|
|
// // import tx
|
|
// auto const xpopJson = loadXpop(ImportTCAccountSet::max);
|
|
// Json::Value tx = import(alice, xpopJson);
|
|
// tx[jss::Sequence] = 0;
|
|
// env(tx, alice, ter(tesSUCCESS));
|
|
// env.close();
|
|
|
|
// // confirm fee was minted
|
|
// auto const postAlice = env.balance(alice);
|
|
// BEAST_EXPECT(
|
|
// postAlice == preAlice + XRP(999'999'999'999'000'000) + XRP(2));
|
|
// auto const postCoins = env.current()->info().drops;
|
|
// BEAST_EXPECT(postCoins == 999'999'999'999'900'000);
|
|
// // std::cout << "POST COINS: " << postCoins << "\n";
|
|
|
|
// // confirm account exists
|
|
// auto const [acct, acctSle] =
|
|
// accountKeyAndSle(*env.current(), alice);
|
|
// BEAST_EXPECT(acctSle != nullptr);
|
|
// env(noop(alice), fee(feeDrops), ter(tesSUCCESS));
|
|
// }
|
|
}
|
|
|
|
public:
|
|
void
|
|
run() override
|
|
{
|
|
using namespace test::jtx;
|
|
FeatureBitset const all{supported_amendments()};
|
|
testWithFeats(all);
|
|
}
|
|
|
|
void
|
|
testWithFeats(FeatureBitset features)
|
|
{
|
|
testComputeStartingBalance(features);
|
|
testIsHex(features);
|
|
testIsBase58(features);
|
|
testIsBase64(features);
|
|
testParseUint64(features);
|
|
testSyntaxCheckProofObject(features);
|
|
testSyntaxCheckXPOP(features);
|
|
testGetVLInfo(features);
|
|
testEnabled(features);
|
|
testInvalidPreflight(features);
|
|
testInvalidPreclaim(features);
|
|
testInvalidDoApply(features);
|
|
testAccountSet(features);
|
|
testAccountSetFlags(features);
|
|
testSetRegularKey(features);
|
|
testSetRegularKeyFlags(features);
|
|
testSignersListSet(features);
|
|
testImportSequence(features);
|
|
testMaxSupply(features);
|
|
testMinMax(features);
|
|
}
|
|
};
|
|
|
|
BEAST_DEFINE_TESTSUITE(Import, app, ripple);
|
|
|
|
} // namespace test
|
|
} // namespace ripple
|