Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix withdraw bid unbonds #5013

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions execution_engine_testing/tests/src/test/regression/ee_1174.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ use casper_types::{
self,
auction::{self, DelegationRate},
},
ApiError, U512,
ApiError, DEFAULT_MINIMUM_BID_AMOUNT, U512,
};

const LARGE_DELEGATION_RATE: DelegationRate = 101;

#[ignore]
#[test]
fn should_run_ee_1174_delegation_rate_too_high() {
let bid_amount = U512::one();
let bid_amount = U512::from(DEFAULT_MINIMUM_BID_AMOUNT);

let mut builder = LmdbWasmTestBuilder::default();
builder.run_genesis(LOCAL_GENESIS_REQUEST.clone());
Expand Down
24 changes: 13 additions & 11 deletions execution_engine_testing/tests/src/test/regression/ee_1217.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use casper_execution_engine::{
engine_state::{engine_config::DEFAULT_MINIMUM_DELEGATION_AMOUNT, Error as CoreError},
execution::ExecError,
};
use casper_types::{runtime_args, system::auction, ApiError, PublicKey, SecretKey, U512};
use casper_types::{
runtime_args, system::auction, ApiError, PublicKey, SecretKey, DEFAULT_MINIMUM_BID_AMOUNT, U512,
};
use once_cell::sync::Lazy;

const CONTRACT_REGRESSION: &str = "ee_1217_regression.wasm";
Expand Down Expand Up @@ -123,7 +125,7 @@ fn should_fail_to_withdraw_bid_from_stored_session_code() {
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => default_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand Down Expand Up @@ -178,7 +180,7 @@ fn should_fail_to_withdraw_bid_from_stored_contract_code() {
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => default_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand Down Expand Up @@ -252,7 +254,7 @@ fn should_fail_to_delegate_from_stored_session_code() {
VALIDATOR_PUBLIC_KEY.to_account_hash(),
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => validator_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand Down Expand Up @@ -332,7 +334,7 @@ fn should_fail_to_delegate_from_stored_contract_code() {
VALIDATOR_PUBLIC_KEY.to_account_hash(),
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => validator_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand Down Expand Up @@ -412,7 +414,7 @@ fn should_fail_to_undelegate_from_stored_session_code() {
VALIDATOR_PUBLIC_KEY.to_account_hash(),
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => validator_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand Down Expand Up @@ -506,7 +508,7 @@ fn should_fail_to_undelegate_from_stored_contract_code() {
VALIDATOR_PUBLIC_KEY.to_account_hash(),
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => validator_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand Down Expand Up @@ -581,7 +583,7 @@ fn should_fail_to_activate_bid_from_stored_session_code() {
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => default_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand All @@ -592,7 +594,7 @@ fn should_fail_to_activate_bid_from_stored_session_code() {
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_WITHDRAW_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => default_public_key_arg.clone(),
},
)
Expand Down Expand Up @@ -647,7 +649,7 @@ fn should_fail_to_activate_bid_from_stored_contract_code() {
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_ADD_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => default_public_key_arg.clone(),
auction::ARG_DELEGATION_RATE => 0u8,
},
Expand All @@ -658,7 +660,7 @@ fn should_fail_to_activate_bid_from_stored_contract_code() {
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_WITHDRAW_BID,
runtime_args! {
auction::ARG_AMOUNT => U512::one(), // zero results in Error::BondTooSmall
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT), // smaller amount results in Error::BondTooSmall
auction::ARG_PUBLIC_KEY => default_public_key_arg.clone(),
},
)
Expand Down
7 changes: 4 additions & 3 deletions execution_engine_testing/tests/src/test/regression/gh_3208.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ use casper_types::{
auction::{self, BidAddr, DelegationRate},
standard_payment,
},
ApiError, GenesisAccount, GenesisValidator, Key, Motes, StoredValue, U512,
ApiError, GenesisAccount, GenesisValidator, Key, Motes, StoredValue,
DEFAULT_MINIMUM_BID_AMOUNT, U512,
};

use crate::lmdb_fixture;
Expand Down Expand Up @@ -188,7 +189,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule()
auction::METHOD_ADD_BID,
runtime_args! {
auction::ARG_PUBLIC_KEY => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(),
auction::ARG_AMOUNT => U512::from(1u64),
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT),
auction::ARG_DELEGATION_RATE => 10 as DelegationRate,
},
)
Expand Down Expand Up @@ -316,7 +317,7 @@ fn should_immediatelly_unbond_genesis_validator_with_zero_day_vesting_schedule_a
auction::METHOD_ADD_BID,
runtime_args! {
auction::ARG_PUBLIC_KEY => DEFAULT_ACCOUNT_PUBLIC_KEY.clone(),
auction::ARG_AMOUNT => U512::from(1u64),
auction::ARG_AMOUNT => U512::from(DEFAULT_MINIMUM_BID_AMOUNT),
auction::ARG_DELEGATION_RATE => 10 as DelegationRate,
},
)
Expand Down
5 changes: 3 additions & 2 deletions execution_engine_testing/tests/src/test/regression/gov_116.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ use casper_storage::data_access_layer::GenesisRequest;
use casper_types::{
runtime_args,
system::auction::{self, DelegationRate, EraValidators, VESTING_SCHEDULE_LENGTH_MILLIS},
GenesisAccount, GenesisValidator, Motes, PublicKey, SecretKey, U256, U512,
GenesisAccount, GenesisValidator, Motes, PublicKey, SecretKey, DEFAULT_MINIMUM_BID_AMOUNT,
U256, U512,
};

const MINIMUM_BONDED_AMOUNT: u64 = 1_000;

/// Validator with smallest stake will withdraw most of his stake to ensure we did move time forward
/// to unlock his whole vesting schedule.
const WITHDRAW_AMOUNT: u64 = MINIMUM_BONDED_AMOUNT - 1;
const WITHDRAW_AMOUNT: u64 = MINIMUM_BONDED_AMOUNT - DEFAULT_MINIMUM_BID_AMOUNT;

/// Initial lockup period
const VESTING_BASE: u64 = DEFAULT_GENESIS_TIMESTAMP_MILLIS + DEFAULT_LOCKED_FUNDS_PERIOD_MILLIS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const CONTRACT_TRANSFER_TO_ACCOUNT_U512: &str = "transfer_to_account_u512.wasm";

// This value is not systemic, as code is added the size of WASM will increase,
// you can change this value to reflect the increase in WASM size.
const HOST_FUNCTION_METRICS_STANDARD_SIZE: usize = 132_461;
const HOST_FUNCTION_METRICS_STANDARD_SIZE: usize = 143_164;
const HOST_FUNCTION_METRICS_STANDARD_GAS_COST: u64 = 422_402_224_490;

/// Acceptable size regression/improvement in percentage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use casper_types::{
ARG_REWARDS_MAP, ARG_VALIDATOR, ERA_ID_KEY, INITIAL_ERA_ID, METHOD_DISTRIBUTE,
},
EntityAddr, EraId, GenesisAccount, GenesisValidator, Key, Motes, ProtocolVersion, PublicKey,
SecretKey, TransactionHash, U256, U512,
SecretKey, TransactionHash, DEFAULT_MINIMUM_BID_AMOUNT, U256, U512,
};

const ARG_TARGET: &str = "target";
Expand Down Expand Up @@ -1940,7 +1940,7 @@ fn fully_undelegated_funds_should_be_released() {
#[ignore]
#[test]
fn should_undelegate_delegators_when_validator_unbonds() {
const VALIDATOR_1_REMAINING_BID: u64 = 1;
const VALIDATOR_1_REMAINING_BID: u64 = DEFAULT_MINIMUM_BID_AMOUNT;
const VALIDATOR_1_WITHDRAW_AMOUNT: u64 = VALIDATOR_1_STAKE - VALIDATOR_1_REMAINING_BID;

let system_fund_request = ExecuteRequestBuilder::standard(
Expand Down Expand Up @@ -2390,6 +2390,205 @@ fn should_undelegate_delegators_when_validator_fully_unbonds() {
);
}

#[ignore]
#[test]
fn should_undelegate_delegators_when_validator_unbonds_below_minimum_bid_amount() {
const VALIDATOR_1_REMAINING_BID: u64 = DEFAULT_MINIMUM_BID_AMOUNT - 1;
const VALIDATOR_1_WITHDRAW_AMOUNT: u64 = VALIDATOR_1_STAKE - VALIDATOR_1_REMAINING_BID;

let system_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_TRANSFER_TO_ACCOUNT,
runtime_args! {
ARG_TARGET => *SYSTEM_ADDR,
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();

let validator_1_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_TRANSFER_TO_ACCOUNT,
runtime_args! {
ARG_TARGET => *VALIDATOR_1_ADDR,
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();

let delegator_1_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_TRANSFER_TO_ACCOUNT,
runtime_args! {
ARG_TARGET => *DELEGATOR_1_ADDR,
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();

let delegator_2_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
CONTRACT_TRANSFER_TO_ACCOUNT,
runtime_args! {
ARG_TARGET => *DELEGATOR_2_ADDR,
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();

let validator_1_add_bid_request = ExecuteRequestBuilder::standard(
*VALIDATOR_1_ADDR,
CONTRACT_ADD_BID,
runtime_args! {
ARG_AMOUNT => U512::from(VALIDATOR_1_STAKE),
ARG_DELEGATION_RATE => VALIDATOR_1_DELEGATION_RATE,
ARG_PUBLIC_KEY => VALIDATOR_1.clone(),
},
)
.build();

let delegator_1_delegate_request = ExecuteRequestBuilder::standard(
*DELEGATOR_1_ADDR,
CONTRACT_DELEGATE,
runtime_args! {
ARG_AMOUNT => U512::from(DELEGATOR_1_STAKE),
ARG_VALIDATOR => VALIDATOR_1.clone(),
ARG_DELEGATOR => DELEGATOR_1.clone(),
},
)
.build();

let delegator_2_delegate_request = ExecuteRequestBuilder::standard(
*DELEGATOR_2_ADDR,
CONTRACT_DELEGATE,
runtime_args! {
ARG_AMOUNT => U512::from(DELEGATOR_2_STAKE),
ARG_VALIDATOR => VALIDATOR_1.clone(),
ARG_DELEGATOR => DELEGATOR_2.clone(),
},
)
.build();

let post_genesis_requests = vec![
system_fund_request,
validator_1_fund_request,
delegator_1_fund_request,
delegator_2_fund_request,
validator_1_add_bid_request,
delegator_1_delegate_request,
delegator_2_delegate_request,
];

let mut timestamp_millis = DEFAULT_GENESIS_TIMESTAMP_MILLIS;
let mut builder = LmdbWasmTestBuilder::default();

builder.run_genesis(LOCAL_GENESIS_REQUEST.clone());

for request in post_genesis_requests {
builder.exec(request).commit().expect_success();
}

// Try to unbond partially. Stake would fall below minimum bid which should force a full
// unbonding.
let validator_1_withdraw_bid = ExecuteRequestBuilder::standard(
*VALIDATOR_1_ADDR,
CONTRACT_WITHDRAW_BID,
runtime_args! {
ARG_PUBLIC_KEY => VALIDATOR_1.clone(),
ARG_AMOUNT => U512::from(VALIDATOR_1_WITHDRAW_AMOUNT),
},
)
.build();

builder
.exec(validator_1_withdraw_bid)
.commit()
.expect_success();

let bids_after = builder.get_bids();
assert!(bids_after.validator_bid(&VALIDATOR_1).is_none());

let unbonding_purses_before = builder.get_unbonds();

let unbond_kind = UnbondKind::Validator(VALIDATOR_1.clone());
let validator_1_era = unbonding_purses_before
.get(&unbond_kind)
.expect("should have unbonding purse")
.first()
.expect("must have unbond")
.eras()
.first()
.expect("should have era");

let unbond_kind = UnbondKind::DelegatedPublicKey(DELEGATOR_1.clone());
let delegator_1_unbonding_purse = unbonding_purses_before
.get(&unbond_kind)
.expect("should have unbonding purse entry")
.first()
.expect("must have unbond")
.eras()
.first()
.expect("should have unbonding purse");

let unbond_kind = UnbondKind::DelegatedPublicKey(DELEGATOR_2.clone());
let delegator_2_unbonding_purse = unbonding_purses_before
.get(&unbond_kind)
.expect("should have unbonding purse entry")
.first()
.expect("must have unbond")
.eras()
.first()
.expect("should have unbonding purse");

assert_eq!(validator_1_era.amount(), &U512::from(VALIDATOR_1_STAKE));
assert_eq!(
delegator_1_unbonding_purse.amount(),
&U512::from(DELEGATOR_1_STAKE)
);
assert_eq!(
delegator_2_unbonding_purse.amount(),
&U512::from(DELEGATOR_2_STAKE)
);

// Process unbonding requests to verify delegators received their stakes
let validator_1 = builder
.get_entity_by_account_hash(*VALIDATOR_1_ADDR)
.expect("should have validator 1 account");
let validator_1_balance_before = builder.get_purse_balance(validator_1.main_purse());

let delegator_1 = builder
.get_entity_by_account_hash(*DELEGATOR_1_ADDR)
.expect("should have delegator 1 account");
let delegator_1_balance_before = builder.get_purse_balance(delegator_1.main_purse());

let delegator_2 = builder
.get_entity_by_account_hash(*DELEGATOR_2_ADDR)
.expect("should have delegator 1 account");
let delegator_2_balance_before = builder.get_purse_balance(delegator_2.main_purse());

for _ in 0..=DEFAULT_UNBONDING_DELAY {
builder.run_auction(timestamp_millis, Vec::new());
timestamp_millis += TIMESTAMP_MILLIS_INCREMENT;
}

let validator_1_balance_after = builder.get_purse_balance(validator_1.main_purse());
let delegator_1_balance_after = builder.get_purse_balance(delegator_1.main_purse());
let delegator_2_balance_after = builder.get_purse_balance(delegator_2.main_purse());

assert_eq!(
validator_1_balance_before + U512::from(VALIDATOR_1_STAKE),
validator_1_balance_after
);
assert_eq!(
delegator_1_balance_before + U512::from(DELEGATOR_1_STAKE),
delegator_1_balance_after
);
assert_eq!(
delegator_2_balance_before + U512::from(DELEGATOR_2_STAKE),
delegator_2_balance_after
);
}

#[ignore]
#[test]
fn should_handle_evictions() {
Expand Down
Loading
Loading