From Mochimo Wiki
Jump to: navigation, search

MIP-0011 - Implement Proof of Merit

Presented to the Core Contributor Team on May 26th, 2023 by user Cuetum


The following Core Contributors have "sponsored" this MIP.

Stackoverflo (talk · contribs) It's a little complicated, but it makes solo mining more equitable, and strengthens the network.

NOTE: Sponsorship for these purposes means that these Core Contributors have committed to developing the code on behalf of the community if this MIP is adopted. Note: Core Contributor sponsorship is not required for a MIP to be implemented. It just makes things easier on the community.

Problem Definition

Only one miner gets paid to mine a block, even if other miners are regularly mining. Implementing a solution that pays more than one miner will reduce the need for centralized mining pools, and allow smaller miners to be compensated according to their contributions.

Solution Summary

Summary: Block rewards will now paid out for the current block -1, only when the current block solution is found. It no longer matters who solved the current block. They will not be paid until the next block is solved. The top 256 miners for each block receive a piece of the payout.

A statistically idealized block will have these 256 PoM transactions:


1    1 x D      1/8     = .125
2    2 x D - 1  1/16    = .125
3    4 x D - 2  1/32    = .125
4    8 x D - 3  1/64    = .125
5   16 x D - 4  1/128   = .125
6   32 x D - 5  1/256   = .125
7   64 x D - 6  1/512   = .125
8  128 x D - 7  1/1024  = .125

To calculate the payout for the current block, the PoMs in the previous block are paid according to their ordinal position in the POM_CURRENT table. If you are position number 2, you will receive 1/16 of pool. If you are position 128, you will receive 1/512th of the pool. This approach ensures that our top 256 miners always get paid according to their respective share of the mining hash rate, averaging their pay automatically and statistically as they contribute to the mining pool. Since the scale of payout is exactly linear, over time the portion of the payout a miner receives will equate to the portion of the network hash rate they represent.


Conversion to Post-MCM 3.0 Ledger-by-Hash
Conversion to Post-MCM 3.0 Variable Length Protocol Data Unit

Hard Fork Required


Technical Details

  • New Global Variables
    • LastReward: Contains the previous block's total reward amount, and is updated on block update. It is populated by the existing mining reward calculator applied upon receipt or generation of a solution block.
    • P2Blockhash: Contains the second previous block hash in the current chain, and is repopulated on block update.
    • BestBlock: The current difficulty of the bestblock.dat file on disk (our best find during this mining iteration). Resets to zero on block update.
  • New File on Disk
    • bestblock.dat: The block representing highest discovered solution of the current block's mining efforts.
  • New Transaction Type: PoM
    • Upon receipt of a transaction, TXVAL will identify the TX as a PoM if the OP_CODE == 20, of length 200 bytes under the new variable-length PDU structure (to be implemented in MCM 3.0).
  • New Validator: pomval()
    • For each received PoM notification, the receiving node performs a validity check:
      • Is this PoM for our first previous block?
      • Is the advertised solution difficulty greater than the previous block's difficulty - 8?
      • Is the previous block hash in the PoM equal to the global P2Blockhash (are we on the same chain?)
      • Is the difficulty in the PoM greater than or equal to the difficulty in the POM_CURRENT[256] Difficulty value?
    • Is the PoM Solution nonce valid within the context of the received trailer information (did the node do the work?)
  • New Working Structs for PoM Sort:
 /* Node maintains 2 PoM transaction structs, with 256 slots each. */
    word8 difficulty;              /*     8 Difficulty of the Solution */
    word8 m_addr;                  /*    32 Miner Address Hash         */ 
    word8 block_trailer[BTSIZE];   /*   160 Block Trailer Struct       */
  • New pomsort() function
    • Has OP_POM TX passed in, and the contents of the POM_CURRENT are evaluated against the new entry 1 entry at a time through 256 iterations, performing an ordinal copy-sort:
    • Loop:
      • If the new PoM difficulty is greater than the current entry, copy the PoM to POM_WORKING, break
      • If the new PoM difficulty is less than the current entry, copy the current entry to POM_WORKING, and continue.
      • If the new PoM difficulty is equal to the current entry:
        • If the new POM m_addr is numerically lower than that of the current entry, copy the current entry to POM_WORKING, break
      • Copy the current entry to the POM_WORKING
      • Copy the remainder of POM_CURRENT to POM_WORKING, less 200 bytes (for the inserted record).
      • Set POM_WORKING to all zeroes.
  • New OPCODE:
  #define OP_POM          20
  #define LAST_OP         20
  • New executor switch case in network.c executor (case switch on line 809)
    • Performs pomval()
    • Performs pomsort()
    • Performs standard tx mirror()
  • New action when generating a candidate block in cblock:
    • When generating a candidate block, the POM_CURRENT is added to the block as the first 51200 bytes of every block following the block header.
  • New action when bval() is run to verify a block: pomval() is run on each of the 256 POMs present to validate them.
  • New action on block update:
    • If the node is mining, a block update is received and successfully processed, if there exists a "bestblock.dat" on disk, an OP_POM tx is generated and sent to the node's peers. When the local ledger is updated, during block update, each of the POM_CURRENT entries in the solution block have their respective address hash credited with the their payout index value based on the ordinal position within the POM_CURRENT Struct, rounded down to the nearest satochi. LastReward is the total of the reward + mining fees from the last block. LastReward is then updated based on the new solution block, Last Weight is set to zero. P2Blockhash is updated to the previous block hash of the previous block. The bestblock.old file is unlinked if it exists, and bestblock.dat is renamed to bestblock.old.