Skip to content
Open
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
3 changes: 2 additions & 1 deletion indexer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ dotenv = "0.15.0"
futures = "0.3"
solana-transaction-status = "1.7.0"
solana-sdk = "1.7.0"
itertools = "0.10.0"
itertools = "0.10.0"
time ="0.3.0-alpha-2"
4 changes: 2 additions & 2 deletions indexer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ diesel migration redo
```
# Create DB
```
diesel migration redo
```
diesel migration run
```
26 changes: 26 additions & 0 deletions indexer/notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Error RPC limit rate
```
{
"jsonrpc": "2.0",
"error": {
"code": 429,
"message": "Too requests for a specific RPC call, contact your app developer or support@rpcpool.com."
},
"id": 1
}
```
# getEpochInfo response
```
{
"jsonrpc": "2.0",
"result": {
"absoluteSlot": 61766440,
"blockHeight": 61223473,
"epoch": 142,
"slotIndex": 422440,
"slotsInEpoch": 432000,
"transactionCount": 354013845
},
"id": 1
}
```
95 changes: 43 additions & 52 deletions indexer/src/decode_solana.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,38 @@
use solana_transaction_status::{EncodedTransaction,UiTransactionEncoding};
use solana_sdk;
use solana_sdk::{
program_utils::limited_deserialize,
transaction::Transaction,
pubkey::Pubkey,
system_instruction::SystemInstruction,
instruction::CompiledInstruction,
instruction::CompiledInstruction, program_utils::limited_deserialize, pubkey::Pubkey,
system_instruction::SystemInstruction, transaction::Transaction,
};

use solana_transaction_status::{EncodedTransaction, UiTransactionEncoding};

//use regex::Error;
use solana_sdk::instruction::InstructionError;
//use core::panicking::assert_failed;


pub fn decode_transaction(blob: &str, base_mode: &str) -> Option<Transaction>{
pub fn decode_transaction(blob: &str, base_mode: &str) -> Option<Transaction> {
let transaction = match base_mode {
"base64" => {
EncodedTransaction::Binary(
blob.to_string(),
UiTransactionEncoding::Base64,
)
}
_ => panic!("not support other base")
"base64" => EncodedTransaction::Binary(blob.to_string(), UiTransactionEncoding::Base64),
_ => panic!("not support other base"),
};
transaction.decode()
}

pub fn decode_instruction_data(instruction: CompiledInstruction, account_keys: Vec<Pubkey>) -> Option<Result<SystemInstruction, InstructionError>> {
let id:usize = instruction.program_id_index as usize;
let program_pubkey = account_keys[id];
pub fn decode_instruction_data(
instruction: CompiledInstruction,
account_keys: Vec<Pubkey>,
) -> Option<Result<SystemInstruction, InstructionError>> {
let id: usize = instruction.program_id_index as usize;
let program_pubkey = account_keys[id];
let si;
if program_pubkey == solana_sdk::system_program::id() {
si = Some(limited_deserialize::<SystemInstruction,>(&instruction.data));
si = Some(limited_deserialize::<SystemInstruction>(&instruction.data));
si
}
else{
} else {
None
}
}

pub fn get_sol_transfer_in_transaction(transaction: Transaction) -> u128{
pub fn get_sol_transfer_in_transaction(transaction: Transaction) -> u128 {
/// Todo: Check transaction is success before add to result
let mut sol_transfer = 0u128;
let message = &transaction.message;
Expand All @@ -52,70 +44,69 @@ pub fn get_sol_transfer_in_transaction(transaction: Transaction) -> u128{
//println!("program_pubkey: {:?}, system_program_id: {:?}",program_pubkey,system_program_id);

/// Todo: Implement to get transfer in the Inner Instructions
if program_pubkey==system_program_id {
if program_pubkey == system_program_id {
/// If this instruction is run by system program
//println!("program_pubkey: {:?}, system_program_id: {:?}",program_pubkey,system_program_id);
let data = &message.instructions[0].data;
/// Decode instruction data
let system_instruction =
limited_deserialize::<solana_sdk::system_instruction::SystemInstruction, >(data);
limited_deserialize::<solana_sdk::system_instruction::SystemInstruction>(data);
match system_instruction {
Ok(si) => {
match si {
SystemInstruction::Transfer { lamports } => {
println!("Add lamports: {}, to sol_transfer: {}", lamports, sol_transfer);
//println!("Add lamports: {}, to sol_transfer: {}", lamports, sol_transfer);
sol_transfer += lamports as u128;
},
SystemInstruction::TransferWithSeed { lamports,from_seed,from_owner } => {
println!("Add lamports: {}, to sol_transfer: {}", lamports, sol_transfer);
}
SystemInstruction::TransferWithSeed {
lamports,
from_seed,
from_owner,
} => {
//println!("Add lamports: {}, to sol_transfer: {}", lamports, sol_transfer);
sol_transfer += lamports as u128;
},
}
_ => continue,
}
},
_ => continue
}
_ => continue,
};
}

}

sol_transfer
}









#[cfg(test)]
mod tests {
#[test]
fn test_decode_transfer() {
let encode_trans = "AZkhMW7dbIZfg3bvFtC60K9u19pnj8RCvZZTv5C2FHB6pWM2HLKaBk/VjrGAnalO/u26tl85eD7T6n0LxqkimgIBAAEDClrNBKMsMKt9IZ8AiJwWnXOyVj1N+ZkcCh9K8GlRngvQbX6GZxfU+TTnG855FaE8v+EXQfNVQW+lbFylHELYQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAzhkJF3mQT9yv74RHe6sNTN9GnOgE9r9iaLbKF9z4oBAgIAAQwCAAAAwNRUBwAAAAA=";
//let encode_trans = "AauO9UickwsDYNWMZH2+DpsvgRXaJ6uYHedM6uMIXvepOmuC/REtcq3yKbDyicCCaOoCQvaITXluMB83Mh52YQEBAAIGdxpKE4kvtsE/HVIYAFjMuYdVmfVSPQsDDyxNrnjnlm790TnNvRMZIWiMfldkdMVvqnPfFAA5+M4xfvuyR/xg3/Gm32WPol4nQOkIkxg3cLzqAY97RTRNCoyLLFuYoeNvDzgJ2D1NxLLY37ddnFlvb8p49JufrVov/d9MuWpR+6GFDy1uAqR6+CTQmradxC1wyyjL+iSft+5XudJWwSdi7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeYUXxaZrV1d1+JF9Txvwqnk/wzUGplyS8B/j2O6m1AECBAUBAgMCAgcAAwAAAAEABQIAAAwCAAAAmA8AAAAAAAA=";
let transaction = EncodedTransaction::Binary(encode_trans.to_string(),
UiTransactionEncoding::Base64,
let transaction =
EncodedTransaction::Binary(encode_trans.to_string(), UiTransactionEncoding::Base64);
println!(
"Decode Transaction {:#?}",
&transaction.decode().unwrap().message.instructions[0].data
);
println!("Decode Transaction {:#?}", &transaction.decode().unwrap().message.instructions[0].data);

let data = &transaction.decode().unwrap().message.instructions[0].data;

//if program_pubkey == solana_sdk::system_program::id() {
let system_instruction =
limited_deserialize::<solana_sdk::system_instruction::SystemInstruction, >(data);
limited_deserialize::<solana_sdk::system_instruction::SystemInstruction>(data);
println!("Decode Intruction data: {:#?}", system_instruction);
match system_instruction {
Ok(si) => {
match si {
SystemInstruction::Transfer { lamports } => assert_eq!(lamports, 123000000),
SystemInstruction::TransferWithSeed { lamports,from_seed,from_owner } => panic!("Not Transfer as expected"),
_ => panic!("Not Transfer as expected"),
}
Ok(si) => match si {
SystemInstruction::Transfer { lamports } => assert_eq!(lamports, 123000000),
SystemInstruction::TransferWithSeed {
lamports,
from_seed,
from_owner,
} => panic!("Not Transfer as expected"),
_ => panic!("Not Transfer as expected"),
},
_ => panic!("Cannot decode into system instruction")
_ => panic!("Cannot decode into system instruction"),
};
}
}
37 changes: 24 additions & 13 deletions indexer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
pub mod schema;
pub mod models;
pub mod decode_solana;
pub mod models;
pub mod schema;

#[macro_use]
extern crate diesel;
extern crate dotenv;

use diesel::prelude::*;
use self::models::SolanaAddress;
use self::models::SolanaBlock;
use diesel::pg::PgConnection;
use diesel::prelude::*;
use dotenv::dotenv;
use std::env;
use self::models::SolanaBlock;
use self::models::SolanaAddress;

pub fn establish_connection() -> PgConnection {
dotenv().ok();

let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
PgConnection::establish(&database_url)
.expect(&format!("Error connecting to {}", database_url))
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
PgConnection::establish(&database_url).expect(&format!("Error connecting to {}", database_url))
}


pub fn create_block_record(conn: &PgConnection, block_number: u128, timestamp: u128, transaction_number: u128, sol_transfer: u128, fee: u128) -> SolanaBlock {
pub fn create_block_record(
conn: &PgConnection,
block_number: u128,
timestamp: u128,
transaction_number: u128,
sol_transfer: u128,
fee: i128,
) -> SolanaBlock {
use schema::solana_block;

/// Todo: use all var in u128!
Expand All @@ -41,7 +45,14 @@ pub fn create_block_record(conn: &PgConnection, block_number: u128, timestamp: u
.expect("Error saving new record")
}

pub fn create_address_record<'a>(conn: &PgConnection, block_number: u128, timestamp: u128, address: &'a str, is_new_create: bool, balance: u128) -> usize {
pub fn create_address_record<'a>(
conn: &PgConnection,
block_number: u128,
timestamp: u128,
address: &'a str,
is_new_create: bool,
balance: u128,
) -> usize {
use schema::solana_address;

/// Todo: use all var in u128!
Expand All @@ -57,4 +68,4 @@ pub fn create_address_record<'a>(conn: &PgConnection, block_number: u128, timest
.values(&new_record)
.execute(conn)
.expect("Error saving new record")
}
}
Loading