stacks-network / stacks-core

The Stacks blockchain implementation
https://docs.stacks.co
GNU General Public License v3.0
3.01k stars 672 forks source link

Implement signer changes for time-based tenure extensions #5467

Open obycode opened 6 days ago

obycode commented 6 days ago

The signer configuration will specify a tenure extend time period. The first version of this to go live on mainnet should start off with this value defaulting to something like 5 minutes. As we validate that these tenure extends do not cause any problems, we can spread the word to signers to iteratively lower this number.

When a new burn block arrives, record the current time, idle_start, and initialize an idle_countdown counter to the configured duration. When a block proposal arrives, record the time, process_start. The block validation endpoint will validate the block and return the cost of that block. If the block has a non-zero cost, subtract (process_start - idle_start) from the idle_countdown. If it has a 0 cost, then subtract (now - idle_start) from the idle_countdown. This difference in how the idle time is computed is important to encourage miners to continue mining blocks with STX transfers after their budget is spent but before enough idle time has passed for a tenure extend.

In the BlockResponse for this proposal, include a timestamp which is current time plus idle_countdown. Once the response is sent, record the current time again to idle_start. Repeat with each block proposal.

We keep track of "idle" time instead of just flat wall time because it allows the signers to factor in how long it actually takes to process the blocks. This will flatten out the total processing time in scenarios where the cost budgeting is overly pessimistic, causing us to see some blocks that can spend the entire budget and be processed in 3 seconds, while others that spend the entire budget take 3 minutes to process.

If a block proposal arrives that contains a TenureExtend transaction and the tenure_consensus_hash is equal to the burn_view_consensus_hash, check that the current idle_countdown is less than or equal to 0 (letting this value go negative is useful feedback to the miner). If so, process the block as usual, else, reject the block. This rejection would have a new reason code.

See #5434