fip | title | status | type | author | created | updated |
---|---|---|---|---|---|---|
10 |
Redesign Fee Computations |
Final |
Functionality |
Ed Rotthoff <[email protected]>; Pawel Mastalerz <[email protected]> |
2020-06-07 |
2021-06-15 |
This FIP implements a redesign of the fee voting and computation, and bundled transaction voting and computation in the FIO Protocol. Specifically:
- Fee computation will be removed from onblock and from setfeevote and setfeemult and attached to a dedicated action/endpoint.
- Top 150 block producers will be permitted to vote for fees and bundled transactions.
- A fee will be collected whenever a setfeevote, setfeemult is executed, and bundlevote
- Only votes of top 21 block producers will be used to compute the fees and bundled transactions.
Proposed new actions:
Action | Endpoint | Description |
---|---|---|
computefees | compute_fees | Computes fee votes and sets fees in the FIO Protocol. |
Modified actions:
Action | Endpoint | Description |
---|---|---|
setfeevote | submit_fee_ratios | Can now be called by top 150 BP. Fee is added. Fee computation removed from this action. |
setfeemult | submit_fee_multiplier | Can now be called by top 150 BP. Fee is added. Fee computation removed from this action. |
bundlevote | submit_bundled_transaction | Can now be called by top 150 BP. Fee is added. |
The FIO Protocol was designed to enable top 21 producers to vote on protocol fees and bundled transactions via setfeevote, and setfeemult.
The computation of fees occurs after every setfeevote or setfeemult. The fees are also recomputed in the onblock every 126 blocks.
It has been found that the processing required to compute fees is too large to be handled in onblock or attached to action of setting fees, especially if number of block producers allowed to vote is increased beyond top 21, which has been discussed in Issue 147 and now part of this FIP.
To address this issue, a new endpoint dedicated to fee computation should be implemented. This will follow the same approach as other areas of the FIO Protocol, such as burning of expired addresses, and claiming of rewards.
Computes and sets fees in the FIO Protocol.
New fee: this action will not have a fee, as it will only process if work is needed and return exception otherwise
Empty
- Request is validated per Exception handling.
- Throw no work exception if no work is left to do.
- Compute the number of fees to process.
- Assemble the next NFP fees to process.
- Process the fees (set the votesPending false on update).
- Return response.
- Any account on the protocol can call this, but BPs should call as a service. Note it throws no work exception when its done all necessary work and so is protected from polluting the block log.
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
No work | No work to perform | 400 | "computefees" | "computefees" | "No work." |
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
fees_processed | Int | Number of fees processed |
{
"status": "OK",
"fees_processed": 7
}
Modified to be callable by top 150 BP, and charge a fee.
Group | Parameter | Required | Format | Definition |
---|---|---|---|---|
fee_ratios | Yes | JSON Array | Array of fees and corresponding ratios. | |
fee_ratios | end_point | Yes | String | Name of endpoint for which fee is being set. |
fee_ratios | value | Yes | Int | Fee in SUFs which will be multiplied by multiplier. |
max_fee | Yes | Positive Int | Maximum amount of SUFs the user is willing to pay for fee. Should be preceded by /get_fee for correct value. | |
actor | Yes | 12 character string | Valid actor of signer. |
{
"fee_ratios": [
{
"end_point": "register_fio_domain",
"value": 40000000000
},
{
"end_point": "register_fio_address",
"value": 2000000000
},
{
"end_point": "renew_fio_domain",
"value": 40000000000
},
{
"end_point": "renew_fio_address",
"value": 2000000000
},
{
"end_point": "add_pub_address",
"value": 30000000
},
{
"end_point": "transfer_tokens_pub_key",
"value": 100000000
},
{
"end_point": "new_funds_request",
"value": 60000000
},
{
"end_point": "reject_funds_request",
"value": 30000000
},
{
"end_point": "record_obt_data",
"value": 60000000
},
{
"end_point": "set_fio_domain_public",
"value": 30000000
},
{
"end_point": "register_producer",
"value": 10000000000
},
{
"end_point": "register_proxy",
"value": 1000000000
},
{
"end_point": "unregister_proxy",
"value": 20000000
},
{
"end_point": "unregister_producer",
"value": 20000000
},
{
"end_point": "proxy_vote",
"value": 30000000
},
{
"end_point": "vote_producer",
"value": 30000000
},
{
"end_point": "auth_delete",
"value": 20000000
},
{
"end_point": "auth_link",
"value": 20000000
},
{
"end_point": "auth_update",
"value": 50000000
},
{
"end_point": "msig_propose",
"value": 50000000
},
{
"end_point": "msig_approve",
"value": 20000000
},
{
"end_point": "msig_unapprove",
"value": 20000000
},
{
"end_point": "msig_cancel",
"value": 20000000
},
{
"end_point": "msig_exec",
"value": 20000000
},
{
"end_point": "msig_invalidate",
"value": 20000000
}
],
"max_fee": 0,
"actor": "aftyershcu22"
}
Modify the existing action to:
- Store submitted value, but not calculate fees.
- Use the new fees table and set the votesPending to 1.
- Allow only Top 150 block producers to call it.
- Charge a fee.
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Not a BP | Actor is not in the Top 150 BP. | 400 | "actor" | Value sent in, e.g. "aftyershcu22" | "Not a top 150 BP." |
Not positive | Fee value is not positive | 400 | "value" | Value sent in, e.g. "-1" | "Value has to be positive." |
Invalid end_point | End point is not valid or does not exist. | 400 | "end_point" | Value sent in, e.g. "xxx" | "Invalid end_point." |
Too soon since last call | Call was made less than 3600 seconds since last call. | 400 | "Too soon since last call." | ||
Invalid fee value | max_fee format is not valid | 400 | "max_fee" | Value sent in, e.g. "-100" | "Invalid fee value" |
Insufficient funds to cover fee | Account does not have enough funds to cover fee | 400 | "max_fee" | Value sent in, e.g. "1000000000" | "Insufficient funds to cover fee" |
Fee exceeds maximum | Actual fee is greater than supplied max_fee | 400 | max_fee" | Value sent in, e.g. "1000000000" | "Fee exceeds supplied maximum" |
Signer’s FIO Public Key does not match actor | Signer’s FIO Public Key does not match actor | 403 | Type: invalid_signature |
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
fee_collected | Int | Amount of SUFs collected as fee |
{
"status": "OK",
"fee_collected": 2000000000
}
Modified to be callable by top 150 BP, and charge a fee.
Parameter | Required | Format | Definition |
---|---|---|---|
multiplier | Yes | Double | Multiplier |
max_fee | Yes | Positive Int | Maximum amount of SUFs the user is willing to pay for fee. Should be preceded by /get_fee for correct value. |
actor | Yes | 12 character string | Valid actor of signer |
Modify the action to:
- Use the new fees table and set the votesPending to 1.
- Allow only top 150 block producers to call it.
- Charge a fee.
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Not a BP | Actor is not a top 150 BP. | 400 | "actor" | Value sent in, e.g. "aftyershcu22" | "Not a top 150 BP." |
Not positive | Multiplier value is not positive | 400 | "value" | Value sent in, e.g. "-1" | "Value has to be positive." |
Too soon since last call | Call was made less than 120 seconds since last call. | 400 | "Too soon since last call." | ||
Invalid fee value | max_fee format is not valid | 400 | "max_fee" | Value sent in, e.g. "-100" | "Invalid fee value" |
Insufficient funds to cover fee | Account does not have enough funds to cover fee | 400 | "max_fee" | Value sent in, e.g. "1000000000" | "Insufficient funds to cover fee" |
Fee exceeds maximum | Actual fee is greater than supplied max_fee | 400 | max_fee" | Value sent in, e.g. "1000000000" | "Fee exceeds supplied maximum" |
Signer’s FIO Public Key does not match actor | Signer’s FIO Public Key does not match actor | 403 | Type: invalid_signature |
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
fee_collected | Int | Amount of SUFs collected as fee |
{
"status": "OK",
"fee_collected": 2000000000
}
Modified to be callable by top 150 BP, and charge a fee.
Parameter | Required | Format | Definition |
---|---|---|---|
bundled_transactions | Yes | int | Number of bundled transactions which should be included with every FIO Address. |
max_fee | Yes | Positive Int | Maximum amount of SUFs the user is willing to pay for fee. Should be preceded by /get_fee for correct value. |
actor | Yes | 12 character string | Valid actor of signer |
Modify the action to:
- Allow only top 150 block producers to call it.
- Charge a fee.
- Record value
Error condition | Trigger | Type | fields:name | fields:value | Error message |
---|---|---|---|---|---|
Not a BP | Actor is not a top 150 BP. | 400 | "actor" | Value sent in, e.g. "aftyershcu22" | "Not a top 150 BP." |
Not positive | bundled_transactions is not positive | 400 | "bundled_transactions" | Value sent in, e.g. "-1" | "Value has to be positive." |
Too soon since last call | Call was made less than 120 seconds since last call. | 400 | "Too soon since last call." | ||
Invalid fee value | max_fee format is not valid | 400 | "max_fee" | Value sent in, e.g. "-100" | "Invalid fee value" |
Insufficient funds to cover fee | Account does not have enough funds to cover fee | 400 | "max_fee" | Value sent in, e.g. "1000000000" | "Insufficient funds to cover fee" |
Fee exceeds maximum | Actual fee is greater than supplied max_fee | 400 | max_fee" | Value sent in, e.g. "1000000000" | "Fee exceeds supplied maximum" |
Parameter | Format | Definition |
---|---|---|
status | String | OK if successful |
fee_collected | Int | Amount of SUFs collected as fee |
{
"status": "OK",
"fee_collected": 2000000000
}
none. using binary extensions ensures backwards compatibilty. setfeemult, setfeevote -- are updated to set the dirty flag after checking that this is a TOP 150 BP.
The following need to be migrated to the new table:
- chain_plugin
none.
The number of fees processed per call must be adaptable as the number of producers registered increases and as the number of fees increases. Present testing shows that the protocol can process up to 20 fee votes per BP (when processing the top 21 only), so we go well under this to become an initial estimated processing limit of 10 fees to process per call.
We will limit the amount of work performed by each call to the compute fees endpoint, we will start at processing 10 fees each call. a no work exception will be thrown when all fees are processed.
The short explanation is that if there are more than 400 PFV to process, then 400 will be processed, until there are less than 400. "no work" exception will be returned when there are no records to process.
The contract action computefees and the updates to setfeevote, setfeemult, and bundlevote were released in fio.contracts v2.2.0.
The compute_fees API endpoint released in fio v3.0.0.
We will add the new field to the fiofee struct as a binary extension, no table migrations will be necessary.
All entities using existing setfeevote and setfeemult actions will have to migrate to new actions, which now inlcude max_fee. However, since this call only impacts block producers, impact is minimized.
None
Parent Branch -- Develop Dev Branch name -- feature/Ed-FIP10-Develop-06122020
Description of contents -- This branch contains modifications to the FIO protocol core to add a new endpoint called compute_fees. These changes can be delivered after the contract changes at any time, since BPs can vote and update fees using push action and the actions in the fio.fee contract
Testing Considerations Regression test the new endpoint.
Pull Reuest -- fioprotocol/fio#174
Parent branch -- Develop Dev Branch name -- feature/FIP-10-fiocontracts-develop-07132020
Description of contents -- This branch contains modifications to the set fee vote to permit 150 registered BPs to vote for fees. This branch introduces a new state table feevotes2 which will replace feevotes, feevotes is left in state for backwards compatibility and migrate-ability of offline tools. This branch introduces votes pending flag to the fiofees table, this is a binary extension, replay testing is required!! This branch modifies setfeevote, and update fees to use the new feevotes2 table.
Testing considerations devnet testing is required due to teh requirement of having at least 15 of the top 21 BPs vote before median calculations willl occur load up the system with 150 voting BPs see that the system functions as expected when updatefees is called. complete full regression testing on all fee voting, and all updatefees
Pull Request -- fioprotocol/fio.contracts#3
Parent branch -- develop Dev Branch Name -- feature/Ed-FIP10-Develop-06132020
Description of contents -- This branch contains changes that add 39 new fees to the fio protocol, this to permit some scaled testing of fee voting. This branch contains a new signing script to test compute fees. This branch contains a new utility script to set fee votes.
Pull Request -- https://github.com/dapixio/fio.devtools/pull/123
Parent Branch -- master Dev Branch name -- feature/Ed-FIP10-master-06302020
Description of contents -- This branch contains changes to enable the testing of fee voting on dev net.. testing approach. edit the fee voting fee setting javascript to add the desired number of registered and voting BPs (uncomment the individual create user tests to get the desired number) run the test...this takes 5-10 minutes depending on the number of BPs set up. after running the test, on your local dev box, with the chain running, perform the following commands. unlock your wallet
Testing instructions (local dev box) from the fio.test, run the javascript tests. npm test wait until they complete (there will be a few errors during processing this is normal) now in another window you can do these commands. ../fio/build/bin/clio -u http://52.247.194.34:8889 get table fio.fee fio.fee fiofees --limit 2000 | grep ""votes_pending": 1" | wc -l this command shows the number of fees not yet processed by update fees. ../fio/build/bin/clio -u http://52.247.194.34:8889 push action fio.fee updatefees "{}" -p wttywsmdmfew@active this command updates the fees. run the two commands iteratively and see the 70 fees voted get processed into the system. ../fio/build/bin/clio -u http://52.247.194.34:8889 get table fio.fee fio.fee fiofees --limit 2000 this command will show the processed fees.
Testing instructions (dev net) instructions. ssh -i "DapixWestPair2.pem" [email protected] cd devnet ./stopall.sh cd .. cd fio.devtools ./start.sh (select 2.0, 1,3,1) stop the present instance ./start.sh (select 2.0,1,1) restart devnet cd .. cd devnet ./goall.sh (this script starts up the a,b,c cluster, registers BPs, and votes them in) fiotop -u http://localhost:8889 (look and wait until all except c6 have produced block, for some reason c6 never does) once all have produced, you can run the tests from your local dev env.
Pull request -- https://github.com/dapixio/fio.test/pull/55