Development Notes
February 3, 2023 ยท View on GitHub
Phat Contract side
Misc
- Refactor experimental code as contracts
- Switch to OpenBrush's
ink-envwith the advanced unit test kits
- Switch to OpenBrush's
Components
- SimpleScheduler
- Design
- Query
poll()- call all the ready targets
- should check health (trigger exactly one health worker)
- Tx
register(config, address, calldata)owner-only (direct call, stateless) - Tx
delete(id)owner-only - log the triggered events
- Rollup Submit
- Account management: generate secret key & reveal public key
- Tx
config(rpc, rollup_handler, anchor)by owner - Query
poll()- get
Result<RollupResult, Vec<u8>>response - submit tx to
RollupResult.target_id- use the latest nonce
- fire and forget
- get
- enum RollupTarget
- EVM(chain, address)
- Pallet(chain)
- Raw tx submit
- Gas efficiency submit - for gas efficiency, save the recent submitted tx to local storage (with timeout) to avoid redundant submission in a short period
- TestOracle
- Minimum implementation
- Refactor to strip SDK logic
- Real-time fetch price
- Feed
- Request
- Locks
- Experimental lock tree (tx_read, tx_write)
- Correct implementation
- struct RollupTx
- Condition
- Updates
- Actions
- struct RollupResult
- RollupTx
- RollupTarget
- (opt) signature of RollupTx
- Read client
- Read from EVM
- Wrap as a client object
- Consider block_hash when reading data
- Read from Substrate
- Batch read optimization
- Substrate WS client
- Security
- RPC cross validation
- RPC redundancy
- RPC light validation
- Rollup cross validation
Development Notes
- To run Phat Contract unit tests, you need to configure
.envfile under each contract directory. It's suggested to copy.env_sampleto.envand config it based on the comments. abi.decode()doesn't have any error handling currently. When it failed, the transaction will get revereted silently, which is hard to debug. So it's always a good habit to verify the raw input todecode()beforehand.- In unit tests, you can enable logging output (e.g. from
pink::info!()) by:- Add
env_loggeras the[dev-dependency]in the Cargo.toml file - Call
env_logger::try_init()at the beginning of each test function - Launch the unit test with additional flags:
RUST_LOG=debug cargo test -- --nocapture
- Add
Manual Full Test
(Doc WIP; info below may be incorrect.)
- Compile and deploy
SampleOracleandEvmTransactorwith theirdefault()constructor- This can be done with the Phat Contract UI
- The caller wallet will be the owner of the two contracts.
- Query
EvmTransactor::wallet()to get the generated EVM wallet address, and deposit some test ETH to the wallet for gas fee. This account will be used to send rollup transaction from Phat Contract to EVM. - Deploy the EVM contracts (
PhatQueuedAnchorandTestOracle) underevm/contracts.- Deploy with hardhat:
npx hardhat run scripts/deploy-test.ts --network <network> - Please replace
phatEvmTransactorindeploy-test.tswith the wallet you get from step 2 - The script will output the address of the deployed contracts
- Deploy with hardhat:
- Config
SampleOracleandEvmTransactor- Can be don with Phat Contract UI
- Config
SampleOracle: give it the EVM RPC address (e.g. Alchemy Goerli RPC) and the EVMPhatQueuedAnchoraddress - Config
EvmTransactor: give it the EVM RPC address, the Phat ContractSampleOracleaddress (rollup_handler), and the EVMPhatQueuedAnchoraddress - The E2E test script is an equivalent example
- Call the EVM contract
TestOracle.request()to initiate a request - Call Phat Contract
EvmTransactor::poll()to answer the request- It should results in an rollup transaction like this
Deploy with scheduler
(Doc WIP; info below may be incorrect.)
- Follow the "Manual Full Test" section to setup
SampleOracle,EvmTransactor, and the EVM contracts. - Deploy
LocalSchedulerwithdefault()constructor - Call
LocalScheduler::add_job()to add the automation job to triggerEvmTransactor::poll()name: an arbitrary namecron_expr: a cron-like expression of the automation.* * * * *means trigger per minute.target: the address ofEvmTransactorcall: the encoded call data ofEvmTransactor::poll(), which is0x1e44dfc6
- Call
poll()repeatedly. It will trigger the job according to the cron expression. - You can check
LocalScheduler::getJobSchedule(n)to check the scheduled tasknis the job id, starting from 0.- Tasks are scheduled after the first
poll(). So a newly added task will haveNoneoutput until the firstpoll().
- The scheduler prints logs to indicate how it trigger the events. Can read it from the UI.
EVM Oracle E2E test
(Doc WIP)