casper_types/
gens.rs

1//! Contains functions for generating arbitrary values for use by
2//! [`Proptest`](https://crates.io/crates/proptest).
3#![allow(missing_docs)]
4use alloc::{
5    boxed::Box,
6    collections::{BTreeMap, BTreeSet},
7    string::String,
8    vec,
9};
10
11use crate::{
12    account::{
13        self, action_thresholds::gens::account_action_thresholds_arb,
14        associated_keys::gens::account_associated_keys_arb, Account, AccountHash,
15    },
16    addressable_entity::{
17        action_thresholds::gens::action_thresholds_arb, associated_keys::gens::associated_keys_arb,
18        ContractRuntimeTag, MessageTopics, NamedKeyAddr, NamedKeyValue, Parameters, Weight,
19    },
20    block::BlockGlobalAddr,
21    byte_code::ByteCodeKind,
22    bytesrepr::Bytes,
23    contract_messages::{MessageAddr, MessageChecksum, MessageTopicSummary, TopicNameHash},
24    contracts::{
25        Contract, ContractHash, ContractPackage, ContractPackageStatus, ContractVersionKey,
26        ContractVersions, EntryPoint as ContractEntryPoint, EntryPoints as ContractEntryPoints,
27        NamedKeys,
28    },
29    crypto::{
30        self,
31        gens::{public_key_arb_no_system, secret_key_arb_no_system},
32    },
33    deploy_info::gens::deploy_info_arb,
34    global_state::{Pointer, TrieMerkleProof, TrieMerkleProofStep},
35    package::{EntityVersionKey, EntityVersions, Groups, PackageStatus},
36    system::{
37        auction::{
38            gens::era_info_arb, Bid, BidAddr, BidKind, DelegationRate, Delegator, DelegatorBid,
39            DelegatorKind, Reservation, UnbondingPurse, ValidatorBid, ValidatorCredit,
40            WithdrawPurse, DELEGATION_RATE_DENOMINATOR,
41        },
42        mint::BalanceHoldAddr,
43        SystemEntityType,
44    },
45    transaction::{
46        gens::deploy_hash_arb, FieldsContainer, InitiatorAddrAndSecretKey, TransactionArgs,
47        TransactionRuntimeParams, TransactionV1Payload,
48    },
49    transfer::{
50        gens::{transfer_v1_addr_arb, transfer_v1_arb},
51        TransferAddr,
52    },
53    AccessRights, AddressableEntity, AddressableEntityHash, BlockTime, ByteCode, ByteCodeAddr,
54    CLType, CLValue, Digest, EntityAddr, EntityEntryPoint, EntityKind, EntryPointAccess,
55    EntryPointAddr, EntryPointPayment, EntryPointType, EntryPoints, EraId, Group, InitiatorAddr,
56    Key, NamedArg, Package, Parameter, Phase, PricingMode, ProtocolVersion, PublicKey, RuntimeArgs,
57    SemVer, StoredValue, TimeDiff, Timestamp, Transaction, TransactionEntryPoint,
58    TransactionInvocationTarget, TransactionScheduling, TransactionTarget, TransactionV1, URef,
59    U128, U256, U512,
60};
61use proptest::{
62    array, bits, bool,
63    collection::{self, vec, SizeRange},
64    option,
65    prelude::*,
66    result,
67};
68
69pub fn u8_slice_32() -> impl Strategy<Value = [u8; 32]> {
70    collection::vec(any::<u8>(), 32).prop_map(|b| {
71        let mut res = [0u8; 32];
72        res.clone_from_slice(b.as_slice());
73        res
74    })
75}
76
77pub fn u2_slice_32() -> impl Strategy<Value = [u8; 32]> {
78    array::uniform32(any::<u8>()).prop_map(|mut arr| {
79        for byte in arr.iter_mut() {
80            *byte &= 0b11;
81        }
82        arr
83    })
84}
85
86pub(crate) fn named_keys_arb(depth: usize) -> impl Strategy<Value = NamedKeys> {
87    collection::btree_map("\\PC*", key_arb(), depth).prop_map(NamedKeys::from)
88}
89
90pub fn access_rights_arb() -> impl Strategy<Value = AccessRights> {
91    prop_oneof![
92        Just(AccessRights::NONE),
93        Just(AccessRights::READ),
94        Just(AccessRights::ADD),
95        Just(AccessRights::WRITE),
96        Just(AccessRights::READ_ADD),
97        Just(AccessRights::READ_WRITE),
98        Just(AccessRights::ADD_WRITE),
99        Just(AccessRights::READ_ADD_WRITE),
100    ]
101}
102
103pub fn phase_arb() -> impl Strategy<Value = Phase> {
104    prop_oneof![
105        Just(Phase::Payment),
106        Just(Phase::Session),
107        Just(Phase::FinalizePayment),
108    ]
109}
110
111pub fn uref_arb() -> impl Strategy<Value = URef> {
112    (array::uniform32(bits::u8::ANY), access_rights_arb())
113        .prop_map(|(id, access_rights)| URef::new(id, access_rights))
114}
115
116pub fn era_id_arb() -> impl Strategy<Value = EraId> {
117    any::<u64>().prop_map(EraId::from)
118}
119
120pub fn named_key_addr_arb() -> impl Strategy<Value = NamedKeyAddr> {
121    (entity_addr_arb(), u8_slice_32())
122        .prop_map(|(entity_addr, b)| NamedKeyAddr::new_named_key_entry(entity_addr, b))
123}
124
125pub fn message_addr_arb() -> impl Strategy<Value = MessageAddr> {
126    prop_oneof![
127        (entity_addr_arb(), u8_slice_32()).prop_map(|(hash_addr, topic_name_hash)| {
128            MessageAddr::new_topic_addr(hash_addr, TopicNameHash::new(topic_name_hash))
129        }),
130        (entity_addr_arb(), u8_slice_32(), example_u32_arb()).prop_map(
131            |(hash_addr, topic_name_hash, index)| MessageAddr::new_message_addr(
132                hash_addr,
133                TopicNameHash::new(topic_name_hash),
134                index
135            )
136        ),
137    ]
138}
139
140pub fn entry_point_addr_arb() -> impl Strategy<Value = EntryPointAddr> {
141    (entity_addr_arb(), any::<String>()).prop_map(|(entity_addr, b)| {
142        EntryPointAddr::new_v1_entry_point_addr(entity_addr, &b).unwrap()
143    })
144}
145
146pub fn byte_code_addr_arb() -> impl Strategy<Value = ByteCodeAddr> {
147    prop_oneof![
148        Just(ByteCodeAddr::Empty),
149        u8_slice_32().prop_map(ByteCodeAddr::V1CasperWasm),
150        u8_slice_32().prop_map(ByteCodeAddr::V2CasperWasm),
151    ]
152}
153
154pub fn key_arb() -> impl Strategy<Value = Key> {
155    prop_oneof![
156        account_hash_arb().prop_map(Key::Account),
157        u8_slice_32().prop_map(Key::Hash),
158        uref_arb().prop_map(Key::URef),
159        transfer_v1_addr_arb().prop_map(Key::Transfer),
160        deploy_hash_arb().prop_map(Key::DeployInfo),
161        era_id_arb().prop_map(Key::EraInfo),
162        uref_arb().prop_map(|uref| Key::Balance(uref.addr())),
163        bid_addr_validator_arb().prop_map(Key::BidAddr),
164        bid_addr_delegator_arb().prop_map(Key::BidAddr),
165        account_hash_arb().prop_map(Key::Withdraw),
166        u8_slice_32().prop_map(Key::Dictionary),
167        balance_hold_addr_arb().prop_map(Key::BalanceHold),
168        Just(Key::EraSummary)
169    ]
170}
171
172pub fn all_keys_arb() -> impl Strategy<Value = Key> {
173    prop_oneof![
174        account_hash_arb().prop_map(Key::Account),
175        u8_slice_32().prop_map(Key::Hash),
176        uref_arb().prop_map(Key::URef),
177        transfer_v1_addr_arb().prop_map(Key::Transfer),
178        deploy_hash_arb().prop_map(Key::DeployInfo),
179        era_id_arb().prop_map(Key::EraInfo),
180        uref_arb().prop_map(|uref| Key::Balance(uref.addr())),
181        account_hash_arb().prop_map(Key::Withdraw),
182        u8_slice_32().prop_map(Key::Dictionary),
183        balance_hold_addr_arb().prop_map(Key::BalanceHold),
184        Just(Key::EraSummary),
185        Just(Key::SystemEntityRegistry),
186        Just(Key::ChainspecRegistry),
187        Just(Key::ChecksumRegistry),
188        bid_addr_arb().prop_map(Key::BidAddr),
189        account_hash_arb().prop_map(Key::Bid),
190        account_hash_arb().prop_map(Key::Unbond),
191        u8_slice_32().prop_map(Key::SmartContract),
192        byte_code_addr_arb().prop_map(Key::ByteCode),
193        entity_addr_arb().prop_map(Key::AddressableEntity),
194        block_global_addr_arb().prop_map(Key::BlockGlobal),
195        message_addr_arb().prop_map(Key::Message),
196        named_key_addr_arb().prop_map(Key::NamedKey),
197        balance_hold_addr_arb().prop_map(Key::BalanceHold),
198        entry_point_addr_arb().prop_map(Key::EntryPoint),
199        entity_addr_arb().prop_map(Key::State),
200    ]
201}
202
203pub fn colliding_key_arb() -> impl Strategy<Value = Key> {
204    prop_oneof![
205        u2_slice_32().prop_map(|bytes| Key::Account(AccountHash::new(bytes))),
206        u2_slice_32().prop_map(Key::Hash),
207        u2_slice_32().prop_map(|bytes| Key::URef(URef::new(bytes, AccessRights::NONE))),
208        u2_slice_32().prop_map(|bytes| Key::Transfer(TransferAddr::new(bytes))),
209        u2_slice_32().prop_map(Key::Dictionary),
210    ]
211}
212
213pub fn account_hash_arb() -> impl Strategy<Value = AccountHash> {
214    u8_slice_32().prop_map(AccountHash::new)
215}
216
217pub fn entity_addr_arb() -> impl Strategy<Value = EntityAddr> {
218    prop_oneof![
219        u8_slice_32().prop_map(EntityAddr::System),
220        u8_slice_32().prop_map(EntityAddr::Account),
221        u8_slice_32().prop_map(EntityAddr::SmartContract),
222    ]
223}
224
225pub fn topic_name_hash_arb() -> impl Strategy<Value = TopicNameHash> {
226    u8_slice_32().prop_map(TopicNameHash::new)
227}
228
229pub fn bid_addr_validator_arb() -> impl Strategy<Value = BidAddr> {
230    u8_slice_32().prop_map(BidAddr::new_validator_addr)
231}
232
233pub fn bid_addr_delegator_arb() -> impl Strategy<Value = BidAddr> {
234    let x = u8_slice_32();
235    let y = u8_slice_32();
236    (x, y).prop_map(BidAddr::new_delegator_account_addr)
237}
238
239pub fn bid_legacy_arb() -> impl Strategy<Value = BidAddr> {
240    u8_slice_32().prop_map(BidAddr::legacy)
241}
242
243pub fn bid_addr_delegated_arb() -> impl Strategy<Value = BidAddr> {
244    (public_key_arb_no_system(), delegator_kind_arb()).prop_map(|(validator, delegator_kind)| {
245        BidAddr::new_delegator_kind(&validator, &delegator_kind)
246    })
247}
248
249pub fn bid_addr_credit_arb() -> impl Strategy<Value = BidAddr> {
250    (public_key_arb_no_system(), era_id_arb())
251        .prop_map(|(validator, era_id)| BidAddr::new_credit(&validator, era_id))
252}
253
254pub fn bid_addr_reservation_account_arb() -> impl Strategy<Value = BidAddr> {
255    (public_key_arb_no_system(), public_key_arb_no_system())
256        .prop_map(|(validator, delegator)| BidAddr::new_reservation_account(&validator, &delegator))
257}
258
259pub fn bid_addr_reservation_purse_arb() -> impl Strategy<Value = BidAddr> {
260    (public_key_arb_no_system(), u8_slice_32())
261        .prop_map(|(validator, uref)| BidAddr::new_reservation_purse(&validator, uref))
262}
263
264pub fn bid_addr_new_unbond_account_arb() -> impl Strategy<Value = BidAddr> {
265    (public_key_arb_no_system(), public_key_arb_no_system())
266        .prop_map(|(validator, unbonder)| BidAddr::new_unbond_account(validator, unbonder))
267}
268
269pub fn bid_addr_arb() -> impl Strategy<Value = BidAddr> {
270    prop_oneof![
271        bid_addr_validator_arb(),
272        bid_addr_delegator_arb(),
273        bid_legacy_arb(),
274        bid_addr_delegated_arb(),
275        bid_addr_credit_arb(),
276        bid_addr_reservation_account_arb(),
277        bid_addr_reservation_purse_arb(),
278        bid_addr_new_unbond_account_arb(),
279    ]
280}
281
282pub fn balance_hold_addr_arb() -> impl Strategy<Value = BalanceHoldAddr> {
283    let x = uref_arb().prop_map(|uref| uref.addr());
284    let y = any::<u64>();
285    (x, y).prop_map(|(x, y)| BalanceHoldAddr::new_gas(x, BlockTime::new(y)))
286}
287
288pub fn block_global_addr_arb() -> impl Strategy<Value = BlockGlobalAddr> {
289    prop_oneof![
290        0 => Just(BlockGlobalAddr::BlockTime),
291        1 => Just(BlockGlobalAddr::MessageCount)
292    ]
293}
294
295pub fn weight_arb() -> impl Strategy<Value = Weight> {
296    any::<u8>().prop_map(Weight::new)
297}
298
299pub fn account_weight_arb() -> impl Strategy<Value = account::Weight> {
300    any::<u8>().prop_map(account::Weight::new)
301}
302
303pub fn sem_ver_arb() -> impl Strategy<Value = SemVer> {
304    (any::<u32>(), any::<u32>(), any::<u32>())
305        .prop_map(|(major, minor, patch)| SemVer::new(major, minor, patch))
306}
307
308pub fn protocol_version_arb() -> impl Strategy<Value = ProtocolVersion> {
309    sem_ver_arb().prop_map(ProtocolVersion::new)
310}
311
312pub fn u128_arb() -> impl Strategy<Value = U128> {
313    collection::vec(any::<u8>(), 0..16).prop_map(|b| U128::from_little_endian(b.as_slice()))
314}
315
316pub fn u256_arb() -> impl Strategy<Value = U256> {
317    collection::vec(any::<u8>(), 0..32).prop_map(|b| U256::from_little_endian(b.as_slice()))
318}
319
320pub fn u512_arb() -> impl Strategy<Value = U512> {
321    prop_oneof![
322        1 => Just(U512::zero()),
323        8 => collection::vec(any::<u8>(), 0..64).prop_map(|b| U512::from_little_endian(b.as_slice())),
324        1 => Just(U512::MAX),
325    ]
326}
327
328pub fn cl_simple_type_arb() -> impl Strategy<Value = CLType> {
329    prop_oneof![
330        Just(CLType::Bool),
331        Just(CLType::I32),
332        Just(CLType::I64),
333        Just(CLType::U8),
334        Just(CLType::U32),
335        Just(CLType::U64),
336        Just(CLType::U128),
337        Just(CLType::U256),
338        Just(CLType::U512),
339        Just(CLType::Unit),
340        Just(CLType::String),
341        Just(CLType::Key),
342        Just(CLType::URef),
343    ]
344}
345
346pub fn cl_type_arb() -> impl Strategy<Value = CLType> {
347    cl_simple_type_arb().prop_recursive(4, 16, 8, |element| {
348        prop_oneof![
349            // We want to produce basic types too
350            element.clone(),
351            // For complex type
352            element
353                .clone()
354                .prop_map(|val| CLType::Option(Box::new(val))),
355            element.clone().prop_map(|val| CLType::List(Box::new(val))),
356            // Realistic Result type generator: ok is anything recursive, err is simple type
357            (element.clone(), cl_simple_type_arb()).prop_map(|(ok, err)| CLType::Result {
358                ok: Box::new(ok),
359                err: Box::new(err)
360            }),
361            // Realistic Map type generator: key is simple type, value is complex recursive type
362            (cl_simple_type_arb(), element.clone()).prop_map(|(key, value)| CLType::Map {
363                key: Box::new(key),
364                value: Box::new(value)
365            }),
366            // Various tuples
367            element
368                .clone()
369                .prop_map(|cl_type| CLType::Tuple1([Box::new(cl_type)])),
370            (element.clone(), element.clone()).prop_map(|(cl_type1, cl_type2)| CLType::Tuple2([
371                Box::new(cl_type1),
372                Box::new(cl_type2)
373            ])),
374            (element.clone(), element.clone(), element).prop_map(
375                |(cl_type1, cl_type2, cl_type3)| CLType::Tuple3([
376                    Box::new(cl_type1),
377                    Box::new(cl_type2),
378                    Box::new(cl_type3)
379                ])
380            ),
381        ]
382    })
383}
384
385pub fn cl_value_arb() -> impl Strategy<Value = CLValue> {
386    // If compiler brings you here it most probably means you've added a variant to `CLType` enum
387    // but forgot to add generator for it.
388    let stub: Option<CLType> = None;
389    if let Some(cl_type) = stub {
390        match cl_type {
391            CLType::Bool
392            | CLType::I32
393            | CLType::I64
394            | CLType::U8
395            | CLType::U32
396            | CLType::U64
397            | CLType::U128
398            | CLType::U256
399            | CLType::U512
400            | CLType::Unit
401            | CLType::String
402            | CLType::Key
403            | CLType::URef
404            | CLType::PublicKey
405            | CLType::Option(_)
406            | CLType::List(_)
407            | CLType::ByteArray(..)
408            | CLType::Result { .. }
409            | CLType::Map { .. }
410            | CLType::Tuple1(_)
411            | CLType::Tuple2(_)
412            | CLType::Tuple3(_)
413            | CLType::Any => (),
414        }
415    };
416
417    prop_oneof![
418        Just(CLValue::from_t(()).expect("should create CLValue")),
419        any::<bool>().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
420        any::<i32>().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
421        any::<i64>().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
422        any::<u8>().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
423        any::<u32>().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
424        any::<u64>().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
425        u128_arb().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
426        u256_arb().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
427        u512_arb().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
428        key_arb().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
429        uref_arb().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
430        ".*".prop_map(|x: String| CLValue::from_t(x).expect("should create CLValue")),
431        option::of(any::<u64>()).prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
432        collection::vec(uref_arb(), 0..100)
433            .prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
434        result::maybe_err(key_arb(), ".*")
435            .prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
436        collection::btree_map(".*", u512_arb(), 0..100)
437            .prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
438        any::<bool>().prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
439        (any::<bool>(), any::<i32>())
440            .prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
441        (any::<bool>(), any::<i32>(), any::<i64>())
442            .prop_map(|x| CLValue::from_t(x).expect("should create CLValue")),
443        // Fixed lists of any size
444        any::<u8>().prop_map(|len| CLValue::from_t([len; 32]).expect("should create CLValue")),
445    ]
446}
447
448pub fn result_arb() -> impl Strategy<Value = Result<u32, u32>> {
449    result::maybe_ok(any::<u32>(), any::<u32>())
450}
451
452pub fn named_args_arb() -> impl Strategy<Value = NamedArg> {
453    (".*", cl_value_arb()).prop_map(|(name, value)| NamedArg::new(name, value))
454}
455
456pub fn group_arb() -> impl Strategy<Value = Group> {
457    ".*".prop_map(Group::new)
458}
459
460pub fn entry_point_access_arb() -> impl Strategy<Value = EntryPointAccess> {
461    prop_oneof![
462        Just(EntryPointAccess::Public),
463        collection::vec(group_arb(), 0..32).prop_map(EntryPointAccess::Groups),
464        Just(EntryPointAccess::Template),
465    ]
466}
467
468pub fn entry_point_type_arb() -> impl Strategy<Value = EntryPointType> {
469    prop_oneof![
470        Just(EntryPointType::Caller),
471        Just(EntryPointType::Called),
472        Just(EntryPointType::Factory),
473    ]
474}
475
476pub fn entry_point_payment_arb() -> impl Strategy<Value = EntryPointPayment> {
477    prop_oneof![
478        Just(EntryPointPayment::Caller),
479        Just(EntryPointPayment::DirectInvocationOnly),
480        Just(EntryPointPayment::SelfOnward),
481    ]
482}
483
484pub fn parameter_arb() -> impl Strategy<Value = Parameter> {
485    (".*", cl_type_arb()).prop_map(|(name, cl_type)| Parameter::new(name, cl_type))
486}
487
488pub fn parameters_arb() -> impl Strategy<Value = Parameters> {
489    collection::vec(parameter_arb(), 0..10)
490}
491
492pub fn entry_point_arb() -> impl Strategy<Value = EntityEntryPoint> {
493    (
494        ".*",
495        parameters_arb(),
496        entry_point_type_arb(),
497        entry_point_access_arb(),
498        entry_point_payment_arb(),
499        cl_type_arb(),
500    )
501        .prop_map(
502            |(name, parameters, entry_point_type, entry_point_access, entry_point_payment, ret)| {
503                EntityEntryPoint::new(
504                    name,
505                    parameters,
506                    ret,
507                    entry_point_access,
508                    entry_point_type,
509                    entry_point_payment,
510                )
511            },
512        )
513}
514
515pub fn contract_entry_point_arb() -> impl Strategy<Value = ContractEntryPoint> {
516    (
517        ".*",
518        parameters_arb(),
519        entry_point_type_arb(),
520        entry_point_access_arb(),
521        cl_type_arb(),
522    )
523        .prop_map(
524            |(name, parameters, entry_point_type, entry_point_access, ret)| {
525                ContractEntryPoint::new(name, parameters, ret, entry_point_access, entry_point_type)
526            },
527        )
528}
529
530pub fn entry_points_arb() -> impl Strategy<Value = EntryPoints> {
531    collection::vec(entry_point_arb(), 1..10).prop_map(EntryPoints::from)
532}
533
534pub fn contract_entry_points_arb() -> impl Strategy<Value = ContractEntryPoints> {
535    collection::vec(contract_entry_point_arb(), 1..10).prop_map(ContractEntryPoints::from)
536}
537
538pub fn message_topics_arb() -> impl Strategy<Value = MessageTopics> {
539    collection::vec(any::<String>(), 1..100).prop_map(|topic_names| {
540        MessageTopics::from(
541            topic_names
542                .into_iter()
543                .map(|name| {
544                    let name_hash = crypto::blake2b(&name).into();
545                    (name, name_hash)
546                })
547                .collect::<BTreeMap<String, TopicNameHash>>(),
548        )
549    })
550}
551
552pub fn account_arb() -> impl Strategy<Value = Account> {
553    (
554        account_hash_arb(),
555        named_keys_arb(20),
556        uref_arb(),
557        account_associated_keys_arb(),
558        account_action_thresholds_arb(),
559    )
560        .prop_map(
561            |(account_hash, named_keys, main_purse, associated_keys, action_thresholds)| {
562                Account::new(
563                    account_hash,
564                    named_keys,
565                    main_purse,
566                    associated_keys,
567                    action_thresholds,
568                )
569            },
570        )
571}
572
573pub fn contract_package_arb() -> impl Strategy<Value = ContractPackage> {
574    (
575        uref_arb(),
576        contract_versions_arb(),
577        disabled_contract_versions_arb(),
578        groups_arb(),
579    )
580        .prop_map(|(access_key, versions, disabled_versions, groups)| {
581            ContractPackage::new(
582                access_key,
583                versions,
584                disabled_versions,
585                groups,
586                ContractPackageStatus::default(),
587            )
588        })
589}
590
591pub fn contract_arb() -> impl Strategy<Value = Contract> {
592    (
593        protocol_version_arb(),
594        contract_entry_points_arb(),
595        u8_slice_32(),
596        u8_slice_32(),
597        named_keys_arb(20),
598    )
599        .prop_map(
600            |(
601                protocol_version,
602                entry_points,
603                contract_package_hash_arb,
604                contract_wasm_hash,
605                named_keys,
606            )| {
607                Contract::new(
608                    contract_package_hash_arb.into(),
609                    contract_wasm_hash.into(),
610                    named_keys,
611                    entry_points,
612                    protocol_version,
613                )
614            },
615        )
616}
617
618pub fn system_entity_type_arb() -> impl Strategy<Value = SystemEntityType> {
619    prop_oneof![
620        Just(SystemEntityType::Mint),
621        Just(SystemEntityType::HandlePayment),
622        Just(SystemEntityType::StandardPayment),
623        Just(SystemEntityType::Auction),
624    ]
625}
626
627pub fn contract_runtime_arb() -> impl Strategy<Value = ContractRuntimeTag> {
628    prop_oneof![
629        Just(ContractRuntimeTag::VmCasperV1),
630        Just(ContractRuntimeTag::VmCasperV2),
631    ]
632}
633
634pub fn entity_kind_arb() -> impl Strategy<Value = EntityKind> {
635    prop_oneof![
636        system_entity_type_arb().prop_map(EntityKind::System),
637        account_hash_arb().prop_map(EntityKind::Account),
638        contract_runtime_arb().prop_map(EntityKind::SmartContract),
639    ]
640}
641
642pub fn addressable_entity_hash_arb() -> impl Strategy<Value = AddressableEntityHash> {
643    u8_slice_32().prop_map(AddressableEntityHash::new)
644}
645
646pub fn addressable_entity_arb() -> impl Strategy<Value = AddressableEntity> {
647    (
648        protocol_version_arb(),
649        u8_slice_32(),
650        u8_slice_32(),
651        uref_arb(),
652        associated_keys_arb(),
653        action_thresholds_arb(),
654        entity_kind_arb(),
655    )
656        .prop_map(
657            |(
658                protocol_version,
659                contract_package_hash_arb,
660                contract_wasm_hash,
661                main_purse,
662                associated_keys,
663                action_thresholds,
664                entity_kind,
665            )| {
666                AddressableEntity::new(
667                    contract_package_hash_arb.into(),
668                    contract_wasm_hash.into(),
669                    protocol_version,
670                    main_purse,
671                    associated_keys,
672                    action_thresholds,
673                    entity_kind,
674                )
675            },
676        )
677}
678
679pub fn byte_code_arb() -> impl Strategy<Value = ByteCode> {
680    collection::vec(any::<u8>(), 1..1000)
681        .prop_map(|byte_code| ByteCode::new(ByteCodeKind::V1CasperWasm, byte_code))
682}
683
684pub fn contract_version_key_arb() -> impl Strategy<Value = ContractVersionKey> {
685    (1..32u32, 1..1000u32)
686        .prop_map(|(major, contract_ver)| ContractVersionKey::new(major, contract_ver))
687}
688
689pub fn entity_version_key_arb() -> impl Strategy<Value = EntityVersionKey> {
690    (1..32u32, 1..1000u32)
691        .prop_map(|(major, contract_ver)| EntityVersionKey::new(major, contract_ver))
692}
693
694pub fn contract_versions_arb() -> impl Strategy<Value = ContractVersions> {
695    collection::btree_map(
696        contract_version_key_arb(),
697        u8_slice_32().prop_map(ContractHash::new),
698        1..5,
699    )
700}
701
702pub fn entity_versions_arb() -> impl Strategy<Value = EntityVersions> {
703    collection::btree_map(entity_version_key_arb(), entity_addr_arb(), 1..5)
704        .prop_map(EntityVersions::from)
705}
706
707pub fn disabled_versions_arb() -> impl Strategy<Value = BTreeSet<EntityVersionKey>> {
708    collection::btree_set(entity_version_key_arb(), 0..5)
709}
710
711pub fn disabled_contract_versions_arb() -> impl Strategy<Value = BTreeSet<ContractVersionKey>> {
712    collection::btree_set(contract_version_key_arb(), 0..5)
713}
714
715pub fn groups_arb() -> impl Strategy<Value = Groups> {
716    collection::btree_map(group_arb(), collection::btree_set(uref_arb(), 1..10), 0..5)
717        .prop_map(Groups::from)
718}
719
720pub fn package_arb() -> impl Strategy<Value = Package> {
721    (entity_versions_arb(), disabled_versions_arb(), groups_arb()).prop_map(
722        |(versions, disabled_versions, groups)| {
723            Package::new(
724                versions,
725                disabled_versions,
726                groups,
727                PackageStatus::default(),
728            )
729        },
730    )
731}
732
733pub(crate) fn delegator_arb() -> impl Strategy<Value = Delegator> {
734    (
735        public_key_arb_no_system(),
736        u512_arb(),
737        uref_arb(),
738        public_key_arb_no_system(),
739    )
740        .prop_map(
741            |(delegator_pk, staked_amount, bonding_purse, validator_pk)| {
742                Delegator::unlocked(delegator_pk, staked_amount, bonding_purse, validator_pk)
743            },
744        )
745}
746
747pub(crate) fn delegator_kind_arb() -> impl Strategy<Value = DelegatorKind> {
748    prop_oneof![
749        public_key_arb_no_system().prop_map(DelegatorKind::PublicKey),
750        array::uniform32(bits::u8::ANY).prop_map(DelegatorKind::Purse)
751    ]
752}
753
754pub(crate) fn delegator_bid_arb() -> impl Strategy<Value = DelegatorBid> {
755    (
756        public_key_arb_no_system(),
757        u512_arb(),
758        uref_arb(),
759        public_key_arb_no_system(),
760    )
761        .prop_map(
762            |(delegator_pk, staked_amount, bonding_purse, validator_pk)| {
763                DelegatorBid::unlocked(
764                    delegator_pk.into(),
765                    staked_amount,
766                    bonding_purse,
767                    validator_pk,
768                )
769            },
770        )
771}
772
773fn delegation_rate_arb() -> impl Strategy<Value = DelegationRate> {
774    0..=DELEGATION_RATE_DENOMINATOR // Maximum, allowed value for delegation rate.
775}
776
777pub(crate) fn reservation_bid_arb() -> impl Strategy<Value = BidKind> {
778    reservation_arb().prop_map(|reservation| BidKind::Reservation(Box::new(reservation)))
779}
780
781pub(crate) fn reservation_arb() -> impl Strategy<Value = Reservation> {
782    (
783        public_key_arb_no_system(),
784        delegator_kind_arb(),
785        delegation_rate_arb(),
786    )
787        .prop_map(|(validator_pk, delegator_kind, delegation_rate)| {
788            Reservation::new(validator_pk, delegator_kind, delegation_rate)
789        })
790}
791
792pub(crate) fn unified_bid_arb(
793    delegations_len: impl Into<SizeRange>,
794) -> impl Strategy<Value = BidKind> {
795    (
796        public_key_arb_no_system(),
797        uref_arb(),
798        u512_arb(),
799        delegation_rate_arb(),
800        bool::ANY,
801        collection::vec(delegator_arb(), delegations_len),
802    )
803        .prop_map(
804            |(
805                validator_public_key,
806                bonding_purse,
807                staked_amount,
808                delegation_rate,
809                is_locked,
810                new_delegators,
811            )| {
812                let mut bid = if is_locked {
813                    Bid::locked(
814                        validator_public_key,
815                        bonding_purse,
816                        staked_amount,
817                        delegation_rate,
818                        1u64,
819                    )
820                } else {
821                    Bid::unlocked(
822                        validator_public_key,
823                        bonding_purse,
824                        staked_amount,
825                        delegation_rate,
826                    )
827                };
828                let delegators = bid.delegators_mut();
829                new_delegators.into_iter().for_each(|delegator| {
830                    assert!(delegators
831                        .insert(delegator.delegator_public_key().clone(), delegator)
832                        .is_none());
833                });
834                BidKind::Unified(Box::new(bid))
835            },
836        )
837}
838
839pub(crate) fn delegator_bid_kind_arb() -> impl Strategy<Value = BidKind> {
840    delegator_bid_arb().prop_map(|delegator| BidKind::Delegator(Box::new(delegator)))
841}
842
843pub(crate) fn validator_bid_arb() -> impl Strategy<Value = BidKind> {
844    (
845        public_key_arb_no_system(),
846        uref_arb(),
847        u512_arb(),
848        delegation_rate_arb(),
849        bool::ANY,
850    )
851        .prop_map(
852            |(validator_public_key, bonding_purse, staked_amount, delegation_rate, is_locked)| {
853                let validator_bid = if is_locked {
854                    ValidatorBid::locked(
855                        validator_public_key,
856                        bonding_purse,
857                        staked_amount,
858                        delegation_rate,
859                        1u64,
860                        0,
861                        u64::MAX,
862                        0,
863                    )
864                } else {
865                    ValidatorBid::unlocked(
866                        validator_public_key,
867                        bonding_purse,
868                        staked_amount,
869                        delegation_rate,
870                        0,
871                        u64::MAX,
872                        0,
873                    )
874                };
875                BidKind::Validator(Box::new(validator_bid))
876            },
877        )
878}
879
880pub(crate) fn credit_bid_arb() -> impl Strategy<Value = BidKind> {
881    (public_key_arb_no_system(), era_id_arb(), u512_arb()).prop_map(
882        |(validator_public_key, era_id, amount)| {
883            BidKind::Credit(Box::new(ValidatorCredit::new(
884                validator_public_key,
885                era_id,
886                amount,
887            )))
888        },
889    )
890}
891
892fn withdraw_arb() -> impl Strategy<Value = WithdrawPurse> {
893    (
894        uref_arb(),
895        public_key_arb_no_system(),
896        public_key_arb_no_system(),
897        era_id_arb(),
898        u512_arb(),
899    )
900        .prop_map(|(bonding_purse, validator_pk, unbonder_pk, era, amount)| {
901            WithdrawPurse::new(bonding_purse, validator_pk, unbonder_pk, era, amount)
902        })
903}
904
905fn withdraws_arb(size: impl Into<SizeRange>) -> impl Strategy<Value = Vec<WithdrawPurse>> {
906    collection::vec(withdraw_arb(), size)
907}
908
909fn unbonding_arb() -> impl Strategy<Value = UnbondingPurse> {
910    (
911        uref_arb(),
912        public_key_arb_no_system(),
913        public_key_arb_no_system(),
914        era_id_arb(),
915        u512_arb(),
916        option::of(public_key_arb_no_system()),
917    )
918        .prop_map(
919            |(
920                bonding_purse,
921                validator_public_key,
922                unbonder_public_key,
923                era,
924                amount,
925                new_validator,
926            )| {
927                UnbondingPurse::new(
928                    bonding_purse,
929                    validator_public_key,
930                    unbonder_public_key,
931                    era,
932                    amount,
933                    new_validator,
934                )
935            },
936        )
937}
938
939fn unbondings_arb(size: impl Into<SizeRange>) -> impl Strategy<Value = Vec<UnbondingPurse>> {
940    collection::vec(unbonding_arb(), size)
941}
942
943fn message_topic_summary_arb() -> impl Strategy<Value = MessageTopicSummary> {
944    (any::<u32>(), any::<u64>(), "test").prop_map(|(message_count, blocktime, topic_name)| {
945        MessageTopicSummary {
946            message_count,
947            blocktime: BlockTime::new(blocktime),
948            topic_name,
949        }
950    })
951}
952
953fn message_summary_arb() -> impl Strategy<Value = MessageChecksum> {
954    u8_slice_32().prop_map(MessageChecksum)
955}
956
957pub fn named_key_value_arb() -> impl Strategy<Value = NamedKeyValue> {
958    (key_arb(), "test").prop_map(|(key, string)| {
959        let cl_key = CLValue::from_t(key).unwrap();
960        let cl_string = CLValue::from_t(string).unwrap();
961        NamedKeyValue::new(cl_key, cl_string)
962    })
963}
964
965pub fn stored_value_arb() -> impl Strategy<Value = StoredValue> {
966    prop_oneof![
967        cl_value_arb().prop_map(StoredValue::CLValue),
968        account_arb().prop_map(StoredValue::Account),
969        byte_code_arb().prop_map(StoredValue::ByteCode),
970        contract_arb().prop_map(StoredValue::Contract),
971        contract_package_arb().prop_map(StoredValue::ContractPackage),
972        addressable_entity_arb().prop_map(StoredValue::AddressableEntity),
973        package_arb().prop_map(StoredValue::SmartContract),
974        transfer_v1_arb().prop_map(StoredValue::Transfer),
975        deploy_info_arb().prop_map(StoredValue::DeployInfo),
976        era_info_arb(1..10).prop_map(StoredValue::EraInfo),
977        unified_bid_arb(0..3).prop_map(StoredValue::BidKind),
978        validator_bid_arb().prop_map(StoredValue::BidKind),
979        delegator_bid_kind_arb().prop_map(StoredValue::BidKind),
980        reservation_bid_arb().prop_map(StoredValue::BidKind),
981        credit_bid_arb().prop_map(StoredValue::BidKind),
982        withdraws_arb(1..50).prop_map(StoredValue::Withdraw),
983        unbondings_arb(1..50).prop_map(StoredValue::Unbonding),
984        message_topic_summary_arb().prop_map(StoredValue::MessageTopic),
985        message_summary_arb().prop_map(StoredValue::Message),
986        named_key_value_arb().prop_map(StoredValue::NamedKey),
987        collection::vec(any::<u8>(), 0..1000).prop_map(StoredValue::RawBytes),
988    ]
989    .prop_map(|stored_value|
990            // The following match statement is here only to make sure
991            // we don't forget to update the generator when a new variant is added.
992            match stored_value {
993                StoredValue::CLValue(_) => stored_value,
994                StoredValue::Account(_) => stored_value,
995                StoredValue::ContractWasm(_) => stored_value,
996                StoredValue::Contract(_) => stored_value,
997                StoredValue::ContractPackage(_) => stored_value,
998                StoredValue::Transfer(_) => stored_value,
999                StoredValue::DeployInfo(_) => stored_value,
1000                StoredValue::EraInfo(_) => stored_value,
1001                StoredValue::Bid(_) => stored_value,
1002                StoredValue::Withdraw(_) => stored_value,
1003                StoredValue::Unbonding(_) => stored_value,
1004                StoredValue::AddressableEntity(_) => stored_value,
1005                StoredValue::BidKind(_) => stored_value,
1006                StoredValue::SmartContract(_) => stored_value,
1007                StoredValue::ByteCode(_) => stored_value,
1008                StoredValue::MessageTopic(_) => stored_value,
1009                StoredValue::Message(_) => stored_value,
1010                StoredValue::NamedKey(_) => stored_value,
1011                StoredValue::Prepayment(_) => stored_value,
1012                StoredValue::EntryPoint(_) => stored_value,
1013                StoredValue::RawBytes(_) => stored_value,
1014        })
1015}
1016
1017pub fn blake2b_hash_arb() -> impl Strategy<Value = Digest> {
1018    vec(any::<u8>(), 0..1000).prop_map(Digest::hash)
1019}
1020
1021pub fn trie_pointer_arb() -> impl Strategy<Value = Pointer> {
1022    prop_oneof![
1023        blake2b_hash_arb().prop_map(Pointer::LeafPointer),
1024        blake2b_hash_arb().prop_map(Pointer::NodePointer)
1025    ]
1026}
1027
1028pub fn trie_merkle_proof_step_arb() -> impl Strategy<Value = TrieMerkleProofStep> {
1029    const POINTERS_SIZE: usize = 32;
1030    const AFFIX_SIZE: usize = 6;
1031
1032    prop_oneof![
1033        (
1034            <u8>::arbitrary(),
1035            vec((<u8>::arbitrary(), trie_pointer_arb()), POINTERS_SIZE)
1036        )
1037            .prop_map(|(hole_index, indexed_pointers_with_hole)| {
1038                TrieMerkleProofStep::Node {
1039                    hole_index,
1040                    indexed_pointers_with_hole,
1041                }
1042            }),
1043        vec(<u8>::arbitrary(), AFFIX_SIZE).prop_map(|affix| {
1044            TrieMerkleProofStep::Extension {
1045                affix: affix.into(),
1046            }
1047        })
1048    ]
1049}
1050
1051pub fn trie_merkle_proof_arb() -> impl Strategy<Value = TrieMerkleProof<Key, StoredValue>> {
1052    const STEPS_SIZE: usize = 6;
1053
1054    (
1055        key_arb(),
1056        stored_value_arb(),
1057        vec(trie_merkle_proof_step_arb(), STEPS_SIZE),
1058    )
1059        .prop_map(|(key, value, proof_steps)| TrieMerkleProof::new(key, value, proof_steps.into()))
1060}
1061
1062pub fn transaction_scheduling_arb() -> impl Strategy<Value = TransactionScheduling> {
1063    prop_oneof![Just(TransactionScheduling::Standard),]
1064}
1065
1066pub fn json_compliant_transaction_scheduling_arb() -> impl Strategy<Value = TransactionScheduling> {
1067    prop_oneof![Just(TransactionScheduling::Standard),]
1068}
1069
1070pub fn transaction_invocation_target_arb() -> impl Strategy<Value = TransactionInvocationTarget> {
1071    prop_oneof![
1072        addressable_entity_hash_arb().prop_map(TransactionInvocationTarget::new_invocable_entity),
1073        Just(TransactionInvocationTarget::new_invocable_entity_alias(
1074            "abcd".to_string()
1075        )),
1076        Just(TransactionInvocationTarget::new_package_alias(
1077            "abcd".to_string(),
1078            None
1079        )),
1080        Just(TransactionInvocationTarget::new_package_alias(
1081            "abcd".to_string(),
1082            Some(10)
1083        )),
1084        u8_slice_32()
1085            .prop_map(|addr| { TransactionInvocationTarget::new_package(addr.into(), None) }),
1086        u8_slice_32()
1087            .prop_map(|addr| { TransactionInvocationTarget::new_package(addr.into(), Some(150)) }),
1088    ]
1089}
1090
1091pub fn stored_transaction_target() -> impl Strategy<Value = TransactionTarget> {
1092    (
1093        transaction_invocation_target_arb(),
1094        transaction_stored_runtime_params_arb(),
1095    )
1096        .prop_map(|(id, runtime)| TransactionTarget::Stored { id, runtime })
1097}
1098
1099fn transferred_value_arb() -> impl Strategy<Value = u64> {
1100    any::<u64>()
1101}
1102
1103fn seed_arb() -> impl Strategy<Value = Option<[u8; 32]>> {
1104    option::of(array::uniform32(any::<u8>()))
1105}
1106
1107pub fn session_transaction_target() -> impl Strategy<Value = TransactionTarget> {
1108    (
1109        any::<bool>(),
1110        Just(Bytes::from(vec![1; 10])),
1111        transaction_session_runtime_params_arb(),
1112    )
1113        .prop_map(
1114            |(is_install_upgrade, module_bytes, runtime)| TransactionTarget::Session {
1115                is_install_upgrade,
1116                module_bytes,
1117                runtime,
1118            },
1119        )
1120}
1121
1122pub(crate) fn transaction_stored_runtime_params_arb(
1123) -> impl Strategy<Value = TransactionRuntimeParams> {
1124    prop_oneof![
1125        Just(TransactionRuntimeParams::VmCasperV1),
1126        transferred_value_arb().prop_map(|transferred_value| {
1127            TransactionRuntimeParams::VmCasperV2 {
1128                transferred_value,
1129                seed: None,
1130            }
1131        }),
1132    ]
1133}
1134
1135pub(crate) fn transaction_session_runtime_params_arb(
1136) -> impl Strategy<Value = TransactionRuntimeParams> {
1137    prop_oneof![
1138        Just(TransactionRuntimeParams::VmCasperV1),
1139        (transferred_value_arb(), seed_arb()).prop_map(|(transferred_value, seed)| {
1140            TransactionRuntimeParams::VmCasperV2 {
1141                transferred_value,
1142                seed,
1143            }
1144        })
1145    ]
1146}
1147
1148pub fn transaction_target_arb() -> impl Strategy<Value = TransactionTarget> {
1149    prop_oneof![
1150        Just(TransactionTarget::Native),
1151        (
1152            transaction_invocation_target_arb(),
1153            transaction_stored_runtime_params_arb(),
1154        )
1155            .prop_map(|(id, runtime)| TransactionTarget::Stored { id, runtime }),
1156        (
1157            any::<bool>(),
1158            Just(Bytes::from(vec![1; 10])),
1159            transaction_session_runtime_params_arb(),
1160        )
1161            .prop_map(|(is_install_upgrade, module_bytes, runtime)| {
1162                TransactionTarget::Session {
1163                    is_install_upgrade,
1164                    module_bytes,
1165                    runtime,
1166                }
1167            })
1168    ]
1169}
1170
1171pub fn legal_target_entry_point_calls_arb(
1172) -> impl Strategy<Value = (TransactionTarget, TransactionEntryPoint)> {
1173    prop_oneof![
1174        native_entry_point_arb().prop_map(|s| (TransactionTarget::Native, s)),
1175        stored_transaction_target()
1176            .prop_map(|s| (s, TransactionEntryPoint::Custom("ABC".to_string()))),
1177        session_transaction_target().prop_map(|s| (s, TransactionEntryPoint::Call)),
1178    ]
1179}
1180
1181pub fn native_entry_point_arb() -> impl Strategy<Value = TransactionEntryPoint> {
1182    prop_oneof![
1183        Just(TransactionEntryPoint::Transfer),
1184        Just(TransactionEntryPoint::AddBid),
1185        Just(TransactionEntryPoint::WithdrawBid),
1186        Just(TransactionEntryPoint::Delegate),
1187        Just(TransactionEntryPoint::Undelegate),
1188        Just(TransactionEntryPoint::Redelegate),
1189        Just(TransactionEntryPoint::ActivateBid),
1190        Just(TransactionEntryPoint::ChangeBidPublicKey),
1191        Just(TransactionEntryPoint::AddReservations),
1192        Just(TransactionEntryPoint::CancelReservations),
1193    ]
1194}
1195pub fn transaction_entry_point_arb() -> impl Strategy<Value = TransactionEntryPoint> {
1196    prop_oneof![
1197        native_entry_point_arb(),
1198        Just(TransactionEntryPoint::Call),
1199        Just(TransactionEntryPoint::Custom("custom".to_string())),
1200    ]
1201}
1202
1203pub fn runtime_args_arb() -> impl Strategy<Value = RuntimeArgs> {
1204    let mut runtime_args_1 = RuntimeArgs::new();
1205    let semi_random_string_pairs = [
1206        ("977837db-8dba-48c2-86f1-32f9740631db", "b7b3b3b3-8b3b-48c2-86f1-32f9740631db"),
1207        ("5de3eecc-b9c8-477f-bebe-937c3a16df85", "2ffd7939-34e5-4660-af9f-772a83011ce0"),
1208        ("036db036-8b7b-4009-a0d4-c9ce", "515f4fe6-06c8-45c5-8554-f07e727a842d036db036-8b7b-4009-a0d4-c9ce036db036-8b7b-4009-a0d4-c9ce"),
1209    ];
1210    for (key, val_str) in semi_random_string_pairs.iter() {
1211        let _ = runtime_args_1.insert(key.to_string(), Bytes::from(val_str.as_bytes()));
1212    }
1213    prop_oneof![Just(runtime_args_1)]
1214}
1215
1216fn transaction_args_bytes_arbitrary() -> impl Strategy<Value = TransactionArgs> {
1217    prop::collection::vec(any::<u8>(), 0..100)
1218        .prop_map(|bytes| TransactionArgs::Bytesrepr(bytes.into()))
1219}
1220
1221pub fn transaction_args_arb() -> impl Strategy<Value = TransactionArgs> {
1222    prop_oneof![
1223        runtime_args_arb().prop_map(TransactionArgs::Named),
1224        transaction_args_bytes_arbitrary()
1225    ]
1226}
1227
1228pub fn fields_arb() -> impl Strategy<Value = BTreeMap<u16, Bytes>> {
1229    collection::btree_map(
1230        any::<u16>(),
1231        any::<String>().prop_map(|s| Bytes::from(s.as_bytes())),
1232        3..30,
1233    )
1234}
1235pub fn v1_transaction_payload_arb() -> impl Strategy<Value = TransactionV1Payload> {
1236    (
1237        any::<String>(),
1238        timestamp_arb(),
1239        any::<u64>(),
1240        pricing_mode_arb(),
1241        initiator_addr_arb(),
1242        fields_arb(),
1243    )
1244        .prop_map(
1245            |(chain_name, timestamp, ttl_millis, pricing_mode, initiator_addr, fields)| {
1246                TransactionV1Payload::new(
1247                    chain_name,
1248                    timestamp,
1249                    TimeDiff::from_millis(ttl_millis),
1250                    pricing_mode,
1251                    initiator_addr,
1252                    fields,
1253                )
1254            },
1255        )
1256}
1257
1258pub fn fixed_pricing_mode_arb() -> impl Strategy<Value = PricingMode> {
1259    (any::<u8>(), any::<u8>()).prop_map(|(gas_price_tolerance, additional_computation_factor)| {
1260        PricingMode::Fixed {
1261            gas_price_tolerance,
1262            additional_computation_factor,
1263        }
1264    })
1265}
1266
1267pub fn pricing_mode_arb() -> impl Strategy<Value = PricingMode> {
1268    prop_oneof![
1269        (any::<u64>(), any::<u8>(), any::<bool>()).prop_map(
1270            |(payment_amount, gas_price_tolerance, standard_payment)| {
1271                PricingMode::PaymentLimited {
1272                    payment_amount,
1273                    gas_price_tolerance,
1274                    standard_payment,
1275                }
1276            }
1277        ),
1278        fixed_pricing_mode_arb(),
1279    ]
1280}
1281
1282pub fn initiator_addr_arb() -> impl Strategy<Value = InitiatorAddr> {
1283    prop_oneof![
1284        public_key_arb_no_system().prop_map(InitiatorAddr::PublicKey),
1285        u2_slice_32().prop_map(|hash| InitiatorAddr::AccountHash(AccountHash::new(hash))),
1286    ]
1287}
1288
1289pub fn timestamp_arb() -> impl Strategy<Value = Timestamp> {
1290    //The weird u64 value is the max milliseconds that are bofeore year 10000. 5 digit years are
1291    // not rfc3339 compliant and will cause an error when trying to serialize to json.
1292    prop_oneof![Just(0_u64), Just(1_u64), Just(253_402_300_799_999_u64)].prop_map(Timestamp::from)
1293}
1294
1295pub fn legal_v1_transaction_arb() -> impl Strategy<Value = TransactionV1> {
1296    (
1297        any::<String>(),
1298        timestamp_arb(),
1299        any::<u32>(),
1300        pricing_mode_arb(),
1301        secret_key_arb_no_system(),
1302        transaction_args_arb(),
1303        json_compliant_transaction_scheduling_arb(),
1304        legal_target_entry_point_calls_arb(),
1305    )
1306        .prop_map(
1307            |(
1308                chain_name,
1309                timestamp,
1310                ttl,
1311                pricing_mode,
1312                secret_key,
1313                args,
1314                scheduling,
1315                (target, entry_point),
1316            )| {
1317                let public_key = PublicKey::from(&secret_key);
1318                let initiator_addr = InitiatorAddr::PublicKey(public_key);
1319                let initiator_addr_with_secret = InitiatorAddrAndSecretKey::Both {
1320                    initiator_addr,
1321                    secret_key: &secret_key,
1322                };
1323                let container = FieldsContainer::new(args, target, entry_point, scheduling);
1324                TransactionV1::build(
1325                    chain_name,
1326                    timestamp,
1327                    TimeDiff::from_seconds(ttl),
1328                    pricing_mode,
1329                    container.to_map().unwrap(),
1330                    initiator_addr_with_secret,
1331                )
1332            },
1333        )
1334}
1335pub fn v1_transaction_arb() -> impl Strategy<Value = TransactionV1> {
1336    (
1337        any::<String>(),
1338        timestamp_arb(),
1339        any::<u32>(),
1340        pricing_mode_arb(),
1341        secret_key_arb_no_system(),
1342        runtime_args_arb(),
1343        transaction_target_arb(),
1344        transaction_entry_point_arb(),
1345        transaction_scheduling_arb(),
1346    )
1347        .prop_map(
1348            |(
1349                chain_name,
1350                timestamp,
1351                ttl,
1352                pricing_mode,
1353                secret_key,
1354                args,
1355                target,
1356                entry_point,
1357                scheduling,
1358            )| {
1359                let public_key = PublicKey::from(&secret_key);
1360                let initiator_addr = InitiatorAddr::PublicKey(public_key);
1361                let initiator_addr_with_secret = InitiatorAddrAndSecretKey::Both {
1362                    initiator_addr,
1363                    secret_key: &secret_key,
1364                };
1365                let container = FieldsContainer::new(
1366                    TransactionArgs::Named(args),
1367                    target,
1368                    entry_point,
1369                    scheduling,
1370                );
1371                TransactionV1::build(
1372                    chain_name,
1373                    timestamp,
1374                    TimeDiff::from_seconds(ttl),
1375                    pricing_mode,
1376                    container.to_map().unwrap(),
1377                    initiator_addr_with_secret,
1378                )
1379            },
1380        )
1381}
1382
1383pub fn transaction_arb() -> impl Strategy<Value = Transaction> {
1384    (v1_transaction_arb()).prop_map(Transaction::V1)
1385}
1386
1387pub fn legal_transaction_arb() -> impl Strategy<Value = Transaction> {
1388    (legal_v1_transaction_arb()).prop_map(Transaction::V1)
1389}
1390pub fn example_u32_arb() -> impl Strategy<Value = u32> {
1391    prop_oneof![Just(0), Just(1), Just(u32::MAX / 2), Just(u32::MAX)]
1392}