[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
Verify voters2 table contents match what was in voters before the migration
Register a producer
Register fio_address for producer
Vote for the producer
Verify owner and fio_address are populated as a voter in the accounts voters2 record
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/