Skip to content

Commit 9edca49

Browse files
authored
feat(iota-protocol, iota-execution, iota-framework): Update signing verifier constants setting (#5588)
* feat(iota-protocol, iota-execution, iota-framework): allowing verifier constants for limits and metering to be set by the node config instead of being hardcoded into the binary
1 parent d0e8afa commit 9edca49

File tree

18 files changed

+210
-42
lines changed

18 files changed

+210
-42
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/iota-config/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ iota-genesis-common.workspace = true
3333
iota-keys.workspace = true
3434
iota-protocol-config.workspace = true
3535
iota-types.workspace = true
36+
move-vm-config.workspace = true

crates/iota-config/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod node_config_metrics;
2121
pub mod object_storage_config;
2222
pub mod p2p;
2323
pub mod transaction_deny_config;
24+
pub mod verifier_signing_config;
2425

2526
use iota_types::multiaddr::Multiaddr;
2627
pub use node::{ConsensusConfig, ExecutionCacheConfig, NodeConfig};

crates/iota-config/src/node.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use tracing::info;
3434
use crate::{
3535
Config, certificate_deny_config::CertificateDenyConfig, genesis,
3636
migration_tx_data::MigrationTxData, object_storage_config::ObjectStoreConfig, p2p::P2pConfig,
37-
transaction_deny_config::TransactionDenyConfig,
37+
transaction_deny_config::TransactionDenyConfig, verifier_signing_config::VerifierSigningConfig,
3838
};
3939

4040
// Default max number of concurrent requests served
@@ -245,6 +245,9 @@ pub struct NodeConfig {
245245

246246
#[serde(default = "bool_true")]
247247
pub enable_validator_tx_finalizer: bool,
248+
249+
#[serde(default)]
250+
pub verifier_signing_config: VerifierSigningConfig,
248251
}
249252

250253
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) Mysten Labs, Inc.
2+
// Modifications Copyright (c) 2025 IOTA Stiftung
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
use move_vm_config::verifier::MeterConfig;
6+
use serde::{Deserialize, Serialize};
7+
8+
// Default values for verifier signing config.
9+
pub const DEFAULT_MAX_PER_FUN_METER_UNITS: usize = 2_200_000;
10+
pub const DEFAULT_MAX_PER_MOD_METER_UNITS: usize = 2_200_000;
11+
pub const DEFAULT_MAX_PER_PKG_METER_UNITS: usize = 2_200_000;
12+
13+
pub const DEFAULT_MAX_BACK_EDGES_PER_FUNCTION: usize = 10_000;
14+
pub const DEFAULT_MAX_BACK_EDGES_PER_MODULE: usize = 10_000;
15+
16+
/// This holds limits that are only set and used by the verifier during signing
17+
/// _only_. There are additional limits in the `MeterConfig` and
18+
/// `VerifierConfig` that are used during both signing and execution, however
19+
/// those limits cannot be set here and must be protocol versioned.
20+
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
21+
#[serde(rename_all = "kebab-case")]
22+
pub struct VerifierSigningConfig {
23+
#[serde(default)]
24+
max_per_fun_meter_units: Option<usize>,
25+
#[serde(default)]
26+
max_per_mod_meter_units: Option<usize>,
27+
#[serde(default)]
28+
max_per_pkg_meter_units: Option<usize>,
29+
30+
#[serde(default)]
31+
max_back_edges_per_function: Option<usize>,
32+
#[serde(default)]
33+
max_back_edges_per_module: Option<usize>,
34+
}
35+
36+
impl VerifierSigningConfig {
37+
pub fn max_per_fun_meter_units(&self) -> usize {
38+
self.max_per_fun_meter_units
39+
.unwrap_or(DEFAULT_MAX_PER_FUN_METER_UNITS)
40+
}
41+
42+
pub fn max_per_mod_meter_units(&self) -> usize {
43+
self.max_per_mod_meter_units
44+
.unwrap_or(DEFAULT_MAX_PER_MOD_METER_UNITS)
45+
}
46+
47+
pub fn max_per_pkg_meter_units(&self) -> usize {
48+
self.max_per_pkg_meter_units
49+
.unwrap_or(DEFAULT_MAX_PER_PKG_METER_UNITS)
50+
}
51+
52+
pub fn max_back_edges_per_function(&self) -> usize {
53+
self.max_back_edges_per_function
54+
.unwrap_or(DEFAULT_MAX_BACK_EDGES_PER_FUNCTION)
55+
}
56+
57+
pub fn max_back_edges_per_module(&self) -> usize {
58+
self.max_back_edges_per_module
59+
.unwrap_or(DEFAULT_MAX_BACK_EDGES_PER_MODULE)
60+
}
61+
62+
/// Return sign-time only limit for back edges for the verifier.
63+
pub fn limits_for_signing(&self) -> (usize, usize) {
64+
(
65+
self.max_back_edges_per_function(),
66+
self.max_back_edges_per_module(),
67+
)
68+
}
69+
70+
/// MeterConfig for metering packages during signing. It is NOT stable
71+
/// between binaries and cannot used during execution.
72+
pub fn meter_config_for_signing(&self) -> MeterConfig {
73+
MeterConfig {
74+
max_per_fun_meter_units: Some(self.max_per_fun_meter_units() as u128),
75+
max_per_mod_meter_units: Some(self.max_per_mod_meter_units() as u128),
76+
max_per_pkg_meter_units: Some(self.max_per_pkg_meter_units() as u128),
77+
}
78+
}
79+
}

crates/iota-core/src/authority.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,7 @@ impl AuthorityState {
898898
input_objects,
899899
&receiving_objects,
900900
&self.metrics.bytecode_verifier_metrics,
901+
&self.config.verifier_signing_config,
901902
)?;
902903

903904
check_coin_deny_list_v1_during_signing(
@@ -1764,6 +1765,7 @@ impl AuthorityState {
17641765
receiving_objects,
17651766
gas_object,
17661767
&self.metrics.bytecode_verifier_metrics,
1768+
&self.config.verifier_signing_config,
17671769
)?,
17681770
Some(gas_object_id),
17691771
)
@@ -1776,6 +1778,7 @@ impl AuthorityState {
17761778
input_objects,
17771779
&receiving_objects,
17781780
&self.metrics.bytecode_verifier_metrics,
1781+
&self.config.verifier_signing_config,
17791782
)?,
17801783
None,
17811784
)
@@ -2004,6 +2007,7 @@ impl AuthorityState {
20042007
receiving_objects,
20052008
dummy_gas_object,
20062009
&self.metrics.bytecode_verifier_metrics,
2010+
&self.config.verifier_signing_config,
20072011
)?
20082012
} else {
20092013
iota_transaction_checks::check_transaction_input(
@@ -2013,6 +2017,7 @@ impl AuthorityState {
20132017
input_objects,
20142018
&receiving_objects,
20152019
&self.metrics.bytecode_verifier_metrics,
2020+
&self.config.verifier_signing_config,
20162021
)?
20172022
}
20182023
};

crates/iota-framework-tests/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ prometheus.workspace = true
2121

2222
# internal dependencies
2323
iota-adapter = { path = "../../iota-execution/latest/iota-adapter", package = "iota-adapter-latest" }
24+
iota-config.workspace = true
2425
iota-framework.workspace = true
2526
iota-move = { workspace = true, features = ["unit_test"] }
2627
iota-move-build.workspace = true

crates/iota-framework-tests/src/metered_verifier.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::{
99
};
1010

1111
use iota_adapter::adapter::run_metered_move_bytecode_verifier;
12+
use iota_config::verifier_signing_config::VerifierSigningConfig;
1213
use iota_framework::BuiltInFramework;
1314
use iota_move_build::{CompiledPackage, IotaPackageHooks};
1415
use iota_protocol_config::ProtocolConfig;
@@ -36,8 +37,10 @@ fn test_metered_move_bytecode_verifier() {
3637
let compiled_modules: Vec<_> = compiled_package.get_modules().cloned().collect();
3738

3839
let protocol_config = ProtocolConfig::get_for_max_version_UNSAFE();
39-
let mut verifier_config = protocol_config.verifier_config(/* for_signing */ true);
40-
let mut meter_config = protocol_config.meter_config_for_signing();
40+
let signing_config = VerifierSigningConfig::default();
41+
let mut verifier_config =
42+
protocol_config.verifier_config(Some(signing_config.limits_for_signing()));
43+
let mut meter_config = signing_config.meter_config_for_signing();
4144
let registry = &Registry::new();
4245
let bytecode_verifier_metrics = Arc::new(BytecodeVerifierMetrics::new(registry));
4346
let mut meter = IotaVerifierMeter::new(meter_config.clone());
@@ -202,9 +205,11 @@ fn test_metered_move_bytecode_verifier() {
202205
let package = build(&path).unwrap();
203206
packages.push(package.get_dependency_sorted_modules(with_unpublished_deps));
204207

208+
let signing_config = VerifierSigningConfig::default();
205209
let protocol_config = ProtocolConfig::get_for_max_version_UNSAFE();
206-
let verifier_config = protocol_config.verifier_config(/* for_signing */ true);
207-
let meter_config = protocol_config.meter_config_for_signing();
210+
let verifier_config =
211+
protocol_config.verifier_config(Some(signing_config.limits_for_signing()));
212+
let meter_config = signing_config.meter_config_for_signing();
208213

209214
// Check if the same meter is indeed used multiple invocations of the verifier
210215
let mut meter = IotaVerifierMeter::new(meter_config);
@@ -229,9 +234,11 @@ fn test_metered_move_bytecode_verifier() {
229234
fn test_meter_system_packages() {
230235
move_package::package_hooks::register_package_hooks(Box::new(IotaPackageHooks));
231236

237+
let signing_config = VerifierSigningConfig::default();
232238
let protocol_config = ProtocolConfig::get_for_max_version_UNSAFE();
233-
let verifier_config = protocol_config.verifier_config(/* for_signing */ true);
234-
let meter_config = protocol_config.meter_config_for_signing();
239+
let verifier_config =
240+
protocol_config.verifier_config(Some(signing_config.limits_for_signing()));
241+
let meter_config = signing_config.meter_config_for_signing();
235242
let registry = &Registry::new();
236243
let bytecode_verifier_metrics = Arc::new(BytecodeVerifierMetrics::new(registry));
237244
let mut meter = IotaVerifierMeter::new(meter_config);
@@ -283,9 +290,11 @@ fn test_meter_system_packages() {
283290
fn test_build_and_verify_programmability_examples() {
284291
move_package::package_hooks::register_package_hooks(Box::new(IotaPackageHooks));
285292

293+
let signing_config = VerifierSigningConfig::default();
286294
let protocol_config = ProtocolConfig::get_for_max_version_UNSAFE();
287-
let verifier_config = protocol_config.verifier_config(/* for_signing */ true);
288-
let meter_config = protocol_config.meter_config_for_signing();
295+
let verifier_config =
296+
protocol_config.verifier_config(Some(signing_config.limits_for_signing()));
297+
let meter_config = signing_config.meter_config_for_signing();
289298
let registry = &Registry::new();
290299
let bytecode_verifier_metrics = Arc::new(BytecodeVerifierMetrics::new(registry));
291300
let examples = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../examples");

crates/iota-protocol-config/src/lib.rs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99

1010
use clap::*;
1111
use iota_protocol_config_macros::{ProtocolConfigAccessors, ProtocolConfigFeatureFlagsGetters};
12-
use move_vm_config::verifier::{MeterConfig, VerifierConfig};
12+
use move_vm_config::verifier::VerifierConfig;
1313
use serde::{Deserialize, Serialize};
1414
use serde_with::skip_serializing_none;
1515
use tracing::{info, warn};
@@ -1706,11 +1706,15 @@ impl ProtocolConfig {
17061706
// Extract the bytecode verifier config from this protocol config. `for_signing`
17071707
// indicates whether this config is used for verification during signing or
17081708
// execution.
1709-
pub fn verifier_config(&self, for_signing: bool) -> VerifierConfig {
1710-
let (max_back_edges_per_function, max_back_edges_per_module) = if for_signing {
1709+
pub fn verifier_config(&self, signing_limits: Option<(usize, usize)>) -> VerifierConfig {
1710+
let (max_back_edges_per_function, max_back_edges_per_module) = if let Some((
1711+
max_back_edges_per_function,
1712+
max_back_edges_per_module,
1713+
)) = signing_limits
1714+
{
17111715
(
1712-
Some(self.max_back_edges_per_function() as usize),
1713-
Some(self.max_back_edges_per_module() as usize),
1716+
Some(max_back_edges_per_function),
1717+
Some(max_back_edges_per_module),
17141718
)
17151719
} else {
17161720
(None, None)
@@ -1740,16 +1744,6 @@ impl ProtocolConfig {
17401744
}
17411745
}
17421746

1743-
/// MeterConfig for metering packages during signing. It is NOT stable
1744-
/// between binaries and cannot used during execution.
1745-
pub fn meter_config_for_signing(&self) -> MeterConfig {
1746-
MeterConfig {
1747-
max_per_fun_meter_units: Some(2_200_000),
1748-
max_per_mod_meter_units: Some(2_200_000),
1749-
max_per_pkg_meter_units: Some(2_200_000),
1750-
}
1751-
}
1752-
17531747
/// Override one or more settings in the config, for testing.
17541748
/// This must be called at the beginning of the test, before
17551749
/// get_for_(min|max)_version is called, since those functions cache

crates/iota-swarm-config/src/node_config_builder.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use iota_config::{
1919
default_end_of_epoch_broadcast_channel_capacity, default_zklogin_oauth_providers,
2020
},
2121
p2p::{P2pConfig, SeedPeer, StateSyncConfig},
22+
verifier_signing_config::VerifierSigningConfig,
2223
};
2324
use iota_types::{
2425
crypto::{AuthorityKeyPair, AuthorityPublicKeyBytes, IotaKeyPair, NetworkKeyPair},
@@ -223,6 +224,7 @@ impl ValidatorConfigBuilder {
223224
firewall_config: self.firewall_config,
224225
execution_cache: ExecutionCacheConfig::default(),
225226
enable_validator_tx_finalizer: true,
227+
verifier_signing_config: VerifierSigningConfig::default(),
226228
}
227229
}
228230

@@ -515,6 +517,7 @@ impl FullnodeConfigBuilder {
515517
execution_cache: ExecutionCacheConfig::default(),
516518
// This is a validator specific feature.
517519
enable_validator_tx_finalizer: false,
520+
verifier_signing_config: VerifierSigningConfig::default(),
518521
}
519522
}
520523

0 commit comments

Comments
 (0)