iota_replay/fuzz_mutations/
shuffle_types.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::{Command, TransactionKind};
6use rand::seq::SliceRandom;
7use tracing::info;
8
9use crate::fuzz::TransactionKindMutator;
10
11pub struct ShuffleTypes {
12    pub rng: rand::rngs::StdRng,
13    pub num_mutations_per_base_left: u64,
14}
15
16impl ShuffleTypes {
17    fn shuffle_command(&mut self, command: &mut Command) {
18        if let Command::MoveCall(ref mut pt) = command {
19            pt.type_arguments.shuffle(&mut self.rng)
20        }
21    }
22}
23
24impl TransactionKindMutator for ShuffleTypes {
25    fn mutate(&mut self, transaction_kind: &TransactionKind) -> Option<TransactionKind> {
26        if self.num_mutations_per_base_left == 0 {
27            // Nothing else to do
28            return None;
29        }
30
31        self.num_mutations_per_base_left -= 1;
32        if let TransactionKind::ProgrammableTransaction(mut p) = transaction_kind.clone() {
33            for command in &mut p.commands {
34                self.shuffle_command(command);
35            }
36            info!("Mutation: Shuffling types");
37            Some(TransactionKind::ProgrammableTransaction(p))
38        } else {
39            // Other types not supported yet
40            None
41        }
42    }
43
44    fn reset(&mut self, mutations_per_base: u64) {
45        self.num_mutations_per_base_left = mutations_per_base;
46    }
47}