Skip to content

Commit

Permalink
Merge pull request #130 from Entropy-Foundation/task/issue-1337
Browse files Browse the repository at this point in the history
[AN-Issue-1337] Added/updated types to facilitate automation task handling and execution
  • Loading branch information
aregng authored Dec 5, 2024
2 parents b414ead + b6fc515 commit 4eb9b7a
Show file tree
Hide file tree
Showing 27 changed files with 3,924 additions and 2,576 deletions.
13 changes: 9 additions & 4 deletions .github/workflows/aptos-framework-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ name: Run aptos framework checks

on:
push:
branches:
- dev
pull_request:
branches:
- dev
- dev
- "release/**"
- "feature/**"

pull_request:
types: [opened, synchronize, ready_for_review]
branches:
- dev
- "release/**"
- "feature/**"
env:
CARGO_TERM_COLOR: always
CARGO_BIN: ~/.cargo/bin/cargo
Expand Down
8 changes: 7 additions & 1 deletion api/types/src/convert.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright © Aptos Foundation
// Parts of the project are originally copyright © Meta Platforms, Inc.
// SPDX-License-Identifier: Apache-2.0
//
// Copyright (c) 2024 Supra.

use crate::{
transaction::{
Expand Down Expand Up @@ -178,7 +180,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 +236,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
86 changes: 86 additions & 0 deletions api/types/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright © Aptos Foundation
// Parts of the project are originally copyright © Meta Platforms, Inc.
// SPDX-License-Identifier: Apache-2.0
//
// Copyright (c) 2024 Supra.

use crate::{
Address, AptosError, EntryFunctionId, EventGuid, HashValue, HexEncodedBytes,
Expand Down Expand Up @@ -29,6 +31,7 @@ use aptos_types::{
AccountAuthenticator, AnyPublicKey, AnySignature, MultiKey, MultiKeyAuthenticator,
SingleKeyAuthenticator, TransactionAuthenticator, MAX_NUM_OF_SIGS,
},
automated_transaction::AutomatedTransaction as UserAutomatedTransaction,
webauthn::{PartialAuthenticatorAssertionResponse, MAX_WEBAUTHN_SIGNATURE_BYTES},
Script, SignedTransaction, TransactionOutput, TransactionWithProof,
},
Expand Down Expand Up @@ -177,6 +180,7 @@ impl
pub enum Transaction {
PendingTransaction(PendingTransaction),
UserTransaction(Box<UserTransaction>),
AutomatedTransaction(Box<AutomatedTransaction>),
GenesisTransaction(GenesisTransaction),
BlockMetadataTransaction(BlockMetadataTransaction),
StateCheckpointTransaction(StateCheckpointTransaction),
Expand All @@ -194,6 +198,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 +211,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 +224,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 +241,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 +254,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 +269,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 +311,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 +398,26 @@ 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 +476,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 +591,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
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0
//
// Copyright (c) 2024 Supra.

//! This module defines the gas parameters for Aptos Framework & Stdlib.
Expand Down Expand Up @@ -269,6 +271,7 @@ crate::gas_schedule::macros::define_gas_parameters!(

[transaction_context_get_txn_hash_base: InternalGas, { 10.. => "transaction_context.get_txn_hash.base" }, 735],
[transaction_context_get_script_hash_base: InternalGas, "transaction_context.get_script_hash.base", 735],
[transaction_context_get_txn_app_hash_base: InternalGas, "transaction_context.get_txn_app_hash.base", 735],
// Based on SHA3-256's cost
[transaction_context_generate_unique_address_base: InternalGas, { 10.. => "transaction_context.generate_unique_address.base" }, 14704],
[transaction_context_sender_base: InternalGas, {RELEASE_V1_12.. => "transaction_context.sender.base"}, 735],
Expand Down
14 changes: 10 additions & 4 deletions aptos-move/aptos-vm/src/aptos_vm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright © Aptos Foundation
// Parts of the project are originally copyright © Meta Platforms, Inc.
// SPDX-License-Identifier: Apache-2.0
//
// Copyright (c) 2024 Supra.

use crate::{
block_executor::{AptosTransactionOutput, BlockAptosVM},
Expand Down Expand Up @@ -761,10 +763,11 @@ impl AptosVM {
let module_id = traversal_context
.referenced_module_ids
.alloc(entry_fn.module().clone());
session.check_dependencies_and_charge_gas(gas_meter, traversal_context, [(
module_id.address(),
module_id.name(),
)])?;
session.check_dependencies_and_charge_gas(
gas_meter,
traversal_context,
[(module_id.address(), module_id.name())],
)?;
}

let function =
Expand Down Expand Up @@ -2433,6 +2436,9 @@ impl AptosVM {
self.process_validator_transaction(resolver, txn.clone(), log_context)?;
(vm_status, output)
},
Transaction::AutomatedTransaction(_) => {
unimplemented!("AutomatedTransaction execution is coming soon")
},
})
}
}
Expand Down
37 changes: 37 additions & 0 deletions aptos-move/aptos-vm/src/transaction_metadata.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
// Copyright © Aptos Foundation
// Parts of the project are originally copyright © Meta Platforms, Inc.
// SPDX-License-Identifier: Apache-2.0
//
// Copyright (c) 2024 Supra.

use aptos_crypto::HashValue;
use aptos_gas_algebra::{FeePerGasUnit, Gas, NumBytes};
use aptos_types::transaction::automated_transaction::AutomatedTransaction;
use aptos_types::{
account_address::AccountAddress,
chain_id::ChainId,
Expand Down Expand Up @@ -31,6 +34,7 @@ pub struct TransactionMetadata {
pub is_keyless: bool,
pub entry_function_payload: Option<EntryFunction>,
pub multisig_payload: Option<Multisig>,
pub txn_app_hash: Vec<u8>,
}

impl TransactionMetadata {
Expand Down Expand Up @@ -80,6 +84,10 @@ impl TransactionMetadata {
TransactionPayload::Multisig(m) => Some(m.clone()),
_ => None,
},
txn_app_hash: HashValue::sha3_256_of(
&bcs::to_bytes(&txn).expect("Unable to serialize SignedTransaction"),
)
.to_vec(),
}
}

Expand Down Expand Up @@ -161,6 +169,35 @@ impl TransactionMetadata {
.map(|entry_func| entry_func.as_entry_function_payload()),
self.multisig_payload()
.map(|multisig| multisig.as_multisig_payload()),
self.txn_app_hash.clone(),
)
}
}

impl From<&AutomatedTransaction> for TransactionMetadata {
fn from(txn: &AutomatedTransaction) -> Self {
Self {
sender: txn.sender(),
authentication_key: txn.authenticator().to_vec(),
secondary_signers: vec![],
secondary_authentication_keys: vec![],
sequence_number: txn.sequence_number(),
fee_payer: None,
fee_payer_authentication_key: None,
max_gas_amount: txn.max_gas_amount().into(),
gas_unit_price: txn.gas_unit_price().into(),
transaction_size: (txn.raw_txn_bytes_len() as u64).into(),
expiration_timestamp_secs: txn.expiration_timestamp_secs(),
chain_id: txn.chain_id(),
script_hash: vec![],
script_size: NumBytes::zero(),
is_keyless: false,
entry_function_payload: match txn.payload() {
TransactionPayload::EntryFunction(e) => Some(e.clone()),
_ => None,
},
multisig_payload: None,
txn_app_hash: txn.hash().to_vec(),
}
}
}
28 changes: 28 additions & 0 deletions aptos-move/framework/src/natives/transaction_context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0
//
// Copyright (c) 2024 Supra.

use aptos_gas_schedule::gas_params::natives::aptos_framework::*;
use aptos_native_interface::{
Expand Down Expand Up @@ -237,6 +239,31 @@ fn native_chain_id_internal(
}
}

/***************************************************************************************************
* native fun get_txn_app_hash
*
* gas cost: base_cost
*
**************************************************************************************************/
fn native_txn_app_hash_internal(
context: &mut SafeNativeContext,
_ty_args: Vec<Type>,
_args: VecDeque<Value>,
) -> SafeNativeResult<SmallVec<[Value; 1]>> {
context.charge(TRANSACTION_CONTEXT_GET_TXN_APP_HASH_BASE)?;

let user_transaction_context_opt = get_user_transaction_context_opt_from_context(context);
if let Some(transaction_context) = user_transaction_context_opt {
Ok(smallvec![Value::vector_u8(
transaction_context.txn_app_hash()
)])
} else {
Err(SafeNativeError::Abort {
abort_code: error::invalid_state(abort_codes::ETRANSACTION_CONTEXT_NOT_AVAILABLE),
})
}
}

fn create_option_some_value(value: Value) -> Value {
Value::struct_(Struct::pack(vec![create_singleton_vector(value)]))
}
Expand Down Expand Up @@ -405,6 +432,7 @@ pub fn make_all(
"multisig_payload_internal",
native_multisig_payload_internal,
),
("txn_app_hash_internal", native_txn_app_hash_internal),
];

builder.make_named_natives(natives)
Expand Down
Loading

0 comments on commit 4eb9b7a

Please sign in to comment.