Skip to content

Commit

Permalink
Merge branch 'eb/set-merkle-fix' into lite-operator
Browse files Browse the repository at this point in the history
  • Loading branch information
ebatsell committed Feb 4, 2025
2 parents 2df202c + 41d6234 commit 070282a
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 24 deletions.
3 changes: 3 additions & 0 deletions tip-router-operator-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ pub enum Commands {

#[arg(long, env)]
override_target_slot: Option<u64>,

#[arg(long, env, default_value = "false")]
set_merkle_roots: bool,
},
SnapshotSlot {
#[arg(short, long, env)]
Expand Down
15 changes: 9 additions & 6 deletions tip-router-operator-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,17 @@ async fn main() -> Result<()> {
let rpc_client = EllipsisClient::from_rpc_with_timeout(
RpcClient::new(cli.rpc_url.clone()),
&read_keypair_file(&cli.keypair_path).expect("Failed to read keypair file"),
60_000,
1_800_000, // 30 minutes
)?;

set_host_id(cli.operator_address.to_string());

// Ensure tx submission works
let test_meta_merkle_root = [1; 32];
let ix = spl_memo::build_memo(&test_meta_merkle_root.to_vec(), &[&keypair.pubkey()]);
info!("Submitting test tx {:?}", test_meta_merkle_root);
let tx = Transaction::new_with_payer(&[ix], Some(&keypair.pubkey()));
rpc_client.process_transaction(tx, &[&keypair]).await?;
// let test_meta_merkle_root = [1; 32];
// let ix = spl_memo::build_memo(&test_meta_merkle_root.to_vec(), &[&keypair.pubkey()]);
// info!("Submitting test tx {:?}", test_meta_merkle_root);
// let tx = Transaction::new_with_payer(&[ix], Some(&keypair.pubkey()));
// rpc_client.process_transaction(tx, &[&keypair]).await?;

info!(
"CLI Arguments:
Expand Down Expand Up @@ -69,6 +69,7 @@ async fn main() -> Result<()> {
num_monitored_epochs,
start_next_epoch,
override_target_slot,
set_merkle_roots,
} => {
info!("Running Tip Router...");
info!("NCN Address: {}", ncn_address);
Expand Down Expand Up @@ -110,6 +111,7 @@ async fn main() -> Result<()> {
&tip_distribution_program_id,
num_monitored_epochs,
&cli_clone,
set_merkle_roots,
)
.await
{
Expand Down Expand Up @@ -240,6 +242,7 @@ async fn main() -> Result<()> {
&tip_router_program_id,
&tip_distribution_program_id,
cli.submit_as_memo,
true,
)
.await?;
}
Expand Down
47 changes: 31 additions & 16 deletions tip-router-operator-cli/src/submit.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::time::Duration;
use std::{path::PathBuf, str::FromStr};

use anchor_lang::AccountDeserialize;
use ellipsis_client::EllipsisClient;
use jito_bytemuck::AccountDeserialize as JitoAccountDeserialize;
use jito_tip_distribution_sdk::{derive_config_account_address, TipDistributionAccount};
use jito_tip_router_core::ballot_box::BallotBox;
use jito_tip_router_core::{ballot_box::BallotBox, config::Config};
use log::{debug, error, info};
use meta_merkle_tree::meta_merkle_tree::MetaMerkleTree;
use solana_account_decoder::UiAccountEncoding;
use solana_client::nonblocking::rpc_client::RpcClient as AsyncRpcClient;
use solana_client::{
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
rpc_filter::{Memcmp, RpcFilterType},
Expand All @@ -28,6 +30,7 @@ pub async fn submit_recent_epochs_to_ncn(
tip_distribution_program_id: &Pubkey,
num_monitored_epochs: u64,
cli_args: &Cli,
set_merkle_roots: bool,
) -> Result<(), anyhow::Error> {
let epoch = client.get_epoch_info()?;
let operator_address = Pubkey::from_str(&cli_args.operator_address)?;
Expand All @@ -52,6 +55,7 @@ pub async fn submit_recent_epochs_to_ncn(
tip_router_program_id,
tip_distribution_program_id,
cli_args.submit_as_memo,
set_merkle_roots,
)
.await
{
Expand All @@ -73,9 +77,11 @@ pub async fn submit_to_ncn(
tip_router_program_id: &Pubkey,
tip_distribution_program_id: &Pubkey,
submit_as_memo: bool,
set_merkle_roots: bool,
) -> Result<(), anyhow::Error> {
let epoch_info = client.get_epoch_info()?;
let meta_merkle_tree = MetaMerkleTree::new_from_file(meta_merkle_tree_path)?;
let config_pda = Config::find_program_address(tip_router_program_id, ncn_address).0;
let config = get_ncn_config(client, tip_router_program_id, ncn_address).await?;

// The meta merkle root files are tagged with the epoch they have created the snapshot for
Expand Down Expand Up @@ -180,16 +186,22 @@ pub async fn submit_to_ncn(
}
}

if ballot_box.is_consensus_reached() {
if ballot_box.is_consensus_reached() && set_merkle_roots {
// Fetch TipDistributionAccounts filtered by epoch and upload authority
// Tip distribution accounts are derived from the epoch they are for
let tip_distribution_accounts = get_tip_distribution_accounts_to_upload(
client,
merkle_root_epoch,
&config_pda,
tip_distribution_program_id,
)
.await?;

info!(
"Setting merkle roots for {} tip distribution accounts",
tip_distribution_accounts.len()
);

// For each TipDistributionAccount returned, if it has no root uploaded, upload root with set_merkle_root
match set_merkle_roots_batched(
client,
Expand Down Expand Up @@ -238,17 +250,17 @@ pub async fn submit_to_ncn(
async fn get_tip_distribution_accounts_to_upload(
client: &EllipsisClient,
epoch: u64,

tip_router_config_address: &Pubkey,
tip_distribution_program_id: &Pubkey,
) -> Result<Vec<(Pubkey, TipDistributionAccount)>, anyhow::Error> {
let config_address = derive_config_account_address(tip_distribution_program_id).0;
let rpc_client = AsyncRpcClient::new_with_timeout(client.url(), Duration::from_secs(1800));

// Filters assume merkle root is None
let filters = vec![
RpcFilterType::Memcmp(Memcmp::new_raw_bytes(
8 // Discriminator
+ 32, // Pubkey - validator_vote_account
config_address.to_bytes().to_vec(),
tip_router_config_address.to_bytes().to_vec(),
)),
RpcFilterType::Memcmp(Memcmp::new_raw_bytes(
8 // Discriminator
Expand All @@ -259,17 +271,19 @@ async fn get_tip_distribution_accounts_to_upload(
)),
];

let tip_distribution_accounts = client.get_program_accounts_with_config(
tip_distribution_program_id,
RpcProgramAccountsConfig {
filters: Some(filters),
account_config: RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64),
..RpcAccountInfoConfig::default()
let tip_distribution_accounts = rpc_client
.get_program_accounts_with_config(
tip_distribution_program_id,
RpcProgramAccountsConfig {
filters: Some(filters),
account_config: RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64),
..RpcAccountInfoConfig::default()
},
..RpcProgramAccountsConfig::default()
},
..RpcProgramAccountsConfig::default()
},
)?;
)
.await?;

let tip_distribution_accounts = tip_distribution_accounts
.into_iter()
Expand All @@ -280,7 +294,8 @@ async fn get_tip_distribution_accounts_to_upload(
Ok(tip_distribution_account) => {
// Double check that GPA filter worked
if tip_distribution_account.epoch_created_at == epoch
&& tip_distribution_account.merkle_root_upload_authority == config_address
&& tip_distribution_account.merkle_root_upload_authority
== *tip_router_config_address
{
Some((pubkey, tip_distribution_account))
} else {
Expand Down
4 changes: 2 additions & 2 deletions tip-router-operator-cli/src/tip_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use jito_tip_router_core::{
epoch_snapshot::{EpochSnapshot, OperatorSnapshot},
epoch_state::EpochState,
};
use log::info;
use log::{error, info};
use meta_merkle_tree::meta_merkle_tree::MetaMerkleTree;
use solana_sdk::{
pubkey::Pubkey,
Expand Down Expand Up @@ -114,7 +114,7 @@ pub async fn set_merkle_roots_batched(
let proof = if let Some(proof) = meta_merkle_node.proof {
proof
} else {
// TODO emit big warning NO PROOF
error!("No proof found for tip distribution account {:?}", key);
return None;
};

Expand Down

0 comments on commit 070282a

Please sign in to comment.