mirror of
				https://github.com/Xahau/xahaud.git
				synced 2025-11-04 10:45:50 +00:00 
			
		
		
		
	reintroduce L2 functionality into the governance hook, compiling not tested
This commit is contained in:
		
							
								
								
									
										158
									
								
								hook/govern.c
									
									
									
									
									
								
							
							
						
						
									
										158
									
								
								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 (votes <
 | 
			
		||||
        t == 'S'
 | 
			
		||||
            ? q80                      // L1s have 80% threshold for membership/seat voting
 | 
			
		||||
            : member_count)            // L1s have 100% threshold for all other voting
 | 
			
		||||
    if (l == 2)
 | 
			
		||||
    {
 | 
			
		||||
       if (votes <
 | 
			
		||||
            (t == 'S'
 | 
			
		||||
                ? q80                      // L1s have 80% threshold for membership/seat 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':
 | 
			
		||||
        {
 | 
			
		||||
@@ -333,7 +456,7 @@ int64_t hook(uint32_t r)
 | 
			
		||||
            
 | 
			
		||||
            DONE("Governance: Reward delay change actioned!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        case 'H':
 | 
			
		||||
        {
 | 
			
		||||
            // hook topics
 | 
			
		||||
@@ -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