Authors: @kubuxu, @raulk.
- BaseFee - current going fee (unit FIL per gas) unit determined by the network required for a message to be included.
- FeeCap - field in a message, determines maximum BaseFee to be paid (unit FIL per gas)
- MaxFee - maximum amount user is willing to pay for the message in total (unit FIL)
- MaxFee = FeeCap * GasLimit
- ActualFee - fee that was charged by the network (unit FIL)
- ActualFee ≈ BaseFee * GasUsed + GasPremium * GasLimit
-
Foundational
- (G1) Implement logical checks at the time of send to warn the user against common pitfalls, gotchas, footguns.
- (G2) Refactor message sending framework to invert the control (“message prototyping”), possibilitating BYOS aka. external wallets, i.e. (“sign this”).
-
User experience
- (G3) Implement an interactive CLI for message sending.
- (G4) Implement an interactive CLI for message monitoring.
(1) can be implemented for simple commands (e.g. send, miner create) without incurring in the refactor of goal (2). (3) and (4) will be implemented on top of the solid foundations created by (1) and (2).
-
Messages remain stuck in mpool because (=> these messages are never mined):
-
Messages not having the expected/successful outcome because (=> included but errored outcome):
The primary goal of following validations is to prevent and correct a wide range of issues a user can encounter while trying to send a message. We believe the following validations address all the identified issues that can be prevented by verification prior to sending a message. For each, we include brief implementation notes.
We propose adding a NodeHealth JSON-RPC operation that verifies if the node is synced and capable of servicing the user.
- add
NodeHealth()
FullNode API endpoint, returning:- the sync status: how far out of sync the node is.
- Use the difference between the current time and genesis to figure out which epoch we should be at.
- peering status: do we have more than 5 peers with positive pubsub scores?
- i.e. are we confident that if we send this message now, it will be properly propagated to the network?
- the sync status: how far out of sync the node is.
- use
NodeHealth
to error on message sending NodeHealth
pass-through for Lotus Lite
- there is no nonce gap for the sender, messages can be selected
- message selection check should verify that messages have FeeCap buffer of ? blocks with max BaseFee growth
- resolution steps would be using interactive message monitoring tool, to be built.
- done by new API endpoint
MpoolHealth(address)
that performs checks and issues global and per message warnings plus errors.- check that balance allows to cover all messages for worst case scenario (full gas usage and BaseFee = FeeCap), issue warning otherwise
- additional concrete checks to be fleshed out
- message is valid for block inclusion
- estimate gas using
GasEstimateMessageGas
- check that balance requirements are met given new message
- verify that new message will result in healthy mpool using MpoolHealth
- if checks fail start an interactive UI see below
- arguments: sender address; array of new messages
- check messages from sender’s mpool with new messages for consistency and balances
- emit warnings and errors on per message (or global if applicable) scope
- don’t stop at first error
Above validations cannot be reacted to on the user side for many commands (~20) as these commands use APIs which send out messages directly. Refactoring these APIs such that the user can see and verify messages to be sent allows the above workflow to execute.
While above validations could be done for these APIs on the node side, the current API will not expose structured errors and warnings. All of the aforementioned APIs return Cid and error string, integrating with which will not be productive. It would also significantly change behaviour of current API.
Proposed solution is to add new variations of these APIs which instead of publishing messages directly would return Message Prototyped. Message Prototype would precisely specify a message but would lack a nonce and signature. The Lotus CLI would validate these messages and use MpoolPushMessage so they have consistent nonce assigned and are signed by existing Lotus facilities.
This also enables Bring Your Own Signature workflow. External wallets will be able to get a Message Prototype, ask Lotus API for the nonce and gas parameters, sign the message externally and submit it to the mpool.
This is how I’m (@kubuxu) imagining the U., The issue is slow, medium, fast model does not really work for base fee/EIP1559 so the idea is to ask the user “how much is this message worth for you” and tell him if and when (when would be quite probabilistic) it would get included.
The UI should do the following:
- tell the user how much the message would cost without any changes (MaxFee)
- tell the user how much would the user need to spend to guarantee inclusion (BaseFee*GasLimit * X
)
- This is important as the difference between BaseFee and FeeCap can be quite large, leading to large difference between MaxFee and ActualFee
- allow the user to select the "guarantee price", that would almost guarantee inclusion even if base fee kept rising at its maximum velocity for next 20 blocks (10x current base fee)
- allow the user to enter their own price
- allow the user to modify selected fee (one that would be use if used confirmed right now)price , by +/- 10%
- alternative is something akin to a slider, doesn't really lend itself to CLI
- warnings should update based on price
- needs to have non-interactive override
- needs to warn about possible interactive UI if used by a script
Roles of this UI
- Monitoring the status of sent messages
- executed on chain: number of confirmations, exit code, total cost
- included on chain but not yet executed
- in mpool, can be selected, message related warnings
- display warnings from
MpoolHealth
- Adjusting already sent messages, to resolve identified issues
- interactive
mpool replace
, with some of the functionalities of interactive UI for message sending
- interactive
- tabular representation of messages in mpool for given sender