Skip to content

Instantly share code, notes, and snippets.

@raulk
Created March 24, 2021 10:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raulk/368429797072295f339e0dbe67168098 to your computer and use it in GitHub Desktop.
Save raulk/368429797072295f339e0dbe67168098 to your computer and use it in GitHub Desktop.

Robust Message Management: Technical work plan

Authors: @kubuxu, @raulk.

Glossary

  • 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

Goals

  • 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).

Common pitfalls

  • Messages remain stuck in mpool because (=> these messages are never mined):

    • The node is unsynced, leading to wrong message parameters 1
    • Configured (likely default) MaxFee is too low 2
    • Sent message Value + MaxFees is higher than balance1
    • nonce gap 1 3
    • not profitable for miner (or precursors/parents not profitable) 3
  • Messages not having the expected/successful outcome because (=> included but errored outcome):

    • run out of gas 3
    • failed to execute successfully 3
    • were forked out (!! rare but possible) 3

(G1) Logical checks

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.

Node is nearly synced and healthy

We propose adding a NodeHealth JSON-RPC operation that verifies if the node is synced and capable of servicing the user.

  1. 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?
  2. use NodeHealth to error on message sending
  3. NodeHealth pass-through for Lotus Lite

mpool + chain combined view is coherent

  • 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

New message will result in healthy mpool

  • 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

MpoolHealth API endpoint

  • 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

(G2) Invert control of message sending

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.

(G3) Interactive UI for resolving problems during message sending

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

(G4) Interactive UI for monitoring and managing messages

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
  • tabular representation of messages in mpool for given sender

Footnotes

  1. solved by verification and fail-by-default with resolution steps 2 3

  2. interactive UI for asking the user for a higher fee

  3. interactive UI for monitoring messages and re-pricing them 2 3 4 5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment