From 5bcf0e5d3f360f73ffab99d9ab2222b2a95cb9cc Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Mon, 15 Jan 2024 12:47:13 +0100 Subject: [PATCH 01/22] rusk-recovery: remove allowlist --- rusk-recovery/config/example.toml | 20 ----- rusk-recovery/config/example_gov.toml | 12 --- rusk-recovery/config/genesis.toml | 3 - rusk-recovery/config/localnet.toml | 16 ---- rusk-recovery/config/singlenet.toml | 8 -- rusk-recovery/config/testnet.toml | 107 ----------------------- rusk-recovery/config/testnet_remote.toml | 3 - rusk-recovery/src/state.rs | 33 ------- rusk-recovery/src/state/snapshot.rs | 19 ---- rusk-recovery/src/state/snapshot/acl.rs | 22 ----- 10 files changed, 243 deletions(-) delete mode 100644 rusk-recovery/config/genesis.toml delete mode 100644 rusk-recovery/src/state/snapshot/acl.rs diff --git a/rusk-recovery/config/example.toml b/rusk-recovery/config/example.toml index 9ae9f82d23..49babdeb17 100644 --- a/rusk-recovery/config/example.toml +++ b/rusk-recovery/config/example.toml @@ -6,26 +6,6 @@ # If no base_state is specified a local one will be generated base_state = "https://dusk-infra.ams3.digitaloceanspaces.com/keys/genesis.zip" -[acl.stake] - -# List of the stake contract owners -# -# Owners can allow other key to partecipate in the stake. -# Each owner is identified by a BLS PublicKey in base58 format -owners = [ - 't7QRJHMJgtGuqfcUbaFNj6QmWyf1MdsRhZMZRdnWdFxEboE849EDLRyw9A6WPjNGvFcVMsq9P3TDfBDrnBRcH3xnmZiaFspQBRRkvv9jmzdvtgyQ1kVVjReHkNXNi9bGqz3', - 'zeegH4ZAzHUUjuR4upqMejtMTvL8wQtjAMFtaxEHuDMQr9hddaUpjfgYXonmuqYcKBavwLMZzK8sVwRMXEQhW6mGaacL6q4SkK7U1TzEdGzY1kqm5LdJQWwnuRGoGP2C2HP', -] - -# List of the allowed stakers. -# -# Stakers in this list can partecipate in the stake -# Each allowed stake is identified by a BLS PublicKey in base58 format -allowlist = [ - '22p9MSeCwzrGtSff3TYPELufsGxU4oumgkHd4XqNTq5tuHmJ3aTPJErA7nF6ns4vqW295y3SXY9FdZd68bXP5q82AAEmCustZvD3mbb8K32Eawm3GNmUkzVLU7t24tCe5atj', - '25c35qHwAUGsRkFuM7xcwwQUFLeLaNE9baLFRJdLwWn5HXFzENF2Re2Lw94bxvQatFhFoS1mvkhQT6nkV3ZAbsNFKrwMtY1c6Q7EnjcN58MD1z654H7MH7K26ZtQtUpEiy9g', - 'tXxJU6caTEWicM7A4cNcPGa7dfGTXvnLuc1gWSSUGgyezSJNMfWEuAsiJrvWQjTzYeJCG8yL46LvtrBS5LqnXMNuamYpYiN3dEW6PDywURF6G6ZjFGNy9juHMFsSMdYx8EH', -] # Balances to be included in the genesis contract # diff --git a/rusk-recovery/config/example_gov.toml b/rusk-recovery/config/example_gov.toml index 3f8909f3df..a333b26ab7 100644 --- a/rusk-recovery/config/example_gov.toml +++ b/rusk-recovery/config/example_gov.toml @@ -1,15 +1,3 @@ -[acl.stake] -owners = [ - '22uowXa4bAwa9uehMFoSZjGCDTUSLGhFjCWxrEGHng8kWsEJSQBZxcCa8PeGMdTXWt9XyYNEx4S85XrGwfE8G1iG5j1ptEU4sSu1Hq3QKHsnBEZwTDLNBQeesSfmUadSjfRh', -] -allowlist = [ - 'rm6jwcM9xQChnVeHYw6W8HP7kW3E8nejgs4XhmKoYspQnrZL5dDcQjVR5e2UmbyNNF4DJDRdZGdYLgJfZ3qQXuhSCL6UTDkcQ2QEf6RW3aCtfqQMKCFMNaBsfNrZuzrP23Z', - 'uazLgN2HtLqaDZCxAtJtkkurQTXyZWXjQYJ3HdSVbpBjGRzMvKaqvpx3MRw8HTv7bTwyviLosEJAa56G66cdNjL4CJdqTUyFHdufzWWfLz9E7eF97tdc6jZsVTiGXGNGf2E', - '23RRcwBV2BsBVvmNPUh16xCYfLZj7qkxjCFg8dS5hkJcRrnVbFr5sHHGvTYbcvyDaZ19D6jqn21miC52y9rjycYrG1EBtc1wYwZLhZLHk63L52aaYYoyJtgM6hbuzmPXVvaQ', - 'xxRf7HtmFrcNqF8QpEpXmNqEePC7ftcrAGyavJQUv5mQrZKmS1GBazS1fbrftFbj5t6A19F4FComuyLcS9dVkgu8bE7vzA4QTfEUWWjLU9As9FaazE8ewVEBkAe4f8SeGny', - 'uZvKUYkVz7SJkicS4gQXGAjj8rziVkcV7ZXqGJAKNSW7iFFfTYCdo3k9Hw4A5dPfUxvBDtBPiSDjmehZGEQwDSYkdSf39WDEbavq9XHyzLY1S72EXCbEoB38avxaY7eXp6i', -] - [[governance]] contract_address = 3 name = "security_1" diff --git a/rusk-recovery/config/genesis.toml b/rusk-recovery/config/genesis.toml deleted file mode 100644 index 36070b918c..0000000000 --- a/rusk-recovery/config/genesis.toml +++ /dev/null @@ -1,3 +0,0 @@ -[acl.stake] -owners = [] -allowlist = [] diff --git a/rusk-recovery/config/localnet.toml b/rusk-recovery/config/localnet.toml index 86e8ea22f8..68e74588a4 100644 --- a/rusk-recovery/config/localnet.toml +++ b/rusk-recovery/config/localnet.toml @@ -1,19 +1,3 @@ -[acl.stake] -owners = [ - '22p9MSeCwzrGtSff3TYPELufsGxU4oumgkHd4XqNTq5tuHmJ3aTPJErA7nF6ns4vqW295y3SXY9FdZd68bXP5q82AAEmCustZvD3mbb8K32Eawm3GNmUkzVLU7t24tCe5atj', - '25c35qHwAUGsRkFuM7xcwwQUFLeLaNE9baLFRJdLwWn5HXFzENF2Re2Lw94bxvQatFhFoS1mvkhQT6nkV3ZAbsNFKrwMtY1c6Q7EnjcN58MD1z654H7MH7K26ZtQtUpEiy9g', - 'tXxJU6caTEWicM7A4cNcPGa7dfGTXvnLuc1gWSSUGgyezSJNMfWEuAsiJrvWQjTzYeJCG8yL46LvtrBS5LqnXMNuamYpYiN3dEW6PDywURF6G6ZjFGNy9juHMFsSMdYx8EH', - 't7QRJHMJgtGuqfcUbaFNj6QmWyf1MdsRhZMZRdnWdFxEboE849EDLRyw9A6WPjNGvFcVMsq9P3TDfBDrnBRcH3xnmZiaFspQBRRkvv9jmzdvtgyQ1kVVjReHkNXNi9bGqz3', - 'zeegH4ZAzHUUjuR4upqMejtMTvL8wQtjAMFtaxEHuDMQr9hddaUpjfgYXonmuqYcKBavwLMZzK8sVwRMXEQhW6mGaacL6q4SkK7U1TzEdGzY1kqm5LdJQWwnuRGoGP2C2HP', -] -allowlist = [ - '22p9MSeCwzrGtSff3TYPELufsGxU4oumgkHd4XqNTq5tuHmJ3aTPJErA7nF6ns4vqW295y3SXY9FdZd68bXP5q82AAEmCustZvD3mbb8K32Eawm3GNmUkzVLU7t24tCe5atj', - '25c35qHwAUGsRkFuM7xcwwQUFLeLaNE9baLFRJdLwWn5HXFzENF2Re2Lw94bxvQatFhFoS1mvkhQT6nkV3ZAbsNFKrwMtY1c6Q7EnjcN58MD1z654H7MH7K26ZtQtUpEiy9g', - 'tXxJU6caTEWicM7A4cNcPGa7dfGTXvnLuc1gWSSUGgyezSJNMfWEuAsiJrvWQjTzYeJCG8yL46LvtrBS5LqnXMNuamYpYiN3dEW6PDywURF6G6ZjFGNy9juHMFsSMdYx8EH', - 't7QRJHMJgtGuqfcUbaFNj6QmWyf1MdsRhZMZRdnWdFxEboE849EDLRyw9A6WPjNGvFcVMsq9P3TDfBDrnBRcH3xnmZiaFspQBRRkvv9jmzdvtgyQ1kVVjReHkNXNi9bGqz3', - 'zeegH4ZAzHUUjuR4upqMejtMTvL8wQtjAMFtaxEHuDMQr9hddaUpjfgYXonmuqYcKBavwLMZzK8sVwRMXEQhW6mGaacL6q4SkK7U1TzEdGzY1kqm5LdJQWwnuRGoGP2C2HP', -] - [[balance]] address = '5i9RZjT87TLa1BtWXRRoFy3FoMzFHiXT3GWasHdUaxuo3YapUKYeXXiY1yuAeKng2hmxxaYsGNhKhjyrE9KYTSE7' seed = 0xdead_beef diff --git a/rusk-recovery/config/singlenet.toml b/rusk-recovery/config/singlenet.toml index e908f6b692..9ad4b7be56 100644 --- a/rusk-recovery/config/singlenet.toml +++ b/rusk-recovery/config/singlenet.toml @@ -1,11 +1,3 @@ -[acl.stake] -owners = [ - '22p9MSeCwzrGtSff3TYPELufsGxU4oumgkHd4XqNTq5tuHmJ3aTPJErA7nF6ns4vqW295y3SXY9FdZd68bXP5q82AAEmCustZvD3mbb8K32Eawm3GNmUkzVLU7t24tCe5atj', -] -allowlist = [ - 'rm6jwcM9xQChnVeHYw6W8HP7kW3E8nejgs4XhmKoYspQnrZL5dDcQjVR5e2UmbyNNF4DJDRdZGdYLgJfZ3qQXuhSCL6UTDkcQ2QEf6RW3aCtfqQMKCFMNaBsfNrZuzrP23Z', -] - [[balance]] address = '5i9RZjT87TLa1BtWXRRoFy3FoMzFHiXT3GWasHdUaxuo3YapUKYeXXiY1yuAeKng2hmxxaYsGNhKhjyrE9KYTSE7' seed = 0xdead_beef diff --git a/rusk-recovery/config/testnet.toml b/rusk-recovery/config/testnet.toml index cffda8368c..947fa4f84b 100644 --- a/rusk-recovery/config/testnet.toml +++ b/rusk-recovery/config/testnet.toml @@ -1,110 +1,3 @@ -[acl.stake] -owners = [ - 'mvft6AXjR1mDtg1Qo3GzGBKZAvvxY1S6h41DSEPh9Ewj9GFR61rPQnjVaM1W9nqkHijRC2d5Yo4FSBwU8wf9eHeEJYXuMSrB7eJxvsY6HjCeDJ9pKfJLdjayAfrxEyudvx2', -] -allowlist = [ - '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', -] - [[balance]] address = '68UiBbsJ4PumJyVpS91VbffhKgq9p6QaLC8QCqzgLiKBX71mvCswmeViTHDsBJ3RMwsVcxBSkZ3HbjHAL9qCNxh' seed = 0xdead_beef diff --git a/rusk-recovery/config/testnet_remote.toml b/rusk-recovery/config/testnet_remote.toml index 014eedfc90..34147ec31b 100644 --- a/rusk-recovery/config/testnet_remote.toml +++ b/rusk-recovery/config/testnet_remote.toml @@ -1,5 +1,2 @@ base_state = "https://dusk-infra.ams3.digitaloceanspaces.com/rusk-state/piecrust-state-20230711" -[acl.stake] -owners = [] -allowlist = [] diff --git a/rusk-recovery/src/state.rs b/rusk-recovery/src/state.rs index 5e7539e3d4..a47aa7d392 100644 --- a/rusk-recovery/src/state.rs +++ b/rusk-recovery/src/state.rs @@ -7,7 +7,6 @@ use crate::Theme; use dusk_bls12_381::BlsScalar; -use dusk_bls12_381_sign::PublicKey as BlsPublicKey; use dusk_bytes::DeserializableSlice; use dusk_jubjub::JubJubScalar; use dusk_pki::PublicSpendKey; @@ -151,30 +150,6 @@ fn generate_stake_state( u64::MAX, ) .expect("stake to be inserted into the state"); - session - .call::<_, ()>( - STAKE_CONTRACT, - "insert_allowlist", - staker.address(), - u64::MAX, - ) - .expect("staker to be inserted into the allowlist"); - }); - snapshot.owners().for_each(|provisioner| { - session - .call::<_, ()>(STAKE_CONTRACT, "add_owner", provisioner, u64::MAX) - .expect("owner to be added into the state"); - }); - - snapshot.allowlist().for_each(|provisioner| { - session - .call::<_, ()>( - STAKE_CONTRACT, - "insert_allowlist", - provisioner, - u64::MAX, - ) - .expect("provisioner to be inserted into the allowlist"); }); let stake_balance: u64 = snapshot.stakes().map(|s| s.amount).sum(); @@ -250,14 +225,6 @@ fn generate_empty_state>( .call::<_, ()>(TRANSFER_CONTRACT, "update_root", &(), u64::MAX) .expect("root to be updated after pushing genesis note"); - let owners = session - .call::<_, Vec>(STAKE_CONTRACT, "owners", &(), u64::MAX) - .expect("Querying the stake owners should succeed"); - assert!( - owners.data.is_empty(), - "Genesis stake should have no owners" - ); - session .call::<_, ()>(LICENSE_CONTRACT, "request_license", &(), u64::MAX) .expect("license contract request license method should succeed"); diff --git a/rusk-recovery/src/state/snapshot.rs b/rusk-recovery/src/state/snapshot.rs index 8a71a1aa98..c61d2cbfbe 100644 --- a/rusk-recovery/src/state/snapshot.rs +++ b/rusk-recovery/src/state/snapshot.rs @@ -6,19 +6,16 @@ use std::fmt::Debug; -use dusk_bls12_381_sign::PublicKey as BlsPublicKey; use dusk_bytes::Serializable; use dusk_pki::PublicSpendKey; use rusk_abi::dusk::Dusk; use serde_derive::{Deserialize, Serialize}; -mod acl; mod governance; mod stake; mod wrapper; use crate::state; -use acl::Acl; pub use stake::GenesisStake; use wrapper::Wrapper; @@ -41,7 +38,6 @@ impl Balance { #[derive(Serialize, Deserialize, Default, PartialEq, Eq)] pub struct Snapshot { base_state: Option, - acl: Acl, owner: Option>, // This "serde skip" workaround seems needed as per https://github.com/toml-rs/toml-rs/issues/384 @@ -80,16 +76,6 @@ impl Snapshot { self.owner.as_ref().unwrap_or(&dusk).to_bytes() } - /// Returns an iterator of the owners of the staking contract - pub fn owners(&self) -> impl Iterator { - self.acl.stake.owners.iter().map(|pk| &**pk) - } - - /// Returns an iterator of the allowed staking addresses - pub fn allowlist(&self) -> impl Iterator { - self.acl.stake.allowlist.iter().map(|pk| &**pk) - } - pub fn base_state(&self) -> Option<&str> { self.base_state.as_deref() } @@ -118,11 +104,6 @@ mod tests { fn testnet_toml() -> Result<(), Box> { let testnet = testnet_from_file()?; - assert_eq!( - testnet.owner(), - (*state::DUSK_KEY).to_bytes(), - "Testnet owner must be dusk" - ); testnet .balance .iter() diff --git a/rusk-recovery/src/state/snapshot/acl.rs b/rusk-recovery/src/state/snapshot/acl.rs deleted file mode 100644 index fdadf20e5d..0000000000 --- a/rusk-recovery/src/state/snapshot/acl.rs +++ /dev/null @@ -1,22 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// Copyright (c) DUSK NETWORK. All rights reserved. - -use dusk_bls12_381_sign::PublicKey as BlsPublicKey; -use dusk_bytes::Serializable; -use serde_derive::{Deserialize, Serialize}; - -use super::Wrapper; - -#[derive(Serialize, Deserialize, Default, PartialEq, Eq)] -pub(super) struct Acl { - pub(super) stake: Users, -} - -#[derive(Serialize, Deserialize, Default, PartialEq, Eq)] -pub(super) struct Users { - pub(super) owners: Vec>, - pub(super) allowlist: Vec>, -} From 5d239fc8850d4bee9ef4b521ea897beb161ca53a Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Mon, 15 Jan 2024 12:47:25 +0100 Subject: [PATCH 02/22] examples: remove allowlist --- examples/genesis.toml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/examples/genesis.toml b/examples/genesis.toml index de976e5db8..56e00f13f8 100644 --- a/examples/genesis.toml +++ b/examples/genesis.toml @@ -1,11 +1,3 @@ -[acl.stake] -owners = [ - 'oCqYsUMRqpRn2kSabH52Gt6FQCwH5JXj5MtRdYVtjMSJ73AFvdbPf98p3gz98fQwNy9ZBiDem6m9BivzURKFSKLYWP3N9JahSPZs9PnZ996P18rTGAjQTNFsxtbrKx79yWu', -] -allowlist = [ - 'oCqYsUMRqpRn2kSabH52Gt6FQCwH5JXj5MtRdYVtjMSJ73AFvdbPf98p3gz98fQwNy9ZBiDem6m9BivzURKFSKLYWP3N9JahSPZs9PnZ996P18rTGAjQTNFsxtbrKx79yWu', -] - [[balance]] address = '4ZH3oyfTuMHyWD1Rp4e7QKp5yK6wLrWvxHneufAiYBAjvereFvfjtDvTbBcZN5ZCsaoMo49s1LKPTwGpowik6QJG' seed = 0xdead_beef From 16b2bed932c2993de9ff0d22e63ddb6df8845c0f Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Mon, 15 Jan 2024 12:31:34 +0100 Subject: [PATCH 03/22] stake-contract: remove allowlist --- contracts/stake/src/lib.rs | 39 -------- contracts/stake/src/state.rs | 80 +-------------- contracts/stake/tests/stake.rs | 178 +-------------------------------- 3 files changed, 5 insertions(+), 292 deletions(-) diff --git a/contracts/stake/src/lib.rs b/contracts/stake/src/lib.rs index c4e3143f61..7246de9971 100644 --- a/contracts/stake/src/lib.rs +++ b/contracts/stake/src/lib.rs @@ -52,14 +52,6 @@ unsafe fn withdraw(arg_len: u32) -> u32 { }) } -#[no_mangle] -unsafe fn allow(arg_len: u32) -> u32 { - rusk_abi::wrap_call(arg_len, |arg| { - assert_transfer_caller(); - STATE.allow(arg) - }) -} - // Queries #[no_mangle] @@ -67,21 +59,6 @@ unsafe fn get_stake(arg_len: u32) -> u32 { rusk_abi::wrap_call(arg_len, |pk: PublicKey| STATE.get_stake(&pk).cloned()) } -#[no_mangle] -unsafe fn allowlist(arg_len: u32) -> u32 { - rusk_abi::wrap_call(arg_len, |_: ()| STATE.stakers_allowlist()) -} - -#[no_mangle] -unsafe fn is_allowlisted(arg_len: u32) -> u32 { - rusk_abi::wrap_call(arg_len, |pk| STATE.is_allowlisted(&pk)) -} - -#[no_mangle] -unsafe fn owners(arg_len: u32) -> u32 { - rusk_abi::wrap_call(arg_len, |_: ()| STATE.owners()) -} - // "Feeder" queries #[no_mangle] @@ -99,14 +76,6 @@ unsafe fn insert_stake(arg_len: u32) -> u32 { }) } -#[no_mangle] -unsafe fn insert_allowlist(arg_len: u32) -> u32 { - rusk_abi::wrap_call(arg_len, |pk| { - assert_external_caller(); - STATE.insert_allowlist(pk); - }) -} - #[no_mangle] unsafe fn reward(arg_len: u32) -> u32 { rusk_abi::wrap_call(arg_len, |(pk, value)| { @@ -115,14 +84,6 @@ unsafe fn reward(arg_len: u32) -> u32 { }) } -#[no_mangle] -unsafe fn add_owner(arg_len: u32) -> u32 { - rusk_abi::wrap_call(arg_len, |pk| { - assert_external_caller(); - STATE.add_owner(pk); - }) -} - /// Asserts the call is made via the transfer contract. /// /// # Panics diff --git a/contracts/stake/src/state.rs b/contracts/stake/src/state.rs index dcad4a49da..d28efb0ee9 100644 --- a/contracts/stake/src/state.rs +++ b/contracts/stake/src/state.rs @@ -6,8 +6,7 @@ use crate::*; -use alloc::collections::{BTreeMap, BTreeSet}; -use alloc::vec::Vec; +use alloc::collections::BTreeMap; use dusk_bls12_381_sign::PublicKey; use dusk_bytes::Serializable; @@ -27,14 +26,12 @@ use transfer_contract_types::*; #[derive(Debug, Default, Clone)] pub struct StakeState { stakes: BTreeMap<[u8; PublicKey::SIZE], StakeData>, - owners: BTreeSet<[u8; PublicKey::SIZE]>, } impl StakeState { pub const fn new() -> Self { Self { stakes: BTreeMap::new(), - owners: BTreeSet::new(), } } @@ -44,9 +41,7 @@ impl StakeState { } // allot a stake to the given key and increment the signature counter - let loaded_stake = self - .load_stake_mut(&stake.public_key) - .expect("The address is not allowed"); + let loaded_stake = self.load_or_create_stake_mut(&stake.public_key); let counter = loaded_stake.counter(); @@ -155,32 +150,6 @@ impl StakeState { .expect("Minting a reward note should succeed"); } - pub fn allow(&mut self, allow: Allow) { - if self.is_allowlisted(&allow.public_key) { - panic!("Address already allowed!"); - } - - if !self.is_owner(&allow.owner) { - panic!("Can only be called by a contract owner!"); - } - - // increment the signature counter - let owner_stake = self.load_or_create_stake_mut(&allow.owner); - - let owner_counter = owner_stake.counter(); - owner_stake.increment_counter(); - - // verify signature - let digest = - allow_signature_message(owner_counter, &allow.public_key).to_vec(); - - if !rusk_abi::verify_bls(digest, allow.owner, allow.signature) { - panic!("Invalid signature!"); - } - - self.insert_allowlist(allow.public_key); - } - /// Gets a reference to a stake. pub fn get_stake(&self, key: &PublicKey) -> Option<&StakeData> { self.stakes.get(&key.to_bytes()) @@ -214,14 +183,6 @@ impl StakeState { self.stakes.get_mut(&pk.to_bytes()).unwrap() } - /// Gets a mutable reference to the stake of a given key. - pub(crate) fn load_stake_mut( - &mut self, - pk: &PublicKey, - ) -> Option<&mut StakeData> { - self.stakes.get_mut(&pk.to_bytes()) - } - /// Rewards a `public_key` with the given `value`. If a stake does not exist /// in the map for the key one will be created. pub fn reward(&mut self, public_key: &PublicKey, value: u64) { @@ -237,41 +198,4 @@ impl StakeState { rusk_abi::feed((pk, stake_data)); } } - - /// Gets a vector of all allowlisted keys. - pub fn stakers_allowlist(&self) -> Vec { - self.stakes - .keys() - .map(|key| PublicKey::from_bytes(key).unwrap()) - .collect() - } - - /// Gets a vector of all owner keys. - pub fn owners(&self) -> Vec { - self.owners - .iter() - .map(|e| PublicKey::from_bytes(e).unwrap()) - .collect() - } - - pub fn add_owner(&mut self, owner: PublicKey) { - if !self.is_owner(&owner) { - self.owners.insert(owner.to_bytes()); - } - } - - pub fn is_owner(&self, owner: &PublicKey) -> bool { - self.owners.get(&owner.to_bytes()).is_some() - } - - pub fn insert_allowlist(&mut self, staker: PublicKey) { - if !self.is_allowlisted(&staker) { - let stake = StakeData::default(); - self.stakes.insert(staker.to_bytes(), stake); - } - } - - pub fn is_allowlisted(&self, staker: &PublicKey) -> bool { - self.stakes.get(&staker.to_bytes()).is_some() - } } diff --git a/contracts/stake/tests/stake.rs b/contracts/stake/tests/stake.rs index 09608c3d7e..b3a8945192 100644 --- a/contracts/stake/tests/stake.rs +++ b/contracts/stake/tests/stake.rs @@ -22,9 +22,8 @@ use rusk_abi::dusk::{dusk, LUX}; use rusk_abi::{CallReceipt, ContractData, ContractError, Error, Session, VM}; use rusk_abi::{STAKE_CONTRACT, TRANSFER_CONTRACT}; use stake_contract_types::{ - allow_signature_message, stake_signature_message, - unstake_signature_message, withdraw_signature_message, Allow, Stake, - StakeData, Unstake, Withdraw, + stake_signature_message, unstake_signature_message, + withdraw_signature_message, Stake, StakeData, Unstake, Withdraw, }; use transfer_circuits::{ CircuitInput, CircuitInputSignature, ExecuteCircuitOneTwo, @@ -48,7 +47,6 @@ fn instantiate( rng: &mut Rng, vm: &VM, psk: &PublicSpendKey, - pk: &PublicKey, ) -> Session { let transfer_bytecode = include_bytes!( "../../../target/wasm64-unknown-unknown/release/transfer_contract.wasm" @@ -89,15 +87,6 @@ fn instantiate( update_root(&mut session).expect("Updating the root should succeed"); - session - .call::<_, ()>(STAKE_CONTRACT, "add_owner", pk, POINT_LIMIT) - .expect("Inserting APK into owners list should suceeed"); - - // allow given public key to stake - session - .call::<_, ()>(STAKE_CONTRACT, "insert_allowlist", pk, POINT_LIMIT) - .expect("Inserting APK into allowlist should succeed"); - // sets the block height for all subsequent operations to 1 let base = session.commit().expect("Committing should succeed"); @@ -221,7 +210,7 @@ fn stake_withdraw_unstake() { let sk = SecretKey::random(rng); let pk = PublicKey::from(&sk); - let mut session = instantiate(rng, vm, &psk, &pk); + let mut session = instantiate(rng, vm, &psk); let leaves = leaves_from_height(&mut session, 0) .expect("Getting leaves in the given range should succeed"); @@ -827,164 +816,3 @@ fn stake_withdraw_unstake() { println!("UNSTAKE : {gas_spent} gas"); } - -#[test] -fn allow() { - const ALLOW_FEE: u64 = dusk(1.0); - - let rng = &mut StdRng::seed_from_u64(0xfeeb); - - let vm = &mut rusk_abi::new_ephemeral_vm() - .expect("Creating ephemeral VM should work"); - - let ssk = SecretSpendKey::random(rng); - // let vk = ssk.view_key(); - let psk = PublicSpendKey::from(&ssk); - - let sk = SecretKey::random(rng); - let pk = PublicKey::from(&sk); - - let allow_sk = SecretKey::random(rng); - let allow_pk = PublicKey::from(&allow_sk); - - let session = &mut instantiate(rng, vm, &psk, &pk); - - let leaves = leaves_from_height(session, 0) - .expect("Getting leaves in the given range should succeed"); - - assert_eq!(leaves.len(), 1, "There should be one note in the state"); - - let input_note = leaves[0].note; - let input_value = input_note - .value(None) - .expect("The value should be transparent"); - let input_blinder = input_note - .blinding_factor(None) - .expect("The blinder should be transparent"); - let input_nullifier = input_note.gen_nullifier(&ssk); - - let gas_limit = ALLOW_FEE; - let gas_price = LUX; - - // Since we're transferring value to a contract, a crossover is needed. Here - // we transfer half of the input note to the stake contract, so the - // crossover value is `input_value/2`. - let crossover_value = input_value / 2; - let crossover_blinder = JubJubScalar::random(rng); - - let (mut fee, crossover) = - Note::obfuscated(rng, &psk, crossover_value, crossover_blinder) - .try_into() - .expect("Getting a fee and a crossover should succeed"); - - fee.gas_limit = gas_limit; - fee.gas_price = gas_price; - - // The change note should have the value of the input note, minus what is - // maximally spent. - let change_value = input_value - crossover_value - gas_price * gas_limit; - let change_blinder = JubJubScalar::random(rng); - let change_note = Note::obfuscated(rng, &psk, change_value, change_blinder); - - // Fashion a Allow struct - let allow_digest = allow_signature_message(0, &allow_pk); - let allow_sig = sk.sign(&pk, &allow_digest); - - let allow = Allow { - public_key: allow_pk, - owner: pk, - signature: allow_sig, - }; - let allow_bytes = rkyv::to_bytes::<_, 2048>(&allow) - .expect("Should serialize Allow correctly") - .to_vec(); - - let call = Some(( - STAKE_CONTRACT.to_bytes(), - String::from("allow"), - allow_bytes, - )); - - // Compose the circuit. In this case we're using one input and one output. - let mut execute_circuit = ExecuteCircuitOneTwo::new(); - - execute_circuit.set_fee_crossover( - &fee, - &crossover, - crossover_value, - crossover_blinder, - ); - - execute_circuit - .add_output_with_data(change_note, change_value, change_blinder) - .expect("appending output should succeed"); - - let input_opening = opening(session, *input_note.pos()) - .expect("Querying the opening for the given position should succeed") - .expect("An opening should exist for a note in the tree"); - - // Generate pk_r_p - let sk_r = ssk.sk_r(input_note.stealth_address()); - let pk_r_p = GENERATOR_NUMS_EXTENDED * sk_r.as_ref(); - - // The transaction hash must be computed before signing - let anchor = - root(session).expect("Getting the anchor should be successful"); - - let tx_hash_input_bytes = Transaction::hash_input_bytes_from_components( - &[input_nullifier], - &[change_note], - &anchor, - &fee, - &Some(crossover), - &call, - ); - let tx_hash = rusk_abi::hash(tx_hash_input_bytes); - - execute_circuit.set_tx_hash(tx_hash); - - let circuit_input_signature = - CircuitInputSignature::sign(rng, &ssk, &input_note, tx_hash); - let circuit_input = CircuitInput::new( - input_opening, - input_note, - pk_r_p.into(), - input_value, - input_blinder, - input_nullifier, - circuit_input_signature, - ); - - execute_circuit - .add_input(circuit_input) - .expect("appending input should succeed"); - - let (prover_key, _) = prover_verifier("ExecuteCircuitOneTwo"); - let (execute_proof, _) = prover_key - .prove(rng, &execute_circuit) - .expect("Proving should be successful"); - - let tx = Transaction { - anchor, - nullifiers: vec![input_nullifier], - outputs: vec![change_note], - fee, - crossover: Some(crossover), - proof: execute_proof.to_bytes().to_vec(), - call, - }; - - let receipt = execute(session, tx).expect("Executing TX should succeed"); - let gas_spent = receipt.gas_spent; - receipt.data.expect("Executed TX should not error"); - update_root(session).expect("Updating the root should succeed"); - - println!("ALLOW : {gas_spent} gas"); - - let is_allowed: bool = session - .call(STAKE_CONTRACT, "is_allowlisted", &allow_pk, POINT_LIMIT) - .expect("Querying the allowlist should succeed") - .data; - - assert!(is_allowed, "The new public key should now be allowed"); -} From 36007e7e42756d536b102061888e728b4b7ae1c7 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Mon, 15 Jan 2024 15:23:50 +0100 Subject: [PATCH 04/22] stake-type: remove allow related structs --- contracts/stake-types/src/lib.rs | 12 ------------ contracts/stake-types/src/sig.rs | 16 ---------------- 2 files changed, 28 deletions(-) diff --git a/contracts/stake-types/src/lib.rs b/contracts/stake-types/src/lib.rs index c94e9694e2..b97e2485ed 100644 --- a/contracts/stake-types/src/lib.rs +++ b/contracts/stake-types/src/lib.rs @@ -67,15 +67,3 @@ pub struct Withdraw { /// A nonce to prevent replay. pub nonce: BlsScalar, } - -/// Allow a public key to stake. -#[derive(Debug, Clone, Archive, Deserialize, Serialize)] -#[archive_attr(derive(CheckBytes))] -pub struct Allow { - /// The public key to allow staking to. - pub public_key: PublicKey, - /// The "owner" of the smart contract. - pub owner: PublicKey, - /// Signature of the `owner` key. - pub signature: Signature, -} diff --git a/contracts/stake-types/src/sig.rs b/contracts/stake-types/src/sig.rs index ebe84bf4bb..246f76495d 100644 --- a/contracts/stake-types/src/sig.rs +++ b/contracts/stake-types/src/sig.rs @@ -9,29 +9,13 @@ use alloc::vec::Vec; use dusk_bls12_381::BlsScalar; -use dusk_bls12_381_sign::PublicKey; use dusk_bytes::Serializable; use dusk_pki::StealthAddress; -const ALLOW_MESSAGE_SIZE: usize = u64::SIZE + PublicKey::SIZE; const STAKE_MESSAGE_SIZE: usize = u64::SIZE + u64::SIZE; const WITHDRAW_MESSAGE_SIZE: usize = u64::SIZE + StealthAddress::SIZE + BlsScalar::SIZE; -/// Signature message used for [`Allow`]. -#[must_use] -pub fn allow_signature_message( - counter: u64, - staker: &PublicKey, -) -> [u8; ALLOW_MESSAGE_SIZE] { - let mut bytes = [0u8; ALLOW_MESSAGE_SIZE]; - - bytes[..u64::SIZE].copy_from_slice(&counter.to_bytes()); - bytes[u64::SIZE..].copy_from_slice(&staker.to_bytes()); - - bytes -} - /// Return the digest to be signed in the `stake` function of the stake /// contract. #[must_use] From de1be2ea9df4c3d24741fa062d1644fde91f22ac Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 10:22:04 +0100 Subject: [PATCH 05/22] rusk: remove allowlist --- rusk/src/lib/lib.rs | 10 ---------- rusk/tests/config/gas-behavior.toml | 4 ---- rusk/tests/config/multi_transfer.toml | 4 ---- rusk/tests/config/rusk-state.toml | 4 ---- rusk/tests/config/stake.toml | 8 -------- rusk/tests/config/transfer.toml | 4 ---- rusk/tests/config/unspendable.toml | 4 ---- 7 files changed, 38 deletions(-) diff --git a/rusk/src/lib/lib.rs b/rusk/src/lib/lib.rs index 3e0405d4c0..dd115b298b 100644 --- a/rusk/src/lib/lib.rs +++ b/rusk/src/lib/lib.rs @@ -426,16 +426,6 @@ impl Rusk { .collect()) } - /// Returns the keys allowed to stake. - pub fn stake_allowlist(&self) -> Result> { - self.query(STAKE_CONTRACT, "allowlist", &()) - } - - /// Returns the keys that own the stake contract. - pub fn stake_owners(&self) -> Result> { - self.query(STAKE_CONTRACT, "owners", &()) - } - pub fn query_raw( &self, contract_id: ContractId, diff --git a/rusk/tests/config/gas-behavior.toml b/rusk/tests/config/gas-behavior.toml index 6825344391..984acdf5b4 100644 --- a/rusk/tests/config/gas-behavior.toml +++ b/rusk/tests/config/gas-behavior.toml @@ -1,7 +1,3 @@ -[acl.stake] -owners = [] -allowlist = [] - [[balance]] address = "ivmscertKgRyX8wNMJJsQcSVEyPsfSMUQXSAgeAPQXsndqFq9Pmknzhm61QvcEEdxPaGgxDS4RHpb6KKccrnSKN" seed = 57005 diff --git a/rusk/tests/config/multi_transfer.toml b/rusk/tests/config/multi_transfer.toml index 39ae1c554e..5ab88e2533 100644 --- a/rusk/tests/config/multi_transfer.toml +++ b/rusk/tests/config/multi_transfer.toml @@ -1,7 +1,3 @@ -[acl.stake] -owners = [] -allowlist = [] - [[balance]] address = "ivmscertKgRyX8wNMJJsQcSVEyPsfSMUQXSAgeAPQXsndqFq9Pmknzhm61QvcEEdxPaGgxDS4RHpb6KKccrnSKN" seed = 57005 diff --git a/rusk/tests/config/rusk-state.toml b/rusk/tests/config/rusk-state.toml index 1c301d9a00..46ea313173 100644 --- a/rusk/tests/config/rusk-state.toml +++ b/rusk/tests/config/rusk-state.toml @@ -1,7 +1,3 @@ -[acl.stake] -owners = [] -allowlist = [] - [[balance]] address = "29ENJqLtHJRSZdghZxiGuzQTe3F4t1bv35zM7mEMS142e5QdxkknokMALrBEFUnyav9NfeXLNvfjx4sfTtJN9WCB" notes = [10_000_000_000] diff --git a/rusk/tests/config/stake.toml b/rusk/tests/config/stake.toml index f3650e7e0f..91771b1607 100644 --- a/rusk/tests/config/stake.toml +++ b/rusk/tests/config/stake.toml @@ -1,11 +1,3 @@ -[acl.stake] -owners = [] -allowlist = [ - "qe1FbZxf6YaCAeFNSvL1G82cBhG4Q4gBf4vKYo527Vws3b23jdbBuzKSFsdUHnZeBgsTnyNJLkApEpRyJw87sdzR9g9iESJrG5ZgpCs9jq88m6d4qMY5txGpaXskRQmkzE3", - "25omWWRyfcMjYNbQZVyc3rypYLi8UqZuthoJHqbCEriRX3z2EmnBaXWZLFL2NvzvDnkoYoHLGiSYQpmupNJj1sSdWNstqzfFEpiqvSNYw7gqvoEiU9FsEHUMG1ZyG3XgL8Rv", - "mqL8WTruQUzafU8Q4bSFqTLMhHmB97DAGow73KRpDkDik5vqMD9EpGvyZc2j3TFaEh8hc6g3LJ5X3ox18HDDoVDj8MKaHPzphvdgyG4XmsFEafAiym6kqRPmB14QNRvkEK4", -] - [[balance]] address = "ivmscertKgRyX8wNMJJsQcSVEyPsfSMUQXSAgeAPQXsndqFq9Pmknzhm61QvcEEdxPaGgxDS4RHpb6KKccrnSKN" seed = 57005 diff --git a/rusk/tests/config/transfer.toml b/rusk/tests/config/transfer.toml index 61dbc64fe4..42d2e378c8 100644 --- a/rusk/tests/config/transfer.toml +++ b/rusk/tests/config/transfer.toml @@ -1,7 +1,3 @@ -[acl.stake] -owners = [] -allowlist = [] - [[balance]] address = "ivmscertKgRyX8wNMJJsQcSVEyPsfSMUQXSAgeAPQXsndqFq9Pmknzhm61QvcEEdxPaGgxDS4RHpb6KKccrnSKN" seed = 57005 diff --git a/rusk/tests/config/unspendable.toml b/rusk/tests/config/unspendable.toml index 39ae1c554e..5ab88e2533 100644 --- a/rusk/tests/config/unspendable.toml +++ b/rusk/tests/config/unspendable.toml @@ -1,7 +1,3 @@ -[acl.stake] -owners = [] -allowlist = [] - [[balance]] address = "ivmscertKgRyX8wNMJJsQcSVEyPsfSMUQXSAgeAPQXsndqFq9Pmknzhm61QvcEEdxPaGgxDS4RHpb6KKccrnSKN" seed = 57005 From b6f16b5b0500c5a2dd8f2f819cfa5973c578b3d7 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Thu, 18 Jan 2024 10:57:36 +0100 Subject: [PATCH 06/22] rusk: remove deprecated tests --- rusk/tests/config/state_service.toml | 155 ---------------- rusk/tests/services/mod.rs | 2 - rusk/tests/services/prover_service.rs | 243 -------------------------- 3 files changed, 400 deletions(-) delete mode 100644 rusk/tests/config/state_service.toml delete mode 100644 rusk/tests/services/prover_service.rs diff --git a/rusk/tests/config/state_service.toml b/rusk/tests/config/state_service.toml deleted file mode 100644 index 518cba61e1..0000000000 --- a/rusk/tests/config/state_service.toml +++ /dev/null @@ -1,155 +0,0 @@ -[acl.stake] -owners = [] -allowlist = [ - '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', -] - -[[stake]] -address = "21aLx16qNEyU14aCGzacr8efbwx7bEytxa2rT71XB24zGZrb6Y398ebg38My7aQikamhpdYzphUAMHfPhH3BWvwsG2G655Dr8gwmQLKH9nERiGmD79Jewkn4ZkMeptfYBMiS" -amount = 1_000_000_000_000 - -[[stake]] -address = "23wQuNYp2dL9BcnFNnizSBnxjhHerR6WjYFNLS6qmM3KNvf1Gia27u3Vkjg88jCwvwwTSHWpEDCX9NojejCKZ25HvZLaDeLrfkL2wCXFXz5GT44QGFyQqM9uN2taNjPVBTkN" -amount = 1_000_000_000_000 - -[[stake]] -address = "24ED5zGePkU2Tfpp3X1NxSFhhgNCYBakorBJCXEhwVeWwB341XY9Xk2cJ5uhQ8TAHXGyJAE4EZakhWFkPy1vRr7moR8A9q47P5kkTzo7pWqggog5Lpjvkko2FJwKNJJRG9mc" -amount = 1_000_000_000_000 - -[[stake]] -address = "uqMkRzvvPL3V3uG2AsZ4M31G4d2tkCRVFEcaeCt2AQpKcFKb9x9Bxa7xTYQsErRp4TsJP5DWyWsPLimTMvGqXXGJEh3aeCYemzD1rwNBQ3fbfD6YHt8T9cLH7MjeAQt9RQv" -amount = 1_000_000_000_000 - -[[stake]] -address = "qFDZZfE9SiADC9s4wAy9mdFHHf4FhG9qZwDd7zx4SAu1s7kjoxgCbMDe6kN2J3QUFE2PPvBJttRhhz8nsWBKL4kRxWwEda2TY7kYKkkBF8NCQiquvB39cqb9Qwi2QHXHcWD" -amount = 1_000_000_000_000 - -[[stake]] -address = "xSZi1pVKSytq9kyGNVkx5hPiXefz8E5Gt7bVUUGosa4Fpe3KusNUp7aVKQcan45kJQL53KKWV64dUkveA83EpRz5ppgNLrNsHwsxJTVGdWsHAcwufhmvSuzr9FSPFCSrgH3" -amount = 1_000_000_000_000 - -[[stake]] -address = "23UKWLdRNPRnm9bqkZPiX5rm4GDmfC8QkpL6vKYSVrgZccbBC7Rd2wppzY32LxoPZRsCjYNYYDZVBybqLiHL2LvGSxKHS6rokWAsS4aZ6ikmMpQv6KQWhCRxh89j1HPeeBAb" -amount = 1_000_000_000_000 - -[[stake]] -address = "24kKm741oCpQti9uWCStQpHHwvS9wR5iBy3dUtdEodVCDhiuUbvPrAbtL3ByaUFCBjhReL6torQvS9ZknbrooV5q5D4xJkUoM3nzjGK6YaryqRwPVKYqnTsDEYBanWKETbEc" -amount = 1_000_000_000_000 - -[[stake]] -address = "or3u1YxTwqsDYpJoJvSTaAPUZywiXsvZasKQdvuy5giBFgxhKCUFRTzRBtgCFRpTapSPNNPG9tbmytTtYWyXNKJBYw46z5P213AqbknGhgTxVg4xsHbosauSwUdU5pRZvkU" -amount = 1_000_000_000_000 - -[[balance]] -address = "ivmscertKgRyX8wNMJJsQcSVEyPsfSMUQXSAgeAPQXsndqFq9Pmknzhm61QvcEEdxPaGgxDS4RHpb6KKccrnSKN" -seed = 57005 -notes = [10_000_000_000] - -[[balance]] -address = "3MoVQ6VfGNu8fJ5GeHPRDVUfxcsDEmGXpWhvKhXY7F2dKCp7QWRw8RqPcbuJGdRqeTtxpuiwETnGAJLnhT4Kq4e8" -seed = 57005 -notes = [10_000_000_000] - -[[balance]] -address = "4RyaodGmN8MyUDmpRrtRxJJhrVW2HsY2ycRUnRUXR97JCN1GHraQT9Ygb8yYo7oKzyZg2EXXCGkHBwoeNb96BKtQ" -seed = 57005 -notes = [10_000_000_000] diff --git a/rusk/tests/services/mod.rs b/rusk/tests/services/mod.rs index adc4136595..1b97082da5 100644 --- a/rusk/tests/services/mod.rs +++ b/rusk/tests/services/mod.rs @@ -6,9 +6,7 @@ pub mod gas_behavior; pub mod multi_transfer; -// pub mod prover_service; pub mod stake; -// pub mod state_service; pub mod transfer; pub mod unspendable; diff --git a/rusk/tests/services/prover_service.rs b/rusk/tests/services/prover_service.rs deleted file mode 100644 index cdad806f78..0000000000 --- a/rusk/tests/services/prover_service.rs +++ /dev/null @@ -1,243 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. -// -// Copyright (c) DUSK NETWORK. All rights reserved. - -use crate::common::*; -use dusk_bls12_381::BlsScalar; -use dusk_bls12_381_sign::PublicKey; -use dusk_bytes::DeserializableSlice; -use dusk_pki::{PublicSpendKey, ViewKey}; -use dusk_plonk::prelude::*; -use dusk_schnorr::Signature; -use dusk_wallet_core::{ - ProverClient as WalletProverClient, StakeInfo, StateClient, Store, - Transaction, UnprovenTransaction, Wallet, POSEIDON_TREE_DEPTH, -}; -use parking_lot::Mutex; -use phoenix_core::{Crossover, Fee}; -use phoenix_core::{Note, NoteType}; -use poseidon_merkle::{Item, Opening as PoseidonOpening, Tree}; -use rand::{CryptoRng, RngCore}; -use rusk::services::prover::{ProverServer, RuskProver}; -use rusk_schema::prover_client::ProverClient; -use rusk_schema::ExecuteProverRequest; -use tonic::transport::Channel; -use tonic::transport::Server; - -/// Create a new wallet meant for tests. It includes a client that will always -/// return a random anchor (same every time), and the default opening. -/// -/// The number of notes available is determined by `note_values`. -fn mock_wallet( - rng: &mut Rng, - client: ProverClient, - note_values: &[u64], -) -> Wallet { - let store = TestStore::new(rng); - let psk = store.retrieve_ssk(0).unwrap().public_spend_key(); - - let notes = new_notes(rng, &psk, note_values); - let anchor = BlsScalar::random(&mut *rng); - - const POS: u64 = 42; - let mut tree = Tree::new(); - tree.insert( - POS, - Item { - hash: BlsScalar::zero(), - data: (), - }, - ); - let opening = tree.opening(POS).unwrap(); - - let node = TestWalletProverClient::new(client); - let state = TestStateClient::new(notes, anchor, opening, vec![]); - - Wallet::new(store, state, node) -} - -/// Returns obfuscated notes with the given value. -fn new_notes( - rng: &mut Rng, - psk: &PublicSpendKey, - note_values: &[u64], -) -> Vec { - note_values - .iter() - .map(|val| { - let blinder = JubJubScalar::random(rng); - Note::new(rng, NoteType::Obfuscated, psk, *val, blinder) - }) - .collect() -} - -/// An in-memory seed store. -#[derive(Debug)] -pub struct TestStore { - seed: [u8; 64], -} - -impl TestStore { - /// Instantiate a new in-memory store with a random seed. - fn new(rng: &mut Rng) -> Self { - let mut seed = [0; 64]; - rng.fill_bytes(&mut seed); - Self { seed } - } -} - -impl Store for TestStore { - type Error = (); - - fn get_seed(&self) -> Result<[u8; 64], Self::Error> { - Ok(self.seed) - } -} - -#[derive(Debug)] -struct TestWalletProverClient { - client: Mutex>, -} - -impl TestWalletProverClient { - fn new(client: ProverClient) -> Self { - Self { - client: Mutex::new(client), - } - } -} - -impl WalletProverClient for TestWalletProverClient { - type Error = (); - - /// Requests that a node prove the given transaction and later propagates it - fn compute_proof_and_propagate( - &self, - utx: &UnprovenTransaction, - ) -> Result { - let utx_bytes = utx.to_var_bytes(); - let request = - tonic::Request::new(ExecuteProverRequest { utx: utx_bytes }); - - let mut prover = self.client.lock(); - let response = prover - .prove_execute(request) - .wait() - .expect("successful call") - .into_inner(); - - let proof = Proof::from_slice(&response.proof).expect("valid proof"); - let tx = utx.clone().prove(proof); - - Ok(tx) - } - - /// Requests an STCT proof. - fn request_stct_proof( - &self, - _fee: &Fee, - _crossover: &Crossover, - _value: u64, - _blinder: JubJubScalar, - _address: BlsScalar, - _signature: Signature, - ) -> Result { - unimplemented!(); - } - - /// Request a WFCT proof. - fn request_wfct_proof( - &self, - _commitment: JubJubAffine, - _value: u64, - _blinder: JubJubScalar, - ) -> Result { - unimplemented!(); - } -} - -/// An in-memory seed store. -#[derive(Debug)] -pub struct TestStateClient { - notes: Vec, - anchor: BlsScalar, - opening: PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4>, - nullifiers: Vec, -} - -impl TestStateClient { - fn new( - notes: Vec, - anchor: BlsScalar, - opening: PoseidonOpening<(), POSEIDON_TREE_DEPTH, 4>, - nullifiers: Vec, - ) -> Self { - Self { - notes, - anchor, - opening, - nullifiers, - } - } -} - -impl StateClient for TestStateClient { - type Error = (); - - fn fetch_notes( - &self, - _: &ViewKey, - ) -> Result, Self::Error> { - Ok(self.notes.iter().map(|note| (note.clone(), 0)).collect()) - } - - fn fetch_anchor(&self) -> Result { - Ok(self.anchor) - } - - fn fetch_existing_nullifiers( - &self, - _nullifiers: &[BlsScalar], - ) -> Result, Self::Error> { - Ok(self.nullifiers.clone()) - } - - fn fetch_opening( - &self, - _: &Note, - ) -> Result, Self::Error> { - Ok(self.opening.clone()) - } - - fn fetch_stake(&self, _pk: &PublicKey) -> Result { - unimplemented!(); - } -} - -#[ignore] -#[tokio::test(flavor = "multi_thread")] -pub async fn prover_walkthrough_uds() { - let (channel, incoming) = setup().await; - - tokio::spawn(async move { - Server::builder() - .add_service(ProverServer::new(RuskProver::default())) - .serve_with_incoming(incoming) - .await - }); - - let mut rng = rand::thread_rng(); - let client = ProverClient::new(channel); - - let wallet = mock_wallet(&mut rng, client, &[5000, 2500, 2500]); - - let send_psk = wallet.public_spend_key(0).unwrap(); - let recv_psk = wallet.public_spend_key(1).unwrap(); - - let ref_id = BlsScalar::random(&mut rng); - let _ = wallet - .transfer(&mut rng, 0, &send_psk, &recv_psk, 100, 100, 1, ref_id) - .expect("Transaction creation to be successful"); -} From e230cc72abc7b751875d96aa944844ae6d90aaf0 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Mon, 15 Jan 2024 17:02:17 +0100 Subject: [PATCH 07/22] transfer-contract: add `sub_module_balance` callable by stake-contract --- contracts/transfer/src/lib.rs | 14 +++++++++++++- contracts/transfer/src/state.rs | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/contracts/transfer/src/lib.rs b/contracts/transfer/src/lib.rs index 3d6cc02f57..a12b0593c8 100644 --- a/contracts/transfer/src/lib.rs +++ b/contracts/transfer/src/lib.rs @@ -15,7 +15,7 @@ mod error; mod state; mod tree; -use rusk_abi::ContractId; +use rusk_abi::{ContractId, STAKE_CONTRACT}; use state::TransferState; #[no_mangle] @@ -163,6 +163,18 @@ unsafe fn add_module_balance(arg_len: u32) -> u32 { }) } +#[no_mangle] +unsafe fn sub_module_balance(arg_len: u32) -> u32 { + rusk_abi::wrap_call(arg_len, |(module, value)| { + if rusk_abi::caller() != STAKE_CONTRACT { + panic!("Can only be called by the stake contract!") + } + STATE + .sub_balance(&module, value) + .expect("Cannot subtract balance") + }) +} + /// Asserts the call is made "from the outside", meaning that it's not an /// inter-contract call. /// diff --git a/contracts/transfer/src/state.rs b/contracts/transfer/src/state.rs index 764bbd9774..c69b3e36c2 100644 --- a/contracts/transfer/src/state.rs +++ b/contracts/transfer/src/state.rs @@ -523,7 +523,7 @@ impl TransferState { self.push_note(block_height, note) } - fn sub_balance( + pub(crate) fn sub_balance( &mut self, address: &ContractId, value: u64, From 47a898c1f79072c57ba4c406af6b92fffaac158c Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Mon, 15 Jan 2024 12:12:43 +0100 Subject: [PATCH 08/22] stake-contract: add slash calls - Add `slash` management call - Add `slashed_amount` query --- contracts/stake/src/lib.rs | 13 +++++++++ contracts/stake/src/state.rs | 52 +++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/contracts/stake/src/lib.rs b/contracts/stake/src/lib.rs index 7246de9971..cbb5e6c4de 100644 --- a/contracts/stake/src/lib.rs +++ b/contracts/stake/src/lib.rs @@ -59,6 +59,11 @@ unsafe fn get_stake(arg_len: u32) -> u32 { rusk_abi::wrap_call(arg_len, |pk: PublicKey| STATE.get_stake(&pk).cloned()) } +#[no_mangle] +unsafe fn slashed_amount(arg_len: u32) -> u32 { + rusk_abi::wrap_call(arg_len, |_: ()| STATE.slashed_amount()) +} + // "Feeder" queries #[no_mangle] @@ -84,6 +89,14 @@ unsafe fn reward(arg_len: u32) -> u32 { }) } +#[no_mangle] +unsafe fn slash(arg_len: u32) -> u32 { + rusk_abi::wrap_call(arg_len, |(pk, value)| { + assert_external_caller(); + STATE.slash(&pk, value); + }) +} + /// Asserts the call is made via the transfer contract. /// /// # Panics diff --git a/contracts/stake/src/state.rs b/contracts/stake/src/state.rs index d28efb0ee9..15dbde371a 100644 --- a/contracts/stake/src/state.rs +++ b/contracts/stake/src/state.rs @@ -4,6 +4,8 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +use core::cmp::min; + use crate::*; use alloc::collections::BTreeMap; @@ -11,7 +13,7 @@ use alloc::collections::BTreeMap; use dusk_bls12_381_sign::PublicKey; use dusk_bytes::Serializable; -use rusk_abi::TRANSFER_CONTRACT; +use rusk_abi::{STAKE_CONTRACT, TRANSFER_CONTRACT}; use stake_contract_types::*; use transfer_contract_types::*; @@ -26,12 +28,14 @@ use transfer_contract_types::*; #[derive(Debug, Default, Clone)] pub struct StakeState { stakes: BTreeMap<[u8; PublicKey::SIZE], StakeData>, + slashed_amount: u64, } impl StakeState { pub const fn new() -> Self { Self { stakes: BTreeMap::new(), + slashed_amount: 0u64, } } @@ -190,6 +194,52 @@ impl StakeState { stake.increase_reward(value); } + /// Total amount slashed from the genesis + pub fn slashed_amount(&self) -> u64 { + self.slashed_amount + } + + /// Slash the given `to_subtract` amount from a `public_key` stake (if + /// any). Firstly the amount is subtracted from the reward, if that's + /// not enough the stake amount is touched. + pub fn slash(&mut self, public_key: &PublicKey, to_slash: u64) { + let stake = self + .get_stake_mut(public_key) + .expect("The stake to slash should exist"); + + let staker_funds = stake.reward + stake.amount.unwrap_or_default().0; + + // Cannot slash more than the staker funds + let to_slash = min(to_slash, staker_funds); + + if to_slash <= stake.reward { + stake.reward -= to_slash; + } else { + // Deplete reward and update `to_slash` with the remaining amount to + // slash from the stake amount. + let remaining_slash = to_slash - stake.reward; + stake.reward = 0; + let (stake_amt, _) = stake + .amount + .as_mut() + .expect("Trying to slash more than slashable_amount"); + + *stake_amt -= remaining_slash; + + // Update the module balance to reflect the change in the amount + // withdrawable from the contract + let _: bool = rusk_abi::call( + TRANSFER_CONTRACT, + "sub_module_balance", + &(STAKE_CONTRACT, remaining_slash), + ) + .expect("Subtracting balance should succeed"); + } + + // Update the total slashed amount + self.slashed_amount += to_slash; + } + /// Feeds the host with the stakes. pub fn stakes(&self) { for (k, v) in self.stakes.iter() { From ba411424881bdfbeedbd419b032715349ebb8bad Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Mon, 15 Jan 2024 17:14:53 +0100 Subject: [PATCH 09/22] rusk: change `rusk::provisioners` to filter out slashed stakes --- rusk/src/lib/http/rusk.rs | 3 +-- rusk/src/lib/lib.rs | 16 +++++++--------- rusk/src/lib/vm.rs | 9 +++++++-- rusk/tests/services/stake.rs | 3 +-- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/rusk/src/lib/http/rusk.rs b/rusk/src/lib/http/rusk.rs index 79c8375eaf..ed00f028c4 100644 --- a/rusk/src/lib/http/rusk.rs +++ b/rusk/src/lib/http/rusk.rs @@ -95,8 +95,7 @@ impl Rusk { fn get_provisioners(&self) -> anyhow::Result { let prov: Vec<_> = self .provisioners(None) - .unwrap() - .iter() + .expect("Cannot query state for provisioners") .filter_map(|(key, stake)| { let key = bs58::encode(key.to_bytes()).into_string(); let (amount, eligibility) = stake.amount.unwrap_or_default(); diff --git a/rusk/src/lib/lib.rs b/rusk/src/lib/lib.rs index dd115b298b..ecd4c6f01d 100644 --- a/rusk/src/lib/lib.rs +++ b/rusk/src/lib/lib.rs @@ -46,6 +46,7 @@ use rusk_profile::to_rusk_state_id_path; use sha3::{Digest, Sha3_256}; pub use version::{VERSION, VERSION_BUILD}; +pub const MINIMUM_STAKE: Dusk = dusk(1000.0); const A: usize = 4; @@ -413,17 +414,14 @@ impl Rusk { pub fn provisioners( &self, base_commit: Option<[u8; 32]>, - ) -> Result> { + ) -> Result> { let (sender, receiver) = mpsc::channel(); self.feeder_query(STAKE_CONTRACT, "stakes", &(), sender, base_commit)?; - Ok(receiver - .into_iter() - .map(|bytes| { - rkyv::from_bytes::<(BlsPublicKey, StakeData)>(&bytes).expect( - "The contract should only return (pk, stake_data) tuples", - ) - }) - .collect()) + Ok(receiver.into_iter().map(|bytes| { + rkyv::from_bytes::<(BlsPublicKey, StakeData)>(&bytes).expect( + "The contract should only return (pk, stake_data) tuples", + ) + })) } pub fn query_raw( diff --git a/rusk/src/lib/vm.rs b/rusk/src/lib/vm.rs index 8694d0c408..a29487eea5 100644 --- a/rusk/src/lib/vm.rs +++ b/rusk/src/lib/vm.rs @@ -12,7 +12,7 @@ use node::vm::VMExecution; use node_data::ledger::{Block, SpentTransaction, Transaction}; use tracing::info; -use crate::Rusk; +use crate::{Rusk, MINIMUM_STAKE}; impl VMExecution for Rusk { fn execute_state_transition>( @@ -160,7 +160,12 @@ impl Rusk { let provisioners = self .provisioners(base_commit) .map_err(|e| anyhow::anyhow!("Cannot get provisioners {e}"))? - .into_iter() + .filter(|(_, stake)| { + stake + .amount + .map(|(amount, _)| amount >= MINIMUM_STAKE) + .unwrap_or_default() + }) .filter_map(|(key, stake)| { stake.amount.map(|(value, eligibility)| { let stake = Stake::new(value, stake.reward, eligibility); diff --git a/rusk/tests/services/stake.rs b/rusk/tests/services/stake.rs index a50fee91d8..fbb8e150a6 100644 --- a/rusk/tests/services/stake.rs +++ b/rusk/tests/services/stake.rs @@ -12,8 +12,7 @@ use dusk_pki::SecretSpendKey; use dusk_wallet_core::{self as wallet, Store}; use rand::prelude::*; use rand::rngs::StdRng; -use rusk::{Result, Rusk}; -use rusk_recovery_tools::state::MINIMUM_STAKE; +use rusk::{Result, Rusk, MINIMUM_STAKE}; use std::collections::HashMap; use tempfile::tempdir; use tracing::info; From a47a56f2ad616cd1c615ced2f04c5e84deffdc20 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 19:54:13 +0100 Subject: [PATCH 10/22] rusk-recovery: remove `MINIMUM_STAKE` const --- rusk-recovery/src/state.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rusk-recovery/src/state.rs b/rusk-recovery/src/state.rs index a47aa7d392..9917b9ccc7 100644 --- a/rusk-recovery/src/state.rs +++ b/rusk-recovery/src/state.rs @@ -14,7 +14,6 @@ use ff::Field; use once_cell::sync::Lazy; use rand::rngs::StdRng; use rand::SeedableRng; -use rusk_abi::dusk::{dusk, Dusk}; use rusk_abi::{ContractData, ContractId, Session, VM}; use rusk_abi::{LICENSE_CONTRACT, STAKE_CONTRACT, TRANSFER_CONTRACT}; use std::error::Error; @@ -32,7 +31,6 @@ mod snapshot; pub mod tar; mod zip; -pub const MINIMUM_STAKE: Dusk = dusk(1000.0); pub const DEFAULT_SNAPSHOT: &str = include_str!("../config/testnet_remote.toml"); From f598c65fe858cf12380221671f149eb4d8f3c6c1 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Tue, 16 Jan 2024 15:20:00 +0100 Subject: [PATCH 11/22] consensus: change VST to verify a Block instead of CallParams --- consensus/src/operations.rs | 5 ++--- consensus/src/validation/step.rs | 29 +++-------------------------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/consensus/src/operations.rs b/consensus/src/operations.rs index 83af1b4bad..c06ee64385 100644 --- a/consensus/src/operations.rs +++ b/consensus/src/operations.rs @@ -6,7 +6,7 @@ use std::fmt; -use node_data::ledger::{Header, SpentTransaction, Transaction}; +use node_data::ledger::{Block, Header, SpentTransaction, Transaction}; pub type StateRoot = [u8; 32]; pub type EventHash = [u8; 32]; @@ -57,8 +57,7 @@ pub trait Operations: Send + Sync { async fn verify_state_transition( &self, - params: CallParams, - txs: Vec, + blk: &Block, ) -> Result; async fn execute_state_transition( diff --git a/consensus/src/validation/step.rs b/consensus/src/validation/step.rs index 7012bb3f39..4819c1d4ca 100644 --- a/consensus/src/validation/step.rs +++ b/consensus/src/validation/step.rs @@ -7,11 +7,9 @@ use crate::commons::{ConsensusError, Database, RoundUpdate}; use crate::config; use crate::execution_ctx::ExecutionCtx; -use crate::operations::{CallParams, Operations}; +use crate::operations::Operations; use crate::validation::handler; use anyhow::anyhow; -use dusk_bytes::DeserializableSlice; -use node_data::bls::PublicKey; use node_data::ledger::{to_str, Block}; use node_data::message::{self, AsyncQueue, Message, Payload, Topics}; use std::sync::Arc; @@ -75,7 +73,7 @@ impl ValidationStep { }; // Call Verify State Transition to make sure transactions set is valid - if let Err(err) = Self::call_vst(candidate, ru, executor).await { + if let Err(err) = Self::call_vst(candidate, executor).await { error!(event = "failed_vst_call", ?err); return; } @@ -122,33 +120,12 @@ impl ValidationStep { async fn call_vst( candidate: &Block, - ru: &RoundUpdate, executor: Arc>, ) -> anyhow::Result<()> { - let pubkey = &candidate.header().generator_bls_pubkey.0; - let generator = match dusk_bls12_381_sign::PublicKey::from_slice(pubkey) - { - Ok(pubkey) => pubkey, - Err(e) => { - return Err(anyhow::anyhow!( - "invalid bls key {}, err: {:?}", - hex::encode(pubkey), - e, - )); - } - }; - match executor .lock() .await - .verify_state_transition( - CallParams { - round: ru.round, - block_gas_limit: candidate.header().gas_limit, - generator_pubkey: PublicKey::new(generator), - }, - candidate.txs().clone(), - ) + .verify_state_transition(candidate) .await { Ok(output) => { From e34676fa02451fe62297dddd15a3fe485af97265 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Tue, 16 Jan 2024 15:20:12 +0100 Subject: [PATCH 12/22] node: change VST to verify a Block instead of CallParams --- node/src/chain/consensus.rs | 7 +++---- node/src/vm.rs | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/node/src/chain/consensus.rs b/node/src/chain/consensus.rs index 02856d9f8a..59ff42771c 100644 --- a/node/src/chain/consensus.rs +++ b/node/src/chain/consensus.rs @@ -13,7 +13,7 @@ use dusk_consensus::operations::{ CallParams, Error, Operations, Output, VerificationOutput, }; use dusk_consensus::user::provisioners::ContextProvisioners; -use node_data::ledger::{Block, Hash, Header, Transaction}; +use node_data::ledger::{Block, Hash, Header}; use node_data::message::payload::GetCandidate; use node_data::message::AsyncQueue; use node_data::message::{Payload, Topics}; @@ -315,14 +315,13 @@ impl Operations for Executor { async fn verify_state_transition( &self, - params: CallParams, - txs: Vec, + blk: &Block, ) -> Result { info!("verifying state"); let vm = self.vm.read().await; - Ok(vm.verify_state_transition(¶ms, txs).map_err(|err| { + Ok(vm.verify_state_transition(blk).map_err(|err| { error!("failed to call VST {}", err); Error::Failed })?) diff --git a/node/src/vm.rs b/node/src/vm.rs index e77845c87a..308b8cea86 100644 --- a/node/src/vm.rs +++ b/node/src/vm.rs @@ -26,8 +26,7 @@ pub trait VMExecution: Send + Sync + 'static { fn verify_state_transition( &self, - params: &CallParams, - txs: Vec, + blk: &Block, ) -> anyhow::Result; fn accept( From 340cd4a057a7148d994f9d3a9a231d0b23f60074 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Tue, 16 Jan 2024 15:20:21 +0100 Subject: [PATCH 13/22] rusk: change VST to verify a Block instead of CallParams --- rusk/src/lib/vm.rs | 15 +++++++++------ rusk/tests/common/state.rs | 6 +++--- rusk/tests/common/wallet.rs | 1 - 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/rusk/src/lib/vm.rs b/rusk/src/lib/vm.rs index a29487eea5..bcaa9f152f 100644 --- a/rusk/src/lib/vm.rs +++ b/rusk/src/lib/vm.rs @@ -42,17 +42,20 @@ impl VMExecution for Rusk { fn verify_state_transition( &self, - params: &CallParams, - txs: Vec, + blk: &Block, ) -> anyhow::Result { info!("Received verify_state_transition request"); + let generator = blk.header().generator_bls_pubkey; + let generator = + dusk_bls12_381_sign::PublicKey::from_slice(&generator.0) + .map_err(|e| anyhow::anyhow!("Error in from_slice {e:?}"))?; let (_, verification_output) = self .verify_transactions( - params.round, - params.block_gas_limit, - params.generator_pubkey.inner(), - &txs[..], + blk.header().height, + blk.header().gas_limit, + &generator, + blk.txs(), ) .map_err(|inner| anyhow::anyhow!("Cannot verify txs: {inner}!!"))?; diff --git a/rusk/tests/common/state.rs b/rusk/tests/common/state.rs index b202ad1142..99ba8679e7 100644 --- a/rusk/tests/common/state.rs +++ b/rusk/tests/common/state.rs @@ -92,9 +92,6 @@ pub fn generator_procedure( ); let txs: Vec<_> = transfer_txs.into_iter().map(|tx| tx.inner).collect(); - let verify_output = - rusk.verify_state_transition(&call_params, txs.clone())?; - info!("verify_state_transition new verification: {verify_output}",); let block = Block::new( Header { @@ -109,6 +106,9 @@ pub fn generator_procedure( ) .expect("valid block"); + let verify_output = rusk.verify_state_transition(&block)?; + info!("verify_state_transition new verification: {verify_output}",); + let (accept_txs, accept_output) = rusk.accept(&block)?; assert_eq!(accept_txs.len(), expected.executed, "all txs accepted"); diff --git a/rusk/tests/common/wallet.rs b/rusk/tests/common/wallet.rs index 5c5a785b99..ac72d0ad80 100644 --- a/rusk/tests/common/wallet.rs +++ b/rusk/tests/common/wallet.rs @@ -118,7 +118,6 @@ impl wallet::StateClient for TestStateClient { let stake = self .rusk .provisioners(None)? - .iter() .find(|(pk, _)| pk == _pk) .map(|(_, stake)| StakeInfo { amount: stake.amount, From c5bc2616d252f0aa8e106cab857ea3c137320c23 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 09:54:32 +0100 Subject: [PATCH 14/22] node-data: add Generator to IterationInfo --- node-data/src/encoding.rs | 14 ++++++++++---- node-data/src/ledger.rs | 26 +++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/node-data/src/encoding.rs b/node-data/src/encoding.rs index 5ca64f6921..4e576db5c7 100644 --- a/node-data/src/encoding.rs +++ b/node-data/src/encoding.rs @@ -4,6 +4,7 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +use crate::bls::PublicKeyBytes; use crate::ledger::*; use crate::message::payload::{QuorumType, Ratification, ValidationResult}; use crate::Serializable; @@ -192,11 +193,12 @@ impl Serializable for IterationsInfo { let count = self.cert_list.len() as u8; w.write_all(&count.to_le_bytes())?; - for cert in &self.cert_list { - match cert { - Some(cert) => { + for iter in &self.cert_list { + match iter { + Some((cert, pk)) => { w.write_all(&[1])?; cert.write(w)?; + w.write_all(pk.inner())?; } None => w.write_all(&[0])?, } @@ -218,7 +220,11 @@ impl Serializable for IterationsInfo { let cert = match opt { 0 => None, - 1 => Some(Certificate::read(r)?), + 1 => { + let cert = Certificate::read(r)?; + let pk = Self::read_bytes(r)?; + Some((cert, PublicKeyBytes(pk))) + } _ => { return Err(io::Error::new( io::ErrorKind::InvalidData, diff --git a/node-data/src/ledger.rs b/node-data/src/ledger.rs index a3387efe12..973d259ed3 100644 --- a/node-data/src/ledger.rs +++ b/node-data/src/ledger.rs @@ -4,7 +4,10 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -use crate::{bls, Serializable}; +use crate::bls::{self, PublicKeyBytes}; +use crate::Serializable; + +use dusk_bytes::DeserializableSlice; use rusk_abi::hash::Hasher; use sha3::Digest; use std::io::{self, Read, Write}; @@ -323,20 +326,37 @@ impl PartialEq for SpentTransaction { impl Eq for SpentTransaction {} +/// Includes a `NilQuorum` certificate and the key of the expected block +/// generator +pub type IterationInfo = (Certificate, PublicKeyBytes); + /// Defines a set of certificates of any former iterations #[derive(Default, Eq, PartialEq, Clone)] pub struct IterationsInfo { /// Represents a list of certificates where position is the iteration /// number - pub cert_list: Vec>, + pub cert_list: Vec>, } impl IterationsInfo { - pub fn new(certificates: Vec>) -> Self { + pub fn new(certificates: Vec>) -> Self { Self { cert_list: certificates, } } + + pub fn to_missed_generators( + &self, + ) -> Result, io::Error> { + self.cert_list + .iter() + .flatten() + .map(|(_, pk)| dusk_bls12_381_sign::PublicKey::from_slice(pk.inner()).map_err(|e|{ + tracing::error!("Unable to generate missing generators from failed_iterations: {e:?}"); + io::Error::new(io::ErrorKind::InvalidData, "Error in deserialize") + })) + .collect() + } } /// Encode a byte array into a shortened HEX representation. From 78c2423901fa8b280ea7d71e37c05dc4c581e5ba Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 09:57:03 +0100 Subject: [PATCH 15/22] consensus: add Generator to IterationInfo --- consensus/src/operations.rs | 3 +++ consensus/src/proposal/block_generator.rs | 11 ++++++--- consensus/src/proposal/step.rs | 3 ++- consensus/src/ratification/handler.rs | 2 ++ consensus/src/step_votes_reg.rs | 29 ++++++++++++++++------- consensus/src/user/committee.rs | 8 ++++++- consensus/src/validation/handler.rs | 2 ++ 7 files changed, 45 insertions(+), 13 deletions(-) diff --git a/consensus/src/operations.rs b/consensus/src/operations.rs index c06ee64385..052abba323 100644 --- a/consensus/src/operations.rs +++ b/consensus/src/operations.rs @@ -6,6 +6,7 @@ use std::fmt; +use dusk_bls12_381_sign::PublicKey; use node_data::ledger::{Block, Header, SpentTransaction, Transaction}; pub type StateRoot = [u8; 32]; @@ -14,6 +15,7 @@ pub type EventHash = [u8; 32]; #[derive(Debug)] pub enum Error { Failed, + InvalidIterationInfo, } #[derive(Default, Clone, Debug)] @@ -21,6 +23,7 @@ pub struct CallParams { pub round: u64, pub block_gas_limit: u64, pub generator_pubkey: node_data::bls::PublicKey, + pub missed_generators: Vec, } #[derive(Default)] diff --git a/consensus/src/proposal/block_generator.rs b/consensus/src/proposal/block_generator.rs index 99e8b8144d..d6ca26ba0d 100644 --- a/consensus/src/proposal/block_generator.rs +++ b/consensus/src/proposal/block_generator.rs @@ -33,7 +33,7 @@ impl Generator { &self, ru: &RoundUpdate, iteration: u8, - failed_iterations: Vec>, + failed_iterations: IterationsInfo, ) -> Result { // Sign seed let seed = ru @@ -80,14 +80,19 @@ impl Generator { ru: &RoundUpdate, seed: Seed, iteration: u8, - failed_iterations: Vec>, + failed_iterations: IterationsInfo, ) -> Result { let start_time = Instant::now(); + let missed_generators = failed_iterations + .to_missed_generators() + .map_err(|_| crate::operations::Error::InvalidIterationInfo)?; + let call_params = CallParams { round: ru.round, block_gas_limit: config::DEFAULT_BLOCK_GAS_LIMIT, generator_pubkey: ru.pubkey_bls.clone(), + missed_generators, }; let result = self @@ -118,7 +123,7 @@ impl Generator { prev_block_cert: *ru.cert(), txroot, iteration, - failed_iterations: IterationsInfo::new(failed_iterations), + failed_iterations, }; // Apply a delay in block generator accordingly diff --git a/consensus/src/proposal/step.rs b/consensus/src/proposal/step.rs index 405295601e..41f295010a 100644 --- a/consensus/src/proposal/step.rs +++ b/consensus/src/proposal/step.rs @@ -8,6 +8,7 @@ use crate::commons::{ConsensusError, Database}; use crate::execution_ctx::ExecutionCtx; use crate::msg_handler::{HandleMsgOutput, MsgHandler}; use crate::operations::Operations; +use node_data::ledger::IterationsInfo; use node_data::message::Message; use std::cmp; use std::sync::Arc; @@ -67,7 +68,7 @@ impl ProposalStep { .generate_candidate_message( &ctx.round_update, ctx.iteration, - failed_certificates, + IterationsInfo::new(failed_certificates), ) .await { diff --git a/consensus/src/ratification/handler.rs b/consensus/src/ratification/handler.rs index 583c2fa511..add8a2c38a 100644 --- a/consensus/src/ratification/handler.rs +++ b/consensus/src/ratification/handler.rs @@ -91,6 +91,7 @@ impl MsgHandler for RatificationHandler { ratification_sv, SvType::Ratification, quorum_reached, + committee.excluded().expect("Generator to be excluded"), ); if quorum_reached { @@ -131,6 +132,7 @@ impl MsgHandler for RatificationHandler { sv, SvType::Ratification, quorum_reached, + committee.excluded().expect("Generator to be excluded"), ) { return Ok(HandleMsgOutput::Ready(quorum_msg)); diff --git a/consensus/src/step_votes_reg.rs b/consensus/src/step_votes_reg.rs index 438d55f0d7..8c8060fa1a 100644 --- a/consensus/src/step_votes_reg.rs +++ b/consensus/src/step_votes_reg.rs @@ -5,8 +5,8 @@ // Copyright (c) DUSK NETWORK. All rights reserved. use crate::commons::RoundUpdate; -use node_data::ledger::StepVotes; -use node_data::ledger::{to_str, Certificate}; +use node_data::bls::PublicKeyBytes; +use node_data::ledger::{to_str, Certificate, IterationInfo, StepVotes}; use node_data::message::{payload, Message, Topics}; use std::collections::HashMap; use std::fmt; @@ -94,13 +94,22 @@ impl CertificateInfo { pub type SafeCertificateInfoRegistry = Arc>; -#[derive(Default, Clone)] +#[derive(Clone)] struct IterationCerts { valid: Option, nil: CertificateInfo, + generator: PublicKeyBytes, } impl IterationCerts { + fn new(generator: PublicKeyBytes) -> Self { + Self { + valid: None, + nil: CertificateInfo::default(), + generator, + } + } + fn for_hash(&mut self, hash: [u8; 32]) -> Option<&mut CertificateInfo> { if hash == [0u8; 32] { return Some(&mut self.nil); @@ -144,8 +153,12 @@ impl CertInfoRegistry { sv: StepVotes, svt: SvType, quorum_reached: bool, + generator: &PublicKeyBytes, ) -> Option { - let cert = self.cert_list.entry(iteration).or_default(); + let cert = self + .cert_list + .entry(iteration) + .or_insert_with(|| IterationCerts::new(*generator)); cert.for_hash(hash).and_then(|cert| { cert.add_sv(iteration, sv, svt, quorum_reached).then(|| { @@ -181,16 +194,16 @@ impl CertInfoRegistry { pub(crate) fn get_nil_certificates( &mut self, to: u8, - ) -> Vec> { + ) -> Vec> { let mut res = Vec::with_capacity(to as usize); for iteration in 0u8..to { res.push( self.cert_list .get(&iteration) - .map(|c| c.nil) - .filter(|ci| ci.has_votes()) - .map(|ci| ci.cert), + .map(|c| (c.nil, c.generator)) + .filter(|(ci, _)| ci.has_votes()) + .map(|(ci, pk)| (ci.cert, pk)), ); } diff --git a/consensus/src/user/committee.rs b/consensus/src/user/committee.rs index a6f5fa182a..8c12cbf69a 100644 --- a/consensus/src/user/committee.rs +++ b/consensus/src/user/committee.rs @@ -9,7 +9,7 @@ use crate::user::sortition; use super::cluster::Cluster; use crate::config; -use node_data::bls::PublicKey; +use node_data::bls::{PublicKey, PublicKeyBytes}; use std::collections::{BTreeMap, HashMap}; use std::fmt; use std::mem; @@ -19,6 +19,7 @@ pub struct Committee { members: BTreeMap, quorum: usize, nil_quorum: usize, + excluded: Option, } impl Committee { @@ -47,6 +48,7 @@ impl Committee { members: BTreeMap::new(), nil_quorum, quorum, + excluded: cfg.exclusion().copied(), }; for member_key in res { @@ -56,6 +58,10 @@ impl Committee { committee } + pub fn excluded(&self) -> Option<&PublicKeyBytes> { + self.excluded.as_ref() + } + /// Returns true if `pubkey_bls` is a member of the generated committee. pub fn is_member(&self, pubkey_bls: &PublicKey) -> bool { self.members.contains_key(pubkey_bls) diff --git a/consensus/src/validation/handler.rs b/consensus/src/validation/handler.rs index 28cf411596..404d57b03b 100644 --- a/consensus/src/validation/handler.rs +++ b/consensus/src/validation/handler.rs @@ -116,6 +116,7 @@ impl MsgHandler for ValidationHandler { sv, SvType::Validation, quorum_reached, + committee.excluded().expect("Generator to be excluded"), ); if quorum_reached { @@ -159,6 +160,7 @@ impl MsgHandler for ValidationHandler { sv, SvType::Validation, quorum_reached, + committee.excluded().expect("Generator to be excluded"), ) { return Ok(HandleMsgOutput::Ready(quorum_msg)); From 7dbd8009378ef747f18fcb6969874cd4bfb511de Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 09:58:59 +0100 Subject: [PATCH 16/22] node: add failed generator check during header validation --- node/src/chain/header_validation.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/node/src/chain/header_validation.rs b/node/src/chain/header_validation.rs index 7cce97835b..80606fe624 100644 --- a/node/src/chain/header_validation.rs +++ b/node/src/chain/header_validation.rs @@ -138,8 +138,16 @@ impl<'a, DB: database::DB> Validator<'a, DB> { .iter() .enumerate() { - if let Some(cert) = cert { + if let Some((cert, pk)) = cert { info!(event = "verify_cert", cert_type = "failed_cert", iter); + let expected_pk = self.provisioners.current().get_generator( + candidate_block.iteration, + candidate_block.seed, + candidate_block.height, + ); + if pk != &expected_pk { + anyhow::bail!("Invalid generator. Expected {expected_pk:?}, actual {pk:?}"); + } let quorums = verify_block_cert( self.block.seed, From 66fc2a08010d24225e42a762b1733c1d106312f1 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 09:57:44 +0100 Subject: [PATCH 17/22] consensus: change get_nil_certificates to return only nil quorums --- consensus/src/step_votes_reg.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/src/step_votes_reg.rs b/consensus/src/step_votes_reg.rs index 8c8060fa1a..ccaf094141 100644 --- a/consensus/src/step_votes_reg.rs +++ b/consensus/src/step_votes_reg.rs @@ -202,7 +202,7 @@ impl CertInfoRegistry { self.cert_list .get(&iteration) .map(|c| (c.nil, c.generator)) - .filter(|(ci, _)| ci.has_votes()) + .filter(|(ci, _)| ci.is_ready()) .map(|(ci, pk)| (ci.cert, pk)), ); } From fd72b6123fba9abe56514f2497ca2d128e771d04 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 09:59:31 +0100 Subject: [PATCH 18/22] node: change header validation to check nil quorums --- node/src/chain/header_validation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/src/chain/header_validation.rs b/node/src/chain/header_validation.rs index 80606fe624..ee16703f72 100644 --- a/node/src/chain/header_validation.rs +++ b/node/src/chain/header_validation.rs @@ -156,7 +156,7 @@ impl<'a, DB: database::DB> Validator<'a, DB> { candidate_block.height, cert, iter as u8, - false, + true, ) .await?; From 88d7c570f01430b5706b66c66741ab858ebb9b72 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 10:00:53 +0100 Subject: [PATCH 19/22] rusk: change block processing to slash failed iterations provisioner --- rusk/src/lib/lib.rs | 40 ++++++++++++++++++++++++++++++++++---- rusk/src/lib/vm.rs | 4 ++++ rusk/tests/common/state.rs | 1 + 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/rusk/src/lib/lib.rs b/rusk/src/lib/lib.rs index ecd4c6f01d..4b5775e321 100644 --- a/rusk/src/lib/lib.rs +++ b/rusk/src/lib/lib.rs @@ -113,6 +113,7 @@ impl Rusk { block_gas_limit: u64, generator: &BlsPublicKey, txs: I, + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, Vec, VerificationOutput)> { let inner = self.inner.lock(); @@ -180,11 +181,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(); @@ -207,6 +209,7 @@ impl Rusk { block_gas_limit: u64, generator: &BlsPublicKey, txs: &[Transaction], + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, VerificationOutput)> { let inner = self.inner.lock(); @@ -214,7 +217,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. @@ -229,6 +239,7 @@ impl Rusk { generator: BlsPublicKey, txs: Vec, consistency_check: Option, + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, VerificationOutput)> { let mut inner = self.inner.lock(); @@ -242,6 +253,7 @@ impl Rusk { block_gas_limit, &generator, &txs[..], + missed_generators, )?; if let Some(expected_verification) = consistency_check { @@ -270,6 +282,7 @@ impl Rusk { generator: BlsPublicKey, txs: Vec, consistency_check: Option, + missed_generators: &[BlsPublicKey], ) -> Result<(Vec, VerificationOutput)> { let mut inner = self.inner.lock(); @@ -283,6 +296,7 @@ impl Rusk { block_gas_limit, &generator, &txs[..], + missed_generators, )?; if let Some(expected_verification) = consistency_check { @@ -611,6 +625,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; @@ -642,7 +657,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(); @@ -708,11 +729,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); @@ -729,6 +751,16 @@ fn reward_and_update_root( &(*generator, generator_value), u64::MAX, )?; + let slash_amount = emission_amount(block_height); + + 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 bcaa9f152f..271a620584 100644 --- a/rusk/src/lib/vm.rs +++ b/rusk/src/lib/vm.rs @@ -32,6 +32,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}!!") @@ -56,6 +57,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}!!"))?; @@ -82,6 +84,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}!!"))?; @@ -108,6 +111,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 From 8a7e9ad948dd46a63f54931b4183cea2cf8afc92 Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Thu, 18 Jan 2024 10:24:57 +0100 Subject: [PATCH 20/22] rusk: add slash tests --- rusk/tests/common/state.rs | 24 +++- rusk/tests/config/slash.toml | 20 ++++ rusk/tests/services/gas_behavior.rs | 1 + rusk/tests/services/multi_transfer.rs | 1 + rusk/tests/services/stake.rs | 163 +++++++++++++++++++++++--- rusk/tests/services/transfer.rs | 23 +++- rusk/tests/services/unspendable.rs | 1 + 7 files changed, 208 insertions(+), 25 deletions(-) create mode 100644 rusk/tests/config/slash.toml diff --git a/rusk/tests/common/state.rs b/rusk/tests/common/state.rs index e080352128..bd6177c756 100644 --- a/rusk/tests/common/state.rs +++ b/rusk/tests/common/state.rs @@ -6,6 +6,7 @@ use std::path::Path; +use dusk_bytes::Serializable; use node::vm::VMExecution; use rusk::{Result, Rusk}; use rusk_recovery_tools::state::{self, Snapshot}; @@ -13,7 +14,10 @@ use rusk_recovery_tools::state::{self, Snapshot}; use dusk_bls12_381_sign::PublicKey; use dusk_consensus::operations::CallParams; use dusk_wallet_core::Transaction as PhoenixTransaction; -use node_data::ledger::{Block, Header, SpentTransaction}; +use node_data::{ + bls::PublicKeyBytes, + ledger::{Block, Certificate, Header, IterationsInfo, SpentTransaction}, +}; use tracing::info; use crate::common::keys::BLS_SK; @@ -55,6 +59,7 @@ pub fn generator_procedure( txs: &[PhoenixTransaction], block_height: u64, block_gas_limit: u64, + missed_generators: Vec, expected: Option, ) -> anyhow::Result> { let expected = expected.unwrap_or(ExecuteResult { @@ -71,18 +76,24 @@ pub fn generator_procedure( let generator_pubkey = node_data::bls::PublicKey::new(generator); let generator_pubkey_bytes = *generator_pubkey.bytes(); let round = block_height; - // let txs = vec![]; + + let mut failed_iterations = IterationsInfo::default(); + for to_slash in &missed_generators { + failed_iterations.cert_list.push(Some(( + Certificate::default(), + PublicKeyBytes(to_slash.to_bytes()), + ))); + } let call_params = CallParams { round, block_gas_limit, generator_pubkey, - missed_generators: vec![], + missed_generators, }; - let (transfer_txs, discarded, execute_output) = rusk - .execute_state_transition(&call_params, txs.into_iter()) - .expect("state transition to success"); + let (transfer_txs, discarded, execute_output) = + rusk.execute_state_transition(&call_params, txs.into_iter())?; assert_eq!(transfer_txs.len(), expected.executed, "all txs accepted"); assert_eq!(discarded.len(), expected.discarded, "no discarded tx"); @@ -101,6 +112,7 @@ pub fn generator_procedure( generator_bls_pubkey: generator_pubkey_bytes, state_hash: execute_output.state_root, event_hash: execute_output.event_hash, + failed_iterations, ..Default::default() }, txs, diff --git a/rusk/tests/config/slash.toml b/rusk/tests/config/slash.toml new file mode 100644 index 0000000000..b55927269c --- /dev/null +++ b/rusk/tests/config/slash.toml @@ -0,0 +1,20 @@ +[[balance]] +address = "ivmscertKgRyX8wNMJJsQcSVEyPsfSMUQXSAgeAPQXsndqFq9Pmknzhm61QvcEEdxPaGgxDS4RHpb6KKccrnSKN" +seed = 57005 +notes = [ + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, + 10_000_000_000_000, +] + +[[stake]] +address = "qe1FbZxf6YaCAeFNSvL1G82cBhG4Q4gBf4vKYo527Vws3b23jdbBuzKSFsdUHnZeBgsTnyNJLkApEpRyJw87sdzR9g9iESJrG5ZgpCs9jq88m6d4qMY5txGpaXskRQmkzE3" +amount = 20_000_000_000 +reward = 3_000_000_000 diff --git a/rusk/tests/services/gas_behavior.rs b/rusk/tests/services/gas_behavior.rs index 7492593014..2c37b087f0 100644 --- a/rusk/tests/services/gas_behavior.rs +++ b/rusk/tests/services/gas_behavior.rs @@ -110,6 +110,7 @@ fn make_transactions( &[tx_0, tx_1], BLOCK_HEIGHT, BLOCK_GAS_LIMIT, + vec![], None, ) .expect("generator procedure should succeed"); diff --git a/rusk/tests/services/multi_transfer.rs b/rusk/tests/services/multi_transfer.rs index c0eb781929..c4fe9da978 100644 --- a/rusk/tests/services/multi_transfer.rs +++ b/rusk/tests/services/multi_transfer.rs @@ -140,6 +140,7 @@ fn wallet_transfer( &txs[..], BLOCK_HEIGHT, BLOCK_GAS_LIMIT, + vec![], Some(expected), ) .expect("generator procedure to succeed"); diff --git a/rusk/tests/services/stake.rs b/rusk/tests/services/stake.rs index fbb8e150a6..305633dff1 100644 --- a/rusk/tests/services/stake.rs +++ b/rusk/tests/services/stake.rs @@ -13,6 +13,8 @@ use dusk_wallet_core::{self as wallet, Store}; use rand::prelude::*; use rand::rngs::StdRng; use rusk::{Result, Rusk, MINIMUM_STAKE}; +use rusk_abi::dusk::dusk; +use rusk_abi::STAKE_CONTRACT; use std::collections::HashMap; use tempfile::tempdir; use tracing::info; @@ -26,13 +28,21 @@ const BLOCK_GAS_LIMIT: u64 = 100_000_000_000; const GAS_LIMIT: u64 = 10_000_000_000; // Creates the Rusk initial state for the tests below -fn initial_state>(dir: P) -> Result { +fn stake_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/stake.toml")) .expect("Cannot deserialize config"); new_state(dir, &snapshot) } +// Creates the Rusk initial state for the tests below +fn slash_state>(dir: P) -> Result { + let snapshot = toml::from_str(include_str!("../config/slash.toml")) + .expect("Cannot deserialize config"); + + new_state(dir, &snapshot) +} + static SSK: LazyLock = LazyLock::new(|| { info!("Generating SecretSpendKey"); TestStore.retrieve_ssk(0).expect("Should not fail in test") @@ -74,9 +84,15 @@ fn wallet_stake( let tx = wallet .stake(&mut rng, 0, 2, &psk, value, GAS_LIMIT, 1) .expect("Failed to create a stake transaction"); - let executed_txs = - generator_procedure(rusk, &[tx], BLOCK_HEIGHT, BLOCK_GAS_LIMIT, None) - .expect("generator procedure to succeed"); + let executed_txs = generator_procedure( + rusk, + &[tx], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![], + None, + ) + .expect("generator procedure to succeed"); if let Some(e) = &executed_txs .first() .expect("Transaction must be executed") @@ -99,9 +115,15 @@ fn wallet_stake( let tx = wallet .unstake(&mut rng, 0, 0, &psk, GAS_LIMIT, 1) .expect("Failed to unstake"); - let spent_txs = - generator_procedure(rusk, &[tx], BLOCK_HEIGHT, BLOCK_GAS_LIMIT, None) - .expect("generator procedure to succeed"); + let spent_txs = generator_procedure( + rusk, + &[tx], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![], + None, + ) + .expect("generator procedure to succeed"); let spent_tx = spent_txs.first().expect("Unstake tx to be included"); assert_eq!(spent_tx.err, None, "unstake to be successfull"); @@ -111,8 +133,15 @@ fn wallet_stake( let tx = wallet .withdraw(&mut rng, 0, 1, &psk, GAS_LIMIT, 1) .expect("failed to withdraw reward"); - generator_procedure(rusk, &[tx], BLOCK_HEIGHT, BLOCK_GAS_LIMIT, None) - .expect("generator procedure to succeed"); + generator_procedure( + rusk, + &[tx], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![], + None, + ) + .expect("generator procedure to succeed"); let stake = wallet.get_stake(1).expect("stake should still be state"); assert_eq!(stake.reward, 0); @@ -124,7 +153,7 @@ pub async fn stake() -> Result<()> { logger(); let tmp = tempdir().expect("Should be able to create temporary directory"); - let rusk = initial_state(&tmp)?; + let rusk = stake_state(&tmp)?; let cache = Arc::new(RwLock::new(HashMap::new())); @@ -192,9 +221,15 @@ fn wallet_reward( 1, ) .expect("Failed to create a reward transaction"); - let executed_txs = - generator_procedure(rusk, &[tx], BLOCK_HEIGHT, BLOCK_GAS_LIMIT, None) - .expect("generator procedure to succeed"); + let executed_txs = generator_procedure( + rusk, + &[tx], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![], + None, + ) + .expect("generator procedure to succeed"); let _ = executed_txs .first() .expect("Transaction must be executed") @@ -211,7 +246,7 @@ pub async fn reward() -> Result<()> { logger(); let tmp = tempdir().expect("Should be able to create temporary directory"); - let rusk = initial_state(&tmp)?; + let rusk = stake_state(&tmp)?; let cache = Arc::new(RwLock::new(HashMap::new())); @@ -242,3 +277,103 @@ pub async fn reward() -> Result<()> { Ok(()) } + +#[tokio::test(flavor = "multi_thread")] +pub async fn slash() -> Result<()> { + // Setup the logger + logger(); + + let tmp = tempdir().expect("Should be able to create temporary directory"); + let rusk = slash_state(&tmp)?; + + let cache = Arc::new(RwLock::new(HashMap::new())); + + // Create a wallet + let wallet = wallet::Wallet::new( + TestStore, + TestStateClient { + rusk: rusk.clone(), + cache, + }, + TestProverClient::default(), + ); + + let original_root = rusk.state_root(); + + info!("Original Root: {:?}", hex::encode(original_root)); + + let module_balance = rusk + .module_balance(STAKE_CONTRACT) + .expect("balance to exists"); + let to_slash = wallet.public_key(0).unwrap(); + let stake = wallet.get_stake(0).unwrap(); + assert_eq!(stake.reward, dusk(3.0)); + assert_eq!(stake.amount, Some((dusk(20.0), 0))); + + generator_procedure( + &rusk, + &[], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![to_slash], + None, + ) + .expect("to work"); + let after_slash = wallet.get_stake(0).unwrap(); + assert_eq!(after_slash.reward, 0); + assert_eq!(after_slash.amount, Some((dusk(7.0), 0))); + let new_balance = rusk.module_balance(STAKE_CONTRACT).unwrap(); + assert_eq!(new_balance, module_balance - dusk(13.0)); + let module_balance = new_balance; + + generator_procedure( + &rusk, + &[], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![to_slash], + None, + ) + .expect("to work"); + let after_slash = wallet.get_stake(0).unwrap(); + assert_eq!(after_slash.reward, 0); + assert_eq!(after_slash.amount, Some((0, 0))); + let new_balance = rusk.module_balance(STAKE_CONTRACT).unwrap(); + assert_eq!(new_balance, module_balance - dusk(7.0)); + let module_balance = new_balance; + + generator_procedure( + &rusk, + &[], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![to_slash], + None, + ) + .expect("to work"); + let after_slash = wallet.get_stake(0).unwrap(); + assert_eq!(after_slash.reward, 0); + assert_eq!(after_slash.amount, Some((0, 0))); + let new_balance = rusk.module_balance(STAKE_CONTRACT).unwrap(); + assert_eq!(new_balance, module_balance); + + generator_procedure( + &rusk, + &[], + BLOCK_HEIGHT, + BLOCK_GAS_LIMIT, + vec![wallet.public_key(1).unwrap()], + None, + ) + .expect_err("Slashing a public key that never staked must fail"); + + // Check the state's root is changed from the original one + let new_root = rusk.state_root(); + info!( + "New root after the 1st transfer: {:?}", + hex::encode(new_root) + ); + assert_ne!(original_root, new_root, "Root should have changed"); + + Ok(()) +} diff --git a/rusk/tests/services/transfer.rs b/rusk/tests/services/transfer.rs index e41a558457..e0ef752cb4 100644 --- a/rusk/tests/services/transfer.rs +++ b/rusk/tests/services/transfer.rs @@ -102,15 +102,28 @@ fn wallet_transfer( let tx_hash = rusk_abi::hash(tx_hash_input_bytes); info!("Tx ID: {}", hex::encode(tx_hash.to_bytes())); - let txs: Vec = - generator_procedure(rusk, &[tx], block_height, BLOCK_GAS_LIMIT, None) - .expect("generator procedure to succeed"); + let txs: Vec = generator_procedure( + rusk, + &[tx], + block_height, + BLOCK_GAS_LIMIT, + vec![], + None, + ) + .expect("generator procedure to succeed"); let tx = txs.first().expect("tx to be processed"); let gas_spent = tx.gas_spent; info!("Gas spent: {gas_spent}"); - generator_procedure(rusk, &[], block_height + 1, BLOCK_GAS_LIMIT, None) - .expect("empty block generator procedure to succeed"); + generator_procedure( + rusk, + &[], + block_height + 1, + BLOCK_GAS_LIMIT, + vec![], + None, + ) + .expect("empty block generator procedure to succeed"); // Check the receiver's balance is changed accordingly assert_eq!( diff --git a/rusk/tests/services/unspendable.rs b/rusk/tests/services/unspendable.rs index 51f9d27f41..d20a2cbab7 100644 --- a/rusk/tests/services/unspendable.rs +++ b/rusk/tests/services/unspendable.rs @@ -148,6 +148,7 @@ fn make_transactions( &[tx_0, tx_1, tx_2], BLOCK_HEIGHT, BLOCK_GAS_LIMIT, + vec![], Some(expected), ) .expect("generator procedure should succeed"); From 16b2446230e5d7430ccdaa124be64e117c5d691d Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 12:27:32 +0100 Subject: [PATCH 21/22] node: update provisioners if slash has been applied --- node/src/chain/acceptor.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/node/src/chain/acceptor.rs b/node/src/chain/acceptor.rs index a3e1eb2a4c..ec2ff74416 100644 --- a/node/src/chain/acceptor.rs +++ b/node/src/chain/acceptor.rs @@ -160,9 +160,21 @@ impl Acceptor { } fn needs_update(blk: &Block, txs: &[SpentTransaction]) -> bool { + // Update provisioners at every epoch (where new stakes take effect) if blk.header().height % EPOCH == 0 { return true; } + // Update provisioners if a slash has been applied + if blk + .header() + .failed_iterations + .cert_list + .iter() + .any(|i| i.is_some()) + { + return true; + }; + // Update provisioners if there is a processed unstake transaction txs.iter().filter(|t| t.err.is_none()).any(|t| { matches!(&t.inner.inner.call, Some((STAKE_CONTRACT, f, _)) if f == "unstake") }) @@ -324,6 +336,12 @@ impl Acceptor { header.height, ); + for (_, slashed) in + header.failed_iterations.cert_list.iter().flatten() + { + info!("Slashed {}", slashed.to_base58()) + } + match Self::needs_update(blk.inner(), &txs) { true => { let state_hash = blk.inner().header().state_hash; From 6421dc43e5fda2b4f9dd401c1228629e831465aa Mon Sep 17 00:00:00 2001 From: Herr Seppia Date: Wed, 17 Jan 2024 11:15:12 +0100 Subject: [PATCH 22/22] rusk: update `CHANGELOG.md` --- rusk/CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rusk/CHANGELOG.md b/rusk/CHANGELOG.md index 554869b2b9..d244cff98f 100644 --- a/rusk/CHANGELOG.md +++ b/rusk/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Add iteration generator to FailedIterations [#1257] + +### Changed + +- Change rusk::provisioners to filter out slashed stakes [#1257] +- Change block processing to slash failed-iteration provisioners [#1257] +- Change FailedIterations to include only nil quorum certificates [#1257] + +### Removed + +- Remove allowlist [#1257] + ## [0.7.0] - 2023-12-31 ### Added @@ -173,6 +187,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add linking between Rusk and Protobuff structs - Add build system that generates keys for circuits and caches them. +[#1257]: https://github.com/dusk-network/rusk/pull/1257 [#1219]: https://github.com/dusk-network/rusk/issues/1219 [#401]: https://github.com/dusk-network/rusk/issues/401 [#369]: https://github.com/dusk-network/rusk/issues/369