sui_adapter_latest/static_programmable_transactions/metering/
loading.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::static_programmable_transactions::{
5    linkage::resolved_linkage::ResolvedLinkage, loading::ast as L,
6    metering::translation_meter::TranslationMeter,
7};
8use sui_types::error::ExecutionErrorTrait;
9
10/// After loading and before type checking we do a pass over the loaded transaction to charge for
11/// types that occured in the transaction and were loaded. We simply charge for the number of type
12/// nodes that were loaded.
13pub fn meter<E: ExecutionErrorTrait>(
14    meter: &mut TranslationMeter,
15    transaction: &L::Transaction,
16) -> Result<(), E> {
17    let inputs = transaction.inputs.iter().filter_map(|i| match &i.1 {
18        L::InputType::Bytes => None,
19        L::InputType::Fixed(ty) => Some(ty),
20    });
21    let commands = transaction.commands.iter().flat_map(command_types);
22    for ty in inputs.chain(commands) {
23        meter.charge_num_type_nodes(ty.node_count())?;
24    }
25
26    for linkage in transaction.commands.iter().filter_map(command_linkage) {
27        meter.charge_num_linkage_entries(linkage.linkage_resolution.len())?;
28    }
29
30    for cmd in &transaction.commands {
31        match cmd {
32            L::Command::Publish(payload, _, _) | L::Command::Upgrade(payload, _, _, _, _) => {
33                meter.charge_package_load(payload)?;
34            }
35            L::Command::MoveCall(_)
36            | L::Command::MakeMoveVec(_, _)
37            | L::Command::TransferObjects(_, _)
38            | L::Command::SplitCoins(_, _)
39            | L::Command::MergeCoins(_, _) => (),
40        }
41    }
42
43    Ok(())
44}
45
46fn command_linkage(cmd: &L::Command) -> Option<&ResolvedLinkage> {
47    match cmd {
48        L::Command::Publish(_, _, linkage) | L::Command::Upgrade(_, _, _, _, linkage) => {
49            Some(linkage)
50        }
51        L::Command::MoveCall(call) => Some(&call.function.linkage.0),
52        L::Command::MakeMoveVec(_, _)
53        | L::Command::TransferObjects(_, _)
54        | L::Command::SplitCoins(_, _)
55        | L::Command::MergeCoins(_, _) => None,
56    }
57}
58
59fn command_types(cmd: &L::Command) -> Box<dyn Iterator<Item = &L::Type> + '_> {
60    match cmd {
61        L::Command::MoveCall(move_call) => Box::new(
62            move_call
63                .function
64                .type_arguments
65                .iter()
66                .chain(move_call.function.signature.parameters.iter())
67                .chain(move_call.function.signature.return_.iter()),
68        ),
69        L::Command::MakeMoveVec(Some(ty), _) => Box::new(std::iter::once(ty)),
70        L::Command::TransferObjects(_, _)
71        | L::Command::SplitCoins(_, _)
72        | L::Command::MergeCoins(_, _)
73        | L::Command::MakeMoveVec(None, _)
74        | L::Command::Publish(_, _, _)
75        | L::Command::Upgrade(_, _, _, _, _) => Box::new(std::iter::empty()),
76    }
77}