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

Nakamoto-Neon: Add nakamoto_node #4133

Merged
merged 14 commits into from
Dec 13, 2023
Merged

Nakamoto-Neon: Add nakamoto_node #4133

merged 14 commits into from
Dec 13, 2023

Conversation

kantai
Copy link
Member

@kantai kantai commented Dec 7, 2023

This PR implements a first version of a "nakamoto neon" node and operation mode.

As part of this implementation, this PR does several things:

  • Refactor some of the reused structs from neon_node (most notably globals).
  • Fix a logic-bug in nakamoto::coordinator: the first prepare phase information will be a Epoch2x block, so the reward set calculation has to handle that.
  • Add nakamoto_node module based on neon_node. It uses a new nakamoto-specifix RelayerDirective enum.
  • Add boot_nakamoto module which wraps and orchestrates the 2.x <-> 3.x node handoff. It wraps a neon or nakamoto runloop, and when the Epoch-3.0 transition is reached, stops the neon loop and starts the nakamoto loop.
  • Add "simple" integration test for nakamoto_node: this integration test actually spins up a neon node to mine through 2.0-2.5, stack enough to active pox-4, then shuts down the neon node and spins up the nakamoto node. This is effectively a first test of node/miner operation during the transition from 2.x to 3.x

Things that are still todo for this PR:

14fc7fe - Update: these are now all done.

Tests

  1. More advanced test that pushes more nakamoto blocks (updated in 14fc7fe)
  2. Test that accepts transactions and confirms that they get mined (updated in 14fc7fe)

Implementation

Block commits need to support RBF and check if the tip tenure ID changed. The reason for this is that miners should normally expect to RBF their block commit at least once:

  1. Before the first block is announced for Tenure 2, the commit for Tenure 3 will point at Tenure 1.
  2. Once the first block is announced for Tenure 2, the commit for Tenure 3 should be RBFed to Tenure 2.

(updated in 14fc7fe)

Upstream PRs

There are multiple PRs that will impact this one:

  1. Feat/tenure change validation #4114 -- this shouldn't be a huge impact, but will require updating the self-signing mode in the nakamoto_node so that it generates a TenureChange tx correctly.
  2. Make set-aggregate-public-key private #4126 and Feat/mockamoto genesis block routine #4113 -- the aggregate public key setting should eventually impact the nakamoto_node. Right now, the nakamoto_node avoids the issue by explicitly passing its self-signing aggregate key to the block acceptance routine, but there probably needs to be a new issue for loading that aggregate key automatically (because such circumvention shouldn't be possible).

@kantai kantai self-assigned this Dec 7, 2023
@kantai kantai added the neon3.0 label Dec 7, 2023
@kantai kantai linked an issue Dec 7, 2023 that may be closed by this pull request
Copy link

codecov bot commented Dec 7, 2023

Codecov Report

Attention: 2447 lines in your changes are missing coverage. Please review.

Comparison is base (c0f30df) 82.78% compared to head (a7aa3f5) 38.68%.

Files Patch % Lines
testnet/stacks-node/src/nakamoto_node/relayer.rs 0.00% 553 Missing ⚠️
testnet/stacks-node/src/run_loop/nakamoto.rs 0.00% 485 Missing ⚠️
testnet/stacks-node/src/nakamoto_node/miner.rs 0.00% 420 Missing ⚠️
...net/stacks-node/src/tests/nakamoto_integrations.rs 0.00% 322 Missing ⚠️
testnet/stacks-node/src/nakamoto_node/peer.rs 0.00% 208 Missing ⚠️
testnet/stacks-node/src/nakamoto_node.rs 0.00% 168 Missing ⚠️
testnet/stacks-node/src/run_loop/boot_nakamoto.rs 0.00% 130 Missing ⚠️
testnet/stacks-node/src/globals.rs 74.55% 43 Missing ⚠️
testnet/stacks-node/src/config.rs 41.37% 34 Missing ⚠️
testnet/stacks-node/src/neon_node.rs 28.57% 25 Missing ⚠️
... and 10 more
Additional details and impacted files
@@             Coverage Diff             @@
##             next    #4133       +/-   ##
===========================================
- Coverage   82.78%   38.68%   -44.11%     
===========================================
  Files         421      429        +8     
  Lines      299213   301662     +2449     
===========================================
- Hits       247717   116711   -131006     
- Misses      51496   184951   +133455     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@kantai kantai changed the title Nakamoto-Neon: Add nakamoto_node (draft) Nakamoto-Neon: Add nakamoto_node Dec 8, 2023
/// Communication link to the coordinator thread
pub(crate) coord_comms: CoordinatorChannels,
/// Unconfirmed transactions (shared between the relayer and p2p threads)
unconfirmed_txs: Arc<Mutex<UnconfirmedTxMap>>,
Copy link
Member

Choose a reason for hiding this comment

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

This goes away in Nakamoto

Copy link
Member Author

Choose a reason for hiding this comment

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

This struct is shared with the neon_node. I could make this field generic as well (and use a void type for it in nakamoto), but that didn't seem like a clear improvement to me.

/// Cointer state in the main thread
pub counters: Counters,
/// Connection to the PoX sync watchdog
pub sync_comms: PoxSyncWatchdogComms,
Copy link
Member

Choose a reason for hiding this comment

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

This can be dropped for Nakamoto as well -- the system must wait for the missing PoX anchor block in all cases.

Copy link
Member Author

Choose a reason for hiding this comment

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

Same as above-- this struct is shared with the neon_node. This field eventually will need to be generic. I think if we don't need the pox_watchdog, this would just be a struct monitoring the mine_after setting (where miners can set when they want to begin issuing block commits).

&chain_state,
&burn_db.index_conn(),
&mut mem_pool,
// TODO (refactor): the nakamoto block builder doesn't use the parent tenure ID,
Copy link
Member

Choose a reason for hiding this comment

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

Yup; already done in #4114

let cur_burn_chain_tip = SortitionDB::get_canonical_burn_chain_tip(burn_db.conn())
.expect("FATAL: failed to query sortition DB for canonical burn chain tip");

if cur_burn_chain_tip.consensus_hash != block.header.consensus_hash {
Copy link
Member

Choose a reason for hiding this comment

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

You wouldn't want to compare to the block's consensus hash, because the sortition may have been empty and the current miner's tenure may still be ongoing. Would it make more sense to compare the sortition tips before and after building the block?

Copy link
Member Author

@kantai kantai Dec 11, 2023

Choose a reason for hiding this comment

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

I'm not sure yet how the nakamoto MinerThread should handle the sortition changing. My current plan is to treat it like a tenure change and do a thread stop and start. That way, the MinerThread really should stop mining if it detects a consensus hash change (which it will sort of need to do in any event: it will have to get a new tenure change tx), because each instantiation of a MinerThread will only ever be active for one bitcoin block.

None
};

parent_block_info.stacks_parent_header.microblock_tail = None;
Copy link
Member

Choose a reason for hiding this comment

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

Might also want to set the seq to 0

Copy link
Member Author

Choose a reason for hiding this comment

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

The sequence number is part of that StacksMicroblockHeader struct, which is being set to None here, right?

)
.expect("BUG: failure processing network results");

if net_receipts.num_new_blocks > 0 || net_receipts.num_new_confirmed_microblocks > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

Does this also check Nakamoto blocks?

Copy link
Member Author

Choose a reason for hiding this comment

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

This method is unchanged from the neon_node's process_net_result method.

pox_watchdog: Option<PoxSyncWatchdog>, // can't be instantiated until .start() is called
is_miner: Option<bool>, // not known until .start() is called
burnchain: Option<Burnchain>, // not known until .start() is called
pox_watchdog_comms: PoxSyncWatchdogComms,
Copy link
Member

Choose a reason for hiding this comment

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

Not necessary anymore

Copy link
Member Author

Choose a reason for hiding this comment

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

Right now, I'm just using it as a placeholder for an ibd global, I think as we move towards Argon, there will need to be a new struct for this, but I'd prefer to hold off on making a decision on that for now.

@@ -63,6 +64,10 @@ pub struct Counters {
pub missed_tenures: RunLoopCounter,
pub missed_microblock_tenures: RunLoopCounter,
pub cancelled_commits: RunLoopCounter,

pub naka_submitted_vrfs: RunLoopCounter,
Copy link
Member

Choose a reason for hiding this comment

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

Nakanaka

Copy link
Member

@zone117x zone117x left a comment

Choose a reason for hiding this comment

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

PR is working for me to spin up a node to epoch2.5 with a fully functional pox-4. I've been unable to get it to boot into epoch3.0 (trying to replicate your integration test). It's likely just a block height config and pox cycle config issue on my end, but would be really helpful if:

  1. Default pox cycle config for neon works to boot epoch3.0 (maybe it already is, but not sure yet)
  2. While loading the config, if the given epoch block heights and pox config do not allow epoch3.0 to activate, then exit with error (e.g. invalid cycle boundaries)

* Refactor some of the reused structs from `neon_node`
* Fix a logic-bug in `nakamoto::coordinator`: the first prepare phase information will be a Epoch2x block, so the reward set calculation has to handle that.
* Add `nakamoto_node` module based on `neon_node`
* Add simple integration test for `nakamoto_node`
…ommits at tenure_id changes, cargo fmt-stacks
Copy link
Member

@jcnelson jcnelson left a comment

Choose a reason for hiding this comment

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

LGTM! Played around with this last night in the integration test framework

@kantai kantai merged commit e71444a into next Dec 13, 2023
1 of 2 checks passed
@blockstack-devops
Copy link
Contributor

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@stacks-network stacks-network locked as resolved and limited conversation to collaborators Nov 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nakamoto: Add new stacks-node mode for “neon” operation:
6 participants