Skip to content
This repository has been archived by the owner on Aug 22, 2024. It is now read-only.

Commit

Permalink
Merge pull request stacks-network#4750 from stacks-network/fix/4734
Browse files Browse the repository at this point in the history
Fix/4734
  • Loading branch information
jcnelson authored May 7, 2024
2 parents 738c4c8 + f98bcbf commit 6ab2fd2
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 49 deletions.
2 changes: 1 addition & 1 deletion stackslib/src/net/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1142,7 +1142,7 @@ impl PeerDB {
}

/// Set a peer as an initial peer
fn set_initial_peer(
pub fn set_initial_peer(
tx: &Transaction,
network_id: u32,
peer_addr: &PeerAddress,
Expand Down
42 changes: 11 additions & 31 deletions stackslib/src/net/inv/epoch2x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ pub const INV_SYNC_INTERVAL: u64 = 150;
#[cfg(test)]
pub const INV_SYNC_INTERVAL: u64 = 3;

#[cfg(not(test))]
pub const INV_REWARD_CYCLES: u64 = 2;
#[cfg(test)]
pub const INV_REWARD_CYCLES: u64 = 1;

#[derive(Debug, PartialEq, Clone)]
pub struct PeerBlocksInv {
Expand Down Expand Up @@ -1756,7 +1753,7 @@ impl PeerNetwork {
}

/// Determine at which reward cycle to begin scanning inventories
fn get_block_scan_start(&self, sortdb: &SortitionDB, highest_remote_reward_cycle: u64) -> u64 {
pub(crate) fn get_block_scan_start(&self, sortdb: &SortitionDB) -> u64 {
// see if the stacks tip affirmation map and heaviest affirmation map diverge. If so, then
// start scaning at the reward cycle just before that.
let am_rescan_rc = self
Expand All @@ -1783,19 +1780,18 @@ impl PeerNetwork {
.block_height_to_reward_cycle(stacks_tip_burn_block_height)
.unwrap_or(0);

let start_reward_cycle = cmp::min(
stacks_tip_rc,
highest_remote_reward_cycle.saturating_sub(self.connection_opts.inv_reward_cycles),
);
let start_reward_cycle =
stacks_tip_rc.saturating_sub(self.connection_opts.inv_reward_cycles);

let rescan_rc = cmp::min(am_rescan_rc, start_reward_cycle);

test_debug!(
"begin blocks inv scan at {} = min({},{},{})",
"begin blocks inv scan at {} = min({},{}) stacks_tip_am={} heaviest_am={}",
rescan_rc,
stacks_tip_rc,
highest_remote_reward_cycle.saturating_sub(self.connection_opts.inv_reward_cycles),
am_rescan_rc
am_rescan_rc,
start_reward_cycle,
&self.stacks_tip_affirmation_map,
&self.heaviest_affirmation_map
);
rescan_rc
}
Expand All @@ -1814,12 +1810,7 @@ impl PeerNetwork {
Some(x) => x,
None => {
// proceed to block scan
let scan_start_rc = self.get_block_scan_start(
sortdb,
self.burnchain
.block_height_to_reward_cycle(stats.inv.get_block_height())
.unwrap_or(0),
);
let scan_start_rc = self.get_block_scan_start(sortdb);

debug!("{:?}: cannot make any more GetPoxInv requests for {:?}; proceeding to block inventory scan at reward cycle {}", &self.local_peer, nk, scan_start_rc);
stats.reset_block_scan(scan_start_rc);
Expand Down Expand Up @@ -1876,12 +1867,7 @@ impl PeerNetwork {
// proceed with block scan.
// If we're in IBD, then this is an always-allowed peer and we should
// react to divergences by deepening our rescan.
let scan_start_rc = self.get_block_scan_start(
sortdb,
self.burnchain
.block_height_to_reward_cycle(stats.inv.get_block_height())
.unwrap_or(0),
);
let scan_start_rc = self.get_block_scan_start(sortdb);
debug!(
"{:?}: proceeding to block inventory scan for {:?} (diverged) at reward cycle {} (ibd={})",
&self.local_peer, nk, scan_start_rc, ibd
Expand Down Expand Up @@ -1982,12 +1968,7 @@ impl PeerNetwork {
}

// proceed to block scan.
let scan_start = self.get_block_scan_start(
sortdb,
self.burnchain
.block_height_to_reward_cycle(stats.inv.get_block_height())
.unwrap_or(0),
);
let scan_start = self.get_block_scan_start(sortdb);
debug!(
"{:?}: proceeding to block inventory scan for {:?} at reward cycle {}",
&self.local_peer, nk, scan_start
Expand Down Expand Up @@ -2368,7 +2349,6 @@ impl PeerNetwork {
.unwrap_or(network.burnchain.reward_cycle_to_block_height(
network.get_block_scan_start(
sortdb,
network.pox_id.num_inventory_reward_cycles() as u64,
),
))
.saturating_sub(sortdb.first_block_height);
Expand Down
53 changes: 46 additions & 7 deletions stackslib/src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2641,6 +2641,26 @@ pub mod test {
&self.network.local_peer
}

pub fn add_neighbor(
&mut self,
n: &mut Neighbor,
stacker_dbs: Option<&[QualifiedContractIdentifier]>,
bootstrap: bool,
) {
let mut tx = self.network.peerdb.tx_begin().unwrap();
n.save(&mut tx, stacker_dbs).unwrap();
if bootstrap {
PeerDB::set_initial_peer(
&tx,
self.config.network_id,
&n.addr.addrbytes,
n.addr.port,
)
.unwrap();
}
tx.commit().unwrap();
}

// TODO: DRY up from PoxSyncWatchdog
pub fn infer_initial_burnchain_block_download(
burnchain: &Burnchain,
Expand Down Expand Up @@ -2849,7 +2869,15 @@ pub mod test {
&mut self,
blockstack_ops: Vec<BlockstackOperationType>,
) -> (u64, BurnchainHeaderHash, ConsensusHash) {
let x = self.inner_next_burnchain_block(blockstack_ops, true, true, true);
let x = self.inner_next_burnchain_block(blockstack_ops, true, true, true, false);
(x.0, x.1, x.2)
}

pub fn next_burnchain_block_diverge(
&mut self,
blockstack_ops: Vec<BlockstackOperationType>,
) -> (u64, BurnchainHeaderHash, ConsensusHash) {
let x = self.inner_next_burnchain_block(blockstack_ops, true, true, true, true);
(x.0, x.1, x.2)
}

Expand All @@ -2862,22 +2890,22 @@ pub mod test {
ConsensusHash,
Option<BlockHeaderHash>,
) {
self.inner_next_burnchain_block(blockstack_ops, true, true, true)
self.inner_next_burnchain_block(blockstack_ops, true, true, true, false)
}

pub fn next_burnchain_block_raw(
&mut self,
blockstack_ops: Vec<BlockstackOperationType>,
) -> (u64, BurnchainHeaderHash, ConsensusHash) {
let x = self.inner_next_burnchain_block(blockstack_ops, false, false, true);
let x = self.inner_next_burnchain_block(blockstack_ops, false, false, true, false);
(x.0, x.1, x.2)
}

pub fn next_burnchain_block_raw_sortition_only(
&mut self,
blockstack_ops: Vec<BlockstackOperationType>,
) -> (u64, BurnchainHeaderHash, ConsensusHash) {
let x = self.inner_next_burnchain_block(blockstack_ops, false, false, false);
let x = self.inner_next_burnchain_block(blockstack_ops, false, false, false, false);
(x.0, x.1, x.2)
}

Expand All @@ -2890,7 +2918,7 @@ pub mod test {
ConsensusHash,
Option<BlockHeaderHash>,
) {
self.inner_next_burnchain_block(blockstack_ops, false, false, true)
self.inner_next_burnchain_block(blockstack_ops, false, false, true, false)
}

pub fn set_ops_consensus_hash(
Expand Down Expand Up @@ -2921,6 +2949,7 @@ pub mod test {
tip_block_height: u64,
tip_block_hash: &BurnchainHeaderHash,
num_ops: u64,
ops_determine_block_header: bool,
) -> BurnchainBlockHeader {
test_debug!(
"make_next_burnchain_block: tip_block_height={} tip_block_hash={} num_ops={}",
Expand All @@ -2939,8 +2968,16 @@ pub mod test {

let now = BURNCHAIN_TEST_BLOCK_TIME;
let block_header_hash = BurnchainHeaderHash::from_bitcoin_hash(
&BitcoinIndexer::mock_bitcoin_header(&parent_hdr.block_hash, now as u32)
.bitcoin_hash(),
&BitcoinIndexer::mock_bitcoin_header(
&parent_hdr.block_hash,
(now as u32)
+ if ops_determine_block_header {
num_ops as u32
} else {
0
},
)
.bitcoin_hash(),
);
test_debug!(
"Block header hash at {} is {}",
Expand Down Expand Up @@ -3012,6 +3049,7 @@ pub mod test {
set_consensus_hash: bool,
set_burn_hash: bool,
update_burnchain: bool,
ops_determine_block_header: bool,
) -> (
u64,
BurnchainHeaderHash,
Expand All @@ -3035,6 +3073,7 @@ pub mod test {
tip.block_height,
&tip.burn_header_hash,
blockstack_ops.len() as u64,
ops_determine_block_header,
);

if set_burn_hash {
Expand Down
2 changes: 2 additions & 0 deletions stackslib/src/net/tests/download/nakamoto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,7 @@ fn test_nakamoto_download_run_2_peers() {
sn.block_height,
&sn.burn_header_hash,
ops.len() as u64,
false,
);
TestPeer::add_burnchain_block(&boot_peer.config.burnchain, &block_header, ops.clone());
}
Expand Down Expand Up @@ -2140,6 +2141,7 @@ fn test_nakamoto_unconfirmed_download_run_2_peers() {
sn.block_height,
&sn.burn_header_hash,
ops.len() as u64,
false,
);
TestPeer::add_burnchain_block(&boot_peer.config.burnchain, &block_header, ops.clone());
}
Expand Down
82 changes: 72 additions & 10 deletions stackslib/src/net/tests/inv/epoch2x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1241,19 +1241,72 @@ fn test_sync_inv_diagnose_nack() {
);
}

#[test]
fn test_inv_sync_start_reward_cycle() {
let mut peer_1_config = TestPeerConfig::new(function_name!(), 0, 0);
peer_1_config.connection_opts.inv_reward_cycles = 0;

let mut peer_1 = TestPeer::new(peer_1_config);

let num_blocks = (GETPOXINV_MAX_BITLEN * 2) as u64;
for i in 0..num_blocks {
let (burn_ops, stacks_block, microblocks) = peer_1.make_default_tenure();
peer_1.next_burnchain_block(burn_ops.clone());
peer_1.process_stacks_epoch_at_tip(&stacks_block, &microblocks);
}

let _ = peer_1.step();

let block_scan_start = peer_1
.network
.get_block_scan_start(peer_1.sortdb.as_ref().unwrap());
assert_eq!(block_scan_start, 7);

peer_1.network.connection_opts.inv_reward_cycles = 1;

let block_scan_start = peer_1
.network
.get_block_scan_start(peer_1.sortdb.as_ref().unwrap());
assert_eq!(block_scan_start, 7);

peer_1.network.connection_opts.inv_reward_cycles = 2;

let block_scan_start = peer_1
.network
.get_block_scan_start(peer_1.sortdb.as_ref().unwrap());
assert_eq!(block_scan_start, 6);

peer_1.network.connection_opts.inv_reward_cycles = 3;

let block_scan_start = peer_1
.network
.get_block_scan_start(peer_1.sortdb.as_ref().unwrap());
assert_eq!(block_scan_start, 5);

peer_1.network.connection_opts.inv_reward_cycles = 300;

let block_scan_start = peer_1
.network
.get_block_scan_start(peer_1.sortdb.as_ref().unwrap());
assert_eq!(block_scan_start, 0);
}

#[test]
#[ignore]
fn test_sync_inv_2_peers_plain() {
with_timeout(600, || {
let mut peer_1_config = TestPeerConfig::new(function_name!(), 0, 0);
let mut peer_2_config = TestPeerConfig::new(function_name!(), 0, 0);

peer_1_config.add_neighbor(&peer_2_config.to_neighbor());
peer_2_config.add_neighbor(&peer_1_config.to_neighbor());
peer_1_config.connection_opts.inv_reward_cycles = 10;
peer_2_config.connection_opts.inv_reward_cycles = 10;

let mut peer_1 = TestPeer::new(peer_1_config);
let mut peer_2 = TestPeer::new(peer_2_config);

peer_1.add_neighbor(&mut peer_2.to_neighbor(), None, true);
peer_2.add_neighbor(&mut peer_1.to_neighbor(), None, true);

let num_blocks = (GETPOXINV_MAX_BITLEN * 2) as u64;
let first_stacks_block_height = {
let sn =
Expand Down Expand Up @@ -1422,12 +1475,15 @@ fn test_sync_inv_2_peers_stale() {
let mut peer_1_config = TestPeerConfig::new(function_name!(), 0, 0);
let mut peer_2_config = TestPeerConfig::new(function_name!(), 0, 0);

peer_1_config.add_neighbor(&peer_2_config.to_neighbor());
peer_2_config.add_neighbor(&peer_1_config.to_neighbor());
peer_1_config.connection_opts.inv_reward_cycles = 10;
peer_2_config.connection_opts.inv_reward_cycles = 10;

let mut peer_1 = TestPeer::new(peer_1_config);
let mut peer_2 = TestPeer::new(peer_2_config);

peer_1.add_neighbor(&mut peer_2.to_neighbor(), None, true);
peer_2.add_neighbor(&mut peer_1.to_neighbor(), None, true);

let num_blocks = (GETPOXINV_MAX_BITLEN * 2) as u64;
let first_stacks_block_height = {
let sn =
Expand Down Expand Up @@ -1525,14 +1581,17 @@ fn test_sync_inv_2_peers_unstable() {
let mut peer_1_config = TestPeerConfig::new(function_name!(), 0, 0);
let mut peer_2_config = TestPeerConfig::new(function_name!(), 0, 0);

let stable_confs = peer_1_config.burnchain.stable_confirmations as u64;
peer_1_config.connection_opts.inv_reward_cycles = 10;
peer_2_config.connection_opts.inv_reward_cycles = 10;

peer_1_config.add_neighbor(&peer_2_config.to_neighbor());
peer_2_config.add_neighbor(&peer_1_config.to_neighbor());
let stable_confs = peer_1_config.burnchain.stable_confirmations as u64;

let mut peer_1 = TestPeer::new(peer_1_config);
let mut peer_2 = TestPeer::new(peer_2_config);

peer_1.add_neighbor(&mut peer_2.to_neighbor(), None, true);
peer_2.add_neighbor(&mut peer_1.to_neighbor(), None, true);

let num_blocks = (GETPOXINV_MAX_BITLEN * 2) as u64;

let first_stacks_block_height = {
Expand All @@ -1559,7 +1618,7 @@ fn test_sync_inv_2_peers_unstable() {
} else {
// peer 1 diverges
test_debug!("Peer 1 diverges at {}", i + first_stacks_block_height);
peer_1.next_burnchain_block(vec![]);
peer_1.next_burnchain_block_diverge(vec![burn_ops[0].clone()]);
}
}

Expand Down Expand Up @@ -1734,15 +1793,18 @@ fn test_sync_inv_2_peers_different_pox_vectors() {
let mut peer_1_config = TestPeerConfig::new(function_name!(), 0, 0);
let mut peer_2_config = TestPeerConfig::new(function_name!(), 0, 0);

peer_1_config.add_neighbor(&peer_2_config.to_neighbor());
peer_2_config.add_neighbor(&peer_1_config.to_neighbor());
peer_1_config.connection_opts.inv_reward_cycles = 10;
peer_2_config.connection_opts.inv_reward_cycles = 10;

let reward_cycle_length = peer_1_config.burnchain.pox_constants.reward_cycle_length as u64;
assert_eq!(reward_cycle_length, 5);

let mut peer_1 = TestPeer::new(peer_1_config);
let mut peer_2 = TestPeer::new(peer_2_config);

peer_1.add_neighbor(&mut peer_2.to_neighbor(), None, true);
peer_2.add_neighbor(&mut peer_1.to_neighbor(), None, true);

let num_blocks = (GETPOXINV_MAX_BITLEN * 3) as u64;

let first_stacks_block_height = {
Expand Down

0 comments on commit 6ab2fd2

Please sign in to comment.