various governance fixes, tests

This commit is contained in:
Richard Holland
2023-08-31 13:20:24 +00:00
parent 7ebfa0b324
commit c2f8b1354a
3 changed files with 773 additions and 631 deletions

View File

@@ -1,6 +1,6 @@
#include "hookapi.h"
#define ASSERT(x)\
if (!(x))\
if ((x) < 0)\
rollback(SBUF("Govern: Assertion failed."),__LINE__);
#define SEAT_COUNT 20
@@ -139,9 +139,7 @@ int64_t hook(uint32_t r)
trace(SBUF("Governance: Starting governance logic on L1 table."), 0,0,0);
int64_t member_count = state(0,0, "MC", 2);
if (DEBUG)
TRACEVAR(member_count);
// initial execution, setup hook
if (member_count == DOESNT_EXIST)
{
@@ -149,11 +147,17 @@ int64_t hook(uint32_t r)
uint8_t imc;
uint64_t irr, ird;
TRACEVAR(imc);
if (hook_param(SVAR(imc), "IMC", 3) < 0)
NOPE("Governance: Initial Member Count Parameter missing (IMC).");
TRACEVAR(imc);
// set member count
ASSERT(state_set(SVAR(imc), "MC", 2));
member_count = imc;
TRACEVAR(member_count);
if (imc == 0)
NOPE("Governance: Initial Member Count must be > 0.");
@@ -178,12 +182,6 @@ int64_t hook(uint32_t r)
ASSERT(state_set(SVAR(ird), "RD", 2));
}
// set member count
ASSERT(state_set(SBUF(imc), "MC", 2));
member_count = imc;
TRACEVAR(member_count);
for (uint8_t i = 0; GUARD(SEAT_COUNT), i < member_count; ++i)
{
uint8_t member_acc[20];
@@ -205,6 +203,10 @@ int64_t hook(uint32_t r)
DONE("Governance: Setup completed successfully.");
}
if (DEBUG)
TRACEVAR(member_count);
// otherwise a normal execution (not initial)
// first let's check if the invoking party is a member
@@ -290,7 +292,7 @@ int64_t hook(uint32_t r)
// and we will have to increment the new voting
// write vote to their voting key
ASSERT(state_set(topic_data, topic_size, SBUF(account_field)) == topic_size);
ASSERT(state_set(topic_data + padding, topic_size, SBUF(account_field)) == topic_size);
uint8_t previous_votes = 0;
// decrement old vote counter for this option
@@ -323,9 +325,9 @@ int64_t hook(uint32_t r)
topic_data[2] = n;
topic_data[3] = l;
state(&votes, 1, SBUF(topic_data));
state(&votes, 1, topic_data, 32);
votes++;
ASSERT(state_set(&votes, 1, SBUF(topic_data)));
ASSERT(state_set(&votes, 1, topic_data, 32));
// restore the saved bytes
*((uint64_t*)topic_data) = saved_data;
@@ -374,7 +376,7 @@ int64_t hook(uint32_t r)
if (DEBUG)
TRACESTR("Actioning votes");
if (l == 1)
if (l == 2)
{
@@ -459,7 +461,7 @@ int64_t hook(uint32_t r)
case 'R':
{
// reward topics
ASSERT(state_set(topic_data, 8, SBUF(topic))); // interest rate is on the the FF, 0...0 key
ASSERT(state_set(topic_data + padding, topic_size, SBUF(topic)));
if (n == 'R')
DONE("Governance: Reward rate change actioned!");
@@ -597,7 +599,7 @@ int64_t hook(uint32_t r)
ASSERT(state_set(topic_data, 20, n, 1) == 20);
// forward key
ASSERT(state_set(n, 1, SBUF(topic_data)) == 20);
ASSERT(state_set(n, 1, topic_data, 32) == 20);
}
DONE("Governance: Action member change.");

File diff suppressed because it is too large Load Diff

View File

@@ -363,7 +363,7 @@ struct XahauGenesis_test : public beast::unit_test::suite
setupGov(env, {alice.id(), bob.id(), carol.id(), david.id(), edward.id()});
auto vote = [](
auto vote = [&](
Account const& acc,
char topic1,
std::optional<char> topic2,
@@ -404,26 +404,21 @@ struct XahauGenesis_test : public beast::unit_test::suite
txn[jss::Account] = acc.human();
txn[jss::TransactionType] = "Invoke";
txn[jss::Destination] = env.master.human();
return txn;
};
// alice votes for a different reward rate
env(vote(alice, 'R', 'R', std::vector<uint8_t>{1,2,3,4,5,6,7,8}), fee(XRP(1)));
env.close();
//VRR...000...alice.id
auto makeStateKey = [&](char a, char b, char c, AccountID const& id) -> uint256
auto makeStateKey =
[&](char voteType, char topic1, char topic2, uint8_t layer, AccountID const& id) -> uint256
{
uint8_t data[32];
memset(data, 0, 32);
data[0] = a;
data[1] = b;
data[2] = c;
data[0] = voteType;
data[1] = topic1;
data[2] = topic2;
data[3] = layer;
for (int i = 0; i < 20; ++i)
data[12 + i] = id.data()[i];
@@ -431,13 +426,50 @@ struct XahauGenesis_test : public beast::unit_test::suite
return uint256::fromVoid(data);
};
//hookState(AccountID const& id, uint256 const& key, uint256 const& ns) noexcept;
auto const kl =
keylet::hookState(env.master.id(), makeStateKey('V', 'R', 'R', alice.id()),
keylet::hookState(env.master.id(), makeStateKey('V', 'R', 'R', 1, alice.id()),
uint256("0000000000000000000000000000000000000000000000000000000000000000"));
auto entry = env.le(kl);
BEAST_EXPECT(!entry);
// alice votes for a different reward rate
std::vector<uint8_t> vote_data{0x00U,0x81U,0xC6U,0xA4U,0x7EU,0x8DU,0x43U,0x54U};
env(vote(alice, 'R', 'R', vote_data), fee(XRP(1)));
env.close();
//VRR...000...alice.id
//hookState(AccountID const& id, uint256 const& key, uint256 const& ns) noexcept;
entry = env.le(kl);
BEAST_REQUIRE(!!entry);
auto data = entry->getFieldVL(sfHookStateData);
BEAST_EXPECT(data.size() == 8);
BEAST_EXPECT(data == vote_data);
auto doL1Vote = [&](Account const& acc, char topic1, char topic2, std::vector<uint8_t> const& data) -> void
{
env(vote(acc, 'R', 'R', vote_data), fee(XRP(1)));
env.close();
auto entry = env.le(keylet::hookState(env.master.id(), makeStateKey('V', 'R', 'R', 1, acc.id()),
uint256("0000000000000000000000000000000000000000000000000000000000000000")));
BEAST_REQUIRE(!!entry);
auto lgr_data = entry->getFieldVL(sfHookStateData);
BEAST_EXPECT(lgr_data.size() == vote_data.size());
BEAST_EXPECT(lgr_data == vote_data);
};
// bob votes the same way
doL1Vote(bob, 'R', 'R', vote_data);
// ... etc until 100%
doL1Vote(carol, 'R', 'R', vote_data);
doL1Vote(david, 'R', 'R', vote_data);
doL1Vote(edward, 'R', 'R', vote_data);
BEAST_EXPECT(!!entry);
}
@@ -498,9 +530,9 @@ struct XahauGenesis_test : public beast::unit_test::suite
run() override
{
using namespace test::jtx;
testPlainActivation();
testWithSignerList();
testWithRegularKey();
//testPlainActivation();
//testWithSignerList();
//testWithRegularKey();
testGovernance();
}
};