[BD-2238] Add voter_info to fio.token accounts table - Development Spec

Links

https://fioprotocol.atlassian.net/browse/BD-2238

https://github.com/fioprotocol/fio/issues/159

Design

Voters table contents will be directly moved over to a new table (voters2)

  • System contract must be made to accept both tables

  • Voters cannot be added to the voters2 table until the migration is done

    • On call to voteproducer, if the voters table is not empty then the migration is considered incomplete

    • Each call to voteproducer will move as many transactions as possible within the allowable timeframe (currently 3 voter records per call to voteproducer)

    • Anyone can call voteproducer to move the records.

    • Once voters table is empty, the calls to voteproducer function as before and use voters2

  • The abi generated will support new and old tables

  • Pre-existing objects referencing the old table will reference the new table in state.

  • Chain_plugin get_account endpoint needs to be updated to use voters2

    • Logic will check for intended record in voters, and then voters2 if not found. If record is not found in one, and then the other, then result is null.


Comparison of voters and voters2 from using fio.devtools voters.

voters table

{ "rows": [{ "id": 0, "fioaddress": "vote1@dapixdev", "addresshash": "0x7dd4aee1e2ec5e5aea42284d55664fab", "owner": "o2ouxipw2rt4", "proxy": "", "producers": [ "qbxn5zhw2ypw" ], "last_vote_weight": "25000000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 1, "fioaddress": "vote2@dapixdev", "addresshash": "0xb74940cb0af1797859852dc95b402edc", "owner": "extjnqh3j3gt", "proxy": "", "producers": [ "hfdg2qumuvlc" ], "last_vote_weight": "25000000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 2, "fioaddress": "vote3@dapixdev", "addresshash": "0xdee17e772d87d113e2da5224848638ca", "owner": "npe3obkgoteh", "proxy": "", "producers": [ "wttywsmdmfew" ], "last_vote_weight": "25000000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 3, "fioaddress": "adam@dapixdev", "addresshash": "0x7b1f3f177bb193e1e48ffb74be9efccc", "owner": "htjonrkf1lgs", "proxy": "", "producers": [], "last_vote_weight": "1000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 4, "fioaddress": "casey@dapixdev", "addresshash": "0xc1a7cdccb8b3f528a33f7005a508ccab", "owner": "r41zuwovtn44", "proxy": "", "producers": [], "last_vote_weight": "1000999000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 5, "fioaddress": "ed@dapixdev", "addresshash": "0x002440d1a3ec11cc70372d45bc645c58", "owner": "euwdcp13zlrj", "proxy": "", "producers": [ "qbxn5zhw2ypw" ], "last_vote_weight": "2000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " } ], "more": false }

 
voters2 table

{ "rows": [{ "id": 0, "fioaddress": "vote1@dapixdev", "addresshash": "0x7dd4aee1e2ec5e5aea42284d55664fab", "owner": "o2ouxipw2rt4", "proxy": "", "producers": [{ "producer": "qbxn5zhw2ypw", "fioaddress": "bp1@dapixdev" } ], "last_vote_weight": "25000000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 1, "fioaddress": "vote2@dapixdev", "addresshash": "0xb74940cb0af1797859852dc95b402edc", "owner": "extjnqh3j3gt", "proxy": "", "producers": [{ "producer": "hfdg2qumuvlc", "fioaddress": "" } ], "last_vote_weight": "25000000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 2, "fioaddress": "vote3@dapixdev", "addresshash": "0xdee17e772d87d113e2da5224848638ca", "owner": "npe3obkgoteh", "proxy": "", "producers": [{ "producer": "wttywsmdmfew", "fioaddress": "" } ], "last_vote_weight": "25000000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 3, "fioaddress": "adam@dapixdev", "addresshash": "0x7b1f3f177bb193e1e48ffb74be9efccc", "owner": "htjonrkf1lgs", "proxy": "", "producers": [], "last_vote_weight": "1000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 4, "fioaddress": "casey@dapixdev", "addresshash": "0xc1a7cdccb8b3f528a33f7005a508ccab", "owner": "r41zuwovtn44", "proxy": "", "producers": [], "last_vote_weight": "1000999000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " },{ "id": 5, "fioaddress": "ed@dapixdev", "addresshash": "0x002440d1a3ec11cc70372d45bc645c58", "owner": "euwdcp13zlrj", "proxy": "", "producers": [{ "producer": "qbxn5zhw2ypw", "fioaddress": "" } ], "last_vote_weight": "2000000000000.00000000000000000", "proxied_vote_weight": "0.00000000000000000", "is_proxy": 0, "is_auto_proxy": 0, "reserved2": 0, "reserved3": "0 " } ], "more": false }

Note the first voter in the entry was used for the voteproducer call and had the votes and producer fioaddress updated on the subsequent call after table migration.

SDK Requirements

  • All tests using the voters table will need to be changed to use voters2 from system contract (currently deployed on account eosio) in any SDKs, possibly 3rd party tools accessing voters table directly

Functional Test plan

Current tests:

  • vote.js > describe('v1.2.0 release only. H. Confirm voter data is returned with get_account'

Post Table Migration

  1. Verify voters2 table contents match what was in voters before the migration

  2. Register a producer

  3. Register fio_address for producer

  4. Vote for the producer

  5. Verify owner and fio_address are populated as a voter in the accounts voters2 record

  6. Verify voting still works and no regression

Plan:

  • TODO: Add the post table migration tests above to vote.js. Confirm running them at all phases of contract rollout.

Performance Testing plan

  • Voteproducer stress testing should be done on voters table before the migration, then voter2 table after the migration. Results will be compared.

  • Tests carried out on devnet, testnet before deployment to mainnet

Fork Testing plan

  • Forking is not anticipated, but producers should be watched carefully on testnet post migration for any possible forking.

Rollout/Release plan

  • Chain_plugin update must be released first so more block producers are able to support the new voters table before the contract update has been rolled out

    • Chain code is in Bahamas

  • There is a single contract deployment (see below)

  • For Testnet and Mainnet release, confirm that bloks.io is accessing either the new Table, or getting voter information from the account record.

  • Work with BPs to update any tools that point to the voters table.

Rollout/Release verification plan

  • After new system contract has been deployed, voteproducer will be called several times by an account with 0 FIO balance. Once migration is complete, the transaction will fail for insufficient balance.

    • As soon as the contract is live, voteproducer will only move records

      • If the account has funds, it will take a fee, so only should be called with 0 FIO account.

    • This copies records over to voters2

    • Moves 2-3 records

    • Once the original table is empty, then voteproducer starts working as expected

    •  

  • Retrieve contents of voters2

  • Verify contents of voters2 with contents of voters, they should contain the original owner account of the producers voted for and an empty fio address field.

  • Plan to have the migration and verification automated on a script. This should be worked on before contract roll-out.

Progress notes

  • Completed work on table migration. In testing phase. fio.system contract (eosio account) has been updated with the following features:

    • Voteproducer calls will only migrate 3 vote records over from voters to voters2 table at a time. After the approximate 83 records are moved over, the voteproducer action will function again.

    • The migration logic will not execute so long as the old voters table stays empty, which should be indefinite or until the contract is updated with the migration logic removed.

    • All contracts will now use “voters2” in state.

    • The data should be exact, and the producers that a voter has voted for will not have the respective fio_address item populated for the producer that was voted for at the time previous to the migration. This will be updated on that users next call to voteproducer.
      https://github.com/fioprotocol/fio.contracts/pull/33/files

  • v1/chain/get_account has been updated to search the voters table first, and then the voters2 table. If there is no result from either table the voter_info is treated as null as before.
    https://github.com/fioprotocol/fio/pull/230/