Skip to content

chore: stash resize registered program account xtask #1904

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use light_merkle_tree_metadata::{

use crate::{
constants::{
ADDRESS_BLOOM_FILTER_CAPACITY, ADDRESS_BLOOM_FILTER_NUM_HASHES,
DEFAULT_ADDRESS_ZKP_BATCH_SIZE, DEFAULT_BATCH_ADDRESS_TREE_HEIGHT,
DEFAULT_BATCH_ROOT_HISTORY_LEN, DEFAULT_BATCH_SIZE,
},
Expand Down Expand Up @@ -39,12 +40,12 @@ impl Default for InitAddressTreeAccountsInstructionData {
index: 0,
program_owner: None,
forester: None,
bloom_filter_num_iters: 3,
bloom_filter_num_iters: ADDRESS_BLOOM_FILTER_NUM_HASHES,
input_queue_batch_size: DEFAULT_BATCH_SIZE,
input_queue_zkp_batch_size: DEFAULT_ADDRESS_ZKP_BATCH_SIZE,
height: 40,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: DEFAULT_BATCH_SIZE * 8,
bloom_filter_capacity: ADDRESS_BLOOM_FILTER_CAPACITY,
network_fee: Some(5000),
rollover_threshold: Some(95),
close_threshold: None,
Expand Down Expand Up @@ -182,12 +183,12 @@ pub mod test_utils {
index: 0,
program_owner: None,
forester: None,
bloom_filter_num_iters: 3,
bloom_filter_num_iters: ADDRESS_BLOOM_FILTER_NUM_HASHES,
input_queue_batch_size: TEST_DEFAULT_BATCH_SIZE,
input_queue_zkp_batch_size: TEST_DEFAULT_ZKP_BATCH_SIZE,
height: 40,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: 20_000 * 8,
bloom_filter_capacity: ADDRESS_BLOOM_FILTER_CAPACITY,
network_fee: Some(5000),
rollover_threshold: Some(95),
close_threshold: None,
Expand All @@ -199,12 +200,12 @@ pub mod test_utils {
index: 0,
program_owner: None,
forester: None,
bloom_filter_num_iters: 3,
bloom_filter_num_iters: ADDRESS_BLOOM_FILTER_NUM_HASHES,
input_queue_batch_size: 500,
input_queue_zkp_batch_size: TEST_DEFAULT_ZKP_BATCH_SIZE,
height: 40,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: 20_000 * 8,
bloom_filter_capacity: ADDRESS_BLOOM_FILTER_CAPACITY,
network_fee: Some(5000),
rollover_threshold: Some(95),
close_threshold: None,
Expand Down
15 changes: 8 additions & 7 deletions program-libs/batched-merkle-tree/src/initialize_state_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use light_merkle_tree_metadata::{

use crate::{
constants::{
DEFAULT_BATCH_SIZE, DEFAULT_BATCH_STATE_TREE_HEIGHT, DEFAULT_CPI_CONTEXT_ACCOUNT_SIZE,
DEFAULT_ZKP_BATCH_SIZE,
ADDRESS_BLOOM_FILTER_CAPACITY, ADDRESS_BLOOM_FILTER_NUM_HASHES,
DEFAULT_BATCH_ROOT_HISTORY_LEN, DEFAULT_BATCH_SIZE, DEFAULT_BATCH_STATE_TREE_HEIGHT,
DEFAULT_CPI_CONTEXT_ACCOUNT_SIZE, DEFAULT_ZKP_BATCH_SIZE,
},
errors::BatchedMerkleTreeError,
merkle_tree::{get_merkle_tree_account_size, BatchedMerkleTreeAccount},
Expand Down Expand Up @@ -48,14 +49,14 @@ impl Default for InitStateTreeAccountsInstructionData {
program_owner: None,
forester: None,
additional_bytes: DEFAULT_CPI_CONTEXT_ACCOUNT_SIZE,
bloom_filter_num_iters: 3,
bloom_filter_num_iters: ADDRESS_BLOOM_FILTER_NUM_HASHES,
input_queue_batch_size: DEFAULT_BATCH_SIZE,
output_queue_batch_size: DEFAULT_BATCH_SIZE,
input_queue_zkp_batch_size: DEFAULT_ZKP_BATCH_SIZE,
output_queue_zkp_batch_size: DEFAULT_ZKP_BATCH_SIZE,
height: DEFAULT_BATCH_STATE_TREE_HEIGHT,
root_history_capacity: (DEFAULT_BATCH_SIZE / DEFAULT_ZKP_BATCH_SIZE * 2) as u32,
bloom_filter_capacity: DEFAULT_BATCH_SIZE * 8,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: ADDRESS_BLOOM_FILTER_CAPACITY,
network_fee: Some(5000),
rollover_threshold: Some(95),
close_threshold: None,
Expand Down Expand Up @@ -259,7 +260,7 @@ pub mod test_utils {
program_owner: None,
forester: None,
additional_bytes: DEFAULT_CPI_CONTEXT_ACCOUNT_SIZE,
bloom_filter_num_iters: 3,
bloom_filter_num_iters: ADDRESS_BLOOM_FILTER_NUM_HASHES,
input_queue_batch_size: TEST_DEFAULT_BATCH_SIZE,
output_queue_batch_size: TEST_DEFAULT_BATCH_SIZE,
input_queue_zkp_batch_size: TEST_DEFAULT_ZKP_BATCH_SIZE,
Expand All @@ -279,7 +280,7 @@ pub mod test_utils {
program_owner: None,
forester: None,
additional_bytes: DEFAULT_CPI_CONTEXT_ACCOUNT_SIZE,
bloom_filter_num_iters: 3,
bloom_filter_num_iters: ADDRESS_BLOOM_FILTER_NUM_HASHES,
input_queue_batch_size: 500,
output_queue_batch_size: 500,
input_queue_zkp_batch_size: TEST_DEFAULT_ZKP_BATCH_SIZE,
Expand Down
47 changes: 47 additions & 0 deletions scripts/create-batched-state-trees.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

# Base directory for keypairs
KEYPAIR_DIR="../light-keypairs/batched-tree-keypairs"

# Command template
CMD_TEMPLATE="cargo xtask create-batch-state-tree --mt-pubkey {SMT} --nfq-pubkey {NFQ} --cpi-pubkey {CPI} --index {INDEX} --network devnet"

# Collect sorted key files for each type
SMT_KEYS=($(ls $KEYPAIR_DIR/bmt*.json | sort))
NFQ_KEYS=($(ls $KEYPAIR_DIR/oq*.json | sort))
CPI_KEYS=($(ls $KEYPAIR_DIR/cpi*.json | sort))

# Ensure equal number of keys for each type
if [[ ${#SMT_KEYS[@]} -ne ${#NFQ_KEYS[@]} || ${#NFQ_KEYS[@]} -ne ${#CPI_KEYS[@]} ]]; then
echo "Error: Mismatched number of SMT, NFQ, and CPI key files."
exit 1
fi

# Execute the command for each triple
for i in "${!SMT_KEYS[@]}"; do
SMT_KEY="${SMT_KEYS[i]}"
NFQ_KEY="${NFQ_KEYS[i]}"
CPI_KEY="${CPI_KEYS[i]}"
INDEX=$((i + 30))

# Replace placeholders in the command template
CMD=${CMD_TEMPLATE//\{SMT\}/"$SMT_KEY"}
CMD=${CMD//\{NFQ\}/"$NFQ_KEY"}
CMD=${CMD//\{CPI\}/"$CPI_KEY"}
CMD=${CMD//\{INDEX\}/"$INDEX"}

echo "Executing: $CMD"
eval "$CMD"

done

echo "All batch state trees created."

# Create batch address tree using the first amt keypair
echo "Creating batch address tree..."
AMT_KEY="$(ls $KEYPAIR_DIR/amt*.json | sort | head -n 1)"
ADDR_CMD="cargo xtask create-batch-address-tree --mt-pubkey $AMT_KEY --network devnet"
echo "Executing: $ADDR_CMD"
eval "$ADDR_CMD"

echo "All commands executed."
Empty file modified scripts/create-state-trees.sh
100755 → 100644
Empty file.
49 changes: 49 additions & 0 deletions scripts/deploy-devnet-upgrade.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# assumes that programs have been build with build-verifiable.sh
# Creates buffer accounts
# Buffer account addresses can be used in multisig action

# Array of program names
libraries=("account_compression" "light_compressed_token" "light_system_program_pinocchio" "light_registry")
program_ids=("compr6CUsB5m2jS4Y3831ztGSTnDpnKJTKS95d64XVq" "cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m" "SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7" "Lighton6oQpVkeewmo2mcPTQQp7kYHr4fWpAgJyEmDX")

BUFFER_KEYPAIR_PATH="target/buffer"


create_buffer_account() {
local max_retries=5
local attempt=1

local program_name="$1"
local program_id="$2"

while (( attempt <= max_retries )); do
echo "Attempt $attempt of $max_retries..."
echo "$BUFFER_KEYPAIR_PATH/$program_name-keypair.json"
echo "Program ID for $program_name: $program_id"
if solana program deploy target/deploy/"$program_name".so --program-id $program_id --buffer "$BUFFER_KEYPAIR_PATH/$program_name-keypair.json" --upgrade-authority ../../.config/solana/id.json; then
echo "Command succeeded on attempt $attempt."
return 0
else
echo "Command failed on attempt $attempt."
((attempt++))
sleep 2
fi
((attempt++))
done

echo "Command failed after $max_retries attempts."
return 1
}



# Iterate over each program and create buffer accounts
for i in "${!program_ids[@]}"; do
program_id="${program_ids[$i]}"
program_name="${libraries[$i]}"

if [[ ! -f "$BUFFER_KEYPAIR_PATH/$program_name-keypair.json" ]]; then
solana-keygen new --outfile "$BUFFER_KEYPAIR_PATH/$program_name-keypair.json" --no-bip39-passphrase
fi
create_buffer_account "$program_name" "$program_id"
done
Empty file modified scripts/install.sh
100755 → 100644
Empty file.
2 changes: 1 addition & 1 deletion sdk-libs/program-test/src/accounts/state_tree_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub async fn create_batched_state_merkle_tree<R: Rpc>(
data: instruction.data(),
}
};

println!("instruction {:?}", instruction);
rpc.create_and_send_transaction(
&[
create_mt_account_ix,
Expand Down
1 change: 1 addition & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ solana-client = { workspace = true }
solana-transaction-status = { workspace = true }
light-batched-merkle-tree = { workspace = true }
light-registry = { workspace = true }
anchor-lang = { workspace = true }
1 change: 1 addition & 0 deletions xtask/src/create_batch_address_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub async fn create_batch_address_tree(options: Options) -> anyhow::Result<()> {
"creating address Merkle tree: \n\tmt {:?}",
merkle_tree_keypair.pubkey(),
);
println!("config {:?}", config);
let balance = rpc.get_balance(&payer.pubkey()).await.unwrap();
println!("Payer balance: {:?}", balance);
let tx_hash =
Expand Down
4 changes: 3 additions & 1 deletion xtask/src/create_batch_state_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ pub async fn create_batch_state_tree(options: Options) -> anyhow::Result<()> {
};
println!("read payer: {:?}", payer.pubkey());

let config = if let Some(config) = options.config {
let mut config = if let Some(config) = options.config {
if config == "testnet" {
InitStateTreeAccountsInstructionData::testnet_default()
} else {
Expand All @@ -113,6 +113,7 @@ pub async fn create_batch_state_tree(options: Options) -> anyhow::Result<()> {
} else {
InitStateTreeAccountsInstructionData::default()
};
config.index = options.index as u64;

for ((merkle_tree_keypair, nullifier_queue_keypair), cpi_context_keypair) in mt_keypairs
.iter()
Expand All @@ -126,6 +127,7 @@ pub async fn create_batch_state_tree(options: Options) -> anyhow::Result<()> {
cpi_context_keypair.pubkey(),
options.index
);
println!("config {:?}", config);
let balance = rpc.get_balance(&payer.pubkey()).await.unwrap();
println!("Payer balance: {:?}", balance);
let tx_hash = create_batched_state_merkle_tree(
Expand Down
7 changes: 7 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod export_photon_test_data;
mod fee;
mod hash_set;
mod new_deployment;
mod resize_registered_program_pda;
mod type_sizes;
mod utils;
mod zero_bytes;
Expand Down Expand Up @@ -57,6 +58,9 @@ enum Command {
InitNewDeployment(new_deployment::Options),
/// cargo xtask create-update-protocol-config --slot-length <u64>
CreateUpdateProtocolConfigIx(create_update_protocol_config_ix::Options),
/// Resize registered program PDA to match current program structure
/// Example: cargo xtask resize-registered-program-pda --network devnet
ResizeRegisteredProgramPda(resize_registered_program_pda::Options),
}

#[tokio::main]
Expand Down Expand Up @@ -89,5 +93,8 @@ async fn main() -> Result<(), anyhow::Error> {
Command::CreateUpdateProtocolConfigIx(opts) => {
create_update_protocol_config_ix::create_update_protocol_config_ix(opts).await
}
Command::ResizeRegisteredProgramPda(opts) => {
resize_registered_program_pda::resize_registered_program_pda(opts).await
}
}
}
115 changes: 115 additions & 0 deletions xtask/src/resize_registered_program_pda.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
use std::{path::PathBuf, str::FromStr};

use anchor_lang::{InstructionData, ToAccountMetas};
use clap::Parser;
use dirs::home_dir;
use light_client::rpc::{LightClient, LightClientConfig, Rpc};
use solana_sdk::{
instruction::Instruction,
signature::{read_keypair_file, Signer},
};

#[derive(Debug, Parser)]
pub struct Options {
#[clap(long)]
payer: Option<PathBuf>,
/// mainnet, devnet, local, default: local
#[clap(long)]
network: Option<String>,
/// mainnet, testnet
#[clap(long)]
config: Option<String>,
}

pub async fn resize_registered_program_pda(options: Options) -> anyhow::Result<()> {
let rpc_url = if let Some(network) = options.network {
if network == "local" {
String::from("http://127.0.0.1:8899")
} else if network == "devnet" {
String::from("https://api.devnet.solana.com")
} else if network == "mainnet" {
String::from("https://api.mainnet-beta.solana.com")
} else {
network.to_string()
}
} else {
String::from("http://127.0.0.1:8899")
};

let mut rpc = LightClient::new(LightClientConfig {
url: rpc_url,
photon_url: None,
commitment_config: None,
fetch_active_tree: false,
api_key: None,
})
.await
.unwrap();

let payer = if let Some(payer_path) = options.payer {
read_keypair_file(payer_path).expect("Failed to read payer keypair")
} else {
let home_dir = home_dir().unwrap();
let payer_path = home_dir.join(".config/solana/id.json");
read_keypair_file(payer_path).expect("Failed to read payer keypair")
};

// Programs to resize
let programs_to_resize = vec![
(
"Light System Program",
solana_sdk::pubkey::Pubkey::from_str("SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7")
.unwrap(),
),
(
"Light Registry Program",
solana_sdk::pubkey::Pubkey::from_str("Lighton6oQpVkeewmo2mcPTQQp7kYHr4fWpAgJyEmDX")
.unwrap(),
),
];

for (program_name, program_id) in programs_to_resize {
println!("Resizing registered program PDA for {}", program_name);
println!("Program ID: {}", program_id);

// Calculate the registered program PDA
let registered_program_pda = solana_sdk::pubkey::Pubkey::find_program_address(
&[program_id.to_bytes().as_slice()],
&account_compression::ID,
)
.0;

println!("Registered program PDA: {}", registered_program_pda);

let instruction_data = account_compression::instruction::ResizeRegisteredProgramPda {};
let accounts = account_compression::accounts::ResizeRegisteredProgramPda {
authority: payer.pubkey(),
registered_program_pda,
system_program: solana_sdk::system_program::ID,
};

let instruction = Instruction {
program_id: account_compression::ID,
accounts: accounts.to_account_metas(Some(true)),
data: instruction_data.data(),
};

println!("Sending resize transaction for {}...", program_name);
match rpc
.create_and_send_transaction(&[instruction], &payer.pubkey(), &[&payer])
.await
{
Ok(signature) => {
println!("✓ Successfully resized {} PDA!", program_name);
println!(" Transaction signature: {}", signature);
}
Err(e) => {
println!("✗ Failed to resize {} PDA: {}", program_name, e);
// Continue with the next program instead of failing entirely
}
}
println!();
}

Ok(())
}
Loading