mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-18 17:45:48 +00:00
add halving tests
This commit is contained in:
@@ -1105,8 +1105,11 @@ private:
|
||||
std::shared_ptr<Ledger>
|
||||
loadLedgerFromFile(std::string const& ledgerID);
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
loadLedgerFromJson(std::string const& jsonValue);
|
||||
|
||||
bool
|
||||
loadOldLedger(std::string const& ledgerID, bool replay, bool isFilename);
|
||||
loadOldLedger(std::string const& ledgerID, bool replay, bool isFilename, bool isJson);
|
||||
|
||||
void
|
||||
setMaxDisallowedLedger();
|
||||
@@ -1234,14 +1237,15 @@ ApplicationImp::setup(boost::program_options::variables_map const& cmdline)
|
||||
}
|
||||
else if (
|
||||
startUp == Config::LOAD || startUp == Config::LOAD_FILE ||
|
||||
startUp == Config::REPLAY)
|
||||
startUp == Config::REPLAY || startUp == Config::LOAD_JSON)
|
||||
{
|
||||
JLOG(m_journal.info()) << "Loading specified Ledger";
|
||||
|
||||
if (!loadOldLedger(
|
||||
config_->START_LEDGER,
|
||||
startUp == Config::REPLAY,
|
||||
startUp == Config::LOAD_FILE))
|
||||
startUp == Config::LOAD_FILE,
|
||||
startUp == Config::LOAD_JSON))
|
||||
{
|
||||
JLOG(m_journal.error())
|
||||
<< "The specified ledger could not be loaded.";
|
||||
@@ -1907,17 +1911,153 @@ ApplicationImp::loadLedgerFromFile(std::string const& name)
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger>
|
||||
ApplicationImp::loadLedgerFromJson(std::string const& jsonValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
Json::Reader reader;
|
||||
Json::Value jLedger;
|
||||
|
||||
if (!reader.parse(jsonValue, jLedger))
|
||||
{
|
||||
JLOG(m_journal.fatal()) << "Unable to parse ledger JSON";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::reference_wrapper<Json::Value> ledger(jLedger);
|
||||
|
||||
// accept a wrapped ledger
|
||||
if (ledger.get().isMember("result"))
|
||||
ledger = ledger.get()["result"];
|
||||
|
||||
if (ledger.get().isMember("ledger"))
|
||||
ledger = ledger.get()["ledger"];
|
||||
|
||||
std::uint32_t seq = 1;
|
||||
auto closeTime = timeKeeper().closeTime();
|
||||
using namespace std::chrono_literals;
|
||||
auto closeTimeResolution = 30s;
|
||||
bool closeTimeEstimated = false;
|
||||
std::uint64_t totalDrops = 0;
|
||||
|
||||
if (ledger.get().isMember("accountState"))
|
||||
{
|
||||
if (ledger.get().isMember(jss::ledger_index))
|
||||
{
|
||||
seq = ledger.get()[jss::ledger_index].asUInt();
|
||||
}
|
||||
|
||||
if (ledger.get().isMember("close_time"))
|
||||
{
|
||||
using tp = NetClock::time_point;
|
||||
using d = tp::duration;
|
||||
closeTime = tp{d{ledger.get()["close_time"].asUInt()}};
|
||||
}
|
||||
if (ledger.get().isMember("close_time_resolution"))
|
||||
{
|
||||
using namespace std::chrono;
|
||||
closeTimeResolution =
|
||||
seconds{ledger.get()["close_time_resolution"].asUInt()};
|
||||
}
|
||||
if (ledger.get().isMember("close_time_estimated"))
|
||||
{
|
||||
closeTimeEstimated =
|
||||
ledger.get()["close_time_estimated"].asBool();
|
||||
}
|
||||
if (ledger.get().isMember("total_coins"))
|
||||
{
|
||||
totalDrops = beast::lexicalCastThrow<std::uint64_t>(
|
||||
ledger.get()["total_coins"].asString());
|
||||
}
|
||||
|
||||
ledger = ledger.get()["accountState"];
|
||||
}
|
||||
|
||||
if (!ledger.get().isArrayOrNull())
|
||||
{
|
||||
JLOG(m_journal.fatal()) << "State nodes must be an array";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto loadLedger =
|
||||
std::make_shared<Ledger>(seq, closeTime, *config_, nodeFamily_);
|
||||
loadLedger->setTotalDrops(totalDrops);
|
||||
|
||||
for (Json::UInt index = 0; index < ledger.get().size(); ++index)
|
||||
{
|
||||
Json::Value& entry = ledger.get()[index];
|
||||
|
||||
if (!entry.isObjectOrNull())
|
||||
{
|
||||
JLOG(m_journal.fatal()) << "Invalid entry in ledger";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint256 uIndex;
|
||||
|
||||
if (!uIndex.parseHex(entry[jss::index].asString()))
|
||||
{
|
||||
JLOG(m_journal.fatal()) << "Invalid entry in ledger";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
entry.removeMember(jss::index);
|
||||
|
||||
STParsedJSONObject stp("sle", ledger.get()[index]);
|
||||
|
||||
if (!stp.object || uIndex.isZero())
|
||||
{
|
||||
JLOG(m_journal.fatal()) << "Invalid entry in ledger";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// VFALCO TODO This is the only place that
|
||||
// constructor is used, try to remove it
|
||||
STLedgerEntry sle(*stp.object, uIndex);
|
||||
|
||||
if (!loadLedger->addSLE(sle))
|
||||
{
|
||||
JLOG(m_journal.fatal())
|
||||
<< "Couldn't add serialized ledger: " << uIndex;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
loadLedger->stateMap().flushDirty(hotACCOUNT_NODE);
|
||||
|
||||
assert(
|
||||
loadLedger->info().seq < XRP_LEDGER_EARLIEST_FEES ||
|
||||
loadLedger->read(keylet::fees()));
|
||||
loadLedger->setAccepted(
|
||||
closeTime, closeTimeResolution, !closeTimeEstimated);
|
||||
|
||||
return loadLedger;
|
||||
}
|
||||
catch (std::exception const& x)
|
||||
{
|
||||
JLOG(m_journal.fatal()) << "Ledger contains invalid data: " << x.what();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ApplicationImp::loadOldLedger(
|
||||
std::string const& ledgerID,
|
||||
bool replay,
|
||||
bool isFileName)
|
||||
bool isFileName,
|
||||
bool isJson)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::shared_ptr<Ledger const> loadLedger, replayLedger;
|
||||
|
||||
if (isFileName)
|
||||
if (isJson)
|
||||
{
|
||||
if (!ledgerID.empty())
|
||||
loadLedger = loadLedgerFromJson(ledgerID);
|
||||
}
|
||||
else if (isFileName)
|
||||
{
|
||||
if (!ledgerID.empty())
|
||||
loadLedger = loadLedgerFromFile(ledgerID);
|
||||
@@ -1999,7 +2139,7 @@ ApplicationImp::loadOldLedger(
|
||||
using namespace std::chrono_literals;
|
||||
using namespace date;
|
||||
static constexpr NetClock::time_point ledgerWarnTimePoint{
|
||||
sys_days{January / 1 / 2018} - sys_days{January / 1 / 2000}};
|
||||
sys_days{January / 1 / 2000} - sys_days{January / 1 / 2000}};
|
||||
if (loadLedger->info().closeTime < ledgerWarnTimePoint)
|
||||
{
|
||||
JLOG(m_journal.fatal())
|
||||
|
||||
@@ -153,7 +153,7 @@ public:
|
||||
|
||||
std::map<std::string, PublicKey> IMPORT_VL_KEYS; // hex string -> class PublicKey (for caching purposes)
|
||||
|
||||
enum StartUpType { FRESH, NORMAL, LOAD, LOAD_FILE, REPLAY, NETWORK };
|
||||
enum StartUpType { FRESH, NORMAL, LOAD, LOAD_FILE, REPLAY, NETWORK, LOAD_JSON };
|
||||
StartUpType START_UP = NORMAL;
|
||||
|
||||
bool START_VALID = false;
|
||||
|
||||
@@ -1158,10 +1158,10 @@ std::string ImportTCPayment::w_seed = R"json({
|
||||
class ImportTCHalving
|
||||
{
|
||||
public:
|
||||
static std::string one_one;
|
||||
static std::string base_genesis;
|
||||
};
|
||||
|
||||
std::string ImportTCHalving::one_one = R"json({
|
||||
std::string ImportTCHalving::base_genesis = R"json({
|
||||
"ledger": {
|
||||
"accepted": true,
|
||||
"accountState": [
|
||||
@@ -1177,56 +1177,20 @@ std::string ImportTCHalving::one_one = R"json({
|
||||
"index": "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8"
|
||||
},
|
||||
{
|
||||
"Amendments": [
|
||||
"740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D628A06927F11",
|
||||
"3012E8230864E95A58C60FD61430D7E1B4D3353195F2981DC12B0C7C0950FFAC",
|
||||
"67A34F2CF55BFC0F93AACD5B281413176FEE195269FA6D95219A2DF738671172",
|
||||
"F64E1EABBE79D55B3BB82020516CEC2C582A98A6BFE20FBE9BB6A0D233418064",
|
||||
"157D2D480E006395B76F948E3E07A45A05FE10230D88A7993C71F97AE4B1F2D1",
|
||||
"7117E2EC2DBF119CA55181D69819F1999ECEE1A0225A7FD2B9ED47940968479C",
|
||||
"CA7C02118BA27599528543DFE77BA6838D1B0F43B447D4D7F53523CE6A0E9AC2",
|
||||
"58BE9B5968C4DA7C59BA900961828B113E5490699B21877DEF9A31E9D0FE5D5F",
|
||||
"3CBC5C4E630A1B82380295CDA84B32B49DD066602E74E39B85EF64137FA65194",
|
||||
"5D08145F0A4983F23AFFFF514E83FAD355C5ABFBB6CAB76FB5BC8519FF5F33BE",
|
||||
"FBD513F1B893AC765B78F250E6FFA6A11B573209D1842ADC787C850696741288",
|
||||
"586480873651E106F1D6339B0C4A8945BA705A777F3F4524626FF1FC07EFE41D",
|
||||
"2CD5286D8D687E98B41102BDD797198E81EA41DF7BD104E6561FEB104EFF2561",
|
||||
"C4483A1896170C66C098DEA5B0E024309C60DC960DE5F01CD7AF986AA3D9AD37",
|
||||
"8F81B066ED20DAECA20DF57187767685EEF3980B228E0667A650BAF24426D3B4",
|
||||
"621A0B264970359869E3C0363A899909AAB7A887C8B73519E4ECF952D33258A8",
|
||||
"89308AF3B8B10B7192C4E613E1D2E4D9BA64B2EE2D5232402AE82A6A7220D953",
|
||||
"00C1FC4A53E60AB02C864641002B3172F38677E29C26C5406685179B37E1EDAC",
|
||||
"25BA44241B3BD880770BFA4DA21C7180576831855368CBEC6A3154FDE4A7676E",
|
||||
"1F4AFA8FA1BC8827AD4C0F682C03A8B671DCDF6B5C4DE36D44243A684103EF88",
|
||||
"4F46DF03559967AC60F2EB272FEFE3928A7594A45FF774B87A7E540DB0F8F068",
|
||||
"B4E4F5D2D6FB84DF7399960A732309C9FD530EAE5941838160042833625A6076",
|
||||
"955DF3FA5891195A9DAEFA1DDC6BB244B545DDE1BAA84CBB25D5F12A8DA68A0C",
|
||||
"AF8DF7465C338AE64B1E937D6C8DA138C0D63AD5134A68792BBBE1F63356C422",
|
||||
"452F5906C46D46F407883344BFDD90E672B672C5E9943DB4891E3A34FEEEB9DB",
|
||||
"B6B3EEDC0267AB50491FDC450A398AF30DBCD977CECED8BEF2499CAB5DAC19E2",
|
||||
"98DECF327BF79997AEC178323AD51A830E457BFC6D454DAF3E46E5EC42DC619F",
|
||||
"B2A4DB846F0891BF2C76AB2F2ACC8F5B4EC64437135C6E56F3F859DE5FFD5856",
|
||||
"32A122F1352A4C7B3A6D790362CC34749C5E57FCE896377BFDC6CCD14F6CD627",
|
||||
"F1ED6B4A411D8B872E65B9DCB4C8B100375B0DD3D62D07192E011D6D7F339013",
|
||||
"75A7E01C505DD5A179DFE3E000A9B6F1EDDEB55A12F95579A23E15B15DC8BE5A",
|
||||
"47C3002ABA31628447E8E9A8B315FAA935CE30183F9A9B86845E469CA2CDC3DF",
|
||||
"93E516234E35E08CA689FA33A6D38E103881F8DCB53023F728C307AA89D515A7",
|
||||
"2E2FB9CF8A44EB80F4694D38AADAE9B8B7ADAFD2F092E10068E61C98C4F092B0",
|
||||
"73761231F7F3D94EC3D8C63D91BDD0D89045C6F71B917D1925C01253515A6669",
|
||||
"AE35ABDEFBDE520372B31C957020B34A7A4A9DC3115A69803A44016477C84D6E",
|
||||
"ECE6819DBA5DB528F1A241695F5A9811EF99467CDE22510954FD357780BBD078",
|
||||
"42F8B586B357ABBAAAA1C733C3E7D3B75761395340D0CDF600179E8737E22478",
|
||||
"919857E4B902A20216E4819B9BD9FD1FD19A66ECF63151C18A4C48C873DB9578",
|
||||
"ECF412BE0964EC2E71DCF807EEEA6EA8470D3DB15173D46F28AB6E234860AC32",
|
||||
"86E83A7D2ECE3AD5FA87AB2195AE015C950469ABF0B72EAACED318F74886AE90",
|
||||
"3C43D9A973AA4443EF3FC38E42DD306160FBFFDAB901CD8BAA15D09F2597EB87",
|
||||
"0285B7E5E08E1A8E4C15636F0591D87F73CB6A7B6452A932AD72BBC8E5D1CBE3",
|
||||
"36799EA497B1369B170805C078AEFE6188345F9B3E324C21E9CA3FF574E3C3D6",
|
||||
"F5751842D26FC057B92CAA435ABF4F1428C2BCC4180D18775ADE92CB2643BBA3"
|
||||
],
|
||||
"Amendments": [],
|
||||
"Flags": 0,
|
||||
"LedgerEntryType": "Amendments",
|
||||
"index": "7DB0788C020F02780A673DC74757F23823FA3014C1866E72CC4CD8B226CD6EF4"
|
||||
},
|
||||
{
|
||||
"BaseFee": "A",
|
||||
"Flags": 0,
|
||||
"LedgerEntryType": "FeeSettings",
|
||||
"ReferenceFeeUnits": 10,
|
||||
"ReserveBase": 1000000,
|
||||
"ReserveIncrement": 200000,
|
||||
"XahauActivationLgrSeq": 0,
|
||||
"index": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A651"
|
||||
}
|
||||
],
|
||||
"account_hash": "5DF3A98772FB73E782B8740E87885C6BAD9BA486422E3626DEF968AD2CB2C514",
|
||||
@@ -1237,16 +1201,16 @@ std::string ImportTCHalving::one_one = R"json({
|
||||
"closed": true,
|
||||
"hash": "56DA0940767AC2F17F0E384F04816002403D0756432B9D503DDA20128A2AAF11",
|
||||
"ledger_hash": "56DA0940767AC2F17F0E384F04816002403D0756432B9D503DDA20128A2AAF11",
|
||||
"ledger_index": "1999998",
|
||||
"ledger_index": "0",
|
||||
"parent_close_time": 0,
|
||||
"parent_hash": "56DA0940767AC2F17F0E384F04816002403D0756432B9D503DDA20128A2AAF11",
|
||||
"seqNum": "1999998",
|
||||
"seqNum": "0",
|
||||
"totalCoins": "0",
|
||||
"total_coins": "0",
|
||||
"transaction_hash": "9A77D1D1A4B36DA77B9C4DC63FDEB8F821741D157802F9C42A6ED86003D8B4A0",
|
||||
"transactions": []
|
||||
},
|
||||
"ledger_current_index": 1999998,
|
||||
"ledger_current_index": 0,
|
||||
"status": "success",
|
||||
"validated": true
|
||||
})json";
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <ripple/protocol/jss.h>
|
||||
#include <test/jtx.h>
|
||||
#include <test/app/Import_json.h>
|
||||
#include <ripple/app/misc/AmendmentTable.h>
|
||||
|
||||
#define BEAST_REQUIRE(x) \
|
||||
{ \
|
||||
@@ -4554,6 +4555,73 @@ class Import_test : public beast::unit_test::suite
|
||||
});
|
||||
}
|
||||
|
||||
std::unique_ptr<Config>
|
||||
makeGenesisConfig(
|
||||
FeatureBitset features,
|
||||
uint32_t networkID,
|
||||
std::string fee,
|
||||
std::string a_res,
|
||||
std::string o_res,
|
||||
uint32_t ledgerID)
|
||||
{
|
||||
using namespace jtx;
|
||||
|
||||
// IMPORT VL KEY
|
||||
std::vector<std::string> const keys = {
|
||||
"ED74D4036C6591A4BDF9C54CEFA39B996A"
|
||||
"5DCE5F86D11FDA1874481CE9D5A1CDC1"};
|
||||
|
||||
Json::Value jsonValue;
|
||||
Json::Reader reader;
|
||||
reader.parse(ImportTCHalving::base_genesis, jsonValue);
|
||||
|
||||
for (size_t i = 0; i < features.size(); ++i)
|
||||
{
|
||||
uint256 const& feature = bitsetIndexToFeature(i);
|
||||
std::string featureName = featureToName(feature);
|
||||
std::optional<uint256> featureHash = getRegisteredFeature(featureName);
|
||||
if (featureHash.has_value() && feature != featureOwnerPaysFee)
|
||||
{
|
||||
std::string hashString = to_string(featureHash.value());
|
||||
jsonValue["ledger"]["accountState"][1]["Amendments"].append(hashString);
|
||||
}
|
||||
}
|
||||
|
||||
jsonValue["ledger_current_index"] = ledgerID;
|
||||
jsonValue["ledger"]["ledger_index"] = to_string(ledgerID);
|
||||
jsonValue["ledger"]["seqNum"] = to_string(ledgerID);
|
||||
|
||||
return envconfig([&](std::unique_ptr<Config> cfg) {
|
||||
cfg->NETWORK_ID = networkID;
|
||||
cfg->START_LEDGER = jsonValue.toStyledString();
|
||||
cfg->START_UP = Config::LOAD_JSON;
|
||||
Section config;
|
||||
config.append(
|
||||
{"reference_fee = " + fee,
|
||||
"account_reserve = " + a_res,
|
||||
"owner_reserve = " + o_res});
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
testHalving(FeatureBitset features)
|
||||
{
|
||||
@@ -4562,16 +4630,17 @@ class Import_test : public beast::unit_test::suite
|
||||
using namespace test::jtx;
|
||||
using namespace std::literals;
|
||||
|
||||
// Halving 1:1
|
||||
// Halving @ ledger seq 1'999'999
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
"../src/test/app/halve_1_1.json"
|
||||
1999998
|
||||
)
|
||||
};
|
||||
|
||||
@@ -4581,7 +4650,6 @@ class Import_test : public beast::unit_test::suite
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
auto initSeq = env.current()->info().seq;
|
||||
std::cout << "initSeq: " << initSeq << "\n";
|
||||
BEAST_EXPECT(initSeq == 1'999'999);
|
||||
|
||||
// init env
|
||||
@@ -4593,7 +4661,7 @@ class Import_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(preAlice == XRP(0));
|
||||
|
||||
// import tx
|
||||
auto const xpopJson = loadXpop(ImportTCAccountSet::min);
|
||||
auto const xpopJson = loadXpop(ImportTCAccountSet::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
@@ -4601,8 +4669,361 @@ class Import_test : public beast::unit_test::suite
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = drops(10) + XRP(2);
|
||||
std::cout << "creditDrops: " << creditDrops << "\n";
|
||||
auto const creditDrops = XRP(1'000) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
BEAST_EXPECT(postAlice == preAlice + creditDrops);
|
||||
|
||||
// confirm total coins header
|
||||
auto const postCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(postCoins == initCoins + creditDrops);
|
||||
}
|
||||
|
||||
// Halving @ ledger seq 2'000'000
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
1999998
|
||||
)
|
||||
};
|
||||
|
||||
auto const feeDrops = env.current()->fees().base;
|
||||
|
||||
// confirm total coins header
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
env.close();
|
||||
auto initSeq = env.current()->info().seq;
|
||||
BEAST_EXPECT(initSeq == 2'000'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::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
env(tx, alice, ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = XRP(1'000) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
BEAST_EXPECT(postAlice == preAlice + creditDrops);
|
||||
|
||||
// confirm total coins header
|
||||
auto const postCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(postCoins == initCoins + creditDrops);
|
||||
}
|
||||
|
||||
// Halving @ ledger seq 2'000'001
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
1999998
|
||||
)
|
||||
};
|
||||
|
||||
auto const feeDrops = env.current()->fees().base;
|
||||
|
||||
// confirm total coins header
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
env.close();
|
||||
env.close();
|
||||
auto initSeq = env.current()->info().seq;
|
||||
BEAST_EXPECT(initSeq == 2'000'001);
|
||||
|
||||
// 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::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
env(tx, alice, ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = drops(999999964) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
BEAST_EXPECT(postAlice == preAlice + creditDrops);
|
||||
|
||||
// confirm total coins header
|
||||
auto const postCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(postCoins == initCoins + creditDrops);
|
||||
}
|
||||
|
||||
// Halving @ ledger seq 5'000'000
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
4999999
|
||||
)
|
||||
};
|
||||
|
||||
auto const feeDrops = env.current()->fees().base;
|
||||
|
||||
// confirm total coins header
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
auto initSeq = env.current()->info().seq;
|
||||
BEAST_EXPECT(initSeq == 5'000'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::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
env(tx, alice, ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = drops(892857142) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
BEAST_EXPECT(postAlice == preAlice + creditDrops);
|
||||
|
||||
// confirm total coins header
|
||||
auto const postCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(postCoins == initCoins + creditDrops);
|
||||
}
|
||||
|
||||
// Halving @ ledger seq 20'000'000
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
19999999
|
||||
)
|
||||
};
|
||||
|
||||
auto const feeDrops = env.current()->fees().base;
|
||||
|
||||
// confirm total coins header
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
auto initSeq = env.current()->info().seq;
|
||||
BEAST_EXPECT(initSeq == 20'000'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::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
env(tx, alice, ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = drops(357142857) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
BEAST_EXPECT(postAlice == preAlice + creditDrops);
|
||||
|
||||
// confirm total coins header
|
||||
auto const postCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(postCoins == initCoins + creditDrops);
|
||||
}
|
||||
|
||||
// Halving @ ledger seq 29'999'998
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
29999998
|
||||
)
|
||||
};
|
||||
|
||||
auto const feeDrops = env.current()->fees().base;
|
||||
|
||||
// confirm total coins header
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
auto initSeq = env.current()->info().seq;
|
||||
BEAST_EXPECT(initSeq == 29'999'999);
|
||||
|
||||
// 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::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
env(tx, alice, ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = drops(35) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
BEAST_EXPECT(postAlice == preAlice + creditDrops);
|
||||
|
||||
// confirm total coins header
|
||||
auto const postCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(postCoins == initCoins + creditDrops);
|
||||
}
|
||||
|
||||
// Halving @ ledger seq 30'000'000
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
29999998
|
||||
)
|
||||
};
|
||||
|
||||
auto const feeDrops = env.current()->fees().base;
|
||||
|
||||
// confirm total coins header
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
env.close();
|
||||
auto initSeq = env.current()->info().seq;
|
||||
BEAST_EXPECT(initSeq == 30'000'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::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
env(tx, alice, ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = drops(0) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
BEAST_EXPECT(postAlice == preAlice + creditDrops);
|
||||
|
||||
// confirm total coins header
|
||||
auto const postCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(postCoins == initCoins + creditDrops);
|
||||
}
|
||||
|
||||
// Halving @ ledger seq 50'000'001
|
||||
{
|
||||
test::jtx::Env env{
|
||||
*this,
|
||||
makeGenesisConfig(
|
||||
features,
|
||||
21337,
|
||||
"10",
|
||||
"1000000",
|
||||
"200000",
|
||||
50000000
|
||||
)
|
||||
};
|
||||
|
||||
auto const feeDrops = env.current()->fees().base;
|
||||
|
||||
// confirm total coins header
|
||||
auto initCoins = env.current()->info().drops;
|
||||
BEAST_EXPECT(initCoins == 0);
|
||||
auto initSeq = env.current()->info().seq;
|
||||
BEAST_EXPECT(initSeq == 50'000'001);
|
||||
|
||||
// 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::w_seed);
|
||||
Json::Value tx = import(alice, xpopJson);
|
||||
tx[jss::Sequence] = 0;
|
||||
tx[jss::Fee] = 0;
|
||||
env(tx, alice, ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// total burn = burn drops + Init Reward
|
||||
auto const creditDrops = drops(0) + XRP(2);
|
||||
|
||||
// confirm fee was minted
|
||||
auto const postAlice = env.balance(alice);
|
||||
@@ -4614,7 +5035,6 @@ class Import_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
@@ -4647,7 +5067,7 @@ public:
|
||||
testImportSequence(features);
|
||||
testMaxSupply(features);
|
||||
testMinMax(features);
|
||||
testHalving(features);
|
||||
testHalving(features - featureOwnerPaysFee);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user