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

fix: use O(n) instead of mn when checking pox bitvec #5291

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions stackslib/src/chainstate/nakamoto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3810,6 +3810,15 @@ impl NakamotoChainState {
active_reward_set: &RewardSet,
) -> Result<(), ChainstateError> {
if !tenure_block_commit.treatment.is_empty() {
let address_to_indeces: HashMap<_, Vec<_>> = active_reward_set
.rewarded_addresses
.iter()
.enumerate()
.fold(HashMap::new(), |mut map, (ix, addr)| {
map.entry(addr).or_insert_with(Vec::new).push(ix);
map
});

// our block commit issued a punishment, check the reward set and bitvector
// to ensure that this was valid.
for treated_addr in tenure_block_commit.treatment.iter() {
Expand All @@ -3820,24 +3829,19 @@ impl NakamotoChainState {
}
// otherwise, we need to find the indices in the rewarded_addresses
// corresponding to this address.
let address_indices = active_reward_set
.rewarded_addresses
.iter()
.enumerate()
.filter_map(|(ix, addr)| {
if addr == treated_addr.deref() {
Some(ix)
} else {
None
}
});
let empty_vec = vec![];
let address_indices = address_to_indeces
.get(treated_addr.deref())
.unwrap_or(&empty_vec);

// if any of them are 0, punishment is okay.
// if all of them are 1, punishment is not okay.
// if all of them are 0, *must* have punished
let bitvec_values: Result<Vec<_>, ChainstateError> = address_indices
.iter()
.map(
|ix| {
let ix = u16::try_from(ix)
let ix = u16::try_from(*ix)
.map_err(|_| ChainstateError::InvalidStacksBlock("Reward set index outside of u16".into()))?;
let bitvec_value = block_bitvec.get(ix)
.unwrap_or_else(|| {
Expand Down