Skip to content

Latest commit

 

History

History
139 lines (107 loc) · 5.81 KB

commit-pub-rand.md

File metadata and controls

139 lines (107 loc) · 5.81 KB

Public Randomness Commit Specification

Overview

The finality provider periodically commits public randomness to the consumer chain to be used for future block finalization. This document specifies the process of committing public randomness.

Commit Process

Generating a Commit

A randomness pair is essentially a pair of 32-byte points over secp256k1. A public randomness commit is a list of public randomness, each committed to a specific height. In particular, a commit consists of:

  • a merkle root containing a list of public randomness values,
  • a start height, indicating from which height the randomness starts, and
  • the number of randomness contained in the merkle tree.

To generate a new commit, following steps are needed:

  1. Generate a list of randomness. This requires an RPC call to the EOTS manager (eotsd) to generate a list of public randomness, each corresponding to a specific height according to the start height and the number of randomness in the request. Randomness generation is required to be deterministic.
  2. Construct the merkle tree based on the list of randomness using the CometBFT's merkle library. The merkle root will be used in the commit, while each randomness number and their merkle proofs will be used for finality vote submission in the future.
  3. Send a Schnorr signature request to the EOTS manager over the hash of the commit (concatenated by the start height, number of randomness, and the merkle root).
  4. Build the commit message (MsgCommitPubRandList) and send a transaction to Babylon.

Timing to Commit

Public randomness is an essential component of finality. It should be committed before finality votes can be sent. Otherwise, the finality provider looses voting power for this height.

To this end, when a finality provider is started, it runs a loop to periodically check whether it needs to make a new commit and calculate the start height of the next commit. In particular:

	tipHeightWithDelay := tipHeight + uint64(fp.cfg.TimestampingDelayBlocks)
	var startHeight uint64
	switch {
	case lastCommittedHeight < tipHeightWithDelay:
		// the start height should consider the timestamping delay
		// as it is only available to use after tip height + estimated timestamping delay
		startHeight = tipHeightWithDelay
	case lastCommittedHeight < tipHeightWithDelay+uint64(fp.cfg.NumPubRand):
		startHeight = lastCommittedHeight + 1
	default:
        // randomness is sufficient, do not need to make a commit

where:

  • lastCommittedHeight is the end height (startHeight + numRand - 1) from the latest public randomness commit recorded on the consumer chain
  • tipHeight is the current height of the consumer chain
  • TimestampingDelayBlocks is a configuration value, which measures when to make a new commit
  • NumPubRand is the number of randomness in a commit defined in the config.

Determining TimestampingDelayBlocks

The value of TimestampingDelayBlocks must account for BTC-timestamping delays, which is needed to activate the randomness for a specific height after the committed epoch is BTC-timestamped. Here's an example:

  • The consumer chain receives a commit with:
    • Start height: 100
    • Number of randomness values: 1000
    • Current epoch: 10
  • This means randomness for heights [100, 1099] becomes available after epoch 10 is finalized

The BTC-timestamping protocol requires:

  • 100 BTC blocks for epoch finalization
  • ≈ 1000 minutes (17 hours) at 10-minute average block time
  • With consumer chain blocks every 10 seconds, this equals approximately 6,000 blocks

Therefore,

  • TimestampingDelayBlocks should be around 6,000
  • Recommended production value: > 10,000 to provide additional safety margin

Determining Start Height

To determine the start height of a commit:

  1. For first-time commit:
    • startHeight = baseHeight + 1,
    • where baseHeight is a future height which is estimated based on the BTC-timestamping delays.
  2. For subsequent commit:
    • startHeight = lastCommittedHeight + 1,
    • where lastCommittedHeight is obtained from the consumer chain.

The baseHeight can be specified via configuration or CLI options.

Important Notes:

  • After long downtime, treat as first-time commit by specifying baseHeight.
  • Consecutiveness across commits is not enforced by the system but different commits must not overlap.
  • startHeight should not be higher than finalityActivationHeight, a parameter defined in Babylon. Therefore, startHeight = max(startHeight, finalityActivationHeight).

Determining the Number of Randomness

The number of randomness contained in a commit is specified in the config NumPubRand. A general strategy is that the value should be as large as possible. This is because each commit to the consumer chain costs gas.

However, in real life, this stategy might not always gain due to the following reasons:

  • A finality provider might not have voting power for every block. Randomness for those heights is a waste.
  • Generating more randomness leads to a larger merkle proof size which will be used for sending finality votes.
  • Generating randomness and saving the merkle proofs require time.

Additionally, given that the end height of a commit equals to startHeight + NumPubRand - 1, we should ensure that the condition lastCommittedHeight > tipHeight + uint64(TimestampingDelayBlocks) can hold for a long period of time to avoid frequent commit of randomness. In real life, the value of NumPubRand should be much larger than TimestampingDelayBlocks, e.g., NumPubRand = 2 * TimestampingDelayBlocks.