Skip to main content

iota_core/
authority.rs

1// Copyright (c) 2021, Facebook, Inc. and its affiliates
2// Copyright (c) Mysten Labs, Inc.
3// Modifications Copyright (c) 2024 IOTA Stiftung
4// SPDX-License-Identifier: Apache-2.0
5
6use std::{
7    cell::Cell,
8    collections::{BTreeMap, HashMap, HashSet},
9    fs::File,
10    io::Write,
11    path::{Path, PathBuf},
12    pin::Pin,
13    sync::{
14        Arc, Weak,
15        atomic::{AtomicBool, Ordering},
16    },
17    time::{Duration, Instant, SystemTime, UNIX_EPOCH},
18    vec,
19};
20
21use arc_swap::{ArcSwap, Guard};
22use async_trait::async_trait;
23use authority_per_epoch_store::TxLockGuard;
24pub use authority_store::{AuthorityStore, ResolverWrapper, UpdateType};
25use fastcrypto::{
26    encoding::{Base58, Encoding},
27    hash::MultisetHash,
28};
29use iota_common::{debug_fatal, fatal};
30use iota_config::{
31    NodeConfig,
32    genesis::Genesis,
33    node::{AuthorityOverloadConfig, ExpensiveSafetyCheckConfig, StateDebugDumpConfig},
34};
35use iota_framework::{BuiltInFramework, SystemPackage as FrameworkSystemPackage};
36use iota_json_rpc_types::{EventFilter, IotaEvent, IotaObjectDataFilter, TransactionFilter};
37use iota_macros::{fail_point, fail_point_async, fail_point_if};
38use iota_metrics::{
39    TX_TYPE_SHARED_OBJ_TX, TX_TYPE_SINGLE_WRITER_TX, monitored_scope, spawn_monitored_task,
40};
41use iota_sdk_types::{
42    Address, CheckpointCommitment, CheckpointContents, CheckpointContentsDigest, CheckpointDigest,
43    CheckpointSummary, Digest, EndOfEpochTransactionKind, Event, ExecutionStatus, GasCostSummary,
44    InputSharedObject, MoveAuthenticator, ObjectDigest, ObjectId, ObjectReference, RandomnessRound,
45    SenderSignedTransaction, StructTag, SystemPackage, Transaction, TransactionDigest,
46    TransactionEffects, TransactionEffectsDigest, TransactionEvents, TransactionKind, TypeTag,
47    Version,
48    crypto::{Intent, IntentScope},
49};
50use iota_storage::{
51    key_value_store::{
52        KVStoreTransactionData, TransactionKeyValueStore, TransactionKeyValueStoreTrait,
53    },
54    key_value_store_metrics::KeyValueStoreMetrics,
55};
56use iota_traffic_controller::{TrafficController, metrics::TrafficControllerMetrics};
57use iota_transaction_checks::VerifierLimitsSource;
58#[cfg(msim)]
59use iota_types::committee::CommitteeTrait;
60use iota_types::{
61    account_abstraction::authenticator_function::{
62        AuthenticatorFunctionRef, AuthenticatorFunctionRefForExecution,
63        MoveAuthenticatorForExecution, MoveAuthenticatorsForExecution,
64        authenticator_function_ref_v1_from_dynamic_field_object,
65        derive_authenticator_function_ref_v1_dynamic_field_id, extract_auth_fun_refs,
66    },
67    attestation::{AttestationRecord, AttestationVerdict},
68    auth_context::AuthContextData,
69    base_types::{AuthorityName, ConciseableName, VersionNumber},
70    committee::{Committee, EpochId, ProtocolVersion},
71    crypto::{AggregateAuthorityPublicKey, AuthoritySignInfo, AuthoritySignature, Signer},
72    deny_list_v1::{check_coin_deny_list_v1, coin_types_for_denylist_check},
73    deny_rule_governance::DenyRuleConfig,
74    digests::ChainIdentifier,
75    dynamic_field::{self, DynamicFieldInfo},
76    effects::{
77        SignedTransactionEffects, TransactionEffectsAPI, TransactionEffectsExt,
78        VerifiedSignedTransactionEffects,
79    },
80    error::{ExecutionError, ExecutionErrorKind, IotaError, IotaResult, UserInputError},
81    event::{EventID, SystemEpochInfoEvent},
82    executable_transaction::VerifiedExecutableTransaction,
83    execution_config_utils::to_binary_config,
84    fp_ensure,
85    gas::IotaGasStatus,
86    gas_coin::mock_simulation_gas_coin,
87    inner_temporary_store::InnerTemporaryStore,
88    iota_system_state::{
89        IotaSystemState, IotaSystemStateTrait,
90        epoch_start_iota_system_state::EpochStartSystemStateTrait, get_iota_system_state,
91    },
92    layout_resolver::into_struct_layout,
93    message_envelope::Message,
94    messages_checkpoint::{
95        CertifiedCheckpointSummary, CheckpointContentsExt, CheckpointRequest, CheckpointResponse,
96        CheckpointSequenceNumber, CheckpointSummaryResponse, CheckpointTimestamp,
97        ECMHLiveObjectSetDigest, VerifiedCheckpoint,
98    },
99    messages_consensus::AuthorityCapabilitiesV1,
100    messages_grpc::{
101        HandleTransactionResponse, LayoutGenerationOption, ObjectInfoRequest,
102        ObjectInfoRequestKind, ObjectInfoResponse, TransactionInfoRequest, TransactionInfoResponse,
103        TransactionStatus,
104    },
105    metrics::{BytecodeVerifierMetrics, LimitsMetrics},
106    move_authenticator::MoveAuthenticatorExt,
107    object::{Object, ObjectRead, ObjectSet, PastObjectRead},
108    storage::{
109        BackingPackageStore, BackingStore, ObjectKey, ObjectOrTombstone, ObjectStore,
110        OwnedObjectCursor, TrackingBackingStore,
111    },
112    supported_protocol_versions::{
113        ProtocolConfig, SupportedProtocolVersions, SupportedProtocolVersionsWithHashes,
114    },
115    traffic_control::{PolicyConfig, TrafficControlReconfigParams},
116    transaction::*,
117    transaction_executor::{SimulateTransactionResult, VmChecks},
118};
119use itertools::Itertools;
120use move_binary_format::{CompiledModule, binary_config::BinaryConfig};
121use move_core_types::{
122    account_address::AccountAddress, annotated_value::MoveStructLayout, language_storage::ModuleId,
123};
124use parking_lot::Mutex;
125use prometheus_filtered::{
126    Histogram, HistogramVec, IntCounter, IntCounterVec, IntGauge, IntGaugeVec, MetricLevel,
127    Registry, register_histogram_vec_with_registry, register_histogram_with_registry,
128    register_int_counter_vec_with_registry, register_int_counter_with_registry,
129    register_int_gauge_vec_with_registry, register_int_gauge_with_registry,
130};
131use serde::{Deserialize, Serialize, de::DeserializeOwned};
132use tap::TapFallible;
133use tokio::{
134    sync::{Notify, RwLock, mpsc, mpsc::unbounded_channel, oneshot, watch},
135    task::JoinHandle,
136};
137use tracing::{debug, error, info, instrument, trace, warn};
138use typed_store::TypedStoreError;
139
140use self::{attestation::attestation_record, authority_store::ExecutionLockWriteGuard};
141#[cfg(msim)]
142pub use crate::checkpoints::checkpoint_executor::utils::{
143    CheckpointTimeoutConfig, init_checkpoint_timeout_config,
144};
145use crate::{
146    authority::{
147        authority_per_epoch_store::{AuthorityPerEpochStore, TxGuard},
148        authority_per_epoch_store_pruner::AuthorityPerEpochStorePruner,
149        authority_store::{ExecutionLockReadGuard, ObjectLockStatus},
150        epoch_start_configuration::{EpochStartConfigTrait, EpochStartConfiguration},
151        historic_ledger::HistoricLedger,
152        historic_objects::HistoricObjects,
153        object_retention::{ObjectRetention, ObjectRetentionGuard},
154        shared_object_version_manager::{AssignedVersions, Schedulable},
155    },
156    authority_client::NetworkAuthorityClient,
157    checkpoints::{CheckpointBuilderError, CheckpointBuilderResult, CheckpointStore},
158    congestion_tracker::CongestionTracker,
159    consensus_adapter::ConsensusAdapter,
160    epoch::committee_store::CommitteeStore,
161    epoch_buckets::PrunedBuckets,
162    epoch_end_db_snapshot::{EpochEndDbSnapshotHandle, HandOver},
163    execution_cache::{
164        CheckpointCache, ExecutionCacheCommit, ExecutionCacheReconfigAPI,
165        ExecutionCacheTraitPointers, ExecutionCacheWrite, ObjectCacheRead, StateSyncAPI,
166        TransactionCacheRead,
167    },
168    execution_driver::execution_process,
169    execution_scheduler::{
170        ExecutionSchedulerAPI, ExecutionSchedulerWrapper, transaction_manager::AttestationSource,
171    },
172    global_state_hasher::{GlobalStateHashStore, GlobalStateHasher},
173    metrics::{LatencyObserver, RateTracker},
174    module_cache_metrics::ResolverMetrics,
175    overload_monitor::{
176        AuthorityOverloadInfo, compute_graduated_load_shedding_percentage,
177        overload_monitor_accept_tx,
178    },
179    post_consensus_input_reader::{
180        AccountVerdict, InputResolution, ReceivingObjectsResolution, ValidationAtCommit,
181        ValidationInputsAtCommit,
182        reader::{CommitIndexedReader, DenyListAtCommit},
183    },
184    rpc_indexes::{
185        RpcIndexesStore,
186        jsonrpc_api::{
187            CachingLayoutResolver, CoinInfo, OwnedObjectsPage, try_create_dynamic_field_info,
188        },
189        schema::{IndexGroup, OwnerTypeFilter},
190    },
191    stake_aggregator::StakeAggregator,
192    transaction_input_loader::TransactionInputLoader,
193    transaction_outputs::TransactionOutputs,
194    validator_tx_finalizer::ValidatorTxFinalizer,
195};
196
197#[cfg(test)]
198#[path = "unit_tests/authority_tests.rs"]
199pub mod authority_tests;
200
201#[cfg(test)]
202#[path = "unit_tests/transaction_tests.rs"]
203pub mod transaction_tests;
204
205#[cfg(test)]
206#[path = "unit_tests/batch_transaction_tests.rs"]
207mod batch_transaction_tests;
208
209#[cfg(test)]
210#[path = "unit_tests/move_integration_tests.rs"]
211pub mod move_integration_tests;
212
213#[cfg(test)]
214#[path = "unit_tests/gas_tests.rs"]
215mod gas_tests;
216
217#[cfg(test)]
218#[path = "unit_tests/batch_verification_tests.rs"]
219mod batch_verification_tests;
220
221#[cfg(test)]
222#[path = "unit_tests/coin_deny_list_tests.rs"]
223mod coin_deny_list_tests;
224
225#[cfg(test)]
226#[path = "unit_tests/pre_execution_failure_tests.rs"]
227mod pre_execution_failure_tests;
228
229#[cfg(test)]
230#[path = "unit_tests/cancelled_move_authenticator_tests.rs"]
231mod cancelled_move_authenticator_tests;
232
233#[cfg(test)]
234#[path = "unit_tests/move_authenticator_attestation_tests.rs"]
235mod move_authenticator_attestation_tests;
236
237#[cfg(test)]
238#[path = "unit_tests/auth_unit_test_utils.rs"]
239pub mod auth_unit_test_utils;
240
241#[cfg(test)]
242#[path = "unit_tests/abstract_account_test_utils.rs"]
243pub mod abstract_account_test_utils;
244
245#[cfg(test)]
246#[path = "unit_tests/attestation_test_utils.rs"]
247pub mod attestation_test_utils;
248
249#[cfg(test)]
250#[path = "unit_tests/attestation_verdict_tests.rs"]
251mod attestation_verdict_tests;
252
253#[cfg(any(test, feature = "test-utils"))]
254pub mod authority_test_utils;
255
256pub(crate) mod attestation;
257mod attestation_verdict;
258pub mod authority_per_epoch_store;
259pub mod authority_per_epoch_store_pruner;
260
261pub mod authority_store_tables;
262pub mod authority_store_types;
263pub mod epoch_markers;
264pub mod epoch_start_configuration;
265pub mod historic_ledger;
266pub mod historic_objects;
267pub mod ledger_backlog_migration;
268pub mod object_backlog_sweep;
269pub mod object_retention;
270pub mod shared_object_congestion_tracker;
271pub mod shared_object_version_manager;
272pub mod suggested_gas_price_calculator;
273#[cfg(any(test, feature = "test-utils"))]
274pub mod test_authority_builder;
275pub mod transaction_deferral;
276
277pub(crate) mod authority_store;
278pub mod backpressure;
279pub(crate) mod dropped_tx_status_cache;
280
281/// Prometheus metrics which can be displayed in Grafana, queried and alerted on
282pub struct AuthorityMetrics {
283    tx_orders: IntCounter,
284    total_certs: IntCounter,
285    total_cert_attempts: IntCounter,
286    total_effects: IntCounter,
287    pub shared_obj_tx: IntCounter,
288    sponsored_tx: IntCounter,
289    tx_already_processed: IntCounter,
290    num_input_objs: Histogram,
291    num_shared_objects: Histogram,
292    batch_size: Histogram,
293
294    authority_state_handle_transaction_latency: Histogram,
295
296    execute_certificate_latency_single_writer: Histogram,
297    execute_certificate_latency_shared_object: Histogram,
298
299    internal_execution_latency: Histogram,
300    /// Number of times the validator refused to report effects (signed or
301    /// unsigned, labeled by RPC surface) because it had previously signed
302    /// different effects for the same transaction.
303    signed_effects_equivocation_prevented: IntCounterVec,
304    execution_load_input_objects_latency: Histogram,
305    prepare_certificate_latency: Histogram,
306    commit_certificate_latency: Histogram,
307    epoch_end_db_snapshot_handover_latency: Histogram,
308    epoch_end_db_snapshots_skipped: IntCounter,
309
310    pub(crate) transaction_manager_num_enqueued_certificates: IntCounterVec,
311    pub(crate) transaction_manager_num_missing_objects: IntGauge,
312    pub(crate) transaction_manager_num_pending_certificates: IntGauge,
313    pub(crate) transaction_manager_num_executing_certificates: IntGauge,
314    pub(crate) transaction_manager_num_ready: IntGauge,
315    pub(crate) transaction_manager_object_cache_size: IntGauge,
316    pub(crate) transaction_manager_object_cache_hits: IntCounter,
317    pub(crate) transaction_manager_object_cache_misses: IntCounter,
318    pub(crate) transaction_manager_object_cache_evictions: IntCounter,
319    pub(crate) transaction_manager_package_cache_size: IntGauge,
320    pub(crate) transaction_manager_package_cache_hits: IntCounter,
321    pub(crate) transaction_manager_package_cache_misses: IntCounter,
322    pub(crate) transaction_manager_package_cache_evictions: IntCounter,
323    pub(crate) transaction_manager_transaction_queue_age_s: Histogram,
324
325    pub(crate) execution_driver_executed_transactions: IntCounter,
326    pub(crate) execution_driver_dispatch_queue: IntGauge,
327    pub(crate) execution_queueing_delay_s: Histogram,
328    pub(crate) prepare_cert_gas_latency_ratio: Histogram,
329    pub(crate) execution_gas_latency_ratio: Histogram,
330
331    /// Modified objects whose pre-image was neither an input nor a read
332    /// object of the transaction, and so was not moved to the historic store.
333    pub(crate) superseded_capture_misses: IntCounter,
334
335    pub(crate) skipped_consensus_txns: IntCounter,
336    pub(crate) skipped_consensus_txns_cache_hit: IntCounter,
337
338    /// Per store, the oldest epoch whose history the node still holds,
339    /// published each time an expiry runs with retention on. Not advancing
340    /// across epochs means expiry is stuck.
341    pub(crate) historic_bucket_earliest_retained_epoch: IntGaugeVec,
342    /// Per store, how long the expiries that dropped a bucket took.
343    pub(crate) historic_bucket_expiry_duration: HistogramVec,
344
345    pub(crate) authority_overload_status: IntGauge,
346    /// Percentage of transactions shed due to consensus queue length.
347    pub(crate) consensus_queue_load_shedding_percentage: IntGauge,
348    /// This authority's locally computed load shedding percentage, taken as the
349    /// max of its latency/rate-based, transaction-manager-queue-based, and
350    /// writeback-cache-backpressure signals.
351    pub(crate) local_post_consensus_load_shedding_percentage: IntGauge,
352
353    pub(crate) transaction_overload_sources: IntCounterVec,
354
355    /// Checkpoint-inclusion waits that timed out before the RPC indexes
356    /// caught up.
357    pub(crate) checkpoint_inclusion_index_wait_timeouts: IntCounter,
358
359    // Consensus handler metrics
360    pub consensus_handler_processed: IntCounterVec,
361    pub consensus_handler_transaction_sizes: HistogramVec,
362    pub consensus_handler_num_low_scoring_authorities: IntGauge,
363    pub consensus_handler_scores: IntGaugeVec,
364    pub consensus_handler_deferred_transactions: IntCounter,
365    pub consensus_handler_congested_transactions: IntCounter,
366    pub consensus_handler_cancelled_transactions: IntCounter,
367    /// Number of user transactions dropped during a consensus commit because
368    /// post-consensus conflict/lock validation rejected them. Distinct from
369    /// `consensus_handler_load_shedding_dropped_transactions`.
370    pub consensus_handler_validation_dropped_transactions: IntCounter,
371    /// Results of the commit-indexed reader in post-consensus validation, by
372    /// result (keep, drop or missing) and the reason that decided it. Only with
373    /// the P-COOL flow on.
374    pub consensus_handler_validation_reader_verdicts: IntCounterVec,
375    /// The commit being validated minus the highest fully executed commit, set
376    /// once per commit. Only with the P-COOL flow on.
377    pub consensus_handler_commit_execution_lag: IntGauge,
378    /// Attested transactions that passed post-consensus validation, by
379    /// attestation kind; a deferred transaction counts again when reloaded.
380    pub(crate) consensus_handler_validation_attested_transactions: IntCounterVec,
381    /// Attested transactions dropped by post-consensus validation because
382    /// their attestor is cut off for the rest of the epoch.
383    pub(crate) consensus_handler_validation_attestor_cut_off_transactions: IntCounter,
384    /// Number of user transactions dropped during a consensus commit by
385    /// post-consensus load shedding, i.e. probabilistically rejected at the
386    /// quorum `consensus_handler_load_shedding_percentage` rate.
387    pub consensus_handler_load_shedding_dropped_transactions: IntCounter,
388    /// Stake-weighted quorum (2f+1) load shedding percentage enforced on user
389    /// transactions in the most recent consensus commit. This is the cluster
390    /// value actually applied post-consensus, as opposed to this authority's
391    /// own `authority_load_shedding_percentage`. 0 when the P-COOL flow is
392    /// disabled.
393    pub consensus_handler_load_shedding_percentage: IntGauge,
394    pub consensus_handler_max_object_costs: IntGaugeVec,
395    pub consensus_committed_subdags: IntCounterVec,
396    pub consensus_committed_messages: IntGaugeVec,
397    pub consensus_committed_user_transactions: IntGaugeVec,
398    pub consensus_handler_leader_round: IntGauge,
399    pub consensus_calculated_throughput: IntGauge,
400    pub consensus_calculated_throughput_profile: IntGauge,
401
402    pub validator_scoreboard_scores: IntGaugeVec,
403    pub invalid_misbehavior_reports_by_authority: IntGaugeVec,
404
405    pub limits_metrics: Arc<LimitsMetrics>,
406
407    /// bytecode verifier metrics for tracking timeouts
408    pub bytecode_verifier_metrics: Arc<BytecodeVerifierMetrics>,
409
410    /// Count of multisig signatures
411    pub multisig_sig_count: IntCounter,
412
413    // Tracks recent average txn queueing delay between when it is ready for execution
414    // until it starts executing.
415    pub execution_queueing_latency: LatencyObserver,
416
417    // Tracks the rate at which transactions become ready for execution in the
418    // scheduler. The need for the Mutex is that the tracker is updated in the
419    // scheduler and read in the overload_monitor. There should be low mutex
420    // contention because the update side is effectively single threaded and the
421    // read rate in overload_monitor is low. If the update side becomes
422    // multi-threaded, we can create one rate tracker per thread.
423    pub txn_ready_rate_tracker: Arc<Mutex<RateTracker>>,
424
425    // Tracks the rate of transactions starts execution in execution driver.
426    // Similar reason for using a Mutex here as to `txn_ready_rate_tracker`.
427    pub execution_rate_tracker: Arc<Mutex<RateTracker>>,
428}
429
430/// How long the historic bucket expiry waits, once a retention guard that kept
431/// a bucket is dropped, before it tries again.
432const HELD_BACK_EXPIRY_INTERVAL: Duration = Duration::from_secs(1);
433
434/// How far behind the network a node's newest executed checkpoint may be for
435/// the node to count as caught up; until then, closed buckets are not
436/// compacted.
437const CATCH_UP_LAG: Duration = Duration::from_secs(10 * 60);
438
439/// How often the background expiry checks again whether the node has caught
440/// up, while that holds back the compaction of closed buckets.
441const COMPACTION_RECHECK_INTERVAL: Duration = Duration::from_secs(5 * 60);
442
443// Override default Prom buckets for positive numbers in 0-10M range
444const POSITIVE_INT_BUCKETS: &[f64] = &[
445    1., 2., 5., 7., 10., 20., 50., 70., 100., 200., 500., 700., 1000., 2000., 5000., 7000., 10000.,
446    20000., 50000., 70000., 100000., 200000., 500000., 700000., 1000000., 2000000., 5000000.,
447    7000000., 10000000.,
448];
449
450const LATENCY_SEC_BUCKETS: &[f64] = &[
451    0.0005, 0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1., 2., 3., 4., 5., 6., 7., 8., 9.,
452    10., 20., 30., 60., 90.,
453];
454
455// Buckets for low latency samples. Starts from 10us.
456const LOW_LATENCY_SEC_BUCKETS: &[f64] = &[
457    0.00001, 0.00002, 0.00005, 0.0001, 0.0002, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1,
458    0.2, 0.5, 1., 2., 5., 10., 20., 50., 100.,
459];
460
461// An expiry deletes the tombstones of the epochs it drops, which can take
462// minutes.
463const HISTORIC_BUCKET_EXPIRY_SEC_BUCKETS: &[f64] = &[
464    0.01, 0.05, 0.1, 0.5, 1., 2., 5., 10., 30., 60., 120., 300., 600., 1200., 1800.,
465];
466
467const GAS_LATENCY_RATIO_BUCKETS: &[f64] = &[
468    10.0, 50.0, 100.0, 200.0, 300.0, 400.0, 500.0, 600.0, 700.0, 800.0, 900.0, 1000.0, 2000.0,
469    3000.0, 4000.0, 5000.0, 6000.0, 7000.0, 8000.0, 9000.0, 10000.0, 50000.0, 100000.0, 1000000.0,
470];
471
472impl AuthorityMetrics {
473    pub fn new(registry: &prometheus_filtered::Registry) -> AuthorityMetrics {
474        let execute_certificate_latency = register_histogram_vec_with_registry!(
475            "authority_state_execute_certificate_latency",
476            "Latency of executing certificates, including waiting for inputs",
477            &["tx_type"],
478            LATENCY_SEC_BUCKETS.to_vec(),
479            registry;
480            MetricLevel::Info,
481        )
482        .unwrap();
483
484        let execute_certificate_latency_single_writer =
485            execute_certificate_latency.with_label_values(&[TX_TYPE_SINGLE_WRITER_TX]);
486        let execute_certificate_latency_shared_object =
487            execute_certificate_latency.with_label_values(&[TX_TYPE_SHARED_OBJ_TX]);
488
489        Self {
490            tx_orders: register_int_counter_with_registry!(
491                "total_transaction_orders",
492                "Total number of transaction orders",
493                registry;
494                MetricLevel::Warn,
495            )
496                .unwrap(),
497            total_certs: register_int_counter_with_registry!(
498                "total_transaction_certificates",
499                "Total number of transaction certificates handled",
500                registry;
501                MetricLevel::Warn,
502            )
503                .unwrap(),
504            total_cert_attempts: register_int_counter_with_registry!(
505                "total_handle_certificate_attempts",
506                "Number of calls to handle_certificate",
507                registry,
508            )
509                .unwrap(),
510            // total_effects == total transactions finished
511            total_effects: register_int_counter_with_registry!(
512                "total_transaction_effects",
513                "Total number of transaction effects produced",
514                registry;
515                MetricLevel::Warn,
516            )
517                .unwrap(),
518
519            shared_obj_tx: register_int_counter_with_registry!(
520                "num_shared_obj_tx",
521                "Number of transactions involving shared objects",
522                registry;
523                MetricLevel::Warn,
524            )
525                .unwrap(),
526
527            sponsored_tx: register_int_counter_with_registry!(
528                "num_sponsored_tx",
529                "Number of sponsored transactions",
530                registry,
531            )
532                .unwrap(),
533
534            tx_already_processed: register_int_counter_with_registry!(
535                "num_tx_already_processed",
536                "Number of transaction orders already processed previously",
537                registry,
538            )
539                .unwrap(),
540            num_input_objs: register_histogram_with_registry!(
541                "num_input_objects",
542                "Distribution of number of input TX objects per TX",
543                POSITIVE_INT_BUCKETS.to_vec(),
544                registry;
545                MetricLevel::Warn,
546            )
547                .unwrap(),
548            num_shared_objects: register_histogram_with_registry!(
549                "num_shared_objects",
550                "Number of shared input objects per TX",
551                POSITIVE_INT_BUCKETS.to_vec(),
552                registry,
553            )
554                .unwrap(),
555            batch_size: register_histogram_with_registry!(
556                "batch_size",
557                "Distribution of size of transaction batch",
558                POSITIVE_INT_BUCKETS.to_vec(),
559                registry,
560            )
561                .unwrap(),
562            authority_state_handle_transaction_latency: register_histogram_with_registry!(
563                "authority_state_handle_transaction_latency",
564                "Latency of handling transactions",
565                LATENCY_SEC_BUCKETS.to_vec(),
566                registry,
567            )
568                .unwrap(),
569            execute_certificate_latency_single_writer,
570            execute_certificate_latency_shared_object,
571            internal_execution_latency: register_histogram_with_registry!(
572                "authority_state_internal_execution_latency",
573                "Latency of actual certificate executions",
574                LATENCY_SEC_BUCKETS.to_vec(),
575                registry,
576            )
577                .unwrap(),
578            signed_effects_equivocation_prevented: register_int_counter_vec_with_registry!(
579                "authority_state_signed_effects_equivocation_prevented",
580                "Number of times the validator refused to report effects that differ from previously signed effects for the same transaction, by RPC surface",
581                &["surface"],
582                registry,
583            )
584            .unwrap(),
585            execution_load_input_objects_latency: register_histogram_with_registry!(
586                "authority_state_execution_load_input_objects_latency",
587                "Latency of loading input objects for execution",
588                LOW_LATENCY_SEC_BUCKETS.to_vec(),
589                registry,
590            )
591                .unwrap(),
592            prepare_certificate_latency: register_histogram_with_registry!(
593                "authority_state_prepare_certificate_latency",
594                "Latency of executing certificates, before committing the results",
595                LATENCY_SEC_BUCKETS.to_vec(),
596                registry,
597            )
598                .unwrap(),
599            commit_certificate_latency: register_histogram_with_registry!(
600                "authority_state_commit_certificate_latency",
601                "Latency of committing certificate execution results",
602                LATENCY_SEC_BUCKETS.to_vec(),
603                registry,
604            )
605                .unwrap(),
606            epoch_end_db_snapshot_handover_latency: register_histogram_with_registry!(
607                "epoch_end_db_snapshot_handover_latency",
608                "Time the epoch boundary waits for the consumer to take its database \
609                 snapshot of the perpetual store",
610                LATENCY_SEC_BUCKETS.to_vec(),
611                registry,
612            ).unwrap(),
613            epoch_end_db_snapshots_skipped: register_int_counter_with_registry!(
614                "epoch_end_db_snapshots_skipped",
615                "Epoch boundaries whose database snapshot was not taken, because the \
616                 consumer was busy or did not take it in time",
617                registry,
618            ).unwrap(),
619            transaction_manager_num_enqueued_certificates: register_int_counter_vec_with_registry!(
620                "transaction_manager_num_enqueued_certificates",
621                "Current number of certificates enqueued to TransactionManager",
622                &["result"],
623                registry,
624            )
625                .unwrap(),
626            transaction_manager_num_missing_objects: register_int_gauge_with_registry!(
627                "transaction_manager_num_missing_objects",
628                "Current number of missing objects in TransactionManager",
629                registry,
630            )
631                .unwrap(),
632            transaction_manager_num_pending_certificates: register_int_gauge_with_registry!(
633                "transaction_manager_num_pending_certificates",
634                "Number of certificates pending in TransactionManager, with at least 1 missing input object",
635                registry;
636                MetricLevel::Warn,
637            )
638                .unwrap(),
639            transaction_manager_num_executing_certificates: register_int_gauge_with_registry!(
640                "transaction_manager_num_executing_certificates",
641                "Number of executing certificates, including queued and actually running certificates",
642                registry;
643                MetricLevel::Warn,
644            )
645                .unwrap(),
646            transaction_manager_num_ready: register_int_gauge_with_registry!(
647                "transaction_manager_num_ready",
648                "Number of ready transactions in TransactionManager",
649                registry,
650            )
651                .unwrap(),
652            transaction_manager_object_cache_size: register_int_gauge_with_registry!(
653                "transaction_manager_object_cache_size",
654                "Current size of object-availability cache in TransactionManager",
655                registry,
656            )
657                .unwrap(),
658            transaction_manager_object_cache_hits: register_int_counter_with_registry!(
659                "transaction_manager_object_cache_hits",
660                "Number of object-availability cache hits in TransactionManager",
661                registry,
662            )
663                .unwrap(),
664            historic_bucket_earliest_retained_epoch: register_int_gauge_vec_with_registry!(
665                "historic_bucket_earliest_retained_epoch",
666                "Earliest epoch whose history a store retains",
667                &["store"],
668                registry;
669                MetricLevel::Warn,
670            )
671            .unwrap(),
672            historic_bucket_expiry_duration: register_histogram_vec_with_registry!(
673                "historic_bucket_expiry_duration_seconds",
674                "How long a store's expiries of historic buckets that dropped a bucket took",
675                &["store"],
676                HISTORIC_BUCKET_EXPIRY_SEC_BUCKETS.to_vec(),
677                registry;
678                MetricLevel::Warn,
679            )
680            .unwrap(),
681            authority_overload_status: register_int_gauge_with_registry!(
682                "authority_overload_status",
683                "Whether authority is current experiencing overload and enters load shedding mode.",
684                registry;
685                MetricLevel::Warn,)
686                .unwrap(),
687            local_post_consensus_load_shedding_percentage: register_int_gauge_with_registry!(
688                "authority_load_shedding_percentage",
689                "This authority's locally computed load shedding percentage. In the P-COOL flow this is the value broadcast to peers, not necessarily the rate enforced (see consensus_handler_load_shedding_percentage).",
690                registry;
691                MetricLevel::Info,)
692                .unwrap(),
693            consensus_queue_load_shedding_percentage: register_int_gauge_with_registry!(
694                "consensus_queue_load_shedding_percentage",
695                "Percentage of transactions shed due to consensus queue length. Separate admission-control signal, not an input to authority_load_shedding_percentage.",
696                registry)
697                .unwrap(),
698            transaction_manager_object_cache_misses: register_int_counter_with_registry!(
699                "transaction_manager_object_cache_misses",
700                "Number of object-availability cache misses in TransactionManager",
701                registry,
702            )
703                .unwrap(),
704            transaction_manager_object_cache_evictions: register_int_counter_with_registry!(
705                "transaction_manager_object_cache_evictions",
706                "Number of object-availability cache evictions in TransactionManager",
707                registry,
708            )
709                .unwrap(),
710            transaction_manager_package_cache_size: register_int_gauge_with_registry!(
711                "transaction_manager_package_cache_size",
712                "Current size of package-availability cache in TransactionManager",
713                registry,
714            )
715                .unwrap(),
716            transaction_manager_package_cache_hits: register_int_counter_with_registry!(
717                "transaction_manager_package_cache_hits",
718                "Number of package-availability cache hits in TransactionManager",
719                registry,
720            )
721                .unwrap(),
722            transaction_manager_package_cache_misses: register_int_counter_with_registry!(
723                "transaction_manager_package_cache_misses",
724                "Number of package-availability cache misses in TransactionManager",
725                registry,
726            )
727                .unwrap(),
728            transaction_manager_package_cache_evictions: register_int_counter_with_registry!(
729                "transaction_manager_package_cache_evictions",
730                "Number of package-availability cache evictions in TransactionManager",
731                registry,
732            )
733                .unwrap(),
734            transaction_manager_transaction_queue_age_s: register_histogram_with_registry!(
735                "transaction_manager_transaction_queue_age_s",
736                "Time spent in waiting for transaction in the queue",
737                LATENCY_SEC_BUCKETS.to_vec(),
738                registry;
739                MetricLevel::Warn,
740            )
741                .unwrap(),
742            transaction_overload_sources: register_int_counter_vec_with_registry!(
743                "transaction_overload_sources",
744                "Number of times each source indicates transaction overload.",
745                &["source"],
746                registry)
747                .unwrap(),
748            execution_driver_executed_transactions: register_int_counter_with_registry!(
749                "execution_driver_executed_transactions",
750                "Cumulative number of transaction executed by execution driver",
751                registry;
752                MetricLevel::Warn,
753            )
754                .unwrap(),
755            execution_driver_dispatch_queue: register_int_gauge_with_registry!(
756                "execution_driver_dispatch_queue",
757                "Number of transaction pending in execution driver dispatch queue",
758                registry,
759            )
760                .unwrap(),
761            execution_queueing_delay_s: register_histogram_with_registry!(
762                "execution_queueing_delay_s",
763                "Queueing delay between a transaction is ready for execution until it starts executing.",
764                LATENCY_SEC_BUCKETS.to_vec(),
765                registry
766            )
767                .unwrap(),
768            prepare_cert_gas_latency_ratio: register_histogram_with_registry!(
769                "prepare_cert_gas_latency_ratio",
770                "The ratio of computation gas divided by VM execution latency.",
771                GAS_LATENCY_RATIO_BUCKETS.to_vec(),
772                registry
773            )
774                .unwrap(),
775            execution_gas_latency_ratio: register_histogram_with_registry!(
776                "execution_gas_latency_ratio",
777                "The ratio of computation gas divided by certificate execution latency, include committing certificate.",
778                GAS_LATENCY_RATIO_BUCKETS.to_vec(),
779                registry
780            )
781                .unwrap(),
782            superseded_capture_misses: register_int_counter_with_registry!(
783                "superseded_capture_misses",
784                "Count of modified object versions whose pre-image could not be captured for relocation into the historic store",
785                registry;
786                MetricLevel::Warn,
787            )
788                .unwrap(),
789            skipped_consensus_txns: register_int_counter_with_registry!(
790                "skipped_consensus_txns",
791                "Total number of consensus transactions skipped",
792                registry,
793            )
794                .unwrap(),
795            skipped_consensus_txns_cache_hit: register_int_counter_with_registry!(
796                "skipped_consensus_txns_cache_hit",
797                "Total number of consensus transactions skipped because of local cache hit",
798                registry,
799            )
800                .unwrap(),
801            checkpoint_inclusion_index_wait_timeouts: register_int_counter_with_registry!(
802                "checkpoint_inclusion_index_wait_timeouts",
803                "Total number of checkpoint-inclusion waits that returned before the RPC indexes had caught up",
804                registry,
805            )
806                .unwrap(),
807            consensus_handler_processed: register_int_counter_vec_with_registry!(
808                "consensus_handler_processed",
809                "Number of transactions processed by consensus handler",
810                &["class"],
811                registry
812            ).unwrap(),
813            consensus_handler_transaction_sizes: register_histogram_vec_with_registry!(
814                "consensus_handler_transaction_sizes",
815                "Sizes of each type of transactions processed by consensus handler",
816                &["class"],
817                POSITIVE_INT_BUCKETS.to_vec(),
818                registry;
819                MetricLevel::Warn,
820            ).unwrap(),
821            consensus_handler_num_low_scoring_authorities: register_int_gauge_with_registry!(
822                "consensus_handler_num_low_scoring_authorities",
823                "Number of low scoring authorities based on reputation scores from consensus",
824                registry
825            ).unwrap(),
826            consensus_handler_scores: register_int_gauge_vec_with_registry!(
827                "consensus_handler_scores",
828                "scores from consensus for each authority",
829                &["authority"],
830                registry,
831            ).unwrap(),
832            validator_scoreboard_scores: register_int_gauge_vec_with_registry!(
833                "validator_scoreboard_scores",
834                "Per-authority validator scores published by the local Scoreboard after each consensus commit. Range [0, MAX_SCORE].",
835                &["authority"],
836                registry;
837                MetricLevel::Warn,
838            ).unwrap(),
839            invalid_misbehavior_reports_by_authority: register_int_gauge_vec_with_registry!(
840                "invalid_misbehavior_reports_by_authority",
841                "Cumulative count of invalid misbehavior reports received from each reporting authority in the current epoch. Bumped when a `MisbehaviorReport` consensus transaction fails sender/authority match or payload validation. Snapshot republished after each consensus commit.",
842                &["authority"],
843                registry;
844                MetricLevel::Warn,
845            ).unwrap(),
846            consensus_handler_deferred_transactions: register_int_counter_with_registry!(
847                "consensus_handler_deferred_transactions",
848                "Number of transactions deferred by consensus handler",
849                registry,
850            ).unwrap(),
851            consensus_handler_congested_transactions: register_int_counter_with_registry!(
852                "consensus_handler_congested_transactions",
853                "Number of transactions deferred by consensus handler due to congestion",
854                registry,
855            ).unwrap(),
856            consensus_handler_cancelled_transactions: register_int_counter_with_registry!(
857                "consensus_handler_cancelled_transactions",
858                "Number of transactions cancelled by consensus handler",
859                registry,
860            ).unwrap(),
861            consensus_handler_validation_dropped_transactions: register_int_counter_with_registry!(
862                "consensus_handler_validation_dropped_transactions",
863                "Number of user transactions dropped by post-consensus validation",
864                registry,
865            ).unwrap(),
866            consensus_handler_validation_reader_verdicts: register_int_counter_vec_with_registry!(
867                "consensus_handler_validation_reader_verdicts",
868                "Verdicts of the commit-indexed reader in post-consensus validation, by verdict and deciding reason",
869                &["verdict", "reason"],
870                registry,
871            ).unwrap(),
872            consensus_handler_commit_execution_lag: register_int_gauge_with_registry!(
873                "consensus_handler_commit_execution_lag",
874                "The consensus commit being validated minus the highest fully executed commit",
875                registry,
876            ).unwrap(),
877            consensus_handler_validation_attested_transactions: register_int_counter_vec_with_registry!(
878                "consensus_handler_validation_attested_transactions",
879                "Number of attested transactions that passed post-consensus validation, by attestation kind; a deferred transaction counts again when reloaded",
880                &["attestation"],
881                registry;
882                MetricLevel::Warn,
883            ).unwrap(),
884            consensus_handler_validation_attestor_cut_off_transactions: register_int_counter_with_registry!(
885                "consensus_handler_validation_attestor_cut_off_transactions",
886                "Number of attested transactions dropped by post-consensus validation because their attestor is cut off for the rest of the epoch",
887                registry,
888            ).unwrap(),
889            consensus_handler_load_shedding_dropped_transactions: register_int_counter_with_registry!(
890                "consensus_handler_load_shedding_dropped_transactions",
891                "Number of user transactions dropped by post-consensus load shedding, based on the quorum load shedding percentage",
892                registry,
893            ).unwrap(),
894            consensus_handler_load_shedding_percentage: register_int_gauge_with_registry!(
895                "consensus_handler_load_shedding_percentage",
896                "Stake-weighted quorum (2f+1) load shedding percentage enforced on user transactions in the most recent consensus commit. 0 when the P-COOL flow is disabled.",
897                registry,
898            ).unwrap(),
899            consensus_handler_max_object_costs: register_int_gauge_vec_with_registry!(
900                "consensus_handler_max_congestion_control_object_costs",
901                "Max object costs for congestion control in the current consensus commit",
902                &["commit_type"],
903                registry,
904            ).unwrap(),
905            consensus_committed_subdags: register_int_counter_vec_with_registry!(
906                "consensus_committed_subdags",
907                "Number of committed subdags, sliced by leader",
908                &["authority"],
909                registry,
910            ).unwrap(),
911            consensus_committed_messages: register_int_gauge_vec_with_registry!(
912                "consensus_committed_messages",
913                "Total number of committed consensus messages, sliced by author",
914                &["authority"],
915                registry;
916                MetricLevel::Warn,
917            ).unwrap(),
918            consensus_committed_user_transactions: register_int_gauge_vec_with_registry!(
919                "consensus_committed_user_transactions",
920                "Number of committed user transactions, sliced by submitter",
921                &["authority"],
922                registry,
923            ).unwrap(),
924            consensus_handler_leader_round: register_int_gauge_with_registry!(
925                "consensus_handler_leader_round",
926                "The leader round of the current consensus output being processed in the consensus handler",
927                registry;
928                MetricLevel::Warn,
929            ).unwrap(),
930            limits_metrics: Arc::new(LimitsMetrics::new(registry)),
931            bytecode_verifier_metrics: Arc::new(BytecodeVerifierMetrics::new(registry)),
932            multisig_sig_count: register_int_counter_with_registry!(
933                "multisig_sig_count",
934                "Count of multisig signatures",
935                registry,
936            )
937                .unwrap(),
938            consensus_calculated_throughput: register_int_gauge_with_registry!(
939                "consensus_calculated_throughput",
940                "The calculated throughput from consensus output. Result is calculated based on unique transactions.",
941                registry,
942            ).unwrap(),
943            consensus_calculated_throughput_profile: register_int_gauge_with_registry!(
944                "consensus_calculated_throughput_profile",
945                "The current active calculated throughput profile",
946                registry
947            ).unwrap(),
948            execution_queueing_latency: LatencyObserver::new(),
949            txn_ready_rate_tracker: Arc::new(Mutex::new(RateTracker::new(Duration::from_secs(10)))),
950            execution_rate_tracker: Arc::new(Mutex::new(RateTracker::new(Duration::from_secs(10)))),
951        }
952    }
953
954    /// Reset metrics that contain `hostname` as one of the labels. This is
955    /// needed to avoid retaining metrics for long-gone committee members and
956    /// only exposing metrics for the committee in the current epoch.
957    pub fn reset_on_reconfigure(&self) {
958        self.consensus_committed_messages.reset();
959        self.consensus_handler_scores.reset();
960        self.validator_scoreboard_scores.reset();
961        self.invalid_misbehavior_reports_by_authority.reset();
962        self.consensus_committed_user_transactions.reset();
963    }
964}
965
966/// a Trait object for `Signer` that is:
967/// - Pin, i.e. confined to one place in memory (we don't want to copy private keys).
968/// - Sync, i.e. can be safely shared between threads.
969///
970/// Typically instantiated with Box::pin(keypair) where keypair is a `KeyPair`
971pub type StableSyncAuthoritySigner = Pin<Arc<dyn Signer<AuthoritySignature> + Send + Sync>>;
972
973/// The checked transaction inputs and, per Move authenticator, its checked inputs.
974type CheckedValidationInputs = (CheckedInputObjects, Vec<CheckedInputObjects>);
975
976/// Execution env contains the "environment" for the transaction to be executed
977/// in, that is, all the information necessary for execution that is not
978/// specified by the transaction itself.
979#[derive(Debug, Clone, Default)]
980pub struct ExecutionEnv {
981    /// The assigned version of each shared object for the transaction.
982    pub assigned_versions: AssignedVersions,
983    /// The expected digest of the effects of the transaction, if executing from
984    /// checkpoint or other sources where the effects are known in advance.
985    pub expected_effects_digest: Option<TransactionEffectsDigest>,
986    /// Where the verdict on the transaction's attestation comes from.
987    pub attestation: AttestationSource,
988}
989
990impl ExecutionEnv {
991    pub fn new() -> Self {
992        Default::default()
993    }
994
995    pub fn with_expected_effects_digest(
996        mut self,
997        expected_effects_digest: TransactionEffectsDigest,
998    ) -> Self {
999        self.expected_effects_digest = Some(expected_effects_digest);
1000        self
1001    }
1002
1003    pub fn with_assigned_versions(mut self, assigned_versions: AssignedVersions) -> Self {
1004        if !assigned_versions.is_empty() {
1005            self.assigned_versions = assigned_versions;
1006        }
1007        self
1008    }
1009
1010    pub fn with_attestation(mut self, attestation: AttestationSource) -> Self {
1011        self.attestation = attestation;
1012        self
1013    }
1014}
1015
1016/// `execute_transaction()`'s result. The fourth element holds every object read
1017/// during execution, where the pre-image of a mutated object that is not a
1018/// declared input, such as a dynamic field, is found; the last is the record of
1019/// an attested transaction's verdict.
1020type TransactionExecutionResult = (
1021    InnerTemporaryStore,
1022    TransactionEffects,
1023    Option<ExecutionError>,
1024    ObjectSet,
1025    Option<AttestationRecord>,
1026);
1027
1028/// Reads latest versions from the live object set, and exact versions from it
1029/// or, after a miss there, from the historic buckets.
1030struct ObjectStoreWithHistoricFallback<'a>(&'a AuthorityState);
1031
1032impl ObjectStore for ObjectStoreWithHistoricFallback<'_> {
1033    fn try_get_object(
1034        &self,
1035        object_id: &ObjectId,
1036    ) -> iota_types::storage::error::Result<Option<Object>> {
1037        self.0.get_object_store().try_get_object(object_id)
1038    }
1039
1040    fn try_get_object_by_key(
1041        &self,
1042        object_id: &ObjectId,
1043        version: Version,
1044    ) -> iota_types::storage::error::Result<Option<Object>> {
1045        self.0
1046            .get_object_with_historic_fallback(&ObjectKey(*object_id, version))
1047            .map_err(iota_types::storage::error::Error::custom)
1048    }
1049
1050    fn try_multi_get_objects_by_key(
1051        &self,
1052        object_keys: &[ObjectKey],
1053    ) -> iota_types::storage::error::Result<Vec<Option<Object>>> {
1054        let mut objects = self
1055            .0
1056            .get_object_store()
1057            .try_multi_get_objects_by_key(object_keys)?;
1058        self.0
1059            .historic_objects
1060            .fill_missing(object_keys, &mut objects, None)
1061            .map_err(iota_types::storage::error::Error::custom)?;
1062        Ok(objects)
1063    }
1064}
1065
1066pub struct AuthorityState {
1067    // Fixed size, static, identity of the authority
1068    /// The name of this authority.
1069    pub name: AuthorityName,
1070    /// The signature key of the authority.
1071    pub secret: StableSyncAuthoritySigner,
1072
1073    /// The database
1074    input_loader: TransactionInputLoader,
1075    execution_cache_trait_pointers: ExecutionCacheTraitPointers,
1076
1077    epoch_store: ArcSwap<AuthorityPerEpochStore>,
1078
1079    /// This lock denotes current 'execution epoch'.
1080    /// Execution acquires read lock, checks transaction epoch and holds it
1081    /// until all writes are complete. Reconfiguration acquires write lock,
1082    /// changes the epoch and revert all transactions from previous epoch
1083    /// that are executed but did not make into checkpoint.
1084    execution_lock: RwLock<EpochId>,
1085
1086    /// The RPC index store, absent when this node maintains no index group.
1087    pub rpc_indexes_store: Option<Arc<RpcIndexesStore>>,
1088
1089    /// Superseded object versions, bucketed by epoch.
1090    historic_objects: Arc<HistoricObjects>,
1091
1092    /// Executed transactions keyed by checkpoint, bucketed by epoch.
1093    historic_ledger: Arc<HistoricLedger>,
1094
1095    pub checkpoint_store: Arc<CheckpointStore>,
1096
1097    committee_store: Arc<CommitteeStore>,
1098
1099    /// Schedules transaction execution.
1100    execution_scheduler: Arc<ExecutionSchedulerWrapper>,
1101
1102    /// Shuts down the execution task. Used only in testing.
1103    #[cfg_attr(not(test), expect(unused))]
1104    tx_execution_shutdown: Mutex<Option<oneshot::Sender<()>>>,
1105
1106    pub metrics: Arc<AuthorityMetrics>,
1107    authority_per_epoch_pruner: AuthorityPerEpochStorePruner,
1108    /// The checkpoints execution responses still read superseded object
1109    /// versions from; bucket expiry keeps their epochs.
1110    object_retention: ObjectRetention,
1111
1112    /// Announces each epoch entered to the task that expires the historic
1113    /// buckets.
1114    historic_bucket_expiry: watch::Sender<EpochId>,
1115    /// Set by [`Self::stop_historic_bucket_work`].
1116    historic_bucket_work_stopped: Arc<AtomicBool>,
1117
1118    pub config: NodeConfig,
1119
1120    /// Current overload status in this authority. Updated periodically.
1121    pub overload_info: AuthorityOverloadInfo,
1122
1123    pub validator_tx_finalizer: Option<Arc<ValidatorTxFinalizer<NetworkAuthorityClient>>>,
1124
1125    /// The chain identifier is derived from the digest of the genesis
1126    /// checkpoint.
1127    chain_identifier: ChainIdentifier,
1128
1129    pub(crate) congestion_tracker: Arc<CongestionTracker>,
1130
1131    /// Traffic controller for IOTA core servers (json-rpc, validator service)
1132    pub traffic_controller: Option<Arc<TrafficController>>,
1133    /// Set when a consumer wants a database snapshot of the perpetual store at
1134    /// each epoch boundary. See [`Self::hand_over_epoch_end_db_snapshot`].
1135    epoch_end_db_snapshots: Option<EpochEndDbSnapshotHandle>,
1136}
1137
1138/// Outputs of the shared transaction validation pipeline used by both
1139/// `handle_transaction_validation_checks` and `attest_transaction`.
1140struct ValidationOutputs<'a> {
1141    per_authenticator_inputs: Vec<(InputObjects, ObjectReadResult)>,
1142    move_authenticators: Vec<&'a MoveAuthenticator>,
1143    gas_status: IotaGasStatus,
1144    tx_checked_input_objects: CheckedInputObjects,
1145    per_authenticator_checked_inputs: Vec<(CheckedInputObjects, AuthenticatorFunctionRef)>,
1146}
1147
1148/// The authority state encapsulates all state, drives execution, and ensures
1149/// safety.
1150///
1151/// Note the authority operations can be accessed through a read ref (&) and do
1152/// not require &mut. Internally a database is synchronized through a mutex
1153/// lock.
1154///
1155/// Repeating valid commands should produce no changes and return no error.
1156impl AuthorityState {
1157    pub fn is_committee_validator(&self, epoch_store: &AuthorityPerEpochStore) -> bool {
1158        epoch_store.committee().authority_exists(&self.name)
1159    }
1160
1161    pub fn is_active_validator(&self, epoch_store: &AuthorityPerEpochStore) -> bool {
1162        epoch_store
1163            .active_validators()
1164            .iter()
1165            .any(|a| AuthorityName::from(a) == self.name)
1166    }
1167
1168    pub fn is_fullnode(&self, epoch_store: &AuthorityPerEpochStore) -> bool {
1169        !self.is_committee_validator(epoch_store)
1170    }
1171
1172    pub fn committee_store(&self) -> &Arc<CommitteeStore> {
1173        &self.committee_store
1174    }
1175
1176    pub fn clone_committee_store(&self) -> Arc<CommitteeStore> {
1177        self.committee_store.clone()
1178    }
1179
1180    pub fn overload_config(&self) -> &AuthorityOverloadConfig {
1181        &self.config.authority_overload_config
1182    }
1183
1184    pub fn get_epoch_state_commitments(
1185        &self,
1186        epoch: EpochId,
1187    ) -> IotaResult<Option<Vec<CheckpointCommitment>>> {
1188        self.checkpoint_store.get_epoch_state_commitments(epoch)
1189    }
1190
1191    /// Runs deny list, input object validation, gas checks, coin deny list, and
1192    /// MoveAuthenticator checks. Returns the owned object refs for optional
1193    /// version validation. Does NOT acquire locks or sign the transaction.
1194    ///
1195    /// [`Self::handle_transaction_validation_checks_at_commit`] repeats the
1196    /// checks after loading the inputs for post-consensus validation at a
1197    /// commit, so a check added here belongs there too.
1198    ///
1199    /// `deny_config` is the deny rule source to enforce, chosen per caller:
1200    /// the local config alone, or with `enable_pcool_flow` the local config
1201    /// combined with the governance rules.
1202    ///
1203    /// These are the checks of validator-local admission: the coin deny list
1204    /// is read at its latest value, so a denial or global pause applies at
1205    /// once, and published packages are verified with this validator's own
1206    /// `VerifierSigningConfig`. Post-consensus validation does not call this
1207    /// function: [`Self::handle_transaction_validation_checks_at_commit`]
1208    /// reads the deny list as of the commit's horizon, where a change made
1209    /// this epoch counts from the horizon distance after the commit that made
1210    /// it, and verifies packages with the protocol config's limits, so every
1211    /// validator reaches the same verdict.
1212    #[instrument(level = "trace", skip_all, fields(tx_digest = ?transaction.digest()))]
1213    pub(crate) async fn handle_transaction_validation_checks(
1214        &self,
1215        transaction: &VerifiedTransaction,
1216        epoch_store: &Arc<AuthorityPerEpochStore>,
1217        deny_config: &dyn DenyRuleConfig,
1218    ) -> IotaResult<Vec<ObjectReference>> {
1219        let protocol_config = epoch_store.protocol_config();
1220        let tx = transaction.data().transaction();
1221
1222        let ValidationOutputs {
1223            move_authenticators,
1224            gas_status,
1225            tx_checked_input_objects,
1226            per_authenticator_checked_inputs,
1227            per_authenticator_inputs: _,
1228        } = self.run_validation_checks(transaction, epoch_store, deny_config, false)?;
1229
1230        let (_, signer, gas_data) = tx.execution_parts();
1231
1232        let (sender_authenticator_function_ref, sponsor_authenticator_function_ref) =
1233            extract_auth_fun_refs(signer, gas_data.owner, |address| {
1234                move_authenticators
1235                    .iter()
1236                    .zip(per_authenticator_checked_inputs.iter())
1237                    .find(|(move_authenticator, _)| move_authenticator.address() == address)
1238                    .map(|(_, (_, auth_fun_ref))| auth_fun_ref.clone())
1239            });
1240
1241        // Filter the authenticators and their checked inputs down to those that must
1242        // be executed pre-consensus. This is done *after* the deny-list check so
1243        // that all MoveAuthenticator input objects are covered by that check regardless
1244        // of deferral.
1245        let pre_consensus_move_authenticators =
1246            pre_consensus_move_authenticators(transaction, protocol_config);
1247        // Asserted before the zip below pairs them positionally; the two lists
1248        // come from independent computations.
1249        debug_assert_eq!(
1250            move_authenticators.len(),
1251            per_authenticator_checked_inputs.len(),
1252            "Move authenticators amount must match the number of checked authenticator inputs"
1253        );
1254        let (move_authenticators, per_authenticator_checked_inputs): (Vec<_>, Vec<_>) =
1255            move_authenticators
1256                .into_iter()
1257                .zip(per_authenticator_checked_inputs)
1258                .filter(|(a, _)| pre_consensus_move_authenticators.contains(a))
1259                .unzip();
1260        // If there are `MoveAuthenticator` signatures, execute them and check if they
1261        // all succeed.
1262        if !move_authenticators.is_empty() {
1263            let authenticators = move_authenticators
1264                .into_iter()
1265                .zip(per_authenticator_checked_inputs)
1266                .map(
1267                    |(
1268                        move_authenticator,
1269                        (authenticator_checked_input_objects, authenticator_function_ref),
1270                    )| {
1271                        (
1272                            move_authenticator.to_owned(),
1273                            authenticator_function_ref,
1274                            authenticator_checked_input_objects,
1275                        )
1276                    },
1277                )
1278                .collect();
1279            self.authenticate_before_consensus(
1280                epoch_store,
1281                transaction,
1282                gas_status,
1283                authenticators,
1284                (
1285                    sender_authenticator_function_ref,
1286                    sponsor_authenticator_function_ref,
1287                ),
1288            )?;
1289        }
1290
1291        Ok(tx_checked_input_objects.inner().filter_owned_objects())
1292    }
1293
1294    /// Runs `authenticators` on their own, metered by `gas_status`, and fails
1295    /// as admission does when one rejects the transaction or runs out of gas.
1296    /// `function_refs` are the sender's and the gas owner's authenticator
1297    /// functions, resolved over every authenticator of the transaction.
1298    fn authenticate_before_consensus(
1299        &self,
1300        epoch_store: &Arc<AuthorityPerEpochStore>,
1301        transaction: &VerifiedTransaction,
1302        gas_status: IotaGasStatus,
1303        authenticators: Vec<(
1304            MoveAuthenticator,
1305            AuthenticatorFunctionRef,
1306            CheckedInputObjects,
1307        )>,
1308        function_refs: (
1309            Option<AuthenticatorFunctionRef>,
1310            Option<AuthenticatorFunctionRef>,
1311        ),
1312    ) -> IotaResult<()> {
1313        let tx = transaction.data().transaction();
1314        let (kind, signer, gas_data) = tx.execution_parts();
1315        let input_objects: Vec<_> = authenticators
1316            .iter()
1317            .map(|(_, _, input_objects)| input_objects)
1318            .collect();
1319        let aggregated_authenticator_input_objects =
1320            iota_transaction_checks::aggregate_authenticator_input_objects(&input_objects)?;
1321        let (sender_auth_digest, sponsor_auth_digest) =
1322            transaction.data().compute_auth_digests()?;
1323        let (sender_authenticator_function_ref, sponsor_authenticator_function_ref) = function_refs;
1324        let auth_context_data = AuthContextData {
1325            transaction_data_bytes: bcs::to_bytes(tx)
1326                .expect("Transaction serialization cannot fail"),
1327            sender_auth_digest,
1328            sponsor_auth_digest,
1329            sender_authenticator_function_ref,
1330            sponsor_authenticator_function_ref,
1331        };
1332
1333        let (_gas_status, result) = epoch_store.executor().authenticate_transaction(
1334            self.get_backing_store().as_ref(),
1335            epoch_store.protocol_config(),
1336            self.metrics.limits_metrics.clone(),
1337            &epoch_store.epoch_start_config().epoch_data().epoch_id(),
1338            epoch_store
1339                .epoch_start_config()
1340                .epoch_data()
1341                .epoch_start_timestamp(),
1342            gas_data,
1343            gas_status,
1344            authenticators,
1345            aggregated_authenticator_input_objects,
1346            kind,
1347            signer,
1348            transaction.digest().to_owned(),
1349            auth_context_data,
1350            &mut None,
1351        );
1352        result.map_err(|error| IotaError::MoveAuthenticatorExecutionFailure {
1353            error: error.to_string(),
1354        })
1355    }
1356
1357    /// Like [`Self::handle_transaction_validation_checks`], but for
1358    /// post-consensus validation at the commit `reader` was built for: the
1359    /// inputs and receiving objects are read as of that commit through the
1360    /// commit-indexed reader. Returns `Drop` or `Missing` when one of them is
1361    /// dropped or not visible yet. Any other failed check returns the same
1362    /// `Err` as at admission, except that the coin deny list is read as of the
1363    /// reader's horizon, with changes counting from there rather than from the
1364    /// next epoch. The Move authenticator's account is not resolved and the
1365    /// authenticators are not run here: both happen at execution. Instead,
1366    /// each account must have had its authenticator function field at the
1367    /// horizon, or the transaction is reported missing. The package that
1368    /// field names, and its dependencies, read as of the horizon, are checked
1369    /// against the deny rules of the commit, and a denial is returned as
1370    /// [`ValidationAtCommit::AuthenticatorPackageDenied`], since it holds for
1371    /// every copy of the transaction. So an account whose function is changed
1372    /// to a denied package above the horizon is not caught here.
1373    ///
1374    /// An attested transaction (`attested`) runs the input checks execution
1375    /// runs, so a kept one cannot fail them at execution. It also runs the
1376    /// checks on receiving objects; the publish verifier stays at execution.
1377    #[instrument(level = "trace", skip_all, fields(tx_digest = ?transaction.digest()))]
1378    pub(crate) fn handle_transaction_validation_checks_at_commit(
1379        &self,
1380        reader: &CommitIndexedReader,
1381        transaction: &VerifiedTransaction,
1382        epoch_store: &Arc<AuthorityPerEpochStore>,
1383        deny_config: &dyn DenyRuleConfig,
1384        verifier_limits_source: VerifierLimitsSource<'_>,
1385        attested: bool,
1386    ) -> IotaResult<ValidationAtCommit> {
1387        let protocol_config = epoch_store.protocol_config();
1388        let reference_gas_price = epoch_store.reference_gas_price();
1389
1390        let tx = transaction.data().transaction();
1391
1392        let (tx_input_objects, tx_receiving_objects, per_authenticator_inputs) = match self
1393            .read_objects_for_validation_at_commit(reader, transaction, protocol_config)?
1394        {
1395            ValidationInputsAtCommit::Loaded {
1396                tx_input_objects,
1397                tx_receiving_objects,
1398                per_authenticator_inputs,
1399            } => (
1400                tx_input_objects,
1401                tx_receiving_objects,
1402                per_authenticator_inputs,
1403            ),
1404            ValidationInputsAtCommit::Drop(kind, reason) => {
1405                return Ok(ValidationAtCommit::Drop(kind, reason));
1406            }
1407            ValidationInputsAtCommit::Missing(kind, reason) => {
1408                return Ok(ValidationAtCommit::Missing(kind, reason));
1409            }
1410        };
1411
1412        // The deny rules load packages through the reader. They run after the
1413        // inputs are loaded, so a call into a package not visible at this
1414        // commit has already answered missing instead of failing here as not
1415        // found.
1416        iota_transaction_checks::deny::check_transaction_for_validation(
1417            tx,
1418            transaction.signatures(),
1419            &transaction
1420                .input_objects(protocol_config.move_authenticator_type_arg_packages_as_inputs())?,
1421            &tx.receiving_objects(),
1422            deny_config,
1423            reader,
1424        )?;
1425
1426        let move_authenticators = transaction.move_authenticators();
1427
1428        // The account is not resolved and the authenticators are not run
1429        // here. Both read a shared object's contents, and a shared input names
1430        // no version, so this would read whatever version this validator
1431        // holds, which differs between validators. Execution reads every
1432        // shared input at the version consensus assigned, so both happen
1433        // there, and a failure there produces failure effects. What is left
1434        // here asks only what the rows can answer: whether each authenticator
1435        // input exists and is what the transaction declares, and whether each
1436        // account had its authenticator function field at the horizon. That
1437        // field also names the package checked against the deny rules below,
1438        // and an account without it is reported missing last.
1439        let (tx_checked_input_objects, per_authenticator_checked_inputs) = if attested {
1440            self.check_attested_transaction_inputs_at_commit(
1441                protocol_config,
1442                reference_gas_price,
1443                tx,
1444                tx_input_objects,
1445                &tx_receiving_objects,
1446                &move_authenticators,
1447                per_authenticator_inputs,
1448            )?
1449        } else {
1450            self.check_transaction_inputs_at_commit(
1451                protocol_config,
1452                reference_gas_price,
1453                tx,
1454                tx_input_objects,
1455                &tx_receiving_objects,
1456                &move_authenticators,
1457                per_authenticator_inputs,
1458                verifier_limits_source,
1459            )?
1460        };
1461
1462        let per_authenticator_checked_input_objects =
1463            per_authenticator_checked_inputs.iter().collect::<Vec<_>>();
1464
1465        debug_assert!(
1466            per_authenticator_checked_input_objects
1467                .iter()
1468                .all(|objects| objects.inner().filter_owned_objects().is_empty()),
1469            "Move authenticator input objects must not contain owned objects"
1470        );
1471
1472        // Each account's authenticator function field as of the horizon, read
1473        // once: the deny check below reads the package it names, and an
1474        // account without it is reported missing last.
1475        let accounts = move_authenticators
1476            .iter()
1477            .map(|move_authenticator| {
1478                let account_kind = move_authenticator
1479                    .object_to_authenticate()
1480                    .input_object_kind()
1481                    .expect("the object to authenticate is validated before consensus");
1482                Ok((account_kind, reader.read_account(account_kind.object_id())?))
1483            })
1484            .collect::<IotaResult<Vec<_>>>()?;
1485
1486        // The package holding each authenticate function, as at admission,
1487        // but named by the account's field as of the horizon, the same on
1488        // every validator.
1489        if protocol_config.deny_authenticator_packages() && deny_config.has_denied_packages() {
1490            let mut function_refs = Vec::new();
1491            for (account_kind, verdict) in &accounts {
1492                if let AccountVerdict::Account(field) = verdict {
1493                    function_refs.extend(
1494                        reader
1495                            .visible_authenticator_function_ref(account_kind.object_id(), field)?,
1496                    );
1497                }
1498            }
1499            if let Err(error) = iota_transaction_checks::deny::check_authenticator_packages(
1500                deny_config,
1501                &function_refs,
1502                reader,
1503            ) {
1504                if error.is_storage_or_epoch_error() {
1505                    return Err(error);
1506                }
1507                return Ok(ValidationAtCommit::AuthenticatorPackageDenied(error));
1508            }
1509        }
1510
1511        // The sender against the coin types of its inputs and receiving
1512        // objects, as at admission, but with the deny list as of the horizon,
1513        // the same on every validator. A kept receiving object was loaded at
1514        // the version the transaction names. A shared input's object is not
1515        // loaded, so its type is read on its own. Execution also checks the
1516        // coins Move code receives, and the coins it writes, against the deny
1517        // list as the epoch started.
1518        let mut shared_objects = Vec::new();
1519        for input in tx_checked_input_objects.inner().iter().chain(
1520            per_authenticator_checked_input_objects
1521                .iter()
1522                .flat_map(|objects| objects.inner().iter()),
1523        ) {
1524            if let (
1525                InputObjectKind::SharedMoveObject {
1526                    id,
1527                    initial_shared_version,
1528                    ..
1529                },
1530                None,
1531            ) = (input.input_object_kind, input.as_object())
1532            {
1533                shared_objects
1534                    .push(reader.read_shared_object_for_type(id, initial_shared_version)?);
1535            }
1536        }
1537        let coin_types = coin_types_for_denylist_check(
1538            tx_checked_input_objects
1539                .inner()
1540                .iter_objects()
1541                .chain(
1542                    per_authenticator_checked_input_objects
1543                        .iter()
1544                        .flat_map(|objects| objects.inner().iter_objects()),
1545                )
1546                .chain(&shared_objects)
1547                .chain(tx_receiving_objects.iter_objects()),
1548        );
1549        if let Some(denial) = DenyListAtCommit::new(reader).denial(tx.sender(), coin_types)? {
1550            return Err(denial.into());
1551        }
1552
1553        // Last, so a check that rejects the transaction outright is reported
1554        // rather than a missing verdict that invites a resubmission.
1555        for (account_kind, verdict) in accounts {
1556            if let AccountVerdict::Missing(reason) = verdict {
1557                return Ok(ValidationAtCommit::Missing(account_kind, reason));
1558            }
1559        }
1560
1561        Ok(ValidationAtCommit::Keep(
1562            tx_checked_input_objects.inner().filter_owned_objects(),
1563        ))
1564    }
1565
1566    /// This is a private method and should be kept that way. It doesn't check
1567    /// whether the provided transaction is a system transaction, and hence
1568    /// can only be called internally.
1569    async fn handle_transaction_impl(
1570        &self,
1571        transaction: VerifiedTransaction,
1572        epoch_store: &Arc<AuthorityPerEpochStore>,
1573    ) -> IotaResult<VerifiedSignedTransaction> {
1574        // Ensure that validator cannot reconfigure while we are signing the tx
1575        let _execution_lock = self.execution_lock_for_signing()?;
1576
1577        let owned_objects = self
1578            .handle_transaction_validation_checks(
1579                &transaction,
1580                epoch_store,
1581                &self.config.transaction_deny_config,
1582            )
1583            .await?;
1584
1585        let epoch = epoch_store.epoch();
1586        let signed_transaction =
1587            VerifiedSignedTransaction::new(epoch, transaction, self.name, &*self.secret);
1588
1589        // Check and write locks, to signed transaction, into the database
1590        // The call to self.set_transaction_lock checks the lock is not conflicting,
1591        // and returns ConflictingTransaction error in case there is a lock on a
1592        // different existing transaction.
1593        self.get_cache_writer().try_acquire_transaction_locks(
1594            epoch_store,
1595            &owned_objects,
1596            signed_transaction.clone(),
1597        )?;
1598
1599        Ok(signed_transaction)
1600    }
1601
1602    /// Initiate a new transaction.
1603    #[instrument(name = "handle_transaction", level = "trace", skip_all, fields(tx_digest = ?transaction.digest(), sender = transaction.data().transaction().gas_owner().to_string()
1604    ))]
1605    pub async fn handle_transaction(
1606        &self,
1607        epoch_store: &Arc<AuthorityPerEpochStore>,
1608        transaction: VerifiedTransaction,
1609    ) -> IotaResult<HandleTransactionResponse> {
1610        let tx_digest = *transaction.digest();
1611        debug!("handle_transaction");
1612
1613        // Ensure an idempotent answer.
1614        if let Some((_, status)) = self.get_transaction_status(&tx_digest, epoch_store)? {
1615            return Ok(HandleTransactionResponse { status });
1616        }
1617
1618        let _metrics_guard = self
1619            .metrics
1620            .authority_state_handle_transaction_latency
1621            .start_timer();
1622        self.metrics.tx_orders.inc();
1623
1624        let signed = self.handle_transaction_impl(transaction, epoch_store).await;
1625        match signed {
1626            Ok(s) => {
1627                if self.is_committee_validator(epoch_store) {
1628                    if let Some(validator_tx_finalizer) = &self.validator_tx_finalizer {
1629                        let tx = s.clone();
1630                        let validator_tx_finalizer = validator_tx_finalizer.clone();
1631                        let cache_reader = self.get_transaction_cache_reader().clone();
1632                        let epoch_store = epoch_store.clone();
1633                        spawn_monitored_task!(epoch_store.within_alive_epoch(
1634                            validator_tx_finalizer.track_signed_tx(cache_reader, &epoch_store, tx)
1635                        ));
1636                    }
1637                }
1638                Ok(HandleTransactionResponse {
1639                    status: TransactionStatus::Signed(s.into_inner().into_sig()),
1640                })
1641            }
1642            // It happens frequently that while we are checking the validity of the transaction, it
1643            // has just been executed.
1644            // In that case, we could still return Ok to avoid showing confusing errors.
1645            Err(err) => Ok(HandleTransactionResponse {
1646                status: self
1647                    .get_transaction_status(&tx_digest, epoch_store)?
1648                    .ok_or(err)?
1649                    .1,
1650            }),
1651        }
1652    }
1653
1654    pub fn check_system_overload_at_signing(&self) -> bool {
1655        self.config
1656            .authority_overload_config
1657            .check_system_overload_at_signing
1658    }
1659
1660    pub fn check_system_overload_at_execution(&self) -> bool {
1661        self.config
1662            .authority_overload_config
1663            .check_system_overload_at_execution
1664    }
1665
1666    /// Checks system overload conditions before accepting a transaction.
1667    ///
1668    /// In certificate-less (P-COOL) mode: only checks consensus
1669    /// queue overload, since execution-based overload will be handled
1670    /// post-consensus.
1671    ///
1672    /// In certificate mode: runs all checks — authority overload
1673    /// (execution latency), the execution scheduler (execution queue),
1674    /// consensus adapter (queue limit), and writeback cache backpressure.
1675    pub(crate) fn check_system_overload(
1676        &self,
1677        consensus_adapter: &Arc<ConsensusAdapter>,
1678        tx: &SenderSignedTransaction,
1679        do_authority_overload_check: bool,
1680        pcool_flow_enabled: bool,
1681    ) -> IotaResult {
1682        if pcool_flow_enabled {
1683            // Graduated shedding: 0% to 100% as consensus queue fills from soft
1684            // to hard limit.
1685            self.check_consensus_queue_graduated_limits(consensus_adapter, tx)
1686                .tap_err(|_| {
1687                    self.update_overload_metrics("consensus");
1688                })?;
1689
1690            // NOTE: graduated shedding at 100% already rejects everything at or above
1691            // `max_pending_transactions`, so the queue-length part of the check below
1692            // is redundant but harmless. But `check_consensus_overload()` should be
1693            // kept here because it also verifies that `submit_semaphore` has permits
1694            // (see `check_consensus_hard_limits` in consensus_adapter.rs), which is a
1695            // separate concurrency limit not covered by the graduated shedding.
1696            consensus_adapter.check_consensus_overload().tap_err(|_| {
1697                self.update_overload_metrics("consensus");
1698            })?;
1699        } else {
1700            if do_authority_overload_check {
1701                self.check_authority_overload(tx).tap_err(|_| {
1702                    self.update_overload_metrics("execution_queue");
1703                })?;
1704            }
1705            self.execution_scheduler
1706                .check_execution_overload(self.overload_config(), tx)
1707                .tap_err(|_| {
1708                    self.update_overload_metrics("execution_pending");
1709                })?;
1710            consensus_adapter.check_consensus_overload().tap_err(|_| {
1711                self.update_overload_metrics("consensus");
1712            })?;
1713
1714            let pending_tx_count = self
1715                .get_cache_commit()
1716                .approximate_pending_transaction_count();
1717            if pending_tx_count
1718                > self
1719                    .config
1720                    .execution_cache_config
1721                    .writeback_cache
1722                    .backpressure_threshold_for_rpc()
1723            {
1724                return Err(IotaError::ValidatorOverloadedRetryAfter {
1725                    retry_after_secs: 10,
1726                });
1727            }
1728        }
1729
1730        Ok(())
1731    }
1732
1733    /// Rejects `tx_data` via graduated shedding based on consensus queue
1734    /// length. Scales from 0% at the soft limit to 100% at
1735    /// `max_pending_transactions`. Returns `ValidatorOverloadedRetryAfter`
1736    /// for probabilistic rejection (shedding percentage < 100%, via
1737    /// `overload_monitor_accept_tx`) or `TooManyTransactionsPendingConsensus`
1738    /// for unconditional rejection (shedding percentage >= 100%). Updates
1739    /// `consensus_queue_load_shedding_percentage` metric.
1740    fn check_consensus_queue_graduated_limits(
1741        &self,
1742        consensus_adapter: &Arc<ConsensusAdapter>,
1743        tx: &SenderSignedTransaction,
1744    ) -> IotaResult {
1745        let num_inflight_txs = consensus_adapter.num_inflight_transactions() as usize;
1746
1747        let shedding_pct = compute_graduated_load_shedding_percentage(
1748            num_inflight_txs,
1749            consensus_adapter.max_pending_transactions(),
1750            consensus_adapter.graduated_load_shedding_soft_limit_pct(),
1751        );
1752
1753        self.metrics
1754            .consensus_queue_load_shedding_percentage
1755            .set(shedding_pct as i64);
1756
1757        if shedding_pct == 0 {
1758            return Ok(());
1759        }
1760
1761        // At/above the hard limit, rejection is unconditional (not
1762        // probabilistic), so the seed-rotation retry hint of
1763        // `ValidatorOverloadedRetryAfter` doesn't apply - return the
1764        // capacity-bound error instead.
1765        if shedding_pct >= 100 {
1766            return Err(IotaError::TooManyTransactionsPendingConsensus);
1767        }
1768
1769        overload_monitor_accept_tx(shedding_pct, tx.digest())
1770    }
1771
1772    fn check_authority_overload(&self, tx: &SenderSignedTransaction) -> IotaResult {
1773        if !self.overload_info.is_overload.load(Ordering::Relaxed) {
1774            return Ok(());
1775        }
1776
1777        let load_shedding_percentage = self
1778            .overload_info
1779            .local_load_shedding_percentage
1780            .load(Ordering::Relaxed);
1781        overload_monitor_accept_tx(load_shedding_percentage, tx.digest())
1782    }
1783
1784    fn update_overload_metrics(&self, source: &str) {
1785        self.metrics
1786            .transaction_overload_sources
1787            .with_label_values(&[source])
1788            .inc();
1789    }
1790
1791    /// Wait for a certificate to be executed.
1792    /// For consensus transactions, it needs to be sequenced by the consensus.
1793    /// For owned object transactions, this function will enqueue the
1794    /// transaction for execution.
1795    #[instrument(level = "trace", skip_all)]
1796    pub async fn wait_for_certificate_execution(
1797        &self,
1798        certificate: &VerifiedCertificate,
1799        epoch_store: &Arc<AuthorityPerEpochStore>,
1800    ) -> IotaResult<TransactionEffects> {
1801        let _metrics_guard = if certificate.contains_shared_object() {
1802            self.metrics
1803                .execute_certificate_latency_shared_object
1804                .start_timer()
1805        } else {
1806            self.metrics
1807                .execute_certificate_latency_single_writer
1808                .start_timer()
1809        };
1810        trace!("wait_for_certificate_execution");
1811
1812        self.metrics.total_cert_attempts.inc();
1813
1814        if !certificate.contains_shared_object() {
1815            // Shared object transactions need to be sequenced by the consensus before
1816            // enqueueing for execution, done in
1817            // AuthorityPerEpochStore::handle_consensus_transaction(). For owned
1818            // object transactions, they can be enqueued for execution immediately.
1819            self.execution_scheduler.enqueue(
1820                vec![(
1821                    Schedulable::Transaction(VerifiedExecutableTransaction::new_from_certificate(
1822                        certificate.clone(),
1823                    )),
1824                    ExecutionEnv::new(),
1825                )],
1826                epoch_store,
1827            );
1828        }
1829
1830        // tx could be reverted when epoch ends, so we must be careful not to return a
1831        // result here after the epoch ends.
1832        epoch_store
1833            .within_alive_epoch(self.notify_read_effects(
1834                "AuthorityState::wait_for_certificate_execution",
1835                certificate,
1836            ))
1837            .await
1838            .and_then(|r| r)
1839    }
1840
1841    /// Internal logic to execute a transaction.
1842    ///
1843    /// Guarantees that
1844    /// - If input objects are available, return no permanent failure.
1845    /// - Execution and output commit are atomic. i.e. outputs are only written to storage,
1846    /// on successful execution; crashed execution has no observable effect and
1847    /// can be retried.
1848    ///
1849    /// It is caller's responsibility to ensure input objects are available and
1850    /// locks are set. If this cannot be satisfied by the caller,
1851    /// `wait_for_certificate_execution()` should be called instead.
1852    ///
1853    /// Should only be called within iota-core.
1854    #[instrument(level = "trace", skip_all, fields(tx_digest = ?transaction.digest()))]
1855    pub fn try_execute_immediately(
1856        &self,
1857        transaction: &VerifiedExecutableTransaction,
1858        execution_env: ExecutionEnv,
1859        epoch_store: &Arc<AuthorityPerEpochStore>,
1860    ) -> IotaResult<(TransactionEffects, Option<ExecutionError>)> {
1861        let _scope = monitored_scope("Execution::try_execute_immediately");
1862        let _metrics_guard = self.metrics.internal_execution_latency.start_timer();
1863
1864        let tx_digest = transaction.digest();
1865
1866        // Acquire a lock to prevent concurrent executions of the same transaction.
1867        let tx_guard = epoch_store.acquire_tx_guard(transaction)?;
1868
1869        // The transaction could have been processed by a concurrent attempt of the
1870        // same transaction, so check if the effects have already been written.
1871        if let Some(effects) = self
1872            .get_transaction_cache_reader()
1873            .try_get_executed_effects(tx_digest)?
1874        {
1875            if let Some(expected_effects_digest_inner) = execution_env.expected_effects_digest {
1876                assert_eq!(
1877                    effects.digest(),
1878                    expected_effects_digest_inner,
1879                    "Unexpected effects digest for transaction {tx_digest}"
1880                );
1881            }
1882            tx_guard.release();
1883            return Ok((effects, None));
1884        }
1885
1886        let (tx_input_objects, per_authenticator_inputs) = self.read_objects_for_execution(
1887            tx_guard.as_lock_guard(),
1888            transaction,
1889            execution_env.assigned_versions,
1890            epoch_store,
1891        )?;
1892
1893        self.process_transaction(
1894            tx_guard,
1895            transaction,
1896            tx_input_objects,
1897            per_authenticator_inputs,
1898            execution_env.expected_effects_digest,
1899            &execution_env.attestation,
1900            epoch_store,
1901        )
1902        .tap_err(|e| info!(?tx_digest, "process_transaction failed: {e}"))
1903        .tap_ok(
1904            |(fx, _)| debug!(?tx_digest, fx_digest=?fx.digest(), "process_transaction succeeded"),
1905        )
1906    }
1907
1908    pub fn read_objects_for_execution(
1909        &self,
1910        tx_lock: &TxLockGuard,
1911        transaction: &VerifiedExecutableTransaction,
1912        assigned_shared_object_versions: AssignedVersions,
1913        epoch_store: &Arc<AuthorityPerEpochStore>,
1914    ) -> IotaResult<(InputObjects, Vec<(InputObjects, ObjectReadResult)>)> {
1915        let _scope = monitored_scope("Execution::load_input_objects");
1916        let _metrics_guard = self
1917            .metrics
1918            .execution_load_input_objects_latency
1919            .start_timer();
1920
1921        let input_objects = transaction.collect_all_input_object_kind_for_reading(
1922            epoch_store
1923                .protocol_config()
1924                .move_authenticator_type_arg_packages_as_inputs(),
1925        )?;
1926
1927        let input_objects = self.input_loader.read_objects_for_execution(
1928            &transaction.key(),
1929            tx_lock,
1930            &input_objects,
1931            &assigned_shared_object_versions,
1932            epoch_store.epoch(),
1933        )?;
1934
1935        transaction.split_input_objects_into_groups_for_reading(input_objects)
1936    }
1937
1938    /// Test only wrapper for `try_execute_immediately()` above, useful for
1939    /// checking errors if the pre-conditions are not satisfied, and
1940    /// executing change epoch transactions. With the P-COOL flow, a committee
1941    /// validator executes only transactions of commits its consensus handler
1942    /// assigned, so a transaction the handler has not assigned is assigned to
1943    /// a new commit first.
1944    pub fn try_execute_for_test(
1945        &self,
1946        certificate: &VerifiedCertificate,
1947        execution_env: ExecutionEnv,
1948    ) -> IotaResult<(VerifiedSignedTransactionEffects, Option<ExecutionError>)> {
1949        let epoch_store = self.epoch_store_for_testing();
1950        epoch_store.assign_to_a_new_commit_for_testing(&[certificate.key()]);
1951        let (effects, execution_error_opt) = self.try_execute_immediately(
1952            &VerifiedExecutableTransaction::new_from_certificate(certificate.clone()),
1953            execution_env,
1954            &epoch_store,
1955        )?;
1956        let signed_effects = self.sign_effects(effects, &epoch_store)?;
1957        Ok((signed_effects, execution_error_opt))
1958    }
1959
1960    /// Non-fallible version of `try_execute_for_test()`.
1961    pub fn execute_for_test(
1962        &self,
1963        certificate: &VerifiedCertificate,
1964        execution_env: ExecutionEnv,
1965    ) -> (VerifiedSignedTransactionEffects, Option<ExecutionError>) {
1966        self.try_execute_for_test(certificate, execution_env)
1967            .expect("try_execute_for_test should not fail")
1968    }
1969
1970    pub async fn notify_read_effects(
1971        &self,
1972        task_name: &'static str,
1973        certificate: &VerifiedCertificate,
1974    ) -> IotaResult<TransactionEffects> {
1975        self.get_transaction_cache_reader()
1976            .try_notify_read_executed_effects(task_name, &[*certificate.digest()])
1977            .await
1978            .map(|mut r| r.pop().expect("must return correct number of effects"))
1979    }
1980
1981    fn check_owned_locks(&self, owned_object_refs: &[ObjectReference]) -> IotaResult {
1982        self.get_object_cache_reader()
1983            .try_check_owned_objects_are_live(owned_object_refs)
1984    }
1985
1986    /// This function captures the required state to debug a forked transaction.
1987    /// The dump is written to a file in dir `path`, with name prefixed by the
1988    /// transaction digest. NOTE: Since this info escapes the validator
1989    /// context, make sure not to leak any private info here
1990    pub(crate) fn debug_dump_transaction_state(
1991        &self,
1992        tx_digest: &TransactionDigest,
1993        effects: &TransactionEffects,
1994        expected_effects_digest: TransactionEffectsDigest,
1995        inner_temporary_store: &InnerTemporaryStore,
1996        transaction: &VerifiedExecutableTransaction,
1997        debug_dump_config: &StateDebugDumpConfig,
1998    ) -> IotaResult<PathBuf> {
1999        // Fall back to the OS temp directory if no dump directory is configured.
2000        // This is safe: dump files are named by transaction digest, so no collisions.
2001        let dump_dir = debug_dump_config
2002            .dump_file_directory
2003            .as_ref()
2004            .cloned()
2005            .unwrap_or(std::env::temp_dir());
2006        let epoch_store = self.load_epoch_store_one_call_per_task();
2007
2008        NodeStateDump::new(
2009            tx_digest,
2010            effects,
2011            expected_effects_digest,
2012            self.get_object_store().as_ref(),
2013            &epoch_store,
2014            inner_temporary_store,
2015            transaction,
2016        )?
2017        .write_to_file(&dump_dir)
2018        .map_err(|e| IotaError::FileIO(e.to_string()))
2019    }
2020
2021    #[instrument(name = "process_certificate", level = "trace", skip_all, fields(tx_digest = ?transaction.digest(), sender = ?transaction.data().transaction().gas_owner().to_string()))]
2022    pub(crate) fn process_transaction(
2023        &self,
2024        tx_guard: TxGuard,
2025        transaction: &VerifiedExecutableTransaction,
2026        tx_input_objects: InputObjects,
2027        per_authenticator_inputs: Vec<(InputObjects, ObjectReadResult)>,
2028        expected_effects_digest: Option<TransactionEffectsDigest>,
2029        attestation: &AttestationSource,
2030        epoch_store: &Arc<AuthorityPerEpochStore>,
2031    ) -> IotaResult<(TransactionEffects, Option<ExecutionError>)> {
2032        let process_transaction_start_time = tokio::time::Instant::now();
2033        let digest = *transaction.digest();
2034
2035        let _scope = monitored_scope("Execution::process_certificate");
2036
2037        fail_point_if!("correlated-crash-process-transaction", || {
2038            if iota_simulator::random::deterministic_probability_once(digest, 0.01) {
2039                iota_simulator::task::kill_current_node(None);
2040            }
2041        });
2042
2043        let execution_guard = self.execution_lock_for_executable_transaction(transaction);
2044        // Any caller that verifies the signatures on the transaction will have already
2045        // checked the epoch. But paths that don't verify sigs (e.g. execution
2046        // from checkpoint, reading from db) present the possibility of an epoch
2047        // mismatch. If this transaction is not finalized in previous epoch, then it's
2048        // invalid.
2049        let execution_guard = match execution_guard {
2050            Ok(execution_guard) => execution_guard,
2051            Err(err) => {
2052                tx_guard.release();
2053                return Err(err);
2054            }
2055        };
2056        // Since we obtain a reference to the epoch store before taking the execution
2057        // lock, it's possible that reconfiguration has happened and they no
2058        // longer match.
2059        if *execution_guard != epoch_store.epoch() {
2060            tx_guard.release();
2061            info!("The epoch of the execution_guard doesn't match the epoch store");
2062            return Err(IotaError::WrongEpoch {
2063                expected_epoch: epoch_store.epoch(),
2064                actual_epoch: *execution_guard,
2065            });
2066        }
2067
2068        // Errors originating from `execute_transaction` may be transient (failure to
2069        // read locks) or non-transient (transaction input is invalid, move vm
2070        // errors). However, all errors from this function occur before we have
2071        // written anything to the db, so we commit the tx guard and rely on the
2072        // client to retry the tx (if it was transient).
2073        let (inner_temporary_store, effects, execution_error_opt, read_objects, attestation_record) =
2074            match self.execute_transaction(
2075                &execution_guard,
2076                transaction,
2077                tx_input_objects,
2078                per_authenticator_inputs,
2079                attestation,
2080                epoch_store,
2081            ) {
2082                Err(e) => {
2083                    info!(name = ?self.name, ?digest, "Error preparing transaction: {e}");
2084                    tx_guard.release();
2085                    return Err(e);
2086                }
2087                Ok(res) => res,
2088            };
2089
2090        if let Some(expected_effects_digest) = expected_effects_digest {
2091            if effects.digest() != expected_effects_digest {
2092                // We dont want to mask the original error, so we log it and continue.
2093                match self.debug_dump_transaction_state(
2094                    &digest,
2095                    &effects,
2096                    expected_effects_digest,
2097                    &inner_temporary_store,
2098                    transaction,
2099                    &self.config.state_debug_dump_config,
2100                ) {
2101                    Ok(out_path) => {
2102                        info!(
2103                            "Dumped node state for transaction {} to {}",
2104                            digest,
2105                            out_path.as_path().display().to_string()
2106                        );
2107                    }
2108                    Err(e) => {
2109                        error!("Error dumping state for transaction {}: {e}", digest);
2110                    }
2111                }
2112                error!(
2113                    tx_digest = ?digest,
2114                    ?expected_effects_digest,
2115                    actual_effects = ?effects,
2116                    "fork detected!"
2117                );
2118                panic!(
2119                    "Transaction {} is expected to have effects digest {}, but got {}!",
2120                    digest,
2121                    expected_effects_digest,
2122                    effects.digest(),
2123                );
2124            }
2125        }
2126
2127        fail_point!("crash");
2128
2129        self.commit_transaction(
2130            transaction,
2131            inner_temporary_store,
2132            &effects,
2133            read_objects,
2134            attestation_record,
2135            tx_guard,
2136            execution_guard,
2137            expected_effects_digest,
2138            epoch_store,
2139        )?;
2140
2141        let elapsed = process_transaction_start_time.elapsed().as_micros() as f64;
2142        if elapsed > 0.0 {
2143            self.metrics
2144                .execution_gas_latency_ratio
2145                .observe(effects.gas_cost_summary().computation_cost as f64 / elapsed);
2146        };
2147        Ok((effects, execution_error_opt))
2148    }
2149
2150    pub async fn reconfigure_traffic_control(
2151        &self,
2152        params: TrafficControlReconfigParams,
2153    ) -> Result<TrafficControlReconfigParams, IotaError> {
2154        if let Some(traffic_controller) = self.traffic_controller.as_ref() {
2155            traffic_controller.admin_reconfigure(params)
2156        } else {
2157            Err(IotaError::InvalidAdminRequest(
2158                "Traffic controller is not configured on this node".to_string(),
2159            ))
2160        }
2161    }
2162
2163    #[instrument(level = "trace", skip_all)]
2164    fn commit_transaction(
2165        &self,
2166        transaction: &VerifiedExecutableTransaction,
2167        inner_temporary_store: InnerTemporaryStore,
2168        effects: &TransactionEffects,
2169        read_objects: ObjectSet,
2170        attestation_record: Option<AttestationRecord>,
2171        tx_guard: TxGuard,
2172        _execution_guard: ExecutionLockReadGuard<'_>,
2173        expected_effects_digest: Option<TransactionEffectsDigest>,
2174        epoch_store: &Arc<AuthorityPerEpochStore>,
2175    ) -> IotaResult {
2176        let _scope: Option<iota_metrics::MonitoredScopeGuard> =
2177            monitored_scope("Execution::commit_certificate");
2178        let _metrics_guard = self.metrics.commit_certificate_latency.start_timer();
2179
2180        let tx_digest = transaction.digest();
2181        let input_object_count = inner_temporary_store.input_objects.len();
2182        let shared_object_count = effects.input_shared_objects().len();
2183
2184        let output_keys = inner_temporary_store.get_output_keys(effects);
2185
2186        // The insertion to epoch_store is not atomic with the insertion to the
2187        // perpetual store. This is OK because we insert to the epoch store
2188        // first. And during lookups we always look up in the perpetual store first.
2189        epoch_store.insert_executed_in_epoch(tx_digest);
2190
2191        let key = transaction.key();
2192        if !matches!(key, TransactionKey::Digest(_)) {
2193            epoch_store.insert_tx_key(key, *tx_digest)?;
2194        }
2195
2196        // Genesis and the change-epoch transaction are roots of no consensus
2197        // commit, so the handler never assigns them one and recording them
2198        // would stop the node. Without rows, the reader takes what they wrote
2199        // as epoch-start state: genesis writes the first epoch's, the
2200        // change-epoch transaction the next epoch's. The migration transactions
2201        // executed at epoch 0 are genesis transactions too: node startup first
2202        // re-executes each one through `execute_genesis_transaction`, which
2203        // asserts its kind, to collect the genesis objects.
2204        if epoch_store.pcool_bookkeeping_enabled()
2205            && !transaction.transaction().is_genesis_tx()
2206            && !transaction.transaction().is_end_of_epoch_tx()
2207        {
2208            epoch_store.record_executed_transaction(&key, effects);
2209        }
2210
2211        // Allow testing what happens if we crash here.
2212        fail_point!("crash");
2213
2214        let transaction_outputs = TransactionOutputs::build_transaction_outputs(
2215            transaction.clone().into_unsigned(),
2216            effects.clone(),
2217            inner_temporary_store,
2218            read_objects,
2219            &self.metrics,
2220            epoch_store.protocol_config().enable_validator_attestation(),
2221            attestation_record,
2222        );
2223        self.get_cache_writer()
2224            .try_write_transaction_outputs(epoch_store.epoch(), transaction_outputs.into())?;
2225
2226        self.report_failed_deny_rule_update_execution(
2227            transaction,
2228            effects,
2229            expected_effects_digest,
2230            epoch_store,
2231        );
2232
2233        if transaction.transaction().is_end_of_epoch_tx() {
2234            // At the end of epoch, since system packages may have been upgraded, force
2235            // reload them in the cache.
2236            self.get_object_cache_reader()
2237                .force_reload_system_packages(&BuiltInFramework::all_package_ids());
2238        }
2239
2240        // `commit_transaction()` finished, the tx is fully committed to the store.
2241        tx_guard.commit_tx();
2242
2243        match self.execution_scheduler.as_ref() {
2244            ExecutionSchedulerWrapper::ExecutionScheduler(_) => {}
2245            ExecutionSchedulerWrapper::TransactionManager(tm) => {
2246                // Notifies transaction manager about transaction and output objects committed.
2247                // This provides necessary information to transaction manager to start executing
2248                // additional ready transactions.
2249                tm.notify_commit(tx_digest, output_keys, epoch_store);
2250                // A transaction with a non-digest key can execute from a synced
2251                // checkpoint, in which case local randomness generation — the only
2252                // other caller of `notify_transaction_key` — never runs for that
2253                // round and would leave the env parked under its key forever. The
2254                // enqueue this triggers is filtered out as already executed.
2255                if let Some(key) = transaction.non_digest_key() {
2256                    tm.notify_transaction_key(epoch_store, key, *tx_digest);
2257                }
2258            }
2259        }
2260
2261        self.update_metrics(transaction, input_object_count, shared_object_count);
2262
2263        Ok(())
2264    }
2265
2266    fn update_metrics(
2267        &self,
2268        transaction: &VerifiedExecutableTransaction,
2269        input_object_count: usize,
2270        shared_object_count: usize,
2271    ) {
2272        // count signature by scheme, for multisig
2273        if transaction.has_multisig() {
2274            self.metrics.multisig_sig_count.inc();
2275        }
2276
2277        self.metrics.total_effects.inc();
2278        self.metrics.total_certs.inc();
2279
2280        if shared_object_count > 0 {
2281            self.metrics.shared_obj_tx.inc();
2282        }
2283
2284        if transaction.is_sponsored_tx() {
2285            self.metrics.sponsored_tx.inc();
2286        }
2287
2288        self.metrics
2289            .num_input_objs
2290            .observe(input_object_count as f64);
2291        self.metrics
2292            .num_shared_objects
2293            .observe(shared_object_count as f64);
2294        self.metrics
2295            .batch_size
2296            .observe(transaction.data().transaction().kind().num_commands() as f64);
2297    }
2298
2299    /// `execute_transaction()` validates the transaction input, and executes
2300    /// the transaction, returning effects, output objects, events, etc.
2301    ///
2302    /// It reads state from the db (both owned and shared locks), but it has no
2303    /// side effects.
2304    ///
2305    /// It can be generally understood that a failure of `execute_transaction`
2306    /// indicates a non-transient error, e.g. the transaction input is
2307    /// somehow invalid, the correct locks are not held, etc. However, this
2308    /// is not entirely true, as a transient db read error may also cause
2309    /// this function to fail.
2310    #[instrument(level = "trace", skip_all)]
2311    fn execute_transaction(
2312        &self,
2313        _execution_guard: &ExecutionLockReadGuard<'_>,
2314        transaction: &VerifiedExecutableTransaction,
2315        tx_input_objects: InputObjects,
2316        per_authenticator_inputs: Vec<(InputObjects, ObjectReadResult)>,
2317        attestation: &AttestationSource,
2318        epoch_store: &Arc<AuthorityPerEpochStore>,
2319    ) -> IotaResult<TransactionExecutionResult> {
2320        let _scope = monitored_scope("Execution::execute_certificate");
2321        let _metrics_guard = self.metrics.prepare_certificate_latency.start_timer();
2322        let prepare_transaction_start_time = tokio::time::Instant::now();
2323
2324        let protocol_config = epoch_store.protocol_config();
2325
2326        let reference_gas_price = epoch_store.reference_gas_price();
2327
2328        let epoch_id = epoch_store.epoch_start_config().epoch_data().epoch_id();
2329        let epoch_start_timestamp = epoch_store
2330            .epoch_start_config()
2331            .epoch_data()
2332            .epoch_start_timestamp();
2333
2334        let tracking_store = TrackingBackingStore::new(self.get_backing_store().as_ref());
2335        let backing_store = &tracking_store;
2336
2337        let tx_digest = *transaction.digest();
2338
2339        // TODO: We need to move this to a more appropriate place to avoid redundant
2340        // checks.
2341        let tx = transaction.data().transaction();
2342        tx.validity_check(protocol_config)?;
2343
2344        // The user signature of an attested transaction is verified pre-consensus
2345        // in the block verifier (`IotaTxValidator::validate_transactions`), exactly
2346        // as for an unattested one, and is not re-checked here.
2347
2348        let (kind, signer, gas_data) = tx.execution_parts();
2349
2350        let move_authenticators = transaction.move_authenticators();
2351
2352        #[cfg_attr(not(any(msim, fail_points)), expect(unused_mut))]
2353        let (inner_temp_store, mut effects, execution_error, outcome) = if move_authenticators
2354            .is_empty()
2355        {
2356            // No Move authentication required, proceed to execute the transaction directly.
2357
2358            // The cost of partially re-auditing a transaction before execution is
2359            // tolerated.
2360            let (tx_gas_status, tx_checked_input_objects) =
2361                iota_transaction_checks::check_certificate_input(
2362                    transaction,
2363                    tx_input_objects,
2364                    protocol_config,
2365                    reference_gas_price,
2366                )?;
2367
2368            let owned_object_refs = tx_checked_input_objects.inner().filter_owned_objects();
2369            self.check_owned_locks(&owned_object_refs)?;
2370            let (inner_temp_store, _gas_status, effects, _timings, execution_error_opt) =
2371                epoch_store.executor().execute_transaction_to_effects(
2372                    backing_store,
2373                    protocol_config,
2374                    self.metrics.limits_metrics.clone(),
2375                    // TODO: would be nice to pass the whole NodeConfig here, but it creates a
2376                    // cyclic dependency w/ iota-adapter
2377                    self.config
2378                        .expensive_safety_check_config
2379                        .enable_deep_per_tx_iota_conservation_check(),
2380                    self.config.certificate_deny_config.certificate_deny_set(),
2381                    &epoch_id,
2382                    epoch_start_timestamp,
2383                    tx_checked_input_objects,
2384                    gas_data,
2385                    tx_gas_status,
2386                    kind,
2387                    signer,
2388                    tx_digest,
2389                    &mut None,
2390                );
2391            // Without Move authentication there is nothing to judge.
2392            let outcome = attestation_verdict::ExecutionOutcome {
2393                blame: None,
2394                consumed_units: 0,
2395                body_ran: attestation_verdict::body_ran(false, execution_error_opt.as_ref().err()),
2396            };
2397            (inner_temp_store, effects, execution_error_opt, outcome)
2398        } else {
2399            // One or more `MoveAuthenticator` signatures present — authenticate each and
2400            // then execute the transaction.
2401            // It is supposed that `MoveAuthenticator` availability is checked in
2402            // `SenderSignedTransaction::validity_check`.
2403
2404            debug_assert_eq!(
2405                move_authenticators.len(),
2406                per_authenticator_inputs.len(),
2407                "Move authenticators amount must match the number of authenticator inputs"
2408            );
2409
2410            // The first account that cannot be resolved fails the transaction. The
2411            // remaining inputs are still collected, since the failure effects need
2412            // them whether or not anyone is charged gas.
2413            let mut per_authenticator_input_objects = Vec::with_capacity(move_authenticators.len());
2414            let mut resolutions = Vec::with_capacity(move_authenticators.len());
2415            for (move_authenticator, (authenticator_input_objects, account_object)) in
2416                move_authenticators.iter().zip(per_authenticator_inputs)
2417            {
2418                // The shape of the object to authenticate is decided by the
2419                // transaction bytes, and `validity_check` settles it in the
2420                // consensus handler, so it cannot be wrong here.
2421                let (account_object_id, account_object_version, account_object_digest) =
2422                    move_authenticator
2423                        .object_to_authenticate_components()
2424                        .expect(
2425                            "the object to authenticate is validated before consensus and cannot \
2426                                be invalid during execution",
2427                        );
2428
2429                // Unlike the shape above, resolving the account depends on state,
2430                // so post-consensus validation cannot keep this check. Here, an
2431                // account that fails it produces failure effects instead of a
2432                // panic.
2433                resolutions.push(self.check_move_account_for_execution(
2434                    account_object_id,
2435                    account_object_version,
2436                    account_object_digest,
2437                    account_object,
2438                    &move_authenticator.address(),
2439                    protocol_config,
2440                ));
2441
2442                per_authenticator_input_objects.push(authenticator_input_objects);
2443            }
2444
2445            // Serialize the Transaction for the auth context.
2446            let tx_bytes = bcs::to_bytes(tx).expect("Transaction serialization cannot fail");
2447
2448            let (sender_auth_digest, sponsor_auth_digest) =
2449                transaction.data().compute_auth_digests()?;
2450
2451            // Check the `MoveAuthenticator` input objects. These are needed to build the
2452            // effect whether or not authentication ultimately runs.
2453            // The `MoveAuthenticator` receiving objects are checked on the signing step.
2454            // `max_auth_gas` is used here as a Move authenticator gas budget until it is
2455            // not a part of the transaction data.
2456            let authenticator_gas_budget = protocol_config.max_auth_gas();
2457            let (
2458                gas_status,
2459                per_authenticator_checked_input_objects,
2460                authenticator_and_tx_checked_input_objects,
2461            ) = iota_transaction_checks::check_certificate_and_move_authenticator_input(
2462                tx,
2463                tx_input_objects,
2464                per_authenticator_input_objects,
2465                None,
2466                authenticator_gas_budget,
2467                protocol_config,
2468                reference_gas_price,
2469            )?;
2470
2471            let owned_object_refs = authenticator_and_tx_checked_input_objects
2472                .inner()
2473                .filter_owned_objects();
2474            self.check_owned_locks(&owned_object_refs)?;
2475
2476            // Only attested transactions can have their Move-authentication
2477            // failure attributed, and only they carry recorded versions to judge.
2478            let attestation_verdict_context = match attestation {
2479                AttestationSource::Attestation(attestation) => {
2480                    Some(attestation_verdict::AttestationVerdictContext {
2481                        attestation,
2482                        attested_versions: attestation_verdict::AttestedObjectVersions {
2483                            object_cache: self.get_object_cache_reader().as_ref(),
2484                            current_epoch: epoch_id,
2485                        },
2486                        store: backing_store,
2487                        executor: epoch_store.executor().as_ref(),
2488                        protocol_config,
2489                        metrics: self.metrics.limits_metrics.clone(),
2490                        epoch_id,
2491                        epoch_timestamp_ms: epoch_start_timestamp,
2492                        reference_gas_price,
2493                        gas_data: gas_data.clone(),
2494                        authenticators: attestation_verdict::authenticator_inputs(
2495                            &move_authenticators,
2496                            &per_authenticator_checked_input_objects,
2497                        ),
2498                        executed_versions: attestation_verdict::executed_versions(
2499                            &per_authenticator_checked_input_objects,
2500                            &resolutions,
2501                        ),
2502                        transaction: tx,
2503                        transaction_signer: signer,
2504                        transaction_digest: tx_digest,
2505                        sender_auth_digest,
2506                        sponsor_auth_digest,
2507                    })
2508                }
2509                AttestationSource::Unattested | AttestationSource::Certified(_) => None,
2510            };
2511
2512            // The function refs of the accounts that resolved, so an
2513            // authenticator that runs after another account failed to resolve
2514            // still finds its own.
2515            let (sender_authenticator_function_ref, sponsor_authenticator_function_ref) =
2516                extract_auth_fun_refs(signer, gas_data.owner, |address| {
2517                    move_authenticators
2518                        .iter()
2519                        .zip(&resolutions)
2520                        .find(|(move_authenticator, _)| move_authenticator.address() == address)
2521                        .and_then(|(_, resolution)| resolution.as_ref().ok())
2522                        .map(|function_ref| function_ref.authenticator_function_ref.clone())
2523                });
2524
2525            let accounts = move_authenticators
2526                .iter()
2527                .map(|move_authenticator| move_authenticator.address())
2528                .collect::<Vec<_>>();
2529            debug_assert_eq!(
2530                move_authenticators.len(),
2531                per_authenticator_checked_input_objects.len(),
2532                "Move authenticators amount must match the number of checked authenticator inputs"
2533            );
2534            // Under the P-COOL flow, a gas owner that cannot be resolved did
2535            // not authorize the transaction, so `gas_owner_pays` decides who
2536            // pays; its own failure is then the one reported.
2537            let pcool_flow = protocol_config.enable_pcool_flow();
2538            let mut first_resolution_error = None;
2539            let mut gas_owner_resolution_error = None;
2540            let mut resolved_authenticators = Vec::with_capacity(move_authenticators.len());
2541            for ((move_authenticator, resolution), authenticator_checked_input_objects) in
2542                move_authenticators
2543                    .into_iter()
2544                    .zip(resolutions)
2545                    .zip(per_authenticator_checked_input_objects)
2546            {
2547                match resolution {
2548                    Ok(function_ref) => {
2549                        resolved_authenticators.push(MoveAuthenticatorForExecution {
2550                            authenticator: move_authenticator.to_owned(),
2551                            function_ref,
2552                            input_objects: authenticator_checked_input_objects,
2553                        })
2554                    }
2555                    Err(error) if pcool_flow && move_authenticator.address() == gas_data.owner => {
2556                        gas_owner_resolution_error = Some(error);
2557                    }
2558                    Err(error) => {
2559                        first_resolution_error.get_or_insert(error);
2560                    }
2561                }
2562            }
2563
2564            let auth_context_data = AuthContextData {
2565                transaction_data_bytes: tx_bytes,
2566                sender_auth_digest,
2567                sponsor_auth_digest,
2568                sender_authenticator_function_ref,
2569                sponsor_authenticator_function_ref,
2570            };
2571
2572            // With a resolution failure, the executor gets the failure in place
2573            // of the list, with the accounts the authenticators would have
2574            // authenticated and, under the P-COOL flow, the gas owner's
2575            // authenticator if its account resolved, so it can decide who pays.
2576            let authenticators = match gas_owner_resolution_error.or(first_resolution_error) {
2577                Some(error) => MoveAuthenticatorsForExecution::ResolutionFailed {
2578                    error,
2579                    accounts,
2580                    gas_owner: if pcool_flow {
2581                        resolved_authenticators
2582                            .into_iter()
2583                            .find(|resolved| resolved.authenticator.address() == gas_data.owner)
2584                            .map(Box::new)
2585                    } else {
2586                        None
2587                    },
2588                },
2589                None => MoveAuthenticatorsForExecution::Resolved(resolved_authenticators),
2590            };
2591
2592            // Whether the gas owner pays when its own authentication fails: the
2593            // judge answers for an attested transaction, the certified record
2594            // when executing from a checkpoint, and nobody pays otherwise. The
2595            // judge's answer is kept for the record.
2596            let blame = Cell::new(None);
2597            let gas_owner_pays = |kind: &ExecutionErrorKind| {
2598                match (attestation, &attestation_verdict_context) {
2599                    (AttestationSource::Attestation(_), Some(context)) => {
2600                        let answer = context.decide_authentication_failure_blame(kind);
2601                        blame.set(Some(answer));
2602
2603                        answer == attestation_verdict::AuthenticationFailureBlame::Account
2604                    }
2605                    (AttestationSource::Certified(record), _)
2606                        if protocol_config.enable_validator_attestation() =>
2607                    {
2608                        // Only the records other than `Valid` are certified, and
2609                        // consensus requires an attestation on every user
2610                        // transaction while the flag is on, so no record means
2611                        // the attestation was valid. The gas owner pays unless
2612                        // the judge blamed the attestor or could not decide.
2613                        !matches!(
2614                            record,
2615                            Some(AttestationRecord {
2616                                verdict: AttestationVerdict::Refuted { .. }
2617                                    | AttestationVerdict::Undecided,
2618                                ..
2619                            })
2620                        )
2621                    }
2622                    _ => false,
2623                }
2624            };
2625
2626            let (
2627                inner_temp_store,
2628                gas_status,
2629                effects,
2630                _timings,
2631                execution_error_opt,
2632                authentication_error,
2633            ) = epoch_store
2634                .executor()
2635                .authenticate_then_execute_transaction_to_effects(
2636                    backing_store,
2637                    protocol_config,
2638                    self.metrics.limits_metrics.clone(),
2639                    self.config
2640                        .expensive_safety_check_config
2641                        .enable_deep_per_tx_iota_conservation_check(),
2642                    self.config.certificate_deny_config.certificate_deny_set(),
2643                    &epoch_id,
2644                    epoch_start_timestamp,
2645                    gas_data,
2646                    gas_status,
2647                    authenticators,
2648                    authenticator_and_tx_checked_input_objects,
2649                    Some(&gas_owner_pays),
2650                    kind,
2651                    signer,
2652                    tx_digest,
2653                    auth_context_data,
2654                    &mut None,
2655                );
2656            // Only an attested transaction whose authentication failed is
2657            // judged, on the authentication error itself: the body's own
2658            // checks may have replaced it in the effects. The engine asks the
2659            // judge only when a gas owner that is a Move account did not
2660            // authorize the transaction, and never about a cancellation or an
2661            // invariant violation; any other failure is judged here, for the
2662            // record.
2663            let blame = blame.get().or_else(|| {
2664                match (&attestation_verdict_context, &authentication_error) {
2665                    (Some(context), Some(kind)) => {
2666                        Some(context.decide_authentication_failure_blame(kind))
2667                    }
2668                    _ => None,
2669                }
2670            });
2671            let outcome = attestation_verdict::ExecutionOutcome {
2672                blame,
2673                consumed_units: attestation_verdict::consumed_units(gas_status),
2674                body_ran: attestation_verdict::body_ran(
2675                    authentication_error.is_some(),
2676                    execution_error_opt.as_ref().err(),
2677                ),
2678            };
2679
2680            (inner_temp_store, effects, execution_error_opt, outcome)
2681        };
2682
2683        // Judged before the fork-injecting fail point below, so that only the
2684        // effects diverge under it.
2685        let attestation_record = attestation_record(
2686            attestation,
2687            &outcome,
2688            &effects,
2689            tx.gas_price(),
2690            protocol_config,
2691        );
2692
2693        fail_point_if!("cp_execution_nondeterminism", || {
2694            #[cfg(msim)]
2695            self.create_fail_state(transaction, epoch_store, &mut effects);
2696        });
2697
2698        let elapsed = prepare_transaction_start_time.elapsed().as_micros() as f64;
2699        if elapsed > 0.0 {
2700            self.metrics
2701                .prepare_cert_gas_latency_ratio
2702                .observe(effects.gas_cost_summary().computation_cost as f64 / elapsed);
2703        }
2704
2705        let read_objects = tracking_store.into_read_objects();
2706
2707        Ok((
2708            inner_temp_store,
2709            effects,
2710            execution_error.err(),
2711            read_objects,
2712            attestation_record,
2713        ))
2714    }
2715
2716    pub fn prepare_transaction_for_benchmark(
2717        &self,
2718        transaction: &VerifiedExecutableTransaction,
2719        input_objects: InputObjects,
2720        epoch_store: &Arc<AuthorityPerEpochStore>,
2721    ) -> IotaResult<(
2722        InnerTemporaryStore,
2723        TransactionEffects,
2724        Option<ExecutionError>,
2725    )> {
2726        let lock = RwLock::new(epoch_store.epoch());
2727        let execution_guard = lock.try_read().unwrap();
2728
2729        self.execute_transaction(
2730            &execution_guard,
2731            transaction,
2732            input_objects,
2733            vec![],
2734            &AttestationSource::Unattested,
2735            epoch_store,
2736        )
2737        .map(|(inner_temp_store, effects, execution_error, _, _)| {
2738            (inner_temp_store, effects, execution_error)
2739        })
2740    }
2741
2742    /// Simulate a transaction without committing it.
2743    ///
2744    /// `checks` selects the Move VM semantics: `VmChecks::Enabled` runs the
2745    /// transaction as it would run on chain (a dry run), while
2746    /// `VmChecks::Disabled` relaxes the checks around entry functions and
2747    /// argument values (a dev inspect). Both report the per-command return
2748    /// values in [`SimulateTransactionResult::execution_result`].
2749    ///
2750    /// Under either `checks`, the simulation fills in whatever gas the
2751    /// transaction leaves unset, so that a caller with no gas to declare can
2752    /// leave all of it out: no gas payment mints a mock gas coin, whose ID is
2753    /// reported back in [`SimulateTransactionResult::mock_gas_id`]; a zero gas
2754    /// price becomes the epoch's reference gas price; and a zero gas budget
2755    /// becomes as much as the gas coins can back, up to
2756    /// [`max_tx_gas`](iota_protocol_config::ProtocolConfig::max_tx_gas).
2757    /// Anything the transaction does declare is metered as given, so a dry run
2758    /// still rejects the gas a validator would.
2759    ///
2760    /// Under either `checks`, the packages the transaction publishes are run
2761    /// through the bytecode verifier with this node's signing-time limits, so a
2762    /// package that signing would reject with
2763    /// [`UserInputError::PackageVerificationTimedout`] is rejected here too.
2764    ///
2765    /// Whatever the budget resolves to, the gas coins have to cover it, since
2766    /// execution reserves the whole budget from them before running any command
2767    /// and refunds it afterwards. A caller leaving the budget at zero to have
2768    /// the cost estimated therefore gets an estimate whatever its coins hold,
2769    /// but the reserved budget is off limits for the duration of the
2770    /// programmable transaction: a transaction that also pays out of its gas
2771    /// coin has to declare a budget leaving room for that, exactly as it would
2772    /// on chain. A balance too small to declare the minimum budget at all is
2773    /// rejected with [`UserInputError::GasBalanceTooLow`].
2774    pub fn simulate_transaction(
2775        &self,
2776        transaction: Transaction,
2777        checks: VmChecks,
2778    ) -> IotaResult<SimulateTransactionResult> {
2779        let epoch_store = self.load_epoch_store_one_call_per_task();
2780        self.simulate_transaction_in_epoch(&epoch_store, transaction, checks)
2781    }
2782
2783    /// Same as [`AuthorityState::simulate_transaction`], for callers that
2784    /// already hold an epoch store.
2785    ///
2786    /// Callers that derive gas parameters from an epoch, or resolve types
2787    /// against its executor once the simulation returns, should pass that same
2788    /// epoch store here so the whole operation observes one epoch.
2789    ///
2790    /// Nothing here checks that `epoch_store` is the current one — pinning a
2791    /// superseded epoch is the point, and is what
2792    /// [`AuthorityState::simulate_transaction`] does for the span of its own
2793    /// call. Keeping one across an unbounded period is the caller's problem:
2794    /// the simulation would run against that epoch's protocol config,
2795    /// executor, and reference gas price.
2796    #[instrument("simulate_tx", level = "trace", skip_all)]
2797    pub fn simulate_transaction_in_epoch(
2798        &self,
2799        epoch_store: &AuthorityPerEpochStore,
2800        transaction: Transaction,
2801        checks: VmChecks,
2802    ) -> IotaResult<SimulateTransactionResult> {
2803        if !self.is_fullnode(epoch_store) {
2804            return Err(IotaError::UnsupportedFeature {
2805                error: "simulate is only supported on fullnodes".to_string(),
2806            });
2807        }
2808
2809        self.simulate_transaction_inner(epoch_store, transaction, checks)
2810    }
2811
2812    /// Same as [`AuthorityState::simulate_transaction`], but runs on a
2813    /// validator too. Only the single-node benchmark, which has no fullnode
2814    /// to run against, needs this.
2815    pub fn simulate_transaction_for_benchmark(
2816        &self,
2817        transaction: Transaction,
2818        checks: VmChecks,
2819    ) -> IotaResult<SimulateTransactionResult> {
2820        let epoch_store = self.load_epoch_store_one_call_per_task();
2821        self.simulate_transaction_inner(&epoch_store, transaction, checks)
2822    }
2823
2824    #[instrument(level = "trace", skip_all)]
2825    fn simulate_transaction_inner(
2826        &self,
2827        epoch_store: &AuthorityPerEpochStore,
2828        mut transaction: Transaction,
2829        checks: VmChecks,
2830    ) -> IotaResult<SimulateTransactionResult> {
2831        if transaction.kind().is_system() {
2832            return Err(IotaError::UnsupportedFeature {
2833                error: "simulate does not support system transactions".to_string(),
2834            });
2835        }
2836
2837        transaction.check_serialized_size(epoch_store.protocol_config())?;
2838
2839        // Cheap validity checks for a transaction, including input size limits.
2840        // This does not check if gas objects are missing since we may create a
2841        // mock gas object. It checks for other transaction input validity.
2842        transaction.validity_check_no_gas_check(epoch_store.protocol_config())?;
2843
2844        // The full validity check caps the gas payment size alongside requiring a
2845        // gas payment at all, which a simulation relaxes so it can mock one. The cap
2846        // still applies, and is cheapest before any object is loaded.
2847        transaction.check_gas_payment_size(epoch_store.protocol_config())?;
2848
2849        let input_object_kinds = transaction.input_objects()?;
2850        let receiving_object_refs = transaction.receiving_objects();
2851
2852        // Since we need to simulate a validator signing the transaction, the first step
2853        // is to check if some transaction elements are denied.
2854        iota_transaction_checks::deny::check_transaction_for_validation(
2855            &transaction,
2856            &[],
2857            &input_object_kinds,
2858            &receiving_object_refs,
2859            &self.config.transaction_deny_config,
2860            self.get_backing_package_store().as_ref(),
2861        )?;
2862
2863        // Load input and receiving objects
2864        let (mut input_objects, receiving_objects) = self.input_loader.read_objects_for_signing(
2865            // We don't want to cache this transaction since it's a simulation.
2866            None,
2867            &input_object_kinds,
2868            &receiving_object_refs,
2869            epoch_store.epoch(),
2870        )?;
2871
2872        // Create a mock gas object if one was not provided
2873        let mock_gas_id = if transaction.gas().is_empty() {
2874            let mock_gas_object = mock_simulation_gas_coin(transaction.gas_data().owner);
2875            let mock_gas_object_ref = mock_gas_object.object_ref();
2876            transaction.gas_data_mut().objects = vec![mock_gas_object_ref];
2877            input_objects.push(ObjectReadResult::new_from_gas_object(&mock_gas_object));
2878            Some(mock_gas_object.id())
2879        } else {
2880            None
2881        };
2882
2883        let protocol_config = epoch_store.protocol_config();
2884
2885        iota_types::gas::fill_in_unset_simulation_gas(
2886            &mut transaction,
2887            &input_objects,
2888            epoch_store.reference_gas_price(),
2889            protocol_config,
2890        );
2891
2892        // `MoveAuthenticator`s are not supported in simulation, so we set the
2893        // `authenticator_gas_budget` to 0.
2894        let authenticator_gas_budget = 0;
2895
2896        // Checks enabled -> DRY-RUN, it means we are simulating a real TX
2897        // Checks disabled -> DEV-INSPECT, more relaxed Move VM checks
2898        let (gas_status, checked_input_objects) = if checks.enabled() {
2899            iota_transaction_checks::check_transaction_input(
2900                protocol_config,
2901                epoch_store.reference_gas_price(),
2902                &transaction,
2903                input_objects,
2904                &receiving_objects,
2905                &self.metrics.bytecode_verifier_metrics,
2906                VerifierLimitsSource::NodeConfig(&self.config.verifier_signing_config),
2907                authenticator_gas_budget,
2908                false,
2909            )?
2910        } else {
2911            // Execution smashes the gas coins and reserves the whole budget from them
2912            // before running any command, treating the input checks as having verified
2913            // that they are gas coins at all — so with those checks skipped here, this
2914            // has to stand in for them. With the checks enabled,
2915            // `check_transaction_input` covers it.
2916            iota_types::gas::check_gas_coins_cover_budget_in_simulation(
2917                &input_objects,
2918                transaction.gas(),
2919                transaction.gas_budget(),
2920            )?;
2921
2922            let checked_input_objects = iota_transaction_checks::check_simulation_input(
2923                protocol_config,
2924                transaction.kind(),
2925                input_objects,
2926                receiving_objects,
2927            )?;
2928
2929            // Execution verifies the packages a transaction publishes with neither a
2930            // limit nor a meter, trusting signing to have bounded them — so with the
2931            // signing-time checks skipped here, this has to bound them. The node's
2932            // own limits reject nothing that signing would accept. With the checks
2933            // enabled, `check_transaction_input` covers it.
2934            iota_transaction_checks::check_non_system_packages_to_be_published(
2935                &transaction,
2936                protocol_config,
2937                &self.metrics.bytecode_verifier_metrics,
2938                VerifierLimitsSource::NodeConfig(&self.config.verifier_signing_config),
2939            )?;
2940
2941            let gas_status = IotaGasStatus::new(
2942                transaction.gas_budget(),
2943                transaction.gas_price(),
2944                epoch_store.reference_gas_price(),
2945                protocol_config,
2946            )?;
2947
2948            (gas_status, checked_input_objects)
2949        };
2950
2951        // Create a new executor for the simulation
2952        let executor = iota_execution::executor(
2953            protocol_config,
2954            true, // silent
2955            None,
2956        )
2957        .expect("Creating an executor should not fail here");
2958
2959        // Execute the simulation
2960        let (kind, signer, gas_data) = transaction.execution_parts();
2961        let (inner_temp_store, _, effects, execution_result) = executor.dev_inspect_transaction(
2962            self.get_backing_store().as_ref(),
2963            protocol_config,
2964            self.metrics.limits_metrics.clone(),
2965            false, // expensive_checks
2966            self.config.certificate_deny_config.certificate_deny_set(),
2967            &epoch_store.epoch_start_config().epoch_data().epoch_id(),
2968            epoch_store
2969                .epoch_start_config()
2970                .epoch_data()
2971                .epoch_start_timestamp(),
2972            checked_input_objects,
2973            gas_data,
2974            gas_status,
2975            kind,
2976            signer,
2977            transaction.digest(),
2978            checks.disabled(),
2979        );
2980
2981        let mut input_objects = inner_temp_store.input_objects;
2982        iota_types::storage::extend_input_objects_with_loaded_runtime_objects(
2983            &mut input_objects,
2984            &effects,
2985            &inner_temp_store.loaded_runtime_objects,
2986            self.get_backing_store().as_object_store(),
2987        );
2988
2989        Ok(SimulateTransactionResult {
2990            input_objects,
2991            output_objects: inner_temp_store.written,
2992            events: effects.events_digest().map(|_| inner_temp_store.events),
2993            effects,
2994            execution_result,
2995            suggested_gas_price: self
2996                .congestion_tracker
2997                .get_prediction_suggested_gas_price(&transaction),
2998            mock_gas_id,
2999            gas_data: transaction.gas_data().clone(),
3000        })
3001    }
3002
3003    // Only used for testing because of how epoch store is loaded.
3004    pub fn reference_gas_price_for_testing(&self) -> Result<u64, anyhow::Error> {
3005        let epoch_store = self.epoch_store_for_testing();
3006        Ok(epoch_store.reference_gas_price())
3007    }
3008
3009    #[instrument(level = "trace", skip_all)]
3010    pub fn try_is_tx_already_executed(&self, digest: &TransactionDigest) -> IotaResult<bool> {
3011        self.get_transaction_cache_reader()
3012            .try_is_tx_already_executed(digest)
3013    }
3014
3015    /// Non-fallible version of `try_is_tx_already_executed`.
3016    pub fn is_tx_already_executed(&self, digest: &TransactionDigest) -> bool {
3017        self.try_is_tx_already_executed(digest)
3018            .expect("storage access failed")
3019    }
3020
3021    #[cfg(msim)]
3022    fn create_fail_state(
3023        &self,
3024        transaction: &VerifiedExecutableTransaction,
3025        epoch_store: &Arc<AuthorityPerEpochStore>,
3026        effects: &mut TransactionEffects,
3027    ) {
3028        use std::cell::RefCell;
3029
3030        use iota_types::effects::TransactionEffectsAPIForTesting;
3031        thread_local! {
3032            static FAIL_STATE: RefCell<(u64, HashSet<AuthorityName>)> = RefCell::new((0, HashSet::new()));
3033        }
3034        if !transaction.data().transaction().is_system_tx() {
3035            let committee = epoch_store.committee();
3036            let cur_stake = (**committee).weight(&self.name);
3037            if cur_stake > 0 {
3038                FAIL_STATE.with_borrow_mut(|fail_state| {
3039                    // let (&mut failing_stake, &mut failing_validators) = fail_state;
3040                    if fail_state.0 < committee.validity_threshold() {
3041                        fail_state.0 += cur_stake;
3042                        fail_state.1.insert(self.name);
3043                    }
3044
3045                    if fail_state.1.contains(&self.name) {
3046                        info!("cp_exec failing tx");
3047                        effects.gas_cost_summary_mut_for_testing().computation_cost += 1;
3048                    }
3049                });
3050            }
3051        }
3052    }
3053
3054    pub fn unixtime_now_ms() -> u64 {
3055        let now = SystemTime::now()
3056            .duration_since(UNIX_EPOCH)
3057            .expect("Time went backwards")
3058            .as_millis();
3059        u64::try_from(now).expect("Travelling in time machine")
3060    }
3061
3062    #[instrument(level = "trace", skip_all)]
3063    pub async fn handle_transaction_info_request(
3064        &self,
3065        request: TransactionInfoRequest,
3066    ) -> IotaResult<TransactionInfoResponse> {
3067        let epoch_store = self.load_epoch_store_one_call_per_task();
3068        let (transaction, status) = self
3069            .get_transaction_status(&request.transaction_digest, &epoch_store)?
3070            .ok_or(IotaError::TransactionNotFound {
3071                digest: request.transaction_digest,
3072            })?;
3073        Ok(TransactionInfoResponse {
3074            transaction,
3075            status,
3076        })
3077    }
3078
3079    #[instrument(level = "trace", skip_all)]
3080    pub async fn handle_object_info_request(
3081        &self,
3082        request: ObjectInfoRequest,
3083    ) -> IotaResult<ObjectInfoResponse> {
3084        let epoch_store = self.load_epoch_store_one_call_per_task();
3085
3086        let requested_object_seq = match request.request_kind {
3087            ObjectInfoRequestKind::LatestObjectInfo => {
3088                self.try_get_object_or_tombstone(request.object_id)?
3089                    .ok_or_else(|| {
3090                        IotaError::from(UserInputError::ObjectNotFound {
3091                            object_id: request.object_id,
3092                            version: None,
3093                        })
3094                    })?
3095                    .version
3096            }
3097            ObjectInfoRequestKind::PastObjectInfoDebug(seq) => seq,
3098        };
3099
3100        // A `PastObjectInfoDebug` request names an older version, which may
3101        // have been moved out of the live table.
3102        let object = self
3103            .get_object_with_historic_fallback(&ObjectKey(request.object_id, requested_object_seq))?
3104            .ok_or_else(|| {
3105                IotaError::from(UserInputError::ObjectNotFound {
3106                    object_id: request.object_id,
3107                    version: Some(requested_object_seq),
3108                })
3109            })?;
3110
3111        let layout = if let (LayoutGenerationOption::Generate, Some(move_obj)) =
3112            (request.generate_layout, object.data.as_opt_struct())
3113        {
3114            Some(into_struct_layout(
3115                epoch_store
3116                    .executor()
3117                    .type_layout_resolver(Box::new(self.get_backing_package_store().as_ref()))
3118                    .get_annotated_layout(move_obj.struct_tag())?,
3119            )?)
3120        } else {
3121            None
3122        };
3123
3124        let lock = if !object.is_address_owned() {
3125            // Only address owned objects have locks.
3126            None
3127        } else {
3128            self.get_transaction_lock(&object.object_ref(), &epoch_store)?
3129                .map(|s| s.into_inner())
3130        };
3131
3132        Ok(ObjectInfoResponse {
3133            object,
3134            layout,
3135            lock_for_debugging: lock,
3136        })
3137    }
3138
3139    #[instrument(level = "trace", skip_all)]
3140    pub fn handle_checkpoint_request(
3141        &self,
3142        request: &CheckpointRequest,
3143    ) -> IotaResult<CheckpointResponse> {
3144        let summary = if request.certified {
3145            let summary = match request.sequence_number {
3146                Some(seq) => self
3147                    .checkpoint_store
3148                    .get_checkpoint_by_sequence_number(seq)?,
3149                None => self.checkpoint_store.get_latest_certified_checkpoint()?,
3150            }
3151            .map(|v| v.into_inner());
3152            summary.map(CheckpointSummaryResponse::Certified)
3153        } else {
3154            let summary = match request.sequence_number {
3155                Some(seq) => self.checkpoint_store.get_locally_computed_checkpoint(seq)?,
3156                None => self
3157                    .checkpoint_store
3158                    .get_latest_locally_computed_checkpoint()?,
3159            };
3160            summary.map(CheckpointSummaryResponse::Pending)
3161        };
3162        let contents = match &summary {
3163            Some(s) => self
3164                .checkpoint_store
3165                .get_checkpoint_contents(&s.contents_digest())?,
3166            None => None,
3167        };
3168        Ok(CheckpointResponse {
3169            checkpoint: summary,
3170            contents,
3171        })
3172    }
3173
3174    fn check_protocol_version(
3175        supported_protocol_versions: SupportedProtocolVersions,
3176        current_version: ProtocolVersion,
3177    ) {
3178        info!("current protocol version is now {:?}", current_version);
3179        info!("supported versions are: {:?}", supported_protocol_versions);
3180        if !supported_protocol_versions.is_version_supported(current_version) {
3181            let msg = format!(
3182                "Unsupported protocol version. The network is at {current_version:?}, but this IotaNode only supports: {supported_protocol_versions:?}. Shutting down.",
3183            );
3184
3185            error!("{}", msg);
3186            eprintln!("{msg}");
3187
3188            #[cfg(not(msim))]
3189            std::process::exit(1);
3190
3191            #[cfg(msim)]
3192            iota_simulator::task::shutdown_current_node();
3193        }
3194    }
3195
3196    #[expect(clippy::disallowed_methods)] // allow unbounded_channel()
3197    pub async fn new(
3198        name: AuthorityName,
3199        secret: StableSyncAuthoritySigner,
3200        supported_protocol_versions: SupportedProtocolVersions,
3201        store: Arc<AuthorityStore>,
3202        execution_cache_trait_pointers: ExecutionCacheTraitPointers,
3203        epoch_store: Arc<AuthorityPerEpochStore>,
3204        committee_store: Arc<CommitteeStore>,
3205        rpc_indexes_store: Option<Arc<RpcIndexesStore>>,
3206        checkpoint_store: Arc<CheckpointStore>,
3207        prometheus_registry: &Registry,
3208        config: NodeConfig,
3209        validator_tx_finalizer: Option<Arc<ValidatorTxFinalizer<NetworkAuthorityClient>>>,
3210        chain_identifier: ChainIdentifier,
3211        policy_config: Option<PolicyConfig>,
3212        epoch_end_db_snapshots: Option<EpochEndDbSnapshotHandle>,
3213    ) -> Arc<Self> {
3214        Self::check_protocol_version(supported_protocol_versions, epoch_store.protocol_version());
3215
3216        // Read by the quarantine flush and the execution watcher; the next
3217        // epoch's store inherits it.
3218        epoch_store.set_effects_store(
3219            execution_cache_trait_pointers
3220                .transaction_cache_reader
3221                .clone(),
3222        );
3223
3224        let metrics = Arc::new(AuthorityMetrics::new(prometheus_registry));
3225        let (tx_ready_transactions, rx_ready_transactions) = unbounded_channel();
3226        let execution_scheduler = Arc::new(ExecutionSchedulerWrapper::new(
3227            execution_cache_trait_pointers.object_cache_reader.clone(),
3228            execution_cache_trait_pointers
3229                .transaction_cache_reader
3230                .clone(),
3231            tx_ready_transactions,
3232            &epoch_store,
3233            metrics.clone(),
3234        ));
3235        let (tx_execution_shutdown, rx_execution_shutdown) = oneshot::channel();
3236
3237        let authority_per_epoch_pruner = AuthorityPerEpochStorePruner::new(
3238            epoch_store.get_parent_path(),
3239            config
3240                .authority_store_pruning_config
3241                .num_latest_epoch_dbs_to_retain,
3242        )
3243        .await;
3244        let object_retention = ObjectRetention::new(
3245            checkpoint_store
3246                .get_highest_executed_checkpoint_seq_number()
3247                .ok()
3248                .flatten()
3249                .unwrap_or_default(),
3250        );
3251        let num_epochs_to_retain = config.authority_store_pruning_config.num_epochs_to_retain;
3252        if epoch_store.committee().authority_exists(&name)
3253            && num_epochs_to_retain > 0
3254            && num_epochs_to_retain < u64::MAX
3255        {
3256            warn!(
3257                num_epochs_to_retain,
3258                "this validator retains superseded object versions it does not serve, which \
3259                 grows its database; lowering the retention later expires every epoch they \
3260                 span at once, at the next start. Set 0 to retain none beyond the current epoch."
3261            );
3262        }
3263        if let Some(delay_days) = config
3264            .authority_store_pruning_config
3265            .periodic_compaction_threshold_days
3266        {
3267            store.perpetual_tables.spawn_periodic_compaction(delay_days);
3268        }
3269        let input_loader =
3270            TransactionInputLoader::new(execution_cache_trait_pointers.object_cache_reader.clone());
3271        let epoch = epoch_store.epoch();
3272        let (historic_bucket_expiry, expiry_epochs) = watch::channel(epoch);
3273        let rgp = epoch_store.reference_gas_price();
3274        let traffic_controller_metrics =
3275            Arc::new(TrafficControllerMetrics::new(prometheus_registry));
3276        let traffic_controller = policy_config.map(|policy_config| {
3277            Arc::new(TrafficController::init(
3278                policy_config,
3279                traffic_controller_metrics,
3280            ))
3281        });
3282        let state = Arc::new(AuthorityState {
3283            name,
3284            secret,
3285            execution_lock: RwLock::new(epoch),
3286            epoch_store: ArcSwap::new(epoch_store.clone()),
3287            input_loader,
3288            execution_cache_trait_pointers,
3289            rpc_indexes_store,
3290            historic_objects: store.get_historic_objects().clone(),
3291            historic_ledger: store.get_historic_ledger().clone(),
3292            checkpoint_store,
3293            committee_store,
3294            execution_scheduler,
3295            tx_execution_shutdown: Mutex::new(Some(tx_execution_shutdown)),
3296            metrics,
3297            authority_per_epoch_pruner,
3298            object_retention,
3299            config,
3300            overload_info: AuthorityOverloadInfo::default(),
3301            validator_tx_finalizer,
3302            chain_identifier,
3303            congestion_tracker: Arc::new(CongestionTracker::new(rgp)),
3304            traffic_controller,
3305            epoch_end_db_snapshots,
3306            historic_bucket_expiry,
3307            historic_bucket_work_stopped: Arc::new(AtomicBool::new(false)),
3308        });
3309        // An expiry cut short by a crash may not have recorded what it
3310        // dropped.
3311        Self::record_pruned_checkpoints(&state.historic_ledger, &state.checkpoint_store);
3312
3313        let expiry = Self::expire_historic_buckets_in_background(
3314            Arc::downgrade(&state),
3315            expiry_epochs,
3316            state.object_retention.released(),
3317        );
3318        spawn_monitored_task!(expiry);
3319
3320        // Start a task to execute ready transactions.
3321        let authority_state = Arc::downgrade(&state);
3322        spawn_monitored_task!(execution_process(
3323            authority_state,
3324            rx_ready_transactions,
3325            rx_execution_shutdown,
3326        ));
3327
3328        state
3329    }
3330
3331    pub fn epoch_db_pruner(&self) -> &AuthorityPerEpochStorePruner {
3332        &self.authority_per_epoch_pruner
3333    }
3334
3335    /// Superseded object versions, bucketed by epoch.
3336    pub fn get_historic_objects(&self) -> &Arc<HistoricObjects> {
3337        &self.historic_objects
3338    }
3339
3340    /// Executed transactions keyed by checkpoint, bucketed by epoch.
3341    pub fn get_historic_ledger(&self) -> &Arc<HistoricLedger> {
3342        &self.historic_ledger
3343    }
3344
3345    // TODO: Consolidate our traits to reduce the number of methods here.
3346    pub fn get_object_cache_reader(&self) -> &Arc<dyn ObjectCacheRead> {
3347        &self.execution_cache_trait_pointers.object_cache_reader
3348    }
3349
3350    pub fn get_transaction_cache_reader(&self) -> &Arc<dyn TransactionCacheRead> {
3351        &self.execution_cache_trait_pointers.transaction_cache_reader
3352    }
3353
3354    pub fn get_cache_writer(&self) -> &Arc<dyn ExecutionCacheWrite> {
3355        &self.execution_cache_trait_pointers.cache_writer
3356    }
3357
3358    pub fn get_backing_store(&self) -> &Arc<dyn BackingStore + Send + Sync> {
3359        &self.execution_cache_trait_pointers.backing_store
3360    }
3361
3362    pub fn get_backing_package_store(&self) -> &Arc<dyn BackingPackageStore + Send + Sync> {
3363        &self.execution_cache_trait_pointers.backing_package_store
3364    }
3365
3366    pub fn get_object_store(&self) -> &Arc<dyn ObjectStore + Send + Sync> {
3367        &self.execution_cache_trait_pointers.object_store
3368    }
3369
3370    pub fn get_reconfig_api(&self) -> &Arc<dyn ExecutionCacheReconfigAPI> {
3371        &self.execution_cache_trait_pointers.reconfig_api
3372    }
3373
3374    pub fn get_global_state_hash_store(&self) -> &Arc<dyn GlobalStateHashStore> {
3375        &self.execution_cache_trait_pointers.global_state_hash_store
3376    }
3377
3378    pub fn get_checkpoint_cache(&self) -> &Arc<dyn CheckpointCache> {
3379        &self.execution_cache_trait_pointers.checkpoint_cache
3380    }
3381
3382    pub fn get_state_sync_store(&self) -> &Arc<dyn StateSyncAPI> {
3383        &self.execution_cache_trait_pointers.state_sync_store
3384    }
3385
3386    pub fn get_cache_commit(&self) -> &Arc<dyn ExecutionCacheCommit> {
3387        &self.execution_cache_trait_pointers.cache_commit
3388    }
3389
3390    pub fn database_for_testing(&self) -> Arc<AuthorityStore> {
3391        self.execution_cache_trait_pointers
3392            .testing_api
3393            .database_for_testing()
3394    }
3395
3396    /// Drops the committed versions of `id` the execution cache holds in
3397    /// memory, so the next read of a committed version goes to the database.
3398    #[cfg(test)]
3399    pub fn evict_committed_object_for_testing(&self, id: &ObjectId) {
3400        self.execution_cache_trait_pointers
3401            .testing_api
3402            .evict_committed_object_for_testing(id)
3403    }
3404
3405    /// Drops the execution cache's copies of committed data, so that reads
3406    /// issued afterwards answer from the store.
3407    pub fn clear_execution_caches_for_testing(&self) {
3408        self.execution_cache_trait_pointers
3409            .testing_api
3410            .clear_caches_for_testing()
3411    }
3412
3413    /// The executed transactions whose outputs are not committed yet.
3414    #[cfg(test)]
3415    pub fn uncommitted_transactions_for_testing(&self) -> Vec<TransactionDigest> {
3416        self.execution_cache_trait_pointers
3417            .testing_api
3418            .uncommitted_transactions_for_testing()
3419    }
3420
3421    pub fn execution_scheduler(&self) -> &Arc<ExecutionSchedulerWrapper> {
3422        &self.execution_scheduler
3423    }
3424
3425    /// Whether this authority runs the `ExecutionScheduler` rather than the
3426    /// `TransactionManager`.
3427    pub fn uses_execution_scheduler(&self) -> bool {
3428        self.execution_scheduler.uses_execution_scheduler()
3429    }
3430
3431    /// Attempts to acquire execution lock for an executable transaction.
3432    /// Returns the lock if the transaction is matching current executed epoch
3433    /// Returns None otherwise
3434    pub fn execution_lock_for_executable_transaction(
3435        &self,
3436        transaction: &VerifiedExecutableTransaction,
3437    ) -> IotaResult<ExecutionLockReadGuard<'_>> {
3438        let lock = self
3439            .execution_lock
3440            .try_read()
3441            .map_err(|_| IotaError::ValidatorHaltedAtEpochEnd)?;
3442        if *lock == transaction.auth_sig().epoch() {
3443            Ok(lock)
3444        } else {
3445            Err(IotaError::WrongEpoch {
3446                expected_epoch: *lock,
3447                actual_epoch: transaction.auth_sig().epoch(),
3448            })
3449        }
3450    }
3451
3452    /// Acquires the execution lock for the duration of a transaction signing
3453    /// request. This prevents reconfiguration from starting until we are
3454    /// finished handling the signing request. Otherwise, in-memory lock
3455    /// state could be cleared (by `ObjectLocks::clear_cached_locks`)
3456    /// while we are attempting to acquire locks for the transaction.
3457    pub fn execution_lock_for_signing(&self) -> IotaResult<ExecutionLockReadGuard<'_>> {
3458        self.execution_lock
3459            .try_read()
3460            .map_err(|_| IotaError::ValidatorHaltedAtEpochEnd)
3461    }
3462
3463    pub async fn execution_lock_for_reconfiguration(&self) -> ExecutionLockWriteGuard<'_> {
3464        self.execution_lock.write().await
3465    }
3466
3467    /// Reports a mirror that diverged from the object at the epoch boundary,
3468    /// where the two must agree. Reporting is the remedy: reconfiguration
3469    /// re-seeds the mirror from the object, so failing here would only pin
3470    /// the node to the diverged state. A missing object is fatal instead.
3471    /// Objects cannot be deleted, so the local store lost it and there is
3472    /// nothing to re-seed from. Nodes outside the closing committee are
3473    /// exempt. So is an epoch this node's consensus did not close. A
3474    /// checkpoint catch-up leaves the mirror legitimately behind until the
3475    /// re-seed.
3476    pub(crate) fn check_transaction_deny_rules_consistency(
3477        &self,
3478        cur_epoch_store: &AuthorityPerEpochStore,
3479        epoch_start_configuration: &EpochStartConfiguration,
3480    ) {
3481        if self.is_fullnode(cur_epoch_store) {
3482            return;
3483        }
3484        let Some(walked_deny_rules) = epoch_start_configuration.transaction_deny_rules_state()
3485        else {
3486            if cur_epoch_store
3487                .epoch_start_config()
3488                .transaction_deny_rules_obj_initial_shared_version()
3489                .is_some()
3490            {
3491                fatal!(
3492                    "TransactionDenyRules object existed in epoch {} but is missing from the \
3493                     state walked for the next epoch — the local store is corrupted; restore or \
3494                     state-sync before rejoining",
3495                    cur_epoch_store.epoch(),
3496                );
3497            }
3498            return;
3499        };
3500        // RejectAllTx proves this node's consensus processed every commit of
3501        // the epoch, so the mirror is complete. Otherwise the tail came from
3502        // synced checkpoints and the mirror's lag carries no signal.
3503        if cur_epoch_store
3504            .get_reconfig_state_read_lock_guard()
3505            .should_accept_tx()
3506        {
3507            info!(
3508                "skipping the deny-rule mirror comparison: consensus did not close epoch {} on \
3509                 this node",
3510                cur_epoch_store.epoch(),
3511            );
3512            return;
3513        }
3514        let mirrored_deny_rules = cur_epoch_store.get_mirrored_transaction_deny_rules();
3515        if *walked_deny_rules != *mirrored_deny_rules {
3516            debug_fatal!(
3517                "TransactionDenyRules object diverged from the mirrored state at the end of \
3518                 epoch {}; continuing from the object (walked: {walked_deny_rules:?}, mirrored: \
3519                 {mirrored_deny_rules:?})",
3520                cur_epoch_store.epoch(),
3521            );
3522            cur_epoch_store.metrics.deny_rule_mirror_divergence.set(1);
3523        }
3524    }
3525
3526    /// Reports a `TransactionDenyRulesUpdate` whose execution failed — an
3527    /// invariant violation, the update is built to exclude every expected
3528    /// failure. The object misses the delta until the epoch boundary re-seeds
3529    /// the mirror. Identification is by kind, so the report needs no tracking
3530    /// state and holds across restarts and replays.
3531    ///
3532    /// `expected_effects_digest` is `Some` when these effects were handed to
3533    /// this node with the transaction, which is the case while executing a
3534    /// certified checkpoint: the failure is then part of agreed history, so it
3535    /// is reported without asserting. Effects the node derived itself assert,
3536    /// because only then is the broken invariant its own.
3537    pub(crate) fn report_failed_deny_rule_update_execution(
3538        &self,
3539        transaction: &VerifiedExecutableTransaction,
3540        effects: &TransactionEffects,
3541        expected_effects_digest: Option<TransactionEffectsDigest>,
3542        epoch_store: &AuthorityPerEpochStore,
3543    ) {
3544        if !matches!(
3545            transaction.transaction().kind(),
3546            TransactionKind::TransactionDenyRulesUpdate(_)
3547        ) || effects.status().is_success()
3548        {
3549            return;
3550        }
3551        epoch_store
3552            .metrics
3553            .deny_rule_update_execution_failures
3554            .inc();
3555        if expected_effects_digest.is_some() {
3556            error!(
3557                digest = ?transaction.digest(),
3558                status = ?effects.status(),
3559                "TransactionDenyRulesUpdate failed execution; the object misses its delta until \
3560                 the epoch boundary re-seeds the mirror"
3561            );
3562            return;
3563        }
3564        debug_fatal!(
3565            "TransactionDenyRulesUpdate failed execution; the object misses its delta until the \
3566             epoch boundary re-seeds the mirror (digest: {:?}, status: {:?})",
3567            transaction.digest(),
3568            effects.status(),
3569        );
3570    }
3571
3572    #[instrument(level = "error", skip_all)]
3573    pub async fn reconfigure(
3574        &self,
3575        cur_epoch_store: &AuthorityPerEpochStore,
3576        supported_protocol_versions: SupportedProtocolVersions,
3577        new_committee: Committee,
3578        epoch_start_configuration: EpochStartConfiguration,
3579        state_hasher: Arc<GlobalStateHasher>,
3580        expensive_safety_check_config: &ExpensiveSafetyCheckConfig,
3581        epoch_supply_change: i64,
3582        epoch_last_checkpoint: CheckpointSequenceNumber,
3583    ) -> IotaResult<Arc<AuthorityPerEpochStore>> {
3584        Self::check_protocol_version(
3585            supported_protocol_versions,
3586            epoch_start_configuration
3587                .epoch_start_state()
3588                .protocol_version(),
3589        );
3590        self.metrics.reset_on_reconfigure();
3591        self.committee_store.insert_new_committee(&new_committee)?;
3592
3593        // Wait until no transactions are being executed.
3594        let mut execution_lock = self.execution_lock_for_reconfiguration().await;
3595
3596        // Terminate all epoch-specific tasks (those started with within_alive_epoch).
3597        cur_epoch_store.epoch_terminated().await;
3598
3599        let highest_locally_built_checkpoint_seq = self
3600            .checkpoint_store
3601            .get_latest_locally_computed_checkpoint()?
3602            .map(|c| c.sequence_number())
3603            .unwrap_or(0);
3604
3605        assert!(
3606            epoch_last_checkpoint >= highest_locally_built_checkpoint_seq,
3607            "expected {epoch_last_checkpoint} >= {highest_locally_built_checkpoint_seq}"
3608        );
3609
3610        // Safe to reconfigure now. No transactions are being executed,
3611        // and no epoch-specific tasks are running.
3612
3613        // TODO: revert_uncommitted_epoch_transactions will soon be unnecessary -
3614        // clear_state_end_of_epoch() can simply drop all uncommitted transactions
3615        self.revert_uncommitted_epoch_transactions(cur_epoch_store)
3616            .await?;
3617        self.get_reconfig_api()
3618            .clear_state_end_of_epoch(&execution_lock);
3619        self.check_system_consistency(
3620            cur_epoch_store,
3621            state_hasher,
3622            expensive_safety_check_config,
3623            epoch_supply_change,
3624        )?;
3625        self.check_transaction_deny_rules_consistency(cur_epoch_store, &epoch_start_configuration);
3626
3627        self.get_reconfig_api()
3628            .try_set_epoch_start_configuration(&epoch_start_configuration)?;
3629        self.hand_over_epoch_end_db_snapshot(cur_epoch_store.epoch())
3630            .await;
3631
3632        let new_epoch = new_committee.epoch;
3633        self.open_historic_buckets(new_epoch)?;
3634        let new_epoch_store = self
3635            .reopen_epoch_db(
3636                cur_epoch_store,
3637                new_committee,
3638                epoch_start_configuration,
3639                expensive_safety_check_config,
3640                epoch_last_checkpoint,
3641            )
3642            .await?;
3643        assert_eq!(new_epoch_store.epoch(), new_epoch);
3644        match self.execution_scheduler.as_ref() {
3645            ExecutionSchedulerWrapper::ExecutionScheduler(_) => {}
3646            ExecutionSchedulerWrapper::TransactionManager(tm) => {
3647                tm.reconfigure(new_epoch);
3648            }
3649        }
3650        *execution_lock = new_epoch;
3651        // Not before the lock reads the new epoch: `try_execute_immediately`
3652        // reads a receiving object's marker before it takes the lock.
3653        if let Err(err) = self
3654            .get_reconfig_api()
3655            .expire_epoch_markers(new_epoch, &execution_lock)
3656        {
3657            error!("Failed to expire the epoch marker buckets: {err:?}");
3658        }
3659        // The other histories expire in the background, so that execution
3660        // resumes without waiting for their deletions.
3661        self.historic_bucket_expiry.send_replace(new_epoch);
3662        // drop execution_lock after epoch store was updated
3663        // see also assert in AuthorityState::process_transaction
3664        // on the epoch store and execution lock epoch match
3665        Ok(new_epoch_store)
3666    }
3667
3668    /// Opens `new_epoch`'s bucket in each per-epoch history, while execution
3669    /// is stopped.
3670    ///
3671    /// # Errors
3672    ///
3673    /// Fails if a history cannot create its bucket for `new_epoch`.
3674    fn open_historic_buckets(&self, new_epoch: EpochId) -> IotaResult<()> {
3675        self.historic_objects.ensure(new_epoch)?;
3676        self.historic_ledger.ensure(new_epoch)?;
3677        self.checkpoint_store
3678            .historic_checkpoints
3679            .ensure(new_epoch)?;
3680        // Not fatal: checkpoint ingest also creates this bucket on demand.
3681        if let Some(indexes) = &self.rpc_indexes_store {
3682            if let Err(err) = indexes.ensure_history_bucket_exists(new_epoch) {
3683                error!("Failed to open the RPC index history bucket of {new_epoch}: {err:?}");
3684            }
3685        }
3686        Ok(())
3687    }
3688
3689    /// Opens `new_epoch`'s buckets and expires the ones outside their
3690    /// retention, as an epoch change and the expiry task that follows it do.
3691    #[cfg(test)]
3692    async fn advance_historic_buckets(&self, new_epoch: EpochId) -> IotaResult<()> {
3693        self.open_historic_buckets(new_epoch)?;
3694        self.expire_historic_buckets(new_epoch).await;
3695        Ok(())
3696    }
3697
3698    /// Expires the buckets of every per-epoch history, the RPC index history
3699    /// included, that fell outside their configured retention as counted from
3700    /// `current_epoch`. A historic-object bucket from the epoch of a
3701    /// checkpoint a [`Self::retain_objects`] guard still holds on is kept.
3702    /// Returns whether such a guard kept a bucket that would otherwise have
3703    /// expired.
3704    ///
3705    /// Errors are logged: an unfinished expiry is retried by the next one, or
3706    /// at the next open.
3707    async fn expire_historic_buckets(&self, current_epoch: EpochId) -> bool {
3708        // Both count the epochs kept below the current one, as `prune` does.
3709        // `None` turns retention off.
3710        let pruning_config = &self.config.authority_store_pruning_config;
3711        let configured_objects_to_retain = pruning_config.num_epochs_to_retain();
3712        let objects_to_retain = configured_objects_to_retain.map(|epochs| {
3713            self.oldest_epoch_retained_for_object_reads()
3714                .map_or(epochs, |epoch| {
3715                    epochs.max(current_epoch.saturating_sub(epoch))
3716                })
3717        });
3718        let held_back = objects_to_retain != configured_objects_to_retain;
3719        let checkpoints_to_retain = pruning_config.num_epochs_to_retain_for_checkpoints();
3720
3721        // Blocks for as long as the deletes and drops take.
3722        let historic_objects = self.historic_objects.clone();
3723        let historic_ledger = self.historic_ledger.clone();
3724        let checkpoint_store = self.checkpoint_store.clone();
3725        let rpc_indexes_store = self.rpc_indexes_store.clone();
3726        let stopped = self.historic_bucket_work_stopped.clone();
3727        let metrics = self.metrics.clone();
3728        let expired = tokio::task::spawn_blocking(move || {
3729            // The index first, so it never names a transaction the ledger has
3730            // dropped, and the checkpoints before the ledger, so a checkpoint
3731            // is never served without its transactions.
3732            // Only runs that dropped a bucket: the ones that drop nothing, as at
3733            // every start, would bury the durations of the ones that do.
3734            let expire =
3735                |store: &str, prune: &dyn Fn() -> Result<Option<PrunedBuckets>, String>| {
3736                    if stopped.load(Ordering::Acquire) {
3737                        return;
3738                    }
3739                    let started = Instant::now();
3740                    match prune() {
3741                        Ok(Some(pruned)) => {
3742                            if pruned.dropped > 0 {
3743                                metrics
3744                                    .historic_bucket_expiry_duration
3745                                    .with_label_values(&[store])
3746                                    .observe(started.elapsed().as_secs_f64());
3747                            }
3748                            metrics
3749                                .historic_bucket_earliest_retained_epoch
3750                                .with_label_values(&[store])
3751                                .set(pruned.earliest_retained as i64);
3752                        }
3753                        Ok(None) => {}
3754                        Err(err) if stopped.load(Ordering::Acquire) => {
3755                            info!(
3756                                store,
3757                                "Stopped expiring historic buckets for a shutdown: {err}"
3758                            )
3759                        }
3760                        Err(err) => error!(store, "Failed to expire historic buckets: {err}"),
3761                    }
3762                };
3763            if let Some(indexes) = &rpc_indexes_store {
3764                expire("indexes", &|| {
3765                    indexes.prune(current_epoch).map_err(|e| format!("{e:?}"))
3766                });
3767            }
3768            if let Some(epochs_to_retain) = checkpoints_to_retain {
3769                // Before each drop, so that no reader is told a checkpoint is
3770                // available after its contents or transactions are gone.
3771                let record =
3772                    || Self::record_pruned_checkpoints(&historic_ledger, &checkpoint_store);
3773                expire("checkpoints", &|| {
3774                    checkpoint_store
3775                        .historic_checkpoints
3776                        .prune(current_epoch, epochs_to_retain, &record)
3777                        .map_err(|e| format!("{e:?}"))
3778                });
3779                expire("ledger", &|| {
3780                    historic_ledger
3781                        .prune(current_epoch, epochs_to_retain, &record)
3782                        .map_err(|e| format!("{e:?}"))
3783                });
3784                // Also when nothing was dropped, after a floor moved without a
3785                // drop, as after a crash between the two.
3786                record();
3787            }
3788            if let Some(epochs_to_retain) = objects_to_retain {
3789                expire("objects", &|| {
3790                    historic_objects
3791                        .prune(current_epoch, epochs_to_retain)
3792                        .map_err(|e| format!("{e:?}"))
3793                });
3794            }
3795        })
3796        .await;
3797        if let Err(err) = expired {
3798            error!("The historic bucket expiry task failed: {err:?}");
3799        }
3800        held_back
3801    }
3802
3803    /// Stops the background expiry and compaction of historic buckets, for a
3804    /// shutdown: an expiry stops before its next store or its next batch of
3805    /// tombstones, and a compaction before its next bucket, as the blocking
3806    /// task holds up the runtime's shutdown. A bucket already being compacted
3807    /// is finished first, which for a large one can take minutes. What is cut
3808    /// short is finished at the next start.
3809    pub fn stop_historic_bucket_work(&self) {
3810        self.historic_bucket_work_stopped
3811            .store(true, Ordering::Release);
3812        self.historic_objects.stop();
3813    }
3814
3815    /// How far this node's newest executed checkpoint is behind the local
3816    /// clock, `None` when nothing is executed yet.
3817    fn execution_lag(&self) -> Option<Duration> {
3818        let Ok(Some(executed)) = self.checkpoint_store.get_highest_executed_checkpoint() else {
3819            return None;
3820        };
3821        let executed_at = UNIX_EPOCH + Duration::from_millis(executed.timestamp_ms);
3822        Some(
3823            SystemTime::now()
3824                .duration_since(executed_at)
3825                .unwrap_or_default(),
3826        )
3827    }
3828
3829    /// Whether this node is still catching up with the network: nothing is
3830    /// executed yet, or its newest executed checkpoint is more than
3831    /// [`CATCH_UP_LAG`] old.
3832    fn is_catching_up(&self) -> bool {
3833        self.execution_lag().is_none_or(|lag| lag > CATCH_UP_LAG)
3834    }
3835
3836    /// Compacts the buckets of every store's closed epochs that are not
3837    /// compacted yet, so a lookup that walks the buckets probes each of them
3838    /// once. Stops before the next bucket once `epochs` announces a new epoch
3839    /// or its sender is dropped, or `stopped` is set, which leaves the rest
3840    /// for the next call.
3841    async fn compact_closed_buckets(
3842        current_epoch: EpochId,
3843        historic_objects: Arc<HistoricObjects>,
3844        historic_ledger: Arc<HistoricLedger>,
3845        checkpoint_store: Arc<CheckpointStore>,
3846        rpc_indexes_store: Option<Arc<RpcIndexesStore>>,
3847        epochs: watch::Receiver<EpochId>,
3848        stopped: Arc<AtomicBool>,
3849    ) {
3850        let compacted = tokio::task::spawn_blocking(move || {
3851            let stop =
3852                || stopped.load(Ordering::Acquire) || !matches!(epochs.has_changed(), Ok(false));
3853            if let Some(indexes) = &rpc_indexes_store {
3854                // The history backfill writes closed epochs' buckets until it
3855                // is done; the next pass compacts them.
3856                if indexes.is_history_backfill_running() {
3857                    info!("Not compacting the RPC index history while its backfill runs");
3858                } else if let Err(err) = indexes.compact_closed_buckets(current_epoch, &stop) {
3859                    error!("Failed to compact the RPC index history: {err:?}");
3860                }
3861            }
3862            if let Err(err) = checkpoint_store
3863                .historic_checkpoints
3864                .compact_closed_buckets(current_epoch, &stop)
3865            {
3866                error!("Failed to compact historic checkpoint buckets: {err:?}");
3867            }
3868            if let Err(err) = historic_ledger.compact_closed_buckets(current_epoch, &stop) {
3869                error!("Failed to compact historic ledger buckets: {err:?}");
3870            }
3871            if let Err(err) = historic_objects.compact_closed_buckets(current_epoch, &stop) {
3872                error!("Failed to compact historic object buckets: {err:?}");
3873            }
3874        })
3875        .await;
3876        if let Err(err) = compacted {
3877            error!("The closed bucket compaction task failed: {err:?}");
3878        }
3879    }
3880
3881    /// Expires the historic buckets for each epoch `epochs` announces,
3882    /// starting with the one it holds, and again once a retention guard is
3883    /// dropped after one kept a bucket; then compacts the closed buckets.
3884    /// Returns once `state` is dropped.
3885    ///
3886    /// Compaction waits while a guard keeps a bucket, which may expire at the
3887    /// next run, and while the node catches up: epochs then close one after
3888    /// another, the oldest expire soon after, and nothing on the catch-up path
3889    /// walks the closed buckets. It is retried every
3890    /// [`COMPACTION_RECHECK_INTERVAL`] until the node has caught up.
3891    async fn expire_historic_buckets_in_background(
3892        state: Weak<AuthorityState>,
3893        mut epochs: watch::Receiver<EpochId>,
3894        released: Arc<Notify>,
3895    ) {
3896        // Logged when it changes, so an operator can see why closed buckets
3897        // are not compacted.
3898        let mut compaction_held_back = None;
3899        loop {
3900            let epoch = *epochs.borrow_and_update();
3901            let Some(this) = state.upgrade() else {
3902                return;
3903            };
3904            if this.historic_bucket_work_stopped.load(Ordering::Acquire) {
3905                return;
3906            }
3907            let held_back = this.expire_historic_buckets(epoch).await;
3908            let catching_up = this.is_catching_up();
3909            let state = (held_back, catching_up);
3910            if compaction_held_back != Some(state) {
3911                match state {
3912                    (false, false) => info!("Compacting the buckets of closed epochs"),
3913                    (true, _) => info!(
3914                        "Not compacting the buckets of closed epochs while a read holds back the \
3915                         expiry of historic objects"
3916                    ),
3917                    (false, true) => info!(
3918                        lag_s = this.execution_lag().map(|lag| lag.as_secs()),
3919                        "Not compacting the buckets of closed epochs while the node catches up: \
3920                         its newest executed checkpoint is more than {} minutes old",
3921                        CATCH_UP_LAG.as_secs() / 60
3922                    ),
3923                }
3924                compaction_held_back = Some(state);
3925            }
3926            let compaction = (!held_back && !catching_up).then(|| {
3927                (
3928                    this.historic_objects.clone(),
3929                    this.historic_ledger.clone(),
3930                    this.checkpoint_store.clone(),
3931                    this.rpc_indexes_store.clone(),
3932                    this.historic_bucket_work_stopped.clone(),
3933                )
3934            });
3935            drop(this);
3936            if let Some((
3937                historic_objects,
3938                historic_ledger,
3939                checkpoint_store,
3940                rpc_indexes_store,
3941                stopped,
3942            )) = compaction
3943            {
3944                Self::compact_closed_buckets(
3945                    epoch,
3946                    historic_objects,
3947                    historic_ledger,
3948                    checkpoint_store,
3949                    rpc_indexes_store,
3950                    epochs.clone(),
3951                    stopped,
3952                )
3953                .await;
3954            }
3955            tokio::select! {
3956                changed = epochs.changed() => {
3957                    if changed.is_err() {
3958                        return;
3959                    }
3960                }
3961                () = released.notified(), if held_back => {
3962                    // Guards come and go with requests, so one expiry per
3963                    // interval rather than one per dropped guard.
3964                    tokio::time::sleep(HELD_BACK_EXPIRY_INTERVAL).await;
3965                }
3966                () = tokio::time::sleep(COMPACTION_RECHECK_INTERVAL), if catching_up && !held_back => {}
3967            }
3968        }
3969    }
3970
3971    /// Moves `HighestPruned` up to the last checkpoint below the epochs both
3972    /// the ledger and the checkpoint history still retain: a checkpoint whose
3973    /// contents or transactions are gone can no longer be served to state-sync
3974    /// peers or RPC clients. Either expiry can fail or be cut short without the
3975    /// other, so this takes whichever floor is higher.
3976    fn record_pruned_checkpoints(
3977        historic_ledger: &HistoricLedger,
3978        checkpoint_store: &CheckpointStore,
3979    ) {
3980        let floor = historic_ledger.earliest_retained_epoch().max(
3981            checkpoint_store
3982                .historic_checkpoints
3983                .earliest_retained_epoch(),
3984        );
3985        if let Err(err) = checkpoint_store.advance_highest_pruned_checkpoint(floor) {
3986            error!("Failed to record the pruned checkpoint range: {err:?}");
3987        }
3988    }
3989
3990    /// The oldest epoch whose historic-object bucket a [`Self::retain_objects`]
3991    /// guard may still read from, `None` when no guard is held.
3992    fn oldest_epoch_retained_for_object_reads(&self) -> Option<EpochId> {
3993        let retained = self.object_retention.lowest_retained()?;
3994        // A retained checkpoint was executed, so its summary is here; without
3995        // it, nothing is known to be safe to drop.
3996        match self
3997            .checkpoint_store
3998            .get_checkpoint_by_sequence_number(retained)
3999        {
4000            Ok(checkpoint) => Some(checkpoint.map_or(0, |checkpoint| checkpoint.epoch())),
4001            Err(err) => {
4002                error!(
4003                    "Failed to read the epoch of retained checkpoint {retained}, keeping \
4004                     every historic object bucket: {err:?}"
4005                );
4006                Some(0)
4007            }
4008        }
4009    }
4010
4011    /// Advance the epoch store to the next epoch for testing only.
4012    /// This only manually sets all the places where we have the epoch number.
4013    /// It doesn't properly reconfigure the node, hence should be only used for
4014    /// testing.
4015    pub async fn reconfigure_for_testing(&self) {
4016        self.reconfigure_for_testing_impl(None).await;
4017    }
4018
4019    /// Like [`Self::reconfigure_for_testing`], but the next epoch uses the
4020    /// given protocol config.
4021    pub async fn reconfigure_for_testing_with_protocol_config(
4022        &self,
4023        protocol_config: ProtocolConfig,
4024    ) {
4025        self.reconfigure_for_testing_impl(Some(protocol_config))
4026            .await;
4027    }
4028
4029    async fn reconfigure_for_testing_impl(&self, protocol_config: Option<ProtocolConfig>) {
4030        let mut execution_lock = self.execution_lock_for_reconfiguration().await;
4031        let epoch_store = self.epoch_store_for_testing().clone();
4032        // Default to the epoch store's config, whose override guard may have
4033        // been dropped. Read it under the lock so config and epoch store are
4034        // one snapshot.
4035        let protocol_config =
4036            protocol_config.unwrap_or_else(|| epoch_store.protocol_config().clone());
4037        let _guard =
4038            ProtocolConfig::apply_overrides_for_testing(move |_, _| protocol_config.clone());
4039        let new_epoch_store = epoch_store.new_at_next_epoch_for_testing(
4040            self.get_backing_package_store().clone(),
4041            &self.config.expensive_safety_check_config,
4042            self.checkpoint_store
4043                .get_epoch_last_checkpoint(epoch_store.epoch())
4044                .unwrap()
4045                .map(|c| c.sequence_number())
4046                .unwrap_or_default(),
4047        );
4048        let new_epoch = new_epoch_store.epoch();
4049        match self.execution_scheduler.as_ref() {
4050            ExecutionSchedulerWrapper::ExecutionScheduler(_) => {}
4051            ExecutionSchedulerWrapper::TransactionManager(tm) => {
4052                tm.reconfigure(new_epoch);
4053            }
4054        }
4055        self.epoch_store.store(new_epoch_store);
4056        epoch_store.epoch_terminated().await;
4057        *execution_lock = new_epoch;
4058    }
4059
4060    #[instrument(level = "error", skip_all)]
4061    fn check_system_consistency(
4062        &self,
4063        cur_epoch_store: &AuthorityPerEpochStore,
4064        state_hasher: Arc<GlobalStateHasher>,
4065        expensive_safety_check_config: &ExpensiveSafetyCheckConfig,
4066        epoch_supply_change: i64,
4067    ) -> IotaResult<()> {
4068        info!(
4069            "Performing iota conservation consistency check for epoch {}",
4070            cur_epoch_store.epoch()
4071        );
4072
4073        if cfg!(debug_assertions) {
4074            cur_epoch_store.check_all_executed_transactions_in_checkpoint();
4075        }
4076
4077        self.get_reconfig_api()
4078            .try_expensive_check_iota_conservation(cur_epoch_store, Some(epoch_supply_change))?;
4079
4080        // check for root state hash consistency with live object set
4081        if expensive_safety_check_config.enable_state_consistency_check() {
4082            info!(
4083                "Performing state consistency check for epoch {}",
4084                cur_epoch_store.epoch()
4085            );
4086            self.expensive_check_is_consistent_state(state_hasher, cur_epoch_store);
4087        }
4088
4089        Ok(())
4090    }
4091
4092    fn expensive_check_is_consistent_state(
4093        &self,
4094        state_hasher: Arc<GlobalStateHasher>,
4095        cur_epoch_store: &AuthorityPerEpochStore,
4096    ) {
4097        let live_object_set_hash = state_hasher
4098            .digest_live_object_set()
4099            .expect("Reading the live object set cannot fail");
4100
4101        let root_state_hash: ECMHLiveObjectSetDigest = self
4102            .get_global_state_hash_store()
4103            .get_root_state_hash_for_epoch(cur_epoch_store.epoch())
4104            .expect("Retrieving root state hash cannot fail")
4105            .expect("Root state hash for epoch must exist")
4106            .1
4107            .digest()
4108            .into();
4109
4110        let is_inconsistent = root_state_hash != live_object_set_hash;
4111        if is_inconsistent {
4112            debug_fatal!(
4113                "Inconsistent state detected: root state hash: {:?}, live object set hash: {:?}",
4114                root_state_hash,
4115                live_object_set_hash
4116            );
4117        } else {
4118            info!("State consistency check passed");
4119        }
4120
4121        state_hasher.set_inconsistent_state(is_inconsistent);
4122    }
4123
4124    pub fn current_epoch_for_testing(&self) -> EpochId {
4125        self.epoch_store_for_testing().epoch()
4126    }
4127
4128    /// Lets the consumer take its database snapshot of the perpetual store as
4129    /// the epoch ends, when there is one. See
4130    /// [`EpochEndDbSnapshotHandle::hand_over`].
4131    #[instrument(level = "error", skip_all)]
4132    async fn hand_over_epoch_end_db_snapshot(&self, epoch: EpochId) {
4133        let Some(handle) = &self.epoch_end_db_snapshots else {
4134            return;
4135        };
4136        let _metrics_guard = self
4137            .metrics
4138            .epoch_end_db_snapshot_handover_latency
4139            .start_timer();
4140        if handle.hand_over(epoch).await == HandOver::Skipped {
4141            self.metrics.epoch_end_db_snapshots_skipped.inc();
4142        }
4143    }
4144
4145    /// Load the current epoch store. This can change during reconfiguration. To
4146    /// ensure that we never end up accessing different epoch stores in a
4147    /// single task, we need to make sure that this is called once per task.
4148    /// Each call needs to be carefully audited to ensure it is
4149    /// the case. This also means we should minimize the number of call-sites.
4150    /// Only call it when there is no way to obtain it from somewhere else.
4151    pub fn load_epoch_store_one_call_per_task(&self) -> Guard<Arc<AuthorityPerEpochStore>> {
4152        self.epoch_store.load()
4153    }
4154
4155    // Load the epoch store, should be used in tests only.
4156    pub fn epoch_store_for_testing(&self) -> Guard<Arc<AuthorityPerEpochStore>> {
4157        self.load_epoch_store_one_call_per_task()
4158    }
4159
4160    pub fn clone_committee_for_testing(&self) -> Committee {
4161        Committee::clone(self.epoch_store_for_testing().committee())
4162    }
4163
4164    #[instrument(level = "trace", skip_all)]
4165    pub fn try_get_object(&self, object_id: &ObjectId) -> IotaResult<Option<Object>> {
4166        self.get_object_store()
4167            .try_get_object(object_id)
4168            .map_err(Into::into)
4169    }
4170
4171    /// Non-fallible version of `try_get_object`.
4172    pub fn get_object(&self, object_id: &ObjectId) -> Option<Object> {
4173        self.try_get_object(object_id)
4174            .expect("storage access failed")
4175    }
4176
4177    pub fn get_iota_system_package_object_ref(&self) -> IotaResult<ObjectReference> {
4178        Ok(self
4179            .try_get_object(&ObjectId::SYSTEM)?
4180            .expect("system package should always exist")
4181            .object_ref())
4182    }
4183
4184    // This function is only used for testing.
4185    pub fn get_iota_system_state_object_for_testing(&self) -> IotaResult<IotaSystemState> {
4186        self.get_object_cache_reader()
4187            .try_get_iota_system_state_object_unsafe()
4188    }
4189
4190    #[instrument(level = "trace", skip_all)]
4191    pub fn get_checkpoint_by_sequence_number(
4192        &self,
4193        sequence_number: CheckpointSequenceNumber,
4194    ) -> IotaResult<Option<VerifiedCheckpoint>> {
4195        Ok(self
4196            .checkpoint_store
4197            .get_checkpoint_by_sequence_number(sequence_number)?)
4198    }
4199
4200    /// Wait until the given transactions are in a checkpoint and the RPC
4201    /// indexes include that checkpoint.
4202    ///
4203    /// Returns a mapping from transaction digest to
4204    /// `(checkpoint_sequence_number, checkpoint_timestamp_ms)`.
4205    /// On timeout, returns partial results for any transactions that were
4206    /// already checkpointed.
4207    ///
4208    /// If the timeout runs out before the indexes include a checkpointed
4209    /// transaction, the transaction is returned all the same, as it is final,
4210    /// and the wait is counted in `checkpoint_inclusion_index_wait_timeouts`.
4211    /// A caller that promises a read right after to see the transaction checks
4212    /// [`Self::is_checkpoint_indexed`] for it.
4213    ///
4214    /// The wait survives epoch boundaries: a transaction in flight at a
4215    /// boundary may only be checkpointed in the next epoch, and still resolves
4216    /// here under the original deadline.
4217    pub async fn wait_for_checkpoint_inclusion(
4218        &self,
4219        digests: &[TransactionDigest],
4220        timeout: Duration,
4221    ) -> IotaResult<BTreeMap<TransactionDigest, (CheckpointSequenceNumber, u64)>> {
4222        let deadline = tokio::time::Instant::now() + timeout;
4223        let results = self.wait_for_checkpoint_mapping(digests, deadline).await?;
4224
4225        // The index commit precedes the `highest_executed_checkpoint` bump,
4226        // in checkpoint order, so the bump means "indexed through this
4227        // checkpoint". Nodes without indexes bump too, so this cannot hang.
4228        if let Some(max_seq) = results.values().map(|(seq, _)| *seq).max() {
4229            let indexed = self
4230                .checkpoint_store
4231                .notify_read_executed_checkpoint(max_seq);
4232            let all_checkpointed = digests.iter().all(|digest| results.contains_key(digest));
4233            // A partial result already reports a timeout to the caller.
4234            if tokio::time::timeout_at(deadline, indexed).await.is_err() && all_checkpointed {
4235                self.metrics.checkpoint_inclusion_index_wait_timeouts.inc();
4236                warn!(
4237                    checkpoint_seq = max_seq,
4238                    "transactions are checkpointed but the RPC indexes have not caught up \
4239                     within the timeout; reporting them without the read-after-write guarantee"
4240                );
4241            }
4242        }
4243
4244        Ok(results)
4245    }
4246
4247    /// Whether the RPC indexes include checkpoint `seq`, so that a read sent
4248    /// now sees its transactions.
4249    pub fn is_checkpoint_indexed(&self, seq: CheckpointSequenceNumber) -> IotaResult<bool> {
4250        Ok(self
4251            .checkpoint_store
4252            .get_highest_executed_checkpoint_seq_number()?
4253            .is_some_and(|indexed| seq <= indexed))
4254    }
4255
4256    /// Wait until each of `digests` is in a checkpoint, or until `deadline`
4257    /// passes. Maps each found digest to `(checkpoint_sequence_number,
4258    /// checkpoint_timestamp_ms)`. Unlike `wait_for_checkpoint_inclusion`, this
4259    /// does not wait until the checkpoint is indexed.
4260    pub(crate) async fn wait_for_checkpoint_mapping(
4261        &self,
4262        digests: &[TransactionDigest],
4263        deadline: tokio::time::Instant,
4264    ) -> IotaResult<BTreeMap<TransactionDigest, (CheckpointSequenceNumber, u64)>> {
4265        let mut checkpoint_timestamp_cache = HashMap::<CheckpointSequenceNumber, u64>::new();
4266        let mut results = BTreeMap::new();
4267        let mut remaining = digests.to_vec();
4268        let mut epoch_store = self.load_epoch_store_one_call_per_task().clone();
4269
4270        loop {
4271            let wait = epoch_store.wait_for_transactions_in_checkpoint_with_timeout(
4272                &remaining,
4273                deadline.saturating_duration_since(tokio::time::Instant::now()),
4274                |seq| self.checkpoint_timestamp_ms_cached(seq, &mut checkpoint_timestamp_cache),
4275            );
4276            tokio::select! {
4277                wait_results = wait => {
4278                    for (digest, seq_and_ts) in remaining.iter().zip(wait_results?) {
4279                        if let Some(seq_and_ts) = seq_and_ts {
4280                            results.insert(*digest, seq_and_ts);
4281                        }
4282                    }
4283                    return Ok(results);
4284                }
4285                _ = epoch_store.wait_epoch_terminated() => {}
4286            }
4287
4288            // The epoch ended mid-wait, and this epoch store's notifications
4289            // can no longer fire: whatever is still uncheckpointed here is
4290            // checkpointed in the next epoch, on the next store. Cancelling
4291            // the wait may also have dropped notifications it had already
4292            // received, but the table write precedes each notification, so
4293            // re-reading the table recovers them.
4294            let found = match epoch_store.multi_get_transaction_checkpoint(&remaining) {
4295                Ok(found) => found,
4296                // The table handles were already released. They are released
4297                // long after the epoch's checkpoints are executed, so nothing
4298                // waited on here can still be checkpointed in the old epoch;
4299                // move on to the next store.
4300                Err(IotaError::EpochEnded(_)) => vec![None; remaining.len()],
4301                Err(err) => return Err(err),
4302            };
4303            let mut still_uncheckpointed = Vec::new();
4304            for (digest, found_seq) in remaining.iter().zip(found) {
4305                match found_seq {
4306                    Some(seq) => {
4307                        let ts = self
4308                            .checkpoint_timestamp_ms_cached(seq, &mut checkpoint_timestamp_cache);
4309                        results.insert(*digest, (seq, ts));
4310                    }
4311                    None => still_uncheckpointed.push(*digest),
4312                }
4313            }
4314            remaining = still_uncheckpointed;
4315            if remaining.is_empty() {
4316                return Ok(results);
4317            }
4318
4319            match self
4320                .wait_for_next_epoch_store(epoch_store.epoch(), deadline)
4321                .await
4322            {
4323                Some(next) => epoch_store = next,
4324                None => return Ok(results),
4325            }
4326        }
4327    }
4328
4329    /// Wait for the epoch store to be swapped to an epoch later than
4330    /// `prev_epoch`, returning `None` if `deadline` passes first.
4331    async fn wait_for_next_epoch_store(
4332        &self,
4333        prev_epoch: EpochId,
4334        deadline: tokio::time::Instant,
4335    ) -> Option<Arc<AuthorityPerEpochStore>> {
4336        // There is no notification for the epoch-store swap, and termination
4337        // and swap can come in either order (`reconfigure` terminates the old
4338        // epoch first, `reconfigure_for_testing` swaps first), so the swap is
4339        // polled at this interval.
4340        const EPOCH_STORE_SWAP_POLL_INTERVAL: Duration = Duration::from_millis(100);
4341
4342        loop {
4343            // Deliberately re-loaded on each poll; the one-call-per-task rule
4344            // guards against *unaware* mixing of epoch stores within a task.
4345            let current = self.load_epoch_store_one_call_per_task().clone();
4346            if current.epoch() > prev_epoch {
4347                return Some(current);
4348            }
4349            if tokio::time::Instant::now() >= deadline {
4350                return None;
4351            }
4352            tokio::time::sleep(EPOCH_STORE_SWAP_POLL_INTERVAL).await;
4353        }
4354    }
4355
4356    /// Resolve a checkpoint's timestamp, memoizing lookups in `cache` so
4357    /// multiple transactions in the same checkpoint trigger a single
4358    /// checkpoint summary lookup.
4359    fn checkpoint_timestamp_ms_cached(
4360        &self,
4361        seq: CheckpointSequenceNumber,
4362        cache: &mut HashMap<CheckpointSequenceNumber, u64>,
4363    ) -> u64 {
4364        *cache.entry(seq).or_insert_with(|| {
4365            self.get_checkpoint_by_sequence_number(seq)
4366                .ok()
4367                .flatten()
4368                .map(|c| c.timestamp_ms)
4369                .unwrap_or(0)
4370        })
4371    }
4372
4373    #[instrument(level = "trace", skip_all)]
4374    pub fn get_transaction_checkpoint_for_tests(
4375        &self,
4376        digest: &TransactionDigest,
4377        epoch_store: &AuthorityPerEpochStore,
4378    ) -> IotaResult<Option<VerifiedCheckpoint>> {
4379        let checkpoint = epoch_store.get_transaction_checkpoint(digest)?;
4380        let Some(checkpoint) = checkpoint else {
4381            return Ok(None);
4382        };
4383        let checkpoint = self
4384            .checkpoint_store
4385            .get_checkpoint_by_sequence_number(checkpoint)?;
4386        Ok(checkpoint)
4387    }
4388
4389    #[instrument(level = "trace", skip_all)]
4390    pub fn get_object_read(&self, object_id: &ObjectId) -> IotaResult<ObjectRead> {
4391        Ok(
4392            match self
4393                .get_object_cache_reader()
4394                .try_get_latest_object_or_tombstone(*object_id)?
4395            {
4396                Some((_, ObjectOrTombstone::Object(object))) => {
4397                    let layout = self.get_object_layout(&object)?;
4398                    ObjectRead::Exists(object.object_ref(), object, layout)
4399                }
4400                Some((_, ObjectOrTombstone::Tombstone(objref))) => ObjectRead::Deleted(objref),
4401                None => ObjectRead::NotExists(*object_id),
4402            },
4403        )
4404    }
4405
4406    /// Chain Identifier is the digest of the genesis checkpoint.
4407    pub fn get_chain_identifier(&self) -> ChainIdentifier {
4408        self.chain_identifier
4409    }
4410
4411    #[instrument(level = "trace", skip_all)]
4412    pub fn get_move_object<T>(&self, object_id: &ObjectId) -> IotaResult<T>
4413    where
4414        T: DeserializeOwned,
4415    {
4416        let o = self.get_object_read(object_id)?.into_object()?;
4417        if let Some(move_object) = o.data.as_opt_struct() {
4418            Ok(bcs::from_bytes(move_object.contents()).map_err(|e| {
4419                IotaError::ObjectDeserialization {
4420                    error: format!("{e}"),
4421                }
4422            })?)
4423        } else {
4424            Err(IotaError::ObjectDeserialization {
4425                error: format!("Provided object : [{object_id}] is not a Move object."),
4426            })
4427        }
4428    }
4429
4430    /// This function aims to serve rpc reads on past objects and
4431    /// we don't expect it to be called for other purposes.
4432    /// Depending on the object pruning policies that will be enforced in the
4433    /// future there is no software-level guarantee/SLA to retrieve an object
4434    /// with an old version even if it exists/existed.
4435    #[instrument(level = "trace", skip_all)]
4436    pub fn get_past_object_read(
4437        &self,
4438        object_id: &ObjectId,
4439        version: Version,
4440    ) -> IotaResult<PastObjectRead> {
4441        // Firstly we see if the object ever existed by getting its latest data
4442        let Some(obj_ref) = self
4443            .get_object_cache_reader()
4444            .try_get_latest_object_ref_or_tombstone(*object_id)?
4445        else {
4446            return Ok(PastObjectRead::ObjectNotExists(*object_id));
4447        };
4448
4449        if version > obj_ref.version {
4450            return Ok(PastObjectRead::VersionTooHigh {
4451                object_id: *object_id,
4452                asked_version: version,
4453                latest_version: obj_ref.version,
4454            });
4455        }
4456
4457        if version < obj_ref.version {
4458            // Read past objects
4459            return Ok(match self.read_object_at_version(object_id, version)? {
4460                Some((object, layout)) => {
4461                    let obj_ref = object.object_ref();
4462                    PastObjectRead::VersionFound(obj_ref, object, layout)
4463                }
4464
4465                None => PastObjectRead::VersionNotFound(*object_id, version),
4466            });
4467        }
4468
4469        if !obj_ref.digest.is_alive() {
4470            return Ok(PastObjectRead::ObjectDeleted(obj_ref));
4471        }
4472
4473        match self.read_object_at_version(object_id, obj_ref.version)? {
4474            Some((object, layout)) => Ok(PastObjectRead::VersionFound(obj_ref, object, layout)),
4475            None => {
4476                debug_fatal!(
4477                    "Object with in parent_entry is missing from object store, datastore is \
4478                     inconsistent",
4479                );
4480                Err(UserInputError::ObjectNotFound {
4481                    object_id: *object_id,
4482                    version: Some(obj_ref.version),
4483                }
4484                .into())
4485            }
4486        }
4487    }
4488
4489    #[instrument(level = "trace", skip_all)]
4490    fn read_object_at_version(
4491        &self,
4492        object_id: &ObjectId,
4493        version: Version,
4494    ) -> IotaResult<Option<(Object, Option<MoveStructLayout>)>> {
4495        let Some(object) =
4496            self.get_object_with_historic_fallback(&ObjectKey(*object_id, version))?
4497        else {
4498            return Ok(None);
4499        };
4500
4501        let layout = self.get_object_layout(&object)?;
4502        Ok(Some((object, layout)))
4503    }
4504
4505    /// The object at an exact version: the live table first, the buckets after
4506    /// a miss there. See [`HistoricObjects::fill_missing`] for when a read may
4507    /// do this.
4508    pub(crate) fn get_object_with_historic_fallback(
4509        &self,
4510        key: &ObjectKey,
4511    ) -> IotaResult<Option<Object>> {
4512        match self
4513            .get_object_cache_reader()
4514            .try_get_object_by_key(&key.0, key.1)?
4515        {
4516            Some(object) => Ok(Some(object)),
4517            None => self.historic_objects.get(key),
4518        }
4519    }
4520
4521    /// The object store for reads that resolve index rows: the row's version
4522    /// leaves the live table when its checkpoint's outputs commit, which is
4523    /// before the index update that replaces the row.
4524    fn object_store_with_historic_fallback(&self) -> ObjectStoreWithHistoricFallback<'_> {
4525        ObjectStoreWithHistoricFallback(self)
4526    }
4527
4528    /// The layout of `object`'s Move struct, `None` for a package.
4529    pub fn get_object_layout(&self, object: &Object) -> IotaResult<Option<MoveStructLayout>> {
4530        let layout = object
4531            .data
4532            .as_opt_struct()
4533            .map(|object| {
4534                into_struct_layout(
4535                    self.load_epoch_store_one_call_per_task()
4536                        .executor()
4537                        // TODO(cache) - must read through cache
4538                        .type_layout_resolver(Box::new(self.get_backing_package_store().as_ref()))
4539                        .get_annotated_layout(object.struct_tag())?,
4540                )
4541            })
4542            .transpose()?;
4543        Ok(layout)
4544    }
4545
4546    /// One page of `owner`'s objects; see
4547    /// [`RpcIndexesStore::get_owner_objects`].
4548    #[instrument(level = "trace", skip_all)]
4549    pub fn get_owner_objects(
4550        &self,
4551        owner: Address,
4552        // If `Some`, the query will start from the next item after the specified cursor
4553        cursor: Option<&OwnedObjectCursor>,
4554        limit: usize,
4555        filter: Option<IotaObjectDataFilter>,
4556        max_read: usize,
4557    ) -> IotaResult<OwnedObjectsPage> {
4558        let indexes = self.require_jsonrpc_indexes()?;
4559        indexes.get_owner_objects(
4560            owner,
4561            cursor,
4562            limit,
4563            filter,
4564            max_read,
4565            &self.object_store_with_historic_fallback(),
4566        )
4567    }
4568
4569    /// One page of `owner`'s coins in the owner index's order, of
4570    /// `coin_type` alone when it is given. The returned type tag is the
4571    /// coin's own `T`, not the `Coin<T>` the object carries.
4572    #[instrument(level = "trace", skip_all)]
4573    pub fn get_owned_coins_page(
4574        &self,
4575        owner: Address,
4576        // If `Some`, the query will start from the next item after the specified cursor
4577        cursor: Option<&OwnedObjectCursor>,
4578        coin_type: Option<TypeTag>,
4579        limit: usize,
4580    ) -> IotaResult<Vec<(TypeTag, ObjectId, CoinInfo, OwnedObjectCursor)>> {
4581        let indexes = self.require_jsonrpc_indexes()?;
4582        indexes.get_owned_coins(
4583            owner,
4584            cursor,
4585            coin_type,
4586            limit,
4587            &self.object_store_with_historic_fallback(),
4588        )
4589    }
4590
4591    /// The cursors of `owner`'s next rows of `Coin<coin_type>`; see
4592    /// [`RpcIndexesStore::owned_coin_rows`].
4593    #[instrument(level = "trace", skip_all)]
4594    pub fn owned_coin_rows(
4595        &self,
4596        owner: Address,
4597        cursor: Option<&OwnedObjectCursor>,
4598        coin_type: TypeTag,
4599        limit: usize,
4600    ) -> IotaResult<Vec<OwnedObjectCursor>> {
4601        self.require_jsonrpc_indexes()?
4602            .owned_coin_rows(owner, cursor, coin_type, limit)
4603    }
4604
4605    #[instrument(level = "trace", skip_all)]
4606    pub fn get_move_objects<T>(&self, owner: Address, tag: StructTag) -> IotaResult<Vec<T>>
4607    where
4608        T: DeserializeOwned,
4609    {
4610        let indexes = self.require_jsonrpc_indexes()?;
4611        // The filter matches the type's identifier only, so the exact type is
4612        // checked per row.
4613        let object_ids = indexes
4614            .owner_iter(owner, None, OwnerTypeFilter::from_struct_tag(Some(&tag)))?
4615            .filter_ok(|(_, info)| info.object_type == tag)
4616            .map_ok(|(key, info)| ObjectKey(key.object_id, info.version))
4617            .collect::<Result<Vec<_>, _>>()?;
4618        let mut move_objects = vec![];
4619
4620        let objects = self
4621            .object_store_with_historic_fallback()
4622            .try_multi_get_objects_by_key(&object_ids)?;
4623
4624        for (o, id) in objects.into_iter().zip(object_ids) {
4625            let object = o.ok_or_else(|| {
4626                IotaError::from(UserInputError::ObjectNotFound {
4627                    object_id: id.0,
4628                    version: Some(id.1),
4629                })
4630            })?;
4631            let move_object = object.data.as_opt_struct().ok_or_else(|| {
4632                IotaError::from(UserInputError::MovePackageAsObject { object_id: id.0 })
4633            })?;
4634            move_objects.push(bcs::from_bytes(move_object.contents()).map_err(|e| {
4635                IotaError::ObjectDeserialization {
4636                    error: format!("{e}"),
4637                }
4638            })?);
4639        }
4640        Ok(move_objects)
4641    }
4642
4643    /// Returns one entry per index row, in index order, for at most `limit`
4644    /// rows. A `None` info marks a field that no longer resolves, so callers
4645    /// can derive pagination cursors from the returned ids alone.
4646    #[instrument(level = "trace", skip_all)]
4647    pub fn get_dynamic_fields(
4648        &self,
4649        owner: ObjectId,
4650        // If `Some`, the query will start from the next item after the specified cursor
4651        cursor: Option<ObjectId>,
4652        limit: usize,
4653    ) -> IotaResult<Vec<(ObjectId, Option<DynamicFieldInfo>)>> {
4654        let indexes = self.require_jsonrpc_indexes()?;
4655        let epoch_store = self.load_epoch_store_one_call_per_task();
4656        let mut base_resolver = epoch_store
4657            .executor()
4658            .type_layout_resolver(Box::new(self.get_backing_package_store().clone()));
4659        // One layout per distinct field type for the whole page.
4660        let mut layout_resolver = CachingLayoutResolver::new(base_resolver.as_mut());
4661        let object_store = self.get_object_store();
4662
4663        let mut fields = Vec::new();
4664        for field_id in indexes
4665            .get_dynamic_field_ids_iterator(owner, cursor)?
4666            .take(limit)
4667        {
4668            let field_id = field_id?;
4669            let Some(field_object) = object_store.try_get_object(&field_id)? else {
4670                fields.push((field_id, None));
4671                continue;
4672            };
4673            match try_create_dynamic_field_info(
4674                &field_object,
4675                object_store.as_ref(),
4676                &mut layout_resolver,
4677            ) {
4678                Ok(info) => fields.push((field_id, info)),
4679                Err(e) => {
4680                    warn!(?field_id, "failed to resolve dynamic field: {e}");
4681                    fields.push((field_id, None));
4682                }
4683            }
4684        }
4685        Ok(fields)
4686    }
4687
4688    #[instrument(level = "trace", skip_all)]
4689    /// The objects of `owner`'s first `limit` dynamic fields, in the order
4690    /// [`Self::get_dynamic_fields`] lists them; `None` for a field whose
4691    /// object is gone.
4692    pub fn get_dynamic_field_objects(
4693        &self,
4694        owner: ObjectId,
4695        limit: usize,
4696    ) -> IotaResult<Vec<(ObjectId, Option<Object>)>> {
4697        let indexes = self.require_jsonrpc_indexes()?;
4698        let object_store = self.get_object_store();
4699        indexes
4700            .get_dynamic_field_ids_iterator(owner, None)?
4701            .take(limit)
4702            .map(|field_id| {
4703                let field_id = field_id?;
4704                Ok((field_id, object_store.try_get_object(&field_id)?))
4705            })
4706            .collect()
4707    }
4708
4709    /// The id of the object `get_dynamic_field_object` returns.
4710    pub fn get_dynamic_field_object_id(
4711        &self,
4712        owner: ObjectId,
4713        name_type: TypeTag,
4714        name_bcs_bytes: &[u8],
4715    ) -> IotaResult<Option<ObjectId>> {
4716        Ok(self
4717            .get_dynamic_field_object(owner, name_type, name_bcs_bytes)?
4718            .map(|object| object.id()))
4719    }
4720
4721    /// The object of `owner`'s dynamic field named `name_type` and
4722    /// `name_bcs_bytes`: the value object for a dynamic object field, the
4723    /// `Field` object otherwise; `None` when there is no such field.
4724    pub fn get_dynamic_field_object(
4725        &self,
4726        owner: ObjectId,
4727        name_type: TypeTag,
4728        name_bcs_bytes: &[u8],
4729    ) -> IotaResult<Option<Object>> {
4730        let derive = |name_type: &TypeTag| {
4731            dynamic_field::derive_dynamic_field_id(owner, name_type, name_bcs_bytes).map_err(|e| {
4732                IotaError::Unknown(format!(
4733                    "Unable to generate dynamic field id. Got error: {e:?}"
4734                ))
4735            })
4736        };
4737        let object_store = self.get_object_store();
4738
4739        // A field's id is derived from its parent and name, so the object
4740        // store alone says whether it exists, as soon as the transaction that
4741        // created it has executed.
4742        if let Some(field) = object_store.try_get_object(&derive(&name_type)?)? {
4743            let wrapped_name = matches!(
4744                &name_type,
4745                TypeTag::Struct(tag) if DynamicFieldInfo::is_dynamic_object_field_wrapper(tag)
4746            );
4747            if !wrapped_name {
4748                return Ok(Some(field));
4749            }
4750            // An already-wrapped name type addresses a dynamic object field
4751            // directly.
4752            return self.dynamic_field_value(field);
4753        }
4754
4755        // A dynamic object field is stored under its `Field` wrapper, which
4756        // holds the id of the value object the caller is after.
4757        let wrapper_type = TypeTag::Struct(Box::new(
4758            DynamicFieldInfo::dynamic_object_field_wrapper(name_type),
4759        ));
4760        match object_store.try_get_object(&derive(&wrapper_type)?)? {
4761            Some(wrapper) => self.dynamic_field_value(wrapper),
4762            None => Ok(None),
4763        }
4764    }
4765
4766    /// The object a dynamic-field lookup resolves `field` to: the value
4767    /// object for a dynamic object field, `field` itself otherwise, or `None`
4768    /// when the field no longer resolves.
4769    fn dynamic_field_value(&self, field: Object) -> IotaResult<Option<Object>> {
4770        let epoch_store = self.load_epoch_store_one_call_per_task();
4771        let mut layout_resolver = epoch_store
4772            .executor()
4773            .type_layout_resolver(Box::new(self.get_backing_package_store().clone()));
4774        let Some(info) = try_create_dynamic_field_info(
4775            &field,
4776            self.get_object_store().as_ref(),
4777            layout_resolver.as_mut(),
4778        )?
4779        else {
4780            return Ok(None);
4781        };
4782        if info.object_id == field.id() {
4783            return Ok(Some(field));
4784        }
4785        Ok(self.get_object_store().try_get_object(&info.object_id)?)
4786    }
4787
4788    #[instrument(level = "trace", skip_all)]
4789    pub fn get_total_transaction_blocks(&self) -> IotaResult<u64> {
4790        Ok(self.get_indexes()?.next_sequence_number())
4791    }
4792
4793    #[instrument(level = "trace", skip_all)]
4794    pub async fn get_executed_transaction_and_effects(
4795        &self,
4796        digest: TransactionDigest,
4797        kv_store: Arc<TransactionKeyValueStore>,
4798    ) -> IotaResult<(TransactionEnvelope, TransactionEffects)> {
4799        let transaction = kv_store.get_tx(digest).await?;
4800        let effects = kv_store.get_fx_by_tx_digest(digest).await?;
4801        Ok((transaction, effects))
4802    }
4803
4804    #[instrument(level = "trace", skip_all)]
4805    pub fn multi_get_checkpoint_by_sequence_number(
4806        &self,
4807        sequence_numbers: &[CheckpointSequenceNumber],
4808    ) -> IotaResult<Vec<Option<VerifiedCheckpoint>>> {
4809        Ok(self
4810            .checkpoint_store
4811            .multi_get_checkpoint_by_sequence_number(sequence_numbers)?)
4812    }
4813
4814    #[instrument(level = "trace", skip_all)]
4815    pub fn get_transaction_events(
4816        &self,
4817        digest: &TransactionDigest,
4818    ) -> IotaResult<TransactionEvents> {
4819        self.get_transaction_cache_reader()
4820            .try_get_events(digest)?
4821            .ok_or(IotaError::TransactionEventsNotFound { digest: *digest })
4822    }
4823
4824    /// The transaction's input objects, reaching the historic buckets for
4825    /// versions the live table no longer holds. Use for assembling responses
4826    /// only — see [`HistoricObjects::fill_missing`].
4827    pub fn get_transaction_input_objects(
4828        &self,
4829        effects: &TransactionEffects,
4830    ) -> anyhow::Result<Vec<Object>> {
4831        historic_objects::get_transaction_input_objects(
4832            self.get_object_store().as_ref(),
4833            &self.historic_objects,
4834            effects,
4835        )
4836        .map_err(Into::into)
4837    }
4838
4839    /// The transaction's output objects, reaching the historic buckets for
4840    /// versions the live table no longer holds. Use for assembling responses
4841    /// only — see [`HistoricObjects::fill_missing`].
4842    pub fn get_transaction_output_objects(
4843        &self,
4844        effects: &TransactionEffects,
4845    ) -> anyhow::Result<Vec<Object>> {
4846        historic_objects::get_transaction_output_objects(
4847            self.get_object_store().as_ref(),
4848            &self.historic_objects,
4849            effects,
4850        )
4851        .map_err(Into::into)
4852    }
4853
4854    fn get_indexes(&self) -> IotaResult<Arc<RpcIndexesStore>> {
4855        match self.jsonrpc_indexes() {
4856            Some(i) => Ok(i.clone()),
4857            None => Err(IotaError::UnsupportedFeature {
4858                error: "extended object indexing is not enabled on this server".into(),
4859            }),
4860        }
4861    }
4862
4863    /// The index store, `None` unless this node maintains the JSON-RPC group.
4864    fn jsonrpc_indexes(&self) -> Option<&Arc<RpcIndexesStore>> {
4865        self.rpc_indexes_store
4866            .as_ref()
4867            .filter(|store| store.serves(IndexGroup::JsonRpc))
4868    }
4869
4870    /// [`Self::jsonrpc_indexes`] for the reads that cannot be served without
4871    /// it.
4872    fn require_jsonrpc_indexes(&self) -> IotaResult<&Arc<RpcIndexesStore>> {
4873        self.jsonrpc_indexes()
4874            .ok_or(IotaError::IndexStoreNotAvailable)
4875    }
4876
4877    pub async fn get_transactions_for_tests(
4878        self: &Arc<Self>,
4879        filter: Option<TransactionFilter>,
4880        cursor: Option<TransactionDigest>,
4881        limit: Option<usize>,
4882        reverse: bool,
4883    ) -> IotaResult<Vec<TransactionDigest>> {
4884        let metrics = KeyValueStoreMetrics::new_for_tests();
4885        let kv_store = Arc::new(TransactionKeyValueStore::new(
4886            "rocksdb",
4887            metrics,
4888            self.clone(),
4889        ));
4890        self.get_transactions(&kv_store, filter, cursor, limit, reverse)
4891            .await
4892    }
4893
4894    #[instrument(level = "trace", skip_all)]
4895    pub async fn get_transactions(
4896        &self,
4897        kv_store: &Arc<TransactionKeyValueStore>,
4898        filter: Option<TransactionFilter>,
4899        // If `Some`, the query will start from the next item after the specified cursor
4900        cursor: Option<TransactionDigest>,
4901        limit: Option<usize>,
4902        reverse: bool,
4903    ) -> IotaResult<Vec<TransactionDigest>> {
4904        if let Some(TransactionFilter::Checkpoint(sequence_number)) = filter {
4905            let checkpoint_contents = kv_store.get_checkpoint_contents(sequence_number).await?;
4906            let iter = checkpoint_contents.iter().map(|c| c.transaction);
4907            if reverse {
4908                let iter = iter
4909                    .rev()
4910                    .skip_while(|d| cursor.is_some() && Some(*d) != cursor)
4911                    .skip(usize::from(cursor.is_some()));
4912                return Ok(iter.take(limit.unwrap_or(usize::MAX)).collect());
4913            } else {
4914                let iter = iter
4915                    .skip_while(|d| cursor.is_some() && Some(*d) != cursor)
4916                    .skip(usize::from(cursor.is_some()));
4917                return Ok(iter.take(limit.unwrap_or(usize::MAX)).collect());
4918            }
4919        }
4920        self.get_indexes()?
4921            .get_transactions(filter, cursor, limit, reverse)
4922    }
4923
4924    pub fn get_checkpoint_store(&self) -> &Arc<CheckpointStore> {
4925        &self.checkpoint_store
4926    }
4927
4928    /// Keeps the object versions that transactions in the highest executed
4929    /// checkpoint, and in every later one, supersede readable until the
4930    /// returned guard is dropped. Take it before submitting a transaction whose
4931    /// input or output objects are read from the store once it is
4932    /// checkpointed.
4933    pub fn retain_objects(&self) -> ObjectRetentionGuard {
4934        self.object_retention.retain()
4935    }
4936
4937    /// Records `executed_seq` as the highest executed checkpoint, which new
4938    /// [`Self::retain_objects`] guards start from. Call it once the
4939    /// checkpoint's outputs are readable.
4940    pub(crate) fn record_executed_for_object_retention(
4941        &self,
4942        executed_seq: CheckpointSequenceNumber,
4943    ) {
4944        self.object_retention.record_executed(executed_seq);
4945    }
4946
4947    pub fn get_latest_checkpoint_sequence_number(&self) -> IotaResult<CheckpointSequenceNumber> {
4948        self.get_checkpoint_store()
4949            .get_highest_executed_checkpoint_seq_number()?
4950            .ok_or(IotaError::UserInput {
4951                error: UserInputError::LatestCheckpointSequenceNumberNotFound,
4952            })
4953    }
4954
4955    #[instrument(level = "trace", skip_all)]
4956    pub fn get_checkpoint_summary_by_sequence_number(
4957        &self,
4958        sequence_number: CheckpointSequenceNumber,
4959    ) -> IotaResult<CheckpointSummary> {
4960        let verified_checkpoint = self
4961            .get_checkpoint_store()
4962            .get_checkpoint_by_sequence_number(sequence_number)?;
4963        match verified_checkpoint {
4964            Some(verified_checkpoint) => Ok(verified_checkpoint.into_inner().into_data()),
4965            None => Err(IotaError::UserInput {
4966                error: UserInputError::VerifiedCheckpointNotFound(sequence_number),
4967            }),
4968        }
4969    }
4970
4971    #[instrument(level = "trace", skip_all)]
4972    pub fn get_checkpoint_summary_by_digest(
4973        &self,
4974        digest: CheckpointDigest,
4975    ) -> IotaResult<CheckpointSummary> {
4976        let verified_checkpoint = self
4977            .get_checkpoint_store()
4978            .get_checkpoint_by_digest(&digest)?;
4979        match verified_checkpoint {
4980            Some(verified_checkpoint) => Ok(verified_checkpoint.into_inner().into_data()),
4981            None => Err(IotaError::UserInput {
4982                error: UserInputError::VerifiedCheckpointDigestNotFound(Base58::encode(digest)),
4983            }),
4984        }
4985    }
4986
4987    #[instrument(level = "trace", skip_all)]
4988    pub fn find_publish_txn_digest(&self, package_id: ObjectId) -> IotaResult<TransactionDigest> {
4989        if package_id.is_system_package() {
4990            return self.find_genesis_txn_digest();
4991        }
4992        Ok(self
4993            .get_object_read(&package_id)?
4994            .into_object()?
4995            .previous_transaction)
4996    }
4997
4998    #[instrument(level = "trace", skip_all)]
4999    pub fn find_genesis_txn_digest(&self) -> IotaResult<TransactionDigest> {
5000        let summary = self
5001            .get_verified_checkpoint_by_sequence_number(0)?
5002            .into_message();
5003        let content = self.get_checkpoint_contents(summary.contents_digest)?;
5004        let genesis_transaction = content.enumerate_transactions(&summary).next();
5005        Ok(genesis_transaction
5006            .ok_or(IotaError::UserInput {
5007                error: UserInputError::GenesisTransactionNotFound,
5008            })?
5009            .1
5010            .transaction)
5011    }
5012
5013    #[instrument(level = "trace", skip_all)]
5014    pub fn get_verified_checkpoint_by_sequence_number(
5015        &self,
5016        sequence_number: CheckpointSequenceNumber,
5017    ) -> IotaResult<VerifiedCheckpoint> {
5018        let verified_checkpoint = self
5019            .get_checkpoint_store()
5020            .get_checkpoint_by_sequence_number(sequence_number)?;
5021        match verified_checkpoint {
5022            Some(verified_checkpoint) => Ok(verified_checkpoint),
5023            None => Err(IotaError::UserInput {
5024                error: UserInputError::VerifiedCheckpointNotFound(sequence_number),
5025            }),
5026        }
5027    }
5028
5029    #[instrument(level = "trace", skip_all)]
5030    pub fn get_verified_checkpoint_summary_by_digest(
5031        &self,
5032        digest: CheckpointDigest,
5033    ) -> IotaResult<VerifiedCheckpoint> {
5034        let verified_checkpoint = self
5035            .get_checkpoint_store()
5036            .get_checkpoint_by_digest(&digest)?;
5037        match verified_checkpoint {
5038            Some(verified_checkpoint) => Ok(verified_checkpoint),
5039            None => Err(IotaError::UserInput {
5040                error: UserInputError::VerifiedCheckpointDigestNotFound(Base58::encode(digest)),
5041            }),
5042        }
5043    }
5044
5045    #[instrument(level = "trace", skip_all)]
5046    pub fn get_checkpoint_contents(
5047        &self,
5048        digest: CheckpointContentsDigest,
5049    ) -> IotaResult<CheckpointContents> {
5050        self.get_checkpoint_store()
5051            .get_checkpoint_contents(&digest)?
5052            .ok_or(IotaError::UserInput {
5053                error: UserInputError::CheckpointContentsNotFound(digest),
5054            })
5055    }
5056
5057    #[instrument(level = "trace", skip_all)]
5058    pub fn get_checkpoint_contents_by_sequence_number(
5059        &self,
5060        sequence_number: CheckpointSequenceNumber,
5061    ) -> IotaResult<CheckpointContents> {
5062        let verified_checkpoint = self
5063            .get_checkpoint_store()
5064            .get_checkpoint_by_sequence_number(sequence_number)?;
5065        match verified_checkpoint {
5066            Some(verified_checkpoint) => {
5067                let contents_digest = verified_checkpoint.into_inner().contents_digest;
5068                self.get_checkpoint_contents(contents_digest)
5069            }
5070            None => Err(IotaError::UserInput {
5071                error: UserInputError::VerifiedCheckpointNotFound(sequence_number),
5072            }),
5073        }
5074    }
5075
5076    #[instrument(level = "trace", skip_all)]
5077    pub async fn query_events(
5078        &self,
5079        kv_store: &Arc<TransactionKeyValueStore>,
5080        query: EventFilter,
5081        // If `Some`, the query will start from the next item after the specified cursor
5082        cursor: Option<EventID>,
5083        limit: usize,
5084        descending: bool,
5085    ) -> IotaResult<Vec<IotaEvent>> {
5086        let stored_events = match query {
5087            // A transaction's own events answer this as soon as it has
5088            // executed, without waiting for its checkpoint to be indexed.
5089            EventFilter::Transaction(digest) => {
5090                Self::transaction_events_page(kv_store, digest, cursor, limit, descending).await?
5091            }
5092            query => {
5093                self.indexed_events_page(kv_store, query, cursor, limit, descending)
5094                    .await?
5095            }
5096        };
5097
5098        let epoch_store = self.load_epoch_store_one_call_per_task();
5099        let backing_store = self.get_backing_package_store().as_ref();
5100        let mut layout_resolver = epoch_store
5101            .executor()
5102            .type_layout_resolver(Box::new(backing_store));
5103        let mut events = vec![];
5104        for (e, tx_digest, event_seq, timestamp) in stored_events.into_iter() {
5105            events.push(IotaEvent::try_from(
5106                e.clone(),
5107                tx_digest,
5108                event_seq as u64,
5109                timestamp,
5110                layout_resolver.get_annotated_layout(&e.struct_tag)?,
5111            )?)
5112        }
5113        Ok(events)
5114    }
5115
5116    /// The page of events matching `query` after `cursor`, from the RPC
5117    /// index; at most `limit`.
5118    async fn indexed_events_page(
5119        &self,
5120        kv_store: &Arc<TransactionKeyValueStore>,
5121        query: EventFilter,
5122        cursor: Option<EventID>,
5123        limit: usize,
5124        descending: bool,
5125    ) -> IotaResult<Vec<(Event, TransactionDigest, usize, Option<u64>)>> {
5126        let index_store = self.get_indexes()?;
5127
5128        // Get the tx_num from tx_digest
5129        let (tx_num, event_num) = if let Some(cursor) = cursor.as_ref() {
5130            let tx_seq = index_store.lookup_digest(&cursor.tx_digest)?.ok_or(
5131                IotaError::TransactionNotFound {
5132                    digest: cursor.tx_digest,
5133                },
5134            )?;
5135            let event = (tx_seq, cursor.event_seq as usize);
5136            // The page below drops its first row as the cursor's own, which is
5137            // only right for an event the index holds.
5138            if index_store.event_timestamp(event)?.is_none() {
5139                return Err(IotaError::TransactionEventsNotFound {
5140                    digest: cursor.tx_digest,
5141                });
5142            }
5143            event
5144        } else if descending {
5145            (u64::MAX, usize::MAX)
5146        } else {
5147            (0, 0)
5148        };
5149
5150        let limit = limit + 1;
5151        let mut event_keys = match query {
5152            EventFilter::All(filters) => {
5153                if filters.is_empty() {
5154                    index_store.all_events(tx_num, event_num, limit, descending)?
5155                } else {
5156                    return Err(IotaError::UserInput {
5157                        error: UserInputError::Unsupported(
5158                            "This query type does not currently support filter combinations"
5159                                .to_string(),
5160                        ),
5161                    });
5162                }
5163            }
5164            EventFilter::MoveModule { package, module } => {
5165                let module_id = ModuleId::new(
5166                    AccountAddress::new(package.into_bytes()),
5167                    move_core_types::identifier::Identifier::new(module.as_str()).unwrap(),
5168                );
5169                index_store.events_by_module_id(&module_id, tx_num, event_num, limit, descending)?
5170            }
5171            EventFilter::MoveEventType(struct_name) => index_store
5172                .events_by_move_event_struct_name(
5173                    &struct_name,
5174                    tx_num,
5175                    event_num,
5176                    limit,
5177                    descending,
5178                )?,
5179            EventFilter::Sender(sender) => {
5180                index_store.events_by_sender(&sender, tx_num, event_num, limit, descending)?
5181            }
5182            EventFilter::TimeRange {
5183                start_time,
5184                end_time,
5185            } => index_store.event_iterator(
5186                start_time,
5187                end_time,
5188                cursor.is_some().then_some((tx_num, event_num)),
5189                limit,
5190                descending,
5191            )?,
5192            EventFilter::MoveEventModule { package, module } => index_store
5193                .events_by_move_event_module(
5194                    &ModuleId::new(
5195                        AccountAddress::new(package.into_bytes()),
5196                        move_core_types::identifier::Identifier::new(module.as_str()).unwrap(),
5197                    ),
5198                    tx_num,
5199                    event_num,
5200                    limit,
5201                    descending,
5202                )?,
5203            // not using "_ =>" because we want to make sure we remember to add new variants here
5204            // Answered by `query_events` from the transaction's own events.
5205            EventFilter::Transaction(_)
5206            | EventFilter::Package(_)
5207            | EventFilter::MoveEventField { .. }
5208            | EventFilter::Any(_)
5209            | EventFilter::And(_, _)
5210            | EventFilter::Or(_, _) => {
5211                return Err(IotaError::UserInput {
5212                    error: UserInputError::Unsupported(
5213                        "This query type is not supported by the full node.".to_string(),
5214                    ),
5215                });
5216            }
5217        };
5218
5219        // skip one event if exclusive cursor is provided,
5220        // otherwise truncate to the original limit.
5221        if cursor.is_some() {
5222            if !event_keys.is_empty() {
5223                event_keys.remove(0);
5224            }
5225        } else {
5226            event_keys.truncate(limit - 1);
5227        }
5228
5229        // get the unique set of digests from the event_keys
5230        let transaction_digests = event_keys
5231            .iter()
5232            .map(|(_, digest, _, _)| *digest)
5233            .collect::<HashSet<_>>()
5234            .into_iter()
5235            .collect::<Vec<_>>();
5236
5237        let events = kv_store
5238            .multi_get_events_by_tx_digests(&transaction_digests)
5239            .await?;
5240
5241        let events_map: HashMap<_, _> = transaction_digests.iter().zip(events).collect();
5242
5243        event_keys
5244            .into_iter()
5245            .map(|k| {
5246                (
5247                    k,
5248                    events_map
5249                        .get(&k.1)
5250                        .expect("fetched digest is missing")
5251                        .clone()
5252                        .and_then(|e| e.get(k.2).cloned()),
5253                )
5254            })
5255            .map(
5256                |((_event_digest, tx_digest, event_seq, timestamp), event)| {
5257                    event
5258                        .map(|e| (e, tx_digest, event_seq, Some(timestamp)))
5259                        .ok_or(IotaError::TransactionEventsNotFound { digest: tx_digest })
5260                },
5261            )
5262            .collect::<Result<Vec<_>, _>>()
5263    }
5264
5265    /// The page of `digest`'s events after `cursor`, which must name one of
5266    /// them, read from the transaction's stored events; at most `limit`.
5267    async fn transaction_events_page(
5268        kv_store: &Arc<TransactionKeyValueStore>,
5269        digest: TransactionDigest,
5270        cursor: Option<EventID>,
5271        limit: usize,
5272        descending: bool,
5273    ) -> IotaResult<Vec<(Event, TransactionDigest, usize, Option<u64>)>> {
5274        let effects = kv_store.get_fx_by_tx_digest(digest).await?;
5275        let events = match effects.events_digest() {
5276            None => Vec::new(),
5277            Some(_) => {
5278                kv_store
5279                    .multi_get_events_by_tx_digests(&[digest])
5280                    .await?
5281                    .into_iter()
5282                    .next()
5283                    .flatten()
5284                    .ok_or(IotaError::TransactionEventsNotFound { digest })?
5285                    .0
5286            }
5287        };
5288        let after = match cursor {
5289            None => None,
5290            Some(cursor) if cursor.tx_digest != digest => {
5291                return Err(IotaError::UserInput {
5292                    error: UserInputError::Unsupported(
5293                        "the cursor must name an event of the transaction the filter names"
5294                            .to_string(),
5295                    ),
5296                });
5297            }
5298            Some(cursor) if cursor.event_seq as usize >= events.len() => {
5299                return Err(IotaError::TransactionEventsNotFound { digest });
5300            }
5301            Some(cursor) => Some(cursor.event_seq as usize),
5302        };
5303        let page: Vec<usize> = if descending {
5304            (0..after.unwrap_or(events.len()))
5305                .rev()
5306                .take(limit)
5307                .collect()
5308        } else {
5309            (after.map_or(0, |seq| seq + 1)..events.len())
5310                .take(limit)
5311                .collect()
5312        };
5313        if page.is_empty() {
5314            return Ok(Vec::new());
5315        }
5316        // The checkpoint's time, as the index records it; none before the
5317        // transaction is in a checkpoint.
5318        let timestamp = match kv_store
5319            .get_transaction_perpetual_checkpoint(digest)
5320            .await?
5321        {
5322            Some(checkpoint) => Some(
5323                kv_store
5324                    .get_checkpoint_summary(checkpoint)
5325                    .await?
5326                    .timestamp_ms,
5327            ),
5328            None => None,
5329        };
5330        Ok(page
5331            .into_iter()
5332            .map(|seq| (events[seq].clone(), digest, seq, timestamp))
5333            .collect())
5334    }
5335
5336    pub fn insert_genesis_object(&self, object: Object) {
5337        self.get_reconfig_api()
5338            .try_insert_genesis_object(object)
5339            .expect("Cannot insert genesis object")
5340    }
5341
5342    pub fn insert_genesis_objects(&self, objects: &[Object]) {
5343        for o in objects {
5344            self.insert_genesis_object(o.clone());
5345        }
5346    }
5347
5348    /// Make a status response for a transaction
5349    #[instrument(level = "trace", skip_all)]
5350    pub fn get_transaction_status(
5351        &self,
5352        transaction_digest: &TransactionDigest,
5353        epoch_store: &Arc<AuthorityPerEpochStore>,
5354    ) -> IotaResult<Option<(SenderSignedTransaction, TransactionStatus)>> {
5355        // TODO: In the case of read path, we should not have to re-sign the effects.
5356        if let Some(effects) =
5357            self.get_signed_effects_and_maybe_resign(transaction_digest, epoch_store)?
5358        {
5359            if let Some(transaction) = self
5360                .get_transaction_cache_reader()
5361                .try_get_transaction_block(transaction_digest)?
5362            {
5363                let cert_sig = epoch_store.get_transaction_cert_sig(transaction_digest)?;
5364                let events = if effects.events_digest().is_some() {
5365                    self.get_transaction_events(effects.transaction_digest())?
5366                } else {
5367                    TransactionEvents::default()
5368                };
5369                return Ok(Some((
5370                    (*transaction).clone().into_message(),
5371                    TransactionStatus::Executed(cert_sig, effects.into_inner(), events),
5372                )));
5373            } else {
5374                // The read of effects and read of transaction are not atomic. It's possible
5375                // that we reverted the transaction (during epoch change) in
5376                // between the above two reads, and we end up having effects but
5377                // not transaction. In this case, we just fall through.
5378                debug!(tx_digest=?transaction_digest, "Signed effects exist but no transaction found");
5379            }
5380        }
5381        if let Some(signed) = epoch_store.get_signed_transaction(transaction_digest)? {
5382            self.metrics.tx_already_processed.inc();
5383            let (transaction, sig) = signed.into_inner().into_data_and_sig();
5384            Ok(Some((transaction, TransactionStatus::Signed(sig))))
5385        } else {
5386            Ok(None)
5387        }
5388    }
5389
5390    /// Get the signed effects of the given transaction. If the effects was
5391    /// signed in a previous epoch, re-sign it so that the caller is able to
5392    /// form a cert of the effects in the current epoch.
5393    #[instrument(level = "trace", skip_all)]
5394    pub fn get_signed_effects_and_maybe_resign(
5395        &self,
5396        transaction_digest: &TransactionDigest,
5397        epoch_store: &Arc<AuthorityPerEpochStore>,
5398    ) -> IotaResult<Option<VerifiedSignedTransactionEffects>> {
5399        let effects = self
5400            .get_transaction_cache_reader()
5401            .try_get_executed_effects(transaction_digest)?;
5402        match effects {
5403            Some(effects) => {
5404                // If the transaction was executed in previous epochs, the validator will
5405                // re-sign the effects with new current epoch so that a client is always able to
5406                // obtain an effects certificate at the current epoch.
5407                //
5408                // Why is this necessary? Consider the following case:
5409                // - assume there are 4 validators
5410                // - Quorum driver gets 2 signed effects before reconfig halt
5411                // - The tx makes it into final checkpoint.
5412                // - 2 validators go away and are replaced in the new epoch.
5413                // - The new epoch begins.
5414                // - The quorum driver cannot complete the partial effects cert from the previous
5415                //   epoch, because it may not be able to reach either of the 2 former validators.
5416                // - But, if the 2 validators that stayed are willing to re-sign the effects in the
5417                //   new epoch, the QD can make a new effects cert and return it to the client.
5418                //
5419                // This is a considered a short-term workaround. Eventually, Quorum Driver
5420                // should be able to return either an effects certificate, -or-
5421                // a proof of inclusion in a checkpoint. In the case above, the
5422                // Quorum Driver would return a proof of inclusion in the final
5423                // checkpoint, and this code would no longer be necessary.
5424                if effects.epoch() != epoch_store.epoch() {
5425                    debug!(
5426                        tx_digest=?transaction_digest,
5427                        effects_epoch=?effects.epoch(),
5428                        epoch=?epoch_store.epoch(),
5429                        "Re-signing the effects with the current epoch"
5430                    );
5431                }
5432                Ok(Some(self.sign_effects(effects, epoch_store)?))
5433            }
5434            None => Ok(None),
5435        }
5436    }
5437
5438    /// A client aggregating effects signatures towards a quorum assumes
5439    /// finality once it collects 2f+1 of them, so within an epoch this
5440    /// validator must never assert two different effects for the same
5441    /// transaction on any RPC surface, signed or unsigned. Executed effects
5442    /// can change across a restart if an uncommitted transaction is
5443    /// re-executed with divergent results (e.g. by a new binary), so every
5444    /// effects-reporting path calls this before returning effects, and
5445    /// refuses to contradict a signature that may already be in a client's
5446    /// hands.
5447    pub fn check_effects_against_previously_signed(
5448        &self,
5449        epoch_store: &AuthorityPerEpochStore,
5450        tx_digest: &TransactionDigest,
5451        effects_digest: &TransactionEffectsDigest,
5452        surface: &'static str,
5453    ) -> IotaResult<()> {
5454        if let Some(previously_signed_digest) = epoch_store.get_signed_effects_digest(tx_digest)? {
5455            if previously_signed_digest != *effects_digest {
5456                self.metrics
5457                    .signed_effects_equivocation_prevented
5458                    .with_label_values(&[surface])
5459                    .inc();
5460                error!(
5461                    ?tx_digest,
5462                    ?previously_signed_digest,
5463                    executed_digest = ?effects_digest,
5464                    surface,
5465                    "refusing to report effects that differ from previously signed effects"
5466                );
5467                return Err(IotaError::GenericAuthority {
5468                    error: format!(
5469                        "Refusing to report effects for transaction {tx_digest}: effects digest \
5470                         {effects_digest} differs from previously signed effects digest \
5471                         {previously_signed_digest}"
5472                    ),
5473                });
5474            }
5475        }
5476        Ok(())
5477    }
5478
5479    #[instrument(level = "trace", skip_all)]
5480    pub(crate) fn sign_effects(
5481        &self,
5482        effects: TransactionEffects,
5483        epoch_store: &Arc<AuthorityPerEpochStore>,
5484    ) -> IotaResult<VerifiedSignedTransactionEffects> {
5485        let tx_digest = *effects.transaction_digest();
5486
5487        self.check_effects_against_previously_signed(
5488            epoch_store,
5489            &tx_digest,
5490            &effects.digest(),
5491            "sign_effects",
5492        )?;
5493
5494        let signed_effects = match epoch_store.get_effects_signature(&tx_digest)? {
5495            Some(sig) => {
5496                debug_assert!(sig.epoch == epoch_store.epoch());
5497                SignedTransactionEffects::new_from_data_and_sig(effects, sig)
5498            }
5499            _ => {
5500                let sig = AuthoritySignInfo::new(
5501                    epoch_store.epoch(),
5502                    &effects,
5503                    Intent::iota_app(IntentScope::TransactionEffects),
5504                    self.name,
5505                    &*self.secret,
5506                );
5507
5508                let effects = SignedTransactionEffects::new_from_data_and_sig(effects, sig.clone());
5509
5510                epoch_store.insert_effects_digest_and_signature(
5511                    &tx_digest,
5512                    effects.digest(),
5513                    &sig,
5514                )?;
5515
5516                effects
5517            }
5518        };
5519
5520        Ok(VerifiedSignedTransactionEffects::new_unchecked(
5521            signed_effects,
5522        ))
5523    }
5524
5525    /// Get the transaction envelope that currently locks the given object, if
5526    /// any. Since object locks are only valid for one epoch, we also need
5527    /// the epoch_id in the query. Returns UserInputError::ObjectNotFound if
5528    /// no lock records for the given object can be found.
5529    /// Returns UserInputError::ObjectVersionUnavailableForConsumption if the
5530    /// object record is at a different version.
5531    /// Returns Some(VerifiedEnvelope) if the given ObjectReference is locked by
5532    /// a certain transaction. Returns None if the a lock record is
5533    /// initialized for the given ObjectReference but not yet locked by any
5534    /// transaction,     or cannot find the transaction in transaction
5535    /// table, because of data race etc.
5536    #[instrument(level = "trace", skip_all)]
5537    pub fn get_transaction_lock(
5538        &self,
5539        object_ref: &ObjectReference,
5540        epoch_store: &AuthorityPerEpochStore,
5541    ) -> IotaResult<Option<VerifiedSignedTransaction>> {
5542        let lock_info = self
5543            .get_object_cache_reader()
5544            .try_get_lock(*object_ref, epoch_store)?;
5545        let lock_info = match lock_info {
5546            ObjectLockStatus::LockedAtDifferentVersion { locked_ref } => {
5547                return Err(UserInputError::ObjectVersionUnavailableForConsumption {
5548                    provided_obj_ref: *object_ref,
5549                    current_version: locked_ref.version,
5550                }
5551                .into());
5552            }
5553            ObjectLockStatus::Initialized => {
5554                return Ok(None);
5555            }
5556            ObjectLockStatus::LockedToTx { locked_by_tx } => locked_by_tx,
5557        };
5558
5559        epoch_store.get_signed_transaction(&lock_info)
5560    }
5561
5562    pub fn try_get_objects(&self, objects: &[ObjectId]) -> IotaResult<Vec<Option<Object>>> {
5563        self.get_object_cache_reader().try_get_objects(objects)
5564    }
5565
5566    /// Non-fallible version of `try_get_objects`.
5567    pub fn get_objects(&self, objects: &[ObjectId]) -> Vec<Option<Object>> {
5568        self.try_get_objects(objects)
5569            .expect("storage access failed")
5570    }
5571
5572    pub fn try_get_object_or_tombstone(
5573        &self,
5574        object_id: ObjectId,
5575    ) -> IotaResult<Option<ObjectReference>> {
5576        self.get_object_cache_reader()
5577            .try_get_latest_object_ref_or_tombstone(object_id)
5578    }
5579
5580    /// Non-fallible version of `try_get_object_or_tombstone`.
5581    pub fn get_object_or_tombstone(&self, object_id: ObjectId) -> Option<ObjectReference> {
5582        self.try_get_object_or_tombstone(object_id)
5583            .expect("storage access failed")
5584    }
5585
5586    /// Ordinarily, protocol upgrades occur when 2f + 1 + (f *
5587    /// ProtocolConfig::buffer_stake_for_protocol_upgrade_bps) vote for the
5588    /// upgrade.
5589    ///
5590    /// This method can be used to dynamic adjust the amount of buffer. If set
5591    /// to 0, the upgrade will go through with only 2f+1 votes.
5592    ///
5593    /// IMPORTANT: If this is used, it must be used on >=2f+1 validators (all
5594    /// should have the same value), or you risk halting the chain.
5595    pub fn set_override_protocol_upgrade_buffer_stake(
5596        &self,
5597        expected_epoch: EpochId,
5598        buffer_stake_bps: u64,
5599    ) -> IotaResult {
5600        let epoch_store = self.load_epoch_store_one_call_per_task();
5601        let actual_epoch = epoch_store.epoch();
5602        if actual_epoch != expected_epoch {
5603            return Err(IotaError::WrongEpoch {
5604                expected_epoch,
5605                actual_epoch,
5606            });
5607        }
5608
5609        epoch_store.set_override_protocol_upgrade_buffer_stake(buffer_stake_bps)
5610    }
5611
5612    pub fn clear_override_protocol_upgrade_buffer_stake(
5613        &self,
5614        expected_epoch: EpochId,
5615    ) -> IotaResult {
5616        let epoch_store = self.load_epoch_store_one_call_per_task();
5617        let actual_epoch = epoch_store.epoch();
5618        if actual_epoch != expected_epoch {
5619            return Err(IotaError::WrongEpoch {
5620                expected_epoch,
5621                actual_epoch,
5622            });
5623        }
5624
5625        epoch_store.clear_override_protocol_upgrade_buffer_stake()
5626    }
5627
5628    /// Get the set of system packages that are compiled in to this build, if
5629    /// those packages are compatible with the current versions of those
5630    /// packages on-chain.
5631    pub async fn get_available_system_packages(
5632        &self,
5633        protocol_config: &ProtocolConfig,
5634    ) -> Vec<ObjectReference> {
5635        let mut results = vec![];
5636
5637        let system_packages = BuiltInFramework::iter_system_packages();
5638
5639        // Add extra framework packages during simtest
5640        #[cfg(msim)]
5641        let extra_packages = framework_injection::get_extra_packages(self.name);
5642        #[cfg(msim)]
5643        let system_packages = {
5644            let mut packages: Vec<_> = system_packages.collect();
5645            packages.extend(extra_packages.iter());
5646            packages
5647        };
5648
5649        for system_package in system_packages {
5650            let modules = system_package.modules().to_vec();
5651            // In simtests, we could override the current built-in framework packages.
5652            #[cfg(msim)]
5653            let modules = framework_injection::get_override_modules(&system_package.id, self.name)
5654                .unwrap_or(modules);
5655
5656            let Some(obj_ref) = iota_framework::compare_system_package(
5657                &self.get_object_store(),
5658                &system_package.id,
5659                &modules,
5660                system_package.dependencies.to_vec(),
5661                protocol_config,
5662            )
5663            .await
5664            else {
5665                return vec![];
5666            };
5667            results.push(obj_ref);
5668        }
5669
5670        results
5671    }
5672
5673    /// Return the new versions, module bytes, and dependencies for the packages
5674    /// that have been committed to for a framework upgrade, in
5675    /// `system_packages`.  Loads the module contents from the binary, and
5676    /// performs the following checks:
5677    ///
5678    /// - Whether its contents matches what is on-chain already, in which case no upgrade is
5679    ///   required, and its contents are omitted from the output.
5680    /// - Whether the contents in the binary can form a package whose digest matches the input,
5681    ///   meaning the framework will be upgraded, and this authority can satisfy that upgrade, in
5682    ///   which case the contents are included in the output.
5683    ///
5684    /// If a needed version of the framework can't be loaded, the binary does
5685    /// not contain the bytes for that framework ID, or the resulting
5686    /// package fails the digest check, `None` is returned indicating that
5687    /// this authority cannot run the upgrade that the network voted on.
5688    ///
5689    /// All object lookups are pinned to the versions in `system_packages`
5690    /// instead of using the latest versions, so that the result is
5691    /// deterministic even if the change epoch transaction that performs the
5692    /// upgrade has already been executed locally (e.g. via state sync). In
5693    /// that case the reconstructed change epoch transaction is byte-identical
5694    /// to the executed one, and the caller detects it as already executed.
5695    async fn get_system_package_bytes(
5696        &self,
5697        system_packages: Vec<ObjectReference>,
5698        binary_config: &BinaryConfig,
5699    ) -> Option<Vec<SystemPackage>> {
5700        let object_store = self.get_object_cache_reader();
5701
5702        let mut res = Vec::with_capacity(system_packages.len());
5703        for system_package_ref in system_packages {
5704            if object_store
5705                .get_object_by_key(&system_package_ref.object_id, system_package_ref.version)
5706                .is_some_and(|object| object.object_ref() == system_package_ref)
5707            {
5708                // Skip this one because it doesn't need to be upgraded.
5709                info!(
5710                    "Framework {} does not need updating",
5711                    system_package_ref.object_id
5712                );
5713                continue;
5714            }
5715
5716            // The digest in `system_package_ref` commits to a package built on top of the
5717            // predecessor version's `previous_transaction` (see `compare_system_package`),
5718            // so it must be re-derived from that version. A ref at
5719            // `Version::OBJECT_START` is a freshly created package with no predecessor.
5720            let prev_transaction = if system_package_ref.version == Version::OBJECT_START {
5721                TransactionDigest::GENESIS_MARKER
5722            } else {
5723                let prev_version = system_package_ref
5724                    .version
5725                    .previous()
5726                    .expect("version is greater than Version::OBJECT_START");
5727                let Some(prev_object) =
5728                    object_store.get_object_by_key(&system_package_ref.object_id, prev_version)
5729                else {
5730                    error!(
5731                        "Framework {} not available locally at version {prev_version:?}, cannot \
5732                         derive upgrade to {system_package_ref:?}",
5733                        system_package_ref.object_id
5734                    );
5735                    return None;
5736                };
5737                prev_object.previous_transaction
5738            };
5739
5740            #[cfg(msim)]
5741            let FrameworkSystemPackage {
5742                id: _,
5743                bytes,
5744                dependencies,
5745            } = framework_injection::get_override_system_package(
5746                &system_package_ref.object_id,
5747                self.name,
5748            )
5749            .unwrap_or_else(|| {
5750                BuiltInFramework::get_package_by_id(&system_package_ref.object_id).clone()
5751            });
5752
5753            #[cfg(not(msim))]
5754            let FrameworkSystemPackage {
5755                id: _,
5756                bytes,
5757                dependencies,
5758            } = BuiltInFramework::get_package_by_id(&system_package_ref.object_id).clone();
5759
5760            let modules: Vec<_> = bytes
5761                .iter()
5762                .map(|m| CompiledModule::deserialize_with_config(m, binary_config).unwrap())
5763                .collect();
5764
5765            let new_object = Object::new_system_package(
5766                &modules,
5767                system_package_ref.version,
5768                dependencies.clone(),
5769                prev_transaction,
5770            );
5771
5772            let new_ref = new_object.object_ref();
5773            if new_ref != system_package_ref {
5774                debug_fatal!(
5775                    "Framework mismatch -- binary: {new_ref:?}\n  upgrade: {system_package_ref:?}"
5776                );
5777                return None;
5778            }
5779
5780            res.push(SystemPackage {
5781                version: system_package_ref.version,
5782                modules: bytes,
5783                dependencies,
5784            });
5785        }
5786
5787        Some(res)
5788    }
5789
5790    /// Returns the new protocol version and system packages that the network
5791    /// has voted to upgrade to. If the proposed protocol version is not
5792    /// supported, None is returned.
5793    fn is_protocol_version_supported_v1(
5794        proposed_protocol_version: ProtocolVersion,
5795        committee: &Committee,
5796        capabilities: Vec<AuthorityCapabilitiesV1>,
5797        mut buffer_stake_bps: u64,
5798    ) -> Option<(ProtocolVersion, Digest, Vec<ObjectReference>)> {
5799        if buffer_stake_bps > 10000 {
5800            warn!("clamping buffer_stake_bps to 10000");
5801            buffer_stake_bps = 10000;
5802        }
5803
5804        // For each validator, gather the protocol version and system packages that it
5805        // would like to upgrade to in the next epoch.
5806        let mut desired_upgrades: Vec<_> = capabilities
5807            .into_iter()
5808            .filter_map(|mut cap| {
5809                // A validator that lists no packages is voting against any change at all.
5810                if cap.available_system_packages.is_empty() {
5811                    return None;
5812                }
5813
5814                cap.available_system_packages.sort();
5815
5816                info!(
5817                    "validator {:?} supports {:?} with system packages: {:?}",
5818                    cap.authority.concise(),
5819                    cap.supported_protocol_versions,
5820                    cap.available_system_packages,
5821                );
5822
5823                // A validator that only supports the current protocol version is also voting
5824                // against any change, because framework upgrades always require a protocol
5825                // version bump.
5826                cap.supported_protocol_versions
5827                    .get_version_digest(proposed_protocol_version)
5828                    .map(|digest| (digest, cap.available_system_packages, cap.authority))
5829            })
5830            .collect();
5831
5832        // There can only be one set of votes that have a majority, find one if it
5833        // exists.
5834        desired_upgrades.sort();
5835        desired_upgrades
5836            .into_iter()
5837            .chunk_by(|(digest, packages, _authority)| (*digest, packages.clone()))
5838            .into_iter()
5839            .find_map(|((digest, packages), group)| {
5840                // should have been filtered out earlier.
5841                assert!(!packages.is_empty());
5842
5843                let mut stake_aggregator: StakeAggregator<(), true> =
5844                    StakeAggregator::new(Arc::new(committee.clone()));
5845
5846                for (_, _, authority) in group {
5847                    stake_aggregator.insert_generic(authority, ());
5848                }
5849
5850                let total_votes = stake_aggregator.total_votes();
5851                let quorum_threshold = committee.quorum_threshold();
5852                let effective_threshold = committee.effective_threshold(buffer_stake_bps);
5853
5854                info!(
5855                    protocol_config_digest = ?digest,
5856                    ?total_votes,
5857                    ?quorum_threshold,
5858                    ?buffer_stake_bps,
5859                    ?effective_threshold,
5860                    ?proposed_protocol_version,
5861                    ?packages,
5862                    "support for upgrade"
5863                );
5864
5865                let has_support = total_votes >= effective_threshold;
5866                has_support.then_some((proposed_protocol_version, digest, packages))
5867            })
5868    }
5869
5870    /// Selects the highest supported protocol version and system packages that
5871    /// the network has voted to upgrade to. If no upgrade is supported,
5872    /// returns the current protocol version and system packages.
5873    fn choose_protocol_version_and_system_packages_v1(
5874        current_protocol_version: ProtocolVersion,
5875        current_protocol_digest: Digest,
5876        committee: &Committee,
5877        capabilities: Vec<AuthorityCapabilitiesV1>,
5878        buffer_stake_bps: u64,
5879    ) -> (ProtocolVersion, Digest, Vec<ObjectReference>) {
5880        let mut next_protocol_version = current_protocol_version;
5881        let mut system_packages = vec![];
5882        let mut protocol_version_digest = current_protocol_digest;
5883
5884        // Finds the highest supported protocol version and system packages by
5885        // incrementing the proposed protocol version by one until no further
5886        // upgrades are supported.
5887        while let Some((version, digest, packages)) = Self::is_protocol_version_supported_v1(
5888            next_protocol_version + 1,
5889            committee,
5890            capabilities.clone(),
5891            buffer_stake_bps,
5892        ) {
5893            next_protocol_version = version;
5894            protocol_version_digest = digest;
5895            system_packages = packages;
5896        }
5897
5898        (
5899            next_protocol_version,
5900            protocol_version_digest,
5901            system_packages,
5902        )
5903    }
5904
5905    /// Returns the indices of validators that support the given protocol
5906    /// version and digest. This includes both committee and non-committee
5907    /// validators based on their capabilities. Uses active validators
5908    /// instead of committee indices.
5909    fn get_validators_supporting_protocol_version(
5910        target_protocol_version: ProtocolVersion,
5911        target_digest: Digest,
5912        active_validators: &[AggregateAuthorityPublicKey],
5913        capabilities: &[AuthorityCapabilitiesV1],
5914    ) -> Vec<u64> {
5915        let mut eligible_validators = Vec::new();
5916
5917        for capability in capabilities {
5918            // Check if this validator supports the target protocol version and digest
5919            if let Some(digest) = capability
5920                .supported_protocol_versions
5921                .get_version_digest(target_protocol_version)
5922            {
5923                if digest == target_digest {
5924                    // Find the validator's index in the active validators list
5925                    if let Some(index) = active_validators
5926                        .iter()
5927                        .position(|name| AuthorityName::from(name) == capability.authority)
5928                    {
5929                        eligible_validators.push(index as u64);
5930                    }
5931                }
5932            }
5933        }
5934
5935        // Sort indices for deterministic behavior
5936        eligible_validators.sort();
5937        eligible_validators
5938    }
5939
5940    /// Calculates the sum of weights for eligible validators that are part of
5941    /// the committee. Takes the indices from
5942    /// get_validators_supporting_protocol_version and maps them back
5943    /// to committee members to get their weights.
5944    fn calculate_eligible_validators_weight(
5945        eligible_validator_indices: &[u64],
5946        active_validators: &[AggregateAuthorityPublicKey],
5947        committee: &Committee,
5948    ) -> u64 {
5949        let mut total_weight = 0u64;
5950
5951        for &index in eligible_validator_indices {
5952            let authority_pubkey = &active_validators[index as usize];
5953            // Check if this validator is in the committee and get their weight
5954            if let Some((_, weight)) = committee
5955                .members()
5956                .find(|(name, _)| *name == AuthorityName::from(authority_pubkey))
5957            {
5958                total_weight += weight;
5959            }
5960        }
5961
5962        total_weight
5963    }
5964
5965    /// Creates and execute the advance epoch transaction to effects without
5966    /// committing it to the database. The effects of the change epoch tx
5967    /// are only written to the database after a certified checkpoint has been
5968    /// formed and executed by CheckpointExecutor.
5969    ///
5970    /// When a framework upgraded has been decided on, but the validator does
5971    /// not have the new versions of the packages locally, the validator
5972    /// cannot form the ChangeEpochTx. In this case it returns Err,
5973    /// indicating that the checkpoint builder should give up trying to make the
5974    /// final checkpoint. As long as the network is able to create a certified
5975    /// checkpoint (which should be ensured by the capabilities vote), it
5976    /// will arrive via state sync and be executed by CheckpointExecutor.
5977    ///
5978    /// `scores` is indexed by authority index, see
5979    /// [`Committee::authority_index()`], as `Scoreboard::current_scores()`
5980    /// returns it. The transaction carries the scores in committee member
5981    /// index order, which is where Move reads them, so this is the one place
5982    /// that converts between the two orders.
5983    #[instrument(level = "error", skip_all)]
5984    pub async fn create_and_execute_advance_epoch_tx(
5985        &self,
5986        epoch_store: &Arc<AuthorityPerEpochStore>,
5987        gas_cost_summary: &GasCostSummary,
5988        checkpoint: CheckpointSequenceNumber,
5989        epoch_start_timestamp_ms: CheckpointTimestamp,
5990        scores: Vec<u64>,
5991    ) -> CheckpointBuilderResult<(
5992        IotaSystemState,
5993        Option<SystemEpochInfoEvent>,
5994        TransactionEffects,
5995    )> {
5996        let mut txns = Vec::new();
5997
5998        // Create the TransactionDenyRules object once: the epoch-start
5999        // configuration is identical on every validator, so the whole
6000        // committee injects (or skips) the kind together. If this epoch
6001        // change falls into safe mode the creation is dropped with it, the
6002        // object stays absent, and the next epoch end injects it again.
6003        if epoch_store.protocol_config().enable_pcool_flow()
6004            && epoch_store
6005                .epoch_start_config()
6006                .transaction_deny_rules_obj_initial_shared_version()
6007                .is_none()
6008        {
6009            txns.push(EndOfEpochTransactionKind::TransactionDenyRulesCreate);
6010        }
6011
6012        let next_epoch = epoch_store.epoch() + 1;
6013
6014        let buffer_stake_bps = epoch_store.get_effective_buffer_stake_bps();
6015        let authority_capabilities = epoch_store
6016            .get_capabilities_v1()
6017            .expect("read capabilities from db cannot fail");
6018        let (next_epoch_protocol_version, next_epoch_protocol_digest, next_epoch_system_packages) =
6019            Self::choose_protocol_version_and_system_packages_v1(
6020                epoch_store.protocol_version(),
6021                SupportedProtocolVersionsWithHashes::protocol_config_digest(
6022                    epoch_store.protocol_config(),
6023                ),
6024                epoch_store.committee(),
6025                authority_capabilities.clone(),
6026                buffer_stake_bps,
6027            );
6028
6029        // since system packages are created during the current epoch, they should abide
6030        // by the rules of the current epoch, including the current epoch's max
6031        // Move binary format version
6032        let config = epoch_store.protocol_config();
6033        let binary_config = to_binary_config(config, None);
6034        let Some(next_epoch_system_package_bytes) = self
6035            .get_system_package_bytes(next_epoch_system_packages.clone(), &binary_config)
6036            .await
6037        else {
6038            debug_fatal!(
6039                "upgraded system packages {:?} are not locally available, cannot create \
6040                ChangeEpochTx. validator binary must be upgraded to the correct version!",
6041                next_epoch_system_packages
6042            );
6043            // the checkpoint builder will keep retrying forever when it hits this error.
6044            // Eventually, one of two things will happen:
6045            // - The operator will upgrade this binary to one that has the new packages locally, and
6046            //   this function will succeed.
6047            // - The final checkpoint will be certified by other validators, we will receive it via
6048            //   state sync, and execute it. This will upgrade the framework packages, reconfigure,
6049            //   and most likely shut down in the new epoch (this validator likely doesn't support
6050            //   the new protocol version, or else it should have had the packages.)
6051            return Err(CheckpointBuilderError::SystemPackagesMissing);
6052        };
6053
6054        // Use ChangeEpochV3 or ChangeEpochV4 when the feature flags are enabled and
6055        // ChangeEpochV2 requirements are met
6056        if config.select_committee_from_eligible_validators() {
6057            // Get the list of eligible validators that support the target protocol version
6058            let active_validators = epoch_store.epoch_start_state().get_active_validators();
6059
6060            let mut eligible_active_validators = (0..active_validators.len() as u64).collect();
6061
6062            // Use validators supporting the target protocol version as eligible validators
6063            // in the next version if select_committee_supporting_next_epoch_version feature
6064            // flag is set to true.
6065            if config.select_committee_supporting_next_epoch_version() {
6066                eligible_active_validators = Self::get_validators_supporting_protocol_version(
6067                    next_epoch_protocol_version,
6068                    next_epoch_protocol_digest,
6069                    &active_validators,
6070                    &authority_capabilities,
6071                );
6072
6073                // Calculate the total weight of eligible validators in the committee
6074                let eligible_validators_weight = Self::calculate_eligible_validators_weight(
6075                    &eligible_active_validators,
6076                    &active_validators,
6077                    epoch_store.committee(),
6078                );
6079
6080                // Safety check: ensure eligible validators have enough stake
6081                // Use the same effective threshold calculation that was used to decide the
6082                // protocol version
6083                let committee = epoch_store.committee();
6084                let effective_threshold = committee.effective_threshold(buffer_stake_bps);
6085
6086                if eligible_validators_weight < effective_threshold {
6087                    error!(
6088                        "Eligible validators weight {eligible_validators_weight} is less than effective threshold {effective_threshold}. \
6089                        This could indicate a bug in validator selection logic or inconsistency with protocol version decision.",
6090                    );
6091                    // Pass all active validator indices as eligible validators
6092                    // to perform selection among all of them.
6093                    eligible_active_validators = (0..active_validators.len() as u64).collect();
6094                }
6095            }
6096
6097            // Use ChangeEpochV4 when the pass_validator_scores_to_advance_epoch feature
6098            // flag is enabled.
6099            if config.pass_validator_scores_to_advance_epoch() {
6100                txns.push(EndOfEpochTransactionKind::new_change_epoch_v4(
6101                    next_epoch,
6102                    next_epoch_protocol_version.as_u64(),
6103                    gas_cost_summary.storage_cost,
6104                    gas_cost_summary.computation_cost,
6105                    gas_cost_summary.computation_cost_burned,
6106                    gas_cost_summary.storage_rebate,
6107                    gas_cost_summary.non_refundable_storage_fee,
6108                    epoch_start_timestamp_ms,
6109                    next_epoch_system_package_bytes,
6110                    eligible_active_validators,
6111                    epoch_store.scores_for_advance_epoch(&scores),
6112                    config.adjust_rewards_by_score(),
6113                ));
6114            } else {
6115                txns.push(EndOfEpochTransactionKind::new_change_epoch_v3(
6116                    next_epoch,
6117                    next_epoch_protocol_version.as_u64(),
6118                    gas_cost_summary.storage_cost,
6119                    gas_cost_summary.computation_cost,
6120                    gas_cost_summary.computation_cost_burned,
6121                    gas_cost_summary.storage_rebate,
6122                    gas_cost_summary.non_refundable_storage_fee,
6123                    epoch_start_timestamp_ms,
6124                    next_epoch_system_package_bytes,
6125                    eligible_active_validators,
6126                ));
6127            }
6128        } else if config.protocol_defined_base_fee()
6129            && config.max_committee_members_count_as_option().is_some()
6130        {
6131            txns.push(EndOfEpochTransactionKind::new_change_epoch_v2(
6132                next_epoch,
6133                next_epoch_protocol_version.as_u64(),
6134                gas_cost_summary.storage_cost,
6135                gas_cost_summary.computation_cost,
6136                gas_cost_summary.computation_cost_burned,
6137                gas_cost_summary.storage_rebate,
6138                gas_cost_summary.non_refundable_storage_fee,
6139                epoch_start_timestamp_ms,
6140                next_epoch_system_package_bytes,
6141            ));
6142        } else {
6143            txns.push(EndOfEpochTransactionKind::new_change_epoch(
6144                next_epoch,
6145                next_epoch_protocol_version.as_u64(),
6146                gas_cost_summary.storage_cost,
6147                gas_cost_summary.computation_cost,
6148                gas_cost_summary.storage_rebate,
6149                gas_cost_summary.non_refundable_storage_fee,
6150                epoch_start_timestamp_ms,
6151                next_epoch_system_package_bytes,
6152            ));
6153        }
6154
6155        let tx = VerifiedTransaction::new_end_of_epoch_transaction(txns);
6156
6157        let executable_tx = VerifiedExecutableTransaction::new_from_checkpoint(
6158            tx.clone(),
6159            epoch_store.epoch(),
6160            checkpoint,
6161        );
6162
6163        let tx_digest = executable_tx.digest();
6164
6165        info!(
6166            ?next_epoch,
6167            ?next_epoch_protocol_version,
6168            ?next_epoch_system_packages,
6169            computation_cost=?gas_cost_summary.computation_cost,
6170            computation_cost_burned=?gas_cost_summary.computation_cost_burned,
6171            storage_cost=?gas_cost_summary.storage_cost,
6172            storage_rebate=?gas_cost_summary.storage_rebate,
6173            non_refundable_storage_fee=?gas_cost_summary.non_refundable_storage_fee,
6174            ?tx_digest,
6175            "Creating advance epoch transaction"
6176        );
6177
6178        fail_point_async!("change_epoch_tx_delay");
6179        let tx_lock = epoch_store.acquire_tx_lock(tx_digest);
6180
6181        // The tx could have been executed by state sync already - if so simply return
6182        // an error. The checkpoint builder will shortly be terminated by
6183        // reconfiguration anyway.
6184        if self
6185            .get_transaction_cache_reader()
6186            .try_is_tx_already_executed(tx_digest)?
6187        {
6188            warn!("change epoch tx has already been executed via state sync");
6189            return Err(CheckpointBuilderError::ChangeEpochTxAlreadyExecuted);
6190        }
6191
6192        let execution_guard = self.execution_lock_for_executable_transaction(&executable_tx)?;
6193
6194        // We must manually assign the shared object versions to the transaction before
6195        // executing it. This is because we do not sequence end-of-epoch
6196        // transactions through consensus.
6197        let assigned_versions = epoch_store.assign_shared_object_versions_idempotent(
6198            self.get_object_cache_reader().as_ref(),
6199            std::iter::once(&Schedulable::Transaction(&executable_tx)),
6200        )?;
6201
6202        assert_eq!(assigned_versions.0.len(), 1);
6203        let assigned_versions = assigned_versions.0.into_iter().next().unwrap().1;
6204
6205        let (input_objects, _) = self.read_objects_for_execution(
6206            &tx_lock,
6207            &executable_tx,
6208            assigned_versions,
6209            epoch_store,
6210        )?;
6211
6212        let (temporary_store, effects, _execution_error_opt, _, _) = self.execute_transaction(
6213            &execution_guard,
6214            &executable_tx,
6215            input_objects,
6216            vec![],
6217            &AttestationSource::Unattested,
6218            epoch_store,
6219        )?;
6220        let system_obj = get_iota_system_state(&temporary_store.written)
6221            .expect("change epoch tx must write to system object");
6222        // Find the SystemEpochInfoEvent emitted by the advance_epoch transaction.
6223        let system_epoch_info_event = temporary_store
6224            .events
6225            .0
6226            .into_iter()
6227            .find(|event| event.is_system_epoch_info_event())
6228            .map(SystemEpochInfoEvent::from);
6229        // The system epoch info event can be `None` in case if the `advance_epoch`
6230        // Move function call failed and was executed in the safe mode.
6231        assert!(system_epoch_info_event.is_some() || system_obj.safe_mode());
6232
6233        // We must write tx and effects to the state sync tables so that state sync is
6234        // able to deliver to the transaction to CheckpointExecutor after it is
6235        // included in a certified checkpoint.
6236        self.get_state_sync_store()
6237            .try_insert_transaction_and_effects(&tx, &effects)?;
6238
6239        info!(
6240            "Effects summary of the change epoch transaction: {:?}",
6241            effects.summary_for_debug()
6242        );
6243        epoch_store.record_checkpoint_builder_is_safe_mode_metric(system_obj.safe_mode());
6244        // The change epoch transaction cannot fail to execute.
6245        assert!(effects.status().is_success());
6246        Ok((system_obj, system_epoch_info_event, effects))
6247    }
6248
6249    /// This function is called at the very end of the epoch.
6250    /// This step is required before updating new epoch in the db and calling
6251    /// reopen_epoch_db.
6252    #[instrument(level = "error", skip_all)]
6253    async fn revert_uncommitted_epoch_transactions(
6254        &self,
6255        epoch_store: &AuthorityPerEpochStore,
6256    ) -> IotaResult {
6257        {
6258            let state = epoch_store.get_reconfig_state_write_lock_guard();
6259            if state.should_accept_user_certs() {
6260                // Need to change this so that consensus adapter do not accept certificates from
6261                // user. This can happen if our local validator did not initiate
6262                // epoch change locally, but 2f+1 nodes already concluded the
6263                // epoch.
6264                //
6265                // This lock is essentially a barrier (in the certificate mode only) for
6266                // `epoch_store.pending_consensus_certificates` table we are reading on the line
6267                // after this block
6268                epoch_store.close_user_certs(state);
6269            }
6270            // lock is dropped here
6271        }
6272
6273        // In the P-COOL flow, the list of pending consensus certificates is
6274        // always empty, so the reverting below is only for the certificate mode.
6275        if !epoch_store.protocol_config().enable_pcool_flow() {
6276            let pending_certificates = epoch_store.pending_consensus_certificates();
6277            info!(
6278                "Reverting {} locally executed transactions that was not included in the epoch: \
6279                    {:?}",
6280                pending_certificates.len(),
6281                pending_certificates,
6282            );
6283            for digest in pending_certificates {
6284                if epoch_store.is_transaction_executed_in_checkpoint(&digest)? {
6285                    info!(
6286                        "Not reverting pending consensus transaction {:?} - it was included in \
6287                            checkpoint",
6288                        digest
6289                    );
6290                    continue;
6291                }
6292                info!("Reverting {:?} at the end of epoch", digest);
6293                epoch_store.revert_executed_transaction(&digest)?;
6294                self.get_reconfig_api().try_revert_state_update(&digest)?;
6295            }
6296            info!("All uncommitted local transactions reverted");
6297        } else {
6298            info!("P-COOL mode: skipping revert of uncommitted epoch transactions");
6299        }
6300
6301        Ok(())
6302    }
6303
6304    #[instrument(level = "error", skip_all)]
6305    async fn reopen_epoch_db(
6306        &self,
6307        cur_epoch_store: &AuthorityPerEpochStore,
6308        new_committee: Committee,
6309        epoch_start_configuration: EpochStartConfiguration,
6310        expensive_safety_check_config: &ExpensiveSafetyCheckConfig,
6311        epoch_last_checkpoint: CheckpointSequenceNumber,
6312    ) -> IotaResult<Arc<AuthorityPerEpochStore>> {
6313        let new_epoch = new_committee.epoch;
6314        info!(new_epoch = ?new_epoch, "re-opening AuthorityEpochTables for new epoch");
6315        assert_eq!(
6316            epoch_start_configuration.epoch_start_state().epoch(),
6317            new_committee.epoch
6318        );
6319        fail_point!("before-open-new-epoch-store");
6320        let new_epoch_store = cur_epoch_store.new_at_next_epoch(
6321            self.name,
6322            new_committee,
6323            epoch_start_configuration,
6324            self.get_backing_package_store().clone(),
6325            expensive_safety_check_config,
6326            epoch_last_checkpoint,
6327        )?;
6328        self.epoch_store.store(new_epoch_store.clone());
6329        Ok(new_epoch_store)
6330    }
6331
6332    /// Resolves the account's `AuthenticatorFunctionRef` on the execution path,
6333    /// where the certificate has already passed validation before consensus.
6334    ///
6335    /// A deleted or cancelled account object is not an error here: its version
6336    /// is returned so execution can proceed and surface the proper effect
6337    /// (e.g. `InputObjectDeleted` or a shared-object congestion cancellation).
6338    ///
6339    /// # Errors
6340    ///
6341    /// Any failure the check finds with the transaction, as the error the
6342    /// transaction fails with, with the original error as the source:
6343    /// [`ExecutionErrorKind::AuthenticatorFunctionNotFound`] when the account
6344    /// has no authenticator function field or the field cannot be read, and
6345    /// [`ExecutionErrorKind::AccountNotSharedObject`] when the account is not a
6346    /// shared object.
6347    ///
6348    /// # Panics
6349    ///
6350    /// When the store cannot be read: that says nothing about the transaction,
6351    /// so nobody can be charged for it, and effects written here would differ
6352    /// from the other validators'.
6353    fn check_move_account_for_execution(
6354        &self,
6355        auth_account_object_id: ObjectId,
6356        auth_account_object_seq_number: Option<Version>,
6357        auth_account_object_digest: Option<ObjectDigest>,
6358        account_object: ObjectReadResult,
6359        signer: &Address,
6360        protocol_config: &ProtocolConfig,
6361    ) -> Result<AuthenticatorFunctionRefForExecution, ExecutionError> {
6362        match self.check_move_account(
6363            auth_account_object_id,
6364            auth_account_object_seq_number,
6365            auth_account_object_digest,
6366            account_object,
6367            signer,
6368            true,
6369            protocol_config,
6370        ) {
6371            Ok(function_ref) => Ok(function_ref),
6372            Err(MoveAccountCheckError::Input(input_error)) => {
6373                let status = match &input_error {
6374                    UserInputError::MoveAuthenticatorNotFound {
6375                        account_object_id, ..
6376                    }
6377                    | UserInputError::InvalidAuthenticatorFunctionRefField { account_object_id } => {
6378                        ExecutionErrorKind::AuthenticatorFunctionNotFound {
6379                            object_id: *account_object_id,
6380                        }
6381                    }
6382                    // Since protocol version 36, only a shared account named with
6383                    // an immutable or owned reference reaches the digest
6384                    // comparison. The fix is the same as for the other two: name
6385                    // the account as a shared object.
6386                    UserInputError::AccountObjectNotSupported { object_id }
6387                    | UserInputError::ImmutableAccountObjectNotSupported { object_id }
6388                    | UserInputError::InvalidAccountObjectDigest { object_id, .. } => {
6389                        ExecutionErrorKind::AccountNotSharedObject {
6390                            object_id: *object_id,
6391                        }
6392                    }
6393                    // The check produces nothing else today. A failure added to
6394                    // it gets this status until it is given one of its own.
6395                    _ => ExecutionErrorKind::FunctionNotFound,
6396                };
6397                Err(ExecutionError::new_with_source(status, input_error))
6398            }
6399            Err(MoveAccountCheckError::Storage(storage_error)) => {
6400                panic!("failed to read the store while checking a Move account: {storage_error}")
6401            }
6402        }
6403    }
6404
6405    /// Resolves the account's `AuthenticatorFunctionRef` on the validation
6406    /// (signing) path, rejecting the transaction when the account object was
6407    /// deleted or belongs to a cancelled transaction.
6408    fn check_move_account_for_validation(
6409        &self,
6410        auth_account_object_id: ObjectId,
6411        auth_account_object_seq_number: Option<Version>,
6412        auth_account_object_digest: Option<ObjectDigest>,
6413        account_object: ObjectReadResult,
6414        signer: &Address,
6415        protocol_config: &ProtocolConfig,
6416    ) -> IotaResult<AuthenticatorFunctionRefForExecution> {
6417        self.check_move_account(
6418            auth_account_object_id,
6419            auth_account_object_seq_number,
6420            auth_account_object_digest,
6421            account_object,
6422            signer,
6423            false,
6424            protocol_config,
6425        )
6426        .map_err(IotaError::from)
6427    }
6428
6429    /// Checks whether `authenticator` unlocks a valid Move account and returns
6430    /// the account-related `AuthenticatorFunctionRef`. Where the protocol
6431    /// config requires it, the account object must be shared, so that a
6432    /// transaction carrying a `MoveAuthenticator` always has a shared input
6433    /// and is ordered by consensus. When `is_execution` is
6434    /// set, a deleted or cancelled account object yields its version instead of
6435    /// an error, so execution can proceed to the proper effect. Prefer the
6436    /// `check_move_account_for_execution` / `check_move_account_for_validation`
6437    /// wrappers over calling this directly.
6438    ///
6439    /// # Errors
6440    ///
6441    /// [`MoveAccountCheckError::Input`] when the account fails a check, and
6442    /// [`MoveAccountCheckError::Storage`] when the store cannot be read. The
6443    /// error type is what lets the execution path distinguish the two, so a
6444    /// new kind of failure here has to be added to it.
6445    fn check_move_account(
6446        &self,
6447        auth_account_object_id: ObjectId,
6448        auth_account_object_seq_number: Option<Version>,
6449        auth_account_object_digest: Option<ObjectDigest>,
6450        account_object: ObjectReadResult,
6451        signer: &Address,
6452        is_execution: bool,
6453        protocol_config: &ProtocolConfig,
6454    ) -> Result<AuthenticatorFunctionRefForExecution, MoveAccountCheckError> {
6455        let auth_account_object_seq_number = match (&account_object.object, is_execution) {
6456            // In any case, if the account object is loaded, we can check its version and digest.
6457            // Then we return the version of the account object to be used for reading the
6458            // authenticator function ref dynamic field.
6459            (ObjectReadResultKind::Object(object), _) => {
6460                let account_object_addr = Address::from(auth_account_object_id);
6461                fp_ensure!(
6462                    signer == &account_object_addr,
6463                    UserInputError::IncorrectUserSignature {
6464                        error: format!("Move authenticator is trying to unlock {account_object_addr:?}, but given signer address is {signer:?}")
6465                    }
6466                    .into()
6467                );
6468
6469                if protocol_config.reject_immutable_account_objects() {
6470                    fp_ensure!(
6471                        !object.is_immutable(),
6472                        UserInputError::ImmutableAccountObjectNotSupported {
6473                            object_id: auth_account_object_id
6474                        }
6475                        .into()
6476                    );
6477                }
6478
6479                fp_ensure!(
6480                    object.is_shared() || object.is_immutable(),
6481                    UserInputError::AccountObjectNotSupported {
6482                        object_id: auth_account_object_id
6483                    }
6484                    .into()
6485                );
6486
6487                let auth_account_object_seq_number =
6488                    if let Some(expected_version) = auth_account_object_seq_number {
6489                        let account_object_version = object.version();
6490
6491                        fp_ensure!(
6492                            account_object_version == expected_version,
6493                            UserInputError::AccountObjectVersionMismatch {
6494                                object_id: auth_account_object_id,
6495                                expected_version,
6496                                actual_version: account_object_version,
6497                            }
6498                            .into()
6499                        );
6500
6501                        expected_version
6502                    } else {
6503                        object.version()
6504                    };
6505
6506                if let Some(expected_digest) = auth_account_object_digest {
6507                    let account_object_digest = object.digest();
6508                    fp_ensure!(
6509                        account_object_digest == expected_digest,
6510                        UserInputError::InvalidAccountObjectDigest {
6511                            object_id: auth_account_object_id,
6512                            expected_digest,
6513                            actual_digest: account_object_digest,
6514                        }
6515                        .into()
6516                    );
6517                }
6518
6519                Ok(auth_account_object_seq_number)
6520            }
6521            // If the account object is not loaded because it was deleted, we return the error in
6522            // the case in which we are not executing the transaction right after.
6523            (ObjectReadResultKind::DeletedSharedObject(version, digest), false) => {
6524                Err(UserInputError::AccountObjectDeleted {
6525                    account_id: account_object.id(),
6526                    account_version: *version,
6527                    transaction_digest: *digest,
6528                })
6529            }
6530            // If the account object is not loaded because the transaction was canceled, we return
6531            // the error in the case in which we are not executing the transaction right
6532            // after.
6533            (ObjectReadResultKind::CancelledTransactionObject(version), false) => {
6534                Err(UserInputError::AccountObjectInCanceledTransaction {
6535                    account_id: account_object.id(),
6536                    account_version: *version,
6537                })
6538            }
6539            // If the account object is not loaded because it was deleted, we return the version in
6540            // the case in which we are executing the transaction right after.
6541            // This version is used to read the authenticator function ref dynamic field because it
6542            // is greater than the version of the child dynamic field.
6543            (ObjectReadResultKind::DeletedSharedObject(version, _), true) => Ok(*version),
6544            // If the account object is not loaded because the transaction was canceled, we return
6545            // the version in the case in which we are executing the transaction right
6546            // after. This version is used to read the authenticator function ref
6547            // dynamic field because it is greater than the version of the child dynamic
6548            // field.
6549            (ObjectReadResultKind::CancelledTransactionObject(version), true) => Ok(*version),
6550            // A transaction validated post-consensus at a commit leaves its account
6551            // to execution, which reads it, so no check gets an unread account.
6552            (ObjectReadResultKind::UnreadSharedObject, _) => unreachable!(
6553                "only post-consensus validation at a commit lists an unread shared object, and \
6554                    it leaves the account to execution"
6555            ),
6556        }?;
6557
6558        let authenticator_function_ref_field_id =
6559            derive_authenticator_function_ref_v1_dynamic_field_id(auth_account_object_id)?;
6560
6561        let authenticator_function_ref_field = self
6562            .get_object_cache_reader()
6563            .try_find_object_lt_or_eq_version(
6564                authenticator_function_ref_field_id,
6565                auth_account_object_seq_number,
6566            )
6567            .map_err(MoveAccountCheckError::Storage)?;
6568
6569        if let Some(authenticator_function_ref_field_obj) = authenticator_function_ref_field {
6570            Ok(authenticator_function_ref_v1_from_dynamic_field_object(
6571                auth_account_object_id,
6572                &authenticator_function_ref_field_obj,
6573            )?)
6574        } else {
6575            Err(UserInputError::MoveAuthenticatorNotFound {
6576                authenticator_function_ref_id: authenticator_function_ref_field_id,
6577                account_object_id: auth_account_object_id,
6578                account_object_version: auth_account_object_seq_number,
6579            }
6580            .into())
6581        }
6582    }
6583
6584    /// Shared validation pipeline for `handle_transaction_validation_checks`
6585    /// and `attest_transaction`. Runs, in order:
6586    ///   1. transaction deny checks
6587    ///   2. input object loading (transaction + per-authenticator + account)
6588    ///   3. `MoveAuthenticator` collection
6589    ///   4. input checks (gas budget covers transaction + authenticators)
6590    ///   5. coin deny list check
6591    ///
6592    /// Keep this helper as the single source of truth so the two callers
6593    /// cannot drift. Raw inputs are cloned and returned only on the
6594    /// `attest_transaction` path (`is_execute_transaction_to_effects`), where
6595    /// the MoveAuthenticator path needs them; the clone is skipped for
6596    /// `handle_transaction_validation_checks`, which ignores them.
6597    fn run_validation_checks<'a>(
6598        &self,
6599        transaction: &'a VerifiedTransaction,
6600        epoch_store: &Arc<AuthorityPerEpochStore>,
6601        deny_config: &dyn DenyRuleConfig,
6602        is_execute_transaction_to_effects: bool,
6603    ) -> IotaResult<ValidationOutputs<'a>> {
6604        let protocol_config = epoch_store.protocol_config();
6605        let reference_gas_price = epoch_store.reference_gas_price();
6606        let epoch = epoch_store.epoch();
6607        let tx = transaction.data().transaction();
6608
6609        // Step 1: deny checks.
6610        // Note: the deny checks may do redundant package loads but:
6611        // - they only load packages when there is an active package deny map
6612        // - the loads are cached anyway
6613        iota_transaction_checks::deny::check_transaction_for_validation(
6614            tx,
6615            transaction.signatures(),
6616            &transaction
6617                .input_objects(protocol_config.move_authenticator_type_arg_packages_as_inputs())?,
6618            &tx.receiving_objects(),
6619            deny_config,
6620            self.get_backing_package_store().as_ref(),
6621        )?;
6622
6623        // Step 2: load all input objects (including authenticator + account).
6624        let (tx_input_objects, tx_receiving_objects, per_authenticator_inputs) =
6625            self.read_objects_for_validation(transaction, epoch, protocol_config)?;
6626
6627        // Step 3: get Move authenticators.
6628        let move_authenticators = transaction.move_authenticators();
6629
6630        // Step 4: check inputs (validates gas budget covers auth + tx). When
6631        // `is_execute_transaction_to_effects` is true (attest_transaction), the
6632        // gas budget is metered for full execution; otherwise (signing) it only
6633        // covers authentication.
6634        //
6635        // Only the attest_transaction path consumes the raw per-authenticator
6636        // inputs from `ValidationOutputs` (to recover each
6637        // `AuthenticatorFunctionRefForExecution`);
6638        // `handle_transaction_validation_checks` discards them. So only clone
6639        // for the output when we actually need it, and move the original into
6640        // the input check otherwise.
6641        let per_authenticator_inputs_for_output = if is_execute_transaction_to_effects {
6642            per_authenticator_inputs.clone()
6643        } else {
6644            Vec::new()
6645        };
6646        let (gas_status, tx_checked_input_objects, per_authenticator_checked_inputs) = self
6647            .check_transaction_inputs_for_validation(
6648                protocol_config,
6649                reference_gas_price,
6650                tx,
6651                tx_input_objects,
6652                &tx_receiving_objects,
6653                &move_authenticators,
6654                per_authenticator_inputs,
6655                VerifierLimitsSource::NodeConfig(&self.config.verifier_signing_config),
6656                is_execute_transaction_to_effects,
6657            )?;
6658
6659        // Move authenticators cannot use owned objects, so their inputs never
6660        // acquire owned-object locks.
6661        debug_assert!(
6662            per_authenticator_checked_inputs
6663                .iter()
6664                .all(|(objects, _)| objects.inner().filter_owned_objects().is_empty()),
6665            "Move authenticator input objects must not contain owned objects"
6666        );
6667
6668        // The package holding each authenticate function is known only now that the
6669        // `AuthenticatorFunctionRef`s are loaded, so the deny-list check for it
6670        // stands apart from the one above. It must stay ahead of two things: the
6671        // filtering below, which drops authenticators that do not run
6672        // pre-consensus, so that every authenticator is covered; and the
6673        // authenticator execution itself, so that a denied package is never run.
6674        if protocol_config.deny_authenticator_packages() {
6675            iota_transaction_checks::deny::check_authenticator_packages(
6676                deny_config,
6677                per_authenticator_checked_inputs
6678                    .iter()
6679                    .map(|(_, authenticator_function_ref)| authenticator_function_ref),
6680                self.get_backing_package_store().as_ref(),
6681            )?;
6682        }
6683
6684        // Step 5: coin deny list. Pass raw `&InputObjects` (the deny-list
6685        // check only reads coin types and does not need the
6686        // `CheckedInputObjects` type-state — which is still enforced fresh
6687        // at `check_certificate_input` in `execute_transaction`).
6688        let per_authenticator_input_objects: Vec<&InputObjects> = per_authenticator_checked_inputs
6689            .iter()
6690            .map(|i| i.0.inner())
6691            .collect();
6692        check_coin_deny_list_v1(
6693            tx.sender(),
6694            tx_checked_input_objects.inner(),
6695            &tx_receiving_objects,
6696            &per_authenticator_input_objects,
6697            &self.get_object_store(),
6698        )?;
6699
6700        Ok(ValidationOutputs {
6701            per_authenticator_inputs: per_authenticator_inputs_for_output,
6702            move_authenticators,
6703            gas_status,
6704            tx_checked_input_objects,
6705            per_authenticator_checked_inputs,
6706        })
6707    }
6708
6709    #[allow(clippy::type_complexity)]
6710    fn read_objects_for_validation(
6711        &self,
6712        transaction: &VerifiedTransaction,
6713        epoch: u64,
6714        protocol_config: &ProtocolConfig,
6715    ) -> IotaResult<(
6716        InputObjects,
6717        ReceivingObjects,
6718        Vec<(InputObjects, ObjectReadResult)>,
6719    )> {
6720        let (input_objects, tx_receiving_objects) = self.input_loader.read_objects_for_signing(
6721            Some(transaction.digest()),
6722            &transaction.collect_all_input_object_kind_for_reading(
6723                protocol_config.move_authenticator_type_arg_packages_as_inputs(),
6724            )?,
6725            &transaction.data().transaction().receiving_objects(),
6726            epoch,
6727        )?;
6728
6729        transaction
6730            .split_input_objects_into_groups_for_reading(input_objects)
6731            .map(|(tx_input_objects, per_authenticator_inputs)| {
6732                (
6733                    tx_input_objects,
6734                    tx_receiving_objects,
6735                    per_authenticator_inputs,
6736                )
6737            })
6738    }
6739
6740    /// Like [`Self::read_objects_for_validation`], but for post-consensus
6741    /// validation at the commit `reader` was built for. Every input and every
6742    /// receiving object comes from the commit-indexed reader, the inputs
6743    /// first, so the first of them that decides is reported as at admission.
6744    fn read_objects_for_validation_at_commit(
6745        &self,
6746        reader: &CommitIndexedReader,
6747        transaction: &VerifiedTransaction,
6748        protocol_config: &ProtocolConfig,
6749    ) -> IotaResult<ValidationInputsAtCommit> {
6750        let input_objects = match self.input_loader.read_objects_at_commit(
6751            reader,
6752            &transaction.collect_all_input_object_kind_for_reading(
6753                protocol_config.move_authenticator_type_arg_packages_as_inputs(),
6754            )?,
6755        )? {
6756            InputResolution::Loaded(input_objects) => input_objects,
6757            InputResolution::Drop(kind, reason) => {
6758                return Ok(ValidationInputsAtCommit::Drop(kind, reason));
6759            }
6760            InputResolution::Missing(kind, reason) => {
6761                return Ok(ValidationInputsAtCommit::Missing(kind, reason));
6762            }
6763        };
6764        let tx_receiving_objects = match self.input_loader.read_receiving_objects_at_commit(
6765            reader,
6766            &transaction.data().transaction().receiving_objects(),
6767        )? {
6768            ReceivingObjectsResolution::Loaded(receiving_objects) => receiving_objects,
6769            ReceivingObjectsResolution::Drop(kind, reason) => {
6770                return Ok(ValidationInputsAtCommit::Drop(kind, reason));
6771            }
6772            ReceivingObjectsResolution::Missing(kind, reason) => {
6773                return Ok(ValidationInputsAtCommit::Missing(kind, reason));
6774            }
6775        };
6776
6777        let (tx_input_objects, per_authenticator_inputs) =
6778            transaction.split_input_objects_into_groups_for_reading(input_objects)?;
6779        Ok(ValidationInputsAtCommit::Loaded {
6780            tx_input_objects,
6781            tx_receiving_objects,
6782            per_authenticator_inputs,
6783        })
6784    }
6785
6786    #[allow(clippy::type_complexity)]
6787    fn check_transaction_inputs_for_validation(
6788        &self,
6789        protocol_config: &ProtocolConfig,
6790        reference_gas_price: u64,
6791        tx: &Transaction,
6792        tx_input_objects: InputObjects,
6793        tx_receiving_objects: &ReceivingObjects,
6794        move_authenticators: &Vec<&MoveAuthenticator>,
6795        per_authenticator_inputs: Vec<(InputObjects, ObjectReadResult)>,
6796        verifier_limits_source: VerifierLimitsSource<'_>,
6797        is_execute_transaction_to_effects: bool,
6798    ) -> IotaResult<(
6799        IotaGasStatus,
6800        CheckedInputObjects,
6801        Vec<(CheckedInputObjects, AuthenticatorFunctionRef)>,
6802    )> {
6803        let authenticator_gas_budget = if move_authenticators.is_empty() {
6804            0
6805        } else {
6806            // `max_auth_gas` is used here as a Move authenticator gas budget until it is
6807            // not a part of the transaction data.
6808            protocol_config.max_auth_gas()
6809        };
6810
6811        debug_assert_eq!(
6812            move_authenticators.len(),
6813            per_authenticator_inputs.len(),
6814            "Move authenticators amount must match the number of authenticator inputs"
6815        );
6816
6817        let per_authenticator_checked_inputs = move_authenticators
6818            .iter()
6819            .zip(per_authenticator_inputs)
6820            .map(
6821                |(move_authenticator, (authenticator_input_objects, account_object))| {
6822                    // Check basic `object_to_authenticate` preconditions and get its components.
6823                    let (
6824                        auth_account_object_id,
6825                        auth_account_object_seq_number,
6826                        auth_account_object_digest,
6827                    ) = move_authenticator.object_to_authenticate_components()?;
6828
6829                    let signer = move_authenticator.address();
6830
6831                    // Make sure the signer is a Move account.
6832                    let AuthenticatorFunctionRefForExecution {
6833                        authenticator_function_ref,
6834                        ..
6835                    } = self.check_move_account_for_validation(
6836                        auth_account_object_id,
6837                        auth_account_object_seq_number,
6838                        auth_account_object_digest,
6839                        account_object,
6840                        &signer,
6841                        protocol_config,
6842                    )?;
6843
6844                    // Check the MoveAuthenticator input objects.
6845                    let authenticator_checked_input_objects =
6846                        iota_transaction_checks::check_move_authenticator_input_for_validation(
6847                            authenticator_input_objects,
6848                        )?;
6849
6850                    Ok((
6851                        authenticator_checked_input_objects,
6852                        authenticator_function_ref,
6853                    ))
6854                },
6855            )
6856            .collect::<IotaResult<Vec<_>>>()?;
6857
6858        // Check the transaction inputs.
6859        let (gas_status, tx_checked_input_objects) =
6860            iota_transaction_checks::check_transaction_input(
6861                protocol_config,
6862                reference_gas_price,
6863                tx,
6864                tx_input_objects,
6865                tx_receiving_objects,
6866                &self.metrics.bytecode_verifier_metrics,
6867                verifier_limits_source,
6868                authenticator_gas_budget,
6869                is_execute_transaction_to_effects,
6870            )?;
6871
6872        Ok((
6873            gas_status,
6874            tx_checked_input_objects,
6875            per_authenticator_checked_inputs,
6876        ))
6877    }
6878
6879    /// Like [`Self::check_transaction_inputs_for_validation`], but for
6880    /// post-consensus validation at a commit. One difference: the Move
6881    /// account is not resolved here, only the authenticator's inputs are
6882    /// checked, so no function reference comes back. The receiving objects,
6883    /// read through the commit-indexed reader, get the same checks as at
6884    /// admission.
6885    fn check_transaction_inputs_at_commit(
6886        &self,
6887        protocol_config: &ProtocolConfig,
6888        reference_gas_price: u64,
6889        tx: &Transaction,
6890        tx_input_objects: InputObjects,
6891        tx_receiving_objects: &ReceivingObjects,
6892        move_authenticators: &[&MoveAuthenticator],
6893        per_authenticator_inputs: Vec<(InputObjects, ObjectReadResult)>,
6894        verifier_limits_source: VerifierLimitsSource<'_>,
6895    ) -> IotaResult<CheckedValidationInputs> {
6896        let authenticator_gas_budget = if move_authenticators.is_empty() {
6897            0
6898        } else {
6899            protocol_config.max_auth_gas()
6900        };
6901
6902        debug_assert_eq!(
6903            move_authenticators.len(),
6904            per_authenticator_inputs.len(),
6905            "Move authenticators amount must match the number of authenticator inputs"
6906        );
6907
6908        // The account object is among the authenticator's inputs. An account
6909        // named as a shared object was decided by the reader from its rows,
6910        // which drop the transaction when the object was not created shared.
6911        // An account named as an immutable-or-owned input was read at the
6912        // version the transaction names, and this check rejects one owned by
6913        // an address or by another object. An immutable account is not
6914        // rejected here. Looking up the account's authenticator function is
6915        // left to execution.
6916        let per_authenticator_checked_inputs = per_authenticator_inputs
6917            .into_iter()
6918            .map(|(authenticator_input_objects, _account_object)| {
6919                iota_transaction_checks::check_move_authenticator_input_for_validation(
6920                    authenticator_input_objects,
6921                )
6922            })
6923            .collect::<IotaResult<Vec<_>>>()?;
6924
6925        // The gas status only meters an authenticator run, which does not happen here.
6926        let (_gas_status, tx_checked_input_objects) =
6927            iota_transaction_checks::check_transaction_input(
6928                protocol_config,
6929                reference_gas_price,
6930                tx,
6931                tx_input_objects,
6932                tx_receiving_objects,
6933                &self.metrics.bytecode_verifier_metrics,
6934                verifier_limits_source,
6935                authenticator_gas_budget,
6936                false,
6937            )?;
6938
6939        Ok((tx_checked_input_objects, per_authenticator_checked_inputs))
6940    }
6941
6942    #[cfg(test)]
6943    pub(crate) fn iter_live_object_set_for_testing(
6944        &self,
6945    ) -> impl Iterator<Item = authority_store_tables::LiveObject> + '_ {
6946        self.get_global_state_hash_store()
6947            .iter_cached_live_object_set_for_testing()
6948            .map(|live_object| live_object.expect("reading the live object set cannot fail"))
6949    }
6950
6951    #[cfg(test)]
6952    pub(crate) fn shutdown_execution_for_test(&self) {
6953        self.tx_execution_shutdown
6954            .lock()
6955            .take()
6956            .unwrap()
6957            .send(())
6958            .unwrap();
6959    }
6960
6961    /// NOTE: this function is only to be used for fuzzing and testing. Never
6962    /// use in prod
6963    pub async fn insert_objects_unsafe_for_testing_only(&self, objects: &[Object]) {
6964        self.get_reconfig_api().bulk_insert_genesis_objects(objects);
6965        self.get_object_cache_reader()
6966            .force_reload_system_packages(&BuiltInFramework::all_package_ids());
6967        self.get_reconfig_api()
6968            .clear_state_end_of_epoch(&self.execution_lock_for_reconfiguration().await);
6969    }
6970}
6971
6972pub struct RandomnessRoundReceiver {
6973    authority_state: Arc<AuthorityState>,
6974    randomness_rx: mpsc::Receiver<(EpochId, RandomnessRound, Vec<u8>)>,
6975}
6976
6977impl RandomnessRoundReceiver {
6978    pub fn spawn(
6979        authority_state: Arc<AuthorityState>,
6980        randomness_rx: mpsc::Receiver<(EpochId, RandomnessRound, Vec<u8>)>,
6981    ) -> JoinHandle<()> {
6982        let rrr = RandomnessRoundReceiver {
6983            authority_state,
6984            randomness_rx,
6985        };
6986        spawn_monitored_task!(rrr.run())
6987    }
6988
6989    async fn run(mut self) {
6990        info!("RandomnessRoundReceiver event loop started");
6991
6992        loop {
6993            tokio::select! {
6994                maybe_recv = self.randomness_rx.recv() => {
6995                    if let Some((epoch, round, bytes)) = maybe_recv {
6996                        self.handle_new_randomness(epoch, round, bytes).await;
6997                    } else {
6998                        break;
6999                    }
7000                },
7001            }
7002        }
7003
7004        info!("RandomnessRoundReceiver event loop ended");
7005    }
7006
7007    #[instrument(level = "debug", skip_all, fields(?epoch, ?round))]
7008    async fn handle_new_randomness(&self, epoch: EpochId, round: RandomnessRound, bytes: Vec<u8>) {
7009        fail_point_async!("randomness-delay");
7010
7011        let epoch_store = self.authority_state.load_epoch_store_one_call_per_task();
7012        if epoch_store.epoch() != epoch {
7013            warn!(
7014                "dropping randomness for epoch {epoch}, round {round}, because we are in epoch {}",
7015                epoch_store.epoch()
7016            );
7017            return;
7018        }
7019        let key = TransactionKey::RandomnessRound(epoch, round);
7020        let transaction = VerifiedTransaction::new_randomness_state_update(
7021            epoch,
7022            round,
7023            bytes,
7024            epoch_store
7025                .epoch_start_config()
7026                .randomness_obj_initial_shared_version(),
7027        );
7028        debug!(
7029            "created randomness state update transaction with digest: {:?}",
7030            transaction.digest()
7031        );
7032        let transaction = VerifiedExecutableTransaction::new_system(transaction, epoch);
7033        let digest = *transaction.digest();
7034
7035        // Randomness state updates contain the full bls signature for the random round,
7036        // which cannot necessarily be reconstructed again later. Therefore we must
7037        // immediately persist this transaction. If we crash before its outputs
7038        // are committed, this ensures we will be able to re-execute it.
7039        self.authority_state
7040            .get_cache_commit()
7041            .persist_transaction(&transaction);
7042
7043        // Notify the scheduler that the transaction key now has a known digest
7044        if epoch_store.insert_tx_key(key, digest).is_err() {
7045            warn!("epoch ended while handling new randomness");
7046        }
7047
7048        // TODO: delete this when transaction manager is deleted
7049        match self.authority_state.execution_scheduler().as_ref() {
7050            ExecutionSchedulerWrapper::ExecutionScheduler(_) => {}
7051            ExecutionSchedulerWrapper::TransactionManager(manager) => {
7052                // Notifies transaction manager about transaction and output objects
7053                // committed. This provides necessary information to transaction manager
7054                // to start executing additional ready transactions.
7055                manager.notify_transaction_key(&epoch_store, key, digest);
7056            }
7057        }
7058
7059        let authority_state = self.authority_state.clone();
7060        spawn_monitored_task!(async move {
7061            // Wait for transaction execution in a separate task, to avoid deadlock in case
7062            // of out-of-order randomness generation. (Each
7063            // RandomnessStateUpdate depends on the output of the
7064            // RandomnessStateUpdate from the previous round.)
7065            //
7066            // We set a very long timeout so that in case this gets stuck for some reason,
7067            // the validator will eventually crash rather than continuing in a
7068            // zombie mode.
7069            const RANDOMNESS_STATE_UPDATE_EXECUTION_TIMEOUT: Duration = Duration::from_secs(300);
7070            let result = tokio::time::timeout(
7071                RANDOMNESS_STATE_UPDATE_EXECUTION_TIMEOUT,
7072                authority_state
7073                    .get_transaction_cache_reader()
7074                    .try_notify_read_executed_effects(
7075                        "RandomnessRoundReceiver::notify_read_executed_effects_first",
7076                        &[digest],
7077                    ),
7078            )
7079            .await;
7080            let result = match result {
7081                Ok(result) => result,
7082                Err(_) => {
7083                    if cfg!(debug_assertions) {
7084                        // Crash on randomness update execution timeout in debug builds.
7085                        panic!(
7086                            "randomness state update transaction execution timed out at epoch {epoch}, round {round}"
7087                        );
7088                    }
7089                    warn!(
7090                        "randomness state update transaction execution timed out at epoch {epoch}, round {round}"
7091                    );
7092                    // Continue waiting as long as necessary in non-debug builds.
7093                    authority_state
7094                        .get_transaction_cache_reader()
7095                        .try_notify_read_executed_effects(
7096                            "RandomnessRoundReceiver::notify_read_executed_effects_second",
7097                            &[digest],
7098                        )
7099                        .await
7100                }
7101            };
7102
7103            let mut effects = result.unwrap_or_else(|_| panic!("failed to get effects for randomness state update transaction at epoch {epoch}, round {round}"));
7104            let effects = effects.pop().expect("should return effects");
7105            if *effects.status() != ExecutionStatus::Success {
7106                fatal!(
7107                    "failed to execute randomness state update transaction at epoch {epoch}, round {round}: {effects:?}"
7108                );
7109            }
7110            debug!(
7111                "successfully executed randomness state update transaction at epoch {epoch}, round {round}"
7112            );
7113        });
7114    }
7115}
7116
7117#[async_trait]
7118impl TransactionKeyValueStoreTrait for AuthorityState {
7119    async fn multi_get(
7120        &self,
7121        transaction_keys: &[TransactionDigest],
7122        effects_keys: &[TransactionDigest],
7123    ) -> IotaResult<KVStoreTransactionData> {
7124        let txns = if !transaction_keys.is_empty() {
7125            self.get_transaction_cache_reader()
7126                .try_multi_get_transaction_blocks(transaction_keys)?
7127                .into_iter()
7128                .map(|t| t.map(|t| (*t).clone().into_inner()))
7129                .collect()
7130        } else {
7131            vec![]
7132        };
7133
7134        let fx = if !effects_keys.is_empty() {
7135            self.get_transaction_cache_reader()
7136                .try_multi_get_executed_effects(effects_keys)?
7137        } else {
7138            vec![]
7139        };
7140
7141        Ok((txns, fx))
7142    }
7143
7144    async fn multi_get_checkpoints(
7145        &self,
7146        checkpoint_summaries: &[CheckpointSequenceNumber],
7147        checkpoint_contents: &[CheckpointSequenceNumber],
7148        checkpoint_summaries_by_digest: &[CheckpointDigest],
7149    ) -> IotaResult<(
7150        Vec<Option<CertifiedCheckpointSummary>>,
7151        Vec<Option<CheckpointContents>>,
7152        Vec<Option<CertifiedCheckpointSummary>>,
7153    )> {
7154        // TODO: use multi-get methods if it ever becomes important (unlikely)
7155        let mut summaries = Vec::with_capacity(checkpoint_summaries.len());
7156        let store = self.get_checkpoint_store();
7157        for seq in checkpoint_summaries {
7158            let checkpoint = store
7159                .get_checkpoint_by_sequence_number(*seq)?
7160                .map(|c| c.into_inner());
7161
7162            summaries.push(checkpoint);
7163        }
7164
7165        let mut contents = Vec::with_capacity(checkpoint_contents.len());
7166        for seq in checkpoint_contents {
7167            let checkpoint = store
7168                .get_checkpoint_by_sequence_number(*seq)?
7169                .and_then(|summary| {
7170                    store
7171                        .get_checkpoint_contents(&summary.contents_digest)
7172                        .expect("db read cannot fail")
7173                });
7174            contents.push(checkpoint);
7175        }
7176
7177        let mut summaries_by_digest = Vec::with_capacity(checkpoint_summaries_by_digest.len());
7178        for digest in checkpoint_summaries_by_digest {
7179            let checkpoint = store
7180                .get_checkpoint_by_digest(digest)?
7181                .map(|c| c.into_inner());
7182            summaries_by_digest.push(checkpoint);
7183        }
7184
7185        Ok((summaries, contents, summaries_by_digest))
7186    }
7187
7188    async fn get_transaction_perpetual_checkpoint(
7189        &self,
7190        digest: TransactionDigest,
7191    ) -> IotaResult<Option<CheckpointSequenceNumber>> {
7192        self.get_checkpoint_cache()
7193            .try_get_transaction_perpetual_checkpoint(&digest)
7194            .map(|res| res.map(|(_epoch, checkpoint)| checkpoint))
7195    }
7196
7197    async fn get_object(
7198        &self,
7199        object_id: ObjectId,
7200        version: VersionNumber,
7201    ) -> IotaResult<Option<Object>> {
7202        self.get_object_with_historic_fallback(&ObjectKey(object_id, version))
7203    }
7204
7205    #[instrument(skip_all)]
7206    async fn multi_get_objects(
7207        &self,
7208        object_keys: &[ObjectKey],
7209    ) -> IotaResult<Vec<Option<Object>>> {
7210        let mut objects = self
7211            .get_object_cache_reader()
7212            .multi_get_objects_by_key(object_keys);
7213        self.historic_objects
7214            .fill_missing(object_keys, &mut objects, None)?;
7215        Ok(objects)
7216    }
7217
7218    async fn multi_get_transactions_perpetual_checkpoints(
7219        &self,
7220        digests: &[TransactionDigest],
7221    ) -> IotaResult<Vec<Option<CheckpointSequenceNumber>>> {
7222        let res = self
7223            .get_checkpoint_cache()
7224            .try_multi_get_transactions_perpetual_checkpoints(digests)?;
7225
7226        Ok(res
7227            .into_iter()
7228            .map(|maybe| maybe.map(|(_epoch, checkpoint)| checkpoint))
7229            .collect())
7230    }
7231
7232    #[instrument(skip(self, digests), fields(digests = digests.iter().map(|d| d.to_string()).collect::<Vec<String>>().join(", ")))]
7233    async fn multi_get_events_by_tx_digests(
7234        &self,
7235        digests: &[TransactionDigest],
7236    ) -> IotaResult<Vec<Option<TransactionEvents>>> {
7237        if digests.is_empty() {
7238            return Ok(vec![]);
7239        }
7240
7241        Ok(self
7242            .get_transaction_cache_reader()
7243            .multi_get_events(digests))
7244    }
7245}
7246
7247#[cfg(msim)]
7248pub mod framework_injection {
7249    use std::{
7250        cell::RefCell,
7251        collections::{BTreeMap, BTreeSet},
7252    };
7253
7254    use iota_framework::{BuiltInFramework, SystemPackage};
7255    use iota_sdk_types::ObjectId;
7256    use iota_types::base_types::AuthorityName;
7257    use move_binary_format::CompiledModule;
7258
7259    type FrameworkOverrideConfig = BTreeMap<ObjectId, PackageOverrideConfig>;
7260
7261    // Thread local cache because all simtests run in a single unique thread.
7262    thread_local! {
7263        static OVERRIDE: RefCell<FrameworkOverrideConfig> = RefCell::new(FrameworkOverrideConfig::default());
7264    }
7265
7266    type Framework = Vec<CompiledModule>;
7267
7268    pub type PackageUpgradeCallback =
7269        Box<dyn Fn(AuthorityName) -> Option<Framework> + Send + Sync + 'static>;
7270
7271    enum PackageOverrideConfig {
7272        Global(Framework),
7273        PerValidator(PackageUpgradeCallback),
7274    }
7275
7276    fn compiled_modules_to_bytes(modules: &[CompiledModule]) -> Vec<Vec<u8>> {
7277        modules
7278            .iter()
7279            .map(|m| {
7280                let mut buf = Vec::new();
7281                m.serialize_with_version(m.version, &mut buf).unwrap();
7282                buf
7283            })
7284            .collect()
7285    }
7286
7287    pub fn set_override(package_id: ObjectId, modules: Vec<CompiledModule>) {
7288        OVERRIDE.with(|bs| {
7289            bs.borrow_mut()
7290                .insert(package_id, PackageOverrideConfig::Global(modules))
7291        });
7292    }
7293
7294    pub fn set_override_cb(package_id: ObjectId, func: PackageUpgradeCallback) {
7295        OVERRIDE.with(|bs| {
7296            bs.borrow_mut()
7297                .insert(package_id, PackageOverrideConfig::PerValidator(func))
7298        });
7299    }
7300
7301    pub fn get_override_bytes(package_id: &ObjectId, name: AuthorityName) -> Option<Vec<Vec<u8>>> {
7302        OVERRIDE.with(|cfg| {
7303            cfg.borrow().get(package_id).and_then(|entry| match entry {
7304                PackageOverrideConfig::Global(framework) => {
7305                    Some(compiled_modules_to_bytes(framework))
7306                }
7307                PackageOverrideConfig::PerValidator(func) => {
7308                    func(name).map(|fw| compiled_modules_to_bytes(&fw))
7309                }
7310            })
7311        })
7312    }
7313
7314    pub fn get_override_modules(
7315        package_id: &ObjectId,
7316        name: AuthorityName,
7317    ) -> Option<Vec<CompiledModule>> {
7318        OVERRIDE.with(|cfg| {
7319            cfg.borrow().get(package_id).and_then(|entry| match entry {
7320                PackageOverrideConfig::Global(framework) => Some(framework.clone()),
7321                PackageOverrideConfig::PerValidator(func) => func(name),
7322            })
7323        })
7324    }
7325
7326    pub fn get_override_system_package(
7327        package_id: &ObjectId,
7328        name: AuthorityName,
7329    ) -> Option<SystemPackage> {
7330        let bytes = get_override_bytes(package_id, name)?;
7331        // A built-in package keeps the dependencies it declares. Anything else is a
7332        // package being added -- including one at a system address that is not built in
7333        // yet -- and is assumed to depend on all existing system packages.
7334        let dependencies = BuiltInFramework::try_get_package_by_id(package_id)
7335            .map_or_else(BuiltInFramework::all_package_ids, |package| {
7336                package.dependencies.to_vec()
7337            });
7338        Some(SystemPackage {
7339            id: *package_id,
7340            bytes,
7341            dependencies,
7342        })
7343    }
7344
7345    pub fn get_extra_packages(name: AuthorityName) -> Vec<SystemPackage> {
7346        let built_in = BTreeSet::from_iter(BuiltInFramework::all_package_ids());
7347        let extra: Vec<ObjectId> = OVERRIDE.with(|cfg| {
7348            cfg.borrow()
7349                .keys()
7350                .filter_map(|package| (!built_in.contains(package)).then_some(*package))
7351                .collect()
7352        });
7353
7354        extra
7355            .into_iter()
7356            .map(|package| SystemPackage {
7357                id: package,
7358                bytes: get_override_bytes(&package, name).unwrap(),
7359                dependencies: BuiltInFramework::all_package_ids(),
7360            })
7361            .collect()
7362    }
7363}
7364
7365#[derive(Debug, Serialize, Deserialize, Clone)]
7366pub struct ObjDumpFormat {
7367    pub id: ObjectId,
7368    pub version: VersionNumber,
7369    pub digest: ObjectDigest,
7370    pub object: Object,
7371}
7372
7373impl ObjDumpFormat {
7374    fn new(object: Object) -> Self {
7375        let oref = object.object_ref();
7376        Self {
7377            id: oref.object_id,
7378            version: oref.version,
7379            digest: oref.digest,
7380            object,
7381        }
7382    }
7383}
7384
7385#[derive(Debug, Serialize, Deserialize, Clone)]
7386pub struct NodeStateDump {
7387    pub tx_digest: TransactionDigest,
7388    pub sender_signed_data: SenderSignedTransaction,
7389    pub executed_epoch: u64,
7390    pub reference_gas_price: u64,
7391    pub protocol_version: u64,
7392    pub epoch_start_timestamp_ms: u64,
7393    pub computed_effects: TransactionEffects,
7394    pub expected_effects_digest: TransactionEffectsDigest,
7395    pub relevant_system_packages: Vec<ObjDumpFormat>,
7396    pub shared_objects: Vec<ObjDumpFormat>,
7397    pub loaded_child_objects: Vec<ObjDumpFormat>,
7398    pub modified_at_versions: Vec<ObjDumpFormat>,
7399    pub runtime_reads: Vec<ObjDumpFormat>,
7400    pub input_objects: Vec<ObjDumpFormat>,
7401}
7402
7403impl NodeStateDump {
7404    pub fn new(
7405        tx_digest: &TransactionDigest,
7406        effects: &TransactionEffects,
7407        expected_effects_digest: TransactionEffectsDigest,
7408        object_store: &dyn ObjectStore,
7409        epoch_store: &Arc<AuthorityPerEpochStore>,
7410        inner_temporary_store: &InnerTemporaryStore,
7411        transaction: &VerifiedExecutableTransaction,
7412    ) -> IotaResult<Self> {
7413        // Epoch info
7414        let executed_epoch = epoch_store.epoch();
7415        let reference_gas_price = epoch_store.reference_gas_price();
7416        let epoch_start_config = epoch_store.epoch_start_config();
7417        let protocol_version = epoch_store.protocol_version().as_u64();
7418        let epoch_start_timestamp_ms = epoch_start_config.epoch_data().epoch_start_timestamp();
7419
7420        // Record all system packages at this version
7421        let mut relevant_system_packages = Vec::new();
7422        for sys_package_id in BuiltInFramework::all_package_ids() {
7423            if let Some(w) = object_store.try_get_object(&sys_package_id)? {
7424                relevant_system_packages.push(ObjDumpFormat::new(w))
7425            }
7426        }
7427
7428        // Record all the shared objects
7429        let mut shared_objects = Vec::new();
7430        for kind in effects.input_shared_objects() {
7431            match kind {
7432                InputSharedObject::Mutate(obj_ref) | InputSharedObject::ReadOnly(obj_ref) => {
7433                    if let Some(w) =
7434                        object_store.try_get_object_by_key(&obj_ref.object_id, obj_ref.version)?
7435                    {
7436                        shared_objects.push(ObjDumpFormat::new(w))
7437                    }
7438                }
7439                InputSharedObject::ReadDeleted(..)
7440                | InputSharedObject::MutateDeleted(..)
7441                // TODO: consider record congested objects.
7442                | InputSharedObject::Canceled(..) => (),
7443                _ => unimplemented!(
7444                    "a new InputSharedObject enum variant was added and needs to be handled"
7445                ),
7446            }
7447        }
7448
7449        // Record all loaded child objects
7450        // Child objects which are read but not mutated are not tracked anywhere else
7451        let mut loaded_child_objects = Vec::new();
7452        for (id, meta) in &inner_temporary_store.loaded_runtime_objects {
7453            if let Some(w) = object_store.try_get_object_by_key(id, meta.version)? {
7454                loaded_child_objects.push(ObjDumpFormat::new(w))
7455            }
7456        }
7457
7458        // Record all modified objects
7459        let mut modified_at_versions = Vec::new();
7460        for modified in effects.modified_at_versions() {
7461            let (id, ver) = (modified.object_id(), modified.version());
7462            if let Some(w) = object_store.try_get_object_by_key(id, ver)? {
7463                modified_at_versions.push(ObjDumpFormat::new(w))
7464            }
7465        }
7466
7467        // Packages read at runtime, which were not previously loaded into the temoorary
7468        // store Some packages may be fetched at runtime and wont show up in
7469        // input objects
7470        let mut runtime_reads = Vec::new();
7471        for obj in inner_temporary_store
7472            .runtime_packages_loaded_from_db
7473            .values()
7474        {
7475            runtime_reads.push(ObjDumpFormat::new(obj.object().clone()));
7476        }
7477
7478        // All other input objects should already be in `inner_temporary_store.objects`
7479
7480        Ok(Self {
7481            tx_digest: *tx_digest,
7482            executed_epoch,
7483            reference_gas_price,
7484            epoch_start_timestamp_ms,
7485            protocol_version,
7486            relevant_system_packages,
7487            shared_objects,
7488            loaded_child_objects,
7489            modified_at_versions,
7490            runtime_reads,
7491            sender_signed_data: transaction.clone().into_message(),
7492            input_objects: inner_temporary_store
7493                .input_objects
7494                .values()
7495                .map(|o| ObjDumpFormat::new(o.clone()))
7496                .collect(),
7497            computed_effects: effects.clone(),
7498            expected_effects_digest,
7499        })
7500    }
7501
7502    pub fn all_objects(&self) -> Vec<ObjDumpFormat> {
7503        let mut objects = Vec::new();
7504        objects.extend(self.relevant_system_packages.clone());
7505        objects.extend(self.shared_objects.clone());
7506        objects.extend(self.loaded_child_objects.clone());
7507        objects.extend(self.modified_at_versions.clone());
7508        objects.extend(self.runtime_reads.clone());
7509        objects.extend(self.input_objects.clone());
7510        objects
7511    }
7512
7513    pub fn write_to_file(&self, path: &Path) -> Result<PathBuf, anyhow::Error> {
7514        let file_name = format!(
7515            "{}_{}_NODE_DUMP.json",
7516            self.tx_digest,
7517            AuthorityState::unixtime_now_ms()
7518        );
7519        let mut path = path.to_path_buf();
7520        path.push(&file_name);
7521        let mut file = File::create(path.clone())?;
7522        file.write_all(serde_json::to_string_pretty(self)?.as_bytes())?;
7523        Ok(path)
7524    }
7525
7526    pub fn read_from_file(path: &PathBuf) -> Result<Self, anyhow::Error> {
7527        let file = File::open(path)?;
7528        serde_json::from_reader(file).map_err(|e| anyhow::anyhow!(e))
7529    }
7530}
7531
7532/// The reason [`AuthorityState::check_move_account`] failed.
7533/// Execution treats the two cases differently, because only
7534/// the first one is about the transaction.
7535enum MoveAccountCheckError {
7536    /// The account fails a check.
7537    Input(UserInputError),
7538
7539    /// This validator failed to read its store.
7540    Storage(IotaError),
7541}
7542
7543impl From<UserInputError> for MoveAccountCheckError {
7544    fn from(error: UserInputError) -> Self {
7545        Self::Input(error)
7546    }
7547}
7548
7549impl From<MoveAccountCheckError> for IotaError {
7550    fn from(error: MoveAccountCheckError) -> Self {
7551        match error {
7552            MoveAccountCheckError::Input(error) => IotaError::UserInput { error },
7553            MoveAccountCheckError::Storage(error) => error,
7554        }
7555    }
7556}
7557
7558/// Returns the [`MoveAuthenticator`]s to execute during the pre-consensus
7559/// phase.
7560///
7561/// When `pre_consensus_sponsor_only_move_authentication` is enabled:
7562/// - For sponsored transactions: only the sponsor's [`MoveAuthenticator`] is returned (empty if the
7563///   sponsor does not use one).
7564/// - For non-sponsored transactions: all [`MoveAuthenticator`]s are returned (currently only the
7565///   sender's).
7566///
7567/// When the flag is not set, all [`MoveAuthenticator`]s are returned for
7568/// compatibility.
7569fn pre_consensus_move_authenticators<'a>(
7570    tx: &'a VerifiedTransaction,
7571    protocol_config: &ProtocolConfig,
7572) -> Vec<&'a MoveAuthenticator> {
7573    if protocol_config.pre_consensus_sponsor_only_move_authentication() {
7574        if tx.transaction().is_sponsored_tx() {
7575            if let Some(sponsor_move_authenticator) = tx.sponsor_move_authenticator() {
7576                vec![sponsor_move_authenticator]
7577            } else {
7578                vec![]
7579            }
7580        } else {
7581            tx.move_authenticators()
7582        }
7583    } else {
7584        tx.move_authenticators()
7585    }
7586}