Skip to content
This repository was archived by the owner on Dec 26, 2023. It is now read-only.
This repository was archived by the owner on Dec 26, 2023. It is now read-only.

Rewards and incentives #38

@lrettig

Description

@lrettig

Overview

The Spacemesh system needs to reward nodes that perform objectively valuable actions for the network such as mining new transactions into blocks, executing and validating the transactions in those blocks, and participating in Hare consensus.

For background see these forum threads:

Goals and motivation

See https://community.spacemesh.io/t/preliminary-proposal-for-incentives-rewards/121/1

High-level design

This design is based on EIP-1559, modified to work for a mesh rather than a chain. We introduce a base_fee in each layer, which all transactions in blocks in that layer must pay. Rewards collected in a layer and distributed to miners are smoothed over all blocks and transactions in a configurable number of layers. We also add reward maturation, so that a reward earned by a miner in a given layer isn't spendable until a configurable number of layers later.

Proposed implementation

  1. Config variables. We add several new config variables, including:
    • smoothing_distance: the number of layers over which rewards are smoothed (0 = no smoothing, 1 = layer-wide smoothing, etc.). Note that this must be hardcoded in genesis for a given net/mesh and cannot change later.
    • maturation_distance: the number of layers that must pass before a reward earned by a miner is spendable
    • max_adjust: the maximum ratio by which we allow the base_fee to change from layer to layer
    • min_gas: the minimum total fee that a miner accepts to mine a transaction into a block. This is not in consensus and will differ from miner to miner. It should represent something close to a miner's actual variable cost of including an additional transaction in a block.
  2. Transaction fees and gas
    • Update Transaction data structure to include GasLimit (already present), MaxFeePerGas (max base fee tx is willing to pay) and MaxTipPerGas
    • Update gas arithmetic in tx processing/STF, and in state projection
  3. Miner transaction selection algorithm and add per-layer base_fee
    • Miners should keep their txpool sorted by fee
    • They should determine the base_fee for the current layer (based on votes in the previous layer), determine which transactions in the txpool pay at least this fee, and select transactions randomly from the set that are above this threshold
    • They should calculate a base_fee (based on layer capacity, to take effect in the following layer) and include their explicit vote for base_fee in blocks they publish in this layer
    • They should consider as contextually invalid, and vote against, any block that includes transactions below the base_fee for a given layer
  4. Reward smoothing and maturation
    • Modify reward smoothing to make it work over a variable number of layers. Make sure it includes all collected tips and fees, as well as the block subsidy.
    • Add maturation so that "paid" rewards don't appear in the recipient's account, and aren't spendable, until maturation_distance has passed
  5. API changes: this will require rethinking the way the API returns info on rewards and account state (balances). We already split account state into current/projected in the API. We could include upcoming (immature) rewards in projected but not current account info. We may need to split rewards endpoint to do something similar. Rewards will now have three states: upcoming/projected (due to smoothing), paid (but not matured/spendable), final (matured/spendable).

Implementation plan

  1. Refactor existing rewards code to standardize type (Standardize rewards type go-spacemesh#2069)
  2. Update types
    • Transaction (as described above)
    • Block (add fee voting: this is just a uint)
  3. Gas arithmetic
    • Implement EIP-1559 logic in STF/tx processor
    • Update state projection logic as well
  4. Mempool management, tx selection & block building logic
    • Rewrite mempool to sort by fee. Will require changing data structures, something like a priority queue/heap but also indexed by account.
    • Add logic to calculate base_fee for new layer based on blocks in DB for previous layer: cutoff top N transactions then pick randomly among them; include vote for base_fee in new block
  5. Smoothing
    • Add smoothing_distance param
    • Rewrite rewards logic using smoothing
    • Evaluate how expensive it would be to reread rewards from previous smoothing_distance layers in each new layer, and whether we need to cache these values in memory. Build a cache if necessary.
  6. Maturation
    • Does not require major changes to rewards logic. Just apply rewards maturation_distance layers behind the latest confirmed layer, whenever a new layer is confirmed (same as now).
  7. Update API methods related to rewards, fees, and account state/balance, as described above.

Questions

  • Don’t we want to emit an event every time we, e.g., update a balance (e.g., applying a reward)? Otherwise, how does a user know why their balance is what it is? Or does this go into a receipt or something?

Ongoing work

This proposal only includes the barebones design and implementation required for a functional reward system for genesis. In particular, only mining is rewarded. Other useful behaviors such as transaction validation and participation in Hare are not covered by this design and are left for follow-on designs.

Dependencies and interactions

  • Config/CLI flags/genesis config
  • Mempool/mining: The implementation work related to mempool management, tx selection, and block construction overlaps with @noamnelke's work on Transaction Processing #37.
  • Mesh
  • Transaction processing/state updates/state projection
  • API

Stakeholders and reviewers

These changes touch several core go-spacemesh components. Reviews will be requested from the folks most familiar with the components that are changed.

  • @noamnelke will review changes related to data structures, mempool management, tx selection, and mining

Testing and performance

Tests will be added for all new and changed code.

Performance considerations:

  • calculating the rewards to be paid out in a given layer when those rewards were smoothed over many previous layers may be expensive if the smoothing_distance is great. We may need a cache for this.
  • we need to carefully design a new data structure for managing the mempool that allows a miner to sort by total fee (max_fee and tip), find the top N transactions, randomly choose among them, as well as to do the things that are already done with the mempool: pruning conflicting transactions, finding transactions by sender/recipient, etc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions