diff --git a/rusk/src/lib/lib.rs b/rusk/src/lib/lib.rs index d419239084..d91f82a772 100644 --- a/rusk/src/lib/lib.rs +++ b/rusk/src/lib/lib.rs @@ -112,6 +112,7 @@ impl Rusk { block_gas_limit: u64, generator: &BlsPublicKey, txs: I, + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, Vec, VerificationOutput)> { let inner = self.inner.lock(); @@ -179,11 +180,12 @@ impl Rusk { } } - reward_and_update_root( + reward_slash_and_update_root( &mut session, block_height, dusk_spent, generator, + missed_generators, )?; let state_root = session.root(); @@ -206,6 +208,7 @@ impl Rusk { block_gas_limit: u64, generator: &BlsPublicKey, txs: &[Transaction], + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, VerificationOutput)> { let inner = self.inner.lock(); @@ -213,7 +216,14 @@ impl Rusk { let mut session = rusk_abi::new_session(&inner.vm, current_commit, block_height)?; - accept(&mut session, block_height, block_gas_limit, generator, txs) + accept( + &mut session, + block_height, + block_gas_limit, + generator, + txs, + missed_generators, + ) } /// Accept the given transactions. @@ -228,6 +238,7 @@ impl Rusk { generator: BlsPublicKey, txs: Vec, consistency_check: Option, + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, VerificationOutput)> { let mut inner = self.inner.lock(); @@ -241,6 +252,7 @@ impl Rusk { block_gas_limit, &generator, &txs[..], + missed_generators, )?; if let Some(expected_verification) = consistency_check { @@ -269,6 +281,7 @@ impl Rusk { generator: BlsPublicKey, txs: Vec, consistency_check: Option, + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, VerificationOutput)> { let mut inner = self.inner.lock(); @@ -282,6 +295,7 @@ impl Rusk { block_gas_limit, &generator, &txs[..], + missed_generators, )?; if let Some(expected_verification) = consistency_check { @@ -620,6 +634,7 @@ fn accept( block_gas_limit: u64, generator: &BlsPublicKey, txs: &[Transaction], + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, VerificationOutput)> { let mut block_gas_left = block_gas_limit; @@ -651,7 +666,13 @@ fn accept( }); } - reward_and_update_root(session, block_height, dusk_spent, generator)?; + reward_slash_and_update_root( + session, + block_height, + dusk_spent, + generator, + missed_generators, + )?; let state_root = session.root(); let event_hash = event_hasher.finalize().into(); @@ -717,11 +738,12 @@ fn update_hasher(hasher: &mut Sha3_256, event: Event) { hasher.update(event.data); } -fn reward_and_update_root( +fn reward_slash_and_update_root( session: &mut Session, block_height: u64, dusk_spent: Dusk, generator: &BlsPublicKey, + slashing: &[BlsPublicKey], ) -> Result<()> { let (dusk_value, generator_value) = coinbase_value(block_height, dusk_spent); @@ -738,6 +760,16 @@ fn reward_and_update_root( &(*generator, generator_value), u64::MAX, )?; + let slash_amount = emission_amount(block_height) / 255; + + for to_slash in slashing { + session.call::<_, ()>( + STAKE_CONTRACT, + "slash", + &(*to_slash, slash_amount), + u64::MAX, + )?; + } session.call::<_, ()>(TRANSFER_CONTRACT, "update_root", &(), u64::MAX)?; diff --git a/rusk/src/lib/vm.rs b/rusk/src/lib/vm.rs index 145f2000a7..1104c2a5f4 100644 --- a/rusk/src/lib/vm.rs +++ b/rusk/src/lib/vm.rs @@ -33,6 +33,7 @@ impl VMExecution for Rusk { params.block_gas_limit, params.generator_pubkey.inner(), txs, + ¶ms.missed_generators[..], ) .map_err(|inner| { anyhow::anyhow!("Cannot execute txs: {inner}!!") @@ -57,6 +58,7 @@ impl VMExecution for Rusk { blk.header().gas_limit, &generator, blk.txs(), + &blk.header().failed_iterations.to_missed_generators()?, ) .map_err(|inner| anyhow::anyhow!("Cannot verify txs: {inner}!!"))?; @@ -83,6 +85,7 @@ impl VMExecution for Rusk { state_root: blk.header().state_hash, event_hash: blk.header().event_hash, }), + &blk.header().failed_iterations.to_missed_generators()?, ) .map_err(|inner| anyhow::anyhow!("Cannot accept txs: {inner}!!"))?; @@ -109,6 +112,7 @@ impl VMExecution for Rusk { state_root: blk.header().state_hash, event_hash: blk.header().event_hash, }), + &blk.header().failed_iterations.to_missed_generators()?, ) .map_err(|inner| { anyhow::anyhow!("Cannot finalize txs: {inner}!!") diff --git a/rusk/tests/common/state.rs b/rusk/tests/common/state.rs index 99ba8679e7..e080352128 100644 --- a/rusk/tests/common/state.rs +++ b/rusk/tests/common/state.rs @@ -77,6 +77,7 @@ pub fn generator_procedure( round, block_gas_limit, generator_pubkey, + missed_generators: vec![], }; let (transfer_txs, discarded, execute_output) = rusk