iota_replay/fuzz_mutations/
drop_random_commands.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use iota_types::transaction::TransactionKind;
6use rand::seq::SliceRandom;
7use tracing::info;
8
9use crate::fuzz::TransactionKindMutator;
10
11pub struct DropRandomCommands {
12    pub rng: rand::rngs::StdRng,
13    pub num_mutations_per_base_left: u64,
14}
15
16impl TransactionKindMutator for DropRandomCommands {
17    fn mutate(&mut self, transaction_kind: &TransactionKind) -> Option<TransactionKind> {
18        if self.num_mutations_per_base_left == 0 {
19            // Nothing else to do
20            return None;
21        }
22
23        self.num_mutations_per_base_left -= 1;
24        if let TransactionKind::ProgrammableTransaction(mut p) = transaction_kind.clone() {
25            if p.commands.is_empty() {
26                return None;
27            }
28            p.commands = p
29                .commands
30                .choose_multiple(&mut self.rng, p.commands.len() - 1)
31                .cloned()
32                .collect();
33            info!("Mutation: Dropping random commands");
34            Some(TransactionKind::ProgrammableTransaction(p))
35        } else {
36            // Other types not supported yet
37            None
38        }
39    }
40
41    fn reset(&mut self, mutations_per_base: u64) {
42        self.num_mutations_per_base_left = mutations_per_base;
43    }
44}