Skip to content

Commit

Permalink
Main (#104)
Browse files Browse the repository at this point in the history
* Fix raw name build (#122)

* Added fetch trees tool (#123)

Fetches a list of trees from an RPC endpoint.

---------

Co-authored-by: Linus Kendall <[email protected]>
  • Loading branch information
Juanito87 and linuskendall authored Oct 2, 2023
1 parent 038fcda commit 75af1ce
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 18 deletions.
38 changes: 20 additions & 18 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ members = [
"nft_ingester",
"tools/acc_forwarder",
"tools/bgtask_creator",
"tools/fetch_trees",
"tools/load_generation",
"tools/tree-status",
"tools/txn_forwarder",
Expand Down
1 change: 1 addition & 0 deletions migration/src/m20230918_182123_add_raw_name_symbol.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use digital_asset_types::dao::asset_data;
use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
Expand Down
17 changes: 17 additions & 0 deletions tools/fetch_trees/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "fetch_trees"
version = "0.7.12"
edition = "2021"
publish = false

[dependencies]
anyhow = "1.0.70"
async-trait = "0.1.53"
borsh = "0.9.1"
clap = { version = "4.2.2", features = ["derive", "cargo"] }
mpl-bubblegum = { git = "https://github.com/metaplex-foundation/mpl-bubblegum.git", rev = "3cb3976d", features = ["no-entrypoint"] }
solana-account-decoder = "~1.14"
solana-client = "~1.14"
solana-sdk = "~1.14"
spl-account-compression = "0.1.8"
tokio = { version = "1.26.0", features = ["full", "tracing"] }
88 changes: 88 additions & 0 deletions tools/fetch_trees/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use {
borsh::{BorshDeserialize, BorshSerialize},
clap::Parser,
solana_account_decoder::UiAccountEncoding,
solana_client::{
nonblocking::rpc_client::RpcClient,
rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
rpc_filter::{Memcmp, RpcFilterType},
rpc_request::MAX_MULTIPLE_ACCOUNTS,
},
solana_sdk::{
account::Account,
pubkey::{Pubkey, PUBKEY_BYTES},
},
spl_account_compression::state::{ConcurrentMerkleTreeHeader, ConcurrentMerkleTreeHeaderData},
};

#[derive(Debug, Parser)]
struct Args {
// Solana RPC endpoint
#[arg(long, short)]
rpc: String,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let args = Args::parse();

let client = RpcClient::new(args.rpc);

// Initialized SPL Account Compression accounts
let config = RpcProgramAccountsConfig {
filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new_raw_bytes(
0,
vec![1u8],
))]),
account_config: RpcAccountInfoConfig {
encoding: Some(UiAccountEncoding::Base64),
..Default::default()
},
..Default::default()
};
let accounts: Vec<(Pubkey, Account)> = client
.get_program_accounts_with_config(&spl_account_compression::id(), config)
.await?;
println!("Received {} accounts", accounts.len());

// Trying to extract authority pubkey
let accounts = accounts
.into_iter()
.filter_map(|(pubkey, account)| {
get_authority(&account.data)
.ok()
.map(|authority| (pubkey, authority))
})
.collect::<Vec<_>>();
println!("Successfully parsed {} accounts", accounts.len());

// Print only accounts where authority owner is bubblegum
let mut id = 1;
for accounts in accounts.chunks(MAX_MULTIPLE_ACCOUNTS) {
let pubkeys = accounts
.iter()
.map(|(_pubkey, authority)| *authority)
.collect::<Vec<_>>();
let authority_accounts = client.get_multiple_accounts(pubkeys.as_slice()).await?;
for (authority_account, (pubkey, _authority)) in authority_accounts.iter().zip(accounts) {
if let Some(account) = authority_account {
if account.owner == mpl_bubblegum::id() {
println!("{} {}", id, pubkey);
id += 1;
}
}
}
}

Ok(())
}

fn get_authority(mut data: &[u8]) -> anyhow::Result<Pubkey> {
// additional checks
let header = ConcurrentMerkleTreeHeader::deserialize(&mut data)?;
let ConcurrentMerkleTreeHeaderData::V1(header) = header.header;
let data = header.try_to_vec()?;

let offset = 4 + 4;
Pubkey::try_from(&data[offset..offset + PUBKEY_BYTES]).map_err(Into::into)
}

0 comments on commit 75af1ce

Please sign in to comment.