lido
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # IStakingModule interface | Expecting approves | | | ------------------------------ | --- | | @george-avs | | | @dgusakov | | | @ztQfQNT3QamKRB2E2yC2hg (Max) | 💬 | | @68uFj4WFReSxi8tiG4ZzUQ (Anna) | | | @F4ever | ✅ | ✅ - approved 💬 - has unresolved comments ## 1. Context The new validator exit mechanism on the EL will not be used regularly due to cost considerations but will serve as a guarantee that any validator can be exited if necessary. Given this, we consider it the node operator's responsibility to exit validators on time, and any violation of this policy will result in penalties. A node operator may be penalized in two ways: 1. A fixed penalty per validator that the node operator failed to exit. 2. Compensation for the incurred cost of submitting a Triggerable Exit (TE) request. ## 2. Decision We propose introducing two new methods in the interface, which will be sufficient for Staking Modules to determine validator/NO penalties. ### Handle Triggerable Exit This method is called each time a validator's TE request is executed. It is triggered only for validators that were requested to exit, but it could have any status on CL. ```solidity= /** * @notice Handles the triggerable exit events validator belonging to a specific node operator * @dev This function is called when a validator is exited using the triggerable exit request on EL. * @param _nodeOperatorIds The ID of the node operator * @param publicKey Validaotor's public key. * @param exitType The type of exit being performed. * This parameter may be interpreted differently across various staking modules, depending on their specific implementation. * @param withdrawalRequestPaidFee Fee amount paid to send withdrawal request on EL. * @param validatorIds Array of the validator indexes from CL that were triggered exit. */ function onTriggerableExit( uint256 _nodeOperatorId, bytes calldata publicKey, uint256 withdrawalRequestPaidFee, uint256 exitType, ) external; ``` Parameter explanations: - `exitType` – This can be defined differently for various staking modules. It is suggested to use this field to indicate whether the node operator should compensate for the TE fee or not. For example: - 0 - Voluntary exit (no compensation expected). - 1 - Forced exit (compensation expected). - `withdrawalRequestPaidFee` – The current fee for submitting a TE request via the EIP-7002 contract. ### Handle Update Validators Exit Statuses ```solidity= /** * @notice Updates the exit-related state of validator belonging to a specific node operator. * @dev This function records the timestamps associated with a validator's exit process, * tracks when the exit was requested, the last known active_ongoing timestamp, and applies any withdrawal request fees. * The data can be used for penalty calculations, tracking validator behavior, and enforcing exit policies. * @param _nodeOperatorsId The ID of the node operator whose validators statuses being delivered. * @param publicKey Validaotor's public key. * @param stillActiveOngoingTimestamp The timestamp on which validators were still in active ongoing status. The timestamp of slot on which CL proof were prepared. * @param eligableToExitInSec number of seconds that NO was eligable to exit validators, but didn't. Matched to the validators from the validatorIds array in the same order. */ function updateValidatorExitStatus( uint256 _nodeOperatorsId, bytes calldata publicKey, uint256 stillActiveOngoingTimestamp, uint256 eligableToExitInSec, ) external; ``` Parameter explanations: - `stillActiveOngoingTimestamp` - will be used to determine whether TE should be compensated or not (e.g., by verifying that the TE creation timestamp is earlier than `stillActiveOngoingTimestamp`). ### Public methods for off-chain applications #### Check if validator should be penalized in Prover bot Since the methods `updateValidatorsExitStatuses` and `onTriggerableExits` are not designed to revert transactions, the bot must ensure that the transaction fees will not be wasted before submitting it. ```solidity= /** * @notice Determines whether a validator exit status should be updated and will have affect on Node Operator. * @param _nodeOperatorId The ID of the node operator. * @param publicKey Validaotor's public key. * @param stillActiveOngoingTimestamp The last known timestamp when the validator was active. * @param eligibleToExitInSec The number of seconds the validator was eligible to exit but did not. * @return bool Returns true if contract should receive updated validator's status. */ function needsUpdateValidatorExitStatus( uint256 _nodeOperatorsId, bytes calldata publicKey, uint256 stillActiveOngoingTimestamp, uint256 eligableToExitInSec, ) view returns (bool); ``` #### Get exit timeframe to optimize requests in Prover bot. The bot also requires to know the time after which a validator is considered late. :::warning Should we add here some pagination? ::: ```solidity= /** * @notice Returns the number of seconds after which a validator is considered late. * @return The exit deadline threshold in seconds. */ function exitDeadlineThreshold(uint256 _nodeOperatorId) external view returns (uint256); ``` #### TE Request Creation Optimization Should we consider adding a function for the TE bot that would preemptively revert a transaction if a TE request for the given validator has already been sent? ## Other Changes to Be Made - Remove the `updateStuckValidatorsCount` method; - Change description and deprecate `_stuckValidatorsCount` param in the `unsafeUpdateValidatorsCount` method; - Change description and deprecate the `stuckValidatorsCount` and `stuckPenaltyEndTimestamp` params in the `getNodeOperatorSummary` method; - Update the description for the `onExitedAndStuckValidatorsCountsUpdated` method; ## 3. Rationale :::success The following interface explanation is based on the current needs of the SMs. The described algorithm does not impose any strict implementation requirements on the module. ::: We decided to proceed with Option B in the Curated Module's penalty system ([TW scope and alignment](https://www.notion.so/TW-alignment-on-critical-product-decisions-1aebf633d0c980f8b4eace3e16333ef2?pvs=4#1aebf633d0c98051a623cc5e2df990a5)). Implementing this feature requires the staking module to handle: - Whether the node operator should compensate for a TE request. - Whether a validator’s exit status should result in a penalty. ![image](https://hackmd.io/_uploads/Hk1piRu3Jx.png) ### **onTriggerableExits** hook received This method notifies SM when a validator exit is triggered via an EL withdrawal request. The module should penalize the node operator only when it violates the policy. Proposed algorithm: 1. If the validator has already exited via TE, return. 2. Record that a TE was triggered for the validator. The module also stores information on exit time, cost, and type. 3. If the exit type is voluntary, return. 4. If there is proof that the validator missed the deadline by more than `eligibleToExitInSec` and since `stillActiveOngoingTimestamp` did not passed `teCompensationWindowInSec`, penalize the node operator for the amount spent on the TE request. :::warning `teCompensationWindowInSec` is a parameter that defines the number of seconds during which proof of a missed deadline remains valid for a TE request, starting from the last recorded proof that the validator was not exiting. If the request is submitted after this period, additional proof with a later slot will be required to compel the node operator to compensate for the late TE request. This mechanism ensures that node operators are not unfairly penalized for validators that were late in the past but have already exited. ::: ### **updateValidatorsExitStatuses** This method informs the SM about the exit status of a validator requested for exit via the VEB on the CL. Proposed algorithm: 1. If an exit status record already exists, ensure that the new data is more recent than the previously recorded data (`eligibleToExitInSecNew` > `eligibleToExitInSecOld`). If the new data is older, return. 2. If `eligibleToExitInSec` exceeds the validator exit deadline, check whether the node operator has already been penalized for this validator. If not, apply the penalty. 3. If no TE exit record exists, return. 4. If TE has already been compensated, return. 5. If the TE timestamp is later than the validator's compensation window (`stillActiveOngoingTimestamp + teCompensationWindowInSec ≤ teTimestamp`), return. 6. Compensate the node operator for the amount recorded in the TE request record (refer to steps 3, 4 from previous section). :::warning This method can be called multiple times for the same validator to update the latest slot when it was active_ongoing, ensuring tracking if the validator remains still active beyond the initially recorded timestamp. ::: ## 4. References - [ADR: Curated Module Implementation](https://hackmd.io/WH_60K4RQIaUZz-BwXMIWg) - [Triggerable Withdrawals spec](https://hackmd.io/tMwct9BuQru47giIv4dVYw) - [TW scope and alignment](https://www.notion.so/TW-alignment-on-critical-product-decisions-1aebf633d0c980f8b4eace3e16333ef2)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully