Re-wrote a bunch of Solana code to avoid all the bloated and unecessary clones
This commit is contained in:
@@ -1,35 +1,31 @@
|
||||
use substreams_solana::pb::sf::solana::r#type::v1::{Block, ConfirmedTransaction};
|
||||
use substreams_solana::pb::sf::solana::r#type::v1::Block;
|
||||
|
||||
// Vote111111111111111111111111111111111111111
|
||||
static VOTE_INSTRUCTION: &'static [u8] = &[7, 97, 72, 29, 53, 116, 116, 187, 124, 77, 118, 36, 235, 211, 189, 179, 216, 53, 94, 115, 209, 16, 67, 252, 13, 163, 83, 128, 0, 0, 0, 0];
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_block_without_votes(block: Block) -> Result<Block, substreams::errors::Error> {
|
||||
let mut block_cloned: Block = block.clone();
|
||||
fn map_block_without_votes(mut block: Block) -> Result<Block, substreams::errors::Error> {
|
||||
block.transactions.retain(|trx| {
|
||||
let meta = match trx.meta.as_ref() {
|
||||
Some(meta) => meta,
|
||||
None => return false,
|
||||
};
|
||||
if meta.err.is_some() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let filtered_transactions: Vec<ConfirmedTransaction> = block.transactions_owned()
|
||||
.filter(|trx| {
|
||||
let meta = match trx.meta.as_ref() {
|
||||
Some(meta) => meta,
|
||||
None => return false,
|
||||
};
|
||||
if meta.err.is_some() {
|
||||
return false;
|
||||
}
|
||||
let transaction = match trx.transaction.as_ref() {
|
||||
Some(transaction) => transaction,
|
||||
None => return false,
|
||||
};
|
||||
let message = transaction.message.as_ref().expect("Message is missing");
|
||||
let transaction = match trx.transaction.as_ref() {
|
||||
Some(transaction) => transaction,
|
||||
None => return false,
|
||||
};
|
||||
let message = transaction.message.as_ref().expect("Message is missing");
|
||||
|
||||
if message.account_keys.contains(&VOTE_INSTRUCTION.to_vec()) {
|
||||
return false;
|
||||
}
|
||||
if message.account_keys.contains(&VOTE_INSTRUCTION.to_vec()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}).collect();
|
||||
true
|
||||
});
|
||||
|
||||
block_cloned.transactions = filtered_transactions;
|
||||
|
||||
Ok(block_cloned)
|
||||
Ok(block)
|
||||
}
|
||||
|
||||
@@ -9,46 +9,39 @@ struct InstructionFilterParams {
|
||||
}
|
||||
|
||||
#[substreams::handlers::map]
|
||||
fn map_filter_instructions(params: String, blk: Block) -> Result<Instructions, Vec<substreams::errors::Error>> {
|
||||
fn map_filter_instructions(params: String, blk: Block) -> Result<Instructions, substreams::errors::Error> {
|
||||
let filters = parse_filters_from_params(params)?;
|
||||
|
||||
let mut instructions : Vec<Instruction> = Vec::new();
|
||||
|
||||
blk.transactions_owned().into_iter().for_each(|tx| {
|
||||
let msg = tx.transaction.clone().unwrap().message.unwrap();
|
||||
let instructions : Vec<Instruction> = blk.transactions().flat_map(|tx| {
|
||||
let msg = tx.transaction.as_ref().unwrap().message.as_ref().unwrap();
|
||||
let acct_keys = tx.resolved_accounts();
|
||||
let insts : Vec<Instruction> = msg.instructions.iter()
|
||||
|
||||
msg.instructions.iter()
|
||||
.filter(|inst| apply_filter(inst, &filters, &acct_keys))
|
||||
.map(|inst| {
|
||||
Instruction {
|
||||
program_id: bs58::encode(acct_keys[inst.program_id_index as usize].to_vec()).into_string(),
|
||||
accounts: inst.accounts.iter().map(|acct| bs58::encode(acct_keys[*acct as usize].to_vec()).into_string()).collect(),
|
||||
data: bs58::encode(inst.data.clone()).into_string(),
|
||||
data: bs58::encode(&inst.data).into_string(),
|
||||
}
|
||||
}).collect();
|
||||
instructions.extend(insts);
|
||||
});
|
||||
}).collect::<Vec<_>>()
|
||||
}).collect();
|
||||
|
||||
Ok(Instructions { instructions })
|
||||
}
|
||||
|
||||
fn parse_filters_from_params(params: String) -> Result<InstructionFilterParams, Vec<substreams::errors::Error>> {
|
||||
let parsed_result = serde_qs::from_str(¶ms);
|
||||
if parsed_result.is_err() {
|
||||
return Err(Vec::from([anyhow!("Unexpected error while parsing parameters")]));
|
||||
fn parse_filters_from_params(params: String) -> Result<InstructionFilterParams, substreams::errors::Error> {
|
||||
match serde_qs::from_str(¶ms) {
|
||||
Ok(filters) => Ok(filters),
|
||||
Err(e) => Err(anyhow!("Failed to parse filters from params: {}", e))
|
||||
}
|
||||
|
||||
let filters = parsed_result.unwrap();
|
||||
//todo: verify_filters(&filters)?;
|
||||
|
||||
Ok(filters)
|
||||
}
|
||||
|
||||
fn apply_filter(instruction: &CompiledInstruction, filters: &InstructionFilterParams, account_keys: &Vec<&Vec<u8>>) -> bool {
|
||||
if filters.program_id.is_none() {
|
||||
return true;
|
||||
}
|
||||
let program_id_filter = filters.program_id.clone().unwrap();
|
||||
let program_id_filter = filters.program_id.as_ref().unwrap();
|
||||
|
||||
let program_account_key = account_keys.get(instruction.program_id_index as usize);
|
||||
if program_account_key.is_none() {
|
||||
@@ -56,7 +49,7 @@ fn apply_filter(instruction: &CompiledInstruction, filters: &InstructionFilterPa
|
||||
}
|
||||
let program_account_key_val = bs58::encode(program_account_key.unwrap()).into_string();
|
||||
|
||||
if program_account_key_val != program_id_filter {
|
||||
if &program_account_key_val != program_id_filter {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ fn map_filter_transactions(params: String, blk: Block) -> Result<Transactions, V
|
||||
.iter()
|
||||
.filter(|tx| apply_filter(tx, &filters))
|
||||
.for_each(|tx| {
|
||||
let msg = tx.transaction.clone().unwrap().message.unwrap();
|
||||
let msg = tx.transaction.as_ref().unwrap().message.as_ref().unwrap();
|
||||
let acct_keys = tx.resolved_accounts();
|
||||
|
||||
let insts: Vec<Instruction> = msg
|
||||
@@ -31,14 +31,14 @@ fn map_filter_transactions(params: String, blk: Block) -> Result<Transactions, V
|
||||
.iter()
|
||||
.map(|acct| bs58::encode(acct_keys[*acct as usize].to_vec()).into_string())
|
||||
.collect(),
|
||||
data: bs58::encode(inst.data.clone()).into_string(),
|
||||
data: bs58::encode(&inst.data).into_string(),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let t = Transaction {
|
||||
signatures: tx
|
||||
.transaction
|
||||
.clone()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.signatures
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user