Skip to content

Commit aa6978b

Browse files
committed
feat: use SenderSignedData input objects
1 parent 07fdff2 commit aa6978b

File tree

8 files changed

+64
-43
lines changed

8 files changed

+64
-43
lines changed

crates/iota-analytics-indexer/src/handlers/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,11 @@ impl InputObjectTracker {
9797
.collect();
9898
let tx_data = txn.transaction_data();
9999
let coins: BTreeSet<ObjectID> = tx_data.gas().iter().map(|obj_ref| obj_ref.0).collect();
100-
let input: BTreeSet<ObjectID> = tx_data
100+
// All input objects (transaction + authenticators) are collected here, just
101+
// like the shared objects previously.
102+
let input: BTreeSet<ObjectID> = txn
101103
.input_objects()
102104
.expect("Input objects must be valid")
103-
.iter()
104105
.map(|io_kind| io_kind.object_id())
105106
.collect();
106107
Self {

crates/iota-analytics-indexer/src/handlers/transaction_handler.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,11 @@ impl TransactionHandler {
154154
is_sponsored_tx,
155155
transaction_count: txn_data.kind().num_commands() as u64,
156156
execution_success: effects.status().is_ok(),
157-
input: txn_data
157+
// Calculate all objects(transaction + authenticators) amount.
158+
input: transaction
158159
.input_objects()
159160
.expect("Input objects must be valid")
160-
.len() as u64,
161+
.count() as u64,
161162
shared_input: transaction.shared_input_objects().count() as u64,
162163
gas_coins: txn_data.gas().len() as u64,
163164
created: effects.created().len() as u64,

crates/iota-analytics-indexer/src/handlers/transaction_objects_handler.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use iota_types::{
1010
base_types::ObjectID,
1111
effects::TransactionEffects,
1212
full_checkpoint_content::{CheckpointData, CheckpointTransaction},
13-
transaction::TransactionDataAPI,
1413
};
1514
use tokio::sync::Mutex;
1615

@@ -97,13 +96,14 @@ impl TransactionObjectsHandler {
9796
let object_status_tracker = ObjectStatusTracker::new(effects);
9897

9998
let transaction_digest = transaction.digest().base58_encode();
100-
let txn_data = transaction.transaction_data();
10199

102100
// input
103-
txn_data
101+
//
102+
// Process all objects associated with the transaction, including authenticator
103+
// inputs.
104+
transaction
104105
.input_objects()
105106
.expect("Input objects must be valid")
106-
.iter()
107107
.map(|object| (object.object_id(), object.version().map(|v| v.value())))
108108
.for_each(|(object_id, version)| {
109109
self.process_transaction_object(

crates/iota-core/src/authority.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -889,14 +889,17 @@ impl AuthorityState {
889889

890890
let tx_data = transaction.data().transaction_data();
891891

892+
let tx_and_auth_input_objects = transaction.input_objects()?.collect::<Vec<_>>();
893+
let tx_receiving_objects = tx_data.receiving_objects();
894+
892895
// Note: the deny checks may do redundant package loads but:
893896
// - they only load packages when there is an active package deny map
894897
// - the loads are cached anyway
895898
iota_transaction_checks::deny::check_transaction_for_signing(
896899
tx_data,
897900
transaction.tx_signatures(),
898-
&tx_data.input_objects()?,
899-
&tx_data.receiving_objects(),
901+
&tx_and_auth_input_objects,
902+
&tx_receiving_objects,
900903
&self.config.transaction_deny_config,
901904
self.get_backing_package_store().as_ref(),
902905
)?;
@@ -905,8 +908,13 @@ impl AuthorityState {
905908
// Authenticator input objects and the account object are loaded in the same
906909
// call if there is a sender `MoveAuthenticator` signature present in the
907910
// transaction.
908-
let (tx_input_objects, tx_receiving_objects, auth_input_objects, account_object) =
909-
self.read_objects_for_signing(&transaction, epoch)?;
911+
let (tx_input_objects, tx_receiving_objects, auth_input_objects, account_object) = self
912+
.read_objects_for_signing(
913+
&transaction,
914+
&tx_and_auth_input_objects,
915+
&tx_receiving_objects,
916+
epoch,
917+
)?;
910918

911919
// Get the sender `MoveAuthenticator`, if any.
912920
// Only one `MoveAuthenticator` signature is possible, since it is not
@@ -1182,12 +1190,15 @@ impl AuthorityState {
11821190
let observed_effects_digest = observed_effects.digest();
11831191
if &observed_effects_digest != expected_effects_digest {
11841192
panic!(
1185-
"Locally executed effects do not match canonical effects! expected_effects_digest={:?} observed_effects_digest={:?} expected_effects={:?} observed_effects={:?} input_objects={:?}",
1193+
"Locally executed effects do not match canonical effects! expected_effects_digest={:?} observed_effects_digest={:?} expected_effects={:?} observed_effects={:?} transaction_input_objects={:?} authenticator_input_objects={:?}",
11861194
expected_effects_digest,
11871195
observed_effects_digest,
11881196
effects.data(),
11891197
observed_effects,
1190-
transaction.data().transaction_data().input_objects()
1198+
transaction.data().transaction_data().input_objects(),
1199+
transaction
1200+
.sender_move_authenticator()
1201+
.map(|a| a.input_objects())
11911202
);
11921203
}
11931204
Ok(())
@@ -1314,7 +1325,7 @@ impl AuthorityState {
13141325
.execution_load_input_objects_latency
13151326
.start_timer();
13161327

1317-
let input_objects = certificate.collect_all_inputs()?;
1328+
let input_objects = certificate.input_objects()?.collect::<Vec<_>>();
13181329

13191330
let input_objects = self.input_loader.read_objects_for_execution(
13201331
epoch_store,
@@ -5454,6 +5465,8 @@ impl AuthorityState {
54545465
fn read_objects_for_signing(
54555466
&self,
54565467
transaction: &VerifiedTransaction,
5468+
input_object_kinds: &[InputObjectKind],
5469+
receiving_objects: &[ObjectRef],
54575470
epoch: u64,
54585471
) -> IotaResult<(
54595472
InputObjects,
@@ -5463,8 +5476,8 @@ impl AuthorityState {
54635476
)> {
54645477
let (input_objects, tx_receiving_objects) = self.input_loader.read_objects_for_signing(
54655478
Some(transaction.digest()),
5466-
&transaction.collect_all_inputs()?,
5467-
&transaction.data().transaction_data().receiving_objects(),
5479+
&input_object_kinds,
5480+
&receiving_objects,
54685481
epoch,
54695482
)?;
54705483

crates/iota-core/src/transaction_manager.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,12 +449,12 @@ impl TransactionManager {
449449
certs
450450
.into_iter()
451451
.filter_map(|(cert, fx_digest)| {
452+
// Check availability of all transaction associated input objects(transaction +
453+
// authenticators).
452454
let input_object_kinds = cert
453-
.data()
454-
.intent_message()
455-
.value
456455
.input_objects()
457-
.expect("input_objects() cannot fail");
456+
.expect("input_objects() cannot fail")
457+
.collect::<Vec<_>>();
458458
let mut input_object_keys = match epoch_store
459459
.get_input_object_keys(&cert.key(), &input_object_kinds)
460460
{

crates/iota-types/src/move_authenticator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ impl MoveAuthenticator {
123123
}
124124

125125
pub fn input_objects(&self) -> Vec<InputObjectKind> {
126+
// TODO: validate uniqueness as it is done for transaction input objects.
126127
self.call_args
127128
.iter()
128129
.flat_map(|arg| arg.input_objects())

crates/iota-types/src/storage/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,10 +529,7 @@ pub fn transaction_non_shared_input_object_keys(
529529
) -> IotaResult<Vec<ObjectKey>> {
530530
use crate::transaction::InputObjectKind as I;
531531
Ok(tx
532-
.intent_message()
533-
.value
534532
.input_objects()?
535-
.into_iter()
536533
.filter_map(|object| match object {
537534
I::MovePackage(_) | I::SharedMoveObject { .. } => None,
538535
I::ImmOrOwnedMoveObject(obj) => Some(obj.into()),

crates/iota-types/src/transaction.rs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,25 +2528,6 @@ impl SenderSignedData {
25282528
})
25292529
}
25302530

2531-
/// Returns all input objects including those from the sender
2532-
/// `MoveAuthenticator` if any.
2533-
pub fn collect_all_inputs(&self) -> IotaResult<Vec<InputObjectKind>> {
2534-
if let Some(move_authenticator) = self.sender_move_authenticator() {
2535-
let mut input_objects_set = self
2536-
.transaction_data()
2537-
.input_objects()?
2538-
.into_iter()
2539-
.collect::<HashSet<_>>();
2540-
2541-
input_objects_set.extend(move_authenticator.input_objects());
2542-
input_objects_set.extend(move_authenticator.object_to_authenticate().input_objects());
2543-
2544-
Ok(input_objects_set.into_iter().collect::<Vec<_>>())
2545-
} else {
2546-
Ok(self.transaction_data().input_objects()?)
2547-
}
2548-
}
2549-
25502531
/// Splits the provided input objects into three groups:
25512532
/// 1. Input objects required by the transaction itself.
25522533
/// 2. Input objects required by the sender `MoveAuthenticator`.
@@ -2646,6 +2627,33 @@ impl SenderSignedData {
26462627
.unique()
26472628
}
26482629

2630+
/// Returns an iterator over all input objects related to this
2631+
/// transaction, including those from the `MoveAuthenticator` if any.
2632+
pub fn input_objects(&self) -> IotaResult<impl Iterator<Item = InputObjectKind> + '_> {
2633+
// Add the Move authenticator input objects if any.
2634+
let authenticator_input_objects =
2635+
if let Some(move_authenticator) = self.sender_move_authenticator() {
2636+
move_authenticator
2637+
.input_objects()
2638+
.into_iter()
2639+
// Add `object_to_authenticate` input object.
2640+
.chain(move_authenticator.object_to_authenticate().input_objects())
2641+
.collect::<Vec<_>>()
2642+
.into_iter()
2643+
} else {
2644+
Vec::new().into_iter()
2645+
};
2646+
2647+
Ok(self
2648+
.inner()
2649+
.intent_message
2650+
.value
2651+
.input_objects()?
2652+
.into_iter()
2653+
.chain(authenticator_input_objects)
2654+
.unique())
2655+
}
2656+
26492657
/// Checks if `SenderSignedData` contains the `Random` object as an
26502658
/// input.
26512659
/// This function checks shared objects from the `MoveAuthenticator` if any.

0 commit comments

Comments
 (0)