From 1e465c474adf3894373d8da4685b4a60b8cc3880 Mon Sep 17 00:00:00 2001 From: Aregnaz Harutyunyan <> Date: Fri, 6 Dec 2024 18:28:31 +0400 Subject: [PATCH] Fixed test failures after rebase --- .../src/tests/automation_transaction.rs | 127 +++++++++++----- aptos-move/framework/cached-packages/build.rs | 8 + aptos-move/framework/src/aptos.rs | 1 + .../doc/automation_registry.md | 137 +++++++++++++++--- .../framework/supra-framework/doc/overview.md | 1 + .../doc/enumerable_map.md | 0 .../framework/supra-stdlib/doc/overview.md | 18 +++ .../supra-stdlib/doc_template/overview.md | 7 + .../supra-stdlib/doc_template/references.md | 1 + 9 files changed, 242 insertions(+), 58 deletions(-) rename aptos-move/framework/{supra-framework => supra-stdlib}/doc/enumerable_map.md (100%) create mode 100644 aptos-move/framework/supra-stdlib/doc/overview.md create mode 100644 aptos-move/framework/supra-stdlib/doc_template/overview.md create mode 100644 aptos-move/framework/supra-stdlib/doc_template/references.md diff --git a/aptos-move/e2e-testsuite/src/tests/automation_transaction.rs b/aptos-move/e2e-testsuite/src/tests/automation_transaction.rs index bd876fef43bbcd..e7ae2f0214db2d 100644 --- a/aptos-move/e2e-testsuite/src/tests/automation_transaction.rs +++ b/aptos-move/e2e-testsuite/src/tests/automation_transaction.rs @@ -1,16 +1,18 @@ // Copyright (c) 2024 Supra. -use std::ops::{Deref, DerefMut}; use aptos_cached_packages::aptos_framework_sdk_builder; use aptos_language_e2e_tests::account::{Account, AccountData}; use aptos_language_e2e_tests::executor::FakeExecutor; use aptos_types::transaction::automation::AutomationTransactionPayload; -use aptos_types::transaction::{EntryFunction, ExecutionStatus, SignedTransaction, TransactionOutput, TransactionPayload, TransactionStatus}; +use aptos_types::transaction::{ + EntryFunction, ExecutionStatus, SignedTransaction, TransactionOutput, TransactionPayload, + TransactionStatus, +}; use move_core_types::account_address::AccountAddress; use move_core_types::ident_str; use move_core_types::language_storage::ModuleId; use move_core_types::vm_status::StatusCode; - +use std::ops::{Deref, DerefMut}; struct AutomationTransactionTestContext { executor: FakeExecutor, @@ -39,20 +41,40 @@ impl AutomationTransactionTestContext { new_account_data } - fn create_automation_txn_payload(&self, seq_num: u64, inner_payload: EntryFunction, expiry_time: u64, max_gas_amount: u64, gas_price_cap: u64 ) -> SignedTransaction { + fn create_automation_txn_payload( + &self, + seq_num: u64, + inner_payload: EntryFunction, + expiry_time: u64, + max_gas_amount: u64, + gas_price_cap: u64, + ) -> SignedTransaction { let inner_entry_function_bytes = bcs::to_bytes(&inner_payload).expect("Can't serialize entry function"); - self.create_automation_txn_payload_raw(seq_num, inner_entry_function_bytes, expiry_time, max_gas_amount, gas_price_cap) + self.create_automation_txn_payload_raw( + seq_num, + inner_entry_function_bytes, + expiry_time, + max_gas_amount, + gas_price_cap, + ) } - fn create_automation_txn_payload_raw(&self, seq_num: u64, inner_entry_function_bytes: Vec, expiry_time: u64, max_gas_amount: u64, gas_price_cap: u64 ) -> SignedTransaction { + fn create_automation_txn_payload_raw( + &self, + seq_num: u64, + inner_entry_function_bytes: Vec, + expiry_time: u64, + max_gas_amount: u64, + gas_price_cap: u64, + ) -> SignedTransaction { let automation_txn_payload = aptos_framework_sdk_builder::automation_registry_register( inner_entry_function_bytes, expiry_time, max_gas_amount, gas_price_cap, ) - .into_entry_function(); + .into_entry_function(); let automation_txn = TransactionPayload::Automation( AutomationTransactionPayload::EntryFunction(automation_txn_payload), ); @@ -75,7 +97,6 @@ impl AutomationTransactionTestContext { }, _ => panic!("Unexpected transaction status: {output:?}"), } - } } @@ -93,7 +114,6 @@ impl DerefMut for AutomationTransactionTestContext { } } - #[test] fn check_successful_registration() { let mut test_context = AutomationTransactionTestContext::new(); @@ -103,9 +123,22 @@ fn check_successful_registration() { aptos_framework_sdk_builder::supra_coin_mint(dest_account.address().clone(), 100) .into_entry_function(); - // TODO: Update expiry_time, max_gas_amount, gas_price_cap when - let automation_txn = test_context.create_automation_txn_payload(0, inner_entry_function, 3600, 100, 100); - + let view_output = test_context.execute_view_function( + str::parse("0x1::timestamp::now_seconds").unwrap(), + vec![], + vec![], + ); + let result = view_output.values.expect("Valid result"); + assert_eq!(result.len(), 1); + let now = bcs::from_bytes::(&result[0]).unwrap(); + let expiration_time = now + 4000; + let automation_txn = test_context.create_automation_txn_payload( + 0, + inner_entry_function, + expiration_time, + 100, + 100, + ); let output = test_context.execute_and_apply(automation_txn); assert_eq!( @@ -143,7 +176,8 @@ fn check_registration_from_non_automation_context() { 100, 100, ); - let user_txn_with_register_entry = test_context.txn_sender + let user_txn_with_register_entry = test_context + .txn_sender .account() .transaction() .payload(entry_with_register) @@ -154,7 +188,7 @@ fn check_registration_from_non_automation_context() { match output.status() { TransactionStatus::Keep(ExecutionStatus::MoveAbort { code, .. }) => { //ENOT_AUTOMATION_TXN_CONTEXT - assert_eq!(*code, 3); + assert_eq!(*code, 6); }, _ => panic!("Unexpected transaction status: {output:?}"), } @@ -174,7 +208,8 @@ fn check_automation_txn_with_invalid_payload(test_context: &mut AutomationTransa let any_entry_function = aptos_framework_sdk_builder::supra_coin_mint(dest_account.address().clone(), 100) .into_entry_function(); - let user_txn_with_register_entry = test_context.txn_sender + let user_txn_with_register_entry = test_context + .txn_sender .account() .transaction() .payload(TransactionPayload::Automation( @@ -184,15 +219,24 @@ fn check_automation_txn_with_invalid_payload(test_context: &mut AutomationTransa .sign(); let output = test_context.execute_transaction(user_txn_with_register_entry); - AutomationTransactionTestContext::check_miscellaneous_output(output, StatusCode::INVALID_AUTOMATION_PAYLOAD) + AutomationTransactionTestContext::check_miscellaneous_output( + output, + StatusCode::INVALID_AUTOMATION_PAYLOAD, + ) } -fn check_automation_txn_with_invalid_inner_function(test_context: &mut AutomationTransactionTestContext) { +fn check_automation_txn_with_invalid_inner_function( + test_context: &mut AutomationTransactionTestContext, +) { println!("checking automation txn within invalid inner function"); // Create automation transaction with non-entry-function - let automation_transaction = test_context.create_automation_txn_payload_raw( 0, vec![42;32], 100, 100, 100); + let automation_transaction = + test_context.create_automation_txn_payload_raw(0, vec![42; 32], 100, 100, 100); let output = test_context.execute_transaction(automation_transaction); - AutomationTransactionTestContext::check_miscellaneous_output(output, StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT); + AutomationTransactionTestContext::check_miscellaneous_output( + output, + StatusCode::FAILED_TO_DESERIALIZE_ARGUMENT, + ); // Create automation transaction with entry-function with invalid arguments. let dest_account = test_context.new_account_data(0, 0); @@ -201,37 +245,46 @@ fn check_automation_txn_with_invalid_inner_function(test_context: &mut Automatio .into_entry_function() .into_inner(); let inner_entry_function = EntryFunction::new(m_id, f_id, vec![], vec![]); - let automation_txn = test_context.create_automation_txn_payload(0, inner_entry_function, 3600, 100, 100); + let automation_txn = + test_context.create_automation_txn_payload(0, inner_entry_function, 3600, 100, 100); let output = test_context.execute_transaction(automation_txn); - AutomationTransactionTestContext::check_miscellaneous_output(output, StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD); + AutomationTransactionTestContext::check_miscellaneous_output( + output, + StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD, + ); } -fn check_automation_txn_with_empty_payload_arguments(test_context: &mut AutomationTransactionTestContext) { +fn check_automation_txn_with_empty_payload_arguments( + test_context: &mut AutomationTransactionTestContext, +) { println!("checking automation txn within empty payload arguments"); - let register_payload = - EntryFunction::new( - ModuleId::new( - AccountAddress::new([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, - ]), - ident_str!("automation_registry").to_owned(), - ), - ident_str!("register").to_owned(), - vec![], - vec![], - ); + let register_payload = EntryFunction::new( + ModuleId::new( + AccountAddress::new([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, + ]), + ident_str!("automation_registry").to_owned(), + ), + ident_str!("register").to_owned(), + vec![], + vec![], + ); let automation_txn_payload = TransactionPayload::Automation( AutomationTransactionPayload::EntryFunction(register_payload), ); - let automation_txn = test_context.txn_sender + let automation_txn = test_context + .txn_sender .account() .transaction() .payload(automation_txn_payload) .sequence_number(0) .sign(); let output = test_context.execute_transaction(automation_txn); - AutomationTransactionTestContext::check_miscellaneous_output(output, StatusCode::INVALID_AUTOMATION_PAYLOAD_ARGUMENTS) + AutomationTransactionTestContext::check_miscellaneous_output( + output, + StatusCode::INVALID_AUTOMATION_PAYLOAD_ARGUMENTS, + ) } diff --git a/aptos-move/framework/cached-packages/build.rs b/aptos-move/framework/cached-packages/build.rs index afec25e78dbe6c..bab8cbb4502a18 100644 --- a/aptos-move/framework/cached-packages/build.rs +++ b/aptos-move/framework/cached-packages/build.rs @@ -49,6 +49,14 @@ fn main() -> Result<()> { .join("Move.toml") .display() ); + println!( + "cargo:rerun-if-changed={}", + prev_dir.join("supra-stdlib").join("sources").display() + ); + println!( + "cargo:rerun-if-changed={}", + prev_dir.join("supra-stdlib").join("Move.toml").display() + ); println!( "cargo:rerun-if-changed={}", prev_dir.join("supra-framework").join("sources").display() diff --git a/aptos-move/framework/src/aptos.rs b/aptos-move/framework/src/aptos.rs index b478d25880cb57..117c23348aa69f 100644 --- a/aptos-move/framework/src/aptos.rs +++ b/aptos-move/framework/src/aptos.rs @@ -60,6 +60,7 @@ impl ReleaseTarget { let result = vec![ ("move-stdlib", None), ("aptos-stdlib", None), + ("supra-stdlib", None), ( "supra-framework", Some("cached-packages/src/aptos_framework_sdk_builder.rs"), diff --git a/aptos-move/framework/supra-framework/doc/automation_registry.md b/aptos-move/framework/supra-framework/doc/automation_registry.md index 4695687df85915..db22debc47c720 100644 --- a/aptos-move/framework/supra-framework/doc/automation_registry.md +++ b/aptos-move/framework/supra-framework/doc/automation_registry.md @@ -14,6 +14,7 @@ This contract is part of the Supra Framework and is designed to manage automated - [Function `initialize`](#0x1_automation_registry_initialize) - [Function `withdraw`](#0x1_automation_registry_withdraw) - [Function `on_new_epoch`](#0x1_automation_registry_on_new_epoch) +- [Function `collect_from_owner`](#0x1_automation_registry_collect_from_owner) - [Function `register`](#0x1_automation_registry_register) - [Function `get_next_task_index`](#0x1_automation_registry_get_next_task_index) - [Function `get_active_task_ids`](#0x1_automation_registry_get_active_task_ids) @@ -21,13 +22,15 @@ This contract is part of the Supra Framework and is designed to manage automated
use 0x1::account;
-use 0x1::enumerable_map;
+use 0x1::block;
+use 0x1::enumerable_map;
 use 0x1::event;
 use 0x1::reconfiguration;
 use 0x1::signer;
 use 0x1::system_addresses;
 use 0x1::timestamp;
 use 0x1::transaction_context;
+use 0x1::vector;
 
@@ -59,13 +62,19 @@ It tracks entries both pending and completed, organized by unique indices. automation_gas_limit: u64
- Automation task gas limit + Automation task gas limit. todo : updatable
duration_upper_limit: u64
- Automation task duration upper limit. + Automation task duration upper limit. todo : updatable +
+
+gas_committed_for_next_epoch: u64 +
+
+ Gas committed for next epoch
registry_fee_address: address @@ -80,7 +89,7 @@ It tracks entries both pending and completed, organized by unique indices. Resource account signature capability
-tasks: enumerable_map::EnumerableMap<u64, automation_registry::AutomationTaskMetaData> +tasks: enumerable_map::EnumerableMap<u64, automation_registry::AutomationTaskMetaData>
A collection of automation task entries that are active state. @@ -180,17 +189,17 @@ It tracks entries both pending and completed, organized by unique indices. -Default automation gas limit +The default automation task gas limit -
const DEFAULT_AUTOMATION_GAS_LIMIT: u64 = 1000000;
+
const DEFAULT_AUTOMATION_GAS_LIMIT: u64 = 100000000;
 
-Default upper gas duration in seconds - 3 days +The default upper limit duration for automation task, specified in seconds (30 days).
const DEFAULT_DURATION_UPPER_LIMIT: u64 = 2592000;
@@ -198,12 +207,42 @@ Default upper gas duration in seconds - 3 days
 
 
 
+
+
+Expiry time must be after the start of the next epoch
+
+
+
const EEXPIRY_BEFORE_NEXT_EPOCH: u64 = 4;
+
+ + + -Expiry time does not go beyond upper cap duration. +Expiry time does not go beyond upper cap duration -
const EEXPIRY_TIME_UPPER: u64 = 2;
+
const EEXPIRY_TIME_UPPER: u64 = 3;
+
+ + + + + +Gas amount does not go beyond upper cap limit + + +
const EGAS_AMOUNT_UPPER: u64 = 5;
+
+ + + + + +Invalid expiry time: it cannot be earlier than the current time + + +
const EINVALID_EXPIRY_TIME: u64 = 2;
 
@@ -213,7 +252,7 @@ Expiry time does not go beyond upper cap duration. Entry function is called not from automation transaction context. -
const ENOT_AUTOMATION_TXN_CONTEXT: u64 = 3;
+
const ENOT_AUTOMATION_TXN_CONTEXT: u64 = 6;
 
@@ -228,6 +267,16 @@ Registry Id not found. + + +Conversion factor between microseconds and millisecond || millisecond and second + + +
const MILLISECOND_CONVERSION_FACTOR: u64 = 1000;
+
+ + + Registry resource creation seed @@ -265,9 +314,10 @@ Registry resource creation seed current_index: 0, automation_gas_limit: DEFAULT_AUTOMATION_GAS_LIMIT, duration_upper_limit: DEFAULT_DURATION_UPPER_LIMIT, + gas_committed_for_next_epoch: 0, registry_fee_address: signer::address_of(®istry_fee_resource_signer), registry_fee_address_signer_cap, - tasks: enumerable_map::new_map(), + tasks: enumerable_map::new_map(), }) }
@@ -315,6 +365,32 @@ Registry resource creation seed
public(friend) fun on_new_epoch() {
     // todo : should perform clean up and updation of state
+    // sumup gas_committed_for_next_epoch whatever is add or remove
+}
+
+ + + + + + + +## Function `collect_from_owner` + +Calculate and collect registry charge from user + + +
fun collect_from_owner(_owner: &signer, _expiry_time: u64, _max_gas_amount: u64)
+
+ + + +
+Implementation + + +
fun collect_from_owner(_owner: &signer, _expiry_time: u64, _max_gas_amount: u64) {
+    // todo : calculate and collect pre-paid amount from the user
 }
 
@@ -349,14 +425,23 @@ Registers a new automation task entry. let registry_data = borrow_global_mut<AutomationRegistry>(@supra_framework); // todo : well formedness check of payload_tx - // todo : pre-paid amount collect from the user - // todo : duration/expiry in seconds - // Expiry time does not go beyond upper cap duration set by admin/governance - assert!(expiry_time < registry_data.duration_upper_limit, EEXPIRY_TIME_UPPER); - // todo : expiry should not be before the start of next epoch - // todo : automation_gas_limit check + + let current_time = timestamp::now_seconds(); + assert!(expiry_time > current_time, EINVALID_EXPIRY_TIME); + assert!((expiry_time - current_time) < registry_data.duration_upper_limit, EEXPIRY_TIME_UPPER); + + let epoch_interval = block::get_epoch_interval_secs(); + let last_epoch_time_ms = reconfiguration::last_reconfiguration_time() / MILLISECOND_CONVERSION_FACTOR; + let last_epoch_time = last_epoch_time_ms / MILLISECOND_CONVERSION_FACTOR; + assert!(expiry_time > (last_epoch_time + epoch_interval), EEXPIRY_BEFORE_NEXT_EPOCH); + + registry_data.gas_committed_for_next_epoch = registry_data.gas_committed_for_next_epoch + max_gas_amount; + assert!(registry_data.gas_committed_for_next_epoch < registry_data.automation_gas_limit, EGAS_AMOUNT_UPPER); + // todo : gas_price_cap should not below chain minimum + collect_from_owner(owner, expiry_time, max_gas_amount); + registry_data.current_index = registry_data.current_index + 1; let automation_task_metadata = AutomationTaskMetaData { @@ -372,7 +457,7 @@ Registers a new automation task entry. tx_hash: transaction_context::get_transaction_hash() // todo : need to double check is that work or not }; - enumerable_map::add_value(&mut registry_data.tasks, registry_data.current_index, automation_task_metadata); + enumerable_map::add_value(&mut registry_data.tasks, registry_data.current_index, automation_task_metadata); event::emit(automation_task_metadata); } @@ -428,7 +513,17 @@ List all the automation task ids
public fun get_active_task_ids(): vector<u64> acquires AutomationRegistry {
     let automation_registry = borrow_global<AutomationRegistry>(@supra_framework);
-    enumerable_map::get_map_list(&automation_registry.tasks)
+
+    let active_task_ids = vector[];
+    let ids = enumerable_map::get_map_list(&automation_registry.tasks);
+
+    vector::for_each(ids, |id| {
+        let task = enumerable_map::get_value(&automation_registry.tasks, id);
+        if (task.is_active) {
+            vector::push_back(&mut active_task_ids, id);
+        };
+    });
+    return active_task_ids
 }
 
@@ -457,8 +552,8 @@ and the second element contains the get_task_details(id: u64): AutomationTaskMetaData acquires AutomationRegistry { let automation_task_metadata = borrow_global<AutomationRegistry>(@supra_framework); - assert!(enumerable_map::contains(&automation_task_metadata.tasks, id), EREGITRY_NOT_FOUND); - enumerable_map::get_value(&automation_task_metadata.tasks, id) + assert!(enumerable_map::contains(&automation_task_metadata.tasks, id), EREGITRY_NOT_FOUND); + enumerable_map::get_value(&automation_task_metadata.tasks, id) }
diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 79f5b45427cf35..88bd03b29e70f6 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -16,6 +16,7 @@ This is the reference documentation of the Supra framework. - [`0x1::aggregator`](aggregator.md#0x1_aggregator) - [`0x1::aggregator_factory`](aggregator_factory.md#0x1_aggregator_factory) - [`0x1::aggregator_v2`](aggregator_v2.md#0x1_aggregator_v2) +- [`0x1::automation_registry`](automation_registry.md#0x1_automation_registry) - [`0x1::block`](block.md#0x1_block) - [`0x1::chain_id`](chain_id.md#0x1_chain_id) - [`0x1::chain_status`](chain_status.md#0x1_chain_status) diff --git a/aptos-move/framework/supra-framework/doc/enumerable_map.md b/aptos-move/framework/supra-stdlib/doc/enumerable_map.md similarity index 100% rename from aptos-move/framework/supra-framework/doc/enumerable_map.md rename to aptos-move/framework/supra-stdlib/doc/enumerable_map.md diff --git a/aptos-move/framework/supra-stdlib/doc/overview.md b/aptos-move/framework/supra-stdlib/doc/overview.md new file mode 100644 index 00000000000000..ef436ff23858d6 --- /dev/null +++ b/aptos-move/framework/supra-stdlib/doc/overview.md @@ -0,0 +1,18 @@ + + + +# Supra Standard Library + + +This is the reference documentation of the Supra standard library extension. + + + + +## Index + + +- [`0x1::enumerable_map`](enumerable_map.md#0x1_enumerable_map) + + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-stdlib/doc_template/overview.md b/aptos-move/framework/supra-stdlib/doc_template/overview.md new file mode 100644 index 00000000000000..8345ced520a1df --- /dev/null +++ b/aptos-move/framework/supra-stdlib/doc_template/overview.md @@ -0,0 +1,7 @@ +# Supra Standard Library + +This is the reference documentation of the Supra standard library extension. + +## Index + +> {{move-index}} diff --git a/aptos-move/framework/supra-stdlib/doc_template/references.md b/aptos-move/framework/supra-stdlib/doc_template/references.md new file mode 100644 index 00000000000000..ad4748ca54059e --- /dev/null +++ b/aptos-move/framework/supra-stdlib/doc_template/references.md @@ -0,0 +1 @@ +[move-book]: https://aptos.dev/move/book/SUMMARY