Table of Contents |
---|
Links
Wrapping Wiki: FIO Token and Domain NFT wrapping
Overview of development environment: [FIP-17.a] FIO Token Wrapping
Wrap use case: Wrap
Unwrap use case: Unwrap
Overview
Oracle code will be run by designated FIO Chain BPs with access to:
Oracles will:
On the FIO Chain
Monitor specific account by inspecting every block and looking for FIO contract
wraptokens
actionExecute ERC20
wrap
action to mint wFIO to the designated account
On the Ethereum Chain
Monitor Ethereum smart contract for inbound transfers of ERC-20 wFIO
Execute FIO contract
unwrap
action to transfer FIO to the designated account
Oracle Go Prototype
The original Oracle prototype code was written in Go and is located at: https://github.com/blockpane/fio.oracle
The FIO wrapping/unwrapping contract
The FIO wrapping/unwrapping contract specification is detailed in FIP 17.a: https://github.com/fioprotocol/fips/blob/master/fip-0017a.md
Github
fio.oracle
contract: https://github.com/fioprotocol/fio.contracts/tree/oracle/tokenwrap/contracts/fio.oracle
The Ethereum ERC20 wrapping/unwrapping contract
The Ethereum wrapping/unwrapping contract specification is detailed on the wiki: fio.erc20 - wFIO Contract Specification
Github
fio.erc20
repository: https://github.com/fioprotocol/fio.erc20
Misc. Requirements
...
Issue
...
Summary
...
Decision
...
Storage of latest block number
...
The Oracle is getting the latest action from FIO history every 5 seconds. But when we restart the server, we read the all latest actions and calling wrap function from the start. Of course, it doesn't mint again but I think wrapping time can be long in this case. To prevent this problem, we need to save the latest block number to database or any external storage.what do you think about my suggest?
...
Casey Gardiner should we track block number in the oracleledger
table?
Suggest that Oracles store a log file of all the transactions locally. If they then go down they can grab a time stamp or transaction ID from the log file to know which transactions have not yet been processed.
If an oracle server crashes and the logs are lost, then the oracle would have to re-process all transactions (and rebuild the log file). This would be a one time process.
Decision: We will start with using log files, but will ask BPs their opinion on this solution.
...
Admin front-end UI
...
Is there a need for a front-end UI to review different transactions, or can we just rely on table lookups, etc.?
Pawel Mastalerz thoughts?
...
Process a single transaction at a time
...
Given the complexity of validating wrap and unwrap transactions all the way through to finality, both Todd and Alex have suggested that we limit oracles to only process a single transaction at a time
Functionality
There are two main use cases that concern the Oracle, Wrap and Unwrap. These are detailed below.
Watchdog routines
In addition to wrap/unwrap, the Oracle should also have certain watchdog/monitoring routines that ensure the processes and routines executed by the Oracle healthy. For example:
Make sure a loop didn’t get stuck.
Ensure there are no blocked channels.
Ensure the health of the daemon itself.
Wrap
Wrap creates wFIO on the Ethereum chain.
See the following page for an overview of the Wrap use case: Wrap
...
Functionality
...
Oracle Initialization
...
Set the initial value of
actionIndex
=last_irreversible_block
number (from FIO Chain) when server starts.TBD: What is the best way to store the actionIndex to persist when an Oracle restarts?
See “Storage of latest block number” above
...
Alice (via dApp) calls wraptokens
inside the fio.oracle
contract on FIO chain
...
Example: Calling wraptokens
using Cryptonym:
...
...
fio.oracle
contract actions
...
fio.oracle
contract actions:
Parameter Validation ( ensuring amount, token codes, pubkey and fees are all properly set )
Search oracle registration table (contains all registered oracles) and tally up the total number of registered oracles
Collect Oracle fees, sort, and find the median.
Send fee to all oracles.
Emplace wrapping details inside the
oracleldgrs
table.Send the wrapped amount from Alice to
fio.oracle
contract.Collect FIO/BP fees
Increase Alices RAM by 512.
Send successful response to Alice
...
Oracle monitors get_actions
API on V1 History node
Every 5 seconds Oracle polls the get_actions
API on History node Plugin to detect activity on the wrapping account (e.g. "o2ouxipw2rt4")
Code Block |
---|
curl -s -XPOST http://44.242.158.42:8080/v1/history/get_actions -d '{
"account_name": "o2ouxipw2rt4",
"pos": -1
}'
|
Retrieve all actions
For each action, if
block_num
>actionIndex
then validate and process the action (call ERC-20wrap
)Set
actionIndex
=block_num
of most recent wraptokens action
Code Block |
---|
const actionIdx = config.oracleCache.get("actionIndex");
const dataLen = Object.keys(data.data.actions).length;
var array = Array();
for (var i = 0; i<dataLen;i++){
if (data.data.actions[i].block_num > actionIdx) {
array.push(data.data.actions[i]);
}
config.oracleCache.set("actionIndex", data.data.actions[dataLen-1].block_num)
}
return array; |
TBD:
Since there eventually may be very many transactions, it may make sense to walk backward through the table using "pos" and "offset". Maybe you grab the most recent 5 actions and see if any of them are new. If ALL of them are new, then you need to grab the next 5 actions, etc.
...
wrap
transaction finality monitoring on FIO Chain
...
TBD: Should the oracle monitor FIO chain for finality by ensuring block number is after the last_irreversible_block?
...
Oracle validates the FIO chain wraptokens
transaction.
...
See “Exception handling” below
Check the actions to confirm it is a wrapping action:
Code Block |
---|
if (wrapData[i].action_trace.act.data.memo == "Token Wrapping") |
...
Responding to invalid wraptokens
transaction
...
TBD: If exceptions are found, what actions does the Oracle take unwind
wraptokens
action?
...
Oracle executes wrap
on fio.erc20
contract on Ethereum chain
...
wFIO recipient eth address, wFIO amount to mint (must match what was wrapped on FIO chain exactly), and the obtid of the FIO transaction are provided as parameters to wrap action
Code Block |
---|
wrap(ethaddress, FIO (SUF) amount, obtid);ex. wrap(“0x00000000000”, 10000000, “0x123456789”); |
...
fio.erc20
contract actions for pre-consensus calls to wrap
function
fio.erc20
contract actions:
...
(Not sure what this means?) ethereum wallet provider (usually truffle/hd-wallet-provider) set to use oracles ethereum private key
...
Overview
The fio.oracle middleware is a standalone node application that monitors activity on the FIO and Ethereum chains and when token and/or domain wraps and unwraps are detected on one chain, it initiates the same action on the other chain, thus acting as a bridge.
The fio.oracle middleware is meant to be run by some number of “oracles” who provide the consensus layer for approving a wrap or unwrap actions. For the initial release, there are three FIO Block producers who have agreed to run the oracle middleware. All three of these BP oracles must approve every wrap or unwrap transaction for it to succeed.
For example, if a user wants to wrap their domain, they first call the wrapdomain action on the FIO chain. Each of the three BP oracles independently are monitoring the FIO chain and see the wrapdomain action. Each of these oracles independently then calls wrapnft on the Polygon chain. If all three oracles execute the transaction on Polygon, the wrap succeeds.
Links
Repository: https://github.com/fioprotocol/fio.oracle
Wrapping Wiki: FIO Token and Domain NFT wrapping
Epic:
Jira Legacy server System JIRA serverId 5f0d8161-d4cf-3d17-96b1-53b2b2b5013d key BD-2195 Overview of development environment: [FIP-17.a] FIO Token Wrapping
Wrap use case: Wrap
Unwrap use case: Unwrap
Overview
Oracle code will be run by designated FIO Chain BPs with access to:
Oracles will:
On the FIO Chain
Monitor specific account by inspecting every block and looking for FIO contract
wraptokens
actionExecute ERC20
wrap
action to mint wFIO to the designated account
On the Ethereum Chain
Monitor Ethereum smart contract for inbound transfers of ERC-20 wFIO
Execute FIO contract
unwrap
action to transfer FIO to the designated account
Oracle Go Prototype
The original Oracle prototype code was written in Go and is located at: https://github.com/blockpane/fio.oracle
The FIO wrapping/unwrapping contract
The FIO wrapping/unwrapping contract specification is detailed in FIP 17.a: https://github.com/fioprotocol/fips/blob/master/fip-0017a.md
Github
fio.oracle
contract: https://github.com/fioprotocol/fio.contracts/tree/oracle/tokenwrap/contracts/fio.oracle
The Ethereum ERC20 wrapping/unwrapping contract
The Ethereum wrapping/unwrapping contract specification is detailed on the wiki: fio.erc20 - wFIO Contract Specification
Github
fio.erc20
repository: https://github.com/fioprotocol/fio.erc20
Misc. Requirements
Issue | Summary | Decision | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
Storage of latest block number | The Oracle is getting the latest action from FIO history every 5 seconds. But when we restart the server, we read the all latest actions and calling wrap function from the start. Of course, it doesn't mint again but I think wrapping time can be long in this case. To prevent this problem, we need to save the latest block number to database or any external storage.what do you think about my suggest? | Should we track block number in the
| ||||||||
Admin front-end UI | Is there a need for a front-end UI to review different transactions, or can we just rely on table lookups, etc.? |
| ||||||||
Process a single transaction at a time | Given the complexity of validating wrap and unwrap transactions all the way through to finality, both Todd and Alex have suggested that we limit oracles to only process a single transaction at a time |
| ||||||||
How often should get_actions be polled? | Need to determine how often to call get_actions on the FIO chain. |
| ||||||||
Transaction Retry | Because we are putting limited validation logic in the oracle, it may be necessary for Oracles to take action on failed transactions. It would be helpful to have a “transaction retry” function that can be called that retries specific wrap/unwrap transactions. |
| ||||||||
Log events and exceptions | All events and errors should be logged. Because there will be limited validation, these logs will be the primary way for oracle node operators to troubleshoot issues. |
| ||||||||
V1 History | The initial implementation calls get_actions against V1 history. Should we look at supporting Hyperion or other history solutions? | Discussed the V1 history implementation with the Oracle BPs and because it is a relatively simple call, it is not worth designing additional support for different history solutions. Once we deploy they will see how well it fits into their environments. | ||||||||
Setting gasPrice and gasLimit | What is the best way to enable Oracle BPs to set the Eth gas prices and limit? | Pawel: Recommends manually setting in an environment variable (or something similar). |
Functionality
There are two main use cases that concern the Oracle, Wrap and Unwrap. These are detailed below.
Watchdog routines
In addition to wrap/unwrap, the Oracle should also have certain watchdog/monitoring routines that ensure the processes and routines executed by the Oracle healthy. For example:
Make sure a loop didn’t get stuck.
Ensure there are no blocked channels.
Ensure the health of the daemon itself.
Wrap
Wrap creates wFIO on the Ethereum chain.
See the following page for an overview of the Wrap use case: Wrap
Functionality | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Oracle Initialization |
| ||||||||||||
Alice (via dApp) calls | Example: Calling | ||||||||||||
|
| ||||||||||||
Oracle monitors | Every 5 seconds Oracle polls the
| ||||||||||||
|
| ||||||||||||
Oracle validates the FIO chain |
| ||||||||||||
Responding to invalid |
| ||||||||||||
Oracle executes |
| ||||||||||||
|
| ||||||||||||
| Example of three oracles calling wrap:
|
|
|
| |
ERC-20 | TBD: Adam to document how the contract handles invalid failed transactions. Put link to content here. Adam Androulidakis |
Responding to invalid ERC-20 |
|
| |
|
|
|
|
Exception handling
Error condition | Trigger |
---|
Type
fields:name
fields:value
Error message
Oracle Action | |
---|---|
Invalid chain | Chain passed to |
Oracle triggers unwraptokens
action to send FIO back to originating address
TBD: How do other oracle get notified when a transaction is getting unwound?
TBD: What if one oracle approves the transaction and another oracle rejects?chain expansion without deployment of code) | Oracle logs error and does no further processing of the transaction. | |
Invalid Ethereum address | Public address passed to | Oracle |
unwraptokens
action to send FIO back to originating addresslogs error and does no further processing of the transaction. |
Unwrap
Unwrap converts wFIO on Ethereum chain to FIO Tokens on FIO chain.
See the following page for an overview of the Unwrap use case: Unwrap
Functionality | |
---|---|
Oracle Initialization |
|
| |||
Alice (dApp) executes | unwrap(fio address, amount); | ||
ERC-20 | TBD: Adam to document how the contract handles invalid failed transactions. Put link to content here. Adam Androulidakis | ||
|
| ||
Oracle monitors |
|
No consensus is required for the unwrap
transaction. Any oracle can initiate the FIO unwraptokens
action.
| |
Oracle validates |
|
If exceptions are found, Oracle takes action to unwind transaction |
|
|
|
upwraptokens
?Ask Paul how Edge assesses finality for Ethereum. Eric Butz
| ||||||||
Oracle executes |
| |||||||
| fio.oracle contract Actions:
| |||||||
Responding to invalid |
|
upwraptokens
transaction succeed, but 1 oracle fails?TBD: Retry?
|
Oracle validates |
Oracles monitor all unwraptokens transactions in process to ensure consensus has been reached.
|
Ongoing monitoring of |
|
Exception handling
Error condition | Trigger |
---|
Type
fields:value
Error message
Oracle Action | ||
---|---|---|
Invalid FIO Address | FIO Address passed in with ERC-20 is not valid or does not exist | Oracle |
wrap
action to send wFIO back to originating addressTBD: What event is being monitored for this?logs error and does no further processing of the transaction. | ||