Skip to content

Commit

Permalink
Merge #4910
Browse files Browse the repository at this point in the history
4910: Add minimum bid amount to add and withdraw bid r=darthsiroftardis a=darthsiroftardis

CHANGELOG:

- Added `minimum_bid_amount` to core config in chainspec which specifies the minimum bid amount in motes
- Changed `add_bid` function to return error if the staked amount is under the minimum amount
- Changed `withdraw_bid` function to completely unbond a validator is their updated stake drops to strictly less than the min bid amount
- Changed `add_bid` from u32 to u64

Closes #4834 



Co-authored-by: Karan Dhareshwar <[email protected]>
  • Loading branch information
2 parents 5a13e6a + 4d58809 commit ce03bbf
Show file tree
Hide file tree
Showing 21 changed files with 129 additions and 59 deletions.
21 changes: 20 additions & 1 deletion execution_engine/src/engine_state/engine_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use num_traits::One;

use casper_types::{
account::AccountHash, FeeHandling, ProtocolVersion, PublicKey, RefundHandling, SystemConfig,
TimeDiff, WasmConfig, DEFAULT_FEE_HANDLING, DEFAULT_REFUND_HANDLING,
TimeDiff, WasmConfig, DEFAULT_FEE_HANDLING, DEFAULT_MINIMUM_BID_AMOUNT,
DEFAULT_REFUND_HANDLING,
};

/// Default value for a maximum query depth configuration option.
Expand Down Expand Up @@ -59,6 +60,7 @@ pub struct EngineConfig {
max_runtime_call_stack_height: u32,
minimum_delegation_amount: u64,
maximum_delegation_amount: u64,
minimum_bid_amount: u64,
/// This flag indicates if arguments passed to contracts are checked against the defined types.
strict_argument_checking: bool,
/// Vesting schedule period in milliseconds.
Expand Down Expand Up @@ -93,6 +95,7 @@ impl Default for EngineConfig {
max_runtime_call_stack_height: DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT,
minimum_delegation_amount: DEFAULT_MINIMUM_DELEGATION_AMOUNT,
maximum_delegation_amount: DEFAULT_MAXIMUM_DELEGATION_AMOUNT,
minimum_bid_amount: DEFAULT_MINIMUM_BID_AMOUNT,
strict_argument_checking: DEFAULT_STRICT_ARGUMENT_CHECKING,
vesting_schedule_period_millis: DEFAULT_VESTING_SCHEDULE_LENGTH_MILLIS,
max_delegators_per_validator: DEFAULT_MAX_DELEGATORS_PER_VALIDATOR,
Expand Down Expand Up @@ -145,6 +148,11 @@ impl EngineConfig {
self.maximum_delegation_amount
}

/// Returns the minimum delegation amount in motes.
pub fn minimum_bid_amount(&self) -> u64 {
self.minimum_bid_amount
}

/// Get the engine config's strict argument checking flag.
pub fn strict_argument_checking(&self) -> bool {
self.strict_argument_checking
Expand Down Expand Up @@ -222,6 +230,7 @@ pub struct EngineConfigBuilder {
max_runtime_call_stack_height: Option<u32>,
minimum_delegation_amount: Option<u64>,
maximum_delegation_amount: Option<u64>,
minimum_bid_amount: Option<u64>,
strict_argument_checking: Option<bool>,
vesting_schedule_period_millis: Option<u64>,
max_delegators_per_validator: Option<u32>,
Expand Down Expand Up @@ -319,6 +328,12 @@ impl EngineConfigBuilder {
self
}

/// Sets the minimum bid amount config option.
pub fn with_minimum_bid_amount(mut self, minimum_bid_amount: u64) -> Self {
self.minimum_bid_amount = Some(minimum_bid_amount);
self
}

/// Sets the administrative accounts.
pub fn with_administrative_accounts(
mut self,
Expand Down Expand Up @@ -390,6 +405,9 @@ impl EngineConfigBuilder {
let maximum_delegation_amount = self
.maximum_delegation_amount
.unwrap_or(DEFAULT_MAXIMUM_DELEGATION_AMOUNT);
let minimum_bid_amount = self
.minimum_bid_amount
.unwrap_or(DEFAULT_MINIMUM_BID_AMOUNT);
let wasm_config = self.wasm_config.unwrap_or_default();
let system_config = self.system_config.unwrap_or_default();
let protocol_version = self.protocol_version.unwrap_or(DEFAULT_PROTOCOL_VERSION);
Expand Down Expand Up @@ -425,6 +443,7 @@ impl EngineConfigBuilder {
max_runtime_call_stack_height,
minimum_delegation_amount,
maximum_delegation_amount,
minimum_bid_amount,
wasm_config,
system_config,
protocol_version,
Expand Down
5 changes: 4 additions & 1 deletion execution_engine/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,13 +1010,15 @@ where
Self::try_get_named_argument(runtime_args, auction::ARG_RESERVED_SLOTS)?
.unwrap_or(0);

let minimum_bid_amount = self.context().engine_config().minimum_bid_amount();
let result = runtime
.add_bid(
account_hash,
delegation_rate,
amount,
minimum_delegation_amount,
maximum_delegation_amount,
minimum_bid_amount,
reserved_slots,
)
.map_err(Self::reverter)?;
Expand All @@ -1029,9 +1031,10 @@ where

let public_key = Self::get_named_argument(runtime_args, auction::ARG_PUBLIC_KEY)?;
let amount = Self::get_named_argument(runtime_args, auction::ARG_AMOUNT)?;
let min_bid_amount = self.context.engine_config().minimum_bid_amount();

let result = runtime
.withdraw_bid(public_key, amount)
.withdraw_bid(public_key, amount, min_bid_amount)
.map_err(Self::reverter)?;
CLValue::from_t(result).map_err(Self::reverter)
})(),
Expand Down
2 changes: 1 addition & 1 deletion execution_engine_testing/test_support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ pub static DEFAULT_ACCOUNTS: Lazy<Vec<GenesisAccount>> = Lazy::new(|| {
/// Default [`ProtocolVersion`].
pub const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = ProtocolVersion::V2_0_0;
/// Default payment.
pub static DEFAULT_PAYMENT: Lazy<U512> = Lazy::new(|| U512::from(2_500_000_000_000u64));
pub static DEFAULT_PAYMENT: Lazy<U512> = Lazy::new(|| U512::from(10_000_000_000_000u64));
/// Default [`WasmConfig`].
pub static DEFAULT_WASM_CONFIG: Lazy<WasmConfig> = Lazy::new(WasmConfig::default);
/// Default [`SystemConfig`].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static ACCOUNT_1_PK: Lazy<PublicKey> = Lazy::new(|| {
const GENESIS_VALIDATOR_STAKE: u64 = 50_000;

static ACCOUNT_1_ADDR: Lazy<AccountHash> = Lazy::new(|| AccountHash::from(&*ACCOUNT_1_PK));
static ACCOUNT_1_FUND: Lazy<U512> = Lazy::new(|| U512::from(1_500_000_000_000u64));
static ACCOUNT_1_FUND: Lazy<U512> = Lazy::new(|| U512::from(10_000_000_000_000u64));
static ACCOUNT_1_BALANCE: Lazy<U512> = Lazy::new(|| *ACCOUNT_1_FUND + 100_000);
static ACCOUNT_1_BOND: Lazy<U512> = Lazy::new(|| U512::from(25_000));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fn should_not_charge_for_create_purse_in_first_time_bond() {
.standard_payment_costs()
.pay;

let add_bid_payment_amount = U512::from(add_bid_cost + pay_cost) * 2;
let add_bid_payment_amount = U512::from(add_bid_cost + pay_cost as u64) * 2;

let sender = *DEFAULT_ACCOUNT_ADDR;
let contract_hash = builder.get_auction_contract_hash();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use casper_types::{
ARG_DELEGATOR, ARG_PUBLIC_KEY, ARG_REWARDS_MAP, ARG_VALIDATOR, DELEGATION_RATE_DENOMINATOR,
METHOD_DISTRIBUTE, SEIGNIORAGE_RECIPIENTS_SNAPSHOT_KEY,
},
EntityAddr, EraId, Key, ProtocolVersion, PublicKey, SecretKey, Timestamp, U512,
EntityAddr, EraId, Key, ProtocolVersion, PublicKey, SecretKey, Timestamp,
DEFAULT_MINIMUM_BID_AMOUNT, U512,
};

const ARG_ENTRY_POINT: &str = "entry_point";
Expand Down Expand Up @@ -1028,11 +1029,13 @@ fn should_distribute_rewards_after_restaking_delegated_funds() {
delegation_rate: 0,
minimum_delegation_amount: updelegate_amount.as_u64(),
maximum_delegation_amount: updelegate_amount.as_u64(),
minimum_bid_amount: DEFAULT_MINIMUM_BID_AMOUNT,
}
} else {
AuctionMethod::WithdrawBid {
public_key: VALIDATOR_1.clone(),
amount,
minimum_bid_amount: DEFAULT_MINIMUM_BID_AMOUNT,
}
}
};
Expand Down
30 changes: 15 additions & 15 deletions execution_engine_testing/tests/src/test/system_costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use casper_types::{
GenesisValidator, HandlePaymentCosts, HostFunction, HostFunctionCost, HostFunctionCosts,
MessageLimits, MintCosts, Motes, OpcodeCosts, ProtocolVersion, PublicKey, RuntimeArgs,
SecretKey, StandardPaymentCosts, StorageCosts, SystemConfig, WasmConfig, DEFAULT_ADD_BID_COST,
DEFAULT_MAX_STACK_HEIGHT, DEFAULT_WASM_MAX_MEMORY, U512,
DEFAULT_MAX_STACK_HEIGHT, DEFAULT_MINIMUM_BID_AMOUNT, DEFAULT_WASM_MAX_MEMORY, U512,
};

use crate::wasm_utils;
Expand All @@ -34,12 +34,12 @@ const VALIDATOR_1_STAKE: u64 = 250_000;
static VALIDATOR_2_SECRET_KEY: Lazy<SecretKey> =
Lazy::new(|| SecretKey::ed25519_from_bytes([124; SecretKey::ED25519_LENGTH]).unwrap());
static VALIDATOR_2: Lazy<PublicKey> = Lazy::new(|| PublicKey::from(&*VALIDATOR_2_SECRET_KEY));
const BOND_AMOUNT: u64 = 42;
const BOND_AMOUNT: u64 = DEFAULT_MINIMUM_BID_AMOUNT + 42;
const BID_AMOUNT: u64 = 99 + DEFAULT_MINIMUM_DELEGATION_AMOUNT;
const TRANSFER_AMOUNT: u64 = 123;
const BID_DELEGATION_RATE: DelegationRate = auction::DELEGATION_RATE_DENOMINATOR;
const UPDATED_CALL_CONTRACT_COST: HostFunctionCost = 12_345;
const NEW_ADD_BID_COST: u32 = 2_500_000_000;
const NEW_ADD_BID_COST: u64 = 2_500_000_000;
const NEW_WITHDRAW_BID_COST: u32 = 2_500_000_000;
const NEW_DELEGATE_COST: u32 = 2_500_000_000;
const NEW_UNDELEGATE_COST: u32 = NEW_DELEGATE_COST;
Expand Down Expand Up @@ -640,62 +640,62 @@ fn should_charge_for_erroneous_system_contract_calls() {
(
auction_hash,
auction::METHOD_WITHDRAW_BID,
system_config.auction_costs().withdraw_bid,
system_config.auction_costs().withdraw_bid.into(),
),
(
auction_hash,
auction::METHOD_DELEGATE,
system_config.auction_costs().delegate,
system_config.auction_costs().delegate.into(),
),
(
auction_hash,
auction::METHOD_UNDELEGATE,
system_config.auction_costs().undelegate,
system_config.auction_costs().undelegate.into(),
),
(
auction_hash,
auction::METHOD_REDELEGATE,
system_config.auction_costs().redelegate,
system_config.auction_costs().redelegate.into(),
),
(
auction_hash,
auction::METHOD_RUN_AUCTION,
system_config.auction_costs().run_auction,
system_config.auction_costs().run_auction.into(),
),
(
auction_hash,
auction::METHOD_SLASH,
system_config.auction_costs().slash,
system_config.auction_costs().slash.into(),
),
(
auction_hash,
auction::METHOD_DISTRIBUTE,
system_config.auction_costs().distribute,
system_config.auction_costs().distribute.into(),
),
(
mint_hash,
mint::METHOD_MINT,
system_config.mint_costs().mint,
system_config.mint_costs().mint.into(),
),
(
mint_hash,
mint::METHOD_REDUCE_TOTAL_SUPPLY,
system_config.mint_costs().reduce_total_supply,
system_config.mint_costs().reduce_total_supply.into(),
),
(
mint_hash,
mint::METHOD_BALANCE,
system_config.mint_costs().balance,
system_config.mint_costs().balance.into(),
),
(
mint_hash,
mint::METHOD_TRANSFER,
system_config.mint_costs().transfer,
system_config.mint_costs().transfer.into(),
),
(
handle_payment_hash,
handle_payment::METHOD_SET_REFUND_PURSE,
system_config.handle_payment_costs().set_refund_purse,
system_config.handle_payment_costs().set_refund_purse.into(),
),
// (
// handle_payment_hash,
Expand Down
6 changes: 3 additions & 3 deletions node/src/components/block_validator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,20 +809,20 @@ async fn ttl() {
.with_num_validators(&mut rng, 1)
.with_transactions(transactions.clone())
.with_count_limits(Some(3000), Some(3000), Some(3000), Some(3000))
.with_block_gas_limit(10_300_000_000_000)
.with_block_gas_limit(15_300_000_000_000)
.include_all_transactions();
let mut transfers_context = ValidationContext::new()
.with_num_validators(&mut rng, 1)
.with_transfers(transfers.clone())
.with_count_limits(Some(3000), Some(3000), Some(3000), Some(3000))
.with_block_gas_limit(10_300_000_000_000)
.with_block_gas_limit(15_300_000_000_000)
.include_all_transfers();
let mut both_context = ValidationContext::new()
.with_num_validators(&mut rng, 1)
.with_transactions(transactions)
.with_transfers(transfers)
.with_count_limits(Some(3000), Some(3000), Some(3000), Some(3000))
.with_block_gas_limit(10_300_000_000_000)
.with_block_gas_limit(15_300_000_000_000)
.include_all_transactions()
.include_all_transfers();

Expand Down
16 changes: 4 additions & 12 deletions node/src/reactor/main_reactor/tests/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2845,22 +2845,13 @@ async fn add_and_withdraw_bid_transaction() {
)
.await;

let transfer_cost: U512 =
U512::from(test.chainspec().system_costs_config.mint_costs().transfer) * MIN_GAS_PRICE;
let min_transfer_amount = U512::from(
test.chainspec()
.transaction_config
.native_transfer_minimum_motes,
);
let half_transfer_cost =
(Ratio::new(U512::from(1), U512::from(2)) * transfer_cost).to_integer();
let transfer_amount = min_transfer_amount * 2 + transfer_cost + half_transfer_cost;
let bid_amount = test.chainspec().core_config.minimum_bid_amount + 10;

let mut txn = Transaction::from(
TransactionV1Builder::new_add_bid(
PublicKey::from(&**BOB_SECRET_KEY),
0,
transfer_amount,
bid_amount,
test.chainspec().core_config.minimum_delegation_amount,
test.chainspec().core_config.maximum_delegation_amount,
)
Expand All @@ -2878,14 +2869,15 @@ async fn add_and_withdraw_bid_transaction() {

let (_, _bob_initial_balance, _) = test.get_balances(None);
let (_txn_hash, _block_height, exec_result) = test.send_transaction(txn).await;
println!("{:?}", exec_result);
assert!(exec_result_is_success(&exec_result));

test.fixture
.run_until_consensus_in_era(ERA_TWO, ONE_MIN)
.await;

let mut txn = Transaction::from(
TransactionV1Builder::new_withdraw_bid(PublicKey::from(&**BOB_SECRET_KEY), transfer_amount)
TransactionV1Builder::new_withdraw_bid(PublicKey::from(&**BOB_SECRET_KEY), bid_amount)
.unwrap()
.with_chain_name(CHAIN_NAME)
.with_initiator_addr(PublicKey::from(&**BOB_SECRET_KEY))
Expand Down
3 changes: 3 additions & 0 deletions resources/local/chainspec.toml.in
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ max_runtime_call_stack_height = 12
minimum_delegation_amount = 500_000_000_000
# Maximum allowed delegation amount in motes
maximum_delegation_amount = 1_000_000_000_000_000_000
# Minimum bid amount allowed in motes. Withdrawing one's bid to an amount strictly less than
# the value specified will be treated as a full unbond of a validator and their associated delegators
minimum_bid_amount = 10_000_000_000_000
# Global state prune batch size (0 = this feature is off)
prune_batch_size = 0
# Enables strict arguments checking when calling a contract; i.e. that all non-optional args are provided and of the correct `CLType`.
Expand Down
5 changes: 4 additions & 1 deletion resources/production/chainspec.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ max_runtime_call_stack_height = 12
minimum_delegation_amount = 500_000_000_000
# Maximum allowed delegation amount in motes
maximum_delegation_amount = 1_000_000_000_000_000_000
# Minimum bid amount allowed in motes. Withdrawing one's bid to an amount strictly less than
# the value specified will be treated as a full unbond of a validator and their associated delegators
minimum_bid_amount = 10_000_000_000_000
# Global state prune batch size (0 = this feature is off)
prune_batch_size = 0
# Enables strict arguments checking when calling a contract; i.e. that all non-optional args are provided and of the correct `CLType`.
Expand Down Expand Up @@ -344,7 +347,7 @@ max_message_size = 1_024
[system_costs.auction_costs]
get_era_validators = 10_000
read_seigniorage_recipients = 10_000
add_bid = 2_500_000_000
add_bid = 5_000_000_000_000
withdraw_bid = 2_500_000_000
delegate = 2_500_000_000
undelegate = 2_500_000_000
Expand Down
Loading

0 comments on commit ce03bbf

Please sign in to comment.