Skip to content

Commit

Permalink
Check draws before executing a denunciation (massalabs#3872)
Browse files Browse the repository at this point in the history
* Check draws before executing a denunciation

* Fix pos check order

* Simplify pos draws check

---------

Co-authored-by: sydhds <[email protected]>
  • Loading branch information
sydhds and sydhds authored Apr 26, 2023
1 parent 0f21d5c commit 945d350
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 12 deletions.
4 changes: 2 additions & 2 deletions massa-execution-worker/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -962,8 +962,8 @@ impl ExecutionContext {
self.speculative_executed_ops.is_op_executed(op_id)
}

/// Check if a denunciation was previously processed (to prevent reuse)
pub fn is_denunciation_processed(&self, de_idx: &DenunciationIndex) -> bool {
/// Check if a denunciation was previously executed (to prevent reuse)
pub fn is_denunciation_executed(&self, de_idx: &DenunciationIndex) -> bool {
self.speculative_processed_denunciations
.is_denunciation_executed(de_idx)
}
Expand Down
50 changes: 47 additions & 3 deletions massa-execution-worker/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ pub(crate) struct ExecutionState {
vesting_manager: Arc<VestingManager>,
// MipStore (Versioning)
mip_store: MipStore,
// selector controller to get draws
selector: Box<dyn SelectorController>,
}

impl ExecutionState {
Expand All @@ -98,6 +100,7 @@ impl ExecutionState {
config: ExecutionConfig,
final_state: Arc<RwLock<FinalState>>,
mip_store: MipStore,
selector: Box<dyn SelectorController>,
) -> ExecutionState {
// Get the slot at the output of which the final state is attached.
// This should be among the latest final slots.
Expand Down Expand Up @@ -162,6 +165,7 @@ impl ExecutionState {
config,
vesting_manager,
mip_store,
selector,
}
}

Expand Down Expand Up @@ -450,19 +454,59 @@ impl ExecutionState {

// ignore the denunciation if it was already executed
let de_idx = DenunciationIndex::from(denunciation);
if context.is_denunciation_processed(&de_idx) {
if context.is_denunciation_executed(&de_idx) {
return Err(ExecutionError::IncludeDenunciationError(
"Denunciation was already executed".to_string(),
));
}

// Check selector
// Note 1: Has to be done after slot limit and executed check
// Note 2: that this is done for a node to create a Block with 'fake' denunciation thus
// include them in executed denunciation and prevent (by occupying the corresponding entry)
// any further 'real' denunciation.

match &denunciation {
Denunciation::Endorsement(_de) => {
// Get selected address from selector and check
let selection = self
.selector
.get_selection(*de_slot)
.expect("Could not get producer from selector");
let selected_addr = selection
.endorsements
.get(*denunciation.get_index().unwrap_or(&0) as usize)
.expect("could not get selection for endorsement at index");

if *selected_addr != addr_denounced {
return Err(ExecutionError::IncludeDenunciationError(
"Attempt to execute a denunciation but address was not selected"
.to_string(),
));
}
}
Denunciation::BlockHeader(_de) => {
let selected_addr = self
.selector
.get_producer(*de_slot)
.expect("Cannot get producer from selector");

if selected_addr != addr_denounced {
return Err(ExecutionError::IncludeDenunciationError(
"Attempt to execute a denunciation but address was not selected"
.to_string(),
));
}
}
}

context.insert_executed_denunciation(&de_idx);

let slashed = context.try_slash_rolls(
&addr_denounced,
self.config.roll_count_to_slash_on_denunciation,
);

context.insert_executed_denunciation(&de_idx);

match slashed {
Ok(slashed_amount) => {
// Add slashed amount / 2 to block reward
Expand Down
6 changes: 2 additions & 4 deletions massa-execution-worker/src/tests/scenarios_mandatories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ mod tests {
MIP_STORE_STATS_COUNTERS_MAX,
};
use massa_models::prehash::PreHashMap;
use massa_models::test_exports::{
gen_block_headers_for_denunciation, gen_endorsements_for_denunciation,
};
use massa_models::test_exports::gen_endorsements_for_denunciation;
use massa_models::{address::Address, amount::Amount, slot::Slot};
use massa_models::{
block_id::BlockId,
Expand Down Expand Up @@ -1846,7 +1844,7 @@ mod tests {

// create a denunciation
let (_slot, _keypair, s_endorsement_1, s_endorsement_2, _) =
gen_block_headers_for_denunciation(Some(Slot::new(2, 4)), Some(keypair));
gen_endorsements_for_denunciation(Some(Slot::new(2, 4)), Some(keypair));
let denunciation = Denunciation::try_from((&s_endorsement_1, &s_endorsement_2)).unwrap();

// create the block containing the roll buy operation
Expand Down
1 change: 1 addition & 0 deletions massa-execution-worker/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ pub fn start_execution_worker(
config.clone(),
final_state,
mip_store,
selector.clone(),
)));

// define the input data interface
Expand Down
8 changes: 8 additions & 0 deletions massa-models/src/denunciation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,14 @@ impl Denunciation {
}
}

/// Get field: index (return None for a block header denunciation)
pub fn get_index(&self) -> Option<&u32> {
match self {
Denunciation::BlockHeader(_) => None,
Denunciation::Endorsement(de) => Some(&de.index),
}
}

/// Get Denunciation public key ref
pub fn get_public_key(&self) -> &PublicKey {
match self {
Expand Down
6 changes: 3 additions & 3 deletions massa-pool-worker/src/denunciation_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ impl DenunciationPool {
Ok(selection) => {
if let Some(address) = selection.endorsements.get(de_p.index as usize) {
if *address != Address::from_public_key(&de_p.public_key) {
warn!("Denunciation factory received a secure share endorsement but address was not selected");
warn!("Denunciation pool received a secure share endorsement but address was not selected");
return;
}
} else {
warn!("Denunciation factory could not get selected address for endorsements at index");
warn!("Denunciation pool could not get selected address for endorsements at index");
return;
}
}
Expand All @@ -131,7 +131,7 @@ impl DenunciationPool {
if address
!= Address::from_public_key(denunciation_precursor.get_public_key())
{
warn!("Denunciation factory received a secured header but address was not selected");
warn!("Denunciation pool received a secured header but address was not selected");
return;
}
}
Expand Down

0 comments on commit 945d350

Please sign in to comment.