From Mochimo Wiki
Revision as of 09:25, 22 November 2020 by Mochimowiki (talk | contribs) (Technical Details)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

MIP-0003 - Add Fountain Functionality As Native Feature

Presented to the Core Contributor Team on November 21, 2020 by user sputnik


The following Core Contributors have "sponsored" this MIP.

Stackoverflo (talk · contribs) I think it's long overdue. I'll code it as an optional module at first and if the community agrees we'll add it to the mainline code.

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

Fountain services are presently operated by the Mochimo project, and while documentation exists for how to run a Fountain Service, it would be beneficial for this to simply be a built-in optional module for the full node code.

Solution Summary

Users will add a "fountain.addr" address file to the Mochimo Full Node startup directory, and then enable an additional command-line switch on node startup, to allow it to receive and process requests as a fountain node.

Hard Fork Required ?


Technical Details

A global byte var "Fountain" is added to data.c to signal when the feature is enabled:

byte Fountain;        /* enable fountain service if true */
byte Max_reg;         /* Maximum number of simultaneous Tag registrations per block */
byte Pending_reg;     /* Number of pending Tag registrations during this block */

A new capability bit "C_FOUNTAIN" is added to types.h to signal the node has fountain service enabled:

#define C_FOUNTAIN   32

NOTE: At time of proposal CBIT 32 is the first available.

A command-line switch "r" is added to mochimo.c, and function usage() updated to reflect new switch "r":

void usage(void)
printf("usage: mochimo [-option...]\n"
"         -r[MAX_REGISTRATIONS]         enable Fountain / Tag Registration Service\n"

Function main() switch(argv[j][1]) updated to reflect new switch "r", set global var Fountain to true, and set node capability bit for C_FOUNTAIN:

case 'r':  Fountain = 1;  Cbits |= C_FOUNTAIN;  Max_registrations = atoi(&argv[j][2]); break;

A new OP_CODE is added to types.h to identify when an inbound transaction is a Tag registration request to the fountain service.

#define OP_REGISTER       20

An handler entry is added to "execute.c" to call the registration function, when a registration request is received:

int execute(NODE *np)
  switch(np->opcode) {
     case OP_REGISTER:
        /* Process a tag registration request if Fountain service is enabled. */
        if(Fountain) register(np);
        return 0;

Add a function to init.c to read in data from fountain1.addr and fountain2.addr:

int read_fountain()
... /* read fountain addresses from /bin/fountain */
... /* returns VEOK if successful */

Add a call to "read_fountain() in function init() if Fountain feature is enabled:

  if(Fountain) {
     /* Add addresses and keys to FountainArray[MAX_REGISTRATIONS*2][MAX_REGISTRATIONS*2] */
     if(read_fountain() != VEOK) error("init(): read_fountain() could not load fountain address files");

Add a line to the server main loop in server.c to reset pending and maximum registrations on block update:

              if(update("rblock.dat", 0) == VEOK) {
                 Max_reg = 0;
                 Pending_reg = 0;
                 Cbits |= C_FOUNTAIN; /* Reset the Fountain bit */
                 /* Empty Registrant IP List */

The file "fountain.c" is added to the source directory with the processing logic for the new OP_CODE, as follows.

  1. If Pending_reg is greater than or equal to Max_reg: return 1.
  2. Increment Pending_reg.
  3. If Pending_reg equals Max_reg: Disable node capability bit for C_FOUNTAIN to signal to queriers that this node is not available to register tags.
  4. Received passed in node pointer, and extract the source address and tag into registry_address.
  5. Collect the node pointer registrant IP.
  6. Confirm the IP is not present in RegIPL. Return 1 if present, decrement Pending_reg, enable node capability bit for C_FOUNTAIN.
  7. Add registrant IP to RegIPL.
  8. Confirm the tag does not exist in the ledger.
  9. Read address from FountainArray[Pending_reg * 1][Pending_reg * 1] into reg1, key1
  10. Read address from FountainArray[Pending_reg * 2][Pending_reg * 1] into reg2, key2
  11. Craft a transaction from reg1 to registry_address, change to reg2, and sign with key1
  12. Craft a transaction from reg2 to registry_address, change to reg1, and sign with key2
  13. Connect to 4 random nodes on the current_peer list and send transactions reg1 and reg2 to them.