Ackee-Blockchain / trident

Rust-based framework to Fuzz and Integration test Solana programs to help you ship secure code.
https://ackee.xyz/
MIT License
185 stars 18 forks source link

fix/allow to process duplicate transactions #147

Closed Ikrk closed 5 months ago

Ikrk commented 5 months ago

This PR resolves an issues with duplicate transactions. If the fuzzer generates two or more consecutive transactions with the same data and accounts (and therefore the same hash) that are executed successfully, than only the first transaction is processed and the remaining transactions are rejected by the runtime. However the process_transaction function returns an Ok(()) result even if the transaction was rejected. This is a problem, because then also the check method is executed and depending on the implementation does not have to pass.

For example if checking that a transfer from an account was done correctly (and that the balance changed), the check will pass after the first transaction but will fail after the remaining ones, because the transaction will not be processed at all and the balance will stay the same.

One option to fix this issue would be to artificially warp to higher slot number so that the runtime does not spot the duplicate. However modifying the slot number might eventually interfere with some protocols relying on it. Therefore another solution was implemented where it is verified before processing a transaction that a transaction with the same hash was not processed before. If yes, the duplicate transaction is skipped and a warning is emitted in logs. The duplicates detection is done via hash of the transaction that is store in a HashMap. If the hash is present, than it is a duplicate. It was not possible to use for example the unique method from the itertools crate, because this method required Eq and Hash trait bounds. This would "color" all the instruction structures and also disallow usage of floating data types as these do not have Eq implementations.

Also a possibility to override this default behavior was implemented. To allow duplicate transactions, it is possible to set the parameter allow_duplicate_txs in Trident.toml to true. This might slightly increase the performance of fuzzing but you risk to encounter false positive crash findings.

As a side effect, the fuzz group in Trident.toml configuration file was renamed to honggfuzz and a new group fuzz was created to setup internal fuzzer parameters.