Fee Voting - zoobc/zoobc-core GitHub Wiki

Fee voting is a feature to scale the minimum fee on the network by executing a set of actions. The fee-scale will be used to scale down/up all the minimum fee across all transaction type.

if tx.Fee < feeScale * txType.MinimumFee {
  Error("NotEnoughFee")
}

Fee scale will be adjusted in consensus within 3 steps separated in 2 phase in one month cycle:

  • Commit Phase 1st - 14th days of month.

  • Reveal Phase 15th - last day of month.

  • Adjustment first block of month.

  • Commit Phase

    Node owner submit the commitment of their vote in form of 32 bytes data. Ideally this data will be the hash of FeeVoteInfo, but it can be anything because the goal of this transaction type is to commit and hide the vote at the same time.

    • Transaction Type:

      Sender submit their vote commitment by submitting CommitFee transaction type.

    • Restrictions:

      • Sender, only node owner.

      • Frequency, can only be submitted once, per-phase, per-node_owner.

      • Time, commit-phase (1st - 14th day of month)

      • If there is none of Fee Vote Commit include in block, all incoming Fee Vote Commit will accept but only one can include in block and the others will be prune from mempool.

  • Reveal Phase

    Node owner submit the actual information of hash submitted in CommitPhase.

    • Transaction Type:

      Sender submit the reveals to the node by posting previously saved FeeVoteInfo via Reveal Fee

    • Restrictions:

      • Sender, only node owner.
      • Frequency, once per-phase per-node_owner.
      • Time, reveal-phase (15th - last day of month)
      • State, hash of this reveal object must be already in node's fee_vote_commitment_vote table.
  • Adjustment

    The adjustment process is triggered on the end of reveal-phase and indicated by the creation of the first block of the month.

    • The median of revealed votes on current voting-period is selected.

    • The selected value is scaled to the original SendMoney minimum fee.

      newScale = median / SendMoney.OriginalMinFee
      
    • The newScale value is constrained, by comparing to previousScale and clamped it to 1/2*previousScale if lower than half previous scale, and 2*previousScale if higher than twice previous scale.

      newPrevRatio = newScale / previousScale
      if newPrevRatio < 0.5 {
        newScale = 0.5 * previousScale
      } else if newPrevRatio > 2.0 {
        newScale = 2.0 * previousScale
      }
      
    • Finally newScale will be finalized and inserted to fee_scale table applied to the next block minimumFee.

    • note: to avoid floating point value, scale is multiplied to constant.OneZBC

  • Data

    • FeeVoteInfo

      FeeVoteInfo is object for the node-owner to vote the next new fee.

      No Field Length (byte) Type
      0 RecentBlockHash 32 byte
      1 RecentBlockHeight 4 uint32
      2 FeeVote 8 int64

      RecentBlockHash: is the latest BlockHash value when this object is created. RecentBlockHeight: is the height of RecentBlockHash FeeVote: next minimum fee the owner want to vote on.

      • Bytes Sequence

        In CommitFee we need to hash the FeeVoteInfo, to do that we convert the object to its bytes sequence in the exact order and size of the above table.