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::ExecutionError;
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(
14    meter: &mut TranslationMeter,
15    transaction: &L::Transaction,
16) -> Result<(), ExecutionError> {
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    Ok(())
31}
32
33fn command_linkage(cmd: &L::Command) -> Option<&ResolvedLinkage> {
34    match cmd {
35        L::Command::Publish(_, _, linkage) | L::Command::Upgrade(_, _, _, _, linkage) => {
36            Some(linkage)
37        }
38        L::Command::MoveCall(call) => Some(&call.function.linkage.resolved_linkage),
39        L::Command::MakeMoveVec(_, _)
40        | L::Command::TransferObjects(_, _)
41        | L::Command::SplitCoins(_, _)
42        | L::Command::MergeCoins(_, _) => None,
43    }
44}
45
46fn command_types(cmd: &L::Command) -> Box<dyn Iterator<Item = &L::Type> + '_> {
47    match cmd {
48        L::Command::MoveCall(move_call) => Box::new(
49            move_call
50                .function
51                .type_arguments
52                .iter()
53                .chain(move_call.function.signature.parameters.iter())
54                .chain(move_call.function.signature.return_.iter()),
55        ),
56        L::Command::MakeMoveVec(Some(ty), _) => Box::new(std::iter::once(ty)),
57        L::Command::TransferObjects(_, _)
58        | L::Command::SplitCoins(_, _)
59        | L::Command::MergeCoins(_, _)
60        | L::Command::MakeMoveVec(None, _)
61        | L::Command::Publish(_, _, _)
62        | L::Command::Upgrade(_, _, _, _, _) => Box::new(std::iter::empty()),
63    }
64}