From 7168f9d9fdef9a8fe4178f216bd2854c37c4c9ae Mon Sep 17 00:00:00 2001 From: Christian Krueger Date: Fri, 6 Dec 2024 10:32:49 -0800 Subject: [PATCH] tests passing --- .../js/jito_tip_router/accounts/ballotBox.ts | 16 ++-- .../js/jito_tip_router/types/ballotTally.ts | 9 -- .../src/generated/accounts/ballot_box.rs | 6 +- .../src/generated/types/ballot_tally.rs | 2 - core/src/ballot_box.rs | 92 +++++++++++-------- core/src/base_reward_router.rs | 2 +- idl/jito_tip_router.json | 15 +-- .../tests/tip_router/bpf/set_merkle_root.rs | 2 +- .../tests/tip_router/initialize_ballot_box.rs | 2 +- .../tests/tip_router/set_tie_breaker.rs | 10 +- program/src/cast_vote.rs | 2 +- program/src/lib.rs | 36 -------- text.txt | 0 13 files changed, 79 insertions(+), 115 deletions(-) create mode 100644 text.txt diff --git a/clients/js/jito_tip_router/accounts/ballotBox.ts b/clients/js/jito_tip_router/accounts/ballotBox.ts index 6e26a70a..10496ca3 100644 --- a/clients/js/jito_tip_router/accounts/ballotBox.ts +++ b/clients/js/jito_tip_router/accounts/ballotBox.ts @@ -55,7 +55,7 @@ export type BallotBox = { reserved: Array; operatorsVoted: bigint; uniqueBallots: bigint; - winningBallot: BallotTally; + winningBallotTally: BallotTally; operatorVotes: Array; ballotTallies: Array; }; @@ -70,7 +70,7 @@ export type BallotBoxArgs = { reserved: Array; operatorsVoted: number | bigint; uniqueBallots: number | bigint; - winningBallot: BallotTallyArgs; + winningBallotTally: BallotTallyArgs; operatorVotes: Array; ballotTallies: Array; }; @@ -86,9 +86,9 @@ export function getBallotBoxEncoder(): Encoder { ['reserved', getArrayEncoder(getU8Encoder(), { size: 128 })], ['operatorsVoted', getU64Encoder()], ['uniqueBallots', getU64Encoder()], - ['winningBallot', getBallotTallyEncoder()], - ['operatorVotes', getArrayEncoder(getOperatorVoteEncoder(), { size: 32 })], - ['ballotTallies', getArrayEncoder(getBallotTallyEncoder(), { size: 32 })], + ['winningBallotTally', getBallotTallyEncoder()], + ['operatorVotes', getArrayEncoder(getOperatorVoteEncoder(), { size: 16 })], + ['ballotTallies', getArrayEncoder(getBallotTallyEncoder(), { size: 16 })], ]); } @@ -103,9 +103,9 @@ export function getBallotBoxDecoder(): Decoder { ['reserved', getArrayDecoder(getU8Decoder(), { size: 128 })], ['operatorsVoted', getU64Decoder()], ['uniqueBallots', getU64Decoder()], - ['winningBallot', getBallotTallyDecoder()], - ['operatorVotes', getArrayDecoder(getOperatorVoteDecoder(), { size: 32 })], - ['ballotTallies', getArrayDecoder(getBallotTallyDecoder(), { size: 32 })], + ['winningBallotTally', getBallotTallyDecoder()], + ['operatorVotes', getArrayDecoder(getOperatorVoteDecoder(), { size: 16 })], + ['ballotTallies', getArrayDecoder(getBallotTallyDecoder(), { size: 16 })], ]); } diff --git a/clients/js/jito_tip_router/types/ballotTally.ts b/clients/js/jito_tip_router/types/ballotTally.ts index b1f669e9..0aa4581a 100644 --- a/clients/js/jito_tip_router/types/ballotTally.ts +++ b/clients/js/jito_tip_router/types/ballotTally.ts @@ -8,10 +8,6 @@ import { combineCodec, - fixDecoderSize, - fixEncoderSize, - getBytesDecoder, - getBytesEncoder, getStructDecoder, getStructEncoder, getU16Decoder, @@ -21,7 +17,6 @@ import { type Codec, type Decoder, type Encoder, - type ReadonlyUint8Array, } from '@solana/web3.js'; import { getBallotDecoder, @@ -39,7 +34,6 @@ export type BallotTally = { ballot: Ballot; stakeWeights: StakeWeights; tally: bigint; - reserved: ReadonlyUint8Array; }; export type BallotTallyArgs = { @@ -47,7 +41,6 @@ export type BallotTallyArgs = { ballot: BallotArgs; stakeWeights: StakeWeightsArgs; tally: number | bigint; - reserved: ReadonlyUint8Array; }; export function getBallotTallyEncoder(): Encoder { @@ -56,7 +49,6 @@ export function getBallotTallyEncoder(): Encoder { ['ballot', getBallotEncoder()], ['stakeWeights', getStakeWeightsEncoder()], ['tally', getU64Encoder()], - ['reserved', fixEncoderSize(getBytesEncoder(), 64)], ]); } @@ -66,7 +58,6 @@ export function getBallotTallyDecoder(): Decoder { ['ballot', getBallotDecoder()], ['stakeWeights', getStakeWeightsDecoder()], ['tally', getU64Decoder()], - ['reserved', fixDecoderSize(getBytesDecoder(), 64)], ]); } diff --git a/clients/rust/jito_tip_router/src/generated/accounts/ballot_box.rs b/clients/rust/jito_tip_router/src/generated/accounts/ballot_box.rs index 640a0335..3ae89ad4 100644 --- a/clients/rust/jito_tip_router/src/generated/accounts/ballot_box.rs +++ b/clients/rust/jito_tip_router/src/generated/accounts/ballot_box.rs @@ -26,9 +26,9 @@ pub struct BallotBox { pub reserved: [u8; 128], pub operators_voted: u64, pub unique_ballots: u64, - pub winning_ballot: BallotTally, - pub operator_votes: [OperatorVote; 32], - pub ballot_tallies: [BallotTally; 32], + pub winning_ballot_tally: BallotTally, + pub operator_votes: [OperatorVote; 16], + pub ballot_tallies: [BallotTally; 16], } impl BallotBox { diff --git a/clients/rust/jito_tip_router/src/generated/types/ballot_tally.rs b/clients/rust/jito_tip_router/src/generated/types/ballot_tally.rs index d47f47b7..1b292ec2 100644 --- a/clients/rust/jito_tip_router/src/generated/types/ballot_tally.rs +++ b/clients/rust/jito_tip_router/src/generated/types/ballot_tally.rs @@ -15,6 +15,4 @@ pub struct BallotTally { pub ballot: Ballot, pub stake_weights: StakeWeights, pub tally: u64, - #[cfg_attr(feature = "serde", serde(with = "serde_with::As::"))] - pub reserved: [u8; 64], } diff --git a/core/src/ballot_box.rs b/core/src/ballot_box.rs index 5ac33b38..d3ac9ef9 100644 --- a/core/src/ballot_box.rs +++ b/core/src/ballot_box.rs @@ -59,7 +59,7 @@ pub struct BallotTally { ballot: Ballot, stake_weights: StakeWeights, tally: PodU64, - reserved: [u8; 64], + // reserved: [u8; 64], } impl Default for BallotTally { @@ -69,7 +69,7 @@ impl Default for BallotTally { ballot: Ballot::default(), stake_weights: StakeWeights::default(), tally: PodU64::from(0), - reserved: [0; 64], + // reserved: [0; 64], } } } @@ -81,7 +81,7 @@ impl BallotTally { ballot, stake_weights: *stake_weights, tally: PodU64::from(1), - reserved: [0; 64], + // reserved: [0; 64], } } @@ -105,6 +105,10 @@ impl BallotTally { self.index() == u16::MAX } + pub fn is_valid(&self) -> bool { + !self.is_empty() + } + pub fn increment_tally(&mut self, stake_weights: &StakeWeights) -> Result<(), TipRouterError> { self.stake_weights.increment(stake_weights)?; self.tally = PodU64::from( @@ -194,11 +198,11 @@ pub struct BallotBox { operators_voted: PodU64, unique_ballots: PodU64, - winning_ballot: BallotTally, + winning_ballot_tally: BallotTally, //TODO fix 32 -> MAX_OPERATORS - operator_votes: [OperatorVote; 32], - ballot_tallies: [BallotTally; 32], + operator_votes: [OperatorVote; 16], + ballot_tallies: [BallotTally; 16], } impl Discriminator for BallotBox { @@ -215,10 +219,10 @@ impl BallotBox { slot_consensus_reached: PodU64::from(DEFAULT_CONSENSUS_REACHED_SLOT), operators_voted: PodU64::from(0), unique_ballots: PodU64::from(0), - winning_ballot: BallotTally::default(), + winning_ballot_tally: BallotTally::default(), //TODO fix 32 -> MAX_OPERATORS - operator_votes: [OperatorVote::default(); 32], - ballot_tallies: [BallotTally::default(); 32], + operator_votes: [OperatorVote::default(); 16], + ballot_tallies: [BallotTally::default(); 16], reserved: [0; 128], } } @@ -299,28 +303,38 @@ impl BallotBox { self.operators_voted.into() } + pub fn has_ballot(&self, ballot: &Ballot) -> bool { + self.ballot_tallies.iter().any(|t| t.ballot.eq(ballot)) + } + pub fn is_consensus_reached(&self) -> bool { - self.slot_consensus_reached() > 0 + self.slot_consensus_reached() != DEFAULT_CONSENSUS_REACHED_SLOT + || self.winning_ballot_tally.is_valid() } - pub fn get_winning_ballot(&self) -> Result<&BallotTally, TipRouterError> { - if self.winning_ballot.is_empty() { + pub fn tie_breaker_set(&self) -> bool { + self.slot_consensus_reached() == DEFAULT_CONSENSUS_REACHED_SLOT + && self.winning_ballot_tally.is_valid() + } + + pub fn get_winning_ballot_tally(&self) -> Result<&BallotTally, TipRouterError> { + if self.winning_ballot_tally.is_empty() { Err(TipRouterError::ConsensusNotReached) } else { - Ok(&self.winning_ballot) + Ok(&self.winning_ballot_tally) } } pub fn has_winning_ballot(&self) -> bool { - !self.winning_ballot.is_empty() + !self.winning_ballot_tally.is_empty() } - pub const fn operator_votes(&self) -> &[OperatorVote; 32] { + pub const fn operator_votes(&self) -> &[OperatorVote; 16] { &self.operator_votes } - pub fn set_winning_ballot(&mut self, ballot: BallotTally) { - self.winning_ballot = ballot; + pub fn set_winning_ballot_tally(&mut self, ballot: BallotTally) { + self.winning_ballot_tally = ballot; } fn increment_or_create_ballot_tally( @@ -432,10 +446,10 @@ impl BallotBox { let consensus_reached = ballot_percentage_of_total.greater_than_or_equal(&target_precise_percentage); - if consensus_reached && self.winning_ballot.is_empty() { + if consensus_reached && self.winning_ballot_tally.is_empty() { self.slot_consensus_reached = PodU64::from(current_slot); - self.set_winning_ballot(*max_tally); + self.set_winning_ballot_tally(*max_tally); } Ok(()) @@ -480,19 +494,10 @@ impl BallotBox { // return Err(TipRouterError::TieBreakerNotInPriorVotes); // } - self.slot_consensus_reached = PodU64::from(0); - self.set_winning_ballot(*finalized_ballot_tally); + self.set_winning_ballot_tally(*finalized_ballot_tally); Ok(()) } - pub fn has_ballot(&self, ballot: &Ballot) -> bool { - self.ballot_tallies.iter().any(|t| t.ballot.eq(ballot)) - } - - pub fn tie_breaker_set(&self) -> bool { - self.slot_consensus_reached() == 0 - } - /// Determines if an operator can still cast their vote. /// Returns true when: /// Consensus is not reached OR the voting window is still valid, assuming set_tie_breaker was not invoked @@ -537,7 +542,7 @@ impl BallotBox { if !meta_merkle_tree::verify::verify( proof, - self.winning_ballot.ballot.root(), + self.winning_ballot_tally.ballot.root(), node_hash.to_bytes(), ) { return Err(TipRouterError::InvalidMerkleProof); @@ -635,7 +640,7 @@ mod tests { ); // Test error on changing vote after consensus - ballot_box.set_winning_ballot(*new_tally); + ballot_box.set_winning_ballot_tally(*new_tally); ballot_box.slot_consensus_reached = PodU64::from(new_slot); let result = ballot_box.cast_vote( operator, @@ -704,7 +709,7 @@ mod tests { assert_eq!(ballot_box.ballot_tallies[1].ballot(), ballot2); // Test error when ballot tallies are full - for i in 3..=32 { + for i in 3..=16 { let ballot = Ballot::new([i as u8; 32]); ballot_box .increment_or_create_ballot_tally(&ballot, &stake_weights) @@ -740,7 +745,7 @@ mod tests { DEFAULT_CONSENSUS_REACHED_SLOT ); assert!(matches!( - ballot_box.get_winning_ballot(), + ballot_box.get_winning_ballot_tally(), Err(TipRouterError::ConsensusNotReached) )); @@ -753,7 +758,10 @@ mod tests { .unwrap(); assert!(ballot_box.is_consensus_reached()); assert_eq!(ballot_box.slot_consensus_reached(), current_slot); - assert_eq!(ballot_box.get_winning_ballot().unwrap().ballot(), ballot); + assert_eq!( + ballot_box.get_winning_ballot_tally().unwrap().ballot(), + ballot + ); // Consensus remains after additional votes let ballot2 = Ballot::new([2; 32]); @@ -765,7 +773,10 @@ mod tests { .unwrap(); assert!(ballot_box.is_consensus_reached()); assert_eq!(ballot_box.slot_consensus_reached(), current_slot); - assert_eq!(ballot_box.get_winning_ballot().unwrap().ballot(), ballot); + assert_eq!( + ballot_box.get_winning_ballot_tally().unwrap().ballot(), + ballot + ); // Test with multiple competing ballots let mut ballot_box = BallotBox::new(ncn, epoch, 0, current_slot); @@ -796,7 +807,10 @@ mod tests { .tally_votes(total_stake_weight, current_slot) .unwrap(); assert!(ballot_box.is_consensus_reached()); - assert_eq!(ballot_box.get_winning_ballot().unwrap().ballot(), ballot3); + assert_eq!( + ballot_box.get_winning_ballot_tally().unwrap().ballot(), + ballot3 + ); } #[test] @@ -822,6 +836,7 @@ mod tests { // Test setting tie breaker before voting is stalled let current_epoch = epoch + 1; let epochs_before_stall = 3; + assert_eq!( ballot_box.set_tie_breaker_ballot(ballot1.root(), current_epoch, epochs_before_stall), Err(TipRouterError::VotingNotFinalized) @@ -833,7 +848,10 @@ mod tests { .set_tie_breaker_ballot(ballot1.root(), current_epoch, epochs_before_stall) .unwrap(); assert!(ballot_box.is_consensus_reached()); - assert_eq!(ballot_box.get_winning_ballot().unwrap().ballot(), ballot1); + assert_eq!( + ballot_box.get_winning_ballot_tally().unwrap().ballot(), + ballot1 + ); // Test setting tie breaker with invalid merkle root let mut ballot_box = BallotBox::new(ncn, epoch, 0, current_slot); diff --git a/core/src/base_reward_router.rs b/core/src/base_reward_router.rs index f649ee56..0c273857 100644 --- a/core/src/base_reward_router.rs +++ b/core/src/base_reward_router.rs @@ -170,7 +170,7 @@ impl BaseRewardRouter { &mut self, ballot_box: &BallotBox, ) -> Result<(), TipRouterError> { - let winning_ballot = ballot_box.get_winning_ballot()?; + let winning_ballot = ballot_box.get_winning_ballot_tally()?; let winning_stake_weight = winning_ballot.stake_weights(); for votes in ballot_box.operator_votes().iter() { diff --git a/idl/jito_tip_router.json b/idl/jito_tip_router.json index 66fa1ecd..54b5d4c2 100644 --- a/idl/jito_tip_router.json +++ b/idl/jito_tip_router.json @@ -1356,7 +1356,7 @@ } }, { - "name": "winningBallot", + "name": "winningBallotTally", "type": { "defined": "BallotTally" } @@ -1368,7 +1368,7 @@ { "defined": "OperatorVote" }, - 32 + 16 ] } }, @@ -1379,7 +1379,7 @@ { "defined": "BallotTally" }, - 32 + 16 ] } } @@ -1932,15 +1932,6 @@ "type": { "defined": "PodU64" } - }, - { - "name": "reserved", - "type": { - "array": [ - "u8", - 64 - ] - } } ] } diff --git a/integration_tests/tests/tip_router/bpf/set_merkle_root.rs b/integration_tests/tests/tip_router/bpf/set_merkle_root.rs index 45626efc..36bad34e 100644 --- a/integration_tests/tests/tip_router/bpf/set_merkle_root.rs +++ b/integration_tests/tests/tip_router/bpf/set_merkle_root.rs @@ -204,7 +204,7 @@ mod set_merkle_root { let winning_ballot = Ballot::new(winning_root); let winning_ballot_tally = BallotTally::new(0, winning_ballot, &StakeWeights::default()); - ballot_box.set_winning_ballot(winning_ballot_tally); + ballot_box.set_winning_ballot_tally(winning_ballot_tally); ballot_box }; diff --git a/integration_tests/tests/tip_router/initialize_ballot_box.rs b/integration_tests/tests/tip_router/initialize_ballot_box.rs index 35fafee1..4c99cb8c 100644 --- a/integration_tests/tests/tip_router/initialize_ballot_box.rs +++ b/integration_tests/tests/tip_router/initialize_ballot_box.rs @@ -32,7 +32,7 @@ mod tests { ballot_box.slot_consensus_reached(), DEFAULT_CONSENSUS_REACHED_SLOT ); - assert!(ballot_box.get_winning_ballot().is_err(),); + assert!(ballot_box.get_winning_ballot_tally().is_err(),); Ok(()) } diff --git a/integration_tests/tests/tip_router/set_tie_breaker.rs b/integration_tests/tests/tip_router/set_tie_breaker.rs index c6380e8a..18ad4712 100644 --- a/integration_tests/tests/tip_router/set_tie_breaker.rs +++ b/integration_tests/tests/tip_router/set_tie_breaker.rs @@ -15,7 +15,6 @@ mod tests { ///// TipRouter Setup ///// fixture.snapshot_test_ncn(&test_ncn).await?; - ////// let clock = fixture.clock().await; let slot = clock.slot; @@ -32,8 +31,8 @@ mod tests { let operator = test_ncn.operators[0].operator_pubkey; let operator_admin = &test_ncn.operators[0].operator_admin; - // Cast a vote so that this vote is one of the valid options - // Gets to 50% consensus weight + // // Cast a vote so that this vote is one of the valid options + // // Gets to 50% consensus weight tip_router_client .do_cast_vote(ncn, operator, operator_admin, meta_merkle_root, ncn_epoch) .await?; @@ -57,7 +56,10 @@ mod tests { let ballot = Ballot::new(meta_merkle_root); assert!(ballot_box.has_ballot(&ballot)); - assert_eq!(ballot_box.get_winning_ballot().unwrap().ballot(), ballot); + assert_eq!( + ballot_box.get_winning_ballot_tally().unwrap().ballot(), + ballot + ); // No official consensus reached so no slot set assert_eq!( ballot_box.slot_consensus_reached(), diff --git a/program/src/cast_vote.rs b/program/src/cast_vote.rs index 20e31480..d292d020 100644 --- a/program/src/cast_vote.rs +++ b/program/src/cast_vote.rs @@ -95,7 +95,7 @@ pub fn process_cast_vote( msg!( "Consensus reached for epoch {} with ballot {:?}", epoch, - ballot_box.get_winning_ballot()? + ballot_box.get_winning_ballot_tally()? ); } diff --git a/program/src/lib.rs b/program/src/lib.rs index 507fb183..4e680be8 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -293,41 +293,5 @@ pub fn process_instruction( msg!("Instruction: SetTieBreaker"); process_set_tie_breaker(program_id, accounts, meta_merkle_root, epoch) } - TipRouterInstruction::InitializeBallotBox { epoch } => { - msg!("Instruction: InitializeBallotBox"); - process_initialize_ballot_box(program_id, accounts, epoch) - } - TipRouterInstruction::CastVote { - meta_merkle_root, - epoch, - } => { - msg!("Instruction: CastVote"); - process_cast_vote(program_id, accounts, meta_merkle_root, epoch) - } - TipRouterInstruction::SetMerkleRoot { - proof, - merkle_root, - max_total_claim, - max_num_nodes, - epoch, - } => { - msg!("Instruction: SetMerkleRoot"); - process_set_merkle_root( - program_id, - accounts, - proof, - merkle_root, - max_total_claim, - max_num_nodes, - epoch, - ) - } - TipRouterInstruction::SetTieBreaker { - meta_merkle_root, - epoch, - } => { - msg!("Instruction: SetTieBreaker"); - process_set_tie_breaker(program_id, accounts, meta_merkle_root, epoch) - } } } diff --git a/text.txt b/text.txt new file mode 100644 index 00000000..e69de29b