Skip to content

Commit

Permalink
Updated api types to support automated transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
Aregnaz Harutyunyan committed Nov 25, 2024
1 parent f216e39 commit 03f2801
Show file tree
Hide file tree
Showing 18 changed files with 3,619 additions and 2,568 deletions.
6 changes: 5 additions & 1 deletion api/types/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl<'a, S: StateView> MoveConverter<'a, S> {
) -> Result<Transaction> {
use aptos_types::transaction::Transaction::{
BlockEpilogue, BlockMetadata, BlockMetadataExt, GenesisTransaction, StateCheckpoint,
UserTransaction,
UserTransaction, AutomatedTransaction
};
let aux_data = self
.db
Expand Down Expand Up @@ -234,6 +234,10 @@ impl<'a, S: StateView> MoveConverter<'a, S> {
aptos_types::transaction::Transaction::ValidatorTransaction(txn) => {
Transaction::ValidatorTransaction((txn, info, events, timestamp).into())
},
AutomatedTransaction(automated_txn) => {
let payload = self.try_into_transaction_payload(automated_txn.payload().clone())?;
(&automated_txn, info, payload, events, timestamp).into()
},
})
}

Expand Down
78 changes: 78 additions & 0 deletions api/types/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use aptos_types::{
jwks::{jwk::JWK, ProviderJWKs, QuorumCertifiedUpdate},
keyless,
transaction::{
automated_transaction::AutomatedTransaction as UserAutomatedTransaction,
authenticator::{
AccountAuthenticator, AnyPublicKey, AnySignature, MultiKey, MultiKeyAuthenticator,
SingleKeyAuthenticator, TransactionAuthenticator, MAX_NUM_OF_SIGS,
Expand Down Expand Up @@ -177,6 +178,7 @@ impl
pub enum Transaction {
PendingTransaction(PendingTransaction),
UserTransaction(Box<UserTransaction>),
AutomatedTransaction(Box<AutomatedTransaction>),
GenesisTransaction(GenesisTransaction),
BlockMetadataTransaction(BlockMetadataTransaction),
StateCheckpointTransaction(StateCheckpointTransaction),
Expand All @@ -194,6 +196,7 @@ impl Transaction {
Transaction::StateCheckpointTransaction(txn) => txn.timestamp.0,
Transaction::BlockEpilogueTransaction(txn) => txn.timestamp.0,
Transaction::ValidatorTransaction(txn) => txn.timestamp().0,
Transaction::AutomatedTransaction(txn) => {txn.timestamp.0}
}
}

Expand All @@ -206,6 +209,7 @@ impl Transaction {
Transaction::StateCheckpointTransaction(txn) => Some(txn.info.version.into()),
Transaction::BlockEpilogueTransaction(txn) => Some(txn.info.version.into()),
Transaction::ValidatorTransaction(txn) => Some(txn.transaction_info().version.into()),
Transaction::AutomatedTransaction(txn ) => Some(txn.info.version.into()),
}
}

Expand All @@ -218,6 +222,7 @@ impl Transaction {
Transaction::StateCheckpointTransaction(txn) => txn.info.success,
Transaction::BlockEpilogueTransaction(txn) => txn.info.success,
Transaction::ValidatorTransaction(txn) => txn.transaction_info().success,
Transaction::AutomatedTransaction(txn) => txn.info.success,
}
}

Expand All @@ -234,6 +239,7 @@ impl Transaction {
Transaction::StateCheckpointTransaction(txn) => txn.info.vm_status.clone(),
Transaction::BlockEpilogueTransaction(txn) => txn.info.vm_status.clone(),
Transaction::ValidatorTransaction(txn) => txn.transaction_info().vm_status.clone(),
Transaction::AutomatedTransaction(txn) => txn.info.vm_status.clone(),
}
}

Expand All @@ -246,6 +252,7 @@ impl Transaction {
Transaction::StateCheckpointTransaction(_) => "state_checkpoint_transaction",
Transaction::BlockEpilogueTransaction(_) => "block_epilogue_transaction",
Transaction::ValidatorTransaction(vt) => vt.type_str(),
Transaction::AutomatedTransaction(_) => "automated_transaction",
}
}

Expand All @@ -260,6 +267,7 @@ impl Transaction {
Transaction::StateCheckpointTransaction(txn) => &txn.info,
Transaction::BlockEpilogueTransaction(txn) => &txn.info,
Transaction::ValidatorTransaction(txn) => txn.transaction_info(),
Transaction::AutomatedTransaction(txn) => &txn.info,
})
}
}
Expand Down Expand Up @@ -301,6 +309,37 @@ impl
}
}

impl
From<(
&UserAutomatedTransaction,
TransactionInfo,
TransactionPayload,
Vec<Event>,
u64,
)> for Transaction
{
fn from(
(txn, info, payload, events, timestamp): (
&UserAutomatedTransaction,
TransactionInfo,
TransactionPayload,
Vec<Event>,
u64,
),
) -> Self {
// If at some point Aptos will utilize Automation transactions then here we will use as
// registration hash(the hash of the transaction which registered this automation task)
// transaction hash calculated in Aptos-style,
// i.e Transaction::AutomatedTransaction(txn).hash() which is stored in TransactionInfo
Transaction::AutomatedTransaction(Box::new(AutomatedTransaction {
meta: (info.hash.clone(), txn, payload).into(),
info,
events,
timestamp: timestamp.into(),
}))
}
}

impl From<(TransactionInfo, WriteSetPayload, Vec<Event>)> for Transaction {
fn from((info, payload, events): (TransactionInfo, WriteSetPayload, Vec<Event>)) -> Self {
Transaction::GenesisTransaction(GenesisTransaction {
Expand Down Expand Up @@ -357,6 +396,20 @@ impl From<(&SignedTransaction, TransactionPayload)> for UserTransactionRequest {
}
}

impl From<(HashValue, &UserAutomatedTransaction, TransactionPayload)> for AutomatedTaskMeta {
fn from((registration_hash, txn, payload): (HashValue, &UserAutomatedTransaction, TransactionPayload)) -> Self {
Self {
sender: txn.sender().into(),
index: txn.sequence_number().into(),
max_gas_amount: txn.max_gas_amount().into(),
gas_unit_price: txn.gas_unit_price().into(),
expiration_timestamp_secs: txn.expiration_timestamp_secs().into(),
registration_hash,
payload,
}
}
}

/// Information related to how a transaction affected the state of the blockchain
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)]
pub struct TransactionInfo {
Expand Down Expand Up @@ -415,6 +468,20 @@ pub struct UserTransaction {
pub timestamp: U64,
}

/// A transaction registered by a user to run periodically in automated manner
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)]
pub struct AutomatedTransaction {
#[serde(flatten)]
#[oai(flatten)]
pub info: TransactionInfo,
#[serde(flatten)]
#[oai(flatten)]
pub meta: AutomatedTaskMeta,
/// Events generated by the transaction
pub events: Vec<Event>,
pub timestamp: U64,
}

/// A state checkpoint transaction
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)]
pub struct StateCheckpointTransaction {
Expand Down Expand Up @@ -516,6 +583,17 @@ pub struct UserTransactionRequest {
pub signature: Option<TransactionSignature>,
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)]
pub struct AutomatedTaskMeta {
pub sender: Address,
pub index: U64,
pub max_gas_amount: U64,
pub gas_unit_price: U64,
pub expiration_timestamp_secs: U64,
pub payload: TransactionPayload,
pub registration_hash: HashValue,
}

/// Request to create signing messages
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)]
pub struct UserCreateSigningMessageRequest {
Expand Down
2 changes: 1 addition & 1 deletion crates/aptos-crypto/src/ed25519/ed25519_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl Ed25519PublicKey {
pub fn aggregate(_pub_keys: Vec<&Ed25519PublicKey>) -> anyhow::Result<Self> {
todo!()
}

/// Derive the actual curve point represented by the public key.
pub fn to_compressed_edwards_y(&self) -> CompressedEdwardsY {
let bytes = self.to_bytes();
Expand Down
77 changes: 57 additions & 20 deletions crates/aptos-rosetta/src/types/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ pub enum TransactionType {
StateCheckpoint,
Validator,
BlockEpilogue,
Automated,
}

impl Display for TransactionType {
Expand All @@ -870,6 +871,7 @@ impl Display for TransactionType {
StateCheckpoint => "StateCheckpoint",
Validator => "Validator",
BlockEpilogue => "BlockEpilogue",
Automated => "Automated",
})
}
}
Expand All @@ -880,21 +882,49 @@ impl Transaction {
txn: TransactionOnChainData,
) -> ApiResult<Transaction> {
use aptos_types::transaction::Transaction::*;
let (txn_type, maybe_user_txn, txn_info, events) = match &txn.transaction {
UserTransaction(user_txn) => {
(TransactionType::User, Some(user_txn), txn.info, txn.events)
},
GenesisTransaction(_) => (TransactionType::Genesis, None, txn.info, txn.events),
BlockMetadata(_) => (TransactionType::BlockMetadata, None, txn.info, txn.events),
let (txn_type, maybe_user_txn, maybe_automated_txn, txn_info, events) = match &txn
.transaction
{
UserTransaction(user_txn) => (
TransactionType::User,
Some(user_txn),
None,
txn.info,
txn.events,
),
GenesisTransaction(_) => (TransactionType::Genesis, None, None, txn.info, txn.events),
BlockMetadata(_) => (
TransactionType::BlockMetadata,
None,
None,
txn.info,
txn.events,
),
BlockMetadataExt(_) => (
TransactionType::BlockMetadataExt,
None,
None,
txn.info,
txn.events,
),
StateCheckpoint(_) => (
TransactionType::StateCheckpoint,
None,
None,
txn.info,
vec![],
),
ValidatorTransaction(_) => {
(TransactionType::Validator, None, None, txn.info, txn.events)
},
BlockEpilogue(_) => (TransactionType::BlockEpilogue, None, None, txn.info, vec![]),
AutomatedTransaction(automated_txn) => (
TransactionType::Automated,
None,
Some(automated_txn),
txn.info,
txn.events,
),
StateCheckpoint(_) => (TransactionType::StateCheckpoint, None, txn.info, vec![]),
ValidatorTransaction(_) => (TransactionType::Validator, None, txn.info, txn.events),
BlockEpilogue(_) => (TransactionType::BlockEpilogue, None, txn.info, vec![]),
};

// Operations must be sequential and operation index must always be in the same order
Expand All @@ -910,8 +940,12 @@ impl Transaction {
state_key,
write_op,
&events,
maybe_user_txn.map(|inner| inner.sender()),
maybe_user_txn.map(|inner| inner.payload()),
maybe_user_txn
.map(|inner| inner.sender())
.or(maybe_automated_txn.map(|inner| inner.sender())),
maybe_user_txn
.map(|inner| inner.payload())
.or(maybe_automated_txn.map(|inner| inner.payload())),
txn.version,
operation_index,
&txn.changes,
Expand All @@ -936,13 +970,13 @@ impl Transaction {
}
}
} else {
let maybe_sender_payload = maybe_user_txn
.map(|txn| (txn.sender(), txn.payload()))
.or(maybe_automated_txn.map(|txn| (txn.sender(), txn.payload())));
// Parse all failed operations from the payload
if let Some(user_txn) = maybe_user_txn {
let mut ops = parse_failed_operations_from_txn_payload(
operation_index,
user_txn.sender(),
user_txn.payload(),
);
if let Some((sender, payload)) = maybe_sender_payload {
let mut ops =
parse_failed_operations_from_txn_payload(operation_index, sender, payload);
operation_index += ops.len() as u64;
operations.append(&mut ops);
}
Expand All @@ -956,12 +990,15 @@ impl Transaction {
}

// Everything committed costs gas
if let Some(txn) = maybe_user_txn {
let maybe_sender_gas_price = maybe_user_txn
.map(|txn| (txn.sender(), txn.gas_unit_price()))
.or(maybe_automated_txn.map(|txn| (txn.sender(), txn.gas_unit_price())));
if let Some((sender, gas_unit_price)) = maybe_sender_gas_price {
operations.push(Operation::gas_fee(
operation_index,
txn.sender(),
sender,
txn_info.gas_used(),
txn.gas_unit_price(),
gas_unit_price,
));
}

Expand Down
4 changes: 2 additions & 2 deletions crates/aptos/src/account/multisig_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub struct Create {
/// Addresses of additional owners for the new multisig, beside the transaction sender.
#[clap(long, num_args = 0.., value_parser = crate::common::types::load_account_arg)]
pub(crate) additional_owners: Vec<AccountAddress>,
/// account level timeout_duration in seconds, all created Tx must be approved and
/// account level timeout_duration in seconds, all created Tx must be approved and
/// executed before this timeout (from its creation) otherwise the Tx is marked for rejection
#[clap(long)]
pub(crate) timeout_duration: u64,
Expand Down Expand Up @@ -136,7 +136,7 @@ impl SupraCommand for Create {
metadata_value,
self.timeout_duration,
);

Ok(
SupraCommandArguments {
payload,
Expand Down
13 changes: 13 additions & 0 deletions crates/aptos/src/common/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,19 @@ impl From<&Transaction> for TransactionSummary {
version: Some(txn.transaction_info().version.0),
vm_status: Some(txn.transaction_info().vm_status.clone()),
},
Transaction::AutomatedTransaction(txn) =>
TransactionSummary {
transaction_hash: txn.info.hash,
sender: Some(*txn.meta.sender.inner()),
gas_used: Some(txn.info.gas_used.0),
gas_unit_price: Some(txn.meta.gas_unit_price.0),
success: Some(txn.info.success),
version: Some(txn.info.version.0),
vm_status: Some(txn.info.vm_status.clone()),
sequence_number: Some(txn.meta.index.0),
timestamp_us: Some(txn.timestamp.0),
pending: None,
},
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ pub fn convert_transaction(
Transaction::ValidatorTransaction(_) => {
transaction::transaction::TransactionType::Validator
},
Transaction::AutomatedTransaction(_) => transaction::transaction::TransactionType::Automated
};

let txn_data = match &transaction {
Expand Down Expand Up @@ -835,6 +836,26 @@ pub fn convert_transaction(
Transaction::ValidatorTransaction(api_validator_txn) => {
convert_validator_transaction(api_validator_txn)
},
Transaction::AutomatedTransaction(at) => {

timestamp = Some(convert_timestamp_usecs(at.timestamp.0));
let expiration_timestamp_secs = Some(convert_timestamp_secs(std::cmp::min(
at.meta.expiration_timestamp_secs.0,
chrono::NaiveDateTime::MAX.timestamp() as u64,
)));
transaction::transaction::TxnData::Automated(transaction::AutomatedTransaction {
meta: Some(transaction::AutomatedTaskMeta {
sender: at.meta.sender.to_string(),
index: at.meta.index.0,
max_gas_amount: at.meta.max_gas_amount.0,
gas_unit_price: at.meta.gas_unit_price.0,
expiration_timestamp_secs,
payload: Some(convert_transaction_payload(&at.meta.payload)),
registration_hash: at.meta.registration_hash.0.to_vec()
}),
events: convert_events(&at.events),
})
}
};

transaction::Transaction {
Expand Down
Loading

0 comments on commit 03f2801

Please sign in to comment.