Skip to content

Commit

Permalink
implement validator bid transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
Maciej Wójcik committed Feb 27, 2024
1 parent 09e13cb commit dae2bf6
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4478,7 +4478,7 @@ fn should_transfer_validator_bid() {
ARG_AMOUNT => U512::from(SYSTEM_TRANSFER_AMOUNT)
},
)
.build();
.build();

let validator_1_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
Expand All @@ -4488,7 +4488,7 @@ fn should_transfer_validator_bid() {
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();
.build();

let validator_2_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
Expand All @@ -4498,7 +4498,7 @@ fn should_transfer_validator_bid() {
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();
.build();

let delegator_1_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
Expand All @@ -4508,7 +4508,7 @@ fn should_transfer_validator_bid() {
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();
.build();

let delegator_2_fund_request = ExecuteRequestBuilder::standard(
*DEFAULT_ACCOUNT_ADDR,
Expand All @@ -4518,7 +4518,7 @@ fn should_transfer_validator_bid() {
ARG_AMOUNT => U512::from(TRANSFER_AMOUNT)
},
)
.build();
.build();

let validator_1_add_bid_request = ExecuteRequestBuilder::standard(
*NON_FOUNDER_VALIDATOR_1_ADDR,
Expand All @@ -4529,7 +4529,7 @@ fn should_transfer_validator_bid() {
ARG_DELEGATION_RATE => ADD_BID_DELEGATION_RATE_1,
},
)
.build();
.build();

let delegator_1_validator_1_delegate_request = ExecuteRequestBuilder::standard(
*BID_ACCOUNT_1_ADDR,
Expand All @@ -4540,7 +4540,7 @@ fn should_transfer_validator_bid() {
ARG_DELEGATOR => BID_ACCOUNT_1_PK.clone(),
},
)
.build();
.build();

let delegator_2_validator_1_delegate_request = ExecuteRequestBuilder::standard(
*BID_ACCOUNT_2_ADDR,
Expand All @@ -4551,7 +4551,7 @@ fn should_transfer_validator_bid() {
ARG_DELEGATOR => BID_ACCOUNT_2_PK.clone(),
},
)
.build();
.build();

let post_genesis_requests = vec![
system_fund_request,
Expand All @@ -4576,7 +4576,9 @@ fn should_transfer_validator_bid() {

let bids = builder.get_bids();
assert_eq!(bids.len(), 3);
assert!(bids.validator_bid(&NON_FOUNDER_VALIDATOR_2_PK.clone()).is_none());
assert!(bids
.validator_bid(&NON_FOUNDER_VALIDATOR_2_PK.clone())
.is_none());

let validator_1_transfer_request = ExecuteRequestBuilder::standard(
*NON_FOUNDER_VALIDATOR_1_ADDR,
Expand All @@ -4586,21 +4588,29 @@ fn should_transfer_validator_bid() {
ARG_NEW_VALIDATOR => NON_FOUNDER_VALIDATOR_2_PK.clone()
},
)
.build();
.build();

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

let bids = builder.get_bids();
assert_eq!(bids.len(), 3);
let validator_bid = bids.validator_bid(&NON_FOUNDER_VALIDATOR_2_PK.clone()).unwrap();
let validator_bid = bids
.validator_bid(&NON_FOUNDER_VALIDATOR_2_PK.clone())
.unwrap();
assert_eq!(
builder.get_purse_balance(*validator_bid.bonding_purse()),
U512::from(ADD_BID_AMOUNT_1)
);
assert!(bids.validator_bid(&NON_FOUNDER_VALIDATOR_1_PK.clone()).is_none());
assert!(bids
.validator_bid(&NON_FOUNDER_VALIDATOR_1_PK.clone())
.is_none());

assert!(bids
.delegators_by_validator_public_key(&NON_FOUNDER_VALIDATOR_1_PK).is_none());
.delegators_by_validator_public_key(&NON_FOUNDER_VALIDATOR_1_PK)
.is_none());
let delegators = bids
.delegators_by_validator_public_key(&NON_FOUNDER_VALIDATOR_2_PK)
.expect("should have delegators");
Expand Down
20 changes: 11 additions & 9 deletions smart_contracts/contracts/client/transfer_validator/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@
extern crate alloc;

use casper_contract::contract_api::{runtime, system};
use casper_types::{runtime_args, system::auction, PublicKey, U512};

const ARG_VALIDATOR: &str = "validator";
const ARG_NEW_VALIDATOR: &str = "new_validator";
use casper_types::{
runtime_args,
system::auction::{ARG_NEW_VALIDATOR, ARG_VALIDATOR, METHOD_TRANSFER_VALIDATOR},
PublicKey,
};

fn transfer_validator(validator: PublicKey, new_validator: PublicKey) {
let contract_hash = system::get_auction();
let args = runtime_args! {
auction::ARG_VALIDATOR => validator,
auction::ARG_NEW_VALIDATOR => new_validator
ARG_VALIDATOR => validator,
ARG_NEW_VALIDATOR => new_validator
};
runtime::call_contract::<()>(contract_hash, auction::METHOD_TRANSFER_VALIDATOR, args);
runtime::call_contract::<()>(contract_hash, METHOD_TRANSFER_VALIDATOR, args);
}

// Transfer validator.
//
// Accepts current validator's public key and new validator's public key
// where the existing `ValidatorBid` and all related delegators should be transferred.
// Accepts current validator's public key and new validator's public key.
// Updates existing validator bid and all related delegator bids with
// the new validator's public key.
#[no_mangle]
pub extern "C" fn call() {
let validator = runtime::get_named_arg(ARG_VALIDATOR);
Expand Down
45 changes: 39 additions & 6 deletions storage/src/system/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,10 @@ pub trait Auction:
}
}

/// Transfers a `ValidatorBid` and all related delegators from one validator public key to another.
/// Updates a `ValidatorBid` and all related delegator bids to use a new validator public key.
///
/// This in effect "transfers" a validator along with its stake and all delegators
/// from one public key to another.
/// This method can only be called by the existing validator.
///
/// The arguments are the existing validator's key and the new validator's key.
Expand All @@ -719,16 +721,47 @@ pub trait Auction:
}

// verify that a bid for existing validator exists
let validator_addr = BidAddr::from(validator_public_key.clone());
let validator_bid = read_validator_bid(self, &validator_addr.into())?;
let validator_bid_addr = BidAddr::from(validator_public_key.clone());
let mut validator_bid = read_validator_bid(self, &validator_bid_addr.into())?;

// verify that a bid for new validator does not exist yet
let new_validator_addr = BidAddr::from(new_validator_public_key.clone());
if self.read_bid(&new_validator_addr.into())?.is_some() {
let new_validator_bid_addr = BidAddr::from(new_validator_public_key.clone());
if self.read_bid(&new_validator_bid_addr.into())?.is_some() {
return Err(Error::TransferValidatorBid);
}

todo!();
debug!("transferring validator bid from {validator_bid_addr} to {new_validator_bid_addr}");

validator_bid.with_validator_public_key(new_validator_public_key.clone());
self.write_bid(
new_validator_bid_addr.into(),
BidKind::Validator(validator_bid),
)?;

debug!("pruning validator bid {}", validator_bid_addr);
self.prune_bid(validator_bid_addr);

debug!("transferring delegator bids from validator {validator_bid_addr} to {new_validator_bid_addr}");
let delegators = read_delegator_bids(self, &validator_public_key)?;
for mut delegator in delegators {
let delegator_public_key = delegator.delegator_public_key().clone();
let delegator_bid_addr =
BidAddr::new_from_public_keys(&validator_public_key, Some(&delegator_public_key));

delegator.with_validator_public_key(new_validator_public_key.clone());
let new_delegator_bid_addr = BidAddr::new_from_public_keys(
&new_validator_public_key,
Some(&delegator_public_key),
);

self.write_bid(
new_delegator_bid_addr.into(),
BidKind::Delegator(Box::from(delegator)),
)?;

debug!("pruning delegator bid {}", delegator_bid_addr);
self.prune_bid(delegator_bid_addr);
}

Ok(())
}
Expand Down
6 changes: 6 additions & 0 deletions types/src/system/auction/delegator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ impl Delegator {
vesting_schedule,
}
}

/// Sets validator public key
pub fn with_validator_public_key(&mut self, validator_public_key: PublicKey) -> &mut Self {
self.validator_public_key = validator_public_key;
self
}
}

impl CLTyped for Delegator {
Expand Down
6 changes: 6 additions & 0 deletions types/src/system/auction/validator_bid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,12 @@ impl ValidatorBid {
self.inactive = true;
true
}

/// Sets validator public key
pub fn with_validator_public_key(&mut self, validator_public_key: PublicKey) -> &mut Self {
self.validator_public_key = validator_public_key;
self
}
}

impl CLTyped for ValidatorBid {
Expand Down

0 comments on commit dae2bf6

Please sign in to comment.