Changed exit block info such that one is created per reward cycle, instead of per block; fixed some tests

This commit is contained in:
Pavitthra Pandurangan
2022-04-14 15:55:43 -04:00
parent 7fbd17e126
commit 5e36a72b9c
7 changed files with 183 additions and 180 deletions

View File

@@ -514,6 +514,7 @@ impl Burnchain {
self.first_block_height + reward_cycle * (self.pox_constants.reward_cycle_length as u64) + 1
}
// Takes in the burn block height
pub fn block_height_to_reward_cycle(&self, block_height: u64) -> Option<u64> {
if block_height < self.first_block_height {
return None;

View File

@@ -447,8 +447,6 @@ impl FromRow<StacksEpoch> for StacksEpoch {
impl FromRow<BlockExitRewardCycleInfo> for BlockExitRewardCycleInfo {
fn from_row<'a>(row: &'a Row) -> Result<BlockExitRewardCycleInfo, db_error> {
let block_id = StacksBlockId::from_column(row, "block_id")?;
let parent_block_id = StacksBlockId::from_column(row, "parent_block_id")?;
let block_reward_cycle = u64::from_column(row, "block_reward_cycle")?;
let curr_exit_proposal = Option::<u64>::from_column(row, "curr_exit_proposal")?;
let curr_exit_at_reward_cycle =
@@ -458,8 +456,6 @@ impl FromRow<BlockExitRewardCycleInfo> for BlockExitRewardCycleInfo {
.map_err(|e| db_error::SerializationError(e))?;
let exit_cycle_info = BlockExitRewardCycleInfo {
block_id,
parent_block_id,
block_reward_cycle,
curr_exit_proposal,
curr_exit_at_reward_cycle,
@@ -638,14 +634,12 @@ const SORTITION_DB_SCHEMA_2: &'static [&'static str] = &[r#"
const SORTITION_DB_SCHEMA_3: &'static [&'static str] = &[r#"
CREATE TABLE exit_at_reward_cycle_info (
block_id TEXT NOT NULL,
parent_block_id TEXT NOT NULL,
block_reward_cycle INTEGER NOT NULL,
curr_exit_proposal INTEGER,
curr_exit_at_reward_cycle INTEGER,
invalid_reward_cycles TEXT NOT NULL,
PRIMARY KEY(block_id)
PRIMARY KEY(block_reward_cycle)
);"#];
const SORTITION_DB_INDEXES: &'static [&'static str] = &[
@@ -666,7 +660,7 @@ const SORTITION_DB_INDEXES: &'static [&'static str] = &[
"CREATE INDEX IF NOT EXISTS index_transfer_stx_burn_header_hash ON transfer_stx(burn_header_hash);",
"CREATE INDEX IF NOT EXISTS index_missed_commits_intended_sortition_id ON missed_commits(intended_sortition_id);",
"CREATE INDEX IF NOT EXISTS canonical_stacks_blocks ON canonical_accepted_stacks_blocks(tip_consensus_hash,stacks_block_hash);",
"CREATE INDEX IF NOT EXISTS exit_reward_cycle_block_ids ON exit_at_reward_cycle_info(block_id);",
"CREATE INDEX IF NOT EXISTS exit_reward_cycle_block_ids ON exit_at_reward_cycle_info(block_reward_cycle);",
];
pub struct SortitionDB {
@@ -3657,10 +3651,10 @@ impl SortitionDB {
/// Get reward cycle info for a particular block
pub fn get_exit_at_reward_cycle_info(
conn: &Connection,
stacks_block_id: &StacksBlockId,
reward_cycle: u64,
) -> Result<Option<BlockExitRewardCycleInfo>, db_error> {
let qry = "SELECT * FROM exit_at_reward_cycle_info WHERE block_id = ?1";
let result = query_row_panic(conn, qry, &[&stacks_block_id], || {
let qry = "SELECT * FROM exit_at_reward_cycle_info WHERE block_reward_cycle = ?1";
let result = query_row_panic(conn, qry, &[&u64_to_sql(reward_cycle)?], || {
"FATAL: multiple rows for reward cycle info for one block".into()
})?;
Ok(result)
@@ -3799,10 +3793,8 @@ impl<'a> SortitionHandleTx<'a> {
None
};
let sql = "INSERT or REPLACE INTO exit_at_reward_cycle_info (block_id, parent_block_id, block_reward_cycle, invalid_reward_cycles, curr_exit_proposal, curr_exit_at_reward_cycle) VALUES (?, ?, ?, ?, ?, ?)";
let sql = "INSERT or REPLACE INTO exit_at_reward_cycle_info (block_reward_cycle, invalid_reward_cycles, curr_exit_proposal, curr_exit_at_reward_cycle) VALUES (?, ?, ?, ?)";
let args: &[&dyn ToSql] = &[
&exit_at_reward_cycle_info.block_id,
&exit_at_reward_cycle_info.parent_block_id,
&u64_to_sql(exit_at_reward_cycle_info.block_reward_cycle)?,
&serde_json::to_string(&exit_at_reward_cycle_info.invalid_reward_cycles).unwrap(),
&exit_proposal,

View File

@@ -101,10 +101,6 @@ pub enum PoxAnchorBlockStatus {
/// It is ultimately stored in the table `exit_at_reward_cycle_info` in the sortition DB.
#[derive(Debug)]
pub struct BlockExitRewardCycleInfo {
/// The block id that corresponds to this exit cycle information
pub block_id: StacksBlockId,
/// The block id of the parent
pub parent_block_id: StacksBlockId,
/// The reward cycle of the block that corresponds to this exit cycle information
pub block_reward_cycle: u64,
/// This value is non-None when consensus has been achieved on a vote; the cycle after this
@@ -949,35 +945,39 @@ impl<
}
pub fn reached_exit_reward_cycle(&self, header: &BurnchainBlockHeader) -> Result<bool, Error> {
if let Some(chain_tip) = self.canonical_chain_tip {
let exit_info_opt =
SortitionDB::get_exit_at_reward_cycle_info(self.sortition_db.conn(), &chain_tip)?;
let current_reward_cycle = self
.burnchain
.block_height_to_reward_cycle(header.block_height as u64)
.ok_or_else(|| DBError::NotFoundError)?;
let exit_info_opt = SortitionDB::get_exit_at_reward_cycle_info(
self.sortition_db.conn(),
current_reward_cycle,
)?;
if let Some(exit_info) = exit_info_opt {
if let Some(exit_reward_cycle) = exit_info.curr_exit_at_reward_cycle {
// get the first reward cycle in this epoch
let epochs = SortitionDB::get_stacks_epochs(self.sortition_db.conn())?;
let curr_epoch = StacksEpoch::get_current_epoch(&epochs, header.block_height);
let first_reward_cycle_in_epoch = self
.burnchain
.block_height_to_reward_cycle(curr_epoch.start_height)
.ok_or(Error::ChainstateError(PoxNoRewardCycle))?;
if let Some(exit_info) = exit_info_opt {
if let Some(exit_reward_cycle) = exit_info.curr_exit_at_reward_cycle {
// get the first reward cycle in this epoch
let epochs = SortitionDB::get_stacks_epochs(self.sortition_db.conn())?;
let curr_epoch = StacksEpoch::get_current_epoch(&epochs, header.block_height);
let first_reward_cycle_in_epoch = self
.burnchain
.block_height_to_reward_cycle(curr_epoch.start_height)
.ok_or(Error::ChainstateError(PoxNoRewardCycle))?;
let curr_reward_cycle = self
.burnchain
.block_height_to_reward_cycle(header.block_height)
.ok_or(Error::ChainstateError(PoxNoRewardCycle))?;
if curr_reward_cycle >= exit_reward_cycle
&& exit_reward_cycle > first_reward_cycle_in_epoch
{
// the burnchain has reached the exit reward cycle (as voted in the
// "exit-at-rc" contract)
info!("Reached the exit reward cycle that was voted on in the \
let curr_reward_cycle = self
.burnchain
.block_height_to_reward_cycle(header.block_height)
.ok_or(Error::ChainstateError(PoxNoRewardCycle))?;
if curr_reward_cycle >= exit_reward_cycle
&& exit_reward_cycle > first_reward_cycle_in_epoch
{
// the burnchain has reached the exit reward cycle (as voted in the
// "exit-at-rc" contract)
info!("Reached the exit reward cycle that was voted on in the \
'exit-at-rc' contract, ignoring subsequent burn blocks";
"exit_reward_cycle" => exit_reward_cycle,
"current_reward_cycle" => curr_reward_cycle);
return Ok(true);
}
return Ok(true);
}
}
}
@@ -1022,36 +1022,32 @@ impl<
.burnchain
.block_height_to_reward_cycle(current_block_height)
.ok_or_else(|| DBError::NotFoundError)?;
let mut current_exit_at_rc = None;
let mut current_proposal = None;
let mut invalid_reward_cycles = vec![];
let stacks_block_id = StacksBlockId::new(&block_receipt.header.consensus_hash, &block_hash);
let parent_block_id = self
.chain_state_db
.get_parent(&stacks_block_id)
.expect("BUG: failed to get parent for processed block");
let parent_reward_cycle = self
.burnchain
.block_height_to_reward_cycle(block_receipt.parent_burn_block_height as u64)
.ok_or_else(|| DBError::NotFoundError)?;
// look up parent in exit_at_reward_cycle_info table
let exit_info_opt =
SortitionDB::get_exit_at_reward_cycle_info(self.sortition_db.conn(), &parent_block_id)?;
if parent_reward_cycle < current_reward_cycle {
// set up data
let mut current_exit_at_rc = None;
let mut current_proposal = None;
let mut invalid_reward_cycles = vec![];
if let Some(parent_exit_info) = exit_info_opt {
info!("RCPR: cc: parent block info is non-None");
// copy info from parent block
current_exit_at_rc = parent_exit_info.curr_exit_at_reward_cycle;
if parent_exit_info.block_reward_cycle == current_reward_cycle {
current_proposal = parent_exit_info.curr_exit_proposal;
}
invalid_reward_cycles = parent_exit_info
.invalid_reward_cycles
.iter()
.filter(|rc| **rc > current_reward_cycle)
.map(|rc| *rc)
.collect();
// get the exit reward cycle info for the parent's reward cycle
let exit_info_opt = SortitionDB::get_exit_at_reward_cycle_info(
self.sortition_db.conn(),
parent_reward_cycle,
)?;
if let Some(parent_exit_info) = exit_info_opt {
// copy over some information from the parent exit info object
current_exit_at_rc = parent_exit_info.curr_exit_at_reward_cycle;
invalid_reward_cycles = parent_exit_info
.invalid_reward_cycles
.iter()
.filter(|rc| **rc > current_reward_cycle)
.map(|rc| *rc)
.collect();
// We process the previous reward cycle as soon as we transition to the next one.
if parent_exit_info.block_reward_cycle < current_reward_cycle {
info!("RCPR: cc: ancestor - rc is greater than parent rc");
// Check if there is some proposal. If so, need to check for a rejection.
if let Some(curr_exit_proposal) = parent_exit_info.curr_exit_proposal {
let rejection_passed = self.read_rejection_state(
@@ -1086,28 +1082,26 @@ impl<
invalid_reward_cycles.push(exit_proposal);
}
}
} else {
warn!(
"Block exit reward cycle info not found for reward cycle: {}",
parent_reward_cycle
);
}
} else {
warn!(
"BlockExitRewardCycleInfo not found for this block: {:?}",
&parent_block_id
);
}
let exit_info = BlockExitRewardCycleInfo {
block_id: stacks_block_id,
parent_block_id,
block_reward_cycle: current_reward_cycle,
curr_exit_proposal: current_proposal,
curr_exit_at_reward_cycle: current_exit_at_rc,
invalid_reward_cycles,
};
info!("RCPR: cc: exit info is: {:?}", exit_info);
let sortdb_tx = self
.sortition_db
.tx_handle_begin(&canonical_sortition_tip)?;
sortdb_tx.store_exit_at_reward_cycle_info(exit_info)?;
sortdb_tx.commit()?;
let exit_info = BlockExitRewardCycleInfo {
block_reward_cycle: current_reward_cycle,
curr_exit_proposal: current_proposal,
curr_exit_at_reward_cycle: current_exit_at_rc,
invalid_reward_cycles,
};
info!("RCPR: cc: exit info is: {:?}", exit_info);
let sortdb_tx = self
.sortition_db
.tx_handle_begin(&canonical_sortition_tip)?;
sortdb_tx.store_exit_at_reward_cycle_info(exit_info)?;
sortdb_tx.commit()?;
}
Ok(())
}

View File

@@ -4217,10 +4217,9 @@ fn test_exit_at_rc_short_reward_cycle() {
// \_ 53 _ 54
// STACKS BLOCK HEIGHT IN CYCLE: 1 2
if ix == 48 || ix == 53 || ix == 54 {
let stacks_block_id =
StacksBlockHeader::make_index_block_hash(&tip.consensus_hash, &block.block_hash());
let current_reward_cycle = b.block_height_to_reward_cycle(tip.block_height).unwrap();
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), current_reward_cycle)
.unwrap()
.unwrap();
let expected_proposal = if ix == 48 { Some(33) } else { None };

View File

@@ -2396,7 +2396,7 @@ pub mod test {
// Just update the expected value
assert_eq!(
genesis_root_hash.to_string(),
"c771616ff6acb710051238c9f4a3c48020a6d70cda637d34b89f2311a7e27886"
"c368ce3b905b36bda3f7c5269423a2ea27162f7a9d51e1d02c01642978f4dc5e"
);
}

View File

@@ -56,7 +56,8 @@ use burnchains::Txid;
use burnchains::{ExitContractConstants, PoxConstants};
use chainstate::stacks::boot::{
exit_at_reward_cycle_test_id, STACKS_BOOT_CODE_MAINNET, STACKS_BOOT_CODE_TESTNET,
exit_at_reward_cycle_test_id, BOOT_CODE_EXIT_AT_RC_TESTNET, STACKS_BOOT_CODE_MAINNET,
STACKS_BOOT_CODE_TESTNET,
};
use util::boot::{boot_code_addr, boot_code_id};
@@ -717,6 +718,44 @@ fn consume_arg(
}
}
fn install_boot_contract<C: ClarityStorage>(
header_db: &CLIHeadersDB,
marf: &mut C,
mainnet: bool,
boot_code_name: &str,
boot_code_contract: &str,
) {
let contract_identifier = QualifiedContractIdentifier::new(
boot_code_addr(mainnet).into(),
ContractName::try_from(boot_code_name.to_string()).unwrap(),
);
debug!(
"Instantiate boot code contract '{}' ({} bytes)...",
&contract_identifier,
boot_code_contract.len()
);
let mut ast = friendly_expect(
parse(&contract_identifier, boot_code_contract),
"Failed to parse program.",
);
let analysis_result = run_analysis_free(&contract_identifier, &mut ast, marf, true);
match analysis_result {
Ok(_) => {
let db = marf.get_clarity_db(header_db, &NULL_BURN_STATE_DB);
let mut vm_env = OwnedEnvironment::new_free(mainnet, db, DEFAULT_CLI_EPOCH);
vm_env
.initialize_contract(contract_identifier, boot_code_contract)
.unwrap();
}
Err(e) => {
panic!("failed to instantiate boot contract: {:?}", e);
}
};
}
/// Only called by `invoke_command` in clarity.rs.
/// Uses the test version of "exit-at-rc" contract.
fn install_boot_code<C: ClarityStorage>(header_db: &CLIHeadersDB, marf: &mut C) {
@@ -728,36 +767,16 @@ fn install_boot_code<C: ClarityStorage>(header_db: &CLIHeadersDB, marf: &mut C)
};
for (boot_code_name, boot_code_contract) in boot_code.iter() {
let contract_identifier = QualifiedContractIdentifier::new(
boot_code_addr(mainnet).into(),
ContractName::try_from(boot_code_name.to_string()).unwrap(),
install_boot_contract(header_db, marf, mainnet, boot_code_name, boot_code_contract);
}
if !mainnet {
install_boot_contract(
header_db,
marf,
mainnet,
"exit-at-rc",
&BOOT_CODE_EXIT_AT_RC_TESTNET,
);
let contract_content = *boot_code_contract;
debug!(
"Instantiate boot code contract '{}' ({} bytes)...",
&contract_identifier,
boot_code_contract.len()
);
let mut ast = friendly_expect(
parse(&contract_identifier, &contract_content),
"Failed to parse program.",
);
let analysis_result = run_analysis_free(&contract_identifier, &mut ast, marf, true);
match analysis_result {
Ok(_) => {
let db = marf.get_clarity_db(header_db, &NULL_BURN_STATE_DB);
let mut vm_env = OwnedEnvironment::new_free(mainnet, db, DEFAULT_CLI_EPOCH);
vm_env
.initialize_contract(contract_identifier, &contract_content)
.unwrap();
}
Err(e) => {
panic!("failed to instantiate boot contract: {:?}", e);
}
};
}
// set up PoX
@@ -799,14 +818,16 @@ fn install_boot_code<C: ClarityStorage>(header_db: &CLIHeadersDB, marf: &mut C)
SymbolicExpression::atom_value(Value::UInt(pox_params.reward_cycle_length as u128)),
SymbolicExpression::atom_value(Value::UInt(exit_params.absolute_minimum_exit_rc as u128)),
];
vm_env
.execute_transaction(
sender,
exit_at_rc_contract,
"set-burnchain-parameters",
params.as_slice(),
)
.unwrap();
if !mainnet {
vm_env
.execute_transaction(
sender,
exit_at_rc_contract,
"set-burnchain-parameters",
params.as_slice(),
)
.unwrap();
}
}
pub fn add_costs(result: &mut serde_json::Value, costs: bool, runtime: ExecutionCost) {

View File

@@ -7057,11 +7057,11 @@ fn exit_at_rc_integration_test() {
// check the sortdb state
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, None);
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, None);
@@ -7219,12 +7219,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - vote threshold not met (<50% of stacked stx involved in vote)
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, None);
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, None);
@@ -7309,11 +7308,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - vote threshold met (>=50% of stacked stx involved in vote) - curr_exit_proposal should be set
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, Some(30));
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, None);
@@ -7344,11 +7343,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - veto threshold met (>=60% of blocks in rc had veto) - curr_exit_at_reward_cycle should not be set
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, None);
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, None);
@@ -7746,12 +7745,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - vote threshold met (>=50% of stacked stx involved in vote) - curr_exit_proposal should be set
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, Some(49));
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, None);
@@ -7764,12 +7762,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - veto threshold not met- curr_exit_at_reward_cycle should be set
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, None);
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, Some(49));
@@ -7935,12 +7932,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - chains coordinator should invalidate votes for cycles less than the agreed upon exit reward cycle
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, None);
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, Some(49));
@@ -8105,11 +8101,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - vote threshold met (>=50% of stacked stx involved in vote) - curr_exit_proposal should be set
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, Some(53));
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, Some(49));
@@ -8145,11 +8141,11 @@ fn exit_at_rc_integration_test() {
// check sortdb - veto threshold not met - curr_exit_proposal should be set
let sort_db = btc_regtest_controller.sortdb_ref();
let stacks_tip = SortitionDB::get_canonical_stacks_chain_tip_hash(sort_db.conn()).unwrap();
let stacks_block_id = StacksBlockId::new(&stacks_tip.0, &stacks_tip.1);
let exit_rc_info = SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), &stacks_block_id)
.unwrap()
.unwrap();
let pox_info = get_pox_info(&http_origin);
let exit_rc_info =
SortitionDB::get_exit_at_reward_cycle_info(sort_db.conn(), pox_info.current_cycle.id)
.unwrap()
.unwrap();
assert_eq!(exit_rc_info.curr_exit_proposal, None);
assert_eq!(exit_rc_info.curr_exit_at_reward_cycle, Some(53));