SPL token balance in transaction metadata (#13673)

* feat: store pre / post token balances

* move helper functions into separate include

* move token balance functionality to transaction-status crate

* fix blockstore processor test

* fix bigtable legacy test

* add caching to decimals
This commit is contained in:
Josh
2020-12-10 19:25:07 -08:00
committed by GitHub
parent 83fda2d972
commit 13db3eca9f
13 changed files with 349 additions and 3 deletions

View File

@@ -5837,6 +5837,8 @@ pub mod tests {
post_balances: post_balances.clone(),
inner_instructions: Some(vec![]),
log_messages: Some(vec![]),
pre_token_balances: Some(vec![]),
post_token_balances: Some(vec![]),
},
)
.unwrap();
@@ -5851,6 +5853,8 @@ pub mod tests {
post_balances: post_balances.clone(),
inner_instructions: Some(vec![]),
log_messages: Some(vec![]),
pre_token_balances: Some(vec![]),
post_token_balances: Some(vec![]),
},
)
.unwrap();
@@ -5863,6 +5867,8 @@ pub mod tests {
post_balances,
inner_instructions: Some(vec![]),
log_messages: Some(vec![]),
pre_token_balances: Some(vec![]),
post_token_balances: Some(vec![]),
}),
}
})
@@ -6053,6 +6059,8 @@ pub mod tests {
instructions: vec![CompiledInstruction::new(1, &(), vec![0])],
}];
let log_messages_vec = vec![String::from("Test message\n")];
let pre_token_balances_vec = vec![];
let post_token_balances_vec = vec![];
// result not found
assert!(transaction_status_cf
@@ -6073,6 +6081,8 @@ pub mod tests {
post_balances: post_balances_vec.clone(),
inner_instructions: Some(inner_instructions_vec.clone()),
log_messages: Some(log_messages_vec.clone()),
pre_token_balances: Some(pre_token_balances_vec.clone()),
post_token_balances: Some(post_token_balances_vec.clone())
},
)
.is_ok());
@@ -6085,6 +6095,8 @@ pub mod tests {
post_balances,
inner_instructions,
log_messages,
pre_token_balances,
post_token_balances,
} = transaction_status_cf
.get((0, Signature::default(), 0))
.unwrap()
@@ -6095,6 +6107,8 @@ pub mod tests {
assert_eq!(post_balances, post_balances_vec);
assert_eq!(inner_instructions.unwrap(), inner_instructions_vec);
assert_eq!(log_messages.unwrap(), log_messages_vec);
assert_eq!(pre_token_balances.unwrap(), pre_token_balances_vec);
assert_eq!(post_token_balances.unwrap(), post_token_balances_vec);
// insert value
assert!(transaction_status_cf
@@ -6107,6 +6121,8 @@ pub mod tests {
post_balances: post_balances_vec.clone(),
inner_instructions: Some(inner_instructions_vec.clone()),
log_messages: Some(log_messages_vec.clone()),
pre_token_balances: Some(pre_token_balances_vec.clone()),
post_token_balances: Some(post_token_balances_vec.clone())
},
)
.is_ok());
@@ -6119,6 +6135,8 @@ pub mod tests {
post_balances,
inner_instructions,
log_messages,
pre_token_balances,
post_token_balances,
} = transaction_status_cf
.get((0, Signature::new(&[2u8; 64]), 9))
.unwrap()
@@ -6131,6 +6149,8 @@ pub mod tests {
assert_eq!(post_balances, post_balances_vec);
assert_eq!(inner_instructions.unwrap(), inner_instructions_vec);
assert_eq!(log_messages.unwrap(), log_messages_vec);
assert_eq!(pre_token_balances.unwrap(), pre_token_balances_vec);
assert_eq!(post_token_balances.unwrap(), post_token_balances_vec);
}
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
@@ -6359,6 +6379,8 @@ pub mod tests {
post_balances: post_balances_vec,
inner_instructions: Some(vec![]),
log_messages: Some(vec![]),
pre_token_balances: Some(vec![]),
post_token_balances: Some(vec![]),
};
let signature1 = Signature::new(&[1u8; 64]);
@@ -6493,6 +6515,8 @@ pub mod tests {
instructions: vec![CompiledInstruction::new(1, &(), vec![0])],
}]);
let log_messages = Some(vec![String::from("Test message\n")]);
let pre_token_balances = Some(vec![]);
let post_token_balances = Some(vec![]);
let signature = transaction.signatures[0];
blockstore
.transaction_status_cf
@@ -6505,6 +6529,8 @@ pub mod tests {
post_balances: post_balances.clone(),
inner_instructions: inner_instructions.clone(),
log_messages: log_messages.clone(),
pre_token_balances: pre_token_balances.clone(),
post_token_balances: post_token_balances.clone(),
},
)
.unwrap();
@@ -6517,6 +6543,8 @@ pub mod tests {
post_balances,
inner_instructions,
log_messages,
pre_token_balances,
post_token_balances,
}),
}
})
@@ -6958,6 +6986,8 @@ pub mod tests {
post_balances: vec![],
inner_instructions: Some(vec![]),
log_messages: Some(vec![]),
pre_token_balances: Some(vec![]),
post_token_balances: Some(vec![]),
},
)
.unwrap();

View File

@@ -36,6 +36,10 @@ use solana_sdk::{
timing::duration_as_ms,
transaction::{Result, Transaction, TransactionError},
};
use solana_transaction_status::token_balances::{
collect_token_balances, TransactionTokenBalancesSet,
};
use std::{
cell::RefCell,
collections::{HashMap, HashSet},
@@ -102,6 +106,16 @@ fn execute_batch(
transaction_status_sender: Option<TransactionStatusSender>,
replay_vote_sender: Option<&ReplayVoteSender>,
) -> Result<()> {
let record_token_balances = transaction_status_sender.is_some();
let mut mint_decimals: HashMap<Pubkey, u8> = HashMap::new();
let pre_token_balances = if record_token_balances {
collect_token_balances(&bank, &batch, &mut mint_decimals)
} else {
vec![]
};
let (tx_results, balances, inner_instructions, transaction_logs) =
batch.bank().load_execute_and_commit_transactions(
batch,
@@ -120,12 +134,22 @@ fn execute_batch(
} = tx_results;
if let Some(sender) = transaction_status_sender {
let post_token_balances = if record_token_balances {
collect_token_balances(&bank, &batch, &mut mint_decimals)
} else {
vec![]
};
let token_balances =
TransactionTokenBalancesSet::new(pre_token_balances, post_token_balances);
send_transaction_status_batch(
bank.clone(),
batch.transactions(),
batch.iteration_order_vec(),
execution_results,
balances,
token_balances,
inner_instructions,
transaction_logs,
sender,
@@ -1038,6 +1062,7 @@ pub struct TransactionStatusBatch {
pub iteration_order: Option<Vec<usize>>,
pub statuses: Vec<TransactionExecutionResult>,
pub balances: TransactionBalancesSet,
pub token_balances: TransactionTokenBalancesSet,
pub inner_instructions: Vec<Option<InnerInstructionsList>>,
pub transaction_logs: Vec<TransactionLogMessages>,
}
@@ -1050,6 +1075,7 @@ pub fn send_transaction_status_batch(
iteration_order: Option<Vec<usize>>,
statuses: Vec<TransactionExecutionResult>,
balances: TransactionBalancesSet,
token_balances: TransactionTokenBalancesSet,
inner_instructions: Vec<Option<InnerInstructionsList>>,
transaction_logs: Vec<TransactionLogMessages>,
transaction_status_sender: TransactionStatusSender,
@@ -1061,6 +1087,7 @@ pub fn send_transaction_status_batch(
iteration_order,
statuses,
balances,
token_balances,
inner_instructions,
transaction_logs,
}) {