modify xahaugenesis to support l2 table setup

This commit is contained in:
Richard Holland
2023-09-15 16:16:46 +00:00
parent e55820e7c6
commit ab67ddeeb6
5 changed files with 1227 additions and 921 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -281,40 +281,55 @@ Change::preCompute()
}
struct L2Table
{
std::string account;
AccountID id;
std::vector<std::string> members;
std::vector<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> params;
};
inline
std::pair<
std::vector<std::pair<std::string, XRPAmount>>,
std::tuple<
std::vector<std::pair<std::string, XRPAmount>>, // initial distribution
std::vector<L2Table>,
std::vector<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>>>
normalizeXahauGenesis(
std::vector<std::pair<std::string, XRPAmount>> const& entries,
std::vector<std::pair<std::string, XRPAmount>> const& distribution,
std::vector<std::pair<std::string, std::vector<std::string>>> l2entries,
std::vector<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> params,
beast::Journal const& j)
{
auto getID = [](std::string const& rn) -> std::optional<std::pair<std::string, AccountID>>
{
if (rn.c_str()[0] == 'r')
{
auto parsed = parseBase58<AccountID>(rn);
if (!parsed)
return {};
return {{toBase58(*parsed), *parsed}};
}
if (rn.c_str()[0] == 'n')
{
auto const parsed = parseBase58<PublicKey>(TokenType::NodePublic, rn);
if (!parsed)
return {};
AccountID id = calcAccountID(*parsed);
return {{toBase58(id), id}};
}
return {};
};
std::set<AccountID> L1Seats;
std::vector<std::pair<std::string, XRPAmount>> amounts;
uint8_t mc = 0;
for (auto const& [rn, x]: entries)
for (auto const& [rn, x]: distribution)
{
auto getID = [](std::string const& rn) -> std::optional<std::pair<std::string, AccountID>>
{
if (rn.c_str()[0] == 'r')
{
auto parsed = parseBase58<AccountID>(rn);
if (!parsed)
return {};
return {{toBase58(*parsed), *parsed}};
}
if (rn.c_str()[0] == 'n')
{
auto const parsed = parseBase58<PublicKey>(TokenType::NodePublic, rn);
if (!parsed)
return {};
AccountID id = calcAccountID(*parsed);
return {{toBase58(id), id}};
}
return {};
};
if (auto parsed = getID(rn); parsed)
{
@@ -331,19 +346,59 @@ normalizeXahauGenesis(
params.emplace_back(
std::vector<uint8_t>{'I', 'S', mc++},
std::vector<uint8_t>(id.data(), id.data() + 20));
L1Seats.emplace(id);
continue;
}
JLOG(j.warn())
<< "featureXahauGenesis could not parse distribution address: " << rn;
}
// initial member count
params.emplace_back(
std::vector<uint8_t>{'I', 'M', 'C'},
std::vector<uint8_t>{mc});
return {amounts, params};
std::vector<L2Table> tables;
for (auto const& [table, members] : l2entries)
{
if (auto parsed = getID(table); parsed)
{
if (L1Seats.find(parsed->second) == L1Seats.end())
{
JLOG(j.warn())
<< "featureXahauGenesis L2Table does not sit at an L1 seat. skipping.";
continue;
}
L2Table t;
t.account = parsed->first;
t.id = parsed->second;
uint8_t mc = 0;
for (auto const& m: members)
{
if (auto parsed = getID(m); parsed)
{
t.members.push_back(parsed->first);
t.params.emplace_back(
std::vector<uint8_t>{'I', 'S', mc++},
std::vector<uint8_t>(parsed->second.data(), parsed->second.data() + 20));
}
else
JLOG(j.warn())
<< "featureXahauGenesis L2Table member: " << m << " unable to be parsed. skipping.";
}
t.params.emplace_back(std::vector<uint8_t>{'I', 'M', 'C'}, std::vector<uint8_t>{mc});
tables.push_back(t);
}
else
JLOG(j.warn())
<< "featureXahauGenesis could not parse L2 table address: " << table;
}
return {amounts, tables, params};
};
@@ -354,11 +409,16 @@ Change::activateXahauGenesis()
using namespace XahauGenesis;
auto [initial_distribution, gov_params] =
bool const isTest = ctx_.tx.getFlags() & tfTestSuite && ctx_.app.config().standalone();
auto [initial_distribution, tables, gov_params] =
normalizeXahauGenesis(
ctx_.tx.getFlags() & tfTestSuite && ctx_.app.config().standalone()
isTest
? TestDistribution
: Distribution,
isTest
? TestL2Membership
: L2Membership,
GovernanceParameters, j_);
const static std::vector<
@@ -446,7 +506,6 @@ Change::activateXahauGenesis()
};
// Step 3: blackhole genesis
sle->setAccountID(sfRegularKey, noAccount());
sle->setFieldU32(sfFlags, lsfDisableMaster);
@@ -521,8 +580,10 @@ Change::activateXahauGenesis()
<< *result2 << ", bailing";
return;
}
auto const hookHash =
ripple::sha512Half_s(ripple::Slice(wasmBytes.data(), wasmBytes.size()));
auto hookHash = ripple::sha512Half_s(ripple::Slice(wasmBytes.data(), wasmBytes.size()));
auto const kl = keylet::hookDefinition(hookHash);
if (view().exists(kl))
{
@@ -541,7 +602,8 @@ Change::activateXahauGenesis()
hookDef->setFieldU16(sfHookApiVersion, 0);
hookDef->setFieldVL(sfCreateCode, wasmBytes);
hookDef->setFieldH256(sfHookSetTxnID, ctx_.tx.getTransactionID());
hookDef->setFieldU64(sfReferenceCount, 1);
// governance hook is referenced by the l2tables
hookDef->setFieldU64(sfReferenceCount, (hookCount == 0 ? tables.size() : 0) + 1);
hookDef->setFieldAmount(sfFee,
XRPAmount {hook::computeExecutionFee(result->first)});
if (result->second > 0)
@@ -567,7 +629,6 @@ Change::activateXahauGenesis()
}
hooks.push_back(hookObj);
}
auto sle = std::make_shared<SLE>(keylet::hook(accid));
@@ -589,6 +650,73 @@ Change::activateXahauGenesis()
sb.insert(sle);
}
// install hooks on layer 2 tables
auto const governHash =
ripple::sha512Half_s(ripple::Slice(XahauGenesis::GovernanceHook.data(), XahauGenesis::GovernanceHook.size()));
for (auto const& t : tables)
{
JLOG(j_.trace())
<< "featureXahauGenesis: installing L2 table at: "
<< t.account << " with " << t.members.size() << " members\n";
auto const hookKL = keylet::hook(t.id);
if (sb.exists(hookKL))
{
JLOG(j_.warn())
<< "featureXahauGenesis layer2 table account already has hooks object in ledger, bailing";
return;
}
ripple::STArray hooks{sfHooks, 1};
STObject hookObj {sfHook};
hookObj.setFieldH256(sfHookHash, governHash);
// parameters
{
std::vector<STObject> vec;
for (auto const& [k, v]: t.params)
{
STObject param(sfHookParameter);
param.setFieldVL(sfHookParameterName, k);
param.setFieldVL(sfHookParameterValue, v);
vec.emplace_back(std::move(param));
};
hookObj.setFieldArray(sfHookParameters, STArray(vec, sfHookParameters));
}
hooks.push_back(hookObj);
auto sle = std::make_shared<SLE>(hookKL);
sle->setFieldArray(sfHooks, hooks);
sle->setAccountID(sfAccount, t.id);
auto const page = sb.dirInsert(
keylet::ownerDir(t.id),
keylet::hook(t.id),
describeOwnerDir(t.id));
if (!page)
{
JLOG(j_.warn())
<< "featureXahauGenesis layer2 table directory full when trying to insert hooks object, bailing";
return;
}
sle->setFieldU64(sfOwnerNode, *page);
sb.insert(sle);
// blackhole the l2 account
{
auto const kl = keylet::account(t.id);
auto sle = sb.peek(kl);
sle->setAccountID(sfRegularKey, noAccount());
sle->setFieldU32(sfFlags, lsfDisableMaster);
sle->setFieldU32(sfOwnerCount, sle->getFieldU32(sfOwnerCount) + 1);
sb.update(sle);
}
}
JLOG(j_.warn()) << "featureXahauGenesis amendment executed successfully";
if (destroyedXRP < beast::zero)
@@ -598,6 +726,8 @@ Change::activateXahauGenesis()
return;
}
// record the start ledger
auto sleFees = sb.peek(keylet::fees());
sleFees->setFieldU32(sfXahauActivationLgrSeq, sb.info().seq);

View File

@@ -50,6 +50,22 @@ namespace XahauGenesis
};
inline
std::vector<std::pair<std::string, std::vector<std::string>>>
TestL2Membership;
inline
std::vector<std::pair<
std::string, // L2 table account
std::vector<std::string>>> // list of initial members
const
L2Membership
{
{"nHUubQ7fqxkwPtwS4pQb2ENZ6fdUcAt7aJRiYcPXjxbbkC778Zjk",
{"rG9QZQDR8XqCU1x2VARPuZwYxqcb3J9bYa", "rPV6jx8QoQBCR1AcmVLDnu98QBu4QakwhU"}}
};
// For the Reward Hook: HookOn is set to ttCLAIM_REWARD only
inline
ripple::uint256 const

View File

@@ -192,7 +192,7 @@ struct XahauGenesis_test : public beast::unit_test::suite
BEAST_EXPECT(!!acc);
auto bal = acc->getFieldAmount(sfBalance);
BEAST_EXPECT(bal == STAmount(x));
params.emplace_back(
std::vector<uint8_t>{'I', 'S', member_count++},
std::vector<uint8_t>(id.data(), id.data() + 20));
@@ -317,7 +317,9 @@ struct XahauGenesis_test : public beast::unit_test::suite
void
setupGov(jtx::Env& env, std::vector<AccountID> const members)
setupGov(jtx::Env& env,
std::vector<AccountID> const members,
std::map<AccountID, std::vector<AccountID>> const tables = {})
{
using namespace jtx;
@@ -326,6 +328,7 @@ struct XahauGenesis_test : public beast::unit_test::suite
env.close();
XahauGenesis::TestDistribution.clear();
XahauGenesis::TestL2Membership.clear();
for (auto& m: members)
{
@@ -333,9 +336,23 @@ struct XahauGenesis_test : public beast::unit_test::suite
XahauGenesis::TestDistribution.emplace_back(acc, XRPAmount(10000000000));
}
for(auto& [t, members] : tables)
{
std::vector<std::string> membersStr;
for (auto& m : members)
membersStr.emplace_back(toBase58(m));
XahauGenesis::TestL2Membership.emplace_back(
toBase58(t), membersStr);
}
activate(env, true, true, true);
env.close();
XahauGenesis::TestDistribution.clear();
XahauGenesis::TestL2Membership.clear();
Json::Value invoke;
invoke[jss::TransactionType] = "Invoke";
@@ -343,6 +360,18 @@ struct XahauGenesis_test : public beast::unit_test::suite
invoke[jss::Destination] = env.master.human();
env(invoke, fee(XRP(1)));
env.close();
for (auto& [t, members] : tables)
{
// setup each L2 table
Json::Value invoke;
invoke[jss::TransactionType] = "Invoke";
invoke[jss::Account] = invoker.human();
invoke[jss::Destination] = toBase58(t);
env(invoke, fee(XRP(1)));
env.close();
std::cout << "invoke: " << invoke << "\n";
}
}
@@ -356,6 +385,16 @@ struct XahauGenesis_test : public beast::unit_test::suite
ret.data()[1] = "0123456789ABCDEF"[(inp >> 0) & 0xFU];
return ret;
}
inline
static
std::vector<uint8_t>
vecFromAcc(jtx::Account const& acc)
{
uint8_t const* data = acc.id().data();
return std::vector<uint8_t>(data, data+20);
};
void
testGovernanceL1()
@@ -393,14 +432,6 @@ struct XahauGenesis_test : public beast::unit_test::suite
auto const m20 = Account("m20");
auto const m21 = Account("m21");
auto vecFromAcc = [](Account const& acc) -> std::vector<uint8_t>
{
uint8_t const* data = acc.id().data();
std::vector<uint8_t> ret(data, data+20);
std::cout << "ret: `" << strHex(ret) << "`, size: " << ret.size() << "\n";
return ret;
};
/*
auto printAcc = [](const char* name, Account const& acc) -> void
{
@@ -410,61 +441,38 @@ struct XahauGenesis_test : public beast::unit_test::suite
#define PRINTACC(a) printAcc(#a, a)
PRINTACC(alice);
PRINTACC(bob);
PRINTACC(carol);
PRINTACC(david);
PRINTACC(edward);
PRINTACC(m1);
PRINTACC(m2);
PRINTACC(m6);
PRINTACC(m7);
PRINTACC(m8);
PRINTACC(m9);
PRINTACC(m10);
PRINTACC(m11);
PRINTACC(m12);
PRINTACC(m13);
PRINTACC(m14);
PRINTACC(m15);
PRINTACC(m16);
PRINTACC(m17);
PRINTACC(m18);
PRINTACC(m19);
PRINTACC(m20);
PRINTACC(m21);
alice: AE123A8556F3CF91154711376AFB0F894F832B3D, rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn
bob: F51DFC2A09D62CBBA1DFBDD4691DAC96AD98B90F, rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK
carol: B389FBCED0AF9DCDFF62900BFAEFA3EB872D8A96, rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW
david: 0F4BFC99EC975E3F753927A69713889359C7100E, rpPtwXbmeXxznrUvnMuGhUqTu4Vvk4V98i
edward: 98D3AAD96D5D3F32C3723B6550A49DEE4DD9D4AC, rNAnHhommqNJvV3mLieHADNJU6mfdRqXKp
m1: 1EF5C53AC2B0E1CDEAF960833A9B7B6814879152, rsF66BeCcW5dxrDhPbCqm4ReU5MjkmshQo
m2: 0D20E8D13A89AA84F2334F57331903D21CCC866C, rpURDnkgizBF1ksJr9DmDTNLhds2NBYNbC
m6: F41810565A673D2C45C63B7A51FEA139221DFB1B, rPEe68FWPYpfEYeL3TtdVGXR8WDET24h6e
m7: 52C947B84E2412B5BD2211639E2B9DEDF3ECB5F4, r3YjXvPbu1srxx22tQefDwhXJS8qjCAgxg
m8: 3392382F09E5EA935D5624D52919C683B661238A, rn6gdHFFtieGK748TioK8cZ8SPrHsWAfe3
m9: 62F73BE6E7718B3328DEB497F8298B1C42FFD3D8, rwpHPvGwiJAFStN3KqVTeTLBTczFyK6Z6D
m10: 971B25036F1EAAEEC7A0C299E15F60AB4C465B37, rNmyZrJEtbg5p84PSKGurNs1efdDNLhb8D
m11: B79B324A56425919D0BF64FA4560C7B616F08509, rHjF2LuJKSRerNHtQMtyDUVXpQKmT18XuC
m12: 8C3AA72EBB3172726BE9FDE2A91C9CE2C9F766E5, rD8T19Nz2gkAtKKEeLpXLkTb57AS7nJ45b
m13: 3B8292604D9CF9C679E70CCD0ED5C9DC1DF84607, raRCHchPDpP8qAysxsmehC279GH613iGiM
m14: E77F5DFE960C4DA9524389F946BCD13AC26AB0D0, r4fsCASeoGzhD2ZeFgcJj1c2tmDsm1re3r
m15: D300D94BA59F55426889E144B423CFEE8F685450, rLNgbTE2HVk5CJG7SHrpSD8gsFcwu5cG1a
m16: D9C6AC46D87BCFE374BE4F59C280CEC377E67788, rLiVdCesA2rV2NjC6HZPVK7k1VpvGwCbjx
m17: A620E154D56E38B12AD76A094A214A25AD8B87A1, rG9QZQDR8XqCU1x2VARPuZwYxqcb3J9bYa
m18: 7A5A72F059F6DCDD6E938DAFBCFFB0541E0A7481, rU9A8u622H6fxGQjux8uDgomks5D8QySfS
m19: F6C06C3D86A9D39FF813AEF6B839AD041651BE7D, rPV6jx8QoQBCR1AcmVLDnu98QBu4QakwhU
m20: 1B4D3113C2AB370293A0ACEA4D68C1B29A01A013, rsVM5ZaK9QMCgrW9UKyXLguESpDpsJnRbu
m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4gD
*/
alice: AE123A8556F3CF91154711376AFB0F894F832B3D, rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn
bob: F51DFC2A09D62CBBA1DFBDD4691DAC96AD98B90F, rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK
carol: B389FBCED0AF9DCDFF62900BFAEFA3EB872D8A96, rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW
david: 0F4BFC99EC975E3F753927A69713889359C7100E, rpPtwXbmeXxznrUvnMuGhUqTu4Vvk4V98i
edward: 98D3AAD96D5D3F32C3723B6550A49DEE4DD9D4AC, rNAnHhommqNJvV3mLieHADNJU6mfdRqXKp
m1: 1EF5C53AC2B0E1CDEAF960833A9B7B6814879152, rsF66BeCcW5dxrDhPbCqm4ReU5MjkmshQo
m2: 0D20E8D13A89AA84F2334F57331903D21CCC866C, rpURDnkgizBF1ksJr9DmDTNLhds2NBYNbC
m6: F41810565A673D2C45C63B7A51FEA139221DFB1B, rPEe68FWPYpfEYeL3TtdVGXR8WDET24h6e
m7: 52C947B84E2412B5BD2211639E2B9DEDF3ECB5F4, r3YjXvPbu1srxx22tQefDwhXJS8qjCAgxg
m8: 3392382F09E5EA935D5624D52919C683B661238A, rn6gdHFFtieGK748TioK8cZ8SPrHsWAfe3
m9: 62F73BE6E7718B3328DEB497F8298B1C42FFD3D8, rwpHPvGwiJAFStN3KqVTeTLBTczFyK6Z6D
m10: 971B25036F1EAAEEC7A0C299E15F60AB4C465B37, rNmyZrJEtbg5p84PSKGurNs1efdDNLhb8D
m11: B79B324A56425919D0BF64FA4560C7B616F08509, rHjF2LuJKSRerNHtQMtyDUVXpQKmT18XuC
m12: 8C3AA72EBB3172726BE9FDE2A91C9CE2C9F766E5, rD8T19Nz2gkAtKKEeLpXLkTb57AS7nJ45b
m13: 3B8292604D9CF9C679E70CCD0ED5C9DC1DF84607, raRCHchPDpP8qAysxsmehC279GH613iGiM
m14: E77F5DFE960C4DA9524389F946BCD13AC26AB0D0, r4fsCASeoGzhD2ZeFgcJj1c2tmDsm1re3r
m15: D300D94BA59F55426889E144B423CFEE8F685450, rLNgbTE2HVk5CJG7SHrpSD8gsFcwu5cG1a
m16: D9C6AC46D87BCFE374BE4F59C280CEC377E67788, rLiVdCesA2rV2NjC6HZPVK7k1VpvGwCbjx
m17: A620E154D56E38B12AD76A094A214A25AD8B87A1, rG9QZQDR8XqCU1x2VARPuZwYxqcb3J9bYa
m18: 7A5A72F059F6DCDD6E938DAFBCFFB0541E0A7481, rU9A8u622H6fxGQjux8uDgomks5D8QySfS
m19: F6C06C3D86A9D39FF813AEF6B839AD041651BE7D, rPV6jx8QoQBCR1AcmVLDnu98QBu4QakwhU
m20: 1B4D3113C2AB370293A0ACEA4D68C1B29A01A013, rsVM5ZaK9QMCgrW9UKyXLguESpDpsJnRbu
m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4gD
*/
env.fund(XRP(10000), alice, bob, carol, david, edward, m1, m2,
m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18, m19, m20, m21);
env.close();
std::vector<Account> initial_members {alice, bob, carol, david, edward};
std::vector<AccountID> initial_members_ids { alice.id(), bob.id(), carol.id(), david.id(), edward.id() };
@@ -473,7 +481,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
auto vote = [&](
uint16_t lineno,
Account const& acc,
char topic1,
char topic1,
std::optional<char> topic2,
std::vector<uint8_t> data,
std::optional<uint8_t> layer = std::nullopt)
@@ -492,7 +500,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
txn[jss::HookParameters][0u][jss::HookParameter][jss::HookParameterValue] = val;
txn[jss::HookParameters][1u] = Json::objectValue;
txn[jss::HookParameters][1u][jss::HookParameter][jss::HookParameterName] =
txn[jss::HookParameters][1u][jss::HookParameter][jss::HookParameterName] =
"56"; // 'V'
{
@@ -512,7 +520,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
strData += charToHex((uint8_t)(lineno >> 8U));
strData += charToHex((uint8_t)(lineno & 0xFFU));
txn[jss::HookParameters][2u][jss::HookParameter][jss::HookParameterValue] = strData;
}
}
if (layer)
@@ -524,7 +532,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
txn[jss::Account] = acc.human();
txn[jss::TransactionType] = "Invoke";
txn[jss::Destination] = env.master.human();
txn[jss::Destination] = env.master.human();
return txn;
};
@@ -547,7 +555,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
};
auto doL1Vote = [&](uint64_t lineno, Account const& acc, char topic1, char topic2,
auto doL1Vote = [&](uint64_t lineno, Account const& acc, char topic1, char topic2,
std::vector<uint8_t> const& vote_data,
std::vector<uint8_t> const& old_data,
bool actioned = true, bool const shouldFail = false)
@@ -570,15 +578,15 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
{
isOldDataZero = false;
break;
}
}
uint8_t const key[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
uint8_t const key[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
topic1 == 'S' ? 0 : topic1, topic2};
// check actioning prior to vote
{
auto entry = env.le(keylet::hookState(env.master.id(), uint256::fromVoid(key), beast::zero));
std::cout
<< "topic vote precheck: " << lineno << "L\n"
std::cout
<< "topic vote precheck: " << lineno << "L\n"
<< "\tacc: " << acc.human() << " shouldAction: " << (actioned ? "true": "false")
<< "\tshouldFail: " << (shouldFail ? "true": "false") << "\n"
<< "\ttopic: " << topic1 << "," << (topic2 < 48 ? topic2 + '1' : topic2) << "\n"
@@ -588,14 +596,14 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
<< "\tlgr_data: " << (!entry ? "doesn't exist" : strHex(entry->getFieldVL(sfHookStateData))) << "\n"
<< "\tnew_data: " << strHex(vote_data) << "\n"
<< "\t(isOldDataZero && !entry): " << (isOldDataZero && !entry ? "true" : "false") << "\n"
<< "\t(entry && entry->getFieldVL(sfHookStateData) == old_data): " <<
<< "\t(entry && entry->getFieldVL(sfHookStateData) == old_data): " <<
(entry && entry->getFieldVL(sfHookStateData) == old_data ? "true" : "false") << "\n"
<< ((isOldDataZero && !entry) ||
(entry && entry->getFieldVL(sfHookStateData) == old_data) ? "" : "\tfailed: ^^^\n");
BEAST_EXPECT((isOldDataZero && !entry) ||
BEAST_EXPECT((isOldDataZero && !entry) ||
(entry && entry->getFieldVL(sfHookStateData) == old_data));
}
}
// perform and check vote
{
@@ -620,7 +628,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// if the vote count isn't high enough it will be hte old value if it's high enough it will be the
// new value
auto entry = env.le(keylet::hookState(env.master.id(), uint256::fromVoid(key), beast::zero));
if (!actioned && isOldDataZero)
{
BEAST_EXPECT(!entry || entry->getFieldVL(sfHookStateData) == old_data);
@@ -634,7 +642,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
else
{
std::cout << "new data: " << strHex(vote_data) << "\n";
std::cout << "lgr data: " <<
std::cout << "lgr data: " <<
(!entry ? "<doesn't exist>" : strHex(entry->getFieldVL(sfHookStateData))) << "\n";
BEAST_EXPECT(!!entry && entry->getFieldVL(sfHookStateData) == vote_data);
}
@@ -649,16 +657,16 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
}
}
};
// 100% vote for a different reward rate
{
// this will be the new reward rate
std::vector<uint8_t> vote_data {0x00U,0x81U,0xC6U,0xA4U,0x7EU,0x8DU,0x43U,0x54U};
// this is the default reward rate
std::vector<uint8_t> const original_data {0x00U,0xE4U,0x61U,0xEEU,0x78U,0x90U,0x83U,0x54U};
doL1Vote(__LINE__, alice, 'R', 'R', vote_data, original_data, false);
doL1Vote(__LINE__, alice, 'R', 'R', vote_data, original_data, false);
doL1Vote(__LINE__, bob, 'R', 'R', vote_data, original_data, false);
doL1Vote(__LINE__, carol, 'R', 'R', vote_data, original_data, false);
doL1Vote(__LINE__, david, 'R', 'R', vote_data, original_data, false);
@@ -671,16 +679,16 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
std::vector<uint8_t> const null_data {0,0,0,0,0,0,0,0};
doL1Vote(__LINE__, david, 'R', 'R', null_data, vote_data, false);
}
// 100% vote for a different reward delay
{
// this will be the new reward delay
std::vector<uint8_t> vote_data {0x00U,0x80U,0xC6U,0xA4U,0x7EU,0x8DU,0x03U,0x55U};
// this is the default reward delay
std::vector<uint8_t> const original_data {0x00U,0x80U,0x6AU,0xACU,0xAFU,0x3CU,0x09U,0x56U};
doL1Vote(__LINE__, edward, 'R', 'D', vote_data, original_data, false);
doL1Vote(__LINE__, edward, 'R', 'D', vote_data, original_data, false);
doL1Vote(__LINE__, david, 'R', 'D', vote_data, original_data, false);
doL1Vote(__LINE__, carol, 'R', 'D', vote_data, original_data, false);
doL1Vote(__LINE__, bob, 'R', 'D', vote_data, original_data, false);
@@ -696,12 +704,12 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// 100% vote to install the accept hook at hook position 7
// create a definition for accept hook first
auto const acceptHookHash =
auto const acceptHookHash =
ripple::sha512Half_s(ripple::Slice(XahauGenesis::AcceptHook.data(), XahauGenesis::AcceptHook.size()));
auto const governHookHash =
auto const governHookHash =
ripple::sha512Half_s(
ripple::Slice(XahauGenesis::GovernanceHook.data(), XahauGenesis::GovernanceHook.size()));
auto const rewardHookHash =
auto const rewardHookHash =
ripple::sha512Half_s(ripple::Slice(XahauGenesis::RewardHook.data(), XahauGenesis::RewardHook.size()));
{
Json::Value tx (Json::objectValue);
@@ -731,7 +739,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
tx[jss::Hooks][2u] = Json::objectValue;
tx[jss::Hooks][2u][jss::Hook] = Json::objectValue;
tx[jss::Hooks][2u][jss::Hook][jss::HookHash] = strHex(rewardHookHash);
env(tx, M(__LINE__), fee(XRP(100)));
env.close();
@@ -743,7 +751,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
std::vector<uint8_t> accept_data(data, data+32);
std::cout << "accept_data-strhex: " << strHex(accept_data) << "\n";
std::vector<uint8_t> const null_data
std::vector<uint8_t> const null_data
{
0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,
0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,
@@ -755,7 +763,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
doL1Vote(__LINE__, bob, 'H', 7, accept_data, null_data, false);
doL1Vote(__LINE__, carol, 'H', 7, accept_data, null_data, false);
doL1Vote(__LINE__, edward, 'H', 7, accept_data, null_data, false);
env.close();
env.close();
@@ -776,7 +784,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
{
auto const hooks = env.le(keylet::hook(env.master.id()));
BEAST_EXPECT(!!hooks && hooks->getFieldArray(sfHooks).size() > 7 &&
hooks->getFieldArray(sfHooks)[7].isFieldPresent(sfHookHash) &&
hooks->getFieldArray(sfHooks)[7].isFieldPresent(sfHookHash) &&
hooks->getFieldArray(sfHooks)[7].getFieldH256(sfHookHash) == acceptHookHash);
}
@@ -785,12 +793,12 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
env.close();
env.close();
// now check it's still installed
{
auto const hooks = env.le(keylet::hook(env.master.id()));
BEAST_EXPECT(!!hooks && hooks->getFieldArray(sfHooks).size() > 7 &&
hooks->getFieldArray(sfHooks)[7].isFieldPresent(sfHookHash) &&
hooks->getFieldArray(sfHooks)[7].isFieldPresent(sfHookHash) &&
hooks->getFieldArray(sfHooks)[7].getFieldH256(sfHookHash) == acceptHookHash);
}
@@ -799,20 +807,20 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
doL1Vote(__LINE__, bob, 'H', 7, null_data, null_data, false);
doL1Vote(__LINE__, david, 'H', 7, null_data, null_data, false);
doL1Vote(__LINE__, edward, 'H', 7, null_data, null_data, false);
env.close();
env.close();
// now check it's still installed
{
auto const hooks = env.le(keylet::hook(env.master.id()));
BEAST_EXPECT(!!hooks && hooks->getFieldArray(sfHooks).size() > 7 &&
!hooks->getFieldArray(sfHooks)[7].isFieldPresent(sfHookHash));
}
// vote to place an invalid hook
std::vector<uint8_t> invalid_data
std::vector<uint8_t> invalid_data
{
0xFFU,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,
0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,
@@ -831,8 +839,8 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
std::vector<uint8_t> govern_data(gdata, gdata+32);
uint8_t const* rdata = rewardHookHash.data();
std::vector<uint8_t> reward_data(rdata, rdata+32);
// vote to put governance hook into position 2
doL1Vote(__LINE__, alice, 'H', 2, govern_data, null_data, false);
doL1Vote(__LINE__, bob, 'H', 2, govern_data, null_data, false);
@@ -841,7 +849,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
doL1Vote(__LINE__, edward, 'H', 2, govern_data, null_data, false);
env.close();
env.close();
env.close();
// vote to replace the hook at position 1 with accept
doL1Vote(__LINE__, alice, 'H', 1, accept_data, null_data, false);
@@ -868,7 +876,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
{
auto const hooksLE = env.le(keylet::hook(env.master.id()));
BEAST_EXPECT(!!hooksLE && hooksLE->getFieldArray(sfHooks).size() >= 3);
if (hooksLE && hooksLE->getFieldArray(sfHooks).size() >=3)
{
auto const hooks = hooksLE->getFieldArray(sfHooks);
@@ -881,20 +889,20 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// set hook 1 back to reward
doL1Vote(__LINE__, alice, 'H', 1, reward_data, null_data, false);
doL1Vote(__LINE__, bob, 'H', 1, reward_data, null_data, false);
doL1Vote(__LINE__, carol, 'H', 1, reward_data, null_data, false);
doL1Vote(__LINE__, carol, 'H', 1, reward_data, null_data, false);
doL1Vote(__LINE__, david, 'H', 1, reward_data, null_data, false);
doL1Vote(__LINE__, edward, 'H', 1, reward_data, null_data, false);
env.close();
env.close();
// set hook 0 back to govern
doL1Vote(__LINE__, alice, 'H', 0, govern_data, null_data, false);
doL1Vote(__LINE__, bob, 'H', 0, govern_data, null_data, false);
doL1Vote(__LINE__, carol, 'H', 0, govern_data, null_data, false);
doL1Vote(__LINE__, carol, 'H', 0, govern_data, null_data, false);
doL1Vote(__LINE__, david, 'H', 0, govern_data, null_data, false);
doL1Vote(__LINE__, edward, 'H', 0, govern_data, null_data, false);
env.close();
env.close();
@@ -907,13 +915,13 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
env.close();
env.close();
// check we're back the way we were
{
auto const hooksLE = env.le(keylet::hook(env.master.id()));
BEAST_EXPECT(!!hooksLE && hooksLE->getFieldArray(sfHooks).size() >= 2);
if (hooksLE && hooksLE->getFieldArray(sfHooks).size() >=2)
{
auto const hooks = hooksLE->getFieldArray(sfHooks);
@@ -930,7 +938,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
{
auto const hooksLE = env.le(keylet::hook(env.master.id()));
BEAST_EXPECT(!!hooksLE && hooksLE->getFieldArray(sfHooks).size() >= 2);
if (hooksLE && hooksLE->getFieldArray(sfHooks).size() >=2)
{
auto const hooks = hooksLE->getFieldArray(sfHooks);
@@ -940,16 +948,16 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
}
}
}
}
uint8_t const member_count_key[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,'M','C'};
std::vector<uint8_t> const null_acc_id {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// four of the 5 vote to remove alice
{
std::vector<uint8_t> const null_acc_id {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
std::vector<uint8_t> id = vecFromAcc(alice);
doL1Vote(__LINE__, bob, 'S', 0, null_acc_id, id, false);
@@ -995,7 +1003,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
doL1Vote(__LINE__, bob, 'S', 2, null_acc_id, id, false);
doL1Vote(__LINE__, edward, 'S', 2, null_acc_id, id, true);
}
// check the membercount is now 2
{
auto entry = env.le(keylet::hookState(env.master.id(),
@@ -1047,7 +1055,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// subsequent edward vote should fail because he's not a member anymore
doL1Vote(__LINE__, edward, 'S', 4, null_acc_id, alice_id, false, true);
}
// check the membercount is now 2
{
auto entry = env.le(keylet::hookState(env.master.id(),
@@ -1071,8 +1079,8 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
int count = voters.size();
for (Account const* voter : voters)
doL1Vote(lineno, *voter, 'S', seat_no, id, previd, --count <= 0 && actioned, shouldFail);
if (!shouldFail)
if (!shouldFail)
{
auto entry = env.le(keylet::hookState(env.master.id(),
uint256::fromVoid(member_count_key), beast::zero));
@@ -1080,11 +1088,11 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
BEAST_REQUIRE(!!entry);
if (entry->getFieldVL(sfHookStateData) != expected_data)
std::cout
<< "doSeatVote failed " << lineno <<"L. entry data: `"
std::cout
<< "doSeatVote failed " << lineno <<"L. entry data: `"
<< strHex(entry->getFieldVL(sfHookStateData)) << "` "
<< "expected data: `" << strHex(expected_data) << "`\n";
BEAST_EXPECT(entry->getFieldVL(sfHookStateData) == expected_data);
}
};
@@ -1093,14 +1101,14 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// put edward into seat 0 previously occupied by alice
doSeatVote(__LINE__, 0, 3, edward.id(), {}, {&alice, &bob});
// at this point the governance table looks like
// 0 - edward
// 1 - bob
// 2 - empty
// 3 - empty
// 4 - alice
// fill seats 2,3 with accounts m6 and m7. this should take 2 votes only
// alice's vote alone is not enough
doSeatVote(__LINE__, 2, 3, m6.id(), {}, {&alice}, false);
@@ -1124,7 +1132,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
for (int i = 12; i < 32; ++i)
key[i] = m6.id().data()[i-12];
auto entry = env.le(keylet::hookState(env.master.id(), uint256::fromVoid(key), beast::zero));
BEAST_EXPECT(!!entry &&
entry->getFieldVL(sfHookStateData) == std::vector<uint8_t>{0x02U});
@@ -1145,7 +1153,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// first put bob in where edward was
doSeatVote(__LINE__, 0, 5, bob.id(), {}, {&alice, &edward, &m6});
// now we have: bob, ed, m6, m7, alice
// we're going to fill the remaining seats up to 20
doSeatVote(__LINE__, 5, 6, carol.id(), {}, {&alice, &edward, &m6, &m7});
@@ -1201,9 +1209,9 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// voting for another random high seat
doSeatVote(__LINE__, 255, 21, m21.id(), {}, {&alice}, false, true);
doSeatVote(__LINE__, 101, 21, m21.id(), {}, {&alice}, false, true);
// RH TODO: check state count
// RH TODO: check state count
// membership:
// { bob, ed, m6, m7, alice, carol, david, m8, ... m20 }
@@ -1226,7 +1234,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
if (!acc)
{
if (entry)
std::cout << "checkSeat failed, seatno->accid present (but should be empty) for seat: "
std::cout << "checkSeat failed, seatno->accid present (but should be empty) for seat: "
<< seat << "\n";
BEAST_EXPECT(!entry);
return;
@@ -1239,12 +1247,12 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
BEAST_EXPECT(!!entry &&
entry->getFieldVL(sfHookStateData) == vecFromAcc(*acc));
}
// accid => seatno
{
for (int i = 12; i < 32; ++i)
key[i] = acc->id().data()[i-12];
auto entry = env.le(keylet::hookState(env.master.id(), uint256::fromVoid(key), beast::zero));
if (!entry)
@@ -1259,7 +1267,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
{
std::vector<Account const*> finalSeats {
&bob, &edward, &m6, &m7, &alice, &carol, &david,
&bob, &edward, &m6, &m7, &alice, &carol, &david,
&m8, &m9, &m10, &m11, &m12, &m13, &m14, &m15, &m16, &m17, &m18, &m19, &m20};
for (int i = 0; i < 20; ++i)
@@ -1272,8 +1280,8 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// floor (20*0.8) = 16
doSeatVote(__LINE__, 0, 19, alice.id(), bob, {
&bob, &edward, &m6, &m7,
&alice, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&alice, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m13, &m14, &m15, &m16}, true);
// now seating is:
@@ -1283,38 +1291,38 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// note floor(19*0.8) = 15
doSeatVote(__LINE__, 4, 19, edward.id(), {}, {
&alice, &edward, &m6, &m7,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m13, &m14, &m15}, true);
// now seating is:
// {alice, blank, m6, m7, edward, carol, david, m8, ...}
// bob into position 1, the count becomes 20
doSeatVote(__LINE__, 1, 20, bob.id(), {}, {
&alice, &edward, &m6, &m7,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m13, &m14, &m15}, true);
// {alice, bob, m6, m7, edward, carol, david, m8, ...}
// carol into position 2, this frees up seat 5, bringing count to 19
doSeatVote(__LINE__, 2, 19, carol.id(), m6, {
&alice, &bob, &m6, &m7,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m13, &m14, &m15, &m17}, true);
// {alice, bob, carol, m7, edward, blank, david, m8, ...}
// david into position 3, this frees up seat 6, bringing count to 18
doSeatVote(__LINE__, 3, 18, david.id(), m7, {
&alice, &bob, &m18, &m17,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m16, &carol, &david, &m8,
&m9, &m10, &m11, &m12,
&m13, &m14, &m15}, true);
// {alice, bob, carol, david, edward, blank, blank, m8, ...}
// remove all higher members
@@ -1324,32 +1332,32 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
// floor(18*0.8) = 14
doSeatVote(__LINE__, 7, 17, null_acc, m8, {
&alice, &bob, &carol, &david, &edward,
&m8, &m9, &m10, &m11, &m12,
&m8, &m9, &m10, &m11, &m12,
&m13, &m14, &m15, &m16 }, true);
// floor(17*0.8) = 13
doSeatVote(__LINE__, 8, 16, null_acc, m9, {
&alice, &bob, &carol, &david, &edward,
&m9, &m10, &m11, &m12,
&m9, &m10, &m11, &m12,
&m13, &m14, &m15, &m16 }, true);
// floor(16*0.8)=12
doSeatVote(__LINE__, 9, 15, null_acc, m10, {
&alice, &bob, &carol, &david, &edward,
&m10, &m11, &m12,
&m10, &m11, &m12,
&m13, &m14, &m15, &m16 }, true);
// floor(15*0.8)=12
doSeatVote(__LINE__, 10, 14, null_acc, m11, {
&alice, &bob, &carol, &david, &edward,
&m11, &m12,
&m11, &m12,
&m13, &m14, &m15, &m16, &m17 }, true);
// floor(14*0.8)=11
doSeatVote(__LINE__, 11, 13, null_acc, m12, {
&alice, &bob, &carol, &david, &edward,
&m12,
&m12,
&m13, &m14, &m15, &m16, &m17 }, true);
@@ -1377,22 +1385,22 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
doSeatVote(__LINE__, 16, 8, null_acc, m17, {
&alice, &bob, &carol, &david, &edward,
&m19, &m20 }, true);
// floor(8*0.8)=6
doSeatVote(__LINE__, 17, 7, null_acc, m18, {
&alice, &bob, &carol, &david, &edward,
&m20 }, true);
// floor(7*0.8)=5
doSeatVote(__LINE__, 18, 6, null_acc, m19, {
&alice, &bob, &carol, &david, &edward}, true);
// floor(6*0.8)=4
doSeatVote(__LINE__, 19, 5, null_acc, m20, {
&alice, &bob, &carol, &david}, true);
// check the seats are correct
// check the seats are correct
{
std::vector<Account const*> finalSeats {
&alice, &bob, &carol, &david, &edward};
@@ -1400,7 +1408,153 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
for (int i = 0; i < 20; ++i)
checkSeat(i, i < 5 ? finalSeats[i] : NULL);
}
}
void testGovernanceL2()
{
using namespace jtx;
testcase("Test governance membership voting L1");
Env env{*this, envconfig(), supported_amendments() - featureXahauGenesis, nullptr,
beast::severities::kTrace
};
auto const alice = Account("alice");
auto const bob = Account("bob");
auto const carol = Account("carol");
auto const david = Account("david");
auto const edward = Account("edward");
auto const t1 = Account("t1");
auto const t2 = Account("t2");
auto const t3 = Account("t3");
auto const m6 = Account("m6");
auto const m7 = Account("m7");
auto const m8 = Account("m8");
auto const m9 = Account("m9");
auto const m10 = Account("m10");
auto const m11 = Account("m11");
auto const m12 = Account("m12");
auto const m13 = Account("m13");
auto const m14 = Account("m14");
auto const m15 = Account("m15");
auto const m16 = Account("m16");
auto const m17 = Account("m17");
auto const m18 = Account("m18");
auto const m19 = Account("m19");
auto const m20 = Account("m20");
auto const m21 = Account("m21");
/*
auto printAcc = [](const char* name, Account const& acc) -> void
{
std::cout << name << ": " << strHex(acc.id()) << ", " << acc.human() << "\n";
};
#define PRINTACC(a) printAcc(#a, a)
alice: AE123A8556F3CF91154711376AFB0F894F832B3D, rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn
bob: F51DFC2A09D62CBBA1DFBDD4691DAC96AD98B90F, rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK
carol: B389FBCED0AF9DCDFF62900BFAEFA3EB872D8A96, rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW
david: 0F4BFC99EC975E3F753927A69713889359C7100E, rpPtwXbmeXxznrUvnMuGhUqTu4Vvk4V98i
edward: 98D3AAD96D5D3F32C3723B6550A49DEE4DD9D4AC, rNAnHhommqNJvV3mLieHADNJU6mfdRqXKp
m1: 1EF5C53AC2B0E1CDEAF960833A9B7B6814879152, rsF66BeCcW5dxrDhPbCqm4ReU5MjkmshQo
m2: 0D20E8D13A89AA84F2334F57331903D21CCC866C, rpURDnkgizBF1ksJr9DmDTNLhds2NBYNbC
m6: F41810565A673D2C45C63B7A51FEA139221DFB1B, rPEe68FWPYpfEYeL3TtdVGXR8WDET24h6e
m7: 52C947B84E2412B5BD2211639E2B9DEDF3ECB5F4, r3YjXvPbu1srxx22tQefDwhXJS8qjCAgxg
m8: 3392382F09E5EA935D5624D52919C683B661238A, rn6gdHFFtieGK748TioK8cZ8SPrHsWAfe3
m9: 62F73BE6E7718B3328DEB497F8298B1C42FFD3D8, rwpHPvGwiJAFStN3KqVTeTLBTczFyK6Z6D
m10: 971B25036F1EAAEEC7A0C299E15F60AB4C465B37, rNmyZrJEtbg5p84PSKGurNs1efdDNLhb8D
m11: B79B324A56425919D0BF64FA4560C7B616F08509, rHjF2LuJKSRerNHtQMtyDUVXpQKmT18XuC
m12: 8C3AA72EBB3172726BE9FDE2A91C9CE2C9F766E5, rD8T19Nz2gkAtKKEeLpXLkTb57AS7nJ45b
m13: 3B8292604D9CF9C679E70CCD0ED5C9DC1DF84607, raRCHchPDpP8qAysxsmehC279GH613iGiM
m14: E77F5DFE960C4DA9524389F946BCD13AC26AB0D0, r4fsCASeoGzhD2ZeFgcJj1c2tmDsm1re3r
m15: D300D94BA59F55426889E144B423CFEE8F685450, rLNgbTE2HVk5CJG7SHrpSD8gsFcwu5cG1a
m16: D9C6AC46D87BCFE374BE4F59C280CEC377E67788, rLiVdCesA2rV2NjC6HZPVK7k1VpvGwCbjx
m17: A620E154D56E38B12AD76A094A214A25AD8B87A1, rG9QZQDR8XqCU1x2VARPuZwYxqcb3J9bYa
m18: 7A5A72F059F6DCDD6E938DAFBCFFB0541E0A7481, rU9A8u622H6fxGQjux8uDgomks5D8QySfS
m19: F6C06C3D86A9D39FF813AEF6B839AD041651BE7D, rPV6jx8QoQBCR1AcmVLDnu98QBu4QakwhU
m20: 1B4D3113C2AB370293A0ACEA4D68C1B29A01A013, rsVM5ZaK9QMCgrW9UKyXLguESpDpsJnRbu
m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4gD
*/
env.fund(XRP(10000), alice, bob, carol, david, edward, t1, t2, t3,
m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18, m19, m20, m21);
env.close();
setupGov(env,
{alice.id(), bob.id(), t1.id(), t2.id()},
{
{t1.id(), {m6, m7}},
{t2.id(), {m11, m12, m13, m14, m15}}
});
BEAST_EXPECT(true);
/*
auto const governHookHash =
ripple::sha512Half_s(
ripple::Slice(XahauGenesis::GovernanceHook.data(), XahauGenesis::GovernanceHook.size()));
auto addHookParams = [](Json::Value& hook, std::map<std::vector<uint8_t>, std::vector<uint8_t>> params)
{
hook[jss::HookParameters] = Json::arrayValue;
uint32_t counter = 0;
for (auto const& [k, v] : params)
{
hook[jss::HookParameters][counter] = Json::objectValue;
hook[jss::HookParameters][counter][jss::HookParameter] = Json::objectValue;
hook[jss::HookParameters][counter][jss::HookParameter][jss::HookParameterName] = strHex(k);
hook[jss::HookParameters][counter][jss::HookParameter][jss::HookParameterValue] = strHex(v);
counter++;
}
};
// governance hook must already be installed
*/
/*
// install governance hook on t1i
auto installL2Table = [&](Account const& table, std::vector<Account const*> members)
{
Json::Value tx (Json::objectValue);
tx[jss::Account] = t1.human();
tx[jss::TransactionType] = "SetHook";
tx[jss::Hooks] = Json::arrayValue;
tx[jss::Hooks][0u] = Json::objectValue;
tx[jss::Hooks][0u][jss::Hook] = Json::objectValue;
tx[jss::Hooks][0u][jss::Hook][jss::HookHash] = strHex(governHookHash);
std::map<std::vector<uint8_t>,std::vector<uint8_t>> params
{
{std::vector<uint8_t>{'I', 'M', 'C'}, std::vector<uint8_t>{ (uint8_t)(members.size()) }}
};
uint8_t counter = 0;
for (Account const* m: members)
params[std::vector<uint8_t>{'I', 'S', counter++}] =
vecFromAccount(*members);
addHookParams(tx[jss::Hooks][0u][jss::Hook], params);
env(tx, M(__LINE__), fee(XRP(100)));
env.close();
}
*/
}
// add a layer 2 table at m14 with m1 and m2 as members
/*
{
@@ -1415,8 +1569,7 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
}
*/
}
// L2 tests
// auto hooksArray =
// RH TODO:
@@ -1462,7 +1615,8 @@ m21: 748B256D2BAD918A967F40F465692C7B9A01F836, rBdNnJ4q9G3riJFcXjkwTgBu1MBR5pG4g
//testPlainActivation();
//testWithSignerList();
//testWithRegularKey();
testGovernanceL1();
// testGovernanceL1();
testGovernanceL2();
}
};