Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue tenure extend if incoming miner fails to mine #5805

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

jferrant
Copy link
Collaborator

@jferrant jferrant commented Feb 5, 2025

Help...why was the sort tip check necessary? If I don't do it, it fails to tenure extend in empty_sortitions_before_proposal case... :(

@jferrant jferrant force-pushed the feat/miner-continues-tenure-if-tenure-empty branch from 7f095aa to e5a2d61 Compare February 5, 2025 02:39
@jferrant jferrant force-pushed the feat/miner-continues-tenure-if-tenure-empty branch from e5a2d61 to 2f4f2dd Compare February 5, 2025 02:49
@aldur aldur added this to the 3.1.0.0.6 milestone Feb 5, 2025
Copy link
Member

@kantai kantai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks mostly good to me -- I'll need to take a closer look at the tests (and probably have some comments there), but I also dropped a description of what scenarios I think need to be covered.

stackslib/src/config/mod.rs Outdated Show resolved Hide resolved
testnet/stacks-node/src/nakamoto_node/relayer.rs Outdated Show resolved Hide resolved
Comment on lines 1470 to 1474
// TODO: I don't understand why this works? HELP???
if sort_tip.consensus_hash != highest_valid_sortition.consensus_hash {
info!("Relayer: will not extend tenure -- we won sortition {}, but the highest valid sortition is {}", &canonical_stacks_snapshot.consensus_hash, &highest_valid_sortition.consensus_hash);
return Ok(None);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so I think what's happening here is the following:

  1. canonical_stacks_snapshot is the bitcoin block that elected the current highest stacks block (which could be the prior tenure, or maybe an earlier tenure if the prior tenure wasn't active)
  2. At this point in the control flow, canonical_stacks_snapshot was also mined by this miner.
  3. find_highest_valid_sortition will only return a sortition strictly after canonical_stacks_snapshot.consensus_hash which tries to build on top of it. This sortition can't have blocks in it yet (because of the first point above).
  4. So if you're in this if let Some() case, that means that there's a new tenure, that new tenure doesn't have blocks yet, and its trying to build off of this miner's view of the stacks tip.
  5. sort_tip is the actual last processed bitcoin block. if the highest valid sortition isn't the last processed bitcoin block, it means that someone had an empty tenure (maybe due to a flash block), but it also means that the miner is unlikely to be able to even communicate over .miners anyways (because they are "2 miners behind").

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I, personally, find all that reasoning above very confusing (and it may not be accurate), so I think I'd be supportive of some factoring of this function if there's some clearer way to do this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah will take a look through it again. I had a really hard time following our current tenure_extend logic but Brice helped me reason it out to a point that maybe I can refactor now.

@@ -12835,3 +12835,883 @@ fn tenure_extend_cost_threshold() {

signer_test.shutdown();
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay -- so I think there's basically four scenarios that should be covered. In each of them, the miners kind of behave the same: Miner A wins tenure N + 1, Miner B wins tenure N. Miner A's block production is stalled. Miner B is configured to wait for Miner A for X seconds before trying to tenure extend over Miner A. Once Miner B has submitted their block proposal and it has been rejected or accepted, Miner A is unstalled and they should try to produce a block proposal. Depending on how the signer set is configured, we'll see different expected behavior. I think signers should be configured with block_proposal_timeouts of like 30 seconds (for signers preferring Miner B to take over) and then like 2 hours for signers preferring Miner A stay valid.

Scenario 1: Signers configured for no handoff

  1. Miner A is "late", Miner B tries to take over.
  2. Signer set is configured to prefer A
  3. Miner B's tenure extension should be rejected
  4. Miner A wakes up, and block proposals should be accepted.

Scenario 2: Signers and miners configured for handoff

  1. Miner A is "late", Miner B tries to take over.
  2. Signer set is configured to allow B
  3. Miner B's tenure extension should be accepted
  4. Miner A's block proposals should be rejected

Scenario 3: Non-blocking minority configured for handoff

  1. Miner A is "late", Miner B tries to take over.
  2. Non blocking minority of Signer set is configured to prefer B
  3. Miner B's tenure extension should be rejected
  4. Miner A's block proposals should be accepted

Scenario 4: Non-blocking minority configured for no handoff

  1. Miner A is "late", Miner B tries to take over.
  2. Non blocking minority of Signer set is configured to prefer A
  3. Miner B's tenure extension should be accepted
  4. Miner A's block proposals should be rejected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Status: 💻 In Progress
Development

Successfully merging this pull request may close these issues.

[miner] Miner should issue a tenure extend if the incoming miner fails to produce a block proposal
3 participants