Skip to content

Commit

Permalink
added in vaultOperatorDelegationVotes
Browse files Browse the repository at this point in the history
  • Loading branch information
coachchucksol committed Nov 14, 2024
1 parent 38f98b5 commit 40e9381
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 60 deletions.
144 changes: 129 additions & 15 deletions core/src/epoch_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,22 +198,70 @@ pub struct OperatorSnapshot {

is_active: PodBool,

operator_index: PodU64,
operator_fee_bps: PodU16,

vault_operator_delegation_count: PodU64,
vault_operator_delegations_registered: PodU64,
valid_operator_vault_delegations: PodU64,

total_votes: PodU128,
reserved: [u8; 256],

reserved: [u8; 128],
// needs to be last item in struct such that it can grow later
vault_operator_votes: [VaultOperatorVotes; 64],
}

#[derive(Debug, Clone, Copy, Zeroable, ShankType, Pod, ShankType)]
#[repr(C)]
pub struct VaultOperatorVotes {
vault: Pubkey,
votes: PodU128,
vault_index: PodU64,
reserved: [u8; 32],
}

impl Default for VaultOperatorVotes {
fn default() -> Self {
Self {
vault: Pubkey::default(),
vault_index: PodU64::from(u64::MAX),
votes: PodU128::from(0),
reserved: [0; 32],
}
}
}

impl VaultOperatorVotes {
pub fn new(vault: Pubkey, votes: u128, vault_index: u64) -> Self {
Self {
vault,
vault_index: PodU64::from(vault_index),
votes: PodU128::from(votes),
reserved: [0; 32],
}
}

pub fn is_empty(&self) -> bool {
self.vault_index() == u64::MAX
}

pub fn vault_index(&self) -> u64 {
self.vault_index.into()
}

pub fn votes(&self) -> u128 {
self.votes.into()
}
}

impl Discriminator for OperatorSnapshot {
const DISCRIMINATOR: u8 = Discriminators::OperatorSnapshot as u8;
}

impl OperatorSnapshot {
pub const MAX_VAULT_OPERATOR_VOTES: usize = 64;

#[allow(clippy::too_many_arguments)]
pub fn new(
operator: Pubkey,
Expand All @@ -222,24 +270,31 @@ impl OperatorSnapshot {
bump: u8,
current_slot: u64,
is_active: bool,
operator_index: u64,
operator_fee_bps: u16,
vault_operator_delegation_count: u64,
) -> Self {
Self {
) -> Result<Self, TipRouterError> {
if vault_operator_delegation_count > Self::MAX_VAULT_OPERATOR_VOTES as u64 {
return Err(TipRouterError::TooManyVaultOperatorDelegations);
}

Ok(Self {
operator,
ncn,
ncn_epoch: PodU64::from(ncn_epoch),
bump,
slot_created: PodU64::from(current_slot),
slot_finalized: PodU64::from(0),
is_active: PodBool::from(is_active),
operator_index: PodU64::from(operator_index),
operator_fee_bps: PodU16::from(operator_fee_bps),
vault_operator_delegation_count: PodU64::from(vault_operator_delegation_count),
vault_operator_delegations_registered: PodU64::from(0),
valid_operator_vault_delegations: PodU64::from(0),
total_votes: PodU128::from(0),
reserved: [0; 128],
}
reserved: [0; 256],
vault_operator_votes: [VaultOperatorVotes::default(); 64],
})
}

pub fn new_active(

Check failure on line 300 in core/src/epoch_snapshot.rs

View workflow job for this annotation

GitHub Actions / lint

this function has too many arguments (8/7)
Expand All @@ -248,16 +303,18 @@ impl OperatorSnapshot {
ncn_epoch: u64,
bump: u8,
current_slot: u64,
operator_index: u64,
operator_fee_bps: u16,
vault_count: u64,
) -> Self {
) -> Result<Self, TipRouterError> {
Self::new(
operator,
ncn,
ncn_epoch,
bump,
current_slot,
true,
operator_index,
operator_fee_bps,
vault_count,
)
Expand All @@ -269,11 +326,22 @@ impl OperatorSnapshot {
ncn_epoch: u64,
bump: u8,
current_slot: u64,
) -> Self {
let mut snapshot = Self::new(operator, ncn, ncn_epoch, bump, current_slot, false, 0, 0);
operator_index: u64,
) -> Result<Self, TipRouterError> {
let mut snapshot = Self::new(
operator,
ncn,
ncn_epoch,
bump,
current_slot,
false,
operator_index,
0,
0,
)?;

snapshot.slot_finalized = PodU64::from(current_slot);
snapshot
Ok(snapshot)
}

pub fn seeds(operator: &Pubkey, ncn: &Pubkey, ncn_epoch: u64) -> Vec<Vec<u8>> {
Expand Down Expand Up @@ -355,27 +423,55 @@ impl OperatorSnapshot {
self.vault_operator_delegations_registered() == self.vault_operator_delegation_count()
}

pub fn insert_vault_operator_votes(
&mut self,
vault: Pubkey,
vault_index: u64,
votes: u128,
) -> Result<(), TipRouterError> {
// Check for duplicate vaults
for vault_operator_vote in self.vault_operator_votes.iter_mut() {
if vault_operator_vote.vault_index() == vault_index {
return Err(TipRouterError::DuplicateVaultOperatorDelegation);
}
}

if self.vault_operator_delegations_registered() > Self::MAX_VAULT_OPERATOR_VOTES as u64 {
return Err(TipRouterError::TooManyVaultOperatorDelegations);
}

self.vault_operator_votes[self.vault_operator_delegations_registered() as usize] =
VaultOperatorVotes::new(vault, votes, vault_index);

Ok(())
}

pub fn increment_vault_operator_delegation_registration(
&mut self,
current_slot: u64,
vault_operator_delegations: u64,
vault: Pubkey,
vault_index: u64,
votes: u128,
) -> Result<(), TipRouterError> {
if self.finalized() {
return Err(TipRouterError::VaultOperatorDelegationFinalized);
}

self.insert_vault_operator_votes(vault, vault_index, votes)?;

self.vault_operator_delegations_registered = PodU64::from(
self.vault_operator_delegations_registered()
.checked_add(1)
.ok_or(TipRouterError::ArithmeticOverflow)?,
);

self.valid_operator_vault_delegations = PodU64::from(
self.valid_operator_vault_delegations()
.checked_add(vault_operator_delegations)
.ok_or(TipRouterError::ArithmeticOverflow)?,
);
if votes > 0 {
self.valid_operator_vault_delegations = PodU64::from(
self.valid_operator_vault_delegations()
.checked_add(1)
.ok_or(TipRouterError::ArithmeticOverflow)?,
);
}

self.total_votes = PodU128::from(
self.total_votes()
Expand Down Expand Up @@ -405,6 +501,8 @@ pub struct VaultOperatorDelegationSnapshot {

is_active: PodBool,

vault_index: PodU64,

st_mint: Pubkey,
total_security: PodU64,
total_votes: PodU128,
Expand All @@ -426,6 +524,7 @@ impl VaultOperatorDelegationSnapshot {
bump: u8,
current_slot: u64,
is_active: bool,
vault_index: u64,
st_mint: Pubkey,
total_security: u64,
total_votes: u128,
Expand All @@ -438,6 +537,7 @@ impl VaultOperatorDelegationSnapshot {
bump,
slot_created: PodU64::from(current_slot),
is_active: PodBool::from(is_active),
vault_index: PodU64::from(vault_index),
st_mint,
total_security: PodU64::from(total_security),
total_votes: PodU128::from(total_votes),
Expand All @@ -453,6 +553,7 @@ impl VaultOperatorDelegationSnapshot {
bump: u8,
current_slot: u64,
st_mint: Pubkey,
vault_index: u64,
total_security: u64,
total_votes: u128,
) -> Self {
Expand All @@ -464,6 +565,7 @@ impl VaultOperatorDelegationSnapshot {
bump,
current_slot,
true,
vault_index,
st_mint,
total_security,
total_votes,
Expand All @@ -477,6 +579,7 @@ impl VaultOperatorDelegationSnapshot {
ncn_epoch: u64,
bump: u8,
current_slot: u64,
vault_index: u64,
st_mint: Pubkey,
) -> Self {
Self::new(
Expand All @@ -487,6 +590,7 @@ impl VaultOperatorDelegationSnapshot {
bump,
current_slot,
false,
vault_index,
st_mint,
0,
0,
Expand All @@ -501,6 +605,7 @@ impl VaultOperatorDelegationSnapshot {
ncn_epoch: u64,
bump: u8,
current_slot: u64,
vault_index: u64,
st_mint: Pubkey,
vault_operator_delegation: &VaultOperatorDelegation,
weight_table: &WeightTable,
Expand Down Expand Up @@ -529,6 +634,7 @@ impl VaultOperatorDelegationSnapshot {
bump,
current_slot,
st_mint,
vault_index,
total_security,
total_votes,
))
Expand Down Expand Up @@ -603,4 +709,12 @@ impl VaultOperatorDelegationSnapshot {
pub fn total_votes(&self) -> u128 {
self.total_votes.into()
}

pub fn vault_index(&self) -> u64 {
self.vault_index.into()
}

pub fn vault(&self) -> Pubkey {

Check failure on line 717 in core/src/epoch_snapshot.rs

View workflow job for this annotation

GitHub Actions / lint

this could be a `const fn`
self.vault
}
}
4 changes: 4 additions & 0 deletions core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ pub enum TipRouterError {
VaultOperatorDelegationFinalized,
#[error("Operator is already finalized - should not happen")]
OperatorFinalized,
#[error("Too many vault operator delegations")]
TooManyVaultOperatorDelegations,
#[error("Duplicate vault operator delegation")]
DuplicateVaultOperatorDelegation,
}

impl<T> DecodeError<T> for TipRouterError {
Expand Down
25 changes: 14 additions & 11 deletions program/src/initialize_operator_snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,39 +99,42 @@ pub fn process_initialize_operator_snapshot(
ncn_operator_okay && operator_ncn_okay
};

let (operator_fee_bps, vault_count, operator_index): (u16, u64, u64) = {
let operator_data = operator.data.borrow();
let operator_account = Operator::try_from_slice_unchecked(&operator_data)?;
(
operator_account.operator_fee_bps.into(),
operator_account.vault_count(),
operator_account.index(),
)
};

let mut operator_snapshot_data: std::cell::RefMut<'_, &mut [u8]> =
operator_snapshot.try_borrow_mut_data()?;
operator_snapshot_data[0] = OperatorSnapshot::DISCRIMINATOR;
let operator_snapshot_account =
OperatorSnapshot::try_from_slice_unchecked_mut(&mut operator_snapshot_data)?;

*operator_snapshot_account = if is_active {
let (operator_fee_bps, vault_count): (u16, u64) = {
let operator_data = operator.data.borrow();
let operator_account = Operator::try_from_slice_unchecked(&operator_data)?;
(
operator_account.operator_fee_bps.into(),
operator_account.vault_count(),
)
};

OperatorSnapshot::new_active(
*operator.key,
*ncn.key,
ncn_epoch,
operator_snapshot_bump,
current_slot,
operator_index,
operator_fee_bps,
vault_count,
)
)?
} else {
OperatorSnapshot::new_inactive(
*operator.key,
*ncn.key,
ncn_epoch,
operator_snapshot_bump,
current_slot,
)
operator_index,
)?
};

// Increment operator registration for an inactive operator
Expand Down
Loading

0 comments on commit 40e9381

Please sign in to comment.