-
Notifications
You must be signed in to change notification settings - Fork 265
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
svm: better testing for transaction batches #2623
Conversation
37c3464
to
e69b046
Compare
cc @apfitzge if you have thoughts on design, im planning on doing my svm tests on top of this and wanted to not have it be in the main prs |
Do you mean account locks? They are not calculated in the SVM.
What kind of tests are you planning on adding? I have some fuzzy tests in the SVM and perhaps we could think of integrating everything. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work!
yea what i mean is, after the svm changes for simd83 (making it so transactions with read/write and write/write duplicate accounts can execute), we are going to make changes to accountsdb (making it so the locks dont conflict so transactions like that can be scheduled) and we probably want some kind of similar runner system for that. thinking whether we just want one shared one or not, tho i guess can decide once accountsdb work is up
the main things im planning on testing are:
|
ok, i addressed the resolved comments. also i made the top-level test take a |
svm/tests/integration_test.rs
Outdated
match (&self.return_data, &execution_details.return_data) { | ||
(ReturnDataAssert::Some(expected_ro_data), Some(actual_ro_data)) => { | ||
assert_eq!(expected_ro_data, actual_ro_data) | ||
} | ||
(ReturnDataAssert::None, None) => {} | ||
(ReturnDataAssert::Skip, _) => {} | ||
(left, right) => panic!( | ||
"assertion `left == right` failed\n {:?}\n {:?}", | ||
left, right | ||
), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can simply do assert_eq!(self.return_data, execution_details.return_data)
, provided that you derive PartialEq
for ReturnDataAssert
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cant because theyre different types, but there is a natural From
impl!
it wasnt possible to rebase without writing new code, this is the incremental diff in case github restarts the diff history once i force push this. master now distinguishes two types of "processed" transaction: an "executed" transaction (which may succeed or fail) and a "fees-only" transaction (which is not executed but fee-payer and nonce account changes are committed) in addition to the regular non-executed transaction (no state changes) hana@laptop:svm$ git diff remotes/origin/20240816_txbatchtest:svm/tests/integration_test.rs HEAD:svm/tests/integration_test.rs
diff --git a/svm/tests/integration_test.rs b/svm/tests/integration_test.rs
index 1c22f8266e..eef355425a 100644
--- a/svm/tests/integration_test.rs
+++ b/svm/tests/integration_test.rs
@@ -21,6 +21,7 @@ use {
solana_svm::{
account_loader::{CheckedTransactionDetails, TransactionCheckResult},
transaction_execution_result::TransactionExecutionDetails,
+ transaction_processing_result::ProcessedTransaction,
transaction_processor::{
ExecutionRecordingConfig, TransactionBatchProcessor, TransactionProcessingConfig,
TransactionProcessingEnvironment,
@@ -573,13 +574,25 @@ fn execute_test_entry(test_entry: SvmTestEntry) {
// build a hashmap of final account states incrementally
// NOTE with SIMD-83 an account may appear multiple times, thus we need the final state
let mut final_accounts_actual = AccountMap::default();
- for (pubkey, account_data) in batch_output
+ for processed_transaction in batch_output
.processing_results
.iter()
- .filter(|r| r.is_ok())
- .flat_map(|r| r.as_ref().unwrap().loaded_transaction.accounts.clone())
+ .filter_map(|r| r.as_ref().ok())
{
- final_accounts_actual.insert(pubkey, account_data);
+ match processed_transaction {
+ ProcessedTransaction::Executed(executed_transaction) => {
+ for (pubkey, account_data) in
+ executed_transaction.loaded_transaction.accounts.clone()
+ {
+ final_accounts_actual.insert(pubkey, account_data);
+ }
+ }
+ // NOTE this is a possible state with `feature_set::enable_transaction_loading_failure_fees` enabled
+ // by using `TransactionProcessingEnvironment::default()` we have all features disabled
+ // in other words, this will be unreachable until we are ready to test fee-only transactions
+ // (or the feature is activated on mainnet and removed... but we should do it before then!)
+ ProcessedTransaction::FeesOnly(_) => unreachable!(),
+ }
}
// check that all the account states we care about are present and correct
@@ -595,7 +608,9 @@ fn execute_test_entry(test_entry: SvmTestEntry) {
.zip(test_entry.asserts())
{
match processing_result {
- Ok(tx) => test_item_asserts.check_executed_transaction(&tx.execution_details),
+ Ok(ProcessedTransaction::Executed(executed_transaction)) => test_item_asserts
+ .check_executed_transaction(&executed_transaction.execution_details),
+ Ok(ProcessedTransaction::FeesOnly(_)) => unreachable!(),
Err(_) => assert!(!test_item_asserts.executed),
}
} will address the rest of comments in next commit! |
implement handling for the new `ProcessedTransaction` type
dda3345
to
b530053
Compare
b055c97
to
f8b74ce
Compare
oki should be all set now! |
implement a rudimentary test framework for integration testing of transaction loading and execution
Problem
transaction loading is a part of the code with poor test coverage. this has recently become (more) problematic for two reasons:
Summary of Changes
using the code in
integration_test.rs
as a basis, i abstracted out a basic framework for doing arbitrary integration tests starting at the transaction processorload_and_execute_sanitized_transactions
entrypoint.program_medley()
is largely identical to the previous tests (some numbers changed for convenience) including checking logs and return data.simple_transfer()
is a simple example of how to add more tests that go through thisone thing im not sure about (other than names of some things, in particulat
TestData
is bad) is if this can easily be further abstracted to also support testing from thebank.rs
load_execute_and_commit_transactions
orload_and_execute_transactions
level. however maybe we dont want to abstract this further and just want two different systems. basically we want to also be able to test locks with batches of transactions