Skip to content

Commit

Permalink
fix/allow to process duplicate transactions (#147)
Browse files Browse the repository at this point in the history
* πŸ› Filter duplicate transactions

πŸ› Allow to process duplicate Transactions

* 🚩 Added allow_duplicate_txs feature flag

* ✨ Trident.toml config refactoring

* βœ… Tests update

* πŸ“ Updated example config files
  • Loading branch information
Ikrk committed Mar 22, 2024
1 parent 2f866fe commit f9f2a41
Show file tree
Hide file tree
Showing 17 changed files with 309 additions and 189 deletions.
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

0 comments on commit f9f2a41

Please sign in to comment.