mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-12 22:55:48 +00:00
reintroduce L2 functionality into the governance hook, compiling not tested
This commit is contained in:
152
hook/govern.c
152
hook/govern.c
@@ -66,14 +66,20 @@
|
||||
* Hook Invocation:
|
||||
* ttINVOKE:
|
||||
* First time:
|
||||
* Behaviour: Setup hook, fund initial accounts, end (accept).
|
||||
* Behaviour: Setup hook, setup initial accounts, end (accept).
|
||||
*
|
||||
* Subsequent:
|
||||
* Behaviour: Vote on a topic, if the votes meet the topic vote threshold, action the topic.
|
||||
*
|
||||
* Parameter Name: {'L'}
|
||||
* Parameter Value: Which layer the vote is inteded for
|
||||
* { '1' a vote cast by an L2 member about an L1 topic }, or
|
||||
* { '2' a vote cast by an L2 member about an L2 topic }
|
||||
*
|
||||
*
|
||||
* Parameter Name: {'T'}
|
||||
* Parameter Value: The topic to vote on <2 bytes>
|
||||
* { 'S|H' (seat L1, hook L1), '\0 + topic id' }, or
|
||||
* { 'S|H' (seat, hook), '\0 + topic id' }, or
|
||||
* { 'R' (reward), 'R|D' (rate, delay) }
|
||||
*
|
||||
* Parameter Name: {'V'}
|
||||
@@ -83,7 +89,7 @@
|
||||
#define SVAR(x) &x, sizeof(x)
|
||||
|
||||
#define DONE(x)\
|
||||
accept(SVAR(x),(uint32_t)__LINE__);
|
||||
accept(SBUF(x),__LINE__);
|
||||
|
||||
#define NOPE(x)\
|
||||
rollback(SBUF(x), __LINE__);
|
||||
@@ -101,6 +107,8 @@ int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
|
||||
etxn_reserve(1);
|
||||
|
||||
int64_t tt = otxn_type();
|
||||
|
||||
if (tt != 99) // ttINVOKE only
|
||||
@@ -121,11 +129,10 @@ int64_t hook(uint32_t r)
|
||||
DONE("Goverance: Passing outgoing txn.");
|
||||
}
|
||||
|
||||
int64_t is_L1 = BUFFER_EQUAL_20(hook_accid + 12, genesis);
|
||||
|
||||
if (!is_L1)
|
||||
NOPE("Governance: This is the L1 governance hook. It can only be used on genesis account.");
|
||||
int64_t is_L1_table = BUFFER_EQUAL_20(hook_accid + 12, genesis);
|
||||
|
||||
if (is_L1_table)
|
||||
trace(SBUF("Governance: Starting governance logic on L1 table."), 0,0,0);
|
||||
|
||||
int64_t member_count = state(0,0, "MC", 2);
|
||||
if (DEBUG)
|
||||
@@ -208,8 +215,8 @@ int64_t hook(uint32_t r)
|
||||
uint8_t n = topic[1]; // number (seats) (or R/D for reward rate/delay)
|
||||
|
||||
if (result != 2 || (
|
||||
t != 'S' && // topic type: seat (L1)
|
||||
t != 'H' && // topic type: hook (L1)
|
||||
t != 'S' && // topic type: seat
|
||||
t != 'H' && // topic type: hook
|
||||
t != 'R')) // topic type: reward
|
||||
NOPE("Governance: Valid TOPIC must be specified as otxn parameter.");
|
||||
|
||||
@@ -223,9 +230,26 @@ int64_t hook(uint32_t r)
|
||||
if (t == 'R' && n != 'R' && n != 'D')
|
||||
NOPE("Governance: Valid reward topics are R (rate) and D (delay).");
|
||||
|
||||
// is their vote for the L2 table or the L1 table?
|
||||
uint8_t l = 1;
|
||||
if (!is_L1_table)
|
||||
{
|
||||
result = otxn_param(SVAR(l), "L", 1);
|
||||
if (result != 1)
|
||||
NOPE("Governance: Missing L parameter. Which layer are you voting for?");
|
||||
|
||||
if (l != '1' && l != '2')
|
||||
NOPE("Governance: Layer parameter must be '1' or '2'.");
|
||||
|
||||
l -= '0'; // now it will be 1/2 rather than '1'/'2'.
|
||||
}
|
||||
|
||||
if (l == 2 && t == 'R')
|
||||
NOPE("Governance: L2s cannot vote on RR/RD at L2, did you mean to set L=1?");
|
||||
|
||||
|
||||
// RH TODO: validate RR/RD xfl > 0
|
||||
uint8_t topic_data[32];
|
||||
uint8_t topic_data[56 /* there's a 24 byte pad on the back for later logic */];
|
||||
uint8_t topic_size =
|
||||
t == 'H' ? 32 : // hook topics are a 32 byte hook hash
|
||||
t == 'S' ? 20 : // account topics are a 20 byte account ID
|
||||
@@ -242,6 +266,7 @@ int64_t hook(uint32_t r)
|
||||
account_field[0] = 'V';
|
||||
account_field[1] = t;
|
||||
account_field[2] = n;
|
||||
account_field[3] = l;
|
||||
|
||||
// get their previous vote if any on this topic
|
||||
uint8_t previous_topic_data[32];
|
||||
@@ -260,6 +285,7 @@ int64_t hook(uint32_t r)
|
||||
// write vote to their voting key
|
||||
ASSERT(state_set(topic_data, topic_size, SBUF(account_field)) == topic_size);
|
||||
|
||||
uint8_t previous_votes = 0;
|
||||
// decrement old vote counter for this option
|
||||
if (previous_topic_size > 0)
|
||||
{
|
||||
@@ -268,9 +294,11 @@ int64_t hook(uint32_t r)
|
||||
previous_topic_data[0] = 'C';
|
||||
previous_topic_data[1] = t;
|
||||
previous_topic_data[2] = n;
|
||||
previous_topic_data[3] = l;
|
||||
|
||||
if (state(&votes, 1, SBUF(previous_topic_data)) && votes > 0)
|
||||
{
|
||||
previous_votes = votes;
|
||||
votes--;
|
||||
// delete the state entry if votes hit zero
|
||||
ASSERT(state_set(votes == 0 ? 0 : &votes, votes == 0 ? 0 : 1, SBUF(previous_topic_data)));
|
||||
@@ -286,6 +314,7 @@ int64_t hook(uint32_t r)
|
||||
topic_data[0] = 'C';
|
||||
topic_data[1] = t;
|
||||
topic_data[2] = n;
|
||||
topic_data[3] = l;
|
||||
|
||||
state(&votes, 1, SBUF(topic_data));
|
||||
votes++;
|
||||
@@ -308,21 +337,115 @@ int64_t hook(uint32_t r)
|
||||
trace(SBUF("topic"), topic, 2, 1);
|
||||
}
|
||||
|
||||
int64_t lost_majority = 0;
|
||||
|
||||
int64_t q80 = member_count * 0.8;
|
||||
int64_t q51 = member_count * 0.51;
|
||||
|
||||
if (l == 2)
|
||||
{
|
||||
if (votes <
|
||||
t == 'S'
|
||||
(t == 'S'
|
||||
? q80 // L1s have 80% threshold for membership/seat voting
|
||||
: member_count) // L1s have 100% threshold for all other voting
|
||||
: member_count)) // L1s have 100% threshold for all other voting
|
||||
DONE("Governance: Vote for L2 topic recorded. Not yet enough votes to action.");
|
||||
}
|
||||
else // l == 1
|
||||
{
|
||||
lost_majority = previous_votes >= q51 && votes < q51;
|
||||
if (lost_majority)
|
||||
trace(SBUF("Governance: Majority lost, undoing L1 vote."),0,0,0);
|
||||
else if (votes < q51)
|
||||
DONE("Governance: Vote for L1 topic recorded. Not yet enough votes to action.");
|
||||
}
|
||||
|
||||
|
||||
DONE("Governance: Vote recorded at L1. Not yet enough votes to action.");
|
||||
|
||||
// action vote
|
||||
if (DEBUG)
|
||||
TRACESTR("Actioning votes");
|
||||
|
||||
switch (t)
|
||||
if (l == 1)
|
||||
{
|
||||
|
||||
|
||||
uint8_t txn_out[1024];
|
||||
uint8_t* buf_out = txn_out;
|
||||
uint32_t cls = (uint32_t)ledger_seq();
|
||||
_01_02_ENCODE_TT (buf_out, ttINVOKE);
|
||||
_02_02_ENCODE_FLAGS (buf_out, tfCANONICAL);
|
||||
_02_04_ENCODE_SEQUENCE (buf_out, 0);
|
||||
_02_26_ENCODE_FLS (buf_out, cls + 1);
|
||||
_02_27_ENCODE_LLS (buf_out, cls + 5);
|
||||
uint8_t* fee_ptr = buf_out;
|
||||
_06_08_ENCODE_DROPS_FEE (buf_out, 0);
|
||||
_07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out);
|
||||
_08_01_ENCODE_ACCOUNT_SRC (buf_out, hook_accid + 12);
|
||||
_08_03_ENCODE_ACCOUNT_DST (buf_out, genesis);
|
||||
int64_t edlen = etxn_details((uint32_t)buf_out, 512);
|
||||
buf_out += edlen;
|
||||
|
||||
/** Parameters:
|
||||
* F013E017 70180154
|
||||
* 701902
|
||||
* <00> <two byte topic code>
|
||||
* E1E0177018015670
|
||||
* 19
|
||||
* <topic len>
|
||||
* <topic data>
|
||||
* E1F1
|
||||
*/
|
||||
|
||||
// note wasm is LE and Txns are BE so these large constants are endian flipped
|
||||
// to undo the flipping on insertion into memory
|
||||
*((uint64_t*)buf_out) = 0x5401187017E013F0ULL; // parameters array, first parameter preamble
|
||||
buf_out += 8;
|
||||
*((uint32_t*)buf_out) = 0x021970UL;
|
||||
buf_out += 3;
|
||||
*buf_out++ = (t << 4) + n; // topic
|
||||
*((uint64_t*)buf_out) = 0x705601187017E0E1ULL;
|
||||
buf_out += 8;
|
||||
*buf_out++ = 0x19U;
|
||||
// topic data len
|
||||
*buf_out++ = topic_size;
|
||||
if (lost_majority)
|
||||
{
|
||||
// do nothing, the array already has zeros here
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t* d = (uint64_t*)buf_out;
|
||||
uint64_t* s = (uint64_t*)(topic_data + padding);
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
buf_out += topic_size;
|
||||
// topicdata
|
||||
*((uint16_t*)buf_out) = 0xF1E1U;
|
||||
|
||||
int64_t txn_len = buf_out - txn_out;
|
||||
|
||||
// populate fee
|
||||
int64_t fee = etxn_fee_base(txn_out, txn_len);
|
||||
_06_08_ENCODE_DROPS_FEE (fee_ptr, fee );
|
||||
|
||||
trace(SBUF("Governance: Emitting invoke to L1"), txn_out, txn_len, 1);
|
||||
|
||||
|
||||
uint8_t emit_hash[32];
|
||||
int64_t emit_result = emit(SBUF(emit_hash), txn_out, txn_len);
|
||||
|
||||
trace_num(SBUF("Governance: Emit result"), emit_result);
|
||||
|
||||
if (emit_result == 32)
|
||||
accept(SBUF("Governance: Successfully emitted L1 vote."), __LINE__);
|
||||
|
||||
NOPE("Governance: L1 vote emission failed.");
|
||||
}
|
||||
|
||||
switch(t)
|
||||
{
|
||||
case 'R':
|
||||
{
|
||||
@@ -368,7 +491,6 @@ int64_t hook(uint32_t r)
|
||||
NOPE("Goverance: Hook Hash doesn't exist on ledger while actioning hook.");
|
||||
|
||||
// it does so now we can do the emit
|
||||
etxn_reserve(1);
|
||||
|
||||
uint8_t* hookhash =
|
||||
topic_data_zero
|
||||
|
||||
Reference in New Issue
Block a user