Skip to content
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

fix/allow to process duplicate transactions #147

Merged
merged 5 commits into from
Mar 22, 2024
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ incremented upon a breaking change and the patch version will be incremented for

## [Unreleased]
### Added
- fix/allow to process duplicate transactions ([#147](https://github.com/Ackee-Blockchain/trident/pull/147))
- feat/possibility to implement custom transaction error handling ([#145](https://github.com/Ackee-Blockchain/trident/pull/145))
- feat/support of automatically obtaining fully qualified paths of Data Accounts Custom types for `accounts_snapshots.rs` ([#141](https://github.com/Ackee-Blockchain/trident/pull/141))
- feat/allow direct accounts manipulation and storage ([#142](https://github.com/Ackee-Blockchain/trident/pull/142))
Expand Down
48 changes: 30 additions & 18 deletions crates/client/derive/fuzz_test_executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,29 +37,40 @@ pub fn fuzz_test_executor(input: TokenStream) -> TokenStream {
let sig: Vec<&Keypair> = signers.iter().collect();
transaction.sign(&sig, client.get_last_blockhash());

let tx_result = client.process_transaction(transaction)
.map_err(|e| e.with_origin(Origin::Instruction(self.to_context_string())));
let duplicate_tx = if cfg!(allow_duplicate_txs) {
None
} else {
let message_hash = transaction.message().hash();
sent_txs.insert(message_hash, ())
};

match duplicate_tx {
Some(_) => eprintln!("\x1b[1;93mWarning\x1b[0m: Skipping duplicate instruction `{}`", self.to_context_string()),
None => {
let tx_result = client.process_transaction(transaction)
.map_err(|e| e.with_origin(Origin::Instruction(self.to_context_string())));

match tx_result {
Ok(_) => {
snaphot.capture_after(client).unwrap();
let (acc_before, acc_after) = snaphot.get_snapshot()
.map_err(|e| e.with_origin(Origin::Instruction(self.to_context_string())))
.expect("Snapshot deserialization expect"); // we want to panic if we cannot unwrap to cause a crash
match tx_result {
Ok(_) => {
snaphot.capture_after(client).unwrap();
let (acc_before, acc_after) = snaphot.get_snapshot()
.map_err(|e| e.with_origin(Origin::Instruction(self.to_context_string())))
.expect("Snapshot deserialization expect"); // we want to panic if we cannot unwrap to cause a crash

if let Err(e) = ix.check(acc_before, acc_after, data).map_err(|e| e.with_origin(Origin::Instruction(self.to_context_string()))) {
eprintln!(
"CRASH DETECTED! Custom check after the {} instruction did not pass!",
self.to_context_string());
panic!("{}", e)
if let Err(e) = ix.check(acc_before, acc_after, data).map_err(|e| e.with_origin(Origin::Instruction(self.to_context_string()))) {
eprintln!(
"\x1b[31mCRASH DETECTED!\x1b[0m Custom check after the {} instruction did not pass!",
self.to_context_string());
panic!("{}", e)
}
},
Err(e) => {
let mut raw_accounts = snaphot.get_raw_pre_ix_accounts();
ix.tx_error_handler(e, data, &mut raw_accounts)?
}
}
},
Err(e) => {
let mut raw_accounts = snaphot.get_raw_pre_ix_accounts();
ix.tx_error_handler(e, data, &mut raw_accounts)?
}
}

}
}
});
Expand All @@ -71,6 +82,7 @@ pub fn fuzz_test_executor(input: TokenStream) -> TokenStream {
program_id: Pubkey,
accounts: &RefCell<FuzzAccounts>,
client: &mut impl FuzzClient,
sent_txs: &mut HashMap<Hash, ()>,
) -> core::result::Result<(), FuzzClientErrorWithOrigin> {
match self {
#(#display_match_arms)*
Expand Down
34 changes: 32 additions & 2 deletions crates/client/src/commander.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl Commander {
// arguments so we need to parse the variable content.
let hfuzz_run_args = std::env::var("HFUZZ_RUN_ARGS").unwrap_or_default();

let fuzz_args = config.get_fuzz_args(hfuzz_run_args);
let fuzz_args = config.get_honggfuzz_args(hfuzz_run_args);

// let cargo_target_dir = std::env::var("CARGO_TARGET_DIR").unwrap_or_default();

Expand Down Expand Up @@ -181,10 +181,20 @@ impl Commander {
}
}

let mut rustflags = if config.fuzz.allow_duplicate_txs {
"--cfg allow_duplicate_txs "
} else {
""
}
.to_string();

rustflags.push_str(&std::env::var("RUSTFLAGS").unwrap_or_default());

let mut child = Command::new("cargo")
.env("HFUZZ_RUN_ARGS", fuzz_args)
.env("CARGO_TARGET_DIR", cargo_target_dir)
.env("HFUZZ_WORKSPACE", hfuzz_workspace)
.env("RUSTFLAGS", rustflags)
.arg("hfuzz")
.arg("run")
.arg(target)
Expand Down Expand Up @@ -226,12 +236,22 @@ impl Commander {
let hfuzz_workspace = std::env::var("HFUZZ_WORKSPACE")
.unwrap_or_else(|_| config.get_env_arg("HFUZZ_WORKSPACE"));

let fuzz_args = config.get_fuzz_args(hfuzz_run_args);
let fuzz_args = config.get_honggfuzz_args(hfuzz_run_args);

let mut rustflags = if config.fuzz.allow_duplicate_txs {
"--cfg allow_duplicate_txs "
} else {
""
}
.to_string();

rustflags.push_str(&std::env::var("RUSTFLAGS").unwrap_or_default());

let mut child = Command::new("cargo")
.env("HFUZZ_RUN_ARGS", fuzz_args)
.env("CARGO_TARGET_DIR", cargo_target_dir)
.env("HFUZZ_WORKSPACE", hfuzz_workspace)
.env("RUSTFLAGS", rustflags)
.arg("hfuzz")
.arg("run")
.arg(target)
Expand Down Expand Up @@ -266,9 +286,19 @@ impl Commander {
let cargo_target_dir = std::env::var("CARGO_TARGET_DIR")
.unwrap_or_else(|_| config.get_env_arg("CARGO_TARGET_DIR"));

let mut rustflags = if config.fuzz.allow_duplicate_txs {
"--cfg allow_duplicate_txs "
} else {
""
}
.to_string();

rustflags.push_str(&std::env::var("RUSTFLAGS").unwrap_or_default());

// using exec rather than spawn and replacing current process to avoid unflushed terminal output after ctrl+c signal
std::process::Command::new("cargo")
.env("CARGO_TARGET_DIR", cargo_target_dir)
.env("RUSTFLAGS", rustflags)
.arg("hfuzz")
.arg("run-debug")
.arg(target)
Expand Down
Loading
Loading