From ae30a87ce4a9ec607f4b8c8148c49cfa0d4ecbab Mon Sep 17 00:00:00 2001 From: Aregnaz Harutyunyan <89187359+aregng@users.noreply.github.com> Date: Fri, 5 Dec 2025 12:02:57 +0400 Subject: [PATCH 01/31] [AN-Issue-2480-2486] Updated system task handling on cancellation and cycle suspension (#313) - If pending system task is cancelled, the task index is removed from the cached list of system tasks - When cycle suspened then system tasks are also included in the removed tasks list of the reported error. Co-authored-by: Aregnaz Harutyunyan <> --- .../doc/automation_registry.md | 9 ++-- .../sources/automation_registry.move | 7 ++- .../tests/automation_registry_tests.move | 47 ++++++++++++++----- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/aptos-move/framework/supra-framework/doc/automation_registry.md b/aptos-move/framework/supra-framework/doc/automation_registry.md index b93e9277a2f..13823a4dab1 100644 --- a/aptos-move/framework/supra-framework/doc/automation_registry.md +++ b/aptos-move/framework/supra-framework/doc/automation_registry.md @@ -4888,6 +4888,7 @@ Committed gas-limit is updated by reducing it with the max-gas-amount of the can assert!(automation_task_metadata.state != CANCELLED, EALREADY_CANCELLED); if (automation_task_metadata.state == PENDING) { enumerable_map::remove_value(&mut automation_registry.main.tasks, task_index); + vector::remove_value(&mut automation_registry.system_tasks_state.task_ids, &task_index); } else { // it is safe not to check the state as above, the cancelled tasks are already rejected. let automation_task_metadata_mut = enumerable_map::get_value_mut( &mut automation_registry.main.tasks, @@ -5654,6 +5655,7 @@ In case if end is identified the registry state is update to CYCLE_READY and cor vector::for_each(task_indexes, |task_index| { if (enumerable_map::contains(&automation_registry.main.tasks, task_index)) { let task = enumerable_map::remove_value(&mut automation_registry.main.tasks, task_index); + vector::push_back(&mut removed_tasks, task_index); mark_task_processed(transition_state, task_index); // Nothing to refund for GST tasks if (is_of_type(&task, UST)) { @@ -5666,9 +5668,8 @@ In case if end is identified the registry state is update to CYCLE_READY and cor &resource_signer, epoch_locked_fees, current_time, - &mut removed_tasks ) - }; + } } }); @@ -5902,7 +5903,7 @@ Removes system task from registry state. Refunds the deposit fee and any autoamtion fees of the task. -
fun refund_task_fees(task: automation_registry::AutomationTaskMetaData, automation_registry: &mut automation_registry::AutomationRegistry, refund_bookkeeping: &mut automation_registry::AutomationRefundBookkeeping, arc: &automation_registry::ActiveAutomationRegistryConfigV2, transition_state: &mut automation_registry::TransitionState, resource_signer: &signer, epoch_locked_fees: u64, current_time: u64, removed_tasks: &mut vector<u64>): u64
+
fun refund_task_fees(task: automation_registry::AutomationTaskMetaData, automation_registry: &mut automation_registry::AutomationRegistry, refund_bookkeeping: &mut automation_registry::AutomationRefundBookkeeping, arc: &automation_registry::ActiveAutomationRegistryConfigV2, transition_state: &mut automation_registry::TransitionState, resource_signer: &signer, epoch_locked_fees: u64, current_time: u64): u64
 
@@ -5920,7 +5921,6 @@ Refunds the deposit fee and any autoamtion fees of the task. resource_signer: &signer, epoch_locked_fees: u64, current_time: u64, - removed_tasks: &mut vector<u64> ) : u64 { assert!(is_of_type(&task, UST), EREGISTERED_TASK_INVALID_TYPE); @@ -5950,7 +5950,6 @@ Refunds the deposit fee and any autoamtion fees of the task. task.owner, task.locked_fee_for_next_epoch, task.locked_fee_for_next_epoch); - vector::push_back(removed_tasks, task.task_index); epoch_locked_fees }
diff --git a/aptos-move/framework/supra-framework/sources/automation_registry.move b/aptos-move/framework/supra-framework/sources/automation_registry.move index b0add20e7e9..5c162aaa74c 100644 --- a/aptos-move/framework/supra-framework/sources/automation_registry.move +++ b/aptos-move/framework/supra-framework/sources/automation_registry.move @@ -1471,6 +1471,7 @@ module supra_framework::automation_registry { assert!(automation_task_metadata.state != CANCELLED, EALREADY_CANCELLED); if (automation_task_metadata.state == PENDING) { enumerable_map::remove_value(&mut automation_registry.main.tasks, task_index); + vector::remove_value(&mut automation_registry.system_tasks_state.task_ids, &task_index); } else { // it is safe not to check the state as above, the cancelled tasks are already rejected. let automation_task_metadata_mut = enumerable_map::get_value_mut( &mut automation_registry.main.tasks, @@ -2047,6 +2048,7 @@ module supra_framework::automation_registry { vector::for_each(task_indexes, |task_index| { if (enumerable_map::contains(&automation_registry.main.tasks, task_index)) { let task = enumerable_map::remove_value(&mut automation_registry.main.tasks, task_index); + vector::push_back(&mut removed_tasks, task_index); mark_task_processed(transition_state, task_index); // Nothing to refund for GST tasks if (is_of_type(&task, UST)) { @@ -2059,9 +2061,8 @@ module supra_framework::automation_registry { &resource_signer, epoch_locked_fees, current_time, - &mut removed_tasks ) - }; + } } }); @@ -2213,7 +2214,6 @@ module supra_framework::automation_registry { resource_signer: &signer, epoch_locked_fees: u64, current_time: u64, - removed_tasks: &mut vector ) : u64 { assert!(is_of_type(&task, UST), EREGISTERED_TASK_INVALID_TYPE); @@ -2243,7 +2243,6 @@ module supra_framework::automation_registry { task.owner, task.locked_fee_for_next_epoch, task.locked_fee_for_next_epoch); - vector::push_back(removed_tasks, task.task_index); epoch_locked_fees } diff --git a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move index 2743f509df2..379b60cd54f 100644 --- a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move +++ b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move @@ -4048,58 +4048,78 @@ module std::automation_registry_tests { initialize_registry_test(framework, user); let (multisig_address, multisig_signer) = setup_multisig_account(framework, user); automation_registry::grant_authorization(framework, multisig_address); + let max_gas_amount = 10; let _ = automation_registry::register_system_task_with_state( &multisig_signer, - 10, + max_gas_amount, 86400, ACTIVE ); let _ = automation_registry::register_system_task_with_state( &multisig_signer, - 10, + max_gas_amount, 86400, ACTIVE ); - // check account balances after registration + // check account balances after registration, no charges are expected let registry_fee_address = automation_registry::get_registry_fee_address(); let user_address = address_of(user); check_account_balance(user_address, ACCOUNT_BALANCE); check_account_balance(multisig_address, ACCOUNT_BALANCE); check_account_balance(registry_fee_address, REGISTRY_DEFAULT_BALANCE); - assert!(20 == automation_registry::get_system_gas_committed_for_next_cycle(), 1); + assert!((2 * max_gas_amount) == automation_registry::get_system_gas_committed_for_next_cycle(), 1); let active_task_ids = automation_registry::get_active_task_ids(); let expected_ids = vector[0, 1]; vector::for_each(expected_ids, |task_index| { assert!(vector::contains(&active_task_ids, &task_index), 1); }); - // Cancel task 2. The committed gas for the next epoch will be updated, + let system_task_ids = automation_registry::get_system_task_indexes(); + vector::for_each(expected_ids, |task_index| { + assert!(vector::contains(&system_task_ids, &task_index), 1); + }); + // Cancel second registered task . The committed gas for the next cycle by system tasks will be updated, // but when requested active task it will be still available in the list automation_registry::cancel_system_task(&multisig_signer, 1); // Task will be still available in the registry but with cancelled state automation_registry::check_task_state(1, true, CANCELLED); - assert!(10 == automation_registry::get_system_gas_committed_for_next_cycle(), 1); + assert!(max_gas_amount == automation_registry::get_system_gas_committed_for_next_cycle(), 1); let active_task_ids = automation_registry::get_active_task_ids(); vector::for_each(expected_ids, |task_index| { assert!(vector::contains(&active_task_ids, &task_index), 1); + }); + let system_task_ids = automation_registry::get_system_task_indexes(); + vector::for_each(expected_ids, |task_index| { + assert!(vector::contains(&system_task_ids, &task_index), 1); }); - // Add and cancel the task in the same epoch. Task index will be 4 + // Add and cancel the task in the same cycle. Task index will be 2 assert!(automation_registry::get_next_task_index() == 2, 1); automation_registry::register_system_task_with_state(&multisig_signer, 10, 86400, PENDING, ); + let expected_system_ids = vector[0, 1, 2]; + let system_task_ids = automation_registry::get_system_task_indexes(); + vector::for_each(expected_ids, |task_index| { + assert!(vector::contains(&system_task_ids, &task_index), 1); + }); automation_registry::cancel_system_task(&multisig_signer, 2); - assert!(10 == automation_registry::get_system_gas_committed_for_next_cycle(), 1); + assert!(max_gas_amount == automation_registry::get_system_gas_committed_for_next_cycle(), 1); let active_task_ids = automation_registry::get_active_task_ids(); vector::for_each(expected_ids, |task_index| { assert!(vector::contains(&active_task_ids, &task_index), 1); }); + let expected_system_ids = vector[0, 1]; + let system_task_ids = automation_registry::get_system_task_indexes(); + vector::for_each(expected_ids, |task_index| { + assert!(vector::contains(&system_task_ids, &task_index), 1); + }); + // there is no task with index 2 and the next task index will be 3. assert!(!automation_registry::has_task_with_id(2), 1); assert!(automation_registry::get_next_task_index() == 3, 1); @@ -4202,7 +4222,7 @@ module std::automation_registry_tests { } #[test(framework = @supra_framework, user = @0x1caff)] - fun check_system_task_successful_stopped( + fun check_system_task_successfully_stopped( framework: &signer, user: &signer ) { @@ -4259,7 +4279,12 @@ module std::automation_registry_tests { assert!(vector::contains(&active_task_ids, &task_index), 2); }); - // 0.002 (*4) - automation_epoch_fee_per_second, 7200 epoch duration + let system_task_ids = automation_registry::get_system_task_indexes(); + vector::for_each(expected_ids, |task_index| { + assert!(vector::contains(&active_task_ids, &task_index), 2); + }); + + // No fees are charged check_account_balance( multisig_address, ACCOUNT_BALANCE ); check_account_balance(user_account, ACCOUNT_BALANCE ); check_account_balance( registry_fee_address, REGISTRY_DEFAULT_BALANCE ); @@ -4311,7 +4336,7 @@ module std::automation_registry_tests { assert!(automation_registry::get_next_task_index() == 5, 1); assert!(3 * max_gas_amount == automation_registry::get_system_gas_committed_for_next_cycle(), 1); - // Check balances after test execution + // Check balances after test execution, no fees are charged or refunded. check_account_balance(multisig_address, ACCOUNT_BALANCE); check_account_balance(user_account, ACCOUNT_BALANCE); check_account_balance(registry_fee_address, REGISTRY_DEFAULT_BALANCE); From 1d856778c65f598720016dfac5755692c6c30a44 Mon Sep 17 00:00:00 2001 From: Saurabh Joshi <106232965+sjoshisupra@users.noreply.github.com> Date: Mon, 8 Dec 2025 12:05:40 +0530 Subject: [PATCH 02/31] add ability for admin to delay unlock by specified periods (#312) Co-authored-by: Saurabh Joshi --- .../sources/pbo_delegation_pool.move | 240 +++++++++++++++++- 1 file changed, 239 insertions(+), 1 deletion(-) diff --git a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move index 848188e4aae..6653a7e098c 100644 --- a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move +++ b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move @@ -256,7 +256,11 @@ module supra_framework::pbo_delegation_pool { /// amount of stake available in the specified stake pool. const EINSUFFICIENT_STAKE_TO_LOCK: u64 = 40; + /// Unlocking has already started, so unlock schedule can not be updated const EUNLOCKING_ALREADY_STARTED: u64 = 41; + + /// Can not increase last unlock period if not at the last element of schedule + const EINVALID_STATE_FOR_OPERATION: u64 = 42; const MAX_U64: u64 = 18446744073709551615; @@ -1846,6 +1850,31 @@ module supra_framework::pbo_delegation_pool { ); } + + public entry fun admin_increase_last_unlock_period( + multisig_admin: &signer, + pool_address: address, + additional_periods: u64 + ) acquires DelegationPool { + // Ensure that the caller is the admin of the delegation pool. + { + assert!( + is_admin(signer::address_of(multisig_admin), pool_address), + error::permission_denied(ENOT_AUTHORIZED) + ); + }; + + let delegation_pool = borrow_global_mut(pool_address); + let last_unlocked_period = delegation_pool.principle_unlock_schedule.last_unlock_period; + let schedule_length = vector::length(&delegation_pool.principle_unlock_schedule.schedule); + // Current last_unlock_period must be greater or equal to schedule_length -1, this is because + // last_unlock_period is used as index into schedule vector. If we are not already at the last index or beyond + // increasing this would have undesirable effect. For example if schedule is [20%, 30%, 10%] and + // last_unlock_period = 1, increasing it by two would directly go to 10% unlock skipping 30% unlock part + assert!(schedule_length -1 <= last_unlocked_period, EINVALID_STATE_FOR_OPERATION); + delegation_pool.principle_unlock_schedule.last_unlock_period = delegation_pool.principle_unlock_schedule.last_unlock_period + additional_periods; + + } /// Updates the `principle_stake` of each `delegator` in `delegators` according to the amount specified /// at the corresponding index of `new_principle_stakes`. Also ensures that the `delegator`'s `active` stake /// is as close to the specified amount as possible. The locked amount is subject to the vesting schedule @@ -2190,7 +2219,7 @@ module supra_framework::pbo_delegation_pool { cfraction = fixed_point64::min(cfraction, one); }; unlock_schedule.cumulative_unlocked_fraction = cfraction; - unlock_schedule.last_unlock_period = unlock_periods_passed; + unlock_schedule.last_unlock_period = math64::max(unlock_periods_passed, last_unlocked_period); let unlockable_amount = cached_unlockable_balance(delegator_addr, pool_address); amount <= unlockable_amount } @@ -8867,6 +8896,215 @@ module supra_framework::pbo_delegation_pool { can_principle_unlock(delegator_address, pool_address, 100 * ONE_SUPRA); assert!(unlock_coin, 18); } + + #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] + #[expected_failure(abort_code = 42, location = Self)] + /// say unlocking schedule is 3 month cliff, monthly unlocking of (2,3,1) tange and principle stake is 100 coins then + /// at the end of 3 months, one can't unlock there principal stacke + /// after 4 months only 90 should remain locked + /// try delaying unlock at this point, which should result in a failure + public entry fun test_increase_last_unlock_period_failure( + supra_framework: &signer, validator: &signer, delegator: &signer + ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + initialize_for_test(supra_framework); + account::create_account_for_test(signer::address_of(validator)); + let delegator_address = signer::address_of(delegator); + let delegator_address_vec = vector[delegator_address]; + let principle_stake = vector[100 * ONE_SUPRA]; + let coin = stake::mint_coins(100 * ONE_SUPRA); + let principle_lockup_time = 7776000; // 3 month cliff + let multisig = generate_multisig_account(validator, vector[@0x12134], 2); + + initialize_test_validator( + validator, + 0, + true, + true, + 0, + delegator_address_vec, + principle_stake, + coin, + option::some(multisig), + vector[2, 3, 1], + 10, + principle_lockup_time, + LOCKUP_CYCLE_SECONDS // monthly unlocking + ); + let validator_address = signer::address_of(validator); + let pool_address = get_owned_pool_address(validator_address); + + // after 2 month unlock reward + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // 3 month + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // after 4 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // Delay unlock by 3 months + let multisig_signer = account::create_signer_for_test(multisig); + admin_increase_last_unlock_period(&multisig_signer, pool_address, 3); + } + + #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] + /// say unlocking schedule is 3 month cliff, monthly unlocking of (2,3,1) tange and principle stake is 100 coins then + /// at the end of 3 months, one can't unlock there principal stacke + /// after 4 months only 90 should remain locked + /// after 5 months only 80 should remain locked and so on + /// then increase unlock period and see if unlocking works as expected + public entry fun test_increase_last_unlock_period_success( + supra_framework: &signer, validator: &signer, delegator: &signer + ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + initialize_for_test(supra_framework); + account::create_account_for_test(signer::address_of(validator)); + let delegator_address = signer::address_of(delegator); + let delegator_address_vec = vector[delegator_address]; + let principle_stake = vector[100 * ONE_SUPRA]; + let coin = stake::mint_coins(100 * ONE_SUPRA); + let principle_lockup_time = 7776000; // 3 month cliff + let multisig = generate_multisig_account(validator, vector[@0x12134], 2); + + initialize_test_validator( + validator, + 0, + true, + true, + 0, + delegator_address_vec, + principle_stake, + coin, + option::some(multisig), + vector[2, 3, 1], + 10, + principle_lockup_time, + LOCKUP_CYCLE_SECONDS // monthly unlocking + ); + let validator_address = signer::address_of(validator); + let pool_address = get_owned_pool_address(validator_address); + + // after 2 month unlock reward + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // 3 month + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // after 4 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. + let unlock_coin = + can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9 + ); + assert!(unlock_coin, 11); + + + // after 5 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9 + ); + assert!(unlock_coin, 12); + + // Delay unlock by 3 months + let multisig_signer = account::create_signer_for_test(multisig); + admin_increase_last_unlock_period(&multisig_signer, pool_address, 3); + + // after 6 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9 + ); + assert!(unlock_coin, 13); + + // after 7 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9 + ); + assert!(unlock_coin, 14); + + // after 8 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9 + ); + assert!(unlock_coin, 15); + + // after 9 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9 + ); + assert!(unlock_coin, 16); + + // after 10 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) - 10 + ); + assert!(unlock_coin, 17); + + // after 11 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock(delegator_address, pool_address, 80 * ONE_SUPRA-9); + assert!(unlock_coin, 18); + + // after 14 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS*3); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock(delegator_address, pool_address, 100 * ONE_SUPRA); + assert!(unlock_coin, 18); + + // after 20 months + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS*6); + end_aptos_epoch(); + let unlock_coin = + can_principle_unlock(delegator_address, pool_address, 100 * ONE_SUPRA); + assert!(unlock_coin, 18); + + + } #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] //Test that `last_unlock_period` increases only up to the point so as to allow From cb4f7aaf354f3ac0de257467dc1307fdf38529bc Mon Sep 17 00:00:00 2001 From: Kiran Kumar Roy Date: Fri, 12 Dec 2025 19:01:35 +0530 Subject: [PATCH 03/31] cli help text (#317) --- crates/aptos/src/common/types.rs | 4 ++-- crates/aptos/src/move_tool/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/aptos/src/common/types.rs b/crates/aptos/src/common/types.rs index ac66783dcc1..3c2019b357b 100644 --- a/crates/aptos/src/common/types.rs +++ b/crates/aptos/src/common/types.rs @@ -1088,10 +1088,10 @@ pub struct MovePackageDir { #[clap(long)] pub skip_attribute_checks: bool, - /// Do apply extended checks for Aptos (e.g. `#[view]` attribute) also on test code. + /// Do apply extended checks (e.g. `#[view]` attribute) also on test code. /// NOTE: this behavior will become the default in the future. /// See - #[clap(long, env = "APTOS_CHECK_TEST_CODE")] + #[clap(long, env = "SUPRA_CHECK_TEST_CODE")] pub check_test_code: bool, } diff --git a/crates/aptos/src/move_tool/mod.rs b/crates/aptos/src/move_tool/mod.rs index c95b5730be4..22ce1652206 100644 --- a/crates/aptos/src/move_tool/mod.rs +++ b/crates/aptos/src/move_tool/mod.rs @@ -465,7 +465,7 @@ pub struct TestPackage { )] pub instruction_execution_bound: u64, - /// Collect coverage information for later use with the various `aptos move coverage` subcommands + /// Collect coverage information for later use with the various `supra move tool coverage` subcommands #[clap(long = "coverage")] pub compute_coverage: bool, @@ -533,7 +533,7 @@ impl CliCommand<&'static str> for TestPackage { }; summary.coverage()?; - println!("Please use `aptos move coverage -h` for more detailed source or bytecode test coverage of this package"); + println!("Please use `supra move tool coverage -h` for more detailed source or bytecode test coverage of this package"); } match result { From 2807494815ff1f90d22ba804d1c6eadb21f5d961 Mon Sep 17 00:00:00 2001 From: Aregnaz Harutyunyan <89187359+aregng@users.noreply.github.com> Date: Fri, 12 Dec 2025 18:48:19 +0400 Subject: [PATCH 04/31] Updated prebuilt packages as follow up of #311 fix (#319) Co-authored-by: Aregnaz Harutyunyan <> --- .../src/aptos_framework_sdk_builder.rs | 52 ++++++++++++++++ .../doc/pbo_delegation_pool.md | 60 ++++++++++++++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs index 345dc79fcde..a55a28a0d4e 100644 --- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs @@ -565,6 +565,11 @@ pub enum EntryFunctionCall { amount: u64, }, + PboDelegationPoolAdminIncreaseLastUnlockPeriod { + pool_address: AccountAddress, + additional_periods: u64, + }, + /// Allows a delegator to delegate its voting power to a voter. If this delegator already has a delegated voter, /// this change won't take effects until the next lockup period. PboDelegationPoolDelegateVotingPower { @@ -1609,6 +1614,13 @@ impl EntryFunctionCall { pool_address, amount, } => pbo_delegation_pool_add_stake(pool_address, amount), + PboDelegationPoolAdminIncreaseLastUnlockPeriod { + pool_address, + additional_periods, + } => pbo_delegation_pool_admin_increase_last_unlock_period( + pool_address, + additional_periods, + ), PboDelegationPoolDelegateVotingPower { pool_address, new_voter, @@ -3500,6 +3512,27 @@ pub fn pbo_delegation_pool_add_stake( )) } +pub fn pbo_delegation_pool_admin_increase_last_unlock_period( + pool_address: AccountAddress, + additional_periods: u64, +) -> TransactionPayload { + TransactionPayload::EntryFunction(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!("pbo_delegation_pool").to_owned(), + ), + ident_str!("admin_increase_last_unlock_period").to_owned(), + vec![], + vec![ + bcs::to_bytes(&pool_address).unwrap(), + bcs::to_bytes(&additional_periods).unwrap(), + ], + )) +} + /// Allows a delegator to delegate its voting power to a voter. If this delegator already has a delegated voter, /// this change won't take effects until the next lockup period. pub fn pbo_delegation_pool_delegate_voting_power( @@ -6413,6 +6446,21 @@ mod decoder { } } + pub fn pbo_delegation_pool_admin_increase_last_unlock_period( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some( + EntryFunctionCall::PboDelegationPoolAdminIncreaseLastUnlockPeriod { + pool_address: bcs::from_bytes(script.args().get(0)?).ok()?, + additional_periods: bcs::from_bytes(script.args().get(1)?).ok()?, + }, + ) + } else { + None + } + } + pub fn pbo_delegation_pool_delegate_voting_power( payload: &TransactionPayload, ) -> Option { @@ -7918,6 +7966,10 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazyuse 0x1::features; use 0x1::fixed_point64; use 0x1::math128; +use 0x1::math64; use 0x1::multisig_account; use 0x1::option; use 0x1::pool_u64_unbound; @@ -1589,6 +1591,16 @@ amount of stake available in the specified stake pool. + + +Can not increase last unlock period if not at the last element of schedule + + +
const EINVALID_STATE_FOR_OPERATION: u64 = 42;
+
+ + + Minimum amount of coins to be unlocked. @@ -1720,6 +1732,7 @@ Commission percentage change is too late in this lockup period, and should be do +Unlocking has already started, so unlock schedule can not be updated
const EUNLOCKING_ALREADY_STARTED: u64 = 41;
@@ -4392,6 +4405,51 @@ validator-owners to prevent it from being abused.
 
 
 
+
+
+
+
+## Function `admin_increase_last_unlock_period`
+
+
+
+
public entry fun admin_increase_last_unlock_period(multisig_admin: &signer, pool_address: address, additional_periods: u64)
+
+ + + +
+Implementation + + +
public entry fun admin_increase_last_unlock_period(
+    multisig_admin: &signer,
+    pool_address: address,
+    additional_periods: u64
+) acquires DelegationPool {
+    // Ensure that the caller is the admin of the delegation pool.
+    {
+        assert!(
+            is_admin(signer::address_of(multisig_admin), pool_address),
+            error::permission_denied(ENOT_AUTHORIZED)
+        );
+    };
+
+    let delegation_pool = borrow_global_mut<DelegationPool>(pool_address);
+    let last_unlocked_period = delegation_pool.principle_unlock_schedule.last_unlock_period;
+    let schedule_length = vector::length(&delegation_pool.principle_unlock_schedule.schedule);
+    // Current last_unlock_period must be greater or equal to schedule_length -1, this is because
+    // last_unlock_period is used as index into schedule vector. If we are not already at the last index or beyond
+    // increasing this would have undesirable effect. For example if schedule is [20%, 30%, 10%] and
+    // last_unlock_period = 1, increasing it by two would directly go to 10% unlock skipping 30% unlock part
+    assert!(schedule_length -1 <= last_unlocked_period, EINVALID_STATE_FOR_OPERATION);
+    delegation_pool.principle_unlock_schedule.last_unlock_period = delegation_pool.principle_unlock_schedule.last_unlock_period + additional_periods;
+
+}
+
+ + +
@@ -4852,7 +4910,7 @@ Note: this does not synchronize with stake pool, therefore the answer may be con cfraction = fixed_point64::min(cfraction, one); }; unlock_schedule.cumulative_unlocked_fraction = cfraction; - unlock_schedule.last_unlock_period = unlock_periods_passed; + unlock_schedule.last_unlock_period = math64::max(unlock_periods_passed, last_unlocked_period); let unlockable_amount = cached_unlockable_balance(delegator_addr, pool_address); amount <= unlockable_amount } From f9a2fb81f96bb822546d379d5f43fb76b55eaecc Mon Sep 17 00:00:00 2001 From: Kiran Kumar Roy Date: Wed, 17 Dec 2025 16:12:41 +0530 Subject: [PATCH 05/31] correction on cli command usage (2532) (#320) * correction on cli command usage (2532) * Correction on the example of --type-args --- crates/aptos/src/common/types.rs | 5 +++-- crates/aptos/src/move_tool/coverage.rs | 2 +- crates/aptos/src/move_tool/mod.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/aptos/src/common/types.rs b/crates/aptos/src/common/types.rs index 3c2019b357b..84e057d8fbc 100644 --- a/crates/aptos/src/common/types.rs +++ b/crates/aptos/src/common/types.rs @@ -1969,9 +1969,10 @@ impl MultisigAccountWithSequenceNumber { #[derive(Clone, Debug, Parser)] pub struct TypeArgVec { - /// TypeTag arguments separated by spaces. + /// Type arguments for generic type parameters in Move functions, separated by spaces. + /// Commonly used to specify coin types, resource types, or other struct types. /// - /// Example: `u8 u16 u32 u64 u128 u256 bool address vector signer` + /// Example: `0x1::supra_coin::SupraCoin` #[clap(long, num_args = 0..)] pub(crate) type_args: Vec, } diff --git a/crates/aptos/src/move_tool/coverage.rs b/crates/aptos/src/move_tool/coverage.rs index 102a22e3c90..5ceecfe37c6 100644 --- a/crates/aptos/src/move_tool/coverage.rs +++ b/crates/aptos/src/move_tool/coverage.rs @@ -172,7 +172,7 @@ fn compile_coverage( /// Computes coverage for a package /// /// Computes coverage on a previous unit test run for a package. Coverage input must -/// first be built with `aptos move test --coverage` +/// first be built with `supra move tool test --coverage` #[derive(Subcommand)] pub enum CoveragePackage { Summary(SummaryCoverage), diff --git a/crates/aptos/src/move_tool/mod.rs b/crates/aptos/src/move_tool/mod.rs index 22ce1652206..57e581d1641 100644 --- a/crates/aptos/src/move_tool/mod.rs +++ b/crates/aptos/src/move_tool/mod.rs @@ -364,7 +364,7 @@ impl CliCommand> for CompilePackage { /// Compiles a Move script into bytecode /// /// Compiles a script into bytecode and provides a hash of the bytecode. -/// This can then be run with `aptos move run-script` +/// This can then be run with `supra move tool run-script` #[derive(Parser)] pub struct CompileScript { #[clap(long, value_parser)] From 7f9a4471a1c29168ba5a109bf03d27a0a21f58f0 Mon Sep 17 00:00:00 2001 From: Saurabh Joshi <106232965+sjoshisupra@users.noreply.github.com> Date: Tue, 6 Jan 2026 19:36:06 +0530 Subject: [PATCH 06/31] Issue 323 (#324) * add update_unlocking_schedule_unchecked * add scenario that non admin can not invoke schedule update * add vesting delay method for admin (#325) Co-authored-by: Saurabh Joshi --------- Co-authored-by: Saurabh Joshi --- .../src/aptos_framework_sdk_builder.rs | 76 + .../sources/pbo_delegation_pool.move | 2844 +++++++++-------- .../sources/vesting_without_staking.move | 1140 ++++--- 3 files changed, 2218 insertions(+), 1842 deletions(-) diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs index a55a28a0d4e..8ef75faeb7e 100644 --- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs @@ -708,6 +708,15 @@ pub enum EntryFunctionCall { unlock_duration: u64, }, + PboDelegationPoolUpdateUnlockingScheduleUnchecked { + pool_address: AccountAddress, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: u64, + last_unlock_period: u64, + }, + /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. PboDelegationPoolWithdraw { pool_address: AccountAddress, @@ -1736,6 +1745,21 @@ impl EntryFunctionCall { unlock_start_time, unlock_duration, ), + PboDelegationPoolUpdateUnlockingScheduleUnchecked { + pool_address, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + last_unlock_period, + } => pbo_delegation_pool_update_unlocking_schedule_unchecked( + pool_address, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + last_unlock_period, + ), PboDelegationPoolWithdraw { pool_address, amount, @@ -3924,6 +3948,35 @@ pub fn pbo_delegation_pool_update_unlocking_schedule( )) } +pub fn pbo_delegation_pool_update_unlocking_schedule_unchecked( + pool_address: AccountAddress, + unlock_numerators: Vec, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: u64, + last_unlock_period: u64, +) -> TransactionPayload { + TransactionPayload::EntryFunction(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!("pbo_delegation_pool").to_owned(), + ), + ident_str!("update_unlocking_schedule_unchecked").to_owned(), + vec![], + vec![ + bcs::to_bytes(&pool_address).unwrap(), + bcs::to_bytes(&unlock_numerators).unwrap(), + bcs::to_bytes(&unlock_denominator).unwrap(), + bcs::to_bytes(&unlock_start_time).unwrap(), + bcs::to_bytes(&unlock_duration).unwrap(), + bcs::to_bytes(&last_unlock_period).unwrap(), + ], + )) +} + /// Withdraw `amount` of owned inactive stake from the delegation pool at `pool_address`. pub fn pbo_delegation_pool_withdraw( pool_address: AccountAddress, @@ -6699,6 +6752,25 @@ mod decoder { } } + pub fn pbo_delegation_pool_update_unlocking_schedule_unchecked( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some( + EntryFunctionCall::PboDelegationPoolUpdateUnlockingScheduleUnchecked { + pool_address: bcs::from_bytes(script.args().get(0)?).ok()?, + unlock_numerators: bcs::from_bytes(script.args().get(1)?).ok()?, + unlock_denominator: bcs::from_bytes(script.args().get(2)?).ok()?, + unlock_start_time: bcs::from_bytes(script.args().get(3)?).ok()?, + unlock_duration: bcs::from_bytes(script.args().get(4)?).ok()?, + last_unlock_period: bcs::from_bytes(script.args().get(5)?).ok()?, + }, + ) + } else { + None + } + } + pub fn pbo_delegation_pool_withdraw(payload: &TransactionPayload) -> Option { if let TransactionPayload::EntryFunction(script) = payload { Some(EntryFunctionCall::PboDelegationPoolWithdraw { @@ -8031,6 +8103,10 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazy(pool_address) - && stake::get_delegated_voter(pool_address) == pool_address + exists(pool_address) && stake::get_delegated_voter( + pool_address + ) == pool_address } #[view] @@ -544,16 +545,13 @@ module supra_framework::pbo_delegation_pool { public fun is_next_commission_percentage_effective( pool_address: address ): bool acquires NextCommissionPercentage { - exists(pool_address) - && timestamp::now_seconds() - >= borrow_global(pool_address).effective_after_secs + exists(pool_address) && timestamp::now_seconds() >= borrow_global< + NextCommissionPercentage>(pool_address).effective_after_secs } #[view] /// Return the operator commission percentage set on the delegation pool `pool_address`. - public fun operator_commission_percentage( - pool_address: address - ): u64 acquires DelegationPool, NextCommissionPercentage { + public fun operator_commission_percentage(pool_address: address): u64 acquires DelegationPool, NextCommissionPercentage { assert_delegation_pool_exists(pool_address); if (is_next_commission_percentage_effective(pool_address)) { operator_commission_percentage_next_lockup_cycle(pool_address) @@ -580,7 +578,7 @@ module supra_framework::pbo_delegation_pool { public fun shareholders_count_active_pool(pool_address: address): u64 acquires DelegationPool { assert_delegation_pool_exists(pool_address); pool_u64::shareholders_count( - &borrow_global(pool_address).active_shares + &borrow_global(pool_address).active_shares, ) } @@ -600,11 +598,13 @@ module supra_framework::pbo_delegation_pool { ): (bool, u64) acquires DelegationPool { assert_delegation_pool_exists(pool_address); let pool = borrow_global(pool_address); - let (lockup_cycle_ended, _, pending_inactive, _, commission_pending_inactive) = - calculate_stake_pool_drift(pool); + let (lockup_cycle_ended, _, pending_inactive, _, commission_pending_inactive) = calculate_stake_pool_drift( + pool + ); - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, delegator_address); + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, delegator_address + ); if (!withdrawal_exists) { // if no pending withdrawal, there is neither inactive nor pending_inactive stake (false, 0) @@ -619,7 +619,7 @@ module supra_framework::pbo_delegation_pool { inactive_shares, pool_u64::shares(inactive_shares, delegator_address), // exclude operator pending_inactive rewards not converted to shares yet - pending_inactive - commission_pending_inactive + pending_inactive - commission_pending_inactive, ); // if withdrawal's lockup cycle ended ONLY on stake pool then it is also inactive (lockup_cycle_ended, pending_inactive) @@ -636,19 +636,20 @@ module supra_framework::pbo_delegation_pool { assert_delegation_pool_exists(pool_address); let pool = borrow_global(pool_address); let (lockup_cycle_ended, active, _, commission_active, commission_pending_inactive) = - - calculate_stake_pool_drift(pool); + calculate_stake_pool_drift(pool); let total_active_shares = pool_u64::total_shares(&pool.active_shares); - let delegator_active_shares = - pool_u64::shares(&pool.active_shares, delegator_address); + let delegator_active_shares = pool_u64::shares( + &pool.active_shares, delegator_address + ); let (_, _, pending_active, _) = stake::get_stake(pool_address); if (pending_active == 0) { // zero `pending_active` stake indicates that either there are no `add_stake` fees or // previous epoch has ended and should identify shares owning these fees as released - total_active_shares = total_active_shares - - pool_u64::shares(&pool.active_shares, NULL_SHAREHOLDER); + total_active_shares = total_active_shares - pool_u64::shares( + &pool.active_shares, NULL_SHAREHOLDER + ); if (delegator_address == NULL_SHAREHOLDER) { delegator_active_shares = 0 } @@ -658,16 +659,16 @@ module supra_framework::pbo_delegation_pool { delegator_active_shares, // exclude operator active rewards not converted to shares yet active - commission_active, - total_active_shares + total_active_shares, ); // get state and stake (0 if there is none) of the pending withdrawal - let (withdrawal_inactive, withdrawal_stake) = - get_pending_withdrawal(pool_address, delegator_address); + let (withdrawal_inactive, withdrawal_stake) = get_pending_withdrawal( + pool_address, delegator_address + ); // report non-active stakes accordingly to the state of the pending withdrawal let (inactive, pending_inactive) = - if (withdrawal_inactive) (withdrawal_stake, 0) - else (0, withdrawal_stake); + if (withdrawal_inactive) (withdrawal_stake, 0) else (0, withdrawal_stake); // should also include commission rewards in case of the operator account // operator rewards are actually used to buy shares which is introducing @@ -695,21 +696,24 @@ module supra_framework::pbo_delegation_pool { /// To mitigate this, some of the added stake is extracted and fed back into the pool as placeholder /// for the rewards the remaining stake would have earned if active: /// extracted-fee = (amount - extracted-fee) * reward-rate% * (100% - operator-commission%) - public fun get_add_stake_fee( - pool_address: address, amount: u64 - ): u64 acquires DelegationPool, NextCommissionPercentage { + public fun get_add_stake_fee(pool_address: address, amount: u64): u64 acquires DelegationPool, NextCommissionPercentage { if (stake::is_current_epoch_validator(pool_address)) { - let (rewards_rate, rewards_rate_denominator) = - staking_config::get_reward_rate(&staking_config::get()); + let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate( + &staking_config::get() + ); if (rewards_rate_denominator != 0) { assert_delegation_pool_exists(pool_address); - rewards_rate = rewards_rate - * (MAX_FEE - operator_commission_percentage(pool_address)); + rewards_rate = rewards_rate * ( + MAX_FEE - operator_commission_percentage(pool_address) + ); rewards_rate_denominator = rewards_rate_denominator * MAX_FEE; ( - (((amount as u128) * (rewards_rate as u128)) - / ((rewards_rate as u128) + (rewards_rate_denominator as u128))) as u64 + ( + ((amount as u128) * (rewards_rate as u128)) / ( + (rewards_rate as u128) + (rewards_rate_denominator as u128) + ) + ) as u64 ) } else { 0 } } else { 0 } @@ -720,8 +724,8 @@ module supra_framework::pbo_delegation_pool { /// the delegation pool, implicitly its stake pool, in the special case /// the validator had gone inactive before its lockup expired. public fun can_withdraw_pending_inactive(pool_address: address): bool { - stake::get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE - && timestamp::now_seconds() >= stake::get_lockup_secs(pool_address) + stake::get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE && timestamp::now_seconds() + >= stake::get_lockup_secs(pool_address) } #[view] @@ -736,8 +740,9 @@ module supra_framework::pbo_delegation_pool { synchronize_delegation_pool(pool_address); let pool = borrow_global(pool_address); let governance_records = borrow_global_mut(pool_address); - let latest_delegated_votes = - update_and_borrow_mut_delegated_votes(pool, governance_records, voter); + let latest_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, voter + ); calculate_total_voting_power(pool, latest_delegated_votes) } @@ -751,7 +756,7 @@ module supra_framework::pbo_delegation_pool { calculate_and_update_delegator_voter_internal( borrow_global(pool_address), borrow_global_mut(pool_address), - delegator_address + delegator_address, ) } @@ -787,7 +792,7 @@ module supra_framework::pbo_delegation_pool { ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( coin::balance(signer::address_of(owner)) >= amount, - error::invalid_argument(EBALANCE_NOT_SUFFICIENT) + error::invalid_argument(EBALANCE_NOT_SUFFICIENT), ); let coin = coin::withdraw(owner, amount); @@ -802,7 +807,7 @@ module supra_framework::pbo_delegation_pool { unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ) } @@ -821,7 +826,7 @@ module supra_framework::pbo_delegation_pool { ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( coin::balance(signer::address_of(owner)) >= amount, - error::invalid_argument(EBALANCE_NOT_SUFFICIENT) + error::invalid_argument(EBALANCE_NOT_SUFFICIENT), ); let coin = coin::withdraw(owner, amount); @@ -836,17 +841,17 @@ module supra_framework::pbo_delegation_pool { unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ) } #[view] /// Return the unlock schedule of the pool as (schedule, start_time, period_duration, last_unlock_period, cumulative_unlocked_fraction) - public fun get_unlock_schedule( - pool_address: address - ): (vector, u64, u64, u64, FixedPoint64) acquires DelegationPool { - let uschedule = - borrow_global(pool_address).principle_unlock_schedule; + public fun get_unlock_schedule(pool_address: address) + : ( + vector, u64, u64, u64, FixedPoint64 + ) acquires DelegationPool { + let uschedule = borrow_global(pool_address).principle_unlock_schedule; ( uschedule.schedule, uschedule.start_timestamp_secs, @@ -860,25 +865,73 @@ module supra_framework::pbo_delegation_pool { // Create `vector` for schedule fractions from numerators and a denominator // Pre-condition: It is assumed that `validate_unlock_schedule_params` is called before this // If the denominator is zero, this function would fail in `create_from_rational` - fun create_schedule_fractions(unlock_numerators: &vector, unlock_denominator: u64) : vector { + fun create_schedule_fractions( + unlock_numerators: &vector, unlock_denominator: u64 + ): vector { - //Create unlock schedule + //Create unlock schedule let schedule = vector::empty(); vector::for_each_ref( unlock_numerators, |e| { - let fraction = - fixed_point64::create_from_rational( - (*e as u128), (unlock_denominator as u128) - ); + let fraction = fixed_point64::create_from_rational( + (*e as u128), + (unlock_denominator as u128), + ); vector::push_back(&mut schedule, fraction); - } + }, ); schedule } + // CAUTION: No pre-conditions checks are done, admin must use this with utmost care + // Does not change `cumulative_unlocked_fraction` to avoid certain inconsistency + public entry fun update_unlocking_schedule_unchecked( + multisig_admin: &signer, + pool_address: address, + unlock_numerators: vector, + unlock_denominator: u64, + unlock_start_time: u64, + unlock_duration: u64, + last_unlock_period: u64 + ) acquires DelegationPool { + assert!( + is_admin(signer::address_of(multisig_admin), pool_address), + error::permission_denied(ENOT_AUTHORIZED), + ); + let pool = borrow_global_mut(pool_address); + + validate_unlock_schedule_params( + &unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration, + ); + + //Create unlock schedule fractions + let schedule = create_schedule_fractions(&unlock_numerators, unlock_denominator); + + pool.principle_unlock_schedule = UnlockSchedule { + schedule: schedule, + start_timestamp_secs: unlock_start_time, + period_duration: unlock_duration, + last_unlock_period: last_unlock_period, + cumulative_unlocked_fraction: pool.principle_unlock_schedule.cumulative_unlocked_fraction + }; + event::emit( + UnlockScheduleUpdated { + pool_address, + unlock_numerators, + unlock_denominator, + unlock_start_time, + unlock_duration + }, + ); + + } + /// Pre-condition: `cumulative_unlocked_fraction` should be zero, which would indicate that even /// though there are principle stake holders, none of those have yet called `unlock` on the pool /// thus it is ``safe'' to change the schedule @@ -895,25 +948,25 @@ module supra_framework::pbo_delegation_pool { ) acquires DelegationPool { assert!( is_admin(signer::address_of(multisig_admin), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); let pool = borrow_global_mut(pool_address); assert!( fixed_point64::is_zero( pool.principle_unlock_schedule.cumulative_unlocked_fraction ), - error::invalid_state(EUNLOCKING_ALREADY_STARTED) + error::invalid_state(EUNLOCKING_ALREADY_STARTED), ); validate_unlock_schedule_params( &unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ); //Create unlock schedule fractions - let schedule = create_schedule_fractions(&unlock_numerators,unlock_denominator); + let schedule = create_schedule_fractions(&unlock_numerators, unlock_denominator); pool.principle_unlock_schedule = UnlockSchedule { schedule: schedule, @@ -929,7 +982,7 @@ module supra_framework::pbo_delegation_pool { unlock_denominator, unlock_start_time, unlock_duration - } + }, ); } @@ -949,23 +1002,23 @@ module supra_framework::pbo_delegation_pool { //Fraction numerators can not be empty assert!( numerator_length != 0, - error::invalid_argument(EEMPTY_UNLOCK_SCHEDULE) + error::invalid_argument(EEMPTY_UNLOCK_SCHEDULE), ); //First and last numerator can not be zero assert!( *vector::borrow(unlock_numerators, 0) != 0, - error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION) + error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION), ); assert!( *vector::borrow(unlock_numerators, numerator_length - 1) != 0, - error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION) + error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION), ); let sum = vector::foldr(*unlock_numerators, 0, |e, a| { e + a }); //Sum of numerators can not be greater than denominators assert!( sum <= unlock_denominator, - error::invalid_argument(ENUMERATORS_GRATER_THAN_DENOMINATOR) + error::invalid_argument(ENUMERATORS_GRATER_THAN_DENOMINATOR), ); } @@ -994,53 +1047,53 @@ module supra_framework::pbo_delegation_pool { let ms_admin = option::get_with_default
(&multisig_admin, @0x0); assert!( ms_admin != @0x0, - error::invalid_argument(EADMIN_ADDRESS_CANNOT_BE_ZERO) + error::invalid_argument(EADMIN_ADDRESS_CANNOT_BE_ZERO), ); assert!( multisig_account::num_signatures_required(ms_admin) >= 2, - EADMIN_NOT_MULTISIG + EADMIN_NOT_MULTISIG, ); }; // fail if the length of delegator_address and principle_stake is not the same assert!( vector::length(&delegator_address) == vector::length(&principle_stake), - error::invalid_argument(EVECTOR_LENGTH_NOT_SAME) + error::invalid_argument(EVECTOR_LENGTH_NOT_SAME), ); //Delegation pool must be enabled assert!( features::delegation_pools_enabled(), - error::invalid_state(EDELEGATION_POOLS_DISABLED) + error::invalid_state(EDELEGATION_POOLS_DISABLED), ); - validate_unlock_schedule_params( &unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ); let owner_address = signer::address_of(owner); assert!( !owner_cap_exists(owner_address), - error::already_exists(EOWNER_CAP_ALREADY_EXISTS) + error::already_exists(EOWNER_CAP_ALREADY_EXISTS), ); assert!( operator_commission_percentage <= MAX_FEE, - error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE) + error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE), ); let sum = vector::fold(principle_stake, 0, |a, e| { a + e }); // fail if the value of coin and the sum of principle_stake is not the same assert!( coin::value(&coin) == sum, - error::invalid_state(ECOIN_VALUE_NOT_SAME_AS_PRINCIPAL_STAKE) + error::invalid_state(ECOIN_VALUE_NOT_SAME_AS_PRINCIPAL_STAKE), ); // generate a seed to be used to create the resource account hosting the delegation pool let seed = create_resource_account_seed(delegation_pool_creation_seed); - let (stake_pool_signer, stake_pool_signer_cap) = - account::create_resource_account(owner, seed); + let (stake_pool_signer, stake_pool_signer_cap) = account::create_resource_account( + owner, seed + ); coin::register(&stake_pool_signer); // stake_pool_signer will be owner of the stake pool and have its `stake::OwnerCapability` @@ -1049,7 +1102,7 @@ module supra_framework::pbo_delegation_pool { &stake_pool_signer, 0, owner_address, - owner_address + owner_address, ); coin::deposit(pool_address, coin); @@ -1057,7 +1110,7 @@ module supra_framework::pbo_delegation_pool { table::add( &mut inactive_shares, olc_with_index(0), - pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR) + pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR), ); let delegator_address_copy = copy delegator_address; @@ -1072,7 +1125,7 @@ module supra_framework::pbo_delegation_pool { }; //Create unlock schedule - let schedule = create_schedule_fractions(&unlock_numerators,unlock_denominator); + let schedule = create_schedule_fractions(&unlock_numerators, unlock_denominator); move_to( &stake_pool_signer, @@ -1109,7 +1162,7 @@ module supra_framework::pbo_delegation_pool { ), distribute_commission_events: account::new_event_handle< DistributeCommissionEvent>(&stake_pool_signer) - } + }, ); // save delegation pool ownership and resource account address (inner stake pool address) on `owner` @@ -1124,15 +1177,13 @@ module supra_framework::pbo_delegation_pool { let (active_stake, _, _, _) = stake::get_stake(pool_address); // fail if coin in StakePool.active does not match with the balance in active_shares pool. assert!( - active_stake - == pool_u64::total_coins( - &borrow_global(pool_address).active_shares - ), - error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL) + active_stake == pool_u64::total_coins( + &borrow_global(pool_address).active_shares, + ), + error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL), ); // All delegation pool enable partial governace voting by default once the feature flag is enabled. - if (features::partial_governance_voting_enabled() - && features::delegation_pool_partial_governance_voting_enabled()) { + if (features::partial_governance_voting_enabled() && features::delegation_pool_partial_governance_voting_enabled()) { enable_partial_governance_voting(pool_address); } } @@ -1146,11 +1197,12 @@ module supra_framework::pbo_delegation_pool { { assert!( is_admin(signer::address_of(funder), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); }; - let principle_stake_table = - &mut (borrow_global_mut(pool_address).principle_stake); + let principle_stake_table = &mut ( + borrow_global_mut(pool_address).principle_stake + ); vector::zip_reverse( delegators, @@ -1161,8 +1213,9 @@ module supra_framework::pbo_delegation_pool { // Compute the actual stake that would be added, `principle_stake` has to be // populated in the table accordingly if (table::contains(principle_stake_table, delegator)) { - let stake_amount = - table::borrow_mut(principle_stake_table, delegator); + let stake_amount = table::borrow_mut( + principle_stake_table, delegator + ); *stake_amount = *stake_amount + stake; } else { table::add(principle_stake_table, delegator, stake); @@ -1174,7 +1227,7 @@ module supra_framework::pbo_delegation_pool { UnlockScheduleApplied { pool_address, delegator, amount: stake } ); } - } + }, ); fund_delegators_with_stake(funder, pool_address, delegators, stakes); @@ -1192,7 +1245,7 @@ module supra_framework::pbo_delegation_pool { stakes, |delegator, stake| { fund_delegator_stake(funder, pool_address, delegator, stake); - } + }, ); } @@ -1216,9 +1269,7 @@ module supra_framework::pbo_delegation_pool { public fun beneficiary_for_operator(operator: address): address acquires BeneficiaryForOperator { if (exists(operator)) { return borrow_global(operator).beneficiary_for_operator - } else { - operator - } + } else { operator } } /// Enable partial governance voting on a stake pool. The voter of this stake pool will be managed by this module. @@ -1228,11 +1279,11 @@ module supra_framework::pbo_delegation_pool { ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( features::partial_governance_voting_enabled(), - error::invalid_state(EDISABLED_FUNCTION) + error::invalid_state(EDISABLED_FUNCTION), ); assert!( features::delegation_pool_partial_governance_voting_enabled(), - error::invalid_state(EDISABLED_FUNCTION) + error::invalid_state(EDISABLED_FUNCTION), ); assert_delegation_pool_exists(pool_address); // synchronize delegation and stake pools before any user operation. @@ -1259,7 +1310,7 @@ module supra_framework::pbo_delegation_pool { ), delegate_voting_power_events: account::new_event_handle< DelegateVotingPowerEvent>(&stake_pool_signer) - } + }, ); } @@ -1270,7 +1321,7 @@ module supra_framework::pbo_delegation_pool { fun assert_delegation_pool_exists(pool_address: address) { assert!( delegation_pool_exists(pool_address), - error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST) + error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST), ); } @@ -1280,18 +1331,19 @@ module supra_framework::pbo_delegation_pool { let balance = pool_u64::balance(&pool.active_shares, delegator_address); assert!( balance >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW) + error::invalid_argument(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW), ); } fun assert_min_pending_inactive_balance( pool: &DelegationPool, delegator_address: address ) { - let balance = - pool_u64::balance(pending_inactive_shares_pool(pool), delegator_address); + let balance = pool_u64::balance( + pending_inactive_shares_pool(pool), delegator_address + ); assert!( balance >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EDELEGATOR_PENDING_INACTIVE_BALANCE_TOO_LOW) + error::invalid_argument(EDELEGATOR_PENDING_INACTIVE_BALANCE_TOO_LOW), ); } @@ -1299,7 +1351,7 @@ module supra_framework::pbo_delegation_pool { assert_delegation_pool_exists(pool_address); assert!( partial_governance_voting_enabled(pool_address), - error::invalid_state(EPARTIAL_GOVERNANCE_VOTING_NOT_ENABLED) + error::invalid_state(EPARTIAL_GOVERNANCE_VOTING_NOT_ENABLED), ); } @@ -1307,11 +1359,10 @@ module supra_framework::pbo_delegation_pool { src_shares_pool: &pool_u64::Pool, shareholder: address, amount: u64 ): u64 { // find how many coins would be redeemed if supplying `amount` - let redeemed_coins = - pool_u64::shares_to_amount( - src_shares_pool, - amount_to_shares_to_redeem(src_shares_pool, shareholder, amount) - ); + let redeemed_coins = pool_u64::shares_to_amount( + src_shares_pool, + amount_to_shares_to_redeem(src_shares_pool, shareholder, amount), + ); // if balance drops under threshold then redeem it entirely let src_balance = pool_u64::balance(src_shares_pool, shareholder); if (src_balance - redeemed_coins < MIN_COINS_ON_SHARES_POOL) { @@ -1327,11 +1378,10 @@ module supra_framework::pbo_delegation_pool { amount: u64 ): u64 { // find how many coins would be redeemed from source if supplying `amount` - let redeemed_coins = - pool_u64::shares_to_amount( - src_shares_pool, - amount_to_shares_to_redeem(src_shares_pool, shareholder, amount) - ); + let redeemed_coins = pool_u64::shares_to_amount( + src_shares_pool, + amount_to_shares_to_redeem(src_shares_pool, shareholder, amount), + ); // if balance on destination would be less than threshold then redeem difference to threshold let dst_balance = pool_u64::balance(dst_shares_pool, shareholder); if (dst_balance + redeemed_coins < MIN_COINS_ON_SHARES_POOL) { @@ -1399,9 +1449,7 @@ module supra_framework::pbo_delegation_pool { /// Update VoteDelegation of a delegator to up-to-date then borrow_mut it. fun update_and_borrow_mut_delegator_vote_delegation( - pool: &DelegationPool, - governance_records: &mut GovernanceRecords, - delegator: address + pool: &DelegationPool, governance_records: &mut GovernanceRecords, delegator: address ): &mut VoteDelegation { let pool_address = get_pool_address(pool); let locked_until_secs = stake::get_lockup_secs(pool_address); @@ -1417,14 +1465,14 @@ module supra_framework::pbo_delegation_pool { voter: delegator, last_locked_until_secs: locked_until_secs, pending_voter: delegator - } + }, ) }; let vote_delegation = smart_table::borrow_mut(vote_delegation_table, delegator); // A lockup period has passed since last time `vote_delegation` was updated. Pending voter takes effect. - if (vote_delegation.last_locked_until_secs < locked_until_secs - && vote_delegation.voter != vote_delegation.pending_voter) { + if (vote_delegation.last_locked_until_secs < locked_until_secs && vote_delegation.voter != vote_delegation + .pending_voter) { vote_delegation.voter = vote_delegation.pending_voter; }; vote_delegation @@ -1451,7 +1499,7 @@ module supra_framework::pbo_delegation_pool { pending_inactive_shares: inactive_shares, active_shares_next_lockup: active_shares, last_locked_until_secs: locked_until_secs - } + }, ) }; @@ -1474,28 +1522,23 @@ module supra_framework::pbo_delegation_pool { fun calculate_total_voting_power( delegation_pool: &DelegationPool, latest_delegated_votes: &DelegatedVotes ): u64 { - let active_amount = - pool_u64::shares_to_amount( - &delegation_pool.active_shares, latest_delegated_votes.active_shares - ); - let pending_inactive_amount = - pool_u64::shares_to_amount( - pending_inactive_shares_pool(delegation_pool), - latest_delegated_votes.pending_inactive_shares - ); + let active_amount = pool_u64::shares_to_amount( + &delegation_pool.active_shares, latest_delegated_votes.active_shares + ); + let pending_inactive_amount = pool_u64::shares_to_amount( + pending_inactive_shares_pool(delegation_pool), + latest_delegated_votes.pending_inactive_shares, + ); active_amount + pending_inactive_amount } /// Update VoteDelegation of a delegator to up-to-date then return the latest voter. fun calculate_and_update_delegator_voter_internal( - pool: &DelegationPool, - governance_records: &mut GovernanceRecords, - delegator: address + pool: &DelegationPool, governance_records: &mut GovernanceRecords, delegator: address ): address { - let vote_delegation = - update_and_borrow_mut_delegator_vote_delegation( - pool, governance_records, delegator - ); + let vote_delegation = update_and_borrow_mut_delegator_vote_delegation( + pool, governance_records, delegator + ); vote_delegation.voter } @@ -1503,22 +1546,21 @@ module supra_framework::pbo_delegation_pool { fun calculate_and_update_delegated_votes( pool: &DelegationPool, governance_records: &mut GovernanceRecords, voter: address ): u64 { - let delegated_votes = - update_and_borrow_mut_delegated_votes(pool, governance_records, voter); + let delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, voter + ); calculate_total_voting_power(pool, delegated_votes) } /// Allows an owner to change the operator of the underlying stake pool. - public entry fun set_operator( - owner: &signer, new_operator: address - ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + public entry fun set_operator(owner: &signer, new_operator: address) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { let pool_address = get_owned_pool_address(signer::address_of(owner)); // synchronize delegation and stake pools before any user operation // ensure the old operator is paid its uncommitted commission rewards synchronize_delegation_pool(pool_address); stake::set_operator( &retrieve_stake_pool_owner(borrow_global(pool_address)), - new_operator + new_operator, ); } @@ -1531,7 +1573,7 @@ module supra_framework::pbo_delegation_pool { ) acquires BeneficiaryForOperator { assert!( features::operator_beneficiary_change_enabled(), - std::error::invalid_state(EOPERATOR_BENEFICIARY_CHANGE_NOT_SUPPORTED) + std::error::invalid_state(EOPERATOR_BENEFICIARY_CHANGE_NOT_SUPPORTED), ); // The beneficiay address of an operator is stored under the operator's address. // So, the operator does not need to be validated with respect to a staking pool. @@ -1539,11 +1581,11 @@ module supra_framework::pbo_delegation_pool { let old_beneficiary = beneficiary_for_operator(operator_addr); if (exists(operator_addr)) { borrow_global_mut(operator_addr).beneficiary_for_operator = - new_beneficiary; + new_beneficiary; } else { move_to( operator, - BeneficiaryForOperator { beneficiary_for_operator: new_beneficiary } + BeneficiaryForOperator { beneficiary_for_operator: new_beneficiary }, ); }; @@ -1552,7 +1594,7 @@ module supra_framework::pbo_delegation_pool { operator: operator_addr, old_beneficiary, new_beneficiary - } + }, ); } @@ -1562,23 +1604,21 @@ module supra_framework::pbo_delegation_pool { ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( features::commission_change_delegation_pool_enabled(), - error::invalid_state(ECOMMISSION_RATE_CHANGE_NOT_SUPPORTED) + error::invalid_state(ECOMMISSION_RATE_CHANGE_NOT_SUPPORTED), ); assert!( new_commission_percentage <= MAX_FEE, - error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE) + error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE), ); let owner_address = signer::address_of(owner); let pool_address = get_owned_pool_address(owner_address); assert!( - operator_commission_percentage(pool_address) + MAX_COMMISSION_INCREASE - >= new_commission_percentage, - error::invalid_argument(ETOO_LARGE_COMMISSION_INCREASE) + operator_commission_percentage(pool_address) + MAX_COMMISSION_INCREASE >= new_commission_percentage, + error::invalid_argument(ETOO_LARGE_COMMISSION_INCREASE), ); assert!( - stake::get_remaining_lockup_secs(pool_address) - >= min_remaining_secs_for_commission_change(), - error::invalid_state(ETOO_LATE_COMMISSION_CHANGE) + stake::get_remaining_lockup_secs(pool_address) >= min_remaining_secs_for_commission_change(), + error::invalid_state(ETOO_LATE_COMMISSION_CHANGE), ); // synchronize delegation and stake pools before any user operation. this ensures: @@ -1587,24 +1627,24 @@ module supra_framework::pbo_delegation_pool { synchronize_delegation_pool(pool_address); if (exists(pool_address)) { - let commission_percentage = - borrow_global_mut(pool_address); + let commission_percentage = borrow_global_mut( + pool_address + ); commission_percentage.commission_percentage_next_lockup_cycle = new_commission_percentage; commission_percentage.effective_after_secs = stake::get_lockup_secs( pool_address ); } else { let delegation_pool = borrow_global(pool_address); - let pool_signer = - account::create_signer_with_capability( - &delegation_pool.stake_pool_signer_cap - ); + let pool_signer = account::create_signer_with_capability( + &delegation_pool.stake_pool_signer_cap + ); move_to( &pool_signer, NextCommissionPercentage { commission_percentage_next_lockup_cycle: new_commission_percentage, effective_after_secs: stake::get_lockup_secs(pool_address) - } + }, ); }; @@ -1613,7 +1653,7 @@ module supra_framework::pbo_delegation_pool { pool_address, owner: owner_address, commission_percentage_next_lockup_cycle: new_commission_percentage - } + }, ); } @@ -1624,14 +1664,14 @@ module supra_framework::pbo_delegation_pool { // No one can change delegated_voter once the partial governance voting feature is enabled. assert!( !features::delegation_pool_partial_governance_voting_enabled(), - error::invalid_state(EDEPRECATED_FUNCTION) + error::invalid_state(EDEPRECATED_FUNCTION), ); let pool_address = get_owned_pool_address(signer::address_of(owner)); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); stake::set_delegated_voter( &retrieve_stake_pool_owner(borrow_global(pool_address)), - new_voter + new_voter, ); } @@ -1648,30 +1688,28 @@ module supra_framework::pbo_delegation_pool { let delegator_address = signer::address_of(delegator); let delegation_pool = borrow_global(pool_address); let governance_records = borrow_global_mut(pool_address); - let delegator_vote_delegation = - update_and_borrow_mut_delegator_vote_delegation( - delegation_pool, governance_records, delegator_address - ); + let delegator_vote_delegation = update_and_borrow_mut_delegator_vote_delegation( + delegation_pool, governance_records, delegator_address + ); let pending_voter: address = delegator_vote_delegation.pending_voter; // No need to update if the voter doesn't really change. if (pending_voter != new_voter) { delegator_vote_delegation.pending_voter = new_voter; - let active_shares = - get_delegator_active_shares(delegation_pool, delegator_address); + let active_shares = get_delegator_active_shares( + delegation_pool, delegator_address + ); // of -= // of += - let pending_delegated_votes = - update_and_borrow_mut_delegated_votes( - delegation_pool, governance_records, pending_voter - ); + let pending_delegated_votes = update_and_borrow_mut_delegated_votes( + delegation_pool, governance_records, pending_voter + ); pending_delegated_votes.active_shares_next_lockup = pending_delegated_votes.active_shares_next_lockup - active_shares; - let new_delegated_votes = - update_and_borrow_mut_delegated_votes( - delegation_pool, governance_records, new_voter - ); + let new_delegated_votes = update_and_borrow_mut_delegated_votes( + delegation_pool, governance_records, new_voter + ); new_delegated_votes.active_shares_next_lockup = new_delegated_votes.active_shares_next_lockup + active_shares; }; @@ -1682,7 +1720,7 @@ module supra_framework::pbo_delegation_pool { pool_address, delegator: delegator_address, voter: new_voter - } + }, ); } @@ -1712,7 +1750,7 @@ module supra_framework::pbo_delegation_pool { // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` assert!( amount >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT), ); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); @@ -1743,7 +1781,7 @@ module supra_framework::pbo_delegation_pool { delegator_address, amount_added: amount, add_stake_fee - } + }, ); } @@ -1756,7 +1794,7 @@ module supra_framework::pbo_delegation_pool { delegator, pool_address, signer::address_of(delegator), - amount + amount, ) } @@ -1790,7 +1828,7 @@ module supra_framework::pbo_delegation_pool { // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` assert!( amount >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT), ); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); @@ -1801,7 +1839,7 @@ module supra_framework::pbo_delegation_pool { pending_inactive_shares_pool(pool), &pool.active_shares, delegator, - amount + amount, ); let observed_lockup_cycle = pool.observed_lockup_cycle; amount = redeem_inactive_shares(pool, delegator, amount, observed_lockup_cycle); @@ -1817,7 +1855,7 @@ module supra_framework::pbo_delegation_pool { pool_address, delegator_address: delegator, amount_reactivated: amount - } + }, ); } @@ -1838,7 +1876,7 @@ module supra_framework::pbo_delegation_pool { { assert!( is_admin(signer::address_of(multisig_admin), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); }; assert!(amount != 0, error::invalid_argument(EWITHDRAW_ZERO_STAKE)); @@ -1846,35 +1884,36 @@ module supra_framework::pbo_delegation_pool { borrow_global_mut(pool_address), delegator_address, amount, - signer::address_of(multisig_admin) + signer::address_of(multisig_admin), ); } - public entry fun admin_increase_last_unlock_period( - multisig_admin: &signer, - pool_address: address, - additional_periods: u64 + multisig_admin: &signer, pool_address: address, additional_periods: u64 ) acquires DelegationPool { // Ensure that the caller is the admin of the delegation pool. { assert!( is_admin(signer::address_of(multisig_admin), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); }; - + let delegation_pool = borrow_global_mut(pool_address); let last_unlocked_period = delegation_pool.principle_unlock_schedule.last_unlock_period; - let schedule_length = vector::length(&delegation_pool.principle_unlock_schedule.schedule); + let schedule_length = vector::length( + &delegation_pool.principle_unlock_schedule.schedule + ); // Current last_unlock_period must be greater or equal to schedule_length -1, this is because // last_unlock_period is used as index into schedule vector. If we are not already at the last index or beyond - // increasing this would have undesirable effect. For example if schedule is [20%, 30%, 10%] and + // increasing this would have undesirable effect. For example if schedule is [20%, 30%, 10%] and // last_unlock_period = 1, increasing it by two would directly go to 10% unlock skipping 30% unlock part - assert!(schedule_length -1 <= last_unlocked_period, EINVALID_STATE_FOR_OPERATION); - delegation_pool.principle_unlock_schedule.last_unlock_period = delegation_pool.principle_unlock_schedule.last_unlock_period + additional_periods; - + assert!(schedule_length - 1 <= last_unlocked_period, EINVALID_STATE_FOR_OPERATION); + delegation_pool.principle_unlock_schedule.last_unlock_period = delegation_pool.principle_unlock_schedule + .last_unlock_period + additional_periods; + } + /// Updates the `principle_stake` of each `delegator` in `delegators` according to the amount specified /// at the corresponding index of `new_principle_stakes`. Also ensures that the `delegator`'s `active` stake /// is as close to the specified amount as possible. The locked amount is subject to the vesting schedule @@ -1894,7 +1933,7 @@ module supra_framework::pbo_delegation_pool { { assert!( is_admin(signer::address_of(multisig_admin), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); }; @@ -1907,8 +1946,9 @@ module supra_framework::pbo_delegation_pool { delegators, new_principle_stakes, |delegator, principle_stake| { - let (active, inactive, pending_inactive) = - get_stake(pool_address, delegator); + let (active, inactive, pending_inactive) = get_stake( + pool_address, delegator + ); // Ensure that all stake to be locked is made `active`. if (active < principle_stake) { @@ -1935,8 +1975,7 @@ module supra_framework::pbo_delegation_pool { if (active_and_pending_inactive < principle_stake) { // Need to reactivate some of the `inactive` stake. - let amount_to_withdraw = - principle_stake - active_and_pending_inactive; + let amount_to_withdraw = principle_stake - active_and_pending_inactive; // Ensure that we do not try to withdraw more stake than the `inactive` stake. if (amount_to_withdraw > inactive) { @@ -1949,14 +1988,14 @@ module supra_framework::pbo_delegation_pool { multisig_admin, pool_address, delegator, - amount_to_withdraw + amount_to_withdraw, ); // Then allocate it to the delegator again. fund_delegator_stake( multisig_admin, pool_address, delegator, - amount_to_withdraw + amount_to_withdraw, ); } } @@ -1964,17 +2003,18 @@ module supra_framework::pbo_delegation_pool { // else: The amount to lock can be covered by the currently `active` stake. // Update the delegator's principle stake and record the details of the lockup event. - let principle_stake_table = - &mut (borrow_global_mut(pool_address).principle_stake); + let principle_stake_table = &mut ( + borrow_global_mut(pool_address).principle_stake + ); table::upsert(principle_stake_table, delegator, principle_stake); event::emit( UnlockScheduleApplied { pool_address, delegator, amount: principle_stake - } + }, ); - } + }, ); } @@ -1998,24 +2038,24 @@ module supra_framework::pbo_delegation_pool { let admin_addr = signer::address_of(multisig_admin); assert!( is_admin(admin_addr, pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); //Ensure replacement address is different assert!( old_delegator != new_delegator, - error::invalid_argument(ENEW_IS_SAME_AS_OLD_DELEGATOR) + error::invalid_argument(ENEW_IS_SAME_AS_OLD_DELEGATOR), ); //Ensure it is a valid `pool_addres` assert!( exists(pool_address), - error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST) + error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST), ); let pool: &mut DelegationPool = borrow_global_mut(pool_address); //Ensure `old_delegator` is part of original principle stakers before commencing the replacement assert!( table::contains(&pool.principle_stake, old_delegator), - error::unavailable(EDELEGATOR_DOES_NOT_EXIST) + error::unavailable(EDELEGATOR_DOES_NOT_EXIST), ); //replace in `active_shares` pool @@ -2026,22 +2066,24 @@ module supra_framework::pbo_delegation_pool { active_pool, old_delegator, new_delegator, - active_shares + active_shares, ); }; //replace in `inactive_shares` pool - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, old_delegator); + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, old_delegator + ); if (withdrawal_exists) { - let inactive_pool = - table::borrow_mut(&mut pool.inactive_shares, withdrawal_olc); + let inactive_pool = table::borrow_mut( + &mut pool.inactive_shares, withdrawal_olc + ); let inactive_shares = pool_u64::shares(inactive_pool, old_delegator); pool_u64::transfer_shares( inactive_pool, old_delegator, new_delegator, - inactive_shares + inactive_shares, ); //replace in `pending_withdrawals` @@ -2075,12 +2117,12 @@ module supra_framework::pbo_delegation_pool { VotingRecordKey { voter: new_delegator, proposal_id: proposal_id - } + }, ); vector::push_back(&mut old_keys, *key); }; - } + }, ); vector::zip_ref( @@ -2088,7 +2130,7 @@ module supra_framework::pbo_delegation_pool { &new_keys, |old, new| { replace_in_smart_tables(&mut grecords.votes, *old, *new); - } + }, ); } }; @@ -2132,31 +2174,31 @@ module supra_framework::pbo_delegation_pool { ): u64 acquires DelegationPool { assert!( exists(pool_addr), - error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST) + error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST), ); let pool = borrow_global(pool_addr); - let delegator_active_balance = - pool_u64::balance(&pool.active_shares, delegator_addr); - let unlockable_fraction = - pool.principle_unlock_schedule.cumulative_unlocked_fraction; - let delegator_principle_stake = - *table::borrow(&pool.principle_stake, delegator_addr); + let delegator_active_balance = pool_u64::balance( + &pool.active_shares, delegator_addr + ); + let unlockable_fraction = pool.principle_unlock_schedule.cumulative_unlocked_fraction; + let delegator_principle_stake = *table::borrow( + &pool.principle_stake, delegator_addr + ); //To avoid problem even if fraction is slightly above 1 - let unlockable_principle_stake = - ( - math128::min( - fixed_point64::multiply_u128( - (delegator_principle_stake as u128), unlockable_fraction - ), - (delegator_principle_stake as u128) - ) as u64 - ); + let unlockable_principle_stake = ( + math128::min( + fixed_point64::multiply_u128( + (delegator_principle_stake as u128), unlockable_fraction + ), + (delegator_principle_stake as u128), + ) as u64 + ); let locked_amount = delegator_principle_stake - unlockable_principle_stake; assert!( delegator_active_balance >= locked_amount, - error::invalid_state(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW) + error::invalid_state(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW), ); delegator_active_balance - locked_amount @@ -2168,58 +2210,62 @@ module supra_framework::pbo_delegation_pool { delegator_addr: address, pool_address: address, amount: u64 ): bool acquires DelegationPool { - let principle_stake_table = - &borrow_global(pool_address).principle_stake; + let principle_stake_table = &borrow_global(pool_address).principle_stake; if (!table::contains(principle_stake_table, delegator_addr)) { return false }; - let unlock_schedule = - &mut borrow_global_mut(pool_address).principle_unlock_schedule; + let unlock_schedule = &mut borrow_global_mut(pool_address).principle_unlock_schedule; let one = fixed_point64::create_from_rational(1, 1); if (fixed_point64::greater_or_equal( - unlock_schedule.cumulative_unlocked_fraction, one - )) { + unlock_schedule.cumulative_unlocked_fraction, one + )) { return true }; if (unlock_schedule.start_timestamp_secs > timestamp::now_seconds()) { - let unlockable_amount = - cached_unlockable_balance(delegator_addr, pool_address); + let unlockable_amount = cached_unlockable_balance( + delegator_addr, pool_address + ); return amount <= unlockable_amount }; //subtraction safety due to check above - let unlock_periods_passed = - (timestamp::now_seconds() - unlock_schedule.start_timestamp_secs) - / unlock_schedule.period_duration; + let unlock_periods_passed = ( + timestamp::now_seconds() - unlock_schedule.start_timestamp_secs + ) / unlock_schedule.period_duration; let last_unlocked_period = unlock_schedule.last_unlock_period; let schedule_length = vector::length(&unlock_schedule.schedule); let cfraction = unlock_schedule.cumulative_unlocked_fraction; while (last_unlocked_period < unlock_periods_passed && fixed_point64::less(cfraction, one) && last_unlocked_period < schedule_length) { - let next_fraction = - *vector::borrow(&unlock_schedule.schedule, last_unlocked_period); + let next_fraction = *vector::borrow( + &unlock_schedule.schedule, last_unlocked_period + ); cfraction = fixed_point64::add(cfraction, next_fraction); last_unlocked_period = last_unlocked_period + 1; }; - if (last_unlocked_period < unlock_periods_passed - && fixed_point64::less(cfraction, one)) { - let final_fraction = - *vector::borrow(&unlock_schedule.schedule, schedule_length - 1); + if (last_unlocked_period < unlock_periods_passed && fixed_point64::less( + cfraction, one + )) { + let final_fraction = *vector::borrow( + &unlock_schedule.schedule, schedule_length - 1 + ); // Acclerate calculation to current period and don't update last_unlocked_period since it is not used anymore cfraction = fixed_point64::add( cfraction, fixed_point64::multiply_u128_return_fixpoint64( (unlock_periods_passed - last_unlocked_period as u128), - final_fraction - ) + final_fraction, + ), ); cfraction = fixed_point64::min(cfraction, one); }; unlock_schedule.cumulative_unlocked_fraction = cfraction; - unlock_schedule.last_unlock_period = math64::max(unlock_periods_passed, last_unlocked_period); + unlock_schedule.last_unlock_period = math64::max( + unlock_periods_passed, last_unlocked_period + ); let unlockable_amount = cached_unlockable_balance(delegator_addr, pool_address); amount <= unlockable_amount } @@ -2234,13 +2280,13 @@ module supra_framework::pbo_delegation_pool { // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` assert!( amount >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT), ); // fail unlock of more stake than `active` on the stake pool let (active, _, _, _) = stake::get_stake(pool_address); assert!( amount <= active, - error::invalid_argument(ENOT_ENOUGH_ACTIVE_STAKE_TO_UNLOCK) + error::invalid_argument(ENOT_ENOUGH_ACTIVE_STAKE_TO_UNLOCK), ); // synchronize delegation and stake pools before any user operation @@ -2251,7 +2297,7 @@ module supra_framework::pbo_delegation_pool { if (is_principle_stakeholder(delegator_address, pool_address)) { assert!( can_principle_unlock(delegator_address, pool_address, amount), - error::invalid_argument(EAMOUNT_REQUESTED_NOT_UNLOCKABLE) + error::invalid_argument(EAMOUNT_REQUESTED_NOT_UNLOCKABLE), ); }; let pool = borrow_global_mut(pool_address); @@ -2259,7 +2305,7 @@ module supra_framework::pbo_delegation_pool { &pool.active_shares, pending_inactive_shares_pool(pool), delegator_address, - amount + amount, ); amount = redeem_active_shares(pool, delegator_address, amount); stake::unlock(&retrieve_stake_pool_owner(pool), amount); @@ -2269,12 +2315,12 @@ module supra_framework::pbo_delegation_pool { event::emit_event( &mut pool.unlock_stake_events, - UnlockStakeEvent { pool_address, delegator_address, amount_unlocked: amount } + UnlockStakeEvent { pool_address, delegator_address, amount_unlocked: amount }, ); let (active_stake, _, pending_active, _) = stake::get_stake(pool_address); assert!( active_stake + pending_active == pool_u64::total_coins(&pool.active_shares), - error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL) + error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL), ); } @@ -2298,7 +2344,7 @@ module supra_framework::pbo_delegation_pool { borrow_global_mut(pool_address), delegator_address, amount, - delegator_address + delegator_address, ); } @@ -2315,29 +2361,31 @@ module supra_framework::pbo_delegation_pool { if (amount == 0) { return }; let pool_address = get_pool_address(pool); - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, delegator_address); + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, delegator_address + ); // exit if no withdrawal or (it is pending and cannot withdraw pending_inactive stake from stake pool) if (!( - withdrawal_exists + withdrawal_exists && ( - withdrawal_olc.index < pool.observed_lockup_cycle.index - || can_withdraw_pending_inactive(pool_address) + withdrawal_olc.index < pool.observed_lockup_cycle.index || can_withdraw_pending_inactive( + pool_address + ) ) - )) { return }; + )) { return }; if (withdrawal_olc.index == pool.observed_lockup_cycle.index) { amount = coins_to_redeem_to_ensure_min_stake( pending_inactive_shares_pool(pool), delegator_address, - amount + amount, ) }; amount = redeem_inactive_shares( pool, delegator_address, amount, - withdrawal_olc + withdrawal_olc, ); let stake_pool_owner = &retrieve_stake_pool_owner(pool); @@ -2369,7 +2417,7 @@ module supra_framework::pbo_delegation_pool { event::emit_event( &mut pool.withdraw_stake_events, - WithdrawStakeEvent { pool_address, delegator_address, amount_withdrawn: amount } + WithdrawStakeEvent { pool_address, delegator_address, amount_withdrawn: amount }, ); } @@ -2381,9 +2429,7 @@ module supra_framework::pbo_delegation_pool { ): (bool, ObservedLockupCycle) { if (table::contains(&pool.pending_withdrawals, delegator_address)) { (true, *table::borrow(&pool.pending_withdrawals, delegator_address)) - } else { - (false, olc_with_index(0)) - } + } else { (false, olc_with_index(0)) } } /// Return a mutable reference to the shares pool of `pending_inactive` stake on the @@ -2404,15 +2450,15 @@ module supra_framework::pbo_delegation_pool { fun execute_pending_withdrawal( pool: &mut DelegationPool, delegator_address: address ) acquires GovernanceRecords { - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, delegator_address); - if (withdrawal_exists - && withdrawal_olc.index < pool.observed_lockup_cycle.index) { + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, delegator_address + ); + if (withdrawal_exists && withdrawal_olc.index < pool.observed_lockup_cycle.index) { withdraw_internal( pool, delegator_address, MAX_U64, - delegator_address + delegator_address, ); } } @@ -2447,10 +2493,9 @@ module supra_framework::pbo_delegation_pool { fun buy_in_pending_inactive_shares( pool: &mut DelegationPool, shareholder: address, coins_amount: u64 ): u128 acquires GovernanceRecords { - let new_shares = - pool_u64::amount_to_shares( - pending_inactive_shares_pool(pool), coins_amount - ); + let new_shares = pool_u64::amount_to_shares( + pending_inactive_shares_pool(pool), coins_amount + ); // never create a new pending withdrawal unless delegator owns some pending_inactive shares if (new_shares == 0) { return 0 @@ -2478,7 +2523,7 @@ module supra_framework::pbo_delegation_pool { *table::borrow_mut_with_default( &mut pool.pending_withdrawals, shareholder, observed_lockup_cycle ) == observed_lockup_cycle, - error::invalid_state(EPENDING_WITHDRAWAL_EXISTS) + error::invalid_state(EPENDING_WITHDRAWAL_EXISTS), ); new_shares @@ -2504,8 +2549,9 @@ module supra_framework::pbo_delegation_pool { fun redeem_active_shares( pool: &mut DelegationPool, shareholder: address, coins_amount: u64 ): u64 acquires GovernanceRecords { - let shares_to_redeem = - amount_to_shares_to_redeem(&pool.active_shares, shareholder, coins_amount); + let shares_to_redeem = amount_to_shares_to_redeem( + &pool.active_shares, shareholder, coins_amount + ); // silently exit if not a shareholder otherwise redeem would fail with `ESHAREHOLDER_NOT_FOUND` if (shares_to_redeem == 0) return 0; @@ -2516,7 +2562,7 @@ module supra_framework::pbo_delegation_pool { pool, pool_address, shares_to_redeem, - shareholder + shareholder, ); }; @@ -2535,32 +2581,32 @@ module supra_framework::pbo_delegation_pool { coins_amount: u64, lockup_cycle: ObservedLockupCycle ): u64 acquires GovernanceRecords { - let shares_to_redeem = - amount_to_shares_to_redeem( - table::borrow(&pool.inactive_shares, lockup_cycle), - shareholder, - coins_amount - ); + let shares_to_redeem = amount_to_shares_to_redeem( + table::borrow(&pool.inactive_shares, lockup_cycle), + shareholder, + coins_amount, + ); // silently exit if not a shareholder otherwise redeem would fail with `ESHAREHOLDER_NOT_FOUND` if (shares_to_redeem == 0) return 0; // Always update governance records before any change to the shares pool. let pool_address = get_pool_address(pool); // Only redeem shares from the pending_inactive pool at `lockup_cycle` == current OLC. - if (partial_governance_voting_enabled(pool_address) - && lockup_cycle.index == pool.observed_lockup_cycle.index) { + if (partial_governance_voting_enabled(pool_address) && lockup_cycle.index == pool.observed_lockup_cycle + .index) { update_governanace_records_for_redeem_pending_inactive_shares( pool, pool_address, shares_to_redeem, - shareholder + shareholder, ); }; let inactive_shares = table::borrow_mut(&mut pool.inactive_shares, lockup_cycle); // 1. reaching here means delegator owns inactive/pending_inactive shares at OLC `lockup_cycle` - let redeemed_coins = - pool_u64::redeem_shares(inactive_shares, shareholder, shares_to_redeem); + let redeemed_coins = pool_u64::redeem_shares( + inactive_shares, shareholder, shares_to_redeem + ); // if entirely reactivated pending_inactive stake or withdrawn inactive one, // re-enable unlocking for delegator by deleting this pending withdrawal @@ -2570,8 +2616,9 @@ module supra_framework::pbo_delegation_pool { table::remove(&mut pool.pending_withdrawals, shareholder); }; // destroy inactive shares pool of past OLC if all its stake has been withdrawn - if (lockup_cycle.index < pool.observed_lockup_cycle.index - && total_coins(inactive_shares) == 0) { + if (lockup_cycle.index < pool.observed_lockup_cycle.index && total_coins( + inactive_shares + ) == 0) { pool_u64::destroy_empty( table::remove(&mut pool.inactive_shares, lockup_cycle) ); @@ -2584,11 +2631,12 @@ module supra_framework::pbo_delegation_pool { /// capture the rewards earned in the meantime, resulted operator commission and /// whether the lockup expired on the stake pool. fun calculate_stake_pool_drift(pool: &DelegationPool): (bool, u64, u64, u64, u64) { - let (active, inactive, pending_active, pending_inactive) = - stake::get_stake(get_pool_address(pool)); + let (active, inactive, pending_active, pending_inactive) = stake::get_stake( + get_pool_address(pool) + ); assert!( inactive >= pool.total_coins_inactive, - error::invalid_state(ESLASHED_INACTIVE_STAKE_ON_PAST_OLC) + error::invalid_state(ESLASHED_INACTIVE_STAKE_ON_PAST_OLC), ); // determine whether a new lockup cycle has been ended on the stake pool and // inactivated SOME `pending_inactive` stake which should stop earning rewards now, @@ -2619,8 +2667,7 @@ module supra_framework::pbo_delegation_pool { ) } else { // handle any slashing applied to `active` stake - 0 - }; + 0 }; // operator `pending_inactive` rewards not persisted yet to the pending_inactive shares pool let pool_pending_inactive = total_coins(pending_inactive_shares_pool(pool)); let commission_pending_inactive = @@ -2628,12 +2675,11 @@ module supra_framework::pbo_delegation_pool { math64::mul_div( pending_inactive - pool_pending_inactive, pool.operator_commission_percentage, - MAX_FEE + MAX_FEE, ) } else { // handle any slashing applied to `pending_inactive` stake - 0 - }; + 0 }; ( lockup_cycle_ended, @@ -2646,9 +2692,7 @@ module supra_framework::pbo_delegation_pool { /// Synchronize delegation and stake pools: distribute yet-undetected rewards to the corresponding internal /// shares pools, assign commission to operator and eventually prepare delegation pool for a new lockup cycle. - public entry fun synchronize_delegation_pool( - pool_address: address - ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + public entry fun synchronize_delegation_pool(pool_address: address) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert_delegation_pool_exists(pool_address); let pool = borrow_global_mut(pool_address); let ( @@ -2674,25 +2718,24 @@ module supra_framework::pbo_delegation_pool { // update total coins accumulated by `active` + `pending_active` shares // redeemed `add_stake` fees are restored and distributed to the rest of the pool as rewards - pool_u64::update_total_coins(&mut pool.active_shares, active - - commission_active); + pool_u64::update_total_coins(&mut pool.active_shares, active - commission_active); // update total coins accumulated by `pending_inactive` shares at current observed lockup cycle pool_u64::update_total_coins( pending_inactive_shares_pool_mut(pool), - pending_inactive - commission_pending_inactive + pending_inactive - commission_pending_inactive, ); // reward operator its commission out of uncommitted active rewards (`add_stake` fees already excluded) buy_in_active_shares( pool, beneficiary_for_operator(stake::get_operator(pool_address)), - commission_active + commission_active, ); // reward operator its commission out of uncommitted pending_inactive rewards buy_in_pending_inactive_shares( pool, beneficiary_for_operator(stake::get_operator(pool_address)), - commission_pending_inactive + commission_pending_inactive, ); event::emit_event( @@ -2702,7 +2745,7 @@ module supra_framework::pbo_delegation_pool { operator: stake::get_operator(pool_address), commission_active, commission_pending_inactive - } + }, ); if (features::operator_beneficiary_change_enabled()) { @@ -2715,7 +2758,7 @@ module supra_framework::pbo_delegation_pool { ), commission_active, commission_pending_inactive - } + }, ) }; @@ -2731,7 +2774,7 @@ module supra_framework::pbo_delegation_pool { table::add( &mut pool.inactive_shares, pool.observed_lockup_cycle, - pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR) + pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR), ); }; @@ -2752,26 +2795,22 @@ module supra_framework::pbo_delegation_pool { // of += // of += let governance_records = borrow_global_mut(pool_address); - let vote_delegation = - update_and_borrow_mut_delegator_vote_delegation( - pool, governance_records, shareholder - ); + let vote_delegation = update_and_borrow_mut_delegator_vote_delegation( + pool, governance_records, shareholder + ); let current_voter = vote_delegation.voter; let pending_voter = vote_delegation.pending_voter; - let current_delegated_votes = - update_and_borrow_mut_delegated_votes( - pool, governance_records, current_voter - ); - current_delegated_votes.active_shares = current_delegated_votes.active_shares - + new_shares; + let current_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, current_voter + ); + current_delegated_votes.active_shares = current_delegated_votes.active_shares + new_shares; if (pending_voter == current_voter) { current_delegated_votes.active_shares_next_lockup = current_delegated_votes.active_shares_next_lockup + new_shares; } else { - let pending_delegated_votes = - update_and_borrow_mut_delegated_votes( - pool, governance_records, pending_voter - ); + let pending_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, pending_voter + ); pending_delegated_votes.active_shares_next_lockup = pending_delegated_votes.active_shares_next_lockup + new_shares; }; @@ -2787,14 +2826,12 @@ module supra_framework::pbo_delegation_pool { // of += // no impact on of let governance_records = borrow_global_mut(pool_address); - let current_voter = - calculate_and_update_delegator_voter_internal( - pool, governance_records, shareholder - ); - let current_delegated_votes = - update_and_borrow_mut_delegated_votes( - pool, governance_records, current_voter - ); + let current_voter = calculate_and_update_delegator_voter_internal( + pool, governance_records, shareholder + ); + let current_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, current_voter + ); current_delegated_votes.pending_inactive_shares = current_delegated_votes.pending_inactive_shares + new_shares; } @@ -2809,26 +2846,22 @@ module supra_framework::pbo_delegation_pool { // of -= // of -= let governance_records = borrow_global_mut(pool_address); - let vote_delegation = - update_and_borrow_mut_delegator_vote_delegation( - pool, governance_records, shareholder - ); + let vote_delegation = update_and_borrow_mut_delegator_vote_delegation( + pool, governance_records, shareholder + ); let current_voter = vote_delegation.voter; let pending_voter = vote_delegation.pending_voter; - let current_delegated_votes = - update_and_borrow_mut_delegated_votes( - pool, governance_records, current_voter - ); - current_delegated_votes.active_shares = current_delegated_votes.active_shares - - shares_to_redeem; + let current_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, current_voter + ); + current_delegated_votes.active_shares = current_delegated_votes.active_shares - shares_to_redeem; if (current_voter == pending_voter) { current_delegated_votes.active_shares_next_lockup = current_delegated_votes.active_shares_next_lockup - shares_to_redeem; } else { - let pending_delegated_votes = - update_and_borrow_mut_delegated_votes( - pool, governance_records, pending_voter - ); + let pending_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, pending_voter + ); pending_delegated_votes.active_shares_next_lockup = pending_delegated_votes.active_shares_next_lockup - shares_to_redeem; }; @@ -2844,14 +2877,12 @@ module supra_framework::pbo_delegation_pool { // of -= // no impact on of let governance_records = borrow_global_mut(pool_address); - let current_voter = - calculate_and_update_delegator_voter_internal( - pool, governance_records, shareholder - ); - let current_delegated_votes = - update_and_borrow_mut_delegated_votes( - pool, governance_records, current_voter - ); + let current_voter = calculate_and_update_delegator_voter_internal( + pool, governance_records, shareholder + ); + let current_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, current_voter + ); current_delegated_votes.pending_inactive_shares = current_delegated_votes.pending_inactive_shares - shares_to_redeem; } @@ -2918,7 +2949,7 @@ module supra_framework::pbo_delegation_pool { true, 1, 100, - 1000000 + 1000000, ); } @@ -2932,7 +2963,7 @@ module supra_framework::pbo_delegation_pool { true, 0, 100, - 1000000 + 1000000, ); } @@ -2956,7 +2987,7 @@ module supra_framework::pbo_delegation_pool { allow_validator_set_change, rewards_rate_numerator, rewards_rate_denominator, - voting_power_increase_limit + voting_power_increase_limit, ); reconfiguration::initialize_for_test(supra_framework); features::change_feature_flags_for_testing( @@ -2965,9 +2996,8 @@ module supra_framework::pbo_delegation_pool { DELEGATION_POOLS, MODULE_EVENT, OPERATOR_BENEFICIARY_CHANGE, - COMMISSION_CHANGE_DELEGATION_POOL - ], - vector[] + COMMISSION_CHANGE_DELEGATION_POOL], + vector[], ); } @@ -3003,7 +3033,7 @@ module supra_framework::pbo_delegation_pool { unlock_numerators, unlock_denominator, principle_lockup_time, - unlock_duration + unlock_duration, ); let pool_address = get_owned_pool_address(validator_address); @@ -3062,7 +3092,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ) } @@ -3087,7 +3117,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let pool_address = get_owned_pool_address(validator_address); @@ -3142,7 +3172,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let coin = stake::mint_coins(100 * ONE_SUPRA); initialize_delegation_pool( @@ -3156,7 +3186,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, 0, - 12 + 12, ); } @@ -3181,7 +3211,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); withdraw(validator, get_owned_pool_address(signer::address_of(validator)), 0); } @@ -3207,7 +3237,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); assert_owner_cap_exists(validator_address); @@ -3225,14 +3255,7 @@ module supra_framework::pbo_delegation_pool { stake::assert_stake_pool(pool_address, 0, 0, 0, 0); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_add_stake_fee( supra_framework: &signer, validator: &signer, @@ -3247,7 +3270,7 @@ module supra_framework::pbo_delegation_pool { true, 1, 100, - 1000000 + 1000000, ); let delegator_address = vector[@0x010, @0x020]; let principle_stake = vector[0, 0]; @@ -3268,7 +3291,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let pool_address = get_owned_pool_address(validator_address); @@ -3277,7 +3300,7 @@ module supra_framework::pbo_delegation_pool { // zero `add_stake` fee as validator is not producing rewards this epoch assert!( get_add_stake_fee(pool_address, 1000000 * ONE_SUPRA) == 0, - 0 + 0, ); // add 1M SUPRA, join the validator set and activate this stake @@ -3296,7 +3319,7 @@ module supra_framework::pbo_delegation_pool { // `add_stake` fee for 100000 coins: 100000 * 0.006265 / (1 + 0.006265) assert!( get_add_stake_fee(pool_address, 100000 * ONE_SUPRA) == 62259941466, - 0 + 0, ); // add pending_active stake from multiple delegators @@ -3312,14 +3335,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 10000000000000, 0, - 0 + 0, ); assert_delegation( delegator2_address, pool_address, 1000000000000, 0, - 0 + 0, ); // add more stake from delegator 1 @@ -3333,7 +3356,7 @@ module supra_framework::pbo_delegation_pool { pool_address, delegator1_active + 10000 * ONE_SUPRA - fee, 0, - 0 + 0, ); // delegator 2 should not benefit in any way from this new stake @@ -3342,7 +3365,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1000000000000, 0, - 0 + 0, ); // add more stake from delegator 2 @@ -3357,7 +3380,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 11062650000001, 0, - 0 + 0, ); // 1000000000000 * 1% * (100 - 37.35)% assert_delegation( @@ -3365,7 +3388,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 11006265000001, 0, - 0 + 0, ); // in-flight operator commission rewards do not automatically restake/compound @@ -3377,14 +3400,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 11062650000001, 0, - 0 + 0, ); assert_delegation( delegator2_address, pool_address, 11006265000001, 0, - 0 + 0, ); end_aptos_epoch(); @@ -3394,14 +3417,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 11131957502251, 0, - 0 + 0, ); assert_delegation( delegator2_address, pool_address, 11075219250226, 0, - 0 + 0, ); // add more stake from delegator 1 @@ -3415,7 +3438,7 @@ module supra_framework::pbo_delegation_pool { pool_address, delegator1_active + 20000 * ONE_SUPRA - fee, 0, - 0 + 0, ); // delegator 1 unlocks his entire newly added stake @@ -3427,7 +3450,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 11201699216002, 0, - 2000000000000 + 2000000000000, ); // stakes should remain the same - `Self::get_stake` correctly calculates them @@ -3437,7 +3460,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 11201699216002, 0, - 2000000000000 + 2000000000000, ); let reward_period_start_time_in_sec = timestamp::now_seconds(); @@ -3449,12 +3472,12 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(6, 1000), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(50, 100) + fixed_point64::create_from_rational(50, 100), ); features::change_feature_flags_for_testing( supra_framework, vector[features::get_periodical_reward_rate_decrease_feature()], - vector[] + vector[], ); // add more stake from delegator 1 @@ -3471,7 +3494,7 @@ module supra_framework::pbo_delegation_pool { pool_address, delegator1_active + 20000 * ONE_SUPRA - fee, 0, - delegator1_pending_inactive + delegator1_pending_inactive, ); // delegator 1 unlocks his entire newly added stake @@ -3483,7 +3506,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 11342056366822, 0, - 4025059974939 + 4025059974939, ); // stakes should remain the same - `Self::get_stake` correctly calculates them @@ -3493,7 +3516,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 11342056366822, 0, - 4025059974939 + 4025059974939, ); fast_forward_seconds(one_year_in_secs); @@ -3521,7 +3544,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -3548,7 +3571,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1009999999, 0, - 0 + 0, ); assert_pending_withdrawal( delegator_address, @@ -3556,7 +3579,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); unlock_with_min_stake_disabled(delegator, pool_address, 2); @@ -3569,7 +3592,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1009999997, 0, - 0 + 0, ); // the pending withdrawal has been created as > 0 pending_inactive shares have been bought assert_pending_withdrawal( @@ -3578,7 +3601,7 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 0 + 0, ); // successfully delete the pending withdrawal (redeem all owned shares even worth 0 coins) @@ -3588,7 +3611,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1009999997, 0, - 0 + 0, ); assert_pending_withdrawal( delegator_address, @@ -3596,7 +3619,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); // unlock min coins to own some pending_inactive balance (have to disable min-balance checks) @@ -3610,7 +3633,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1009999994, 0, - 1 + 1, ); // the pending withdrawal has been created as > 0 pending_inactive shares have been bought assert_pending_withdrawal( @@ -3619,7 +3642,7 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 1 + 1, ); reactivate_stake(delegator, pool_address, MIN_COINS_ON_SHARES_POOL); @@ -3629,7 +3652,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1009999995, 0, - 0 + 0, ); // the pending withdrawal has been deleted as delegator has 0 pending_inactive shares now assert_pending_withdrawal( @@ -3638,7 +3661,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); } @@ -3666,7 +3689,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); } @@ -3692,7 +3715,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -3705,13 +3728,13 @@ module supra_framework::pbo_delegation_pool { pool_address, 1000 * ONE_SUPRA, 0, - 0 + 0, ); // zero `add_stake` fee as validator is not producing rewards this epoch assert!( get_add_stake_fee(pool_address, 250 * ONE_SUPRA) == 0, - 0 + 0, ); // check `add_stake` increases `active` stakes of delegator and stake pool @@ -3722,7 +3745,7 @@ module supra_framework::pbo_delegation_pool { // check added stake have been transferred out of delegator account assert!( coin::balance(validator_address) == balance - 250 * ONE_SUPRA, - 0 + 0, ); // zero `add_stake` fee charged from added stake assert_delegation( @@ -3730,7 +3753,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1250 * ONE_SUPRA, 0, - 0 + 0, ); // zero `add_stake` fee transferred to null shareholder assert_delegation(NULL_SHAREHOLDER, pool_address, 0, 0, 0); @@ -3751,7 +3774,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1500 * ONE_SUPRA - fee1, 0, - 0 + 0, ); // check `add_stake` fee has been transferred to the null shareholder assert_delegation(NULL_SHAREHOLDER, pool_address, fee1, 0, 0); @@ -3760,7 +3783,7 @@ module supra_framework::pbo_delegation_pool { 1250 * ONE_SUPRA, 0, 250 * ONE_SUPRA, - 0 + 0, ); // add 100 additional coins being pending_active until next epoch @@ -3773,7 +3796,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1600 * ONE_SUPRA - fee1 - fee2, 0, - 0 + 0, ); // check `add_stake` fee has been transferred to the null shareholder assert_delegation(NULL_SHAREHOLDER, pool_address, fee1 + fee2, 0, 0); @@ -3782,7 +3805,7 @@ module supra_framework::pbo_delegation_pool { 1250 * ONE_SUPRA, 0, 350 * ONE_SUPRA, - 0 + 0, ); end_aptos_epoch(); @@ -3792,7 +3815,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 161250000000, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 161250000000, 0, 0, 0); @@ -3802,9 +3825,9 @@ module supra_framework::pbo_delegation_pool { assert!( pool_u64::shares( &borrow_global(pool_address).active_shares, - NULL_SHAREHOLDER + NULL_SHAREHOLDER, ) == 0, - 0 + 0, ); assert_delegation(NULL_SHAREHOLDER, pool_address, 0, 0, 0); @@ -3818,7 +3841,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 181250000000 - fee1, 0, - 0 + 0, ); // check `add_stake` fee has been transferred to the null shareholder assert_delegation(NULL_SHAREHOLDER, pool_address, fee1 - 1, 0, 0); @@ -3831,7 +3854,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 182862500000, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 182862500000, 0, 0, 0); @@ -3841,9 +3864,9 @@ module supra_framework::pbo_delegation_pool { assert!( pool_u64::shares( &borrow_global(pool_address).active_shares, - NULL_SHAREHOLDER + NULL_SHAREHOLDER, ) == 0, - 0 + 0, ); assert_delegation(NULL_SHAREHOLDER, pool_address, 0, 0, 0); } @@ -3870,7 +3893,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -3885,7 +3908,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1000 * ONE_SUPRA, 0, - 0 + 0, ); // add 250 coins from second account @@ -3898,21 +3921,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 250 * ONE_SUPRA - fee1, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 1000 * ONE_SUPRA, 0, - 0 + 0, ); stake::assert_stake_pool( pool_address, 1000 * ONE_SUPRA, 0, 250 * ONE_SUPRA, - 0 + 0, ); end_aptos_epoch(); @@ -3924,7 +3947,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 250 * ONE_SUPRA, 0, - 0 + 0, ); // actual active rewards have been distributed to their earner(s) assert_delegation( @@ -3932,7 +3955,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 100999999999, 0, - 0 + 0, ); // add another 250 coins from first account @@ -3945,21 +3968,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 125999999999 - fee1, 0, - 0 + 0, ); assert_delegation( delegator_address, pool_address, 250 * ONE_SUPRA, 0, - 0 + 0, ); stake::assert_stake_pool( pool_address, 1260 * ONE_SUPRA, 0, 250 * ONE_SUPRA, - 0 + 0, ); // add another 100 coins from second account @@ -3972,21 +3995,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 350 * ONE_SUPRA - fee2, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 125999999999 - fee1, 0, - 0 + 0, ); stake::assert_stake_pool( pool_address, 1260 * ONE_SUPRA, 0, 350 * ONE_SUPRA, - 0 + 0, ); end_aptos_epoch(); @@ -3997,7 +4020,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 35250000001, 0, - 0 + 0, ); // 1010 * 1.01 active stake + 250 pending_active stake assert_delegation( @@ -4005,7 +4028,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 127009999998, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 162260000000, 0, 0, 0); } @@ -4032,7 +4055,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -4051,14 +4074,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 300 * ONE_SUPRA - fee, 0, - 0 + 0, ); stake::assert_stake_pool( pool_address, 100 * ONE_SUPRA, 0, 200 * ONE_SUPRA, - 0 + 0, ); // cannot unlock pending_active stake (only 100/300 stake can be displaced) @@ -4068,7 +4091,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 200 * ONE_SUPRA - fee, 0, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); assert_pending_withdrawal( validator_address, @@ -4076,14 +4099,14 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); stake::assert_stake_pool( pool_address, 0, 0, 200 * ONE_SUPRA, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); assert_inactive_shares_pool(pool_address, 0, true, 100 * ONE_SUPRA); @@ -4095,7 +4118,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 250 * ONE_SUPRA - fee, 0, - 50 * ONE_SUPRA + 50 * ONE_SUPRA, ); assert_pending_withdrawal( validator_address, @@ -4103,14 +4126,14 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 50 * ONE_SUPRA + 50 * ONE_SUPRA, ); stake::assert_stake_pool( pool_address, 50 * ONE_SUPRA, 0, 200 * ONE_SUPRA, - 50 * ONE_SUPRA + 50 * ONE_SUPRA, ); reactivate_stake(validator, pool_address, 50 * ONE_SUPRA); @@ -4120,7 +4143,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 300 * ONE_SUPRA - fee, 0, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -4128,14 +4151,14 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); stake::assert_stake_pool( pool_address, 100 * ONE_SUPRA, 0, 200 * ONE_SUPRA, - 0 + 0, ); // pending_inactive shares pool has not been deleted (as can still `unlock` this OLC) assert_inactive_shares_pool(pool_address, 0, true, 0); @@ -4147,7 +4170,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 301 * ONE_SUPRA, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 301 * ONE_SUPRA, 0, 0, 0); @@ -4158,7 +4181,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 15100000001, 0, - 14999999999 + 14999999999, ); stake::assert_stake_pool(pool_address, 15100000001, 0, 0, 14999999999); assert_pending_withdrawal( @@ -4167,13 +4190,12 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 14999999999 + 14999999999, ); assert!( - stake::get_remaining_lockup_secs(pool_address) - == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, - 0 + stake::get_remaining_lockup_secs(pool_address) == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, + 0, ); end_aptos_epoch(); // additionally forwards EPOCH_DURATION seconds @@ -4184,7 +4206,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 15251000001, 0, - 15149999998 + 15149999998, ); assert_pending_withdrawal( validator_address, @@ -4192,7 +4214,7 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 15149999998 + 15149999998, ); stake::assert_stake_pool(pool_address, 15251000001, 0, 0, 15149999998); @@ -4205,7 +4227,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 15403510001, 15301499997, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -4213,7 +4235,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 15301499997 + 15301499997, ); stake::assert_stake_pool(pool_address, 15403510001, 15301499997, 0, 0); @@ -4230,21 +4252,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 4999999999 - fee, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 15403510001, 15301499997, - 0 + 0, ); stake::assert_stake_pool( pool_address, 15403510001, 15301499997, 50 * ONE_SUPRA, - 0 + 0, ); // cannot withdraw stake unlocked by others @@ -4259,7 +4281,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 15403510001, 0, - 0 + 0, ); // pending withdrawal has been executed and deleted assert_pending_withdrawal( @@ -4268,7 +4290,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); // inactive shares pool on OLC 0 has been deleted because its stake has been withdrawn assert_inactive_shares_pool(pool_address, 0, false, 0); @@ -4280,7 +4302,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10000000000, 0, - 5403510000 + 5403510000, ); assert_pending_withdrawal( validator_address, @@ -4288,7 +4310,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 5403510000 + 5403510000, ); // end lockup cycle 1 @@ -4301,7 +4323,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10100000000, 5457545100, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -4309,7 +4331,7 @@ module supra_framework::pbo_delegation_pool { true, 1, true, - 5457545100 + 5457545100, ); // unlock when the pending withdrawal exists and gets automatically executed @@ -4317,14 +4339,14 @@ module supra_framework::pbo_delegation_pool { unlock(validator, pool_address, 10100000000); assert!( coin::balance(validator_address) == balance + 5457545100, - 0 + 0, ); assert_delegation( validator_address, pool_address, 0, 0, - 10100000000 + 10100000000, ); // this is the new pending withdrawal replacing the executed one assert_pending_withdrawal( @@ -4333,7 +4355,7 @@ module supra_framework::pbo_delegation_pool { true, 2, false, - 10100000000 + 10100000000, ); // create dummy validator to ensure the existing validator can leave the set @@ -4342,8 +4364,9 @@ module supra_framework::pbo_delegation_pool { let coin = stake::mint_coins(100 * ONE_SUPRA); // lockup time updated as you see above we `fast_forward_seconds` alog with `end_aptos_epoch` - principle_lockup_time = LOCKUP_CYCLE_SECONDS - + (LOCKUP_CYCLE_SECONDS - (3 * EPOCH_DURATION)) + (5 * EPOCH_DURATION); + principle_lockup_time = LOCKUP_CYCLE_SECONDS + ( + LOCKUP_CYCLE_SECONDS - (3 * EPOCH_DURATION) + ) + (5 * EPOCH_DURATION); initialize_test_validator( delegator, 100 * ONE_SUPRA, @@ -4357,7 +4380,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); // inactivate validator stake::leave_validator_set(validator, pool_address); @@ -4380,7 +4403,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 0, 0, - 10303010000 + 10303010000, ); // the pending withdrawal should be reported as still pending assert_pending_withdrawal( @@ -4389,7 +4412,7 @@ module supra_framework::pbo_delegation_pool { true, 2, false, - 10303010000 + 10303010000, ); // validator is inactive and lockup expired => pending_inactive stake is withdrawable @@ -4398,7 +4421,7 @@ module supra_framework::pbo_delegation_pool { assert!( coin::balance(validator_address) == balance + 10303010000, - 0 + 0, ); assert_delegation(validator_address, pool_address, 0, 0, 0); assert_pending_withdrawal( @@ -4407,7 +4430,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); stake::assert_stake_pool(pool_address, 5100500001, 0, 0, 0); // pending_inactive shares pool has not been deleted (as can still `unlock` this OLC) @@ -4415,7 +4438,7 @@ module supra_framework::pbo_delegation_pool { pool_address, observed_lockup_cycle(pool_address), true, - 0 + 0, ); stake::mint(validator, 30 * ONE_SUPRA); @@ -4427,7 +4450,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 2000000000, 0, - 999999999 + 999999999, ); // the pending withdrawal should be reported as still pending assert_pending_withdrawal( @@ -4436,7 +4459,7 @@ module supra_framework::pbo_delegation_pool { true, 2, false, - 999999999 + 999999999, ); balance = coin::balance(validator_address); @@ -4448,7 +4471,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 2000000000, 0, - 999999998 + 999999998, ); assert_pending_withdrawal( validator_address, @@ -4456,22 +4479,15 @@ module supra_framework::pbo_delegation_pool { true, 2, false, - 999999998 + 999999998, ); assert!( coin::balance(validator_address) == balance + 1, - 0 + 0, ); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_total_coins_inactive( supra_framework: &signer, validator: &signer, @@ -4496,7 +4512,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 1, principle_lockup_time, - 60 + 60, ); let validator_address = signer::address_of(validator); @@ -4519,14 +4535,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 100 * ONE_SUPRA, 0, - 0 + 0, ); assert_delegation( delegator2_address, pool_address, 200 * ONE_SUPRA, 0, - 0 + 0, ); // unlock some stake from delegator 1 @@ -4536,7 +4552,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 5000000000, 0, - 4999999999 + 4999999999, ); // move to lockup cycle 1 @@ -4549,14 +4565,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 5050000000, 5049999998, - 0 + 0, ); assert_delegation( delegator2_address, pool_address, 202 * ONE_SUPRA, 0, - 0 + 0, ); synchronize_delegation_pool(pool_address); @@ -4569,7 +4585,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 15200000001, 0, - 4999999999 + 4999999999, ); // withdraw some of inactive stake of delegator 1 @@ -4579,7 +4595,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 5050000000, 3000000001, - 0 + 0, ); assert!(total_coins_inactive(pool_address) == 3000000001, 0); @@ -4594,14 +4610,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 5100500000, 3000000001, - 0 + 0, ); assert_delegation( delegator2_address, pool_address, 15352000001, 5049999998, - 0 + 0, ); // total_coins_inactive remains unchanged in the absence of user operations @@ -4609,9 +4625,9 @@ module supra_framework::pbo_delegation_pool { synchronize_delegation_pool(pool_address); // total_coins_inactive == previous inactive stake + previous pending_inactive stake and its rewards assert!( - total_coins_inactive(pool_address) - == inactive + pending_inactive + pending_inactive / 100, - 0 + total_coins_inactive(pool_address) == inactive + pending_inactive + pending_inactive + / 100, + 0, ); // withdraw some of inactive stake of delegator 2 @@ -4619,7 +4635,7 @@ module supra_framework::pbo_delegation_pool { withdraw(delegator2, pool_address, 3049999998); assert!( total_coins_inactive(pool_address) == total_coins_inactive - 3049999997, - 0 + 0, ); // unlock some stake from delegator `validator` @@ -4643,7 +4659,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); // inactivate validator stake::leave_validator_set(validator, pool_address); @@ -4699,7 +4715,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -4712,14 +4728,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 100 * ONE_SUPRA, 0, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); stake::assert_stake_pool( pool_address, 100 * ONE_SUPRA, 0, 0, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); assert_pending_withdrawal( validator_address, @@ -4727,7 +4743,7 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); // add some stake to pending_active state @@ -4740,14 +4756,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 250 * ONE_SUPRA - fee, 0, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); stake::assert_stake_pool( pool_address, 100 * ONE_SUPRA, 0, 150 * ONE_SUPRA, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); // can reactivate only pending_inactive stake @@ -4758,14 +4774,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 350 * ONE_SUPRA - fee, 0, - 0 + 0, ); stake::assert_stake_pool( pool_address, 200 * ONE_SUPRA, 0, 150 * ONE_SUPRA, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -4773,7 +4789,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); end_aptos_epoch(); @@ -4783,7 +4799,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 35200000000, 0, - 0 + 0, ); // unlock stake added at previous epoch (expect some imprecision when moving shares) @@ -4793,7 +4809,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 20200000001, 0, - 14999999999 + 14999999999, ); stake::assert_stake_pool(pool_address, 20200000001, 0, 0, 14999999999); @@ -4807,7 +4823,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 20402000001, 15149999998, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -4815,7 +4831,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 15149999998 + 15149999998, ); // cannot reactivate inactive stake @@ -4825,7 +4841,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 20402000001, 15149999998, - 0 + 0, ); // unlock stake in the new lockup cycle (the pending withdrawal is executed) @@ -4836,7 +4852,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10402000002, 0, - 9999999999 + 9999999999, ); assert_pending_withdrawal( validator_address, @@ -4844,7 +4860,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 9999999999 + 9999999999, ); // reactivate the new pending withdrawal almost entirely @@ -4855,7 +4871,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 1000000000 + 1000000000, ); // reactivate remaining stake of the new pending withdrawal reactivate_stake(validator, pool_address, 1000000000); @@ -4865,7 +4881,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); } @@ -4891,7 +4907,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 1, principle_lockup_time, - 60 + 60, ); let validator_address = signer::address_of(validator); @@ -4910,7 +4926,7 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -4921,14 +4937,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 200 * ONE_SUPRA, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 90899999999, 10100000000, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -4936,7 +4952,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 10100000000 + 10100000000, ); assert_inactive_shares_pool(pool_address, 0, true, 100 * ONE_SUPRA); @@ -4947,14 +4963,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 200 * ONE_SUPRA, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 90899999999, 10100000000, - 0 + 0, ); unlock(delegator, pool_address, 100 * ONE_SUPRA); @@ -4963,14 +4979,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 10000000000, 0, - 9999999999 + 9999999999, ); assert_delegation( validator_address, pool_address, 90900000000, 10100000000, - 0 + 0, ); assert_pending_withdrawal( delegator_address, @@ -4978,7 +4994,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 9999999999 + 9999999999, ); // check cannot withdraw inactive stake unlocked by others even if owning pending_inactive @@ -4988,14 +5004,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 10000000000, 0, - 9999999999 + 9999999999, ); assert_delegation( validator_address, pool_address, 90900000000, 10100000000, - 0 + 0, ); // withdraw entire owned inactive stake @@ -5003,7 +5019,7 @@ module supra_framework::pbo_delegation_pool { withdraw(validator, pool_address, MAX_U64); assert!( coin::balance(validator_address) == balance + 10100000000, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -5011,7 +5027,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); assert_inactive_shares_pool(pool_address, 0, false, 0); @@ -5023,7 +5039,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10100000000, 10099999998, - 0 + 0, ); assert_pending_withdrawal( delegator_address, @@ -5031,7 +5047,7 @@ module supra_framework::pbo_delegation_pool { true, 1, true, - 10099999998 + 10099999998, ); assert_inactive_shares_pool(pool_address, 1, true, 9999999999); @@ -5045,7 +5061,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10100000000, 10099999998, - 0 + 0, ); assert_pending_withdrawal( delegator_address, @@ -5053,7 +5069,7 @@ module supra_framework::pbo_delegation_pool { true, 1, true, - 10099999998 + 10099999998, ); // implicitly execute the pending withdrawal by unlocking min stake to buy 1 share @@ -5064,7 +5080,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10099999998, 0, - 1 + 1, ); // old pending withdrawal has been replaced assert_pending_withdrawal( @@ -5073,7 +5089,7 @@ module supra_framework::pbo_delegation_pool { true, 2, false, - 1 + 1, ); assert_inactive_shares_pool(pool_address, 1, false, 0); assert_inactive_shares_pool(pool_address, 2, true, 1); @@ -5101,7 +5117,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 1, principle_lockup_time, - 60 + 60, ); let validator_address = signer::address_of(validator); @@ -5144,7 +5160,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); // inactivate validator stake::leave_validator_set(validator, pool_address); @@ -5165,21 +5181,21 @@ module supra_framework::pbo_delegation_pool { 113231100001, 20200000000, 0, - 10200999997 + 10200999997, ); assert_delegation( delegator_address, pool_address, 10201000000, 0, - 10200999997 + 10200999997, ); assert_delegation( validator_address, pool_address, 103030100000, 20200000000, - 0 + 0, ); // withdraw some inactive stake (remaining pending_inactive is not inactivated) @@ -5189,21 +5205,21 @@ module supra_framework::pbo_delegation_pool { 113231100001, 20000000001, 0, - 10200999997 + 10200999997, ); assert_delegation( delegator_address, pool_address, 10201000000, 0, - 10200999997 + 10200999997, ); assert_delegation( validator_address, pool_address, 103030100000, 20000000001, - 0 + 0, ); // withdraw some pending_inactive stake (remaining pending_inactive is not inactivated) @@ -5213,21 +5229,21 @@ module supra_framework::pbo_delegation_pool { 113231100001, 20000000001, 0, - 10000000001 + 10000000001, ); assert_delegation( delegator_address, pool_address, 10201000000, 0, - 10000000001 + 10000000001, ); assert_delegation( validator_address, pool_address, 103030100000, 20000000001, - 0 + 0, ); // no new inactive stake detected => OLC does not advance @@ -5242,14 +5258,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 0, 0, - 10000000002 + 10000000002, ); assert_delegation( validator_address, pool_address, 103030100001, 20000000001, - 0 + 0, ); assert_pending_withdrawal( validator_address, @@ -5257,7 +5273,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 20000000001 + 20000000001, ); assert_pending_withdrawal( delegator_address, @@ -5265,21 +5281,21 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 10000000002 + 10000000002, ); stake::assert_stake_pool( pool_address, 103030100001, 20000000001, 0, - 10000000002 + 10000000002, ); // reactivate validator stake::join_validator_set(validator, pool_address); assert!( stake::get_validator_state(pool_address) == VALIDATOR_STATUS_PENDING_ACTIVE, - 0 + 0, ); end_aptos_epoch(); @@ -5290,7 +5306,7 @@ module supra_framework::pbo_delegation_pool { 103030100001, 20000000001, 0, - 10000000002 + 10000000002, ); synchronize_delegation_pool(pool_address); @@ -5300,7 +5316,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 20000000001 + 20000000001, ); assert_pending_withdrawal( delegator_address, @@ -5308,7 +5324,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 10000000002 + 10000000002, ); assert!(observed_lockup_cycle(pool_address) == observed_lockup_cycle, 0); @@ -5320,7 +5336,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 10000000002 + 10000000002, ); // earning rewards is resumed from this epoch on @@ -5330,7 +5346,7 @@ module supra_framework::pbo_delegation_pool { 104060401001, 20000000001, 0, - 10100000002 + 10100000002, ); // new pending_inactive stake earns rewards but so does the old one @@ -5341,7 +5357,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 104060401000 + 104060401000, ); assert_pending_withdrawal( delegator_address, @@ -5349,7 +5365,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 10100000002 + 10100000002, ); end_aptos_epoch(); assert_pending_withdrawal( @@ -5358,7 +5374,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 105101005010 + 105101005010, ); assert_pending_withdrawal( delegator_address, @@ -5366,7 +5382,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 10201000002 + 10201000002, ); } @@ -5392,7 +5408,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -5405,7 +5421,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1010 * ONE_SUPRA, 0, - 0 + 0, ); // add stake in pending_active state @@ -5418,7 +5434,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1210 * ONE_SUPRA - fee, 0, - 0 + 0, ); end_aptos_epoch(); @@ -5428,7 +5444,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 122010000000, 0, - 0 + 0, ); end_aptos_epoch(); @@ -5438,7 +5454,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 123230100000, 0, - 0 + 0, ); // 123230100000 active stake * 1.01 @@ -5456,7 +5472,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 129516073574, 0, - 0 + 0, ); // unlock 200 coins from delegator `validator` @@ -5466,7 +5482,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 109516073575, 0, - 19999999999 + 19999999999, ); // end this lockup cycle @@ -5478,7 +5494,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 110611234310, 20199999998, - 0 + 0, ); end_aptos_epoch(); @@ -5488,7 +5504,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 111717346653, 20199999998, - 0 + 0, ); // add stake in pending_active state @@ -5501,7 +5517,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 211717346653 - fee, 20199999998, - 0 + 0, ); end_aptos_epoch(); @@ -5511,7 +5527,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 212834520119, 20199999998, - 0 + 0, ); end_aptos_epoch(); @@ -5521,7 +5537,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 214962865320, 20199999998, - 0 + 0, ); } @@ -5547,7 +5563,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -5564,21 +5580,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 300 * ONE_SUPRA - fee, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 200 * ONE_SUPRA, 0, - 0 + 0, ); stake::assert_stake_pool( pool_address, 200 * ONE_SUPRA, 0, 300 * ONE_SUPRA, - 0 + 0, ); end_aptos_epoch(); @@ -5588,14 +5604,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 300 * ONE_SUPRA, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 20199999999, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 502 * ONE_SUPRA, 0, 0, 0); @@ -5606,14 +5622,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 303 * ONE_SUPRA, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 20401999999, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 50702000000, 0, 0, 0); @@ -5624,14 +5640,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 30603000000, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 20606019999, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 51209020000, 0, 0, 0); @@ -5641,14 +5657,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 30909030000, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 20812080199, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 51721110200, 0, 0, 0); @@ -5662,14 +5678,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 130909030000 - fee, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 20812080199, 0, - 0 + 0, ); end_aptos_epoch(); @@ -5679,14 +5695,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 131218120300, 0, - 0 + 0, ); assert_delegation( validator_address, pool_address, 21020201001, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 152238321302, 0, 0, 0); } @@ -5713,7 +5729,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -5725,7 +5741,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1010 * ONE_SUPRA, 0, - 0 + 0, ); // unlock 200 coins from delegator `validator` @@ -5735,7 +5751,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 81000000001, 0, - 19999999999 + 19999999999, ); end_aptos_epoch(); // 81000000001 active stake * 1.01 + 19999999999 pending_inactive stake * 1.01 @@ -5749,7 +5765,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 84288924811, 20606019996, - 0 + 0, ); // unlock 200 coins from delegator `validator` which implicitly executes its pending withdrawal @@ -5760,7 +5776,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 64288924812, 0, - 19999999999 + 19999999999, ); // lockup cycle is not ended, pending_inactive stake is still earning @@ -5773,7 +5789,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 66899312957, 0, - 20812080195 + 20812080195, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -5785,18 +5801,11 @@ module supra_framework::pbo_delegation_pool { pool_address, 68926429037, 21020200996, - 0 + 0, ); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_out_of_order_redeem( supra_framework: &signer, validator: &signer, @@ -5821,7 +5830,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -5849,7 +5858,7 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 14999999999 + 14999999999, ); // move to lockup cycle 1 @@ -5864,7 +5873,7 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 14999999999 + 14999999999, ); // 14999999999 pending_inactive stake * 1.01 assert_pending_withdrawal( @@ -5873,7 +5882,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 15149999998 + 15149999998, ); // move to lockup cycle 2 @@ -5886,7 +5895,7 @@ module supra_framework::pbo_delegation_pool { true, 1, true, - 15149999998 + 15149999998, ); assert_pending_withdrawal( delegator1_address, @@ -5894,7 +5903,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 15149999998 + 15149999998, ); // both delegators who unlocked at different lockup cycles should be able to withdraw their stakes @@ -5907,7 +5916,7 @@ module supra_framework::pbo_delegation_pool { true, 1, true, - 10000000001 + 10000000001, ); assert_pending_withdrawal( delegator1_address, @@ -5915,7 +5924,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); assert!(coin::balance(delegator1_address) == 15149999998, 0); assert!(coin::balance(delegator2_address) == 5149999997, 0); @@ -5933,7 +5942,7 @@ module supra_framework::pbo_delegation_pool { true, 1, true, - 10000000001 + 10000000001, ); // 9999999999 pending_inactive stake * 1.01 assert_pending_withdrawal( @@ -5942,7 +5951,7 @@ module supra_framework::pbo_delegation_pool { true, 2, true, - 10099999998 + 10099999998, ); // withdraw inactive stake of delegator 2 left from lockup cycle 1 in cycle 3 @@ -5954,14 +5963,14 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); // withdraw inactive stake of delegator 1 left from previous lockup cycle withdraw(delegator1, pool_address, 10099999998); assert!( coin::balance(delegator1_address) == 15149999998 + 10099999998, - 0 + 0, ); assert_pending_withdrawal( delegator1_address, @@ -5969,18 +5978,11 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_operator_fee( supra_framework: &signer, validator: &signer, @@ -6007,7 +6009,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 1, principle_lockup_time, - 60 + 60, ); let pool_address = get_owned_pool_address(validator_address); assert!(stake::get_operator(pool_address) == validator_address, 0); @@ -6045,7 +6047,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10087350000, 0, - 0 + 0, ); // 20000000000 active stake * 1.008735 assert_delegation( @@ -6053,7 +6055,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 20174700000, 0, - 0 + 0, ); end_aptos_epoch(); @@ -6069,7 +6071,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10175573500, 0, - 0 + 0, ); // 20174700000 active stake * 1.008735 + some of the rewards of previous commission if restaked assert_delegation( @@ -6077,7 +6079,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 20351147000, 0, - 0 + 0, ); // restake operator commission rewards @@ -6092,7 +6094,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 115658596, 0, - 0 + 0, ); // 10175573500 active stake * 1.008735 assert_delegation( @@ -6100,7 +6102,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10264457134, 0, - 0 + 0, ); // 20351147000 active stake * 1.008735 assert_delegation( @@ -6108,7 +6110,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 20528914269, 0, - 0 + 0, ); // check operator is rewarded by pending_inactive stake too @@ -6124,7 +6126,7 @@ module supra_framework::pbo_delegation_pool { false, 0, false, - 0 + 0, ); // distribute operator pending_inactive commission rewards synchronize_delegation_pool(pool_address); @@ -6135,7 +6137,7 @@ module supra_framework::pbo_delegation_pool { true, 0, false, - 12649998 + 12649998, ); // 209090300 active rewards * 0.1265 + 115658596 active stake * 1.008735 @@ -6145,7 +6147,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 143118796, 0, - 12649998 + 12649998, ); // 10264457134 active stake * 1.008735 assert_delegation( @@ -6153,7 +6155,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10354117168, 0, - 0 + 0, ); // 10528914270 active stake * 1.008735 // 9999999999 pending_inactive stake * 1.008735 @@ -6162,7 +6164,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10620884336, 0, - 10087349999 + 10087349999, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -6177,7 +6179,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 171083360, 25536995, - 0 + 0, ); // distribute operator pending_inactive commission rewards synchronize_delegation_pool(pool_address); @@ -6187,14 +6189,14 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 25536995 + 25536995, ); // check operator is not rewarded by `add_stake` fees stake::mint(delegator1, 100 * ONE_SUPRA); assert!( get_add_stake_fee(pool_address, 100 * ONE_SUPRA) > 0, - 0 + 0, ); add_stake(delegator1, pool_address, 100 * ONE_SUPRA); @@ -6207,7 +6209,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 199559340, 25536995, - 0 + 0, ); // unlock some more stake to produce pending_inactive commission @@ -6218,7 +6220,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 10807241561, 10175463001, - 0 + 0, ); unlock(delegator2, pool_address, 100 * ONE_SUPRA); // 10807241561 - 100 SUPRA < `MIN_COINS_ON_SHARES_POOL` thus active stake is entirely unlocked @@ -6227,7 +6229,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 807241561, 0, - 9999999999 + 9999999999, ); end_aptos_epoch(); @@ -6237,7 +6239,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 228553872, 25536996, - 12649999 + 12649999, ); assert_pending_withdrawal( validator_address, @@ -6245,7 +6247,7 @@ module supra_framework::pbo_delegation_pool { true, 0, true, - 25536996 + 25536996, ); // distribute in-flight pending_inactive commission, implicitly executing the inactive withdrawal of operator @@ -6260,7 +6262,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 228553872, 0, - 12649998 + 12649998, ); assert_pending_withdrawal( validator_address, @@ -6268,18 +6270,11 @@ module supra_framework::pbo_delegation_pool { true, 1, false, - 12649998 + 12649998, ); } - #[ - test( - supra_framework = @supra_framework, - old_operator = @0x123, - delegator = @0x010, - new_operator = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, old_operator = @0x123, delegator = @0x010, new_operator = @0x020)] public entry fun test_change_operator( supra_framework: &signer, old_operator: &signer, @@ -6310,7 +6305,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let pool_address = get_owned_pool_address(old_operator_address); assert!(stake::get_operator(pool_address) == old_operator_address, 0); @@ -6335,7 +6330,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 12650000, 0, - 12650000 + 12650000, ); end_aptos_epoch(); stake::assert_stake_pool(pool_address, 10201000000, 0, 0, 10201000000); @@ -6344,7 +6339,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 25426500, 0, - 25426500 + 25426500, ); // change operator @@ -6358,7 +6353,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 25648600, 0, - 25648600 + 25648600, ); // 102010000 active rewards * 0.1265 and 102010000 pending_inactive rewards * 0.1265 assert_delegation( @@ -6366,7 +6361,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 12904265, 0, - 12904265 + 12904265, ); // restake `new_operator` commission rewards @@ -6380,7 +6375,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 25872641, 0, - 25872641 + 25872641, ); // 103030100 active rewards * 0.1265 and 12904265 active stake * 1.008735 // 103030100 pending_inactive rewards * 0.1265 and 12904265 pending_inactive stake * 1.008735 @@ -6389,19 +6384,11 @@ module supra_framework::pbo_delegation_pool { pool_address, 26050290, 0, - 26050290 + 26050290, ); } - #[ - test( - supra_framework = @supra_framework, - operator1 = @0x123, - delegator = @0x010, - beneficiary = @0x020, - operator2 = @0x030 - ) - ] + #[test(supra_framework = @supra_framework, operator1 = @0x123, delegator = @0x010, beneficiary = @0x020, operator2 = @0x030)] public entry fun test_set_beneficiary_for_operator( supra_framework: &signer, operator1: &signer, @@ -6435,7 +6422,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let pool_address = get_owned_pool_address(operator1_address); assert!(stake::get_operator(pool_address) == operator1_address, 0); @@ -6459,14 +6446,14 @@ module supra_framework::pbo_delegation_pool { 101000000000000, 0, 0, - 101000000000000 + 101000000000000, ); assert_delegation( operator1_address, pool_address, 126500000000, 0, - 126500000000 + 126500000000, ); end_aptos_epoch(); stake::assert_stake_pool( @@ -6474,14 +6461,14 @@ module supra_framework::pbo_delegation_pool { 102010000000000, 0, 0, - 102010000000000 + 102010000000000, ); assert_delegation( operator1_address, pool_address, 254265000000, 0, - 254265000000 + 254265000000, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); @@ -6489,7 +6476,7 @@ module supra_framework::pbo_delegation_pool { withdraw(operator1, pool_address, ONE_SUPRA); assert!( coin::balance(operator1_address) == ONE_SUPRA - 1, - 0 + 0, ); set_beneficiary_for_operator(operator1, beneficiary_address); @@ -6503,11 +6490,11 @@ module supra_framework::pbo_delegation_pool { withdraw(beneficiary, pool_address, ONE_SUPRA); assert!( coin::balance(beneficiary_address) == ONE_SUPRA - 1, - 0 + 0, ); assert!( coin::balance(operator1_address) == ONE_SUPRA - 1, - 0 + 0, ); // switch operator to operator2. The rewards should go to operator2 not to the beneficiay of operator1. @@ -6520,11 +6507,11 @@ module supra_framework::pbo_delegation_pool { withdraw(operator2, pool_address, ONE_SUPRA); assert!( coin::balance(beneficiary_address) == ONE_SUPRA - 1, - 0 + 0, ); assert!( coin::balance(operator2_address) == ONE_SUPRA - 1, - 0 + 0, ); } @@ -6552,7 +6539,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let pool_address = get_owned_pool_address(operator_address); assert!(stake::get_operator(pool_address) == operator_address, 0); @@ -6577,7 +6564,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 12650000, 0, - 12650000 + 12650000, ); end_aptos_epoch(); stake::assert_stake_pool(pool_address, 10201000000, 0, 0, 10201000000); @@ -6586,7 +6573,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 25426500, 0, - 25426500 + 25426500, ); // change the commission percentage @@ -6601,7 +6588,7 @@ module supra_framework::pbo_delegation_pool { // fee amount 76756290 in the following case, not 86593604 (calculated with the old commission rate). assert!( get_add_stake_fee(pool_address, 100 * ONE_SUPRA) == 76756290, - 0 + 0, ); synchronize_delegation_pool(pool_address); @@ -6615,7 +6602,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 62187388, 38552865, - 0 + 0, ); end_aptos_epoch(); @@ -6625,7 +6612,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 86058258, 38552865, - 0 + 0, ); } @@ -6653,7 +6640,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let pool_address = get_owned_pool_address(operator_address); assert!(stake::get_operator(pool_address) == operator_address, 0); @@ -6694,14 +6681,7 @@ module supra_framework::pbo_delegation_pool { update_commission_percentage(operator, 2255); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_min_stake_is_preserved( supra_framework: &signer, validator: &signer, @@ -6726,7 +6706,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -6752,7 +6732,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 5000000000, 0, - 0 + 0, ); // pending_inactive balance would be under threshold => move MIN_COINS_ON_SHARES_POOL coins unlock(delegator1, pool_address, MIN_COINS_ON_SHARES_POOL); @@ -6761,7 +6741,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 4900000000, 0, - 100000000 + 100000000, ); // pending_inactive balance is over threshold @@ -6771,7 +6751,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 5000000000, 0, - 0 + 0, ); // pending_inactive balance would be under threshold => move entire balance @@ -6781,21 +6761,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 5000000000, 0, - 0 + 0, ); // active balance would be under threshold => move entire balance unlock( delegator1, pool_address, - 5000000000 - (MIN_COINS_ON_SHARES_POOL - 1) + 5000000000 - (MIN_COINS_ON_SHARES_POOL - 1), ); assert_delegation( delegator1_address, pool_address, 0, 0, - 5000000000 + 5000000000, ); // active balance would be under threshold => move MIN_COINS_ON_SHARES_POOL coins @@ -6805,7 +6785,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 100000000, 0, - 4900000000 + 4900000000, ); // active balance is over threshold @@ -6815,21 +6795,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 0, 0, - 5000000000 + 5000000000, ); // pending_inactive balance would be under threshold => move entire balance reactivate_stake( delegator1, pool_address, - 4000000000 - (MIN_COINS_ON_SHARES_POOL - 1) + 4000000000 - (MIN_COINS_ON_SHARES_POOL - 1), ); assert_delegation( delegator1_address, pool_address, 3900000001, 0, - 1099999999 + 1099999999, ); // active + pending_inactive balance < 2 * MIN_COINS_ON_SHARES_POOL @@ -6839,7 +6819,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 16 * ONE_SUPRA, 0, - 0 + 0, ); unlock(delegator2, pool_address, MIN_COINS_ON_SHARES_POOL); assert_delegation( @@ -6847,7 +6827,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1500000000, 0, - 100000000 + 100000000, ); reactivate_stake(delegator2, pool_address, MIN_COINS_ON_SHARES_POOL); assert_delegation( @@ -6855,7 +6835,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1600000000, 0, - 0 + 0, ); unlock(delegator2, pool_address, ONE_SUPRA); @@ -6864,7 +6844,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 1500000000, 0, - 100000000 + 100000000, ); reactivate_stake(delegator2, pool_address, 2 * ONE_SUPRA); assert_delegation( @@ -6872,7 +6852,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 16 * ONE_SUPRA, 0, - 0 + 0, ); // share price becomes 1.01 on both pools @@ -6882,7 +6862,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 3800000001, 0, - 1199999999 + 1199999999, ); end_aptos_epoch(); assert_delegation( @@ -6890,7 +6870,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 3838000001, 0, - 1211999998 + 1211999998, ); // pending_inactive balance is over threshold @@ -6900,7 +6880,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 3938000000, 0, - 1111999999 + 1111999999, ); // 1 coin < 1.01 so no shares are redeemed @@ -6910,7 +6890,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 4037999999, 0, - 1012000000 + 1012000000, ); // pending_inactive balance is over threshold @@ -6921,7 +6901,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 4137999998, 0, - 912000001 + 912000001, ); // 1 coin < 1.01 so no shares are redeemed @@ -6931,7 +6911,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 4237999997, 0, - 812000002 + 812000002, ); // pending_inactive balance would be under threshold => move entire balance @@ -6941,7 +6921,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 4337999996, 0, - 712000003 + 712000003, ); // pending_inactive balance would be under threshold => move MIN_COINS_ON_SHARES_POOL coins @@ -6951,7 +6931,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 4237999996, 0, - 812000002 + 812000002, ); // pending_inactive balance would be under threshold => move entire balance @@ -6961,7 +6941,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 4337999995, 0, - 712000003 + 712000003, ); } @@ -6969,9 +6949,9 @@ module supra_framework::pbo_delegation_pool { public entry fun test_get_expected_stake_pool_address(staker: address) { let pool_address = get_expected_stake_pool_address(staker, vector[0x42, 0x42]); assert!( - pool_address - == @0xcb5678be9ec64067c2c3f9f8de78e19509411b053d723d2788ebf1f7ba02f04b, - 0 + pool_address == + @0xcb5678be9ec64067c2c3f9f8de78e19509411b053d723d2788ebf1f7ba02f04b, + 0, ); } @@ -6983,8 +6963,9 @@ module supra_framework::pbo_delegation_pool { inactive_stake: u64, pending_inactive_stake: u64 ) acquires DelegationPool, BeneficiaryForOperator { - let (actual_active, actual_inactive, actual_pending_inactive) = - get_stake(pool_address, delegator_address); + let (actual_active, actual_inactive, actual_pending_inactive) = get_stake( + pool_address, delegator_address + ); assert!(actual_active == active_stake, actual_active); assert!(actual_inactive == inactive_stake, actual_inactive); assert!( @@ -7003,12 +6984,14 @@ module supra_framework::pbo_delegation_pool { ) acquires DelegationPool { assert_delegation_pool_exists(pool_address); let pool = borrow_global(pool_address); - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, delegator_address); + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, delegator_address + ); assert!(withdrawal_exists == exists, 0); assert!(withdrawal_olc.index == olc, withdrawal_olc.index); - let (withdrawal_inactive, withdrawal_stake) = - get_pending_withdrawal(pool_address, delegator_address); + let (withdrawal_inactive, withdrawal_stake) = get_pending_withdrawal( + pool_address, delegator_address + ); assert!(withdrawal_inactive == inactive, 0); assert!(withdrawal_stake == stake, withdrawal_stake); } @@ -7024,8 +7007,9 @@ module supra_framework::pbo_delegation_pool { let pool = borrow_global(pool_address); assert!(table::contains(&pool.inactive_shares, olc_with_index(olc)) == exists, 0); if (exists) { - let actual_stake = - total_coins(table::borrow(&pool.inactive_shares, olc_with_index(olc))); + let actual_stake = total_coins( + table::borrow(&pool.inactive_shares, olc_with_index(olc)) + ); assert!(actual_stake == stake, actual_stake); } else { assert!(0 == stake, 0); @@ -7060,7 +7044,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -7093,7 +7077,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -7103,14 +7087,7 @@ module supra_framework::pbo_delegation_pool { unlock(delegator, pool_address, 100 * ONE_SUPRA); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_unlock_mutiple_delegators( supra_framework: &signer, validator: &signer, @@ -7135,7 +7112,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -7167,7 +7144,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -7178,14 +7155,7 @@ module supra_framework::pbo_delegation_pool { unlock(delegator1, pool_address, 600 * ONE_SUPRA); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] #[expected_failure(abort_code = 65561, location = Self)] public entry fun test_multiple_users( supra_framework: &signer, @@ -7215,7 +7185,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -7229,14 +7199,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 1000 * ONE_SUPRA, 0, - 0 + 0, ); assert_delegation( delegator1_address, pool_address, 200999999999, 0, - 0 + 0, ); unlock(delegator2, pool_address, 1000 * ONE_SUPRA); assert_delegation( @@ -7244,7 +7214,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 0, 0, - 1000 * ONE_SUPRA + 1000 * ONE_SUPRA, ); unlock(delegator1, pool_address, 1000 * ONE_SUPRA); assert_delegation( @@ -7252,7 +7222,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 101000000001, 0, - 99999999999 + 99999999999, ); unlock(delegator1, pool_address, 1000 * ONE_SUPRA); } @@ -7262,15 +7232,16 @@ module supra_framework::pbo_delegation_pool { owner: &signer, addition_owner: vector
, threshold: u64 ): address { let owner_addr = aptos_std::signer::address_of(owner); - let multisig_addr = - multisig_account::get_next_multisig_account_address(owner_addr); + let multisig_addr = multisig_account::get_next_multisig_account_address( + owner_addr + ); multisig_account::create_with_owners( owner, addition_owner, threshold, vector[], vector[], - 300 + 300, ); multisig_addr } @@ -7302,7 +7273,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -7310,7 +7281,7 @@ module supra_framework::pbo_delegation_pool { &account::create_signer_for_test(multisig), pool_address, @0x010, - @0x0101 + @0x0101, ); } @@ -7338,7 +7309,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); } @@ -7369,12 +7340,11 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); - let new_multisig = generate_multisig_account( - supra_framework, vector[@0x12234], 2 - ); + let new_multisig = + generate_multisig_account(supra_framework, vector[@0x12234], 2); let multisig_signer = account::create_signer_for_test(new_multisig); let validator_address = signer::address_of(validator); @@ -7383,18 +7353,11 @@ module supra_framework::pbo_delegation_pool { &multisig_signer, pool_address, @0x010, - @0x0101 + @0x0101, ); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_lose_shares_small( supra_framework: &signer, validator: &signer, @@ -7419,7 +7382,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -7433,7 +7396,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let index = 0; while (index < 1828) { @@ -7447,7 +7410,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 7933617798152065, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 9913173264836398460, 0, 0, 0); unlock(delegator1, pool_address, 1 * ONE_SUPRA); @@ -7456,14 +7419,14 @@ module supra_framework::pbo_delegation_pool { pool_address, 7933617698152064, 0, - 100000000 + 100000000, ); stake::assert_stake_pool( pool_address, 9913173264736398460, 0, 0, - 100000000 + 100000000, ); unlock(delegator1, pool_address, 1 * ONE_SUPRA); stake::assert_stake_pool( @@ -7471,21 +7434,21 @@ module supra_framework::pbo_delegation_pool { 9913173264636398461, 0, 0, - 199999999 + 199999999, ); assert_delegation( delegator1_address, pool_address, 7933617598152064, 0, - 199999999 + 199999999, ); assert_delegation( delegator2_address, pool_address, 7933617798152065133, 0, - 0 + 0, ); unlock(delegator2, pool_address, 1000 * ONE_SUPRA); assert_delegation( @@ -7493,18 +7456,11 @@ module supra_framework::pbo_delegation_pool { pool_address, 7933617698152065134, 0, - 99999999999 + 99999999999, ); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator1 = @0x010, - delegator2 = @0x020 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator1 = @0x010, delegator2 = @0x020)] public entry fun test_lose_shares_large( supra_framework: &signer, validator: &signer, @@ -7529,7 +7485,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -7543,7 +7499,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let index = 0; while (index < 10) { @@ -7557,7 +7513,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 110462212, 0, - 0 + 0, ); stake::assert_stake_pool(pool_address, 9941599156262803145, 0, 0, 0); unlock(delegator1, pool_address, 1 * ONE_SUPRA); @@ -7566,35 +7522,35 @@ module supra_framework::pbo_delegation_pool { pool_address, 0, 0, - 110462212 + 110462212, ); stake::assert_stake_pool( pool_address, 9941599156152340933, 0, 0, - 110462212 + 110462212, ); stake::assert_stake_pool( pool_address, 9941599156152340933, 0, 0, - 110462212 + 110462212, ); assert_delegation( delegator1_address, pool_address, 0, 0, - 110462212 + 110462212, ); assert_delegation( delegator2_address, pool_address, 9941599128700840588, 0, - 0 + 0, ); unlock(delegator2, pool_address, 1 * ONE_SUPRA); assert_delegation( @@ -7602,7 +7558,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 9941599128600840588, 0, - 100000000 + 100000000, ); } @@ -7633,7 +7589,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let multisig_signer = account::create_signer_for_test(multisig); @@ -7645,21 +7601,21 @@ module supra_framework::pbo_delegation_pool { pool_address, 100 * ONE_SUPRA, 0, - 0 + 0, ); replace_delegator( &multisig_signer, pool_address, @0x010, - new_delegator + new_delegator, ); assert_delegation( new_delegator, pool_address, 100 * ONE_SUPRA, 0, - 0 + 0, ); } @@ -7690,7 +7646,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -7702,7 +7658,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 200 * ONE_SUPRA, 0, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); let multisig_signer = account::create_signer_for_test(multisig); @@ -7711,7 +7667,7 @@ module supra_framework::pbo_delegation_pool { &multisig_signer, pool_address, delegator_address, - new_delegator_address + new_delegator_address, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -7720,11 +7676,11 @@ module supra_framework::pbo_delegation_pool { withdraw( &account::create_signer_for_test(new_delegator_address), pool_address, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); assert!( coin::balance(new_delegator_address) == (100 * ONE_SUPRA) - 1, - 0 + 0, ); } @@ -7756,7 +7712,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); @@ -7768,7 +7724,7 @@ module supra_framework::pbo_delegation_pool { &multisig_signer, pool_address, delegator_address, - new_delegator_address + new_delegator_address, ); unlock(delegator, pool_address, 100 * ONE_SUPRA); @@ -7806,20 +7762,21 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); let multisig_signer = account::create_signer_for_test(multisig); let new_delegator_address = @0x0101; - let new_delegator_address_signer = - &account::create_signer_for_test(new_delegator_address); + let new_delegator_address_signer = &account::create_signer_for_test( + new_delegator_address + ); replace_delegator( &multisig_signer, pool_address, delegator_address, - new_delegator_address + new_delegator_address, ); unlock(new_delegator_address_signer, pool_address, 100 * ONE_SUPRA); @@ -7828,7 +7785,7 @@ module supra_framework::pbo_delegation_pool { pool_address, 200 * ONE_SUPRA, 0, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -7837,18 +7794,11 @@ module supra_framework::pbo_delegation_pool { withdraw(new_delegator_address_signer, pool_address, 100 * ONE_SUPRA); assert!( coin::balance(new_delegator_address) == (100 * ONE_SUPRA) - 1, - 0 + 0, ); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator = @0x010, - funder = @0x999 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010, funder = @0x999)] /// if delegator is not part of one of the principle stake holder, and not funded with locked stake, /// they can unlock/withdraw without restriction public entry fun test_unlock_withdraw_multiple_funded_delegator_not_part_of_principle_stake_success( @@ -7879,30 +7829,32 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); let new_delegator_address = @0x0215; - let new_delegator_address_signer = - account::create_account_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_account_for_test( + new_delegator_address + ); let new_delegator_address2 = @0x0216; - let new_delegator_address_signer2 = - account::create_account_for_test(new_delegator_address2); + let new_delegator_address_signer2 = account::create_account_for_test( + new_delegator_address2 + ); let funder_signer = account::create_account_for_test(funder); stake::mint(&funder_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); fund_delegators_with_stake( &funder_signer, pool_address, vector[new_delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); assert!(coin::balance(funder) == 0, 0); @@ -7918,13 +7870,13 @@ module supra_framework::pbo_delegation_pool { let new_delegator_balance = coin::balance(new_delegator_address); assert!( new_delegator_balance == (30 * ONE_SUPRA) - 1, - new_delegator_balance + new_delegator_balance, ); withdraw(&new_delegator_address_signer2, pool_address, (70 * ONE_SUPRA)); let new_delegator_balance2 = coin::balance(new_delegator_address2); assert!( new_delegator_balance2 == (70 * ONE_SUPRA) - 1, - new_delegator_balance2 + new_delegator_balance2, ); } @@ -7957,27 +7909,28 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS + LOCKUP_CYCLE_SECONDS, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); let new_delegator_address = @0x0215; - let new_delegator_address_signer = - account::create_account_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_account_for_test( + new_delegator_address + ); let funder_signer = account::create_signer_for_test(multisig); let funder = signer::address_of(&funder_signer); stake::mint(&funder_signer, 100 * ONE_SUPRA); stake::mint(&new_delegator_address_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); assert!( coin::balance(new_delegator_address) == (100 * ONE_SUPRA), - 0 + 0, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -7987,7 +7940,7 @@ module supra_framework::pbo_delegation_pool { validator, pool_address, vector[new_delegator_address], - vector[1 * ONE_SUPRA] + vector[1 * ONE_SUPRA], ); } @@ -8019,27 +7972,28 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS + LOCKUP_CYCLE_SECONDS, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); let new_delegator_address = @0x0215; - let new_delegator_address_signer = - account::create_account_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_account_for_test( + new_delegator_address + ); let funder_signer = account::create_signer_for_test(multisig); let funder = signer::address_of(&funder_signer); stake::mint(&funder_signer, 100 * ONE_SUPRA); stake::mint(&new_delegator_address_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); assert!( coin::balance(new_delegator_address) == (100 * ONE_SUPRA), - 0 + 0, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -8049,7 +8003,7 @@ module supra_framework::pbo_delegation_pool { &funder_signer, pool_address, vector[new_delegator_address], - vector[0] + vector[0], ); { // if the locked stake is zero, assert that it does not get added to `principle_stake` table @@ -8068,18 +8022,11 @@ module supra_framework::pbo_delegation_pool { let new_delegator_balance = coin::balance(new_delegator_address); assert!( new_delegator_balance == (100 * ONE_SUPRA) - 1, - new_delegator_balance + new_delegator_balance, ); } - #[ - test( - supra_framework = @supra_framework, - validator = @0x123, - delegator = @0x010, - funder = @0x999 - ) - ] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010, funder = @0x999)] /// if a single delegator was not part of one of the principle stake holder, and not funded with locked stake, /// they can unlock/withdraw without restriction public entry fun test_unlock_withdraw_funded_delegator_not_part_of_principle_stake_success( @@ -8110,27 +8057,28 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); let new_delegator_address = @0x0215; - let new_delegator_address_signer = - account::create_account_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_account_for_test( + new_delegator_address + ); let funder_signer = account::create_account_for_test(funder); stake::mint(&funder_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); fund_delegator_stake( &funder_signer, pool_address, new_delegator_address, - 100 * ONE_SUPRA + 100 * ONE_SUPRA, ); assert!(coin::balance(funder) == 0, 0); @@ -8145,7 +8093,7 @@ module supra_framework::pbo_delegation_pool { let new_delegator_balance = coin::balance(new_delegator_address); assert!( new_delegator_balance == (100 * ONE_SUPRA) - 1, - new_delegator_balance + new_delegator_balance, ); } @@ -8176,20 +8124,21 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - 12 + 12, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); let new_delegator_address = @0x0215; - let new_delegator_address_signer = - account::create_account_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_account_for_test( + new_delegator_address + ); stake::mint(&new_delegator_address_signer, 100 * ONE_SUPRA); assert!( coin::balance(new_delegator_address) == (100 * ONE_SUPRA), - 0 + 0, ); add_stake(&new_delegator_address_signer, pool_address, 100 * ONE_SUPRA); @@ -8203,7 +8152,7 @@ module supra_framework::pbo_delegation_pool { withdraw(&new_delegator_address_signer, pool_address, (100 * ONE_SUPRA)); assert!( coin::balance(new_delegator_address) == (100 * ONE_SUPRA) - 1, - 0 + 0, ); } @@ -8236,7 +8185,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let funder_signer = account::create_signer_for_test(multisig); let funder = signer::address_of(&funder_signer); @@ -8250,7 +8199,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let new_delegator_address = @0x0215; @@ -8260,23 +8209,23 @@ module supra_framework::pbo_delegation_pool { stake::mint(&funder_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); fund_delegators_with_locked_stake( &funder_signer, pool_address, vector[new_delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); assert!(coin::balance(funder) == 0, 0); assert!( get_principle_stake(new_delegator_address, pool_address) == 30 * ONE_SUPRA, - 9 + 9, ); assert!( get_principle_stake(new_delegator_address2, pool_address) == 70 * ONE_SUPRA, - 9 + 9, ); // 3 month @@ -8316,7 +8265,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let funder_signer = account::create_signer_for_test(multisig); let funder = signer::address_of(&funder_signer); @@ -8330,7 +8279,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let new_delegator_address = @0x0215; @@ -8339,30 +8288,30 @@ module supra_framework::pbo_delegation_pool { stake::mint(&funder_signer, 200 * ONE_SUPRA); assert!( coin::balance(funder) == (200 * ONE_SUPRA), - 0 + 0, ); fund_delegators_with_stake( &funder_signer, pool_address, vector[new_delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); fund_delegators_with_locked_stake( &funder_signer, pool_address, vector[new_delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); assert!(coin::balance(funder) == 0, 0); assert!( get_principle_stake(new_delegator_address, pool_address) == 30 * ONE_SUPRA, - 99 + 99, ); assert!( get_principle_stake(new_delegator_address2, pool_address) == 70 * ONE_SUPRA, - 99 + 99, ); let (amount1, _, _) = get_stake(pool_address, new_delegator_address); let (amount2, _, _) = get_stake(pool_address, new_delegator_address2); @@ -8377,8 +8326,9 @@ module supra_framework::pbo_delegation_pool { timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let new_delegator_address_signer = - account::create_signer_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_signer_for_test( + new_delegator_address + ); unlock(&new_delegator_address_signer, pool_address, 30 * ONE_SUPRA); unlock(&new_delegator_address_signer, pool_address, 1 * ONE_SUPRA); } @@ -8410,7 +8360,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let funder_signer = account::create_signer_for_test(multisig); let funder = signer::address_of(&funder_signer); @@ -8424,7 +8374,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let new_delegator_address = @0x0215; @@ -8433,21 +8383,21 @@ module supra_framework::pbo_delegation_pool { stake::mint(&funder_signer, 200 * ONE_SUPRA); assert!( coin::balance(funder) == (200 * ONE_SUPRA), - 0 + 0, ); fund_delegators_with_stake( &funder_signer, pool_address, vector[new_delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); fund_delegators_with_locked_stake( &funder_signer, pool_address, vector[new_delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); assert!(coin::balance(funder) == 0, 0); @@ -8459,8 +8409,9 @@ module supra_framework::pbo_delegation_pool { timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let new_delegator_address_signer = - account::create_signer_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_signer_for_test( + new_delegator_address + ); unlock(&new_delegator_address_signer, pool_address, 30 * ONE_SUPRA); unlock(&new_delegator_address_signer, pool_address, 2 * ONE_SUPRA); } @@ -8493,7 +8444,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -8505,7 +8456,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let new_delegator_address2 = @0x0216; @@ -8514,14 +8465,14 @@ module supra_framework::pbo_delegation_pool { stake::mint(&funder_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); //fund existing delegator_address with locked state, this should still work fund_delegators_with_locked_stake( &funder_signer, pool_address, vector[delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); assert!(coin::balance(funder) == 0, 0); @@ -8566,7 +8517,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -8578,7 +8529,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let new_delegator_address2 = @0x0216; @@ -8587,14 +8538,14 @@ module supra_framework::pbo_delegation_pool { stake::mint(&funder_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); //fund existing delegator_address with locked state, this should still work fund_delegators_with_locked_stake( &funder_signer, pool_address, vector[delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); assert!(coin::balance(funder) == 0, 0); //Check that funded delegator was indeed added as a principle stake holder @@ -8604,12 +8555,11 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); let (active_amount, _, _) = get_stake(pool_address, new_delegator_address2); assert!(active_amount == 70 * ONE_SUPRA, active_amount); - let d2_principle_stake = get_principle_stake( - new_delegator_address2, pool_address - ); + let d2_principle_stake = + get_principle_stake(new_delegator_address2, pool_address); assert!( active_amount == d2_principle_stake, - active_amount - d2_principle_stake + active_amount - d2_principle_stake, ); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); @@ -8624,8 +8574,9 @@ module supra_framework::pbo_delegation_pool { timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); // 30% of 130, so 39*ONE_SUPRA should be unlockable out of which 13 were already unlocked earlier - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, 26 * ONE_SUPRA); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, 26 * ONE_SUPRA + ); let amount = cached_unlockable_balance(delegator_address, pool_address); assert!(unlock_coin, amount); @@ -8659,7 +8610,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -8671,7 +8622,7 @@ module supra_framework::pbo_delegation_pool { fixed_point64::create_from_rational(1, 100), one_year_in_secs, reward_period_start_time_in_sec, - fixed_point64::create_from_rational(0, 100) + fixed_point64::create_from_rational(0, 100), ); let new_delegator_address2 = @0x0216; @@ -8680,14 +8631,14 @@ module supra_framework::pbo_delegation_pool { stake::mint(&funder_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); //fund existing delegator_address with locked state, this should still work fund_delegators_with_locked_stake( &funder_signer, pool_address, vector[delegator_address, new_delegator_address2], - vector[30 * ONE_SUPRA, 70 * ONE_SUPRA] + vector[30 * ONE_SUPRA, 70 * ONE_SUPRA], ); assert!(coin::balance(funder) == 0, 0); @@ -8742,7 +8693,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -8756,12 +8707,11 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 10); } @@ -8795,7 +8745,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -8815,88 +8765,82 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 13); // after 7 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (70 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 14); // after 8 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (80 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (80 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 15); // after 9 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (90 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (90 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 16); // after 10 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (100 * ONE_SUPRA) - 10 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (100 * ONE_SUPRA) - 10, + ); assert!(unlock_coin, 17); // after 11 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, 100 * ONE_SUPRA); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, 100 * ONE_SUPRA + ); assert!(unlock_coin, 18); } - + #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] #[expected_failure(abort_code = 42, location = Self)] /// say unlocking schedule is 3 month cliff, monthly unlocking of (2,3,1) tange and principle stake is 100 coins then @@ -8928,7 +8872,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -8948,11 +8892,11 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // Delay unlock by 3 months - let multisig_signer = account::create_signer_for_test(multisig); + let multisig_signer = account::create_signer_for_test(multisig); admin_increase_last_unlock_period(&multisig_signer, pool_address, 3); - } + } - #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] + #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] /// say unlocking schedule is 3 month cliff, monthly unlocking of (2,3,1) tange and principle stake is 100 coins then /// at the end of 3 months, one can't unlock there principal stacke /// after 4 months only 90 should remain locked @@ -8983,7 +8927,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9003,107 +8947,101 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); - - + // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // Delay unlock by 3 months - let multisig_signer = account::create_signer_for_test(multisig); + let multisig_signer = account::create_signer_for_test(multisig); admin_increase_last_unlock_period(&multisig_signer, pool_address, 3); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 13); // after 7 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 14); // after 8 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 15); // after 9 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 16); // after 10 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (70 * ONE_SUPRA) - 10 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) - 10, + ); assert!(unlock_coin, 17); // after 11 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, 80 * ONE_SUPRA-9); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, 80 * ONE_SUPRA - 9 + ); assert!(unlock_coin, 18); - + // after 14 months - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS*3); + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS * 3); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, 100 * ONE_SUPRA); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, 100 * ONE_SUPRA + ); assert!(unlock_coin, 18); - + // after 20 months - timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS*6); + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS * 6); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, 100 * ONE_SUPRA); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, 100 * ONE_SUPRA + ); assert!(unlock_coin, 18); - } #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] @@ -9134,7 +9072,7 @@ module supra_framework::pbo_delegation_pool { vector[1], 2, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9168,18 +9106,18 @@ module supra_framework::pbo_delegation_pool { timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, (100 * ONE_SUPRA)); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, (100 * ONE_SUPRA) + ); assert!(unlock_coin, 11); - let unlock_schedule = - borrow_global(pool_address).principle_unlock_schedule; + let unlock_schedule = borrow_global(pool_address).principle_unlock_schedule; let cfraction_upperbound = fixed_point64::create_from_rational(3, 2); assert!( fixed_point64::less( unlock_schedule.cumulative_unlocked_fraction, cfraction_upperbound ), - unlock_schedule.last_unlock_period + unlock_schedule.last_unlock_period, ); } @@ -9210,7 +9148,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9229,12 +9167,11 @@ module supra_framework::pbo_delegation_pool { timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -9265,7 +9202,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9285,23 +9222,21 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -9332,7 +9267,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9352,34 +9287,31 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -9410,7 +9342,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9430,45 +9362,41 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 13); // after 7 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (70 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -9499,7 +9427,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9519,56 +9447,51 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 13); // after 7 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (70 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 14); // after 8 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (80 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (80 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -9599,7 +9522,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9619,67 +9542,61 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 13); // after 7 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (70 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 14); // after 8 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (80 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (80 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 15); // after 9 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (90 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (90 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -9710,7 +9627,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9730,78 +9647,71 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 13); // after 7 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (70 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 14); // after 8 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (80 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (80 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 15); // after 9 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (90 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (90 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 16); // after 10 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (100 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (100 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -9834,7 +9744,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9853,8 +9763,9 @@ module supra_framework::pbo_delegation_pool { timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let (_, old_stime, _old_duration, old_last_unlock, old_cfraction) = - get_unlock_schedule(pool_address); + let (_, old_stime, _old_duration, old_last_unlock, old_cfraction) = get_unlock_schedule( + pool_address + ); // Assert that `get_unlock_schedule` is returning expected values assert!(old_stime == principle_lockup_time, old_stime); assert!(old_last_unlock == 0, old_last_unlock); @@ -9868,11 +9779,196 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time / 3, - LOCKUP_CYCLE_SECONDS + LOCKUP_CYCLE_SECONDS, ); } + // Test that after unlock schedule change, one is able to unlock as per + // new schedule but NOT as per old schedule final failure when + // someone other than admin tries to change the schedule + #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] + #[expected_failure(abort_code = 327716, location = Self)] + public entry fun test_change_unlock_schedule_unchecked( + supra_framework: &signer, validator: &signer, delegator: &signer + ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { + initialize_for_test(supra_framework); + account::create_account_for_test(signer::address_of(validator)); + let delegator_address = signer::address_of(delegator); + let delegator_address_vec = vector[delegator_address]; + let principle_stake = vector[100 * ONE_SUPRA]; + let coin = stake::mint_coins(100 * ONE_SUPRA); + let principle_lockup_time = 7776000; // 3 month cliff + let multisig = generate_multisig_account(validator, vector[@0x12134], 2); + + initialize_test_validator( + validator, + 0, + true, + true, + 0, + delegator_address_vec, + principle_stake, + coin, + option::some(multisig), + vector[5], + 100, + principle_lockup_time, + LOCKUP_CYCLE_SECONDS, // monthly unlocking + ); + let validator_address = signer::address_of(validator); + let pool_address = get_owned_pool_address(validator_address); + + // after 2 month unlock reward + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // 3 month + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + // after 12 months + timestamp::fast_forward_seconds(9 * LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, (45 * ONE_SUPRA) - 9 + ); + let (_, old_stime, _old_duration, old_last_unlock, old_cfraction) = get_unlock_schedule( + pool_address + ); + assert!(unlock_coin, 11); + // Assert that `get_unlock_schedule` is returning expected values + assert!(old_stime == principle_lockup_time, old_stime); + // 9 monthly unlocks have passed total 12 months including 3 month cliff + assert!(old_last_unlock == 9, old_last_unlock); + let precision_tolerance = fixed_point64::create_from_rational(1, 1000000000); + let tmp_fraction = fixed_point64::create_from_rational(9 * 5, 100); + let old_cfraction_raw = fixed_point64::get_raw_value(old_cfraction); + let tmp_cfraction_raw = fixed_point64::get_raw_value(tmp_fraction); + let diff = + fixed_point64::sub( + fixed_point64::max(old_cfraction, tmp_fraction), + fixed_point64::min(old_cfraction, tmp_fraction), + ); + //assert cumulative fraction is within expected tolerance + assert!(fixed_point64::less_or_equal(diff, precision_tolerance), 91); + + // Change schedule to increase last unlock period by 2 + admin_increase_last_unlock_period( + &account::create_signer_for_test(multisig), + pool_address, + 2, + ); + + let (_, new_stime, _new_duration, new_last_unlock, new_cfraction) = get_unlock_schedule( + pool_address + ); + // assert start time unchanged + assert!( + new_stime == principle_lockup_time, new_stime + ); + // assert last unlock period increased + assert!(new_last_unlock == 11, new_last_unlock); + // assert cumulative fraction unchanged + assert!( + fixed_point64::get_raw_value(new_cfraction) == fixed_point64::get_raw_value( + old_cfraction + ), + 99, + ); + + //Must not be able to unlock next month since unlock period was increased + // total 13 months including 3 month cliff, 10th unlock must not happen since last unlock period increased to 11 + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, (46 * ONE_SUPRA) - 9 + ); + assert!(!unlock_coin, 13); + + // total 14 months including 3 month cliff + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + // update schedule to 3 months and 15% unlock instead of 5% + // update last unlock period to 3, to indicate 3 quarters of unlock have passed. + update_unlocking_schedule_unchecked( + &account::create_signer_for_test(multisig), + pool_address, + vector[15], + 100, + principle_lockup_time, + LOCKUP_CYCLE_SECONDS * 3, + 3, + ); + + //assert cumulative fraction unchanged and last unlock updated + let (_, new_stime2, _new_duration2, new_last_unlock2, new_cfraction2) = get_unlock_schedule( + pool_address + ); + assert!( + fixed_point64::get_raw_value(new_cfraction2) == fixed_point64::get_raw_value( + new_cfraction + ), + 99, + ); + assert!(new_last_unlock2 == 3, new_last_unlock2); + + // total 15 months including 3 month cliff, 4 quarters for unlock has passed + // assert this time 15% additional unlock possible + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); + assert!(unlock_coin, 15); + + // assert that next month unlock would not happen since unlock changed to quarterly schedule + timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (61 * ONE_SUPRA) - 9, + ); + assert!(!unlock_coin, 15); + + timestamp::fast_forward_seconds(2 * LOCKUP_CYCLE_SECONDS); + end_aptos_epoch(); + // total 18 months including 3 month cliff, 5 quarters for unlock has passed but last + // unlock period should be 4 until can_principle_unlock is called + let (_, new_stime3, _new_duration3, new_last_unlock3, new_cfraction3) = get_unlock_schedule( + pool_address + ); + assert!(new_last_unlock3 == 4, new_last_unlock3); + + // additional 15% unlock should be possible now + unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (75 * ONE_SUPRA) - 9, + ); + assert!(unlock_coin, 16); + // assert that last unlock period is now 5 + let (_, new_stime4, _new_duration4, new_last_unlock4, new_cfraction4) = get_unlock_schedule( + pool_address + ); + assert!(new_last_unlock4 == 5, new_last_unlock4); + update_unlocking_schedule_unchecked( + delegator, + pool_address, + vector[20], + 100, + principle_lockup_time, + LOCKUP_CYCLE_SECONDS * 3, + 9, + ); + } + // Test that after unlock schedule change, one is able to unlock as per // new schedule but NOT as per old schedule #[test(supra_framework = @supra_framework, validator = @0x123, delegator = @0x010)] @@ -9902,7 +9998,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -9921,8 +10017,9 @@ module supra_framework::pbo_delegation_pool { timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let (_, old_stime, _old_duration, old_last_unlock, old_cfraction) = - get_unlock_schedule(pool_address); + let (_, old_stime, _old_duration, old_last_unlock, old_cfraction) = get_unlock_schedule( + pool_address + ); // Assert that `get_unlock_schedule` is returning expected values assert!(old_stime == principle_lockup_time, old_stime); assert!(old_last_unlock == 0, old_last_unlock); @@ -9934,24 +10031,24 @@ module supra_framework::pbo_delegation_pool { vector[1], 10, principle_lockup_time / 3, - LOCKUP_CYCLE_SECONDS + LOCKUP_CYCLE_SECONDS, ); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let (_, new_stime, _new_duration, new_last_unlock, new_cfraction) = - get_unlock_schedule(pool_address); + let (_, new_stime, _new_duration, new_last_unlock, new_cfraction) = get_unlock_schedule( + pool_address + ); // Assert that `get_unlock_schedule` is returning expected values assert!( new_stime == principle_lockup_time / 3, - new_stime + new_stime, ); assert!(new_last_unlock == 0, new_last_unlock); assert!(fixed_point64::is_zero(new_cfraction), 99); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (30 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (30 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months @@ -9960,13 +10057,13 @@ module supra_framework::pbo_delegation_pool { unlock_coin = can_principle_unlock( delegator_address, pool_address, - (40 * ONE_SUPRA) - 9 + (40 * ONE_SUPRA) - 9, ); assert!(unlock_coin, 12); unlock_coin = can_principle_unlock( delegator_address, pool_address, - (50 * ONE_SUPRA) - 9 + (50 * ONE_SUPRA) - 9, ); assert!(unlock_coin, 13); @@ -9999,7 +10096,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -10019,89 +10116,81 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); // after 6 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (60 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (60 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 13); // after 7 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (70 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (70 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 14); // after 8 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (80 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (80 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 15); // after 9 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (90 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (90 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 16); // after 10 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (100 * ONE_SUPRA) - 10 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (100 * ONE_SUPRA) - 10, + ); assert!(unlock_coin, 17); // after 11 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (100 * ONE_SUPRA) + 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (100 * ONE_SUPRA) + 1, + ); assert!(unlock_coin, 20); } @@ -10132,7 +10221,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -10152,23 +10241,21 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // It's acceptable to round off 9 because this coin will remain locked and won't be transferred anywhere. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (20 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (20 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (50 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (50 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -10179,8 +10266,9 @@ module supra_framework::pbo_delegation_pool { // after 11 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, 100 * ONE_SUPRA); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, 100 * ONE_SUPRA + ); assert!(unlock_coin, 18); } @@ -10211,7 +10299,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -10231,23 +10319,21 @@ module supra_framework::pbo_delegation_pool { end_aptos_epoch(); // After three mounth cliff and one extra mouth, 2/10 of the principle stake (113) = 22.6 can be unlocked. minus 9 for rounding off. - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (22 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (22 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 11); // after 5 months, 5/10 of the principle stake (113) = 56.5 can be unlocked. minus 9 for rounding off. timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (55 * ONE_SUPRA) - 9 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (55 * ONE_SUPRA) - 9, + ); assert!(unlock_coin, 12); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); @@ -10258,8 +10344,9 @@ module supra_framework::pbo_delegation_pool { // after 11 months timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_aptos_epoch(); - let unlock_coin = - can_principle_unlock(delegator_address, pool_address, 113 * ONE_SUPRA); + let unlock_coin = can_principle_unlock( + delegator_address, pool_address, 113 * ONE_SUPRA + ); assert!(unlock_coin, 18); } @@ -10290,7 +10377,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -10302,12 +10389,11 @@ module supra_framework::pbo_delegation_pool { // After cliff, 5/10 of the principle stake (1000) = 500 can be unlocked. timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS * 2); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (500 * ONE_SUPRA) - 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (500 * ONE_SUPRA) - 1, + ); assert!(unlock_coin, 11); } @@ -10338,7 +10424,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -10350,12 +10436,11 @@ module supra_framework::pbo_delegation_pool { // After cliff, 7/10 of the principle stake (1000) = 700 can be unlocked. timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS * 4); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (700 * ONE_SUPRA) - 1 - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (700 * ONE_SUPRA) - 1, + ); assert!(unlock_coin, 11); } @@ -10386,7 +10471,7 @@ module supra_framework::pbo_delegation_pool { vector[2, 3, 1], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS // monthly unlocking + LOCKUP_CYCLE_SECONDS, // monthly unlocking ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); @@ -10398,12 +10483,11 @@ module supra_framework::pbo_delegation_pool { // After cliff, all of the principle stake (1000) can be unlocked. timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS * 8); - let unlock_coin = - can_principle_unlock( - delegator_address, - pool_address, - (1000 * ONE_SUPRA) - ); + let unlock_coin = can_principle_unlock( + delegator_address, + pool_address, + (1000 * ONE_SUPRA), + ); assert!(unlock_coin, 11); } @@ -10433,27 +10517,28 @@ module supra_framework::pbo_delegation_pool { vector[2, 2, 3], 10, principle_lockup_time, - LOCKUP_CYCLE_SECONDS + LOCKUP_CYCLE_SECONDS, ); let validator_address = signer::address_of(validator); let pool_address = get_owned_pool_address(validator_address); let new_delegator_address = @0x0215; - let new_delegator_address_signer = - account::create_account_for_test(new_delegator_address); + let new_delegator_address_signer = account::create_account_for_test( + new_delegator_address + ); let funder_signer = account::create_signer_for_test(multisig); let funder = signer::address_of(&funder_signer); stake::mint(&funder_signer, 100 * ONE_SUPRA); stake::mint(&new_delegator_address_signer, 100 * ONE_SUPRA); assert!( coin::balance(funder) == (100 * ONE_SUPRA), - 0 + 0, ); assert!( coin::balance(new_delegator_address) == (100 * ONE_SUPRA), - 0 + 0, ); add_stake(&new_delegator_address_signer, pool_address, 100 * ONE_SUPRA); @@ -10467,7 +10552,7 @@ module supra_framework::pbo_delegation_pool { &funder_signer, pool_address, vector[new_delegator_address], - vector[1 * ONE_SUPRA] + vector[1 * ONE_SUPRA], ); // Ensure that its stake is not subject to the pool vesting schedule. assert!(!is_principle_stakeholder(new_delegator_address, pool_address), 1); @@ -10477,7 +10562,7 @@ module supra_framework::pbo_delegation_pool { &funder_signer, pool_address, vector[new_delegator_address], - vector[1 * ONE_SUPRA] + vector[1 * ONE_SUPRA], ); // Ensure that its stake is now subject to the pool vesting schedule. assert!(is_principle_stakeholder(new_delegator_address, pool_address), 0); @@ -10491,17 +10576,15 @@ module supra_framework::pbo_delegation_pool { let delegator_allocation = 10 * ONE_SUPRA; let half_delegator_allocation = delegator_allocation / 2; // A rounding error of 1 Quant is introduced by `unlock`. - let half_delegator_allocation_with_rounding_error = half_delegator_allocation - - 1; - let delegator_allocation_after_rounding_error = - half_delegator_allocation + half_delegator_allocation_with_rounding_error; + let half_delegator_allocation_with_rounding_error = half_delegator_allocation - 1; + let delegator_allocation_after_rounding_error = half_delegator_allocation + half_delegator_allocation_with_rounding_error; // Fund another delegator. fund_delegators_with_stake( &funder_signer, pool_address, vector[delegator], - vector[delegator_allocation] + vector[delegator_allocation], ); // End the current lockup cycle to ensure that the stake fee that is deducted when the stake @@ -10523,7 +10606,7 @@ module supra_framework::pbo_delegation_pool { assert!(inactive == 0, inactive); assert!( pending_inactive == half_delegator_allocation_with_rounding_error, - pending_inactive + pending_inactive, ); // Attempt to lock the full allocation, which should cause the `pending_inactive` allocation @@ -10532,7 +10615,7 @@ module supra_framework::pbo_delegation_pool { &funder_signer, pool_address, vector[delegator], - vector[delegator_allocation_after_rounding_error] + vector[delegator_allocation_after_rounding_error], ); // Ensure that the entire allocation is marked as active again. @@ -10556,17 +10639,16 @@ module supra_framework::pbo_delegation_pool { let delegator_stake = delegator_allocation_after_rounding_error + epoch_reward; // The amount of stake withheld due to the withdrawal and restaking process used to // recover `inactive` stake. - let add_stake_fee = - get_add_stake_fee( - pool_address, half_delegator_allocation + half_epoch_reward - ); + let add_stake_fee = get_add_stake_fee( + pool_address, half_delegator_allocation + half_epoch_reward + ); // Fund another delegator. fund_delegators_with_stake( &funder_signer, pool_address, vector[delegator], - vector[delegator_allocation] + vector[delegator_allocation], ); // End the current lockup cycle to ensure that the stake fee that is deducted when the stake @@ -10590,14 +10672,13 @@ module supra_framework::pbo_delegation_pool { let (active, inactive, pending_inactive) = get_stake(pool_address, delegator); assert!( active == half_delegator_allocation + half_epoch_reward, - active + active, ); // Another rounding error is introduced by the second `unlock`. assert!( - inactive - == half_delegator_allocation_with_rounding_error + half_epoch_reward - - 1, - inactive + inactive == half_delegator_allocation_with_rounding_error + half_epoch_reward + - 1, + inactive, ); assert!(pending_inactive == 0, pending_inactive); @@ -10607,7 +10688,7 @@ module supra_framework::pbo_delegation_pool { &funder_signer, pool_address, vector[delegator], - vector[delegator_stake] + vector[delegator_stake], ); // Ensure that the entire allocation is marked as active again. The fee for adding stake @@ -10635,13 +10716,12 @@ module supra_framework::pbo_delegation_pool { &funder_signer, pool_address, vector[delegator], - vector[delegator_allocation] + vector[delegator_allocation], ); // Calculate the fee for the newly added amount. let add_stake_fee = get_add_stake_fee(pool_address, delegator_allocation); - let expected_total_stake = - expected_active_stake + delegator_allocation - add_stake_fee; + let expected_total_stake = expected_active_stake + delegator_allocation - add_stake_fee; // Ensure that the entire allocation is marked as active. let (active, inactive, pending_inactive) = get_stake(pool_address, delegator); @@ -10655,7 +10735,7 @@ module supra_framework::pbo_delegation_pool { &funder_signer, pool_address, vector[delegator], - vector[more_than_allocated_stake] + vector[more_than_allocated_stake], ); // Ensure that the delegator's `principle_stake` has been updated. @@ -10663,7 +10743,7 @@ module supra_framework::pbo_delegation_pool { let delegator_principle_stake = *table::borrow(&pool.principle_stake, delegator); assert!( delegator_principle_stake == more_than_allocated_stake, - delegator_principle_stake + delegator_principle_stake, ); } } diff --git a/aptos-move/framework/supra-framework/sources/vesting_without_staking.move b/aptos-move/framework/supra-framework/sources/vesting_without_staking.move index d94330ea2a0..226a49acb93 100644 --- a/aptos-move/framework/supra-framework/sources/vesting_without_staking.move +++ b/aptos-move/framework/supra-framework/sources/vesting_without_staking.move @@ -62,6 +62,8 @@ module supra_framework::vesting_without_staking { const ESHAREHOLDER_NOT_EXIST: u64 = 18; /// Invalid vesting schedule parameter const EINVALID_VESTING_SCHEDULE: u64 = 19; + /// Invalid vesting delay parameter + const EINVALID_VESTING_DELAY: u64 = 20; /// Vesting contract states. /// Vesting contract is active and distributions can be made. @@ -209,11 +211,10 @@ module supra_framework::vesting_without_staking { vesting_contract_address: address, shareholder_address: address ): (u64, u64, u64) acquires VestingContract { assert_vesting_contract_exists(vesting_contract_address); - let vesting_record = - simple_map::borrow( - &borrow_global(vesting_contract_address).shareholders, - &shareholder_address, - ); + let vesting_record = simple_map::borrow( + &borrow_global(vesting_contract_address).shareholders, + &shareholder_address, + ); ( vesting_record.init_amount, vesting_record.left_amount, @@ -441,20 +442,23 @@ module supra_framework::vesting_without_staking { // Initialize the vesting contract in a new resource account. This allows the same admin to create multiple // pools. - let (contract_signer, contract_signer_cap) = - create_vesting_contract_account(admin, contract_creation_seed); + let (contract_signer, contract_signer_cap) = create_vesting_contract_account( + admin, contract_creation_seed + ); let contract_signer_address = signer::address_of(&contract_signer); let schedule = vector::map_ref( &vesting_numerators, |numerator| { - let event = - fixed_point32::create_from_rational(*numerator, vesting_denominator); + let event = fixed_point32::create_from_rational( + *numerator, vesting_denominator + ); event }, ); - let vesting_schedule = - create_vesting_schedule(schedule, start_timestamp_secs, period_duration); + let vesting_schedule = create_vesting_schedule( + schedule, start_timestamp_secs, period_duration + ); let shareholders_map = simple_map::create(); let grant_amount = 0; vector::for_each_reverse( @@ -568,8 +572,9 @@ module supra_framework::vesting_without_staking { // Initialize the vesting contract in a new resource account. This allows the same admin to create multiple // pools. - let (contract_signer, contract_signer_cap) = - create_vesting_contract_account(admin, contract_creation_seed); + let (contract_signer, contract_signer_cap) = create_vesting_contract_account( + admin, contract_creation_seed + ); let contract_signer_address = signer::address_of(&contract_signer); coin::deposit(contract_signer_address, grant); @@ -645,10 +650,9 @@ module supra_framework::vesting_without_staking { return }; - let vesting_record = - simple_map::borrow_mut( - &mut vesting_contract.shareholders, &shareholder_address - ); + let vesting_record = simple_map::borrow_mut( + &mut vesting_contract.shareholders, &shareholder_address + ); let signer_cap = &vesting_contract.signer_cap; // Check if the next vested period has already passed. If not, short-circuit since there's nothing to vest. @@ -656,9 +660,9 @@ module supra_framework::vesting_without_staking { let schedule = &vesting_schedule.schedule; let last_vested_period = vesting_record.last_vested_period; let next_period_to_vest = last_vested_period + 1; - let last_completed_period = - (timestamp::now_seconds() - vesting_schedule.start_timestamp_secs) / vesting_schedule - .period_duration; + let last_completed_period = ( + timestamp::now_seconds() - vesting_schedule.start_timestamp_secs + ) / vesting_schedule.period_duration; // Index is 0-based while period is 1-based so we need to subtract 1. let one = fixed_point32::create_from_rational(1, 1); @@ -683,9 +687,10 @@ module supra_framework::vesting_without_staking { let final_fraction = *vector::borrow(schedule, vector::length(schedule) - 1); // Determine how many periods is needed based on the left_amount periods_fast_forward = last_completed_period - next_period_to_vest + 1; - let added_fraction = fixed_point32::multiply_u64_return_fixpoint32( - periods_fast_forward, final_fraction - ); + let added_fraction = + fixed_point32::multiply_u64_return_fixpoint32( + periods_fast_forward, final_fraction + ); // If the added_fraction is greater than or equal to the left_amount, then we can vest all the left_amount total_vesting_fraction = fixed_point32::add( total_vesting_fraction, added_fraction @@ -695,12 +700,13 @@ module supra_framework::vesting_without_staking { // Make sure the total vesting fraction is not greater than 1. total_vesting_fraction = fixed_point32::min(total_vesting_fraction, one); // We don't need to check vesting_record.left_amount > 0 because vest_transfer will handle that. - let transfer_happened = vest_transfer( - vesting_record, - signer_cap, - beneficiary, - total_vesting_fraction, - ); + let transfer_happened = + vest_transfer( + vesting_record, + signer_cap, + beneficiary, + total_vesting_fraction, + ); //If no amount was transferred DO NOT advance last_vested_period in the vesting record // This check is needed because if the fraction is too low, `vesting_record.init_amount * vesting_fraction` // may be 0. By not advancing, we allow for the possibility for `vesting_fraction` to become large enough @@ -733,11 +739,10 @@ module supra_framework::vesting_without_staking { let vesting_signer = account::create_signer_with_capability(signer_cap); //amount to be transfer is minimum of what is left and vesting fraction due of init_amount - let amount = - min( - vesting_record.left_amount, - fixed_point32::multiply_u64(vesting_record.init_amount, vesting_fraction), - ); + let amount = min( + vesting_record.left_amount, + fixed_point32::multiply_u64(vesting_record.init_amount, vesting_fraction), + ); if (amount > 0) { //update left_amount for the shareholder vesting_record.left_amount = vesting_record.left_amount - amount; @@ -746,6 +751,30 @@ module supra_framework::vesting_without_staking { } else { false } } + // CAUTION: This function will delay all shareholders' vesting by `delay_periods`. To be called + // by multisig admin only with extreme caution. + public entry fun admin_delay_vesting( + admin: &signer, contract_address: address, delay_periods: u64 + ) acquires VestingContract { + assert_active_vesting_contract(contract_address); + let vesting_contract = borrow_global_mut(contract_address); + verify_admin(admin, vesting_contract); + + assert!(delay_periods > 0, error::invalid_argument(EINVALID_VESTING_DELAY)); + let (shareholders, vrecords) = simple_map::to_vec_pair( + vesting_contract.shareholders + ); + vector::zip_mut( + &mut shareholders, + &mut vrecords, + |_s, vrecord| { + let mrecord: &mut VestingRecord = vrecord; + mrecord.last_vested_period = mrecord.last_vested_period + delay_periods; + }, + ); + vesting_contract.shareholders = simple_map::new_from(shareholders, vrecords); + } + public entry fun set_vesting_schedule( admin: &signer, contract_address: address, @@ -775,9 +804,8 @@ module supra_framework::vesting_without_staking { &mut values, |shareholder, srecord| { let msrecord: &mut VestingRecord = srecord; - let new_last_vested_period = ( - msrecord.last_vested_period * old_period_duration - ) / period_duration; + let new_last_vested_period = + (msrecord.last_vested_period * old_period_duration) / period_duration; msrecord.last_vested_period = new_last_vested_period; }, ); @@ -806,8 +834,9 @@ module supra_framework::vesting_without_staking { let vesting_contract = borrow_global_mut(contract_address); verify_admin(admin, vesting_contract); let vesting_signer = get_vesting_account_signer_internal(vesting_contract); - let shareholder_amount = - simple_map::borrow(&vesting_contract.shareholders, &shareholder_address).left_amount; + let shareholder_amount = simple_map::borrow( + &vesting_contract.shareholders, &shareholder_address + ).left_amount; coin::transfer( &vesting_signer, vesting_contract.withdrawal_address, shareholder_amount ); @@ -822,16 +851,18 @@ module supra_framework::vesting_without_staking { // remove `shareholder_address`` from `vesting_contract.shareholders` let shareholders = &mut vesting_contract.shareholders; - let (_, shareholders_vesting) = - simple_map::remove(shareholders, &shareholder_address); + let (_, shareholders_vesting) = simple_map::remove( + shareholders, &shareholder_address + ); // remove `shareholder_address` from `vesting_contract.beneficiaries` let beneficiary = option::none(); let shareholder_beneficiaries = &mut vesting_contract.beneficiaries; // Not all shareholders have their beneficiaries, so before removing them, we need to check if the beneficiary exists if (simple_map::contains_key(shareholder_beneficiaries, &shareholder_address)) { - let (_, shareholder_baneficiary) = - simple_map::remove(shareholder_beneficiaries, &shareholder_address); + let (_, shareholder_baneficiary) = simple_map::remove( + shareholder_beneficiaries, &shareholder_address + ); beneficiary = option::some(shareholder_baneficiary); }; @@ -862,10 +893,9 @@ module supra_framework::vesting_without_staking { vector::for_each_ref( &shareholders_address, |shareholder| { - let shareholder_amount = - simple_map::borrow_mut( - &mut vesting_contract.shareholders, shareholder - ); + let shareholder_amount = simple_map::borrow_mut( + &mut vesting_contract.shareholders, shareholder + ); shareholder_amount.left_amount = 0; }, ); @@ -938,9 +968,9 @@ module supra_framework::vesting_without_staking { let vesting_contract = borrow_global_mut(contract_address); let addr = signer::address_of(account); assert!( - addr == vesting_contract.admin - || addr - == get_role_holder(contract_address, utf8(ROLE_BENEFICIARY_RESETTER)), + addr == vesting_contract.admin || addr == get_role_holder( + contract_address, utf8(ROLE_BENEFICIARY_RESETTER) + ), error::permission_denied(EPERMISSION_DENIED), ); @@ -966,8 +996,7 @@ module supra_framework::vesting_without_staking { VestingAccountManagement { roles: simple_map::create() }, ) }; - let roles = - &mut borrow_global_mut(contract_address).roles; + let roles = &mut borrow_global_mut(contract_address).roles; simple_map::upsert(roles, role, role_holder); } @@ -1155,12 +1184,11 @@ module supra_framework::vesting_without_staking { ); }, ); - let vesting_schedule = - create_vesting_schedule( - schedule, - timestamp::now_seconds() + VESTING_SCHEDULE_CLIFF, - VESTING_PERIOD, - ); + let vesting_schedule = create_vesting_schedule( + schedule, + timestamp::now_seconds() + VESTING_SCHEDULE_CLIFF, + VESTING_PERIOD, + ); let buy_ins = simple_map::create>(); vector::enumerate_ref( @@ -1240,15 +1268,14 @@ module supra_framework::vesting_without_staking { ); stake::mint(admin, GRANT_AMOUNT); // Contract with monthly vesting 10% - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[10], - 100, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -1279,8 +1306,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 7; // 1% of 750 is 7 with rounding let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, 0); assert!(last_vested_period == 1, 0); @@ -1290,8 +1318,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 14; // 2% of 750 is 14 with rounding shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, left_amount); assert!(last_vested_period == 2, 0); @@ -1306,13 +1335,15 @@ module supra_framework::vesting_without_staking { 600, ); // last vested period for shareholder 2 should be number of 10 minute periods in 2 years - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 105120, last_vested_period); // no vesting has been called for shareholder 1 yet - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 0, last_vested_period); // When you vest now, shareholder 1 will move to minutes equivalent to 631 = (365*2)+1 days, @@ -1320,15 +1351,17 @@ module supra_framework::vesting_without_staking { //vesting fraction would be too small to vest even 1 quant vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 105120, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); assert!(shareholder_2_balance == 14, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 105264, last_vested_period); //shareholder 1 correctly gets 5 quant for 2 year + 1 day of advancement @@ -1365,15 +1398,14 @@ module supra_framework::vesting_without_staking { ); stake::mint(admin, GRANT_AMOUNT); // Contract with monthly vesting 10% - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[10], - 100, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -1404,8 +1436,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 7; // 1% of 750 is 7 with rounding let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, 0); assert!(last_vested_period == 1, 0); @@ -1415,8 +1448,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 14; // 2% of 750 is 14 with rounding shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, left_amount); assert!(last_vested_period == 2, 0); @@ -1431,12 +1465,14 @@ module supra_framework::vesting_without_staking { 300, ); // last vested period for shareholder 2 should be number of 5 min periods in 2 years - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 210240, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 0, last_vested_period); // When you vest now, both shareholders should vest @@ -1444,16 +1480,18 @@ module supra_framework::vesting_without_staking { // 1 day period is too small to vest anything so last_vested_period and balance will not mvoe // for shareholder 2 - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 210240, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); assert!(shareholder_2_balance == 14, shareholder_2_balance); //shareholder 1 last_vested_amount will move as per 5 min period in 2year + 1 day - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 210528, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -1491,15 +1529,14 @@ module supra_framework::vesting_without_staking { ); stake::mint(admin, GRANT_AMOUNT); // Contract with monthly vesting 10% - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[10], - 100, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -1530,8 +1567,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 7; // 1% of 750 is 7 with rounding let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, 0); assert!(last_vested_period == 1, 0); @@ -1541,8 +1579,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 14; // 2% of 750 is 14 with rounding shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, left_amount); assert!(last_vested_period == 2, 0); @@ -1557,27 +1596,31 @@ module supra_framework::vesting_without_staking { 60, ); // last vested period for shareholder 2 should be number of minutes in 2 years - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 1051200, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 0, last_vested_period); vest(contract_address); //for shareholder 2, 1 day period is too small to vest anything so last_vested_period and balance will not mvoe - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 1051200, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); assert!(shareholder_2_balance == 14, shareholder_2_balance); //for shareholder 1, last_vested_period will be numbbeer of minutes in 2 year + 1 day - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 1052640, last_vested_period); // precision is too low so the balance will be 4 instead of 5 @@ -1614,15 +1657,14 @@ module supra_framework::vesting_without_staking { ); stake::mint(admin, GRANT_AMOUNT); // Contract with monthly vesting 10% - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[10], - 100, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -1653,8 +1695,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 7; // 1% of 750 is 7 with rounding let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, 0); assert!(last_vested_period == 1, 0); @@ -1664,8 +1707,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = 14; // 2% of 750 is 14 with rounding shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, left_amount); assert!(last_vested_period == 2, 0); @@ -1679,20 +1723,23 @@ module supra_framework::vesting_without_staking { 365 * ONE_DAY * 10000, 1, ); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 63072000, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 0, last_vested_period); // When you vest now, both shareholder 1 and shareholder 2 should have 9 weeks passed vest(contract_address); // for shareholder 2, last_vested_period will be number of seconds in 2 years - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 63072000, last_vested_period); // 1 day period is too small to vest anything so last_vested_period and balance will not mvoe let shareholder_2_balance = coin::balance(shareholder_2_address); @@ -1700,8 +1747,9 @@ module supra_framework::vesting_without_staking { assert!(shareholder_2_balance == 14, shareholder_2_balance); //for shareholder 1, last_vested_period will be number of seconds in 2 year + 1 day - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 63158400, last_vested_period); //precision is too low, the fraction loses 38-40% of the value @@ -1738,15 +1786,14 @@ module supra_framework::vesting_without_staking { ); stake::mint(admin, GRANT_AMOUNT); // Contract with monthly vesting 10% - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[10], - 100, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -1769,8 +1816,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = GRANT_AMOUNT * 3 * 10 / 400 - 1; // diff of 1 because of rounding let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, 0); assert!(last_vested_period == 1, 0); @@ -1780,8 +1828,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = GRANT_AMOUNT * 3 * 20 / 400 - 2; shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, left_amount); assert!(last_vested_period == 2, 0); @@ -1797,19 +1846,22 @@ module supra_framework::vesting_without_staking { ); // last vested period for shareholder 2 should be 8, while total 65 days have passed but his // last vesting corresponds to 60 days, so 8 weeks have passed - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 8, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 0, last_vested_period); // When you vest now, both shareholder 1 and shareholder 2 should have 9 weeks passed vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 9, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); @@ -1817,8 +1869,9 @@ module supra_framework::vesting_without_staking { // so instead of 157 ( 17.49 * 9) he will get 165 assert!(shareholder_2_balance == 165, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 9, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -1833,19 +1886,22 @@ module supra_framework::vesting_without_staking { 1000, 3 * ONE_DAY, ); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 21, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 21, last_vested_period); // When you vest now, both shareholder 1 and shareholder 2 should have 9 weeks passed vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 22, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); @@ -1853,8 +1909,9 @@ module supra_framework::vesting_without_staking { // so instead of 157 ( 17.49 * 9) he will get 165 assert!(shareholder_2_balance == 172, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 22, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -1871,19 +1928,22 @@ module supra_framework::vesting_without_staking { 3000, ONE_DAY, ); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 66, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 66, last_vested_period); // When you vest now, both shareholder 1 and shareholder 2 should have 9 weeks passed vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 68, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); @@ -1891,8 +1951,9 @@ module supra_framework::vesting_without_staking { // so instead of 157 ( 17.49 * 9) he will get 165 assert!(shareholder_2_balance == 176, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 68, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -1910,19 +1971,22 @@ module supra_framework::vesting_without_staking { 1, ); //last vesting happened at 68 days meaning 5875200 seconds - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 5875200, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 5875200, last_vested_period); // When you vest now, both shareholder 1 and shareholder 2 should have 9 weeks passed vest(contract_address); // if the vesting fraction is too low so that vesting amount is zero, last_vested_period should not advance - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 5875200, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); @@ -1930,8 +1994,9 @@ module supra_framework::vesting_without_staking { // so instead of 157 ( 17.49 * 9) he will get 165 assert!(shareholder_2_balance == 176, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 5875200, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -1941,8 +2006,9 @@ module supra_framework::vesting_without_staking { timestamp::fast_forward_seconds(2 * ONE_DAY); vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 6051600, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); @@ -1950,8 +2016,9 @@ module supra_framework::vesting_without_staking { // so instead of 157 ( 17.49 * 9) he will get 165 assert!(shareholder_2_balance == 181, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 6051600, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -1988,15 +2055,14 @@ module supra_framework::vesting_without_staking { ); stake::mint(admin, GRANT_AMOUNT); // Contract with monthly vesting 10% - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[10], - 100, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2019,8 +2085,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = GRANT_AMOUNT * 3 * 10 / 400 - 1; // diff of 1 because of rounding let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, 0); assert!(last_vested_period == 1, 0); @@ -2030,8 +2097,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = GRANT_AMOUNT * 3 * 20 / 400 - 2; shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, left_amount); assert!(last_vested_period == 2, 0); @@ -2049,7 +2117,8 @@ module supra_framework::vesting_without_staking { } #[test(supra_framework = @0x1, admin = @0x123, shareholder_1 = @0x234, shareholder_2 = @0x345, withdrawal = @111)] - public entry fun test_e2e_with_vesting_schedule_update_increasing_period( + #[expected_failure(abort_code = 262151, location = Self)] + public entry fun test_e2e_with_admin_vesting_delay_increasing_period( supra_framework: &signer, admin: &signer, shareholder_1: &signer, @@ -2075,15 +2144,14 @@ module supra_framework::vesting_without_staking { ); stake::mint(admin, GRANT_AMOUNT); // Contract with monthly vesting 10% - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[10], - 100, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2106,8 +2174,9 @@ module supra_framework::vesting_without_staking { vested_amount_2 = GRANT_AMOUNT * 3 * 10 / 400 - 1; // diff of 1 because of rounding let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, 0); assert!(last_vested_period == 1, 0); @@ -2117,48 +2186,200 @@ module supra_framework::vesting_without_staking { vested_amount_2 = GRANT_AMOUNT * 3 * 20 / 400 - 2; shareholder_2_balance = coin::balance(shareholder_2_address); assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(init_amount - left_amount == vested_amount_2, left_amount); assert!(last_vested_period == 2, 0); - // Fast forward time to another 42 days, total 102 days from start - timestamp::fast_forward_seconds(42 * ONE_DAY); - // Note that per month 10% would now translate to 4/30 , approx 13.3333333% per 40 days - set_vesting_schedule( - admin, - contract_address, - vector[40], - 300, - 40 * ONE_DAY, + //increase delay by 2 periods (months) + admin_delay_vesting( + admin, contract_address, 2 ); - // last vested period for shareholder 2 should be 1, while total 102 days have passed, from last vesting at 60 day - // only one 40 day period has passed - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); - assert!(last_vested_period == 1, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); - assert!(last_vested_period == 0, last_vested_period); + //assert last_vested_period is 4 and 2 for shareholder 2 and 1 respectively + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); + assert!(last_vested_period == 4, last_vested_period); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); + assert!(last_vested_period == 2, last_vested_period); - // When you vest now, both shareholder 1 and shareholder 2 should have 2* 40 day period passed + // fast forward by one period, now 3 periods have passed + timestamp::fast_forward_seconds(period_duration_secs(contract_address)); + // When you vest now, both shareholder 1 will get 1 vesting fraction and shareholder 2 will + // stay the same as last_vested_period is 4 vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); - assert!(last_vested_period == 2, last_vested_period); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); + assert!(last_vested_period == 4, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); - // shareholder 2 will get around 13.33% (for one 40 day period = 99) but he already got 148 for 2 month 60 days - // so instead of 199 shareholder will get 247 - assert!(shareholder_2_balance == 247, shareholder_2_balance); + // balance is 148 as shareholder 2 has 2 vested fractions of 75 each but lost 2 due to corresponding + // vest_individual (directly or indirectly by vest) was called twice for this shareholder + assert!(shareholder_2_balance == 148, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); - assert!(last_vested_period == 2, last_vested_period); + // for shareholder 1, 3 periods have passed + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); + assert!(last_vested_period == 3, last_vested_period); - // for shareholder 1, 26.66% of 250 would be 66 + // for shareholder 1, 10% of 250 would be 24 (1 missed due to rounding) + // even though 3 periods is passed, got only one fraction due to delay introduced + let shareholder_1_balance = coin::balance(shareholder_1_address); + assert!(init_amount - left_amount == shareholder_1_balance, 0); + assert!(shareholder_1_balance == 24, shareholder_1_balance); + + // fast forward by 4 periods, now 7 periods have passed + timestamp::fast_forward_seconds(period_duration_secs(contract_address) * 4); + // now last vested period should be 7 for both shareholders + vest(contract_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); + assert!(last_vested_period == 7, last_vested_period); + let shareholder_2_balance = coin::balance(shareholder_2_address); + assert!(init_amount - left_amount == shareholder_2_balance, 0); + // shareholder will have 5 vested fractions (2 missed due to introduced delay) 75 * 5 = 375 but missing 3 due to rounding + assert!(shareholder_2_balance == 372, shareholder_2_balance); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); + assert!(last_vested_period == 7, last_vested_period); + let shareholder_1_balance = coin::balance(shareholder_1_address); + assert!(init_amount - left_amount == shareholder_1_balance, 0); + //shareholder 1 will ahve 5 vested fractions 25 * 5 =125 but missing 2 due to rounding + assert!(shareholder_1_balance == 123, shareholder_1_balance); + + //finally test that non admin can not invoke + admin_delay_vesting( + shareholder_1, + contract_address, + 3, + ); + } + + #[test(supra_framework = @0x1, admin = @0x123, shareholder_1 = @0x234, shareholder_2 = @0x345, withdrawal = @111)] + public entry fun test_e2e_with_vesting_schedule_update_increasing_period( + supra_framework: &signer, + admin: &signer, + shareholder_1: &signer, + shareholder_2: &signer, + withdrawal: &signer + ) acquires AdminStore, VestingContract { + let admin_address = signer::address_of(admin); + let withdrawal_address = signer::address_of(withdrawal); + let shareholder_1_address = signer::address_of(shareholder_1); + let shareholder_2_address = signer::address_of(shareholder_2); + let shareholders = vector[shareholder_1_address, shareholder_2_address]; + let shareholder_1_share = GRANT_AMOUNT / 4; + let shareholder_2_share = GRANT_AMOUNT * 3 / 4; + let shares = vector[shareholder_1_share, shareholder_2_share]; + // Create the vesting contract. + setup( + supra_framework, + vector[ + admin_address, + withdrawal_address, + shareholder_1_address, + shareholder_2_address], + ); + stake::mint(admin, GRANT_AMOUNT); + // Contract with monthly vesting 10% + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[10], + 100, + ); + assert!( + vector::length(&borrow_global(admin_address).vesting_contracts) == + 1, + 0, + ); + let vested_amount_1 = 0; + let vested_amount_2 = 0; + + assert!(coin::balance(contract_address) == GRANT_AMOUNT, 0); + assert!(coin::balance(shareholder_1_address) == vested_amount_1, 0); + assert!(coin::balance(shareholder_2_address) == vested_amount_2, 0); + + // Time is now at the start time, vest will unlock the first period, which is 1/10. + timestamp::update_global_time_for_test_secs( + vesting_start_secs(contract_address) + period_duration_secs(contract_address), + ); + + // After 1st vesting shareholder 2 should have 1/10 of the total amount modulo rounding + vest_individual(contract_address, shareholder_2_address); + vested_amount_2 = GRANT_AMOUNT * 3 * 10 / 400 - 1; // diff of 1 because of rounding + let shareholder_2_balance = coin::balance(shareholder_2_address); + assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); + assert!(init_amount - left_amount == vested_amount_2, 0); + assert!(last_vested_period == 1, 0); + + // Fast forward another month, shareholder 2 should now have 2/10 (20%) vested modulo rounding + timestamp::fast_forward_seconds(period_duration_secs(contract_address)); + vest_individual(contract_address, shareholder_2_address); + vested_amount_2 = GRANT_AMOUNT * 3 * 20 / 400 - 2; + shareholder_2_balance = coin::balance(shareholder_2_address); + assert!(shareholder_2_balance == vested_amount_2, shareholder_2_balance); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); + assert!(init_amount - left_amount == vested_amount_2, left_amount); + assert!(last_vested_period == 2, 0); + + // Fast forward time to another 42 days, total 102 days from start + timestamp::fast_forward_seconds(42 * ONE_DAY); + // Note that per month 10% would now translate to 4/30 , approx 13.3333333% per 40 days + set_vesting_schedule( + admin, + contract_address, + vector[40], + 300, + 40 * ONE_DAY, + ); + // last vested period for shareholder 2 should be 1, while total 102 days have passed, from last vesting at 60 day + // only one 40 day period has passed + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); + assert!(last_vested_period == 1, last_vested_period); + + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); + assert!(last_vested_period == 0, last_vested_period); + + // When you vest now, both shareholder 1 and shareholder 2 should have 2* 40 day period passed + vest(contract_address); + + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); + assert!(last_vested_period == 2, last_vested_period); + let shareholder_2_balance = coin::balance(shareholder_2_address); + assert!(init_amount - left_amount == shareholder_2_balance, 0); + // shareholder 2 will get around 13.33% (for one 40 day period = 99) but he already got 148 for 2 month 60 days + // so instead of 199 shareholder will get 247 + assert!(shareholder_2_balance == 247, shareholder_2_balance); + + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); + assert!(last_vested_period == 2, last_vested_period); + + // for shareholder 1, 26.66% of 250 would be 66 let shareholder_1_balance = coin::balance(shareholder_1_address); assert!(init_amount - left_amount == shareholder_1_balance, 0); assert!(shareholder_1_balance == 66, shareholder_1_balance); @@ -2172,19 +2393,22 @@ module supra_framework::vesting_without_staking { 2 * VESTING_PERIOD, ); //We are still at 102 days so only 1 * 2 month period - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 1, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 1, last_vested_period); // When you vest now, both shareholder 1 and shareholder 2 should have 102 days (one 60 day period) passed vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 1, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); @@ -2192,8 +2416,9 @@ module supra_framework::vesting_without_staking { // so instead of 157 ( 17.49 * 9) he will get 165 assert!(shareholder_2_balance == 247, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 1, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -2210,19 +2435,22 @@ module supra_framework::vesting_without_staking { 100, 4 * VESTING_PERIOD, ); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 0, last_vested_period); - let (_, _, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (_, _, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 0, last_vested_period); // When you vest now, both shareholder 1 and shareholder 2 should have 9 weeks passed vest(contract_address); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 0, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); @@ -2230,8 +2458,9 @@ module supra_framework::vesting_without_staking { // so instead of 157 ( 17.49 * 9) he will get 165 assert!(shareholder_2_balance == 247, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 0, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -2242,8 +2471,9 @@ module supra_framework::vesting_without_staking { timestamp::fast_forward_seconds(10 * ONE_DAY); vest(contract_address); //last vesting happened at 60 days as per records - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 1, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); @@ -2253,8 +2483,9 @@ module supra_framework::vesting_without_staking { // so instead of 300 he will get 546 assert!(shareholder_2_balance == 546, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 1, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -2271,16 +2502,18 @@ module supra_framework::vesting_without_staking { ); vest(contract_address); // for shareholder 2 scaled last_vested_period would be 4 and upon calling vest would go to 5 - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(last_vested_period == 5, last_vested_period); let shareholder_2_balance = coin::balance(shareholder_2_address); assert!(init_amount - left_amount == shareholder_2_balance, 0); //1 vesting would occur at 10% rate again, so 546 + 74 would be 620 assert!(shareholder_2_balance == 620, shareholder_2_balance); - let (init_amount, left_amount, last_vested_period) = - get_vesting_record(contract_address, shareholder_1_address); + let (init_amount, left_amount, last_vested_period) = get_vesting_record( + contract_address, shareholder_1_address + ); assert!(last_vested_period == 5, last_vested_period); let shareholder_1_balance = coin::balance(shareholder_1_address); @@ -2316,15 +2549,14 @@ module supra_framework::vesting_without_staking { shareholder_1_address, shareholder_2_address], ); - let contract_address = - setup_vesting_contract_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - &vector[1], - 1, - ); + let contract_address = setup_vesting_contract_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + &vector[1], + 1, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2381,15 +2613,14 @@ module supra_framework::vesting_without_staking { shareholder_2_address], ); stake::mint(admin, GRANT_AMOUNT); - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - vector[1], - 1, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + vector[1], + 1, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2443,13 +2674,12 @@ module supra_framework::vesting_without_staking { shareholder_1_address, shareholder_2_address], ); - let contract_address = - setup_vesting_contract( - admin, - shareholders, - shares, - withdrawal_address, - ); + let contract_address = setup_vesting_contract( + admin, + shareholders, + shares, + withdrawal_address, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2495,13 +2725,12 @@ module supra_framework::vesting_without_staking { shareholder_1_address, shareholder_2_address], ); - let contract_address = - setup_vesting_contract( - admin, - shareholders, - shares, - withdrawal_address, - ); + let contract_address = setup_vesting_contract( + admin, + shareholders, + shares, + withdrawal_address, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2615,13 +2844,12 @@ module supra_framework::vesting_without_staking { shareholder_1_address, shareholder_2_address], ); - let contract_address = - setup_vesting_contract( - admin, - shareholders, - shares, - withdrawal_address, - ); + let contract_address = setup_vesting_contract( + admin, + shareholders, + shares, + withdrawal_address, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2657,16 +2885,14 @@ module supra_framework::vesting_without_staking { ); assert!(coin::balance(shareholder_2_address) == vested_amount_2, 0); assert!(coin::balance(shareholder_1_address) == vested_amount_1, 0); - let vesting_record_1 = - simple_map::borrow( - &borrow_global(contract_address).shareholders, - &shareholder_1_address, - ); - let vesting_record_2 = - simple_map::borrow( - &borrow_global(contract_address).shareholders, - &shareholder_2_address, - ); + let vesting_record_1 = simple_map::borrow( + &borrow_global(contract_address).shareholders, + &shareholder_1_address, + ); + let vesting_record_2 = simple_map::borrow( + &borrow_global(contract_address).shareholders, + &shareholder_2_address, + ); //Check that loop only as many vesting periods have passed which is required to vest everything assert!( vesting_record_1.last_vested_period == 50, @@ -2704,13 +2930,12 @@ module supra_framework::vesting_without_staking { shareholder_1_address, shareholder_2_address], ); - let contract_address = - setup_vesting_contract( - admin, - shareholders, - shares, - withdrawal_address, - ); + let contract_address = setup_vesting_contract( + admin, + shareholders, + shares, + withdrawal_address, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -2925,16 +3150,15 @@ module supra_framework::vesting_without_staking { let admin_address = signer::address_of(admin); let shareholder_address = signer::address_of(shareholder); setup(supra_framework, vector[admin_address, shareholder_address]); - let contract_address = - setup_vesting_contract_with_schedule( - admin, - &vector[shareholder_address], - &vector[GRANT_AMOUNT], - admin_address, - // First vest = 3/4 but last vest should only be for the remaining 1/4. - &vector[3], - 4, - ); + let contract_address = setup_vesting_contract_with_schedule( + admin, + &vector[shareholder_address], + &vector[GRANT_AMOUNT], + admin_address, + // First vest = 3/4 but last vest should only be for the remaining 1/4. + &vector[3], + 4, + ); // First vest is 3/4 timestamp::update_global_time_for_test_secs( @@ -2964,16 +3188,15 @@ module supra_framework::vesting_without_staking { let shareholder_address = signer::address_of(shareholder); setup(supra_framework, vector[admin_address, shareholder_address]); stake::mint(admin, GRANT_AMOUNT); - let contract_address = - setup_vesting_contract_with_amount_with_schedule( - admin, - vector[shareholder_address], - vector[GRANT_AMOUNT], - admin_address, - // First vest = 3/4 but last vest should only be for the remaining 1/4. - vector[3], - 4, - ); + let contract_address = setup_vesting_contract_with_amount_with_schedule( + admin, + vector[shareholder_address], + vector[GRANT_AMOUNT], + admin_address, + // First vest = 3/4 but last vest should only be for the remaining 1/4. + vector[3], + 4, + ); // First vest is 3/4 timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + VESTING_PERIOD @@ -3002,13 +3225,12 @@ module supra_framework::vesting_without_staking { let admin_address = signer::address_of(admin); let shareholder_address = signer::address_of(shareholder); setup(supra_framework, vector[admin_address, shareholder_address]); - let contract_address = - setup_vesting_contract( - admin, - &vector[shareholder_address], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[shareholder_address], + &vector[GRANT_AMOUNT], + admin_address, + ); // Immediately terminate. Calling vest should now fail. terminate_vesting_contract(admin, contract_address); @@ -3023,13 +3245,12 @@ module supra_framework::vesting_without_staking { let admin_address = signer::address_of(admin); let shareholder_address = signer::address_of(shareholder); setup(supra_framework, vector[admin_address, shareholder_address]); - let contract_address = - setup_vesting_contract( - admin, - &vector[shareholder_address], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[shareholder_address], + &vector[GRANT_AMOUNT], + admin_address, + ); // Call terminate_vesting_contract twice should fail. terminate_vesting_contract(admin, contract_address); @@ -3044,13 +3265,12 @@ module supra_framework::vesting_without_staking { let admin_address = signer::address_of(admin); let shareholder_address = signer::address_of(shareholder); setup(supra_framework, vector[admin_address, shareholder_address]); - let contract_address = - setup_vesting_contract( - admin, - &vector[shareholder_address], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[shareholder_address], + &vector[GRANT_AMOUNT], + admin_address, + ); // Calling admin_withdraw should fail as contract has not been terminated. admin_withdraw(admin, contract_address); @@ -3063,13 +3283,12 @@ module supra_framework::vesting_without_staking { ) acquires AdminStore, VestingContract { let admin_address = signer::address_of(admin); setup(supra_framework, vector[admin_address]); - let contract_address = - setup_vesting_contract( - admin, - &vector[@1, @2], - &vector[GRANT_AMOUNT, GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@1, @2], + &vector[GRANT_AMOUNT, GRANT_AMOUNT], + admin_address, + ); set_beneficiary(admin, contract_address, @1, @11); } @@ -3080,13 +3299,12 @@ module supra_framework::vesting_without_staking { ) acquires AdminStore, VestingContract { let admin_address = signer::address_of(admin); setup(supra_framework, vector[admin_address]); - let contract_address = - setup_vesting_contract( - admin, - &vector[@1, @2], - &vector[GRANT_AMOUNT, GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@1, @2], + &vector[GRANT_AMOUNT, GRANT_AMOUNT], + admin_address, + ); create_account_for_test(@11); set_beneficiary(admin, contract_address, @1, @11); } @@ -3097,13 +3315,12 @@ module supra_framework::vesting_without_staking { ) acquires AdminStore, VestingContract { let admin_address = signer::address_of(admin); setup(supra_framework, vector[admin_address, @11]); - let contract_address = - setup_vesting_contract( - admin, - &vector[@1], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@1], + &vector[GRANT_AMOUNT], + admin_address, + ); set_beneficiary(admin, contract_address, @1, @11); assert!(beneficiary(contract_address, @1) == @11, 0); @@ -3124,13 +3341,12 @@ module supra_framework::vesting_without_staking { ) acquires AdminStore, VestingAccountManagement, VestingContract { let admin_address = signer::address_of(admin); setup(supra_framework, vector[admin_address]); - let contract_address = - setup_vesting_contract( - admin, - &vector[@11], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@11], + &vector[GRANT_AMOUNT], + admin_address, + ); let role = utf8(b"RANDOM"); set_management_role(admin, contract_address, role, @12); assert!(get_role_holder(contract_address, role) == @12, 0); @@ -3147,13 +3363,12 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, @11, @12], ); - let contract_address = - setup_vesting_contract( - admin, - &vector[@11], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@11], + &vector[GRANT_AMOUNT], + admin_address, + ); set_beneficiary(admin, contract_address, @11, @12); assert!(beneficiary(contract_address, @11) == @12, 0); @@ -3189,13 +3404,12 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, @11, @12], ); - let contract_address = - setup_vesting_contract( - admin, - &vector[@11], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@11], + &vector[GRANT_AMOUNT], + admin_address, + ); set_beneficiary(admin, contract_address, @11, @12); assert!(beneficiary(contract_address, @11) == @12, 0); @@ -3222,13 +3436,12 @@ module supra_framework::vesting_without_staking { ) acquires AdminStore, VestingAccountManagement, VestingContract { let admin_address = signer::address_of(admin); setup(supra_framework, vector[admin_address, @11]); - let contract_address = - setup_vesting_contract( - admin, - &vector[@11], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@11], + &vector[GRANT_AMOUNT], + admin_address, + ); // Reset the beneficiary with a random account. This should failed. set_beneficiary_resetter(admin, contract_address, signer::address_of(resetter)); @@ -3244,13 +3457,12 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, @11, @12], ); - let contract_address = - setup_vesting_contract( - admin, - &vector[@11], - &vector[GRANT_AMOUNT], - admin_address, - ); + let contract_address = setup_vesting_contract( + admin, + &vector[@11], + &vector[GRANT_AMOUNT], + admin_address, + ); // Confirm that the lookup returns the same address when a shareholder is // passed for which there is no beneficiary. @@ -3298,9 +3510,10 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, withdrawal_address, shareholder_address], ); - let contract_address = setup_vesting_contract( - admin, shareholders, shares, withdrawal_address - ); + let contract_address = + setup_vesting_contract( + admin, shareholders, shares, withdrawal_address + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -3347,9 +3560,10 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, withdrawal_address, shareholder_address], ); - let contract_address = setup_vesting_contract( - admin, shareholders, shares, withdrawal_address - ); + let contract_address = + setup_vesting_contract( + admin, shareholders, shares, withdrawal_address + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -3396,9 +3610,10 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, withdrawal_address, shareholder_address], ); - let contract_address = setup_vesting_contract( - admin, shareholders, shares, withdrawal_address - ); + let contract_address = + setup_vesting_contract( + admin, shareholders, shares, withdrawal_address + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -3449,14 +3664,15 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, withdrawal_address, shareholder_address], ); - let contract_address = setup_vesting_contract_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - &vector[2, 3, 1], - 10, - ); + let contract_address = + setup_vesting_contract_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + &vector[2, 3, 1], + 10, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -3496,14 +3712,15 @@ module supra_framework::vesting_without_staking { supra_framework, vector[admin_address, withdrawal_address, shareholder_address], ); - let contract_address = setup_vesting_contract_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - &vector[2, 3, 1], - 10, - ); + let contract_address = + setup_vesting_contract_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + &vector[2, 3, 1], + 10, + ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == 1, @@ -3560,14 +3777,15 @@ module supra_framework::vesting_without_staking { let numerators: vector = vector[1]; // Create vesting contract with period_duration = 1, vesting_numerators = [1], vesting_denominator = 1 - let contract_address = setup_vesting_contract_with_amount_with_schedule( - admin, - shareholders, - shares, - withdrawal_address, - numerators, - 1, - ); + let contract_address = + setup_vesting_contract_with_amount_with_schedule( + admin, + shareholders, + shares, + withdrawal_address, + numerators, + 1, + ); set_vesting_schedule( admin, contract_address, @@ -3587,10 +3805,12 @@ module supra_framework::vesting_without_staking { vest_individual(contract_address, shareholder_2_address); // Assert both shareholders have received their full original amount - let (init_amount_1, left_amount_1, _) = - get_vesting_record(contract_address, shareholder_1_address); - let (init_amount_2, left_amount_2, _) = - get_vesting_record(contract_address, shareholder_2_address); + let (init_amount_1, left_amount_1, _) = get_vesting_record( + contract_address, shareholder_1_address + ); + let (init_amount_2, left_amount_2, _) = get_vesting_record( + contract_address, shareholder_2_address + ); assert!(left_amount_1 == 0, left_amount_1); assert!(left_amount_2 == 0, left_amount_2); From 29cbdc862f94d8016ca71ded9ebd11b861340449 Mon Sep 17 00:00:00 2001 From: Saurabh Joshi <106232965+sjoshisupra@users.noreply.github.com> Date: Fri, 9 Jan 2026 18:53:02 +0530 Subject: [PATCH 07/31] update auto generated sdk_builder and docs (#326) Co-authored-by: Saurabh Joshi --- .../src/aptos_framework_sdk_builder.rs | 47 ++ .../doc/pbo_delegation_pool.md | 780 ++++++++++-------- .../doc/vesting_without_staking.md | 160 ++-- 3 files changed, 570 insertions(+), 417 deletions(-) diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs index 8ef75faeb7e..56e348c4b75 100644 --- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs @@ -1168,6 +1168,11 @@ pub enum EntryFunctionCall { contract_addresses: Vec, }, + VestingWithoutStakingAdminDelayVesting { + contract_address: AccountAddress, + delay_periods: u64, + }, + /// Withdraw all funds to the preset vesting contract's withdrawal address. This can only be called if the contract /// has already been terminated. VestingWithoutStakingAdminWithdraw { @@ -2011,6 +2016,10 @@ impl EntryFunctionCall { } => vesting_update_voter(contract_address, new_voter), VestingVest { contract_address } => vesting_vest(contract_address), VestingVestMany { contract_addresses } => vesting_vest_many(contract_addresses), + VestingWithoutStakingAdminDelayVesting { + contract_address, + delay_periods, + } => vesting_without_staking_admin_delay_vesting(contract_address, delay_periods), VestingWithoutStakingAdminWithdraw { contract_address } => { vesting_without_staking_admin_withdraw(contract_address) }, @@ -5447,6 +5456,27 @@ pub fn vesting_vest_many(contract_addresses: Vec) -> Transaction )) } +pub fn vesting_without_staking_admin_delay_vesting( + contract_address: AccountAddress, + delay_periods: u64, +) -> TransactionPayload { + TransactionPayload::EntryFunction(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!("vesting_without_staking").to_owned(), + ), + ident_str!("admin_delay_vesting").to_owned(), + vec![], + vec![ + bcs::to_bytes(&contract_address).unwrap(), + bcs::to_bytes(&delay_periods).unwrap(), + ], + )) +} + /// Withdraw all funds to the preset vesting contract's withdrawal address. This can only be called if the contract /// has already been terminated. pub fn vesting_without_staking_admin_withdraw( @@ -7635,6 +7665,19 @@ mod decoder { } } + pub fn vesting_without_staking_admin_delay_vesting( + payload: &TransactionPayload, + ) -> Option { + if let TransactionPayload::EntryFunction(script) = payload { + Some(EntryFunctionCall::VestingWithoutStakingAdminDelayVesting { + contract_address: bcs::from_bytes(script.args().get(0)?).ok()?, + delay_periods: bcs::from_bytes(script.args().get(1)?).ok()?, + }) + } else { + None + } + } + pub fn vesting_without_staking_admin_withdraw( payload: &TransactionPayload, ) -> Option { @@ -8397,6 +8440,10 @@ static SCRIPT_FUNCTION_DECODER_MAP: once_cell::sync::Lazypublic fun partial_governance_voting_enabled(pool_address: address): bool { - exists<GovernanceRecords>(pool_address) - && stake::get_delegated_voter(pool_address) == pool_address + exists<GovernanceRecords>(pool_address) && stake::get_delegated_voter( + pool_address + ) == pool_address }
@@ -1980,9 +1982,8 @@ Return whether the commission percentage for the next lockup cycle is effective.
public fun is_next_commission_percentage_effective(
     pool_address: address
 ): bool acquires NextCommissionPercentage {
-    exists<NextCommissionPercentage>(pool_address)
-        && timestamp::now_seconds()
-            >= borrow_global<NextCommissionPercentage>(pool_address).effective_after_secs
+    exists<NextCommissionPercentage>(pool_address) && timestamp::now_seconds() >= borrow_global<
+        NextCommissionPercentage>(pool_address).effective_after_secs
 }
 
@@ -2007,9 +2008,7 @@ Return the operator commission percentage set on the delegation pool pool_ Implementation -
public fun operator_commission_percentage(
-    pool_address: address
-): u64 acquires DelegationPool, NextCommissionPercentage {
+
public fun operator_commission_percentage(pool_address: address): u64 acquires DelegationPool, NextCommissionPercentage {
     assert_delegation_pool_exists(pool_address);
     if (is_next_commission_percentage_effective(pool_address)) {
         operator_commission_percentage_next_lockup_cycle(pool_address)
@@ -2076,7 +2075,7 @@ Return the number of delegators owning active stake within pool_addresspublic fun shareholders_count_active_pool(pool_address: address): u64 acquires DelegationPool {
     assert_delegation_pool_exists(pool_address);
     pool_u64::shareholders_count(
-        &borrow_global<DelegationPool>(pool_address).active_shares
+        &borrow_global<DelegationPool>(pool_address).active_shares,
     )
 }
 
@@ -2136,11 +2135,13 @@ some stake and the stake pool's lockup cycle has not ended, their coins are not ): (bool, u64) acquires DelegationPool { assert_delegation_pool_exists(pool_address); let pool = borrow_global<DelegationPool>(pool_address); - let (lockup_cycle_ended, _, pending_inactive, _, commission_pending_inactive) = - calculate_stake_pool_drift(pool); + let (lockup_cycle_ended, _, pending_inactive, _, commission_pending_inactive) = calculate_stake_pool_drift( + pool + ); - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, delegator_address); + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, delegator_address + ); if (!withdrawal_exists) { // if no pending withdrawal, there is neither inactive nor pending_inactive stake (false, 0) @@ -2155,7 +2156,7 @@ some stake and the stake pool's lockup cycle has not ended, their coins are not inactive_shares, pool_u64::shares(inactive_shares, delegator_address), // exclude operator pending_inactive rewards not converted to shares yet - pending_inactive - commission_pending_inactive + pending_inactive - commission_pending_inactive, ); // if withdrawal's lockup cycle ended ONLY on stake pool then it is also inactive (lockup_cycle_ended, pending_inactive) @@ -2192,19 +2193,20 @@ in each of its individual states: (active,inactive,assert_delegation_pool_exists(pool_address); let pool = borrow_global<DelegationPool>(pool_address); let (lockup_cycle_ended, active, _, commission_active, commission_pending_inactive) = - - calculate_stake_pool_drift(pool); + calculate_stake_pool_drift(pool); let total_active_shares = pool_u64::total_shares(&pool.active_shares); - let delegator_active_shares = - pool_u64::shares(&pool.active_shares, delegator_address); + let delegator_active_shares = pool_u64::shares( + &pool.active_shares, delegator_address + ); let (_, _, pending_active, _) = stake::get_stake(pool_address); if (pending_active == 0) { // zero `pending_active` stake indicates that either there are no `add_stake` fees or // previous epoch has ended and should identify shares owning these fees as released - total_active_shares = total_active_shares - - pool_u64::shares(&pool.active_shares, NULL_SHAREHOLDER); + total_active_shares = total_active_shares - pool_u64::shares( + &pool.active_shares, NULL_SHAREHOLDER + ); if (delegator_address == NULL_SHAREHOLDER) { delegator_active_shares = 0 } @@ -2214,16 +2216,16 @@ in each of its individual states: (active,inactive,to shares yet active - commission_active, - total_active_shares + total_active_shares, ); // get state and stake (0 if there is none) of the pending withdrawal - let (withdrawal_inactive, withdrawal_stake) = - get_pending_withdrawal(pool_address, delegator_address); + let (withdrawal_inactive, withdrawal_stake) = get_pending_withdrawal( + pool_address, delegator_address + ); // report non-active stakes accordingly to the state of the pending withdrawal let (inactive, pending_inactive) = - if (withdrawal_inactive) (withdrawal_stake, 0) - else (0, withdrawal_stake); + if (withdrawal_inactive) (withdrawal_stake, 0) else (0, withdrawal_stake); // should also include commission rewards in case of the operator account // operator rewards are actually used to buy shares which is introducing @@ -2271,21 +2273,24 @@ extracted-fee = (amount - extracted-fee) * reward-rate% * (100% - operator-commi Implementation -
public fun get_add_stake_fee(
-    pool_address: address, amount: u64
-): u64 acquires DelegationPool, NextCommissionPercentage {
+
public fun get_add_stake_fee(pool_address: address, amount: u64): u64 acquires DelegationPool, NextCommissionPercentage {
     if (stake::is_current_epoch_validator(pool_address)) {
-        let (rewards_rate, rewards_rate_denominator) =
-            staking_config::get_reward_rate(&staking_config::get());
+        let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate(
+            &staking_config::get()
+        );
         if (rewards_rate_denominator != 0) {
             assert_delegation_pool_exists(pool_address);
 
-            rewards_rate = rewards_rate
-                * (MAX_FEE - operator_commission_percentage(pool_address));
+            rewards_rate = rewards_rate * (
+                MAX_FEE - operator_commission_percentage(pool_address)
+            );
             rewards_rate_denominator = rewards_rate_denominator * MAX_FEE;
             (
-                (((amount as u128) * (rewards_rate as u128))
-                    / ((rewards_rate as u128) + (rewards_rate_denominator as u128))) as u64
+                (
+                    ((amount as u128) * (rewards_rate as u128)) / (
+                        (rewards_rate as u128) + (rewards_rate_denominator as u128)
+                    )
+                ) as u64
             )
         } else { 0 }
     } else { 0 }
@@ -2316,8 +2321,8 @@ the validator had gone inactive before its lockup expired.
 
 
 
public fun can_withdraw_pending_inactive(pool_address: address): bool {
-    stake::get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE
-        && timestamp::now_seconds() >= stake::get_lockup_secs(pool_address)
+    stake::get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE && timestamp::now_seconds()
+        >= stake::get_lockup_secs(pool_address)
 }
 
@@ -2352,8 +2357,9 @@ latest state. synchronize_delegation_pool(pool_address); let pool = borrow_global<DelegationPool>(pool_address); let governance_records = borrow_global_mut<GovernanceRecords>(pool_address); - let latest_delegated_votes = - update_and_borrow_mut_delegated_votes(pool, governance_records, voter); + let latest_delegated_votes = update_and_borrow_mut_delegated_votes( + pool, governance_records, voter + ); calculate_total_voting_power(pool, latest_delegated_votes) }
@@ -2387,7 +2393,7 @@ latest state. calculate_and_update_delegator_voter_internal( borrow_global<DelegationPool>(pool_address), borrow_global_mut<GovernanceRecords>(pool_address), - delegator_address + delegator_address, ) }
@@ -2483,7 +2489,7 @@ Initialize a delegation pool without actual coin but withdraw from the owner's a ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( coin::balance<SupraCoin>(signer::address_of(owner)) >= amount, - error::invalid_argument(EBALANCE_NOT_SUFFICIENT) + error::invalid_argument(EBALANCE_NOT_SUFFICIENT), ); let coin = coin::withdraw<SupraCoin>(owner, amount); @@ -2498,7 +2504,7 @@ Initialize a delegation pool without actual coin but withdraw from the owner's a unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ) }
@@ -2537,7 +2543,7 @@ Initialize a delegation pool without actual coin but withdraw from the owner's a ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( coin::balance<SupraCoin>(signer::address_of(owner)) >= amount, - error::invalid_argument(EBALANCE_NOT_SUFFICIENT) + error::invalid_argument(EBALANCE_NOT_SUFFICIENT), ); let coin = coin::withdraw<SupraCoin>(owner, amount); @@ -2552,7 +2558,7 @@ Initialize a delegation pool without actual coin but withdraw from the owner's a unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ) }
@@ -2578,11 +2584,11 @@ Return the unlock schedule of the pool as (schedule, start_time, period_duration Implementation -
public fun get_unlock_schedule(
-    pool_address: address
-): (vector<FixedPoint64>, u64, u64, u64, FixedPoint64) acquires DelegationPool {
-    let uschedule =
-        borrow_global<DelegationPool>(pool_address).principle_unlock_schedule;
+
public fun get_unlock_schedule(pool_address: address)
+    : (
+    vector<FixedPoint64>, u64, u64, u64, FixedPoint64
+) acquires DelegationPool {
+    let uschedule = borrow_global<DelegationPool>(pool_address).principle_unlock_schedule;
     (
         uschedule.schedule,
         uschedule.start_timestamp_secs,
@@ -2613,19 +2619,21 @@ Return the unlock schedule of the pool as (schedule, start_time, period_duration
 Implementation
 
 
-
fun create_schedule_fractions(unlock_numerators: &vector<u64>, unlock_denominator: u64) : vector<FixedPoint64> {
+
fun create_schedule_fractions(
+    unlock_numerators: &vector<u64>, unlock_denominator: u64
+): vector<FixedPoint64> {
 
-//Create unlock schedule
+    //Create unlock schedule
     let schedule = vector::empty();
     vector::for_each_ref(
         unlock_numerators,
         |e| {
-            let fraction =
-                fixed_point64::create_from_rational(
-                    (*e as u128), (unlock_denominator as u128)
-                );
+            let fraction = fixed_point64::create_from_rational(
+                (*e as u128),
+                (unlock_denominator as u128),
+            );
             vector::push_back(&mut schedule, fraction);
-        }
+        },
     );
 
     schedule
@@ -2635,6 +2643,70 @@ Return the unlock schedule of the pool as (schedule, start_time, period_duration
 
 
 
+
+
+
+
+## Function `update_unlocking_schedule_unchecked`
+
+
+
+
public entry fun update_unlocking_schedule_unchecked(multisig_admin: &signer, pool_address: address, unlock_numerators: vector<u64>, unlock_denominator: u64, unlock_start_time: u64, unlock_duration: u64, last_unlock_period: u64)
+
+ + + +
+Implementation + + +
public entry fun update_unlocking_schedule_unchecked(
+    multisig_admin: &signer,
+    pool_address: address,
+    unlock_numerators: vector<u64>,
+    unlock_denominator: u64,
+    unlock_start_time: u64,
+    unlock_duration: u64,
+    last_unlock_period: u64
+) acquires DelegationPool {
+    assert!(
+        is_admin(signer::address_of(multisig_admin), pool_address),
+        error::permission_denied(ENOT_AUTHORIZED),
+    );
+    let pool = borrow_global_mut<DelegationPool>(pool_address);
+
+    validate_unlock_schedule_params(
+        &unlock_numerators,
+        unlock_denominator,
+        unlock_start_time,
+        unlock_duration,
+    );
+
+    //Create unlock schedule fractions
+    let schedule = create_schedule_fractions(&unlock_numerators, unlock_denominator);
+
+    pool.principle_unlock_schedule = UnlockSchedule {
+        schedule: schedule,
+        start_timestamp_secs: unlock_start_time,
+        period_duration: unlock_duration,
+        last_unlock_period: last_unlock_period,
+        cumulative_unlocked_fraction: pool.principle_unlock_schedule.cumulative_unlocked_fraction
+    };
+    event::emit(
+        UnlockScheduleUpdated {
+            pool_address,
+            unlock_numerators,
+            unlock_denominator,
+            unlock_start_time,
+            unlock_duration
+        },
+    );
+
+}
+
+ + +
@@ -2668,25 +2740,25 @@ before external validators are allowed to join the validator set. ) acquires DelegationPool { assert!( is_admin(signer::address_of(multisig_admin), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); let pool = borrow_global_mut<DelegationPool>(pool_address); assert!( fixed_point64::is_zero( pool.principle_unlock_schedule.cumulative_unlocked_fraction ), - error::invalid_state(EUNLOCKING_ALREADY_STARTED) + error::invalid_state(EUNLOCKING_ALREADY_STARTED), ); validate_unlock_schedule_params( &unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ); //Create unlock schedule fractions - let schedule = create_schedule_fractions(&unlock_numerators,unlock_denominator); + let schedule = create_schedule_fractions(&unlock_numerators, unlock_denominator); pool.principle_unlock_schedule = UnlockSchedule { schedule: schedule, @@ -2702,7 +2774,7 @@ before external validators are allowed to join the validator set. unlock_denominator, unlock_start_time, unlock_duration - } + }, ); } @@ -2741,23 +2813,23 @@ before external validators are allowed to join the validator set. //Fraction numerators can not be empty assert!( numerator_length != 0, - error::invalid_argument(EEMPTY_UNLOCK_SCHEDULE) + error::invalid_argument(EEMPTY_UNLOCK_SCHEDULE), ); //First and last numerator can not be zero assert!( *vector::borrow(unlock_numerators, 0) != 0, - error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION) + error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION), ); assert!( *vector::borrow(unlock_numerators, numerator_length - 1) != 0, - error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION) + error::invalid_argument(ESCHEDULE_WITH_ZERO_FRACTION), ); let sum = vector::foldr(*unlock_numerators, 0, |e, a| { e + a }); //Sum of numerators can not be greater than denominators assert!( sum <= unlock_denominator, - error::invalid_argument(ENUMERATORS_GRATER_THAN_DENOMINATOR) + error::invalid_argument(ENUMERATORS_GRATER_THAN_DENOMINATOR), ); } @@ -2806,53 +2878,53 @@ Ownership over setting the operator/voter is granted to owner who h let ms_admin = option::get_with_default<address>(&multisig_admin, @0x0); assert!( ms_admin != @0x0, - error::invalid_argument(EADMIN_ADDRESS_CANNOT_BE_ZERO) + error::invalid_argument(EADMIN_ADDRESS_CANNOT_BE_ZERO), ); assert!( multisig_account::num_signatures_required(ms_admin) >= 2, - EADMIN_NOT_MULTISIG + EADMIN_NOT_MULTISIG, ); }; // fail if the length of delegator_address and principle_stake is not the same assert!( vector::length(&delegator_address) == vector::length(&principle_stake), - error::invalid_argument(EVECTOR_LENGTH_NOT_SAME) + error::invalid_argument(EVECTOR_LENGTH_NOT_SAME), ); //Delegation pool must be enabled assert!( features::delegation_pools_enabled(), - error::invalid_state(EDELEGATION_POOLS_DISABLED) + error::invalid_state(EDELEGATION_POOLS_DISABLED), ); - validate_unlock_schedule_params( &unlock_numerators, unlock_denominator, unlock_start_time, - unlock_duration + unlock_duration, ); let owner_address = signer::address_of(owner); assert!( !owner_cap_exists(owner_address), - error::already_exists(EOWNER_CAP_ALREADY_EXISTS) + error::already_exists(EOWNER_CAP_ALREADY_EXISTS), ); assert!( operator_commission_percentage <= MAX_FEE, - error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE) + error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE), ); let sum = vector::fold(principle_stake, 0, |a, e| { a + e }); // fail if the value of coin and the sum of principle_stake is not the same assert!( coin::value(&coin) == sum, - error::invalid_state(ECOIN_VALUE_NOT_SAME_AS_PRINCIPAL_STAKE) + error::invalid_state(ECOIN_VALUE_NOT_SAME_AS_PRINCIPAL_STAKE), ); // generate a seed to be used to create the resource account hosting the delegation pool let seed = create_resource_account_seed(delegation_pool_creation_seed); - let (stake_pool_signer, stake_pool_signer_cap) = - account::create_resource_account(owner, seed); + let (stake_pool_signer, stake_pool_signer_cap) = account::create_resource_account( + owner, seed + ); coin::register<SupraCoin>(&stake_pool_signer); // stake_pool_signer will be owner of the stake pool and have its `stake::OwnerCapability` @@ -2861,7 +2933,7 @@ Ownership over setting the operator/voter is granted to owner who h &stake_pool_signer, 0, owner_address, - owner_address + owner_address, ); coin::deposit(pool_address, coin); @@ -2869,7 +2941,7 @@ Ownership over setting the operator/voter is granted to owner who h table::add( &mut inactive_shares, olc_with_index(0), - pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR) + pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR), ); let delegator_address_copy = copy delegator_address; @@ -2884,7 +2956,7 @@ Ownership over setting the operator/voter is granted to owner who h }; //Create unlock schedule - let schedule = create_schedule_fractions(&unlock_numerators,unlock_denominator); + let schedule = create_schedule_fractions(&unlock_numerators, unlock_denominator); move_to( &stake_pool_signer, @@ -2921,7 +2993,7 @@ Ownership over setting the operator/voter is granted to owner who h ), distribute_commission_events: account::new_event_handle< DistributeCommissionEvent>(&stake_pool_signer) - } + }, ); // save delegation pool ownership and resource account address (inner stake pool address) on `owner` @@ -2936,15 +3008,13 @@ Ownership over setting the operator/voter is granted to owner who h let (active_stake, _, _, _) = stake::get_stake(pool_address); // fail if coin in StakePool.active does not match with the balance in active_shares pool. assert!( - active_stake - == pool_u64::total_coins( - &borrow_global<DelegationPool>(pool_address).active_shares - ), - error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL) + active_stake == pool_u64::total_coins( + &borrow_global<DelegationPool>(pool_address).active_shares, + ), + error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL), ); // All delegation pool enable partial governace voting by default once the feature flag is enabled. - if (features::partial_governance_voting_enabled() - && features::delegation_pool_partial_governance_voting_enabled()) { + if (features::partial_governance_voting_enabled() && features::delegation_pool_partial_governance_voting_enabled()) { enable_partial_governance_voting(pool_address); } } @@ -2978,11 +3048,12 @@ Ownership over setting the operator/voter is granted to owner who h { assert!( is_admin(signer::address_of(funder), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); }; - let principle_stake_table = - &mut (borrow_global_mut<DelegationPool>(pool_address).principle_stake); + let principle_stake_table = &mut ( + borrow_global_mut<DelegationPool>(pool_address).principle_stake + ); vector::zip_reverse( delegators, @@ -2993,8 +3064,9 @@ Ownership over setting the operator/voter is granted to owner who h // Compute the actual stake that would be added, `principle_stake` has to be // populated in the table accordingly if (table::contains(principle_stake_table, delegator)) { - let stake_amount = - table::borrow_mut(principle_stake_table, delegator); + let stake_amount = table::borrow_mut( + principle_stake_table, delegator + ); *stake_amount = *stake_amount + stake; } else { table::add(principle_stake_table, delegator, stake); @@ -3006,7 +3078,7 @@ Ownership over setting the operator/voter is granted to owner who h UnlockScheduleApplied { pool_address, delegator, amount: stake } ); } - } + }, ); fund_delegators_with_stake(funder, pool_address, delegators, stakes); @@ -3044,7 +3116,7 @@ Ownership over setting the operator/voter is granted to owner who h stakes, |delegator, stake| { fund_delegator_stake(funder, pool_address, delegator, stake); - } + }, ); }
@@ -3128,9 +3200,7 @@ Return the beneficiary address of the operator.
public fun beneficiary_for_operator(operator: address): address acquires BeneficiaryForOperator {
     if (exists<BeneficiaryForOperator>(operator)) {
         return borrow_global<BeneficiaryForOperator>(operator).beneficiary_for_operator
-    } else {
-        operator
-    }
+    } else { operator }
 }
 
@@ -3160,11 +3230,11 @@ THe existing voter will be replaced. The function is permissionless. ) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( features::partial_governance_voting_enabled(), - error::invalid_state(EDISABLED_FUNCTION) + error::invalid_state(EDISABLED_FUNCTION), ); assert!( features::delegation_pool_partial_governance_voting_enabled(), - error::invalid_state(EDISABLED_FUNCTION) + error::invalid_state(EDISABLED_FUNCTION), ); assert_delegation_pool_exists(pool_address); // synchronize delegation and stake pools before any user operation. @@ -3191,7 +3261,7 @@ THe existing voter will be replaced. The function is permissionless. ), delegate_voting_power_events: account::new_event_handle< DelegateVotingPowerEvent>(&stake_pool_signer) - } + }, ); }
@@ -3242,7 +3312,7 @@ THe existing voter will be replaced. The function is permissionless.
fun assert_delegation_pool_exists(pool_address: address) {
     assert!(
         delegation_pool_exists(pool_address),
-        error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST)
+        error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST),
     );
 }
 
@@ -3272,7 +3342,7 @@ THe existing voter will be replaced. The function is permissionless. let balance = pool_u64::balance(&pool.active_shares, delegator_address); assert!( balance >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW) + error::invalid_argument(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW), ); }
@@ -3299,11 +3369,12 @@ THe existing voter will be replaced. The function is permissionless.
fun assert_min_pending_inactive_balance(
     pool: &DelegationPool, delegator_address: address
 ) {
-    let balance =
-        pool_u64::balance(pending_inactive_shares_pool(pool), delegator_address);
+    let balance = pool_u64::balance(
+        pending_inactive_shares_pool(pool), delegator_address
+    );
     assert!(
         balance >= MIN_COINS_ON_SHARES_POOL,
-        error::invalid_argument(EDELEGATOR_PENDING_INACTIVE_BALANCE_TOO_LOW)
+        error::invalid_argument(EDELEGATOR_PENDING_INACTIVE_BALANCE_TOO_LOW),
     );
 }
 
@@ -3331,7 +3402,7 @@ THe existing voter will be replaced. The function is permissionless. assert_delegation_pool_exists(pool_address); assert!( partial_governance_voting_enabled(pool_address), - error::invalid_state(EPARTIAL_GOVERNANCE_VOTING_NOT_ENABLED) + error::invalid_state(EPARTIAL_GOVERNANCE_VOTING_NOT_ENABLED), ); }
@@ -3359,11 +3430,10 @@ THe existing voter will be replaced. The function is permissionless. src_shares_pool: &pool_u64::Pool, shareholder: address, amount: u64 ): u64 { // find how many coins would be redeemed if supplying `amount` - let redeemed_coins = - pool_u64::shares_to_amount( - src_shares_pool, - amount_to_shares_to_redeem(src_shares_pool, shareholder, amount) - ); + let redeemed_coins = pool_u64::shares_to_amount( + src_shares_pool, + amount_to_shares_to_redeem(src_shares_pool, shareholder, amount), + ); // if balance drops under threshold then redeem it entirely let src_balance = pool_u64::balance(src_shares_pool, shareholder); if (src_balance - redeemed_coins < MIN_COINS_ON_SHARES_POOL) { @@ -3399,11 +3469,10 @@ THe existing voter will be replaced. The function is permissionless. amount: u64 ): u64 { // find how many coins would be redeemed from source if supplying `amount` - let redeemed_coins = - pool_u64::shares_to_amount( - src_shares_pool, - amount_to_shares_to_redeem(src_shares_pool, shareholder, amount) - ); + let redeemed_coins = pool_u64::shares_to_amount( + src_shares_pool, + amount_to_shares_to_redeem(src_shares_pool, shareholder, amount), + ); // if balance on destination would be less than threshold then redeem difference to threshold let dst_balance = pool_u64::balance(dst_shares_pool, shareholder); if (dst_balance + redeemed_coins < MIN_COINS_ON_SHARES_POOL) { @@ -3631,9 +3700,7 @@ Update VoteDelegation of a delegator to up-to-date then borrow_mut it.
fun update_and_borrow_mut_delegator_vote_delegation(
-    pool: &DelegationPool,
-    governance_records: &mut GovernanceRecords,
-    delegator: address
+    pool: &DelegationPool, governance_records: &mut GovernanceRecords, delegator: address
 ): &mut VoteDelegation {
     let pool_address = get_pool_address(pool);
     let locked_until_secs = stake::get_lockup_secs(pool_address);
@@ -3649,14 +3716,14 @@ Update VoteDelegation of a delegator to up-to-date then borrow_mut it.
                 voter: delegator,
                 last_locked_until_secs: locked_until_secs,
                 pending_voter: delegator
-            }
+            },
         )
     };
 
     let vote_delegation = smart_table::borrow_mut(vote_delegation_table, delegator);
     // A lockup period has passed since last time `vote_delegation` was updated. Pending voter takes effect.
-    if (vote_delegation.last_locked_until_secs < locked_until_secs
-        && vote_delegation.voter != vote_delegation.pending_voter) {
+    if (vote_delegation.last_locked_until_secs < locked_until_secs && vote_delegation.voter != vote_delegation
+        .pending_voter) {
         vote_delegation.voter = vote_delegation.pending_voter;
     };
     vote_delegation
@@ -3703,7 +3770,7 @@ Update DelegatedVotes of a voter to up-to-date then borrow_mut it.
                 pending_inactive_shares: inactive_shares,
                 active_shares_next_lockup: active_shares,
                 last_locked_until_secs: locked_until_secs
-            }
+            },
         )
     };
 
@@ -3766,15 +3833,13 @@ power, which equals to the sum of the coin amounts.
 
fun calculate_total_voting_power(
     delegation_pool: &DelegationPool, latest_delegated_votes: &DelegatedVotes
 ): u64 {
-    let active_amount =
-        pool_u64::shares_to_amount(
-            &delegation_pool.active_shares, latest_delegated_votes.active_shares
-        );
-    let pending_inactive_amount =
-        pool_u64::shares_to_amount(
-            pending_inactive_shares_pool(delegation_pool),
-            latest_delegated_votes.pending_inactive_shares
-        );
+    let active_amount = pool_u64::shares_to_amount(
+        &delegation_pool.active_shares, latest_delegated_votes.active_shares
+    );
+    let pending_inactive_amount = pool_u64::shares_to_amount(
+        pending_inactive_shares_pool(delegation_pool),
+        latest_delegated_votes.pending_inactive_shares,
+    );
     active_amount + pending_inactive_amount
 }
 
@@ -3800,14 +3865,11 @@ Update VoteDelegation of a delegator to up-to-date then return the latest voter.
fun calculate_and_update_delegator_voter_internal(
-    pool: &DelegationPool,
-    governance_records: &mut GovernanceRecords,
-    delegator: address
+    pool: &DelegationPool, governance_records: &mut GovernanceRecords, delegator: address
 ): address {
-    let vote_delegation =
-        update_and_borrow_mut_delegator_vote_delegation(
-            pool, governance_records, delegator
-        );
+    let vote_delegation = update_and_borrow_mut_delegator_vote_delegation(
+        pool, governance_records, delegator
+    );
     vote_delegation.voter
 }
 
@@ -3835,8 +3897,9 @@ Update DelegatedVotes of a voter to up-to-date then return the total voting powe
fun calculate_and_update_delegated_votes(
     pool: &DelegationPool, governance_records: &mut GovernanceRecords, voter: address
 ): u64 {
-    let delegated_votes =
-        update_and_borrow_mut_delegated_votes(pool, governance_records, voter);
+    let delegated_votes = update_and_borrow_mut_delegated_votes(
+        pool, governance_records, voter
+    );
     calculate_total_voting_power(pool, delegated_votes)
 }
 
@@ -3861,16 +3924,14 @@ Allows an owner to change the operator of the underlying stake pool. Implementation -
public entry fun set_operator(
-    owner: &signer, new_operator: address
-) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
+
public entry fun set_operator(owner: &signer, new_operator: address) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
     let pool_address = get_owned_pool_address(signer::address_of(owner));
     // synchronize delegation and stake pools before any user operation
     // ensure the old operator is paid its uncommitted commission rewards
     synchronize_delegation_pool(pool_address);
     stake::set_operator(
         &retrieve_stake_pool_owner(borrow_global<DelegationPool>(pool_address)),
-        new_operator
+        new_operator,
     );
 }
 
@@ -3903,7 +3964,7 @@ one for each pool. ) acquires BeneficiaryForOperator { assert!( features::operator_beneficiary_change_enabled(), - std::error::invalid_state(EOPERATOR_BENEFICIARY_CHANGE_NOT_SUPPORTED) + std::error::invalid_state(EOPERATOR_BENEFICIARY_CHANGE_NOT_SUPPORTED), ); // The beneficiay address of an operator is stored under the operator's address. // So, the operator does not need to be validated with respect to a staking pool. @@ -3911,11 +3972,11 @@ one for each pool. let old_beneficiary = beneficiary_for_operator(operator_addr); if (exists<BeneficiaryForOperator>(operator_addr)) { borrow_global_mut<BeneficiaryForOperator>(operator_addr).beneficiary_for_operator = - new_beneficiary; + new_beneficiary; } else { move_to( operator, - BeneficiaryForOperator { beneficiary_for_operator: new_beneficiary } + BeneficiaryForOperator { beneficiary_for_operator: new_beneficiary }, ); }; @@ -3924,7 +3985,7 @@ one for each pool. operator: operator_addr, old_beneficiary, new_beneficiary - } + }, ); }
@@ -3954,23 +4015,21 @@ Allows an owner to update the commission percentage for the operator of the unde ) acquires DelegationPoolOwnership, DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage { assert!( features::commission_change_delegation_pool_enabled(), - error::invalid_state(ECOMMISSION_RATE_CHANGE_NOT_SUPPORTED) + error::invalid_state(ECOMMISSION_RATE_CHANGE_NOT_SUPPORTED), ); assert!( new_commission_percentage <= MAX_FEE, - error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE) + error::invalid_argument(EINVALID_COMMISSION_PERCENTAGE), ); let owner_address = signer::address_of(owner); let pool_address = get_owned_pool_address(owner_address); assert!( - operator_commission_percentage(pool_address) + MAX_COMMISSION_INCREASE - >= new_commission_percentage, - error::invalid_argument(ETOO_LARGE_COMMISSION_INCREASE) + operator_commission_percentage(pool_address) + MAX_COMMISSION_INCREASE >= new_commission_percentage, + error::invalid_argument(ETOO_LARGE_COMMISSION_INCREASE), ); assert!( - stake::get_remaining_lockup_secs(pool_address) - >= min_remaining_secs_for_commission_change(), - error::invalid_state(ETOO_LATE_COMMISSION_CHANGE) + stake::get_remaining_lockup_secs(pool_address) >= min_remaining_secs_for_commission_change(), + error::invalid_state(ETOO_LATE_COMMISSION_CHANGE), ); // synchronize delegation and stake pools before any user operation. this ensures: @@ -3979,24 +4038,24 @@ Allows an owner to update the commission percentage for the operator of the unde synchronize_delegation_pool(pool_address); if (exists<NextCommissionPercentage>(pool_address)) { - let commission_percentage = - borrow_global_mut<NextCommissionPercentage>(pool_address); + let commission_percentage = borrow_global_mut<NextCommissionPercentage>( + pool_address + ); commission_percentage.commission_percentage_next_lockup_cycle = new_commission_percentage; commission_percentage.effective_after_secs = stake::get_lockup_secs( pool_address ); } else { let delegation_pool = borrow_global<DelegationPool>(pool_address); - let pool_signer = - account::create_signer_with_capability( - &delegation_pool.stake_pool_signer_cap - ); + let pool_signer = account::create_signer_with_capability( + &delegation_pool.stake_pool_signer_cap + ); move_to( &pool_signer, NextCommissionPercentage { commission_percentage_next_lockup_cycle: new_commission_percentage, effective_after_secs: stake::get_lockup_secs(pool_address) - } + }, ); }; @@ -4005,7 +4064,7 @@ Allows an owner to update the commission percentage for the operator of the unde pool_address, owner: owner_address, commission_percentage_next_lockup_cycle: new_commission_percentage - } + }, ); }
@@ -4036,14 +4095,14 @@ Allows an owner to change the delegated voter of the underlying stake pool. // No one can change delegated_voter once the partial governance voting feature is enabled. assert!( !features::delegation_pool_partial_governance_voting_enabled(), - error::invalid_state(EDEPRECATED_FUNCTION) + error::invalid_state(EDEPRECATED_FUNCTION), ); let pool_address = get_owned_pool_address(signer::address_of(owner)); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); stake::set_delegated_voter( &retrieve_stake_pool_owner(borrow_global<DelegationPool>(pool_address)), - new_voter + new_voter, ); }
@@ -4080,30 +4139,28 @@ this change won't take effects until the next lockup period. let delegator_address = signer::address_of(delegator); let delegation_pool = borrow_global<DelegationPool>(pool_address); let governance_records = borrow_global_mut<GovernanceRecords>(pool_address); - let delegator_vote_delegation = - update_and_borrow_mut_delegator_vote_delegation( - delegation_pool, governance_records, delegator_address - ); + let delegator_vote_delegation = update_and_borrow_mut_delegator_vote_delegation( + delegation_pool, governance_records, delegator_address + ); let pending_voter: address = delegator_vote_delegation.pending_voter; // No need to update if the voter doesn't really change. if (pending_voter != new_voter) { delegator_vote_delegation.pending_voter = new_voter; - let active_shares = - get_delegator_active_shares(delegation_pool, delegator_address); + let active_shares = get_delegator_active_shares( + delegation_pool, delegator_address + ); // <active shares> of <pending voter of shareholder> -= <active_shares> // <active shares> of <new voter of shareholder> += <active_shares> - let pending_delegated_votes = - update_and_borrow_mut_delegated_votes( - delegation_pool, governance_records, pending_voter - ); + let pending_delegated_votes = update_and_borrow_mut_delegated_votes( + delegation_pool, governance_records, pending_voter + ); pending_delegated_votes.active_shares_next_lockup = pending_delegated_votes.active_shares_next_lockup - active_shares; - let new_delegated_votes = - update_and_borrow_mut_delegated_votes( - delegation_pool, governance_records, new_voter - ); + let new_delegated_votes = update_and_borrow_mut_delegated_votes( + delegation_pool, governance_records, new_voter + ); new_delegated_votes.active_shares_next_lockup = new_delegated_votes.active_shares_next_lockup + active_shares; }; @@ -4114,7 +4171,7 @@ this change won't take effects until the next lockup period. pool_address, delegator: delegator_address, voter: new_voter - } + }, ); } @@ -4184,7 +4241,7 @@ Add amount of coins to the delegation pool pool_addressMIN_COINS_ON_SHARES_POOL` assert!( amount >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT), ); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); @@ -4215,7 +4272,7 @@ Add amount of coins to the delegation pool pool_addressamount of coins to the delegation pool pool_addresssigner::address_of(delegator), - amount + amount, ) } @@ -4322,7 +4379,7 @@ authorized to reactivate their own stake. // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` assert!( amount >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT), ); // synchronize delegation and stake pools before any user operation synchronize_delegation_pool(pool_address); @@ -4333,7 +4390,7 @@ authorized to reactivate their own stake. pending_inactive_shares_pool(pool), &pool.active_shares, delegator, - amount + amount, ); let observed_lockup_cycle = pool.observed_lockup_cycle; amount = redeem_inactive_shares(pool, delegator, amount, observed_lockup_cycle); @@ -4349,7 +4406,7 @@ authorized to reactivate their own stake. pool_address, delegator_address: delegator, amount_reactivated: amount - } + }, ); } @@ -4390,7 +4447,7 @@ validator-owners to prevent it from being abused. { assert!( is_admin(signer::address_of(multisig_admin), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); }; assert!(amount != 0, error::invalid_argument(EWITHDRAW_ZERO_STAKE)); @@ -4398,7 +4455,7 @@ validator-owners to prevent it from being abused. borrow_global_mut<DelegationPool>(pool_address), delegator_address, amount, - signer::address_of(multisig_admin) + signer::address_of(multisig_admin), ); } @@ -4423,27 +4480,28 @@ validator-owners to prevent it from being abused.
public entry fun admin_increase_last_unlock_period(
-    multisig_admin: &signer,
-    pool_address: address,
-    additional_periods: u64
+    multisig_admin: &signer, pool_address: address, additional_periods: u64
 ) acquires DelegationPool {
     // Ensure that the caller is the admin of the delegation pool.
     {
         assert!(
             is_admin(signer::address_of(multisig_admin), pool_address),
-            error::permission_denied(ENOT_AUTHORIZED)
+            error::permission_denied(ENOT_AUTHORIZED),
         );
     };
 
     let delegation_pool = borrow_global_mut<DelegationPool>(pool_address);
     let last_unlocked_period = delegation_pool.principle_unlock_schedule.last_unlock_period;
-    let schedule_length = vector::length(&delegation_pool.principle_unlock_schedule.schedule);
+    let schedule_length = vector::length(
+        &delegation_pool.principle_unlock_schedule.schedule
+    );
     // Current last_unlock_period must be greater or equal to schedule_length -1, this is because
     // last_unlock_period is used as index into schedule vector. If we are not already at the last index or beyond
     // increasing this would have undesirable effect. For example if schedule is [20%, 30%, 10%] and
     // last_unlock_period = 1, increasing it by two would directly go to 10% unlock skipping 30% unlock part
-    assert!(schedule_length -1 <= last_unlocked_period, EINVALID_STATE_FOR_OPERATION);
-    delegation_pool.principle_unlock_schedule.last_unlock_period = delegation_pool.principle_unlock_schedule.last_unlock_period + additional_periods;
+    assert!(schedule_length - 1 <= last_unlocked_period, EINVALID_STATE_FOR_OPERATION);
+    delegation_pool.principle_unlock_schedule.last_unlock_period = delegation_pool.principle_unlock_schedule
+        .last_unlock_period + additional_periods;
 
 }
 
@@ -4486,7 +4544,7 @@ validator-owners to prevent it from being abused. { assert!( is_admin(signer::address_of(multisig_admin), pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); }; @@ -4499,8 +4557,9 @@ validator-owners to prevent it from being abused. delegators, new_principle_stakes, |delegator, principle_stake| { - let (active, inactive, pending_inactive) = - get_stake(pool_address, delegator); + let (active, inactive, pending_inactive) = get_stake( + pool_address, delegator + ); // Ensure that all stake to be locked is made `active`. if (active < principle_stake) { @@ -4527,8 +4586,7 @@ validator-owners to prevent it from being abused. if (active_and_pending_inactive < principle_stake) { // Need to reactivate some of the `inactive` stake. - let amount_to_withdraw = - principle_stake - active_and_pending_inactive; + let amount_to_withdraw = principle_stake - active_and_pending_inactive; // Ensure that we do not try to withdraw more stake than the `inactive` stake. if (amount_to_withdraw > inactive) { @@ -4541,14 +4599,14 @@ validator-owners to prevent it from being abused. multisig_admin, pool_address, delegator, - amount_to_withdraw + amount_to_withdraw, ); // Then allocate it to the delegator again. fund_delegator_stake( multisig_admin, pool_address, delegator, - amount_to_withdraw + amount_to_withdraw, ); } } @@ -4556,17 +4614,18 @@ validator-owners to prevent it from being abused. // else: The amount to lock can be covered by the currently `active` stake. // Update the delegator's principle stake and record the details of the lockup event. - let principle_stake_table = - &mut (borrow_global_mut<DelegationPool>(pool_address).principle_stake); + let principle_stake_table = &mut ( + borrow_global_mut<DelegationPool>(pool_address).principle_stake + ); table::upsert(principle_stake_table, delegator, principle_stake); event::emit( UnlockScheduleApplied { pool_address, delegator, amount: principle_stake - } + }, ); - } + }, ); } @@ -4610,24 +4669,24 @@ validator-owners to prevent it from being abused. let admin_addr = signer::address_of(multisig_admin); assert!( is_admin(admin_addr, pool_address), - error::permission_denied(ENOT_AUTHORIZED) + error::permission_denied(ENOT_AUTHORIZED), ); //Ensure replacement address is different assert!( old_delegator != new_delegator, - error::invalid_argument(ENEW_IS_SAME_AS_OLD_DELEGATOR) + error::invalid_argument(ENEW_IS_SAME_AS_OLD_DELEGATOR), ); //Ensure it is a valid `pool_addres` assert!( exists<DelegationPool>(pool_address), - error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST) + error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST), ); let pool: &mut DelegationPool = borrow_global_mut<DelegationPool>(pool_address); //Ensure `old_delegator` is part of original principle stakers before commencing the replacement assert!( table::contains(&pool.principle_stake, old_delegator), - error::unavailable(EDELEGATOR_DOES_NOT_EXIST) + error::unavailable(EDELEGATOR_DOES_NOT_EXIST), ); //replace in `active_shares` pool @@ -4638,22 +4697,24 @@ validator-owners to prevent it from being abused. active_pool, old_delegator, new_delegator, - active_shares + active_shares, ); }; //replace in `inactive_shares` pool - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, old_delegator); + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, old_delegator + ); if (withdrawal_exists) { - let inactive_pool = - table::borrow_mut(&mut pool.inactive_shares, withdrawal_olc); + let inactive_pool = table::borrow_mut( + &mut pool.inactive_shares, withdrawal_olc + ); let inactive_shares = pool_u64::shares(inactive_pool, old_delegator); pool_u64::transfer_shares( inactive_pool, old_delegator, new_delegator, - inactive_shares + inactive_shares, ); //replace in `pending_withdrawals` @@ -4687,12 +4748,12 @@ validator-owners to prevent it from being abused. VotingRecordKey { voter: new_delegator, proposal_id: proposal_id - } + }, ); vector::push_back(&mut old_keys, *key); }; - } + }, ); vector::zip_ref( @@ -4700,7 +4761,7 @@ validator-owners to prevent it from being abused. &new_keys, |old, new| { replace_in_smart_tables(&mut grecords.votes, *old, *new); - } + }, ); } }; @@ -4804,31 +4865,31 @@ accurate as time passes ): u64 acquires DelegationPool { assert!( exists<DelegationPool>(pool_addr), - error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST) + error::invalid_argument(EDELEGATION_POOL_DOES_NOT_EXIST), ); let pool = borrow_global<DelegationPool>(pool_addr); - let delegator_active_balance = - pool_u64::balance(&pool.active_shares, delegator_addr); - let unlockable_fraction = - pool.principle_unlock_schedule.cumulative_unlocked_fraction; - let delegator_principle_stake = - *table::borrow(&pool.principle_stake, delegator_addr); + let delegator_active_balance = pool_u64::balance( + &pool.active_shares, delegator_addr + ); + let unlockable_fraction = pool.principle_unlock_schedule.cumulative_unlocked_fraction; + let delegator_principle_stake = *table::borrow( + &pool.principle_stake, delegator_addr + ); //To avoid problem even if fraction is slightly above 1 - let unlockable_principle_stake = - ( - math128::min( - fixed_point64::multiply_u128( - (delegator_principle_stake as u128), unlockable_fraction - ), - (delegator_principle_stake as u128) - ) as u64 - ); + let unlockable_principle_stake = ( + math128::min( + fixed_point64::multiply_u128( + (delegator_principle_stake as u128), unlockable_fraction + ), + (delegator_principle_stake as u128), + ) as u64 + ); let locked_amount = delegator_principle_stake - unlockable_principle_stake; assert!( delegator_active_balance >= locked_amount, - error::invalid_state(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW) + error::invalid_state(EDELEGATOR_ACTIVE_BALANCE_TOO_LOW), ); delegator_active_balance - locked_amount @@ -4859,58 +4920,62 @@ Note: this does not synchronize with stake pool, therefore the answer may be con delegator_addr: address, pool_address: address, amount: u64 ): bool acquires DelegationPool { - let principle_stake_table = - &borrow_global<DelegationPool>(pool_address).principle_stake; + let principle_stake_table = &borrow_global<DelegationPool>(pool_address).principle_stake; if (!table::contains(principle_stake_table, delegator_addr)) { return false }; - let unlock_schedule = - &mut borrow_global_mut<DelegationPool>(pool_address).principle_unlock_schedule; + let unlock_schedule = &mut borrow_global_mut<DelegationPool>(pool_address).principle_unlock_schedule; let one = fixed_point64::create_from_rational(1, 1); if (fixed_point64::greater_or_equal( - unlock_schedule.cumulative_unlocked_fraction, one - )) { + unlock_schedule.cumulative_unlocked_fraction, one + )) { return true }; if (unlock_schedule.start_timestamp_secs > timestamp::now_seconds()) { - let unlockable_amount = - cached_unlockable_balance(delegator_addr, pool_address); + let unlockable_amount = cached_unlockable_balance( + delegator_addr, pool_address + ); return amount <= unlockable_amount }; //subtraction safety due to check above - let unlock_periods_passed = - (timestamp::now_seconds() - unlock_schedule.start_timestamp_secs) - / unlock_schedule.period_duration; + let unlock_periods_passed = ( + timestamp::now_seconds() - unlock_schedule.start_timestamp_secs + ) / unlock_schedule.period_duration; let last_unlocked_period = unlock_schedule.last_unlock_period; let schedule_length = vector::length(&unlock_schedule.schedule); let cfraction = unlock_schedule.cumulative_unlocked_fraction; while (last_unlocked_period < unlock_periods_passed && fixed_point64::less(cfraction, one) && last_unlocked_period < schedule_length) { - let next_fraction = - *vector::borrow(&unlock_schedule.schedule, last_unlocked_period); + let next_fraction = *vector::borrow( + &unlock_schedule.schedule, last_unlocked_period + ); cfraction = fixed_point64::add(cfraction, next_fraction); last_unlocked_period = last_unlocked_period + 1; }; - if (last_unlocked_period < unlock_periods_passed - && fixed_point64::less(cfraction, one)) { - let final_fraction = - *vector::borrow(&unlock_schedule.schedule, schedule_length - 1); + if (last_unlocked_period < unlock_periods_passed && fixed_point64::less( + cfraction, one + )) { + let final_fraction = *vector::borrow( + &unlock_schedule.schedule, schedule_length - 1 + ); // Acclerate calculation to current period and don't update last_unlocked_period since it is not used anymore cfraction = fixed_point64::add( cfraction, fixed_point64::multiply_u128_return_fixpoint64( (unlock_periods_passed - last_unlocked_period as u128), - final_fraction - ) + final_fraction, + ), ); cfraction = fixed_point64::min(cfraction, one); }; unlock_schedule.cumulative_unlocked_fraction = cfraction; - unlock_schedule.last_unlock_period = math64::max(unlock_periods_passed, last_unlocked_period); + unlock_schedule.last_unlock_period = math64::max( + unlock_periods_passed, last_unlocked_period + ); let unlockable_amount = cached_unlockable_balance(delegator_addr, pool_address); amount <= unlockable_amount } @@ -4945,13 +5010,13 @@ at most how much active stake there is on the stake pool. // fail unlock of less than `MIN_COINS_ON_SHARES_POOL` assert!( amount >= MIN_COINS_ON_SHARES_POOL, - error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT) + error::invalid_argument(EMINIMUM_UNLOCK_AMOUNT), ); // fail unlock of more stake than `active` on the stake pool let (active, _, _, _) = stake::get_stake(pool_address); assert!( amount <= active, - error::invalid_argument(ENOT_ENOUGH_ACTIVE_STAKE_TO_UNLOCK) + error::invalid_argument(ENOT_ENOUGH_ACTIVE_STAKE_TO_UNLOCK), ); // synchronize delegation and stake pools before any user operation @@ -4962,7 +5027,7 @@ at most how much active stake there is on the stake pool. if (is_principle_stakeholder(delegator_address, pool_address)) { assert!( can_principle_unlock(delegator_address, pool_address, amount), - error::invalid_argument(EAMOUNT_REQUESTED_NOT_UNLOCKABLE) + error::invalid_argument(EAMOUNT_REQUESTED_NOT_UNLOCKABLE), ); }; let pool = borrow_global_mut<DelegationPool>(pool_address); @@ -4970,7 +5035,7 @@ at most how much active stake there is on the stake pool. &pool.active_shares, pending_inactive_shares_pool(pool), delegator_address, - amount + amount, ); amount = redeem_active_shares(pool, delegator_address, amount); stake::unlock(&retrieve_stake_pool_owner(pool), amount); @@ -4980,12 +5045,12 @@ at most how much active stake there is on the stake pool. event::emit_event( &mut pool.unlock_stake_events, - UnlockStakeEvent { pool_address, delegator_address, amount_unlocked: amount } + UnlockStakeEvent { pool_address, delegator_address, amount_unlocked: amount }, ); let (active_stake, _, pending_active, _) = stake::get_stake(pool_address); assert!( active_stake + pending_active == pool_u64::total_coins(&pool.active_shares), - error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL) + error::invalid_state(EACTIVE_COIN_VALUE_NOT_SAME_STAKE_DELEGATION_POOL), ); } @@ -5049,7 +5114,7 @@ Withdraw amount of owned inactive stake from the delegation pool at borrow_global_mut<DelegationPool>(pool_address), delegator_address, amount, - delegator_address + delegator_address, ); } @@ -5084,29 +5149,31 @@ Withdraw amount of owned inactive stake from the delegation pool at if (amount == 0) { return }; let pool_address = get_pool_address(pool); - let (withdrawal_exists, withdrawal_olc) = - pending_withdrawal_exists(pool, delegator_address); + let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists( + pool, delegator_address + ); // exit if no withdrawal or (it is pending and cannot withdraw pending_inactive stake from stake pool) if (!( - withdrawal_exists + withdrawal_exists && ( - withdrawal_olc.index < pool.observed_lockup_cycle.index - || can_withdraw_pending_inactive(pool_address) + withdrawal_olc.index < pool.observed_lockup_cycle.index || can_withdraw_pending_inactive( + pool_address + ) ) - )) { return }; + )) { return }; if (withdrawal_olc.index == pool.observed_lockup_cycle.index) { amount = coins_to_redeem_to_ensure_min_stake( pending_inactive_shares_pool(pool), delegator_address, - amount + amount, ) }; amount = redeem_inactive_shares( pool, delegator_address, amount, - withdrawal_olc + withdrawal_olc, ); let stake_pool_owner = &retrieve_stake_pool_owner(pool); @@ -5138,7 +5205,7 @@ Withdraw amount of owned inactive stake from the delegation pool at event::emit_event( &mut pool.withdraw_stake_events, - WithdrawStakeEvent { pool_address, delegator_address, amount_withdrawn: amount } + WithdrawStakeEvent { pool_address, delegator_address, amount_withdrawn: amount }, ); } @@ -5170,9 +5237,7 @@ A bool is returned to signal if a pending withdrawal exists at all. ): (bool, ObservedLockupCycle) { if (table::contains(&pool.pending_withdrawals, delegator_address)) { (true, *table::borrow(&pool.pending_withdrawals, delegator_address)) - } else { - (false, olc_with_index(0)) - } + } else { (false, olc_with_index(0)) } } @@ -5253,15 +5318,15 @@ be explicitly withdrawn by delegator
fun execute_pending_withdrawal(
     pool: &mut DelegationPool, delegator_address: address
 ) acquires GovernanceRecords {
-    let (withdrawal_exists, withdrawal_olc) =
-        pending_withdrawal_exists(pool, delegator_address);
-    if (withdrawal_exists
-        && withdrawal_olc.index < pool.observed_lockup_cycle.index) {
+    let (withdrawal_exists, withdrawal_olc) = pending_withdrawal_exists(
+        pool, delegator_address
+    );
+    if (withdrawal_exists && withdrawal_olc.index < pool.observed_lockup_cycle.index) {
         withdraw_internal(
             pool,
             delegator_address,
             MAX_U64,
-            delegator_address
+            delegator_address,
         );
     }
 }
@@ -5336,10 +5401,9 @@ to ensure there is always only one withdrawal request.
 
fun buy_in_pending_inactive_shares(
     pool: &mut DelegationPool, shareholder: address, coins_amount: u64
 ): u128 acquires GovernanceRecords {
-    let new_shares =
-        pool_u64::amount_to_shares(
-            pending_inactive_shares_pool(pool), coins_amount
-        );
+    let new_shares = pool_u64::amount_to_shares(
+        pending_inactive_shares_pool(pool), coins_amount
+    );
     // never create a new pending withdrawal unless delegator owns some pending_inactive shares
     if (new_shares == 0) {
         return 0
@@ -5367,7 +5431,7 @@ to ensure there is always only one withdrawal request.
         *table::borrow_mut_with_default(
             &mut pool.pending_withdrawals, shareholder, observed_lockup_cycle
         ) == observed_lockup_cycle,
-        error::invalid_state(EPENDING_WITHDRAWAL_EXISTS)
+        error::invalid_state(EPENDING_WITHDRAWAL_EXISTS),
     );
 
     new_shares
@@ -5433,8 +5497,9 @@ be available for withdrawal when current OLC ends.
 
fun redeem_active_shares(
     pool: &mut DelegationPool, shareholder: address, coins_amount: u64
 ): u64 acquires GovernanceRecords {
-    let shares_to_redeem =
-        amount_to_shares_to_redeem(&pool.active_shares, shareholder, coins_amount);
+    let shares_to_redeem = amount_to_shares_to_redeem(
+        &pool.active_shares, shareholder, coins_amount
+    );
     // silently exit if not a shareholder otherwise redeem would fail with `ESHAREHOLDER_NOT_FOUND`
     if (shares_to_redeem == 0) return 0;
 
@@ -5445,7 +5510,7 @@ be available for withdrawal when current OLC ends.
             pool,
             pool_address,
             shares_to_redeem,
-            shareholder
+            shareholder,
         );
     };
 
@@ -5484,32 +5549,32 @@ escape inactivation when current lockup ends.
     coins_amount: u64,
     lockup_cycle: ObservedLockupCycle
 ): u64 acquires GovernanceRecords {
-    let shares_to_redeem =
-        amount_to_shares_to_redeem(
-            table::borrow(&pool.inactive_shares, lockup_cycle),
-            shareholder,
-            coins_amount
-        );
+    let shares_to_redeem = amount_to_shares_to_redeem(
+        table::borrow(&pool.inactive_shares, lockup_cycle),
+        shareholder,
+        coins_amount,
+    );
     // silently exit if not a shareholder otherwise redeem would fail with `ESHAREHOLDER_NOT_FOUND`
     if (shares_to_redeem == 0) return 0;
 
     // Always update governance records before any change to the shares pool.
     let pool_address = get_pool_address(pool);
     // Only redeem shares from the pending_inactive pool at `lockup_cycle` == current OLC.
-    if (partial_governance_voting_enabled(pool_address)
-        && lockup_cycle.index == pool.observed_lockup_cycle.index) {
+    if (partial_governance_voting_enabled(pool_address) && lockup_cycle.index == pool.observed_lockup_cycle
+        .index) {
         update_governanace_records_for_redeem_pending_inactive_shares(
             pool,
             pool_address,
             shares_to_redeem,
-            shareholder
+            shareholder,
         );
     };
 
     let inactive_shares = table::borrow_mut(&mut pool.inactive_shares, lockup_cycle);
     // 1. reaching here means delegator owns inactive/pending_inactive shares at OLC `lockup_cycle`
-    let redeemed_coins =
-        pool_u64::redeem_shares(inactive_shares, shareholder, shares_to_redeem);
+    let redeemed_coins = pool_u64::redeem_shares(
+        inactive_shares, shareholder, shares_to_redeem
+    );
 
     // if entirely reactivated pending_inactive stake or withdrawn inactive one,
     // re-enable unlocking for delegator by deleting this pending withdrawal
@@ -5519,8 +5584,9 @@ escape inactivation when current lockup ends.
         table::remove(&mut pool.pending_withdrawals, shareholder);
     };
     // destroy inactive shares pool of past OLC if all its stake has been withdrawn
-    if (lockup_cycle.index < pool.observed_lockup_cycle.index
-        && total_coins(inactive_shares) == 0) {
+    if (lockup_cycle.index < pool.observed_lockup_cycle.index && total_coins(
+            inactive_shares
+        ) == 0) {
         pool_u64::destroy_empty(
             table::remove(&mut pool.inactive_shares, lockup_cycle)
         );
@@ -5553,11 +5619,12 @@ whether the lockup expired on the stake pool.
 
 
 
fun calculate_stake_pool_drift(pool: &DelegationPool): (bool, u64, u64, u64, u64) {
-    let (active, inactive, pending_active, pending_inactive) =
-        stake::get_stake(get_pool_address(pool));
+    let (active, inactive, pending_active, pending_inactive) = stake::get_stake(
+        get_pool_address(pool)
+    );
     assert!(
         inactive >= pool.total_coins_inactive,
-        error::invalid_state(ESLASHED_INACTIVE_STAKE_ON_PAST_OLC)
+        error::invalid_state(ESLASHED_INACTIVE_STAKE_ON_PAST_OLC),
     );
     // determine whether a new lockup cycle has been ended on the stake pool and
     // inactivated SOME `pending_inactive` stake which should stop earning rewards now,
@@ -5588,8 +5655,7 @@ whether the lockup expired on the stake pool.
             )
         } else {
             // handle any slashing applied to `active` stake
-            0
-        };
+            0 };
     // operator `pending_inactive` rewards not persisted yet to the pending_inactive shares pool
     let pool_pending_inactive = total_coins(pending_inactive_shares_pool(pool));
     let commission_pending_inactive =
@@ -5597,12 +5663,11 @@ whether the lockup expired on the stake pool.
             math64::mul_div(
                 pending_inactive - pool_pending_inactive,
                 pool.operator_commission_percentage,
-                MAX_FEE
+                MAX_FEE,
             )
         } else {
             // handle any slashing applied to `pending_inactive` stake
-            0
-        };
+            0 };
 
     (
         lockup_cycle_ended,
@@ -5635,9 +5700,7 @@ shares pools, assign commission to operator and eventually prepare delegation po
 Implementation
 
 
-
public entry fun synchronize_delegation_pool(
-    pool_address: address
-) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
+
public entry fun synchronize_delegation_pool(pool_address: address) acquires DelegationPool, GovernanceRecords, BeneficiaryForOperator, NextCommissionPercentage {
     assert_delegation_pool_exists(pool_address);
     let pool = borrow_global_mut<DelegationPool>(pool_address);
     let (
@@ -5663,25 +5726,24 @@ shares pools, assign commission to operator and eventually prepare delegation po
 
     // update total coins accumulated by `active` + `pending_active` shares
     // redeemed `add_stake` fees are restored and distributed to the rest of the pool as rewards
-    pool_u64::update_total_coins(&mut pool.active_shares, active
-        - commission_active);
+    pool_u64::update_total_coins(&mut pool.active_shares, active - commission_active);
     // update total coins accumulated by `pending_inactive` shares at current observed lockup cycle
     pool_u64::update_total_coins(
         pending_inactive_shares_pool_mut(pool),
-        pending_inactive - commission_pending_inactive
+        pending_inactive - commission_pending_inactive,
     );
 
     // reward operator its commission out of uncommitted active rewards (`add_stake` fees already excluded)
     buy_in_active_shares(
         pool,
         beneficiary_for_operator(stake::get_operator(pool_address)),
-        commission_active
+        commission_active,
     );
     // reward operator its commission out of uncommitted pending_inactive rewards
     buy_in_pending_inactive_shares(
         pool,
         beneficiary_for_operator(stake::get_operator(pool_address)),
-        commission_pending_inactive
+        commission_pending_inactive,
     );
 
     event::emit_event(
@@ -5691,7 +5753,7 @@ shares pools, assign commission to operator and eventually prepare delegation po
             operator: stake::get_operator(pool_address),
             commission_active,
             commission_pending_inactive
-        }
+        },
     );
 
     if (features::operator_beneficiary_change_enabled()) {
@@ -5704,7 +5766,7 @@ shares pools, assign commission to operator and eventually prepare delegation po
                 ),
                 commission_active,
                 commission_pending_inactive
-            }
+            },
         )
     };
 
@@ -5720,7 +5782,7 @@ shares pools, assign commission to operator and eventually prepare delegation po
         table::add(
             &mut pool.inactive_shares,
             pool.observed_lockup_cycle,
-            pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR)
+            pool_u64::create_with_scaling_factor(SHARES_SCALING_FACTOR),
         );
     };
 
@@ -5761,26 +5823,22 @@ shares pools, assign commission to operator and eventually prepare delegation po
     // <active shares> of <current voter of shareholder> += <new_shares>
     // <active shares> of <next voter of shareholder> += <new_shares>
     let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    let vote_delegation =
-        update_and_borrow_mut_delegator_vote_delegation(
-            pool, governance_records, shareholder
-        );
+    let vote_delegation = update_and_borrow_mut_delegator_vote_delegation(
+        pool, governance_records, shareholder
+    );
     let current_voter = vote_delegation.voter;
     let pending_voter = vote_delegation.pending_voter;
-    let current_delegated_votes =
-        update_and_borrow_mut_delegated_votes(
-            pool, governance_records, current_voter
-        );
-    current_delegated_votes.active_shares = current_delegated_votes.active_shares
-        + new_shares;
+    let current_delegated_votes = update_and_borrow_mut_delegated_votes(
+        pool, governance_records, current_voter
+    );
+    current_delegated_votes.active_shares = current_delegated_votes.active_shares + new_shares;
     if (pending_voter == current_voter) {
         current_delegated_votes.active_shares_next_lockup = current_delegated_votes.active_shares_next_lockup
             + new_shares;
     } else {
-        let pending_delegated_votes =
-            update_and_borrow_mut_delegated_votes(
-                pool, governance_records, pending_voter
-            );
+        let pending_delegated_votes = update_and_borrow_mut_delegated_votes(
+            pool, governance_records, pending_voter
+        );
         pending_delegated_votes.active_shares_next_lockup = pending_delegated_votes.active_shares_next_lockup
             + new_shares;
     };
@@ -5816,14 +5874,12 @@ shares pools, assign commission to operator and eventually prepare delegation po
     // <pending inactive shares> of <current voter of shareholder> += <new_shares>
     // no impact on <pending inactive shares> of <next voter of shareholder>
     let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    let current_voter =
-        calculate_and_update_delegator_voter_internal(
-            pool, governance_records, shareholder
-        );
-    let current_delegated_votes =
-        update_and_borrow_mut_delegated_votes(
-            pool, governance_records, current_voter
-        );
+    let current_voter = calculate_and_update_delegator_voter_internal(
+        pool, governance_records, shareholder
+    );
+    let current_delegated_votes = update_and_borrow_mut_delegated_votes(
+        pool, governance_records, current_voter
+    );
     current_delegated_votes.pending_inactive_shares = current_delegated_votes.pending_inactive_shares
         + new_shares;
 }
@@ -5858,26 +5914,22 @@ shares pools, assign commission to operator and eventually prepare delegation po
     // <active shares> of <current voter of shareholder> -= <shares_to_redeem>
     // <active shares> of <next voter of shareholder> -= <shares_to_redeem>
     let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    let vote_delegation =
-        update_and_borrow_mut_delegator_vote_delegation(
-            pool, governance_records, shareholder
-        );
+    let vote_delegation = update_and_borrow_mut_delegator_vote_delegation(
+        pool, governance_records, shareholder
+    );
     let current_voter = vote_delegation.voter;
     let pending_voter = vote_delegation.pending_voter;
-    let current_delegated_votes =
-        update_and_borrow_mut_delegated_votes(
-            pool, governance_records, current_voter
-        );
-    current_delegated_votes.active_shares = current_delegated_votes.active_shares
-        - shares_to_redeem;
+    let current_delegated_votes = update_and_borrow_mut_delegated_votes(
+        pool, governance_records, current_voter
+    );
+    current_delegated_votes.active_shares = current_delegated_votes.active_shares - shares_to_redeem;
     if (current_voter == pending_voter) {
         current_delegated_votes.active_shares_next_lockup = current_delegated_votes.active_shares_next_lockup
             - shares_to_redeem;
     } else {
-        let pending_delegated_votes =
-            update_and_borrow_mut_delegated_votes(
-                pool, governance_records, pending_voter
-            );
+        let pending_delegated_votes = update_and_borrow_mut_delegated_votes(
+            pool, governance_records, pending_voter
+        );
         pending_delegated_votes.active_shares_next_lockup = pending_delegated_votes.active_shares_next_lockup
             - shares_to_redeem;
     };
@@ -5913,14 +5965,12 @@ shares pools, assign commission to operator and eventually prepare delegation po
     // <pending inactive shares> of <current voter of shareholder> -= <shares_to_redeem>
     // no impact on <pending inactive shares> of <next voter of shareholder>
     let governance_records = borrow_global_mut<GovernanceRecords>(pool_address);
-    let current_voter =
-        calculate_and_update_delegator_voter_internal(
-            pool, governance_records, shareholder
-        );
-    let current_delegated_votes =
-        update_and_borrow_mut_delegated_votes(
-            pool, governance_records, current_voter
-        );
+    let current_voter = calculate_and_update_delegator_voter_internal(
+        pool, governance_records, shareholder
+    );
+    let current_delegated_votes = update_and_borrow_mut_delegated_votes(
+        pool, governance_records, current_voter
+    );
     current_delegated_votes.pending_inactive_shares = current_delegated_votes.pending_inactive_shares
         - shares_to_redeem;
 }
diff --git a/aptos-move/framework/supra-framework/doc/vesting_without_staking.md b/aptos-move/framework/supra-framework/doc/vesting_without_staking.md
index 08dbd417921..976c5583991 100644
--- a/aptos-move/framework/supra-framework/doc/vesting_without_staking.md
+++ b/aptos-move/framework/supra-framework/doc/vesting_without_staking.md
@@ -39,6 +39,7 @@ Vesting without staking contract
 -  [Function `vest`](#0x1_vesting_without_staking_vest)
 -  [Function `vest_individual`](#0x1_vesting_without_staking_vest_individual)
 -  [Function `vest_transfer`](#0x1_vesting_without_staking_vest_transfer)
+-  [Function `admin_delay_vesting`](#0x1_vesting_without_staking_admin_delay_vesting)
 -  [Function `set_vesting_schedule`](#0x1_vesting_without_staking_set_vesting_schedule)
 -  [Function `remove_shareholder`](#0x1_vesting_without_staking_remove_shareholder)
 -  [Function `terminate_vesting_contract`](#0x1_vesting_without_staking_terminate_vesting_contract)
@@ -660,6 +661,16 @@ Vesting schedule cannot be empty.
 
 
 
+
+
+Invalid vesting delay parameter
+
+
+
const EINVALID_VESTING_DELAY: u64 = 20;
+
+ + + Invalid vesting schedule parameter @@ -992,11 +1003,10 @@ This errors out if the vesting contract with the provided address doesn't exist. vesting_contract_address: address, shareholder_address: address ): (u64, u64, u64) acquires VestingContract { assert_vesting_contract_exists(vesting_contract_address); - let vesting_record = - simple_map::borrow( - &borrow_global<VestingContract>(vesting_contract_address).shareholders, - &shareholder_address, - ); + let vesting_record = simple_map::borrow( + &borrow_global<VestingContract>(vesting_contract_address).shareholders, + &shareholder_address, + ); ( vesting_record.init_amount, vesting_record.left_amount, @@ -1424,20 +1434,23 @@ Create a vesting schedule with the given schedule of distributions, a vesting st // Initialize the vesting contract in a new resource account. This allows the same admin to create multiple // pools. - let (contract_signer, contract_signer_cap) = - create_vesting_contract_account(admin, contract_creation_seed); + let (contract_signer, contract_signer_cap) = create_vesting_contract_account( + admin, contract_creation_seed + ); let contract_signer_address = signer::address_of(&contract_signer); let schedule = vector::map_ref( &vesting_numerators, |numerator| { - let event = - fixed_point32::create_from_rational(*numerator, vesting_denominator); + let event = fixed_point32::create_from_rational( + *numerator, vesting_denominator + ); event }, ); - let vesting_schedule = - create_vesting_schedule(schedule, start_timestamp_secs, period_duration); + let vesting_schedule = create_vesting_schedule( + schedule, start_timestamp_secs, period_duration + ); let shareholders_map = simple_map::create<address, VestingRecord>(); let grant_amount = 0; vector::for_each_reverse( @@ -1571,8 +1584,9 @@ Create a vesting contract with a given configurations. // Initialize the vesting contract in a new resource account. This allows the same admin to create multiple // pools. - let (contract_signer, contract_signer_cap) = - create_vesting_contract_account(admin, contract_creation_seed); + let (contract_signer, contract_signer_cap) = create_vesting_contract_account( + admin, contract_creation_seed + ); let contract_signer_address = signer::address_of(&contract_signer); coin::deposit(contract_signer_address, grant); @@ -1688,10 +1702,9 @@ Unlock any vested portion of the grant. return }; - let vesting_record = - simple_map::borrow_mut( - &mut vesting_contract.shareholders, &shareholder_address - ); + let vesting_record = simple_map::borrow_mut( + &mut vesting_contract.shareholders, &shareholder_address + ); let signer_cap = &vesting_contract.signer_cap; // Check if the next vested period has already passed. If not, short-circuit since there's nothing to vest. @@ -1699,9 +1712,9 @@ Unlock any vested portion of the grant. let schedule = &vesting_schedule.schedule; let last_vested_period = vesting_record.last_vested_period; let next_period_to_vest = last_vested_period + 1; - let last_completed_period = - (timestamp::now_seconds() - vesting_schedule.start_timestamp_secs) / vesting_schedule - .period_duration; + let last_completed_period = ( + timestamp::now_seconds() - vesting_schedule.start_timestamp_secs + ) / vesting_schedule.period_duration; // Index is 0-based while period is 1-based so we need to subtract 1. let one = fixed_point32::create_from_rational(1, 1); @@ -1726,9 +1739,10 @@ Unlock any vested portion of the grant. let final_fraction = *vector::borrow(schedule, vector::length(schedule) - 1); // Determine how many periods is needed based on the left_amount periods_fast_forward = last_completed_period - next_period_to_vest + 1; - let added_fraction = fixed_point32::multiply_u64_return_fixpoint32( - periods_fast_forward, final_fraction - ); + let added_fraction = + fixed_point32::multiply_u64_return_fixpoint32( + periods_fast_forward, final_fraction + ); // If the added_fraction is greater than or equal to the left_amount, then we can vest all the left_amount total_vesting_fraction = fixed_point32::add( total_vesting_fraction, added_fraction @@ -1738,12 +1752,13 @@ Unlock any vested portion of the grant. // Make sure the total vesting fraction is not greater than 1. total_vesting_fraction = fixed_point32::min(total_vesting_fraction, one); // We don't need to check vesting_record.left_amount > 0 because vest_transfer will handle that. - let transfer_happened = vest_transfer( - vesting_record, - signer_cap, - beneficiary, - total_vesting_fraction, - ); + let transfer_happened = + vest_transfer( + vesting_record, + signer_cap, + beneficiary, + total_vesting_fraction, + ); //If no amount was transferred DO NOT advance last_vested_period in the vesting record // This check is needed because if the fraction is too low, `vesting_record.init_amount * vesting_fraction` // may be 0. By not advancing, we allow for the possibility for `vesting_fraction` to become large enough @@ -1794,11 +1809,10 @@ Unlock any vested portion of the grant. let vesting_signer = account::create_signer_with_capability(signer_cap); //amount to be transfer is minimum of what is left and vesting fraction due of init_amount - let amount = - min( - vesting_record.left_amount, - fixed_point32::multiply_u64(vesting_record.init_amount, vesting_fraction), - ); + let amount = min( + vesting_record.left_amount, + fixed_point32::multiply_u64(vesting_record.init_amount, vesting_fraction), + ); if (amount > 0) { //update left_amount for the shareholder vesting_record.left_amount = vesting_record.left_amount - amount; @@ -1810,6 +1824,48 @@ Unlock any vested portion of the grant. + + + + +## Function `admin_delay_vesting` + + + +
public entry fun admin_delay_vesting(admin: &signer, contract_address: address, delay_periods: u64)
+
+ + + +
+Implementation + + +
public entry fun admin_delay_vesting(
+    admin: &signer, contract_address: address, delay_periods: u64
+) acquires VestingContract {
+    assert_active_vesting_contract(contract_address);
+    let vesting_contract = borrow_global_mut<VestingContract>(contract_address);
+    verify_admin(admin, vesting_contract);
+
+    assert!(delay_periods > 0, error::invalid_argument(EINVALID_VESTING_DELAY));
+    let (shareholders, vrecords) = simple_map::to_vec_pair(
+        vesting_contract.shareholders
+    );
+    vector::zip_mut<address, VestingRecord>(
+        &mut shareholders,
+        &mut vrecords,
+        |_s, vrecord| {
+            let mrecord: &mut VestingRecord = vrecord;
+            mrecord.last_vested_period = mrecord.last_vested_period + delay_periods;
+        },
+    );
+    vesting_contract.shareholders = simple_map::new_from(shareholders, vrecords);
+}
+
+ + +
@@ -1856,9 +1912,8 @@ Unlock any vested portion of the grant. &mut values, |shareholder, srecord| { let msrecord: &mut VestingRecord = srecord; - let new_last_vested_period = ( - msrecord.last_vested_period * old_period_duration - ) / period_duration; + let new_last_vested_period = + (msrecord.last_vested_period * old_period_duration) / period_duration; msrecord.last_vested_period = new_last_vested_period; }, ); @@ -1907,8 +1962,9 @@ Example usage: If admin find shareholder suspicious, admin can remove it. let vesting_contract = borrow_global_mut<VestingContract>(contract_address); verify_admin(admin, vesting_contract); let vesting_signer = get_vesting_account_signer_internal(vesting_contract); - let shareholder_amount = - simple_map::borrow(&vesting_contract.shareholders, &shareholder_address).left_amount; + let shareholder_amount = simple_map::borrow( + &vesting_contract.shareholders, &shareholder_address + ).left_amount; coin::transfer<SupraCoin>( &vesting_signer, vesting_contract.withdrawal_address, shareholder_amount ); @@ -1923,16 +1979,18 @@ Example usage: If admin find shareholder suspicious, admin can remove it. // remove `shareholder_address`` from `vesting_contract.shareholders` let shareholders = &mut vesting_contract.shareholders; - let (_, shareholders_vesting) = - simple_map::remove(shareholders, &shareholder_address); + let (_, shareholders_vesting) = simple_map::remove( + shareholders, &shareholder_address + ); // remove `shareholder_address` from `vesting_contract.beneficiaries` let beneficiary = option::none(); let shareholder_beneficiaries = &mut vesting_contract.beneficiaries; // Not all shareholders have their beneficiaries, so before removing them, we need to check if the beneficiary exists if (simple_map::contains_key(shareholder_beneficiaries, &shareholder_address)) { - let (_, shareholder_baneficiary) = - simple_map::remove(shareholder_beneficiaries, &shareholder_address); + let (_, shareholder_baneficiary) = simple_map::remove( + shareholder_beneficiaries, &shareholder_address + ); beneficiary = option::some(shareholder_baneficiary); }; @@ -1983,10 +2041,9 @@ Terminate the vesting contract and send all funds back to the withdrawal address vector::for_each_ref( &shareholders_address, |shareholder| { - let shareholder_amount = - simple_map::borrow_mut( - &mut vesting_contract.shareholders, shareholder - ); + let shareholder_amount = simple_map::borrow_mut( + &mut vesting_contract.shareholders, shareholder + ); shareholder_amount.left_amount = 0; }, ); @@ -2119,9 +2176,9 @@ account. let vesting_contract = borrow_global_mut<VestingContract>(contract_address); let addr = signer::address_of(account); assert!( - addr == vesting_contract.admin - || addr - == get_role_holder(contract_address, utf8(ROLE_BENEFICIARY_RESETTER)), + addr == vesting_contract.admin || addr == get_role_holder( + contract_address, utf8(ROLE_BENEFICIARY_RESETTER) + ), error::permission_denied(EPERMISSION_DENIED), ); @@ -2167,8 +2224,7 @@ account. VestingAccountManagement { roles: simple_map::create<String, address>() }, ) }; - let roles = - &mut borrow_global_mut<VestingAccountManagement>(contract_address).roles; + let roles = &mut borrow_global_mut<VestingAccountManagement>(contract_address).roles; simple_map::upsert(roles, role, role_holder); }
From cb34a04f974513a8422eb4147b59b17c4439b3a4 Mon Sep 17 00:00:00 2001 From: Aregnaz Harutyunyan <89187359+aregng@users.noreply.github.com> Date: Mon, 2 Feb 2026 12:18:30 +0400 Subject: [PATCH 08/31] [AN-Issue-2637] Unlocked valid cycle fee and updated registry state properly when tasks are stopped (#329) * [AN-Issue-2637] Unlocked valid cycle fee and updated registry state properly when tasks are stopped * Fixed comment --------- Co-authored-by: Aregnaz Harutyunyan <> --- .../doc/automation_registry.md | 40 ++++++++++++++----- .../sources/automation_registry.move | 40 ++++++++++++++----- .../tests/automation_registry_tests.move | 17 +++++--- 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/aptos-move/framework/supra-framework/doc/automation_registry.md b/aptos-move/framework/supra-framework/doc/automation_registry.md index 13823a4dab1..4ebcdd03c97 100644 --- a/aptos-move/framework/supra-framework/doc/automation_registry.md +++ b/aptos-move/framework/supra-framework/doc/automation_registry.md @@ -2668,6 +2668,16 @@ Invalid number of auxiliary data. + + +The refund fee for remaining cycle time is greater than total cycle fee for the task. + + +
const EINVALID_CYCLE_REFUND_FEE: u64 = 48;
+
+ + + Invalid expiry time: it cannot be earlier than the current time @@ -4663,7 +4673,7 @@ by the max gas amount of the stopped task. Half of the remaining task fee is ref let stopped_task_details = vector[]; let total_refund_fee = 0; - let epoch_locked_fees = automation_registry.epoch_locked_fees; + let total_cycle_locked_fees = automation_registry.epoch_locked_fees; // Calculate refundable fee for this remaining time task in current epoch let current_time = timestamp::now_seconds(); @@ -4700,8 +4710,14 @@ by the max gas amount of the stopped task. Half of the remaining task fee is ref automation_registry.gas_committed_for_next_epoch = automation_registry.gas_committed_for_next_epoch - task.max_gas_amount; }; - let (epoch_fee_refund, deposit_refund) = if (task.state != PENDING) { - let task_fee = calculate_task_fee( + let (cycle_locked_fee_for_task, cycle_fee_refund, deposit_refund) = if (task.state != PENDING) { + let task_fee_for_full_cycle = + calculate_automation_fee_for_interval( + cycle_info.duration_secs, + task.max_gas_amount, + automation_fee_per_sec, + arc.registry_max_gas_cap); + let task_fee_for_residual_time = calculate_task_fee( &arc, &task, residual_interval, @@ -4709,27 +4725,28 @@ by the max gas amount of the stopped task. Half of the remaining task fee is ref automation_fee_per_sec ); // Refund full deposit and the half of the remaining run-time fee when task is active or cancelled stage - (task_fee / REFUND_FRACTION, task.locked_fee_for_next_epoch) + (task_fee_for_full_cycle, task_fee_for_residual_time / REFUND_FRACTION, task.locked_fee_for_next_epoch) } else { - (0, (task.locked_fee_for_next_epoch / REFUND_FRACTION)) + (0, 0, (task.locked_fee_for_next_epoch / REFUND_FRACTION)) }; let result = safe_unlock_locked_deposit( refund_bookkeeping, task.locked_fee_for_next_epoch, task.task_index); assert!(result, EDEPOSIT_REFUND); - let (result, remaining_epoch_locked_fees) = safe_unlock_locked_epoch_fee( - epoch_locked_fees, - epoch_fee_refund, + assert!(cycle_locked_fee_for_task >= cycle_fee_refund, EINVALID_CYCLE_REFUND_FEE); + let (result, remaining_cycle_locked_fees) = safe_unlock_locked_epoch_fee( + total_cycle_locked_fees, + cycle_locked_fee_for_task, task.task_index); assert!(result, EEPOCH_FEE_REFUND); - epoch_locked_fees = remaining_epoch_locked_fees; + total_cycle_locked_fees = remaining_cycle_locked_fees; - total_refund_fee = total_refund_fee + (epoch_fee_refund + deposit_refund); + total_refund_fee = total_refund_fee + (cycle_fee_refund + deposit_refund); vector::push_back( &mut stopped_task_details, - TaskStoppedV2 { task_index, deposit_refund, epoch_fee_refund, registration_hash: task.tx_hash } + TaskStoppedV2 { task_index, deposit_refund, epoch_fee_refund: cycle_fee_refund, registration_hash: task.tx_hash } ); } }); @@ -4743,6 +4760,7 @@ by the max gas amount of the stopped task. Half of the remaining task fee is ref let resource_account_balance = coin::balance<SupraCoin>(automation_registry.registry_fee_address); assert!(resource_account_balance >= total_refund_fee, EINSUFFICIENT_BALANCE_FOR_REFUND); coin::transfer<SupraCoin>(&resource_signer, owner, total_refund_fee); + automation_registry.epoch_locked_fees = total_cycle_locked_fees; // Emit task stopped event event::emit(TasksStoppedV2 { diff --git a/aptos-move/framework/supra-framework/sources/automation_registry.move b/aptos-move/framework/supra-framework/sources/automation_registry.move index 5c162aaa74c..15965aec1d9 100644 --- a/aptos-move/framework/supra-framework/sources/automation_registry.move +++ b/aptos-move/framework/supra-framework/sources/automation_registry.move @@ -135,6 +135,8 @@ module supra_framework::automation_registry { const EREGISTRY_SYSTEM_MAX_GAS_CAP_NON_ZERO: u64 = 46; /// The input address is not identified as multisig account. const EUNKNOWN_MULTISIG_ADDRESS: u64 = 47; + /// The refund fee for remaining cycle time is greater than total cycle fee for the task. + const EINVALID_CYCLE_REFUND_FEE: u64 = 48; /// The length of the transaction hash. const TXN_HASH_LENGTH: u64 = 32; @@ -1286,7 +1288,7 @@ module supra_framework::automation_registry { let stopped_task_details = vector[]; let total_refund_fee = 0; - let epoch_locked_fees = automation_registry.epoch_locked_fees; + let total_cycle_locked_fees = automation_registry.epoch_locked_fees; // Calculate refundable fee for this remaining time task in current epoch let current_time = timestamp::now_seconds(); @@ -1323,8 +1325,14 @@ module supra_framework::automation_registry { automation_registry.gas_committed_for_next_epoch = automation_registry.gas_committed_for_next_epoch - task.max_gas_amount; }; - let (epoch_fee_refund, deposit_refund) = if (task.state != PENDING) { - let task_fee = calculate_task_fee( + let (cycle_locked_fee_for_task, cycle_fee_refund, deposit_refund) = if (task.state != PENDING) { + let task_fee_for_full_cycle = + calculate_automation_fee_for_interval( + cycle_info.duration_secs, + task.max_gas_amount, + automation_fee_per_sec, + arc.registry_max_gas_cap); + let task_fee_for_residual_time = calculate_task_fee( &arc, &task, residual_interval, @@ -1332,27 +1340,28 @@ module supra_framework::automation_registry { automation_fee_per_sec ); // Refund full deposit and the half of the remaining run-time fee when task is active or cancelled stage - (task_fee / REFUND_FRACTION, task.locked_fee_for_next_epoch) + (task_fee_for_full_cycle, task_fee_for_residual_time / REFUND_FRACTION, task.locked_fee_for_next_epoch) } else { - (0, (task.locked_fee_for_next_epoch / REFUND_FRACTION)) + (0, 0, (task.locked_fee_for_next_epoch / REFUND_FRACTION)) }; let result = safe_unlock_locked_deposit( refund_bookkeeping, task.locked_fee_for_next_epoch, task.task_index); assert!(result, EDEPOSIT_REFUND); - let (result, remaining_epoch_locked_fees) = safe_unlock_locked_epoch_fee( - epoch_locked_fees, - epoch_fee_refund, + assert!(cycle_locked_fee_for_task >= cycle_fee_refund, EINVALID_CYCLE_REFUND_FEE); + let (result, remaining_cycle_locked_fees) = safe_unlock_locked_epoch_fee( + total_cycle_locked_fees, + cycle_locked_fee_for_task, task.task_index); assert!(result, EEPOCH_FEE_REFUND); - epoch_locked_fees = remaining_epoch_locked_fees; + total_cycle_locked_fees = remaining_cycle_locked_fees; - total_refund_fee = total_refund_fee + (epoch_fee_refund + deposit_refund); + total_refund_fee = total_refund_fee + (cycle_fee_refund + deposit_refund); vector::push_back( &mut stopped_task_details, - TaskStoppedV2 { task_index, deposit_refund, epoch_fee_refund, registration_hash: task.tx_hash } + TaskStoppedV2 { task_index, deposit_refund, epoch_fee_refund: cycle_fee_refund, registration_hash: task.tx_hash } ); } }); @@ -1366,6 +1375,7 @@ module supra_framework::automation_registry { let resource_account_balance = coin::balance(automation_registry.registry_fee_address); assert!(resource_account_balance >= total_refund_fee, EINSUFFICIENT_BALANCE_FOR_REFUND); coin::transfer(&resource_signer, owner, total_refund_fee); + automation_registry.epoch_locked_fees = total_cycle_locked_fees; // Emit task stopped event event::emit(TasksStoppedV2 { @@ -3334,6 +3344,14 @@ module supra_framework::automation_registry { automation_registry.main.epoch_locked_fees = locked_fee; } + #[test_only] + public(friend) fun check_locked_fee( + locked_fee: u64, + ) acquires AutomationRegistryV2 { + let automation_registry = borrow_global_mut(@supra_framework); + assert!(automation_registry.main.epoch_locked_fees == locked_fee, locked_fee); + } + #[test_only] public(friend) fun set_total_deposited_automation_fee( fee: u64, diff --git a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move index 379b60cd54f..5ffd5f4e114 100644 --- a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move +++ b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move @@ -12,7 +12,7 @@ module std::automation_registry_tests { use supra_framework::multisig_account; use supra_framework::automation_registry::{ check_task_priority, check_cycle_state_and_duration, check_next_task_index_to_be_processed, - calculate_automation_fee_multiplier_for_committed_occupancy, AutomationRegistryConfigV2, + calculate_automation_fee_multiplier_for_committed_occupancy, AutomationRegistryConfigV2, check_locked_fee, }; use supra_framework::coin; use supra_framework::config_buffer; @@ -2841,11 +2841,12 @@ module std::automation_registry_tests { }); // 0.002 (*4) - automation_epoch_fee_per_second, 7200 epoch duration - let expected_automation_fee = 4 * (max_gas_amount * EPOCH_INTERVAL_FOR_TEST_IN_SECS / 100000); - expected_current_balance = expected_current_balance - expected_automation_fee; - expected_registry_balance = expected_registry_balance + expected_automation_fee; - check_account_balance(user_account, expected_current_balance ); - check_account_balance( registry_fee_address, expected_registry_balance ); + let expected_automation_fees = 4 * (max_gas_amount * EPOCH_INTERVAL_FOR_TEST_IN_SECS / 100000); + expected_current_balance = expected_current_balance - expected_automation_fees; + expected_registry_balance = expected_registry_balance + expected_automation_fees; + check_account_balance(user_account, expected_current_balance); + check_account_balance(registry_fee_address, expected_registry_balance); + check_locked_fee(expected_automation_fees); timestamp::update_global_time_for_test_secs( EPOCH_INTERVAL_FOR_TEST_IN_SECS + (EPOCH_INTERVAL_FOR_TEST_IN_SECS / 2) @@ -2869,6 +2870,8 @@ module std::automation_registry_tests { expected_registry_balance = expected_registry_balance - expected_refund; check_account_balance(user_account, expected_current_balance); check_account_balance(registry_fee_address, expected_registry_balance); + // locked cycle fees are deducted by the full cycle fee amount for the user + check_locked_fee((expected_automation_fees * 3) / 4); // Add and stop the task in the same epoch. Task index will be 4 assert!(automation_registry::get_next_task_index() == 4, 1); @@ -2903,6 +2906,8 @@ module std::automation_registry_tests { expected_refund = automation_fee_cap / REFUND_FACTOR; check_account_balance(user_account, expected_current_balance + expected_refund); check_account_balance(registry_fee_address, expected_registry_balance - expected_refund); + // As long as the task was not active, no locked fee for it will be unlocked + check_locked_fee((expected_automation_fees * 3) / 4); } #[test(framework = @supra_framework, user = @0x1cafe, user2 = @0x1cafa)] From 375bc82039e82c84448e829284d99571929fe5fd Mon Sep 17 00:00:00 2001 From: Supra-RaghulRajeshR Date: Wed, 11 Feb 2026 17:33:02 +0530 Subject: [PATCH 09/31] update runner (#337) Co-authored-by: Supra-RaghulRajeshR --- .github/workflows/aptos-framework-test.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/aptos-framework-test.yaml b/.github/workflows/aptos-framework-test.yaml index d37d24d880f..b5707ecab49 100644 --- a/.github/workflows/aptos-framework-test.yaml +++ b/.github/workflows/aptos-framework-test.yaml @@ -18,11 +18,23 @@ env: SUI_BIN: ~/.cargo/bin/sui APTOS_BIN: ~/.local/bin/aptos SCRYPTO_BIN: ~/.cargo/bin/scrypto + REPO_KEY: ${{ secrets.REPO_KEY }} + jobs: build: runs-on: ghr-elastic-supra-aptos-core-runner timeout-minutes: 90 steps: + - name: Install SSH Client + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ secrets.REPO_KEY }} + + - name: SSH key Scan + run: | + mkdir -p ~/.ssh + ssh-keyscan github.com >> ~/.ssh/known_hosts + - uses: dtolnay/rust-toolchain@stable - uses: actions/checkout@v4 - run: cargo test --release -p aptos-types --lib unit_tests --no-fail-fast From 585341b461b9746c9cfae0281ab6214a6f7acaf0 Mon Sep 17 00:00:00 2001 From: Dhaval Purohit Date: Fri, 13 Feb 2026 19:52:43 +0530 Subject: [PATCH 10/31] Adding leader ban registry module in supra framework (#290) * WIP: adding leader ban registry module in supra framework * WIP: Resolve comments and added further implementation * resolved comments * Fixed compilation issue * resolved comments * Minor formatiing * added config tests * resolved comments * resolved comments * added few more cases * resolved comments + formatted with movefmt * updated with probation period * added docs from comments and removed reinstate proposer * updated the flow for expiration of bans --- .../supra-framework/sources/block.move | 3 + .../sources/configs/config_buffer.move | 1 + .../configs/leader_ban_registry_config.move | 266 +++++++ .../supra-framework/sources/genesis.move | 11 + .../sources/leader_ban_registry.move | 586 ++++++++++++++ .../sources/reconfiguration.move | 2 + .../sources/reconfiguration_with_dkg.move | 2 + .../supra-framework/sources/stake.move | 64 ++ .../tests/test_leader_ban_registry.move | 360 +++++++++ .../test_leader_ban_registry_config.move | 125 +++ .../framework/supra-stdlib/doc/decode_bcs.md | 729 ++++++++++++++++++ .../framework/supra-stdlib/doc/overview.md | 1 + .../supra-stdlib/sources/decode_bcs.move | 370 +++++++++ 13 files changed, 2520 insertions(+) create mode 100644 aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move create mode 100644 aptos-move/framework/supra-framework/sources/leader_ban_registry.move create mode 100644 aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move create mode 100644 aptos-move/framework/supra-framework/tests/test_leader_ban_registry_config.move create mode 100644 aptos-move/framework/supra-stdlib/doc/decode_bcs.md create mode 100644 aptos-move/framework/supra-stdlib/sources/decode_bcs.move diff --git a/aptos-move/framework/supra-framework/sources/block.move b/aptos-move/framework/supra-framework/sources/block.move index 0628c6d4443..cedf43e8427 100644 --- a/aptos-move/framework/supra-framework/sources/block.move +++ b/aptos-move/framework/supra-framework/sources/block.move @@ -18,6 +18,7 @@ module supra_framework::block { use supra_framework::system_addresses; use supra_framework::timestamp; use supra_framework::transaction_fee; + use supra_framework::leader_ban_registry; friend supra_framework::genesis; @@ -216,6 +217,8 @@ module supra_framework::block { // transition is the last block in the previous epoch. stake::update_performance_statistics(proposer_index, failed_proposer_indices); state_storage::on_new_block(reconfiguration::current_epoch()); + + leader_ban_registry::update_ban_registry(epoch, round, proposer_index, failed_proposer_indices); automation_registry::monitor_cycle_end(); diff --git a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move index 9a3d3848275..a2fa31c0cc8 100644 --- a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move +++ b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move @@ -32,6 +32,7 @@ module supra_framework::config_buffer { friend supra_framework::randomness_config_seqnum; friend supra_framework::version; friend supra_framework::automation_registry; + friend supra_framework::leader_ban_registry_config; /// Config buffer operations failed with permission denied. const ESTD_SIGNER_NEEDED: u64 = 1; diff --git a/aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move b/aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move new file mode 100644 index 00000000000..0c1ac2066d5 --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move @@ -0,0 +1,266 @@ +/// Provides the config related to leader ban registry +module supra_framework::leader_ban_registry_config { + use std::error; + use std::option; + use std::option::Option; + use std::vector; + use supra_std::decode_bcs; + use supra_framework::config_buffer; + use supra_framework::system_addresses; + #[test_only] + use std::signer; + + friend supra_framework::genesis; + friend supra_framework::reconfiguration_with_dkg; + + #[test_only] + friend supra_framework::test_leader_ban_registry_config; + #[test_only] + friend supra_framework::test_leader_ban_registry; + + /// The provided on chain config bytes are empty or invalid + const EINVALID_CONFIG: u64 = 1; + /// The provided on chain config version should be equal or greater than existing + const EINVALID_VERSION: u64 = 2; + /// Decoding from version bytes failed + const EINVALID_VERSION_BYTES: u64 = 3; + /// The BanRegistryParameters already initialised + const EALREADY_INITIALISED: u64 = 4; + + /// Holds ban registry parameters bytes and it's version + struct BanRegistryParameters has drop, key, store { + /// Denotes config bcs bytes + config: vector, + /// Denotes config version + version: u8 + } + + /// Ban registry parameters v0 + struct BanRegistryParametersV0 has drop, key, store { + /// Denotes initial election count denied + initial_elections_denied: u8, + /// Denotes max election count denied + max_elections_denied: u32, + /// Denotes the minimum number of validators that must remain eligible for proposal. This + /// helps to preserve liveness in the presence of extended periods of network asynchrony. + minimum_unbanned_proposers: u8, + /// Denotes the number of elections a validator must serve on probation after ban expires. + /// The ban duration compounds each time a validator is banned whilst on probation, and + /// resets to the base duration if the validator passes probation. + probation_elections: u8 + } + + /// Publishes the BanRegistryParameters config. + public(friend) fun initialize( + supra_framework: &signer, config: vector + ) { + system_addresses::assert_supra_framework(supra_framework); + assert!(vector::length(&config) != 0, error::invalid_argument(EINVALID_CONFIG)); + assert!( + !exists(@supra_framework), + error::already_exists(EALREADY_INITIALISED) + ); + let v0 = deserialise_v0_params(config); + if (option::is_none(&v0)) { + abort error::invalid_argument(EINVALID_VERSION_BYTES) + }; + // we always init with version 0 + move_to(supra_framework, BanRegistryParameters { config, version: 0 }); + let v0_params = option::extract(&mut v0); + move_to(supra_framework, v0_params); + } + + /// This can be called by on-chain governance to update on-chain configs for the next epoch. + /// Example usage: + /// ``` + /// supra_framework::leader_ban_registry_config::set_for_next_epoch(&framework_signer, some_config_bytes, version); + /// supra_framework::supra_governance::reconfigure(&framework_signer); + /// ``` + public fun set_for_next_epoch( + account: &signer, config: vector, version: u8 + ) acquires BanRegistryParameters { + system_addresses::assert_supra_framework(account); + assert!(vector::length(&config) != 0, error::invalid_argument(EINVALID_CONFIG)); + if (exists(@supra_framework)) { + let ban_registry_params = + borrow_global(@supra_framework); + assert!( + version >= ban_registry_params.version, + error::invalid_argument(EINVALID_VERSION) + ); + }; + std::config_buffer::upsert( + BanRegistryParameters { config, version } + ); + } + + /// Only used in reconfigurations to apply the pending `BanRegistryParameters`, if there is any. + public(friend) fun on_new_epoch( + framework: &signer + ) acquires BanRegistryParameters, BanRegistryParametersV0 { + system_addresses::assert_supra_framework(framework); + if (config_buffer::does_exist()) { + let new_config = config_buffer::extract(); + if (exists(@supra_framework)) { + *borrow_global_mut(@supra_framework) = new_config; + } else { + move_to(framework, new_config); + }; + let params = borrow_global(@supra_framework); + if (params.version == 0) { + let v0 = deserialise_v0_params(params.config); + // This is to prevent abort on new epoch if deserialise failed. + if (option::is_some(&v0)) { + let ban_registry_params = option::extract(&mut v0); + if (exists(@supra_framework)) { + *borrow_global_mut(@supra_framework) = ban_registry_params; + } else { + move_to(framework, ban_registry_params); + } + } + } + // later version can be assigned here + } + } + + #[view] + public fun get_ban_registry_params(): (vector, u8) acquires BanRegistryParameters { + if (exists(@supra_framework)) { + let ban_registry_config = + borrow_global(@supra_framework); + return (ban_registry_config.config, ban_registry_config.version) + }; + (vector::empty(), 0) + } + + #[view] + public fun get_ban_registry_params_v0(): (u8, u32, u8, u8) acquires BanRegistryParameters, BanRegistryParametersV0 { + if (exists(@supra_framework)) { + let ban_registry_config = + borrow_global(@supra_framework); + if (ban_registry_config.version == 0) { + let ban_registry_params = + borrow_global(@supra_framework); + return ( + ban_registry_params.initial_elections_denied, + ban_registry_params.max_elections_denied, + ban_registry_params.minimum_unbanned_proposers, + ban_registry_params.probation_elections + ) + } + }; + (0, 0, 0, 0) + } + + /// Provide initial election denied value + public fun get_initial_elections_denied(): u8 acquires BanRegistryParameters, BanRegistryParametersV0 { + if (exists(@supra_framework)) { + let ban_registry_config = + borrow_global(@supra_framework); + if (ban_registry_config.version == 0) { + let ban_registry_params = + borrow_global(@supra_framework); + return ban_registry_params.initial_elections_denied + } + }; + 0 + } + + /// Provide max election denied value + public fun get_max_elections_denied(): u32 acquires BanRegistryParameters, BanRegistryParametersV0 { + if (exists(@supra_framework)) { + let ban_registry_config = + borrow_global(@supra_framework); + if (ban_registry_config.version == 0) { + let ban_registry_params = + borrow_global(@supra_framework); + return ban_registry_params.max_elections_denied + } + }; + 0 + } + + /// Provide minimum unbanned proposers value + public fun get_minimum_unbanned_proposers(): u8 acquires BanRegistryParameters, BanRegistryParametersV0 { + if (exists(@supra_framework)) { + let ban_registry_config = + borrow_global(@supra_framework); + if (ban_registry_config.version == 0) { + let ban_registry_params = + borrow_global(@supra_framework); + return ban_registry_params.minimum_unbanned_proposers + } + }; + 0 + } + + /// Provide probation elections value + public fun get_probation_elections(): u8 acquires BanRegistryParameters, BanRegistryParametersV0 { + if (exists(@supra_framework)) { + let ban_registry_config = + borrow_global(@supra_framework); + if (ban_registry_config.version == 0) { + let ban_registry_params = + borrow_global(@supra_framework); + return ban_registry_params.probation_elections + } + }; + 0 + } + + /// Decoding bytes to `BanRegistryParametersV0` using bcs + fun deserialise_v0_params(bytes: vector): Option { + let bcs_bytes = decode_bcs::new(bytes); + let initial_elections_denied: u8 = decode_bcs::peel_u8(&mut bcs_bytes); + let max_elections_denied: u32 = decode_bcs::peel_u32(&mut bcs_bytes); + let minimum_unbanned_proposers: u8 = decode_bcs::peel_u8(&mut bcs_bytes); + let probation_elections: u8 = decode_bcs::peel_u8(&mut bcs_bytes); + // making sure no bytes left to decode means correct parameter version + if (vector::length(&decode_bcs::into_remainder_bytes(bcs_bytes)) == 0) { + return option::some( + BanRegistryParametersV0 { + initial_elections_denied, + max_elections_denied, + minimum_unbanned_proposers, + probation_elections + } + ) + }; + option::none() + } + + #[test_only] + public fun get_test_ban_registry_params_v0(): BanRegistryParametersV0 { + BanRegistryParametersV0 { + initial_elections_denied: 1, + max_elections_denied: 5, + minimum_unbanned_proposers: 2, + probation_elections: 1 + } + } + + #[test_only] + public fun get_custom_ban_registry_params_v0( + initial_elections_denied: u8, + max_elections_denied: u32, + minimum_unbanned_proposers: u8, + probation_elections: u8 + ): BanRegistryParametersV0 { + BanRegistryParametersV0 { + initial_elections_denied, + max_elections_denied, + minimum_unbanned_proposers, + probation_elections + } + } + + #[test_only] + public fun check_ban_registry_params_exist(sender: &signer): bool { + exists(signer::address_of(sender)) + } + + #[test_only] + public fun check_ban_registry_params_v0_exist(sender: &signer): bool { + exists(signer::address_of(sender)) + } +} diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index a13f985ba38..a56f60f0a0d 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -19,6 +19,8 @@ module supra_framework::genesis { use supra_framework::evm_genesis_config; use supra_framework::create_signer::create_signer; use supra_framework::gas_schedule; + use supra_framework::leader_ban_registry; + use supra_framework::leader_ban_registry_config; use supra_framework::multisig_account; use supra_framework::pbo_delegation_pool; use supra_framework::reconfiguration; @@ -291,6 +293,15 @@ module supra_framework::genesis { evm_genesis_config::initialize(supra_framework, evm_genesis_config); } + /// Initialize the leader ban config + fun initialize_leader_ban_registry_config( + supra_framework: &signer, + leader_ban_registry_config: vector, + ) { + leader_ban_registry_config::initialize(supra_framework, leader_ban_registry_config); + leader_ban_registry::initialize_leader_ban_registry(supra_framework); + } + fun create_accounts(supra_framework: &signer, accounts: vector) { let unique_accounts = vector::empty(); diff --git a/aptos-move/framework/supra-framework/sources/leader_ban_registry.move b/aptos-move/framework/supra-framework/sources/leader_ban_registry.move new file mode 100644 index 00000000000..a04dcb4a46a --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/leader_ban_registry.move @@ -0,0 +1,586 @@ +/// Maintains the list of banned validators and updates counters on every epoch. +/// +/// This implementation assumes that each validator is elected once every `n` consensus rounds on expectation, +/// where `n` is the number of validators in the consensus committee (i.e. the `ValidatorSet`). +module supra_framework::leader_ban_registry { + use std::error; + use std::features; + use std::option; + use std::option::Option; + use supra_framework::system_addresses; + use std::vector; + use aptos_std::math64::{pow, min}; + use supra_framework::event; + use supra_framework::stake; + use supra_framework::leader_ban_registry_config; + + friend supra_framework::block; + friend supra_framework::genesis; + friend supra_framework::reconfiguration; + + #[test_only] + friend supra_framework::test_leader_ban_registry; + + /// Leader ban registry already initialized + const EBAN_REGISTRY_ALREADY_EXISTS: u64 = 1; + /// Leader ban registry not initialized + const EBAN_REGISTRY_NOT_INITIALIZED: u64 = 2; + /// Latest view already initialized + const ELATEST_VIEW_ALREADY_EXISTS: u64 = 3; + + /// Information about a ban that is currently in effect for a validator. + struct ActiveBan has store, drop, copy { + /// The consensus epoch in which the current ban was issued (if `on_probation` is `false`) or + /// when its probation period started (if `on_probation` is `true`). + epoch_earned: u64, + /// The consensus round in which the current ban was issued (if `on_probation` is `false`) or + /// when its probation period started (if `on_probation` is `true`). + round_earned: u64, + /// Round count incremented on every epoch change + rounds_served_in_previous_epochs: u64, + /// If `true` then the current ban period has expired and the validator is currently on probation; i.e., it is + /// eligible for election but will be banned for a longer period if it once again fails to propose a canonical + /// block when elected. If `true` then the other fields of this struct denote the consensus view in which + /// the probation period started. + on_probation: bool + } + + /// Holds validator metrics regarding duration pool address etc + struct ValidatorBans has store, drop, copy { + /// Information about the ban that is currently in effect. + active: ActiveBan, + /// The number of consecutive probations that this validator has failed. + consecutive_bans: u32, + /// Validator's pool address + pool_address: address + } + + /// Holds ban registry + struct BanRegistry has drop, store, key { + /// List of validator active bans with pool address + bans: vector + } + + /// Holds latest processed round and epoch + struct LatestView has drop, store, key, copy { + /// Epoch + epoch: u64, + /// Round + round: u64 + } + + #[event] + /// Emits when validator receives a ban or consucutive ban occurred + struct Banned has drop, store { + /// Validator's pool address + pool_address: address, + /// Epoch + epoch: u64, + /// Round + round: u64, + /// The number of consecutive probations that this validator has failed. + consecutive_bans: u32 + } + + #[event] + /// Emitted when a validator's ban is lifted and its probation period starts. A validator that is on probation is + /// eligible for election again, but will be banned for longer if it once again fails to propose a canonical block. + struct ReinstatedWithProbation has drop, store { + /// Validator's pool address + pool_address: address, + /// Epoch + epoch: u64, + /// Round + round: u64 + } + + #[event] + /// Emitted when a validator's probation period ends without the validator earning a new ban. + struct Reinstated has drop, store { + /// Validator's pool address + pool_address: address, + /// Epoch + epoch: u64, + /// Round + round: u64 + } + + /// Initialise leader ban registry + public(friend) fun initialize_leader_ban_registry( + supra_framework: &signer + ) { + system_addresses::assert_supra_framework(supra_framework); + assert!( + !exists(@supra_framework), + error::already_exists(EBAN_REGISTRY_ALREADY_EXISTS) + ); + assert!( + !exists(@supra_framework), + error::already_exists(EBAN_REGISTRY_ALREADY_EXISTS) + ); + move_to(supra_framework, BanRegistry { bans: vector::empty() }); + move_to(supra_framework, LatestView { epoch: 0, round: 0 }); + } + + #[view] + /// Returns list of validators active ban with it's pool address + public fun get_ban_registry(): vector acquires BanRegistry { + if (!exists(@supra_framework)) { + return vector::empty() + }; + let ban_registry = borrow_global(@supra_framework); + ban_registry.bans + } + + #[view] + /// Return latest view + public fun get_latest_view(): LatestView acquires LatestView { + if (!exists(@supra_framework)) { + return LatestView { epoch: 0, round: 0 } + }; + let latest_view = borrow_global(@supra_framework); + *latest_view + } + + #[view] + /// Returns the number of consensus rounds that a validator is banned for when it fails to propose a + /// canonical block when elected as leader whilst not on probation. + public fun get_initial_ban_duration(): u64 { + let initial_elections_denied = + leader_ban_registry_config::get_initial_elections_denied(); + let committee_size = stake::get_committee_size(); + committee_size * (initial_elections_denied as u64) + } + + #[view] + /// Returns the maximum number of consensus rounds that a validator may banned for when it repeatedly fails to + /// propose a canonical block when elected as leader whilst on probation. + public fun get_max_ban_duration(): u64 { + let max_elections_denied = leader_ban_registry_config::get_max_elections_denied(); + let committee_size = stake::get_committee_size(); + committee_size * (max_elections_denied as u64) + } + + #[view] + /// Returns the number of consensus rounds that a validator is considered to be on probation for after having + /// served its most recent ban. + public fun get_probation_duration(): u64 { + let probation_elections = leader_ban_registry_config::get_probation_elections(); + let committee_size = stake::get_committee_size(); + committee_size * (probation_elections as u64) + } + + #[view] + /// Returns the number of consensus rounds remaining in the ban for the validator with the given + /// pool address. Returns 0 if the validator is not banned (including if it is on probation). + public fun get_remaining_ban_duration(pool_address: address): u64 acquires BanRegistry, LatestView { + if (!exists(@supra_framework) || !exists(@supra_framework)) { + return 0 + }; + let ban_registry = borrow_global(@supra_framework); + let latest_view = borrow_global(@supra_framework); + let (found, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + v.pool_address == pool_address && !v.active.on_probation + } + ); + if (found) { + remaining_ban_duration(vector::borrow(&ban_registry.bans, index), latest_view) + } else { + 0 + } + } + + #[view] + /// Returns the number of consensus rounds remaining in the probation period for the validator + /// with the given pool address. Returns 0 if the validator is not on probation. + public fun get_remaining_probation_duration(pool_address: address): u64 acquires BanRegistry, LatestView { + if (!exists(@supra_framework) || !exists(@supra_framework)) { + return 0 + }; + let ban_registry = borrow_global(@supra_framework); + let latest_view = borrow_global(@supra_framework); + let (found, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + v.pool_address == pool_address && v.active.on_probation + } + ); + if (found) { + let probation_dur = get_probation_duration(); + remaining_probation_duration(vector::borrow(&ban_registry.bans, index), latest_view, probation_dur) + } else { + 0 + } + } + + /// Add or update the ban registry as per block metadata + public(friend) fun update_ban_registry( + current_epoch: u64, + current_round: u64, + proposer_index: Option, + failed_proposer_indices: vector + ) acquires BanRegistry, LatestView { + if (!exists(@supra_framework)) { return }; + if (!exists(@supra_framework)) { return }; + let ban_registry = borrow_global_mut(@supra_framework); + let latest_view = borrow_global_mut(@supra_framework); + latest_view.epoch = current_epoch; + latest_view.round = current_round; + + // ban the failed proposers + ban_failed_proposers(latest_view, failed_proposer_indices, ban_registry); + + // remove expired bans + reinstate_expired_bans(latest_view, ban_registry); + } + + /// Adds failed proposer indices to ban registry + fun ban_failed_proposers( + latest_view: &LatestView, + failed_proposer_indices: vector, + ban_registry: &mut BanRegistry + ) { + let initial_ban_duration = get_initial_ban_duration(); + if (initial_ban_duration == 0) { return }; + + vector::for_each( + failed_proposer_indices, + |failed_validator_index| { + let validator_pool_address_opt = + stake::get_pool_address_from_index(failed_validator_index); + + if (option::is_some(&validator_pool_address_opt)) { + let validator_pool_address = + option::extract(&mut validator_pool_address_opt); + let (is_banned, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + validator_pool_address == v.pool_address + } + ); + if (is_banned) { + // Validator is already in registry (either banned or on probation). + // Re-banning resets the ban period and increases consecutive count. + // If the consensus code is implemented correctly then the validator should + // not be re-banned whilst serving a ban as it should not be eligible for election + // when banned (i.e. this branch should only be taken when a validator is on probation). + let bans = vector::borrow_mut(&mut ban_registry.bans, index); + bans.consecutive_bans = bans.consecutive_bans + 1; + bans.active.round_earned = latest_view.round; + bans.active.epoch_earned = latest_view.epoch; + bans.active.rounds_served_in_previous_epochs = 0; + bans.active.on_probation = false; // Reset to banned state + + if (features::module_event_enabled()) { + event::emit( + Banned { + pool_address: validator_pool_address, + epoch: latest_view.epoch, + round: latest_view.round, + consecutive_bans: bans.consecutive_bans + } + ); + } + } else { + let ban_registry_len = vector::length(&ban_registry.bans); + if (can_be_banned(ban_registry_len)) { + let ban_with_address = ValidatorBans { + active: ActiveBan { + epoch_earned: latest_view.epoch, + round_earned: latest_view.round, + rounds_served_in_previous_epochs: 0, + on_probation: false + }, + consecutive_bans: 0, + pool_address: validator_pool_address + }; + vector::push_back(&mut ban_registry.bans, ban_with_address); + + if (features::module_event_enabled()) { + event::emit( + Banned { + pool_address: ban_with_address.pool_address, + epoch: ban_with_address.active.epoch_earned, + round: ban_with_address.active.round_earned, + consecutive_bans: ban_with_address.consecutive_bans + } + ); + } + } + }; + }; + } + ); + } + + /// Handles ban and probation expiry: + /// - When probation expires: removes from registry, emits Reinstated + /// - When ban expires and probation_duration > 0: transitions to probation, emits ReinstatedWithProbation + /// - When ban expires and probation_duration == 0: removes from registry, emits Reinstated + fun reinstate_expired_bans( + latest_view: &LatestView, ban_registry: &mut BanRegistry + ) { + let probation_duration = get_probation_duration(); + + // First pass: remove validators whose probation has expired. + // Done before ban-to-probation transitions to avoid iterating just-transitioned validators. + // Always runs (even when probation_duration == 0) to clean up validators that were already + // on probation before a config change set probation_duration to 0. + let pool_addresses_for_full_reinstatement = vector::empty(); + vector::for_each_ref( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + if (v.active.on_probation + && remaining_probation_duration(v, latest_view, probation_duration) == 0) { + vector::push_back( + &mut pool_addresses_for_full_reinstatement, v.pool_address + ); + } + } + ); + + vector::for_each_ref( + &pool_addresses_for_full_reinstatement, + |p| { + let (found, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + &v.pool_address == p + } + ); + if (found) { + vector::swap_remove(&mut ban_registry.bans, index); + + if (features::module_event_enabled()) { + event::emit( + Reinstated { + epoch: latest_view.epoch, + round: latest_view.round, + pool_address: *p + } + ) + } + } + } + ); + + // Second pass: handle expired bans + let pool_addresses_with_expired_bans = vector::empty(); + vector::for_each_ref( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + if (!v.active.on_probation && remaining_ban_duration(v, latest_view) == 0) { + vector::push_back(&mut pool_addresses_with_expired_bans, v.pool_address); + } + } + ); + + if (probation_duration > 0) { + // Transition expired bans to probation + vector::for_each_ref( + &pool_addresses_with_expired_bans, + |p| { + let (found, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + &v.pool_address == p + } + ); + if (found) { + let ban = vector::borrow_mut(&mut ban_registry.bans, index); + ban.active.on_probation = true; + // Reset active fields so probation duration is calculated from this point + ban.active.epoch_earned = latest_view.epoch; + ban.active.round_earned = latest_view.round; + ban.active.rounds_served_in_previous_epochs = 0; + + if (features::module_event_enabled()) { + event::emit( + ReinstatedWithProbation { + epoch: latest_view.epoch, + round: latest_view.round, + pool_address: *p + } + ) + } + } + } + ); + } else { + // No probation period - directly remove validators whose ban expired + vector::for_each_ref( + &pool_addresses_with_expired_bans, + |p| { + let (found, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + &v.pool_address == p + } + ); + if (found) { + vector::swap_remove(&mut ban_registry.bans, index); + + if (features::module_event_enabled()) { + event::emit( + Reinstated { + epoch: latest_view.epoch, + round: latest_view.round, + pool_address: *p + } + ) + } + } + } + ); + }; + } + + /// Increments the total number of consensus rounds served by each banned validator and removes + /// registry entries for validators that have left the validator set. + /// + /// The number of rounds in each epoch may vary due to network asynchrony, so we must record the + /// number of rounds served in previous epochs to be able to ensure that a banned validator serves its + /// full ban period when its ban span multiple epochs. + public(friend) fun on_new_epoch() acquires BanRegistry, LatestView { + if (!exists(@supra_framework)) { return }; + if (!exists(@supra_framework)) { return }; + let latest_view = borrow_global(@supra_framework); + let ban_registry = borrow_global_mut(@supra_framework); + + // The pool addresses of the validators for the new epoch. + let new_committee_pool_addresses = stake::get_committee_pool_addresses(); + // The pool addresses of the validators that have left the committee. + let retired_validators = vector::empty(); + vector::for_each_mut( + &mut ban_registry.bans, + |v| { + let v: &mut ValidatorBans = v; + if (vector::contains(&new_committee_pool_addresses, &v.pool_address)) { + if (latest_view.epoch > v.active.epoch_earned) { + v.active.rounds_served_in_previous_epochs = v.active.rounds_served_in_previous_epochs + + latest_view.round; + } else if (latest_view.epoch == v.active.epoch_earned && latest_view.round > v.active.round_earned) { + v.active.rounds_served_in_previous_epochs = latest_view.round - v.active.round_earned; + }; + // else: The ban hasn't started yet. + } else { + vector::push_back(&mut retired_validators, v.pool_address) + } + } + ); + + vector::for_each_ref( + &retired_validators, + |p| { + let (is_banned, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + &v.pool_address == p + } + ); + if (is_banned) { + vector::swap_remove(&mut ban_registry.bans, index); + + if (features::module_event_enabled()) { + event::emit( + Reinstated { + pool_address: *p, + epoch: latest_view.epoch, + round: latest_view.round + } + ); + } + } + } + ); + } + + /// Calculate the number of rounds remaining in a given ban (not including probation). + fun remaining_ban_duration( + ban: &ValidatorBans, latest_view: &LatestView + ): u64 { + let initial_ban_duration = get_initial_ban_duration(); + let max_ban_duration = get_max_ban_duration(); + let duration = initial_ban_duration * pow(2, (ban.consecutive_bans as u64)); + let duration = min(duration, max_ban_duration); + let rounds_served = + if (latest_view.epoch > ban.active.epoch_earned) { + ban.active.rounds_served_in_previous_epochs + latest_view.round + } else if (latest_view.epoch == ban.active.epoch_earned && latest_view.round > ban.active.round_earned) { + latest_view.round - ban.active.round_earned + } else { + // The ban hasn't started yet. + 0 + }; + if (duration > rounds_served) { + duration - rounds_served + } else { 0 } + } + + /// Calculate the number of rounds remaining in probation. + /// Probation duration is constant and does not scale with consecutive bans. + fun remaining_probation_duration( + ban: &ValidatorBans, latest_view: &LatestView, probation_duration: u64 + ): u64 { + let rounds_served = + if (latest_view.epoch > ban.active.epoch_earned) { + ban.active.rounds_served_in_previous_epochs + latest_view.round + } else if (latest_view.epoch == ban.active.epoch_earned && latest_view.round > ban.active.round_earned) { + latest_view.round - ban.active.round_earned + } else { + // The ban hasn't started yet. + 0 + }; + if (probation_duration > rounds_served) { + probation_duration - rounds_served + } else { 0 } + } + + /// Returns true until ban registry size + minimum proposers required count less than committee size + fun can_be_banned(ban_registry_len: u64): bool { + let minimum_unbanned_proposers = + leader_ban_registry_config::get_minimum_unbanned_proposers(); + let committee_size = stake::get_committee_size(); + committee_size > ban_registry_len + (minimum_unbanned_proposers as u64) + } + + /// Validates registry initialised if not aborted with `EBAN_REGISTRY_NOT_INITIALIZED` + fun assert_registry_initialized() { + assert!( + exists(@supra_framework), + error::invalid_state(EBAN_REGISTRY_NOT_INITIALIZED) + ); + } + + #[test_only] + public fun get_pool_address_from_vp( + validator_with_pool_addr: &ValidatorBans + ): address { + validator_with_pool_addr.pool_address + } + + #[test_only] + public fun get_consecutive_count_from_vp( + validator_with_pool_addr: &ValidatorBans + ): u32 { + validator_with_pool_addr.consecutive_bans + } + + #[test_only] + public fun is_on_probation_from_vp( + validator_with_pool_addr: &ValidatorBans + ): bool { + validator_with_pool_addr.active.on_probation + } +} diff --git a/aptos-move/framework/supra-framework/sources/reconfiguration.move b/aptos-move/framework/supra-framework/sources/reconfiguration.move index 4e082ad8fac..fe46773ee1e 100644 --- a/aptos-move/framework/supra-framework/sources/reconfiguration.move +++ b/aptos-move/framework/supra-framework/sources/reconfiguration.move @@ -4,6 +4,7 @@ module supra_framework::reconfiguration { use std::error; use std::features; use std::signer; + use supra_framework::leader_ban_registry; use supra_framework::account; use supra_framework::chain_status; @@ -151,6 +152,7 @@ module supra_framework::reconfiguration { // Call stake to compute the new validator set and distribute rewards and transaction fees. stake::on_new_epoch(); + leader_ban_registry::on_new_epoch(); storage_gas::on_reconfig(); assert!(current_time > config_ref.last_reconfiguration_time, error::invalid_state(EINVALID_BLOCK_TIME)); diff --git a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move index 08b0792ce85..8386cf18dd9 100644 --- a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move +++ b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move @@ -10,6 +10,7 @@ module supra_framework::reconfiguration_with_dkg { use supra_framework::jwk_consensus_config; use supra_framework::jwks; use supra_framework::keyless_account; + use supra_framework::leader_ban_registry_config; use supra_framework::randomness_api_v0_config; use supra_framework::randomness_config; use supra_framework::randomness_config_seqnum; @@ -60,6 +61,7 @@ module supra_framework::reconfiguration_with_dkg { jwk_consensus_config::on_new_epoch(framework); jwks::on_new_epoch(framework); keyless_account::on_new_epoch(framework); + leader_ban_registry_config::on_new_epoch(framework); randomness_config_seqnum::on_new_epoch(framework); randomness_config::on_new_epoch(framework); randomness_api_v0_config::on_new_epoch(framework); diff --git a/aptos-move/framework/supra-framework/sources/stake.move b/aptos-move/framework/supra-framework/sources/stake.move index 4b6d9451c22..5717ce4b270 100644 --- a/aptos-move/framework/supra-framework/sources/stake.move +++ b/aptos-move/framework/supra-framework/sources/stake.move @@ -40,6 +40,10 @@ module supra_framework::stake { friend supra_framework::reconfiguration; friend supra_framework::reconfiguration_with_dkg; friend supra_framework::transaction_fee; + friend supra_framework::leader_ban_registry; + + #[test_only] + friend supra_framework::test_leader_ban_registry; /// Validator Config not published. const EVALIDATOR_CONFIG: u64 = 1; @@ -506,6 +510,66 @@ module supra_framework::stake { move_to(supra_framework, SupraCoinCapabilities { mint_cap }) } + /// To get validator pool address from validator index + public(friend) fun get_pool_address_from_index(index: u64) : Option
+ acquires ValidatorSet + { + if (exists(@supra_framework)) { + let validator_set = borrow_global(@supra_framework); + // it can happen that some validator may added a leave request in between + // this can change the order of indexes in active validator + // so need to iterate through all until find pool address in active and pending_active + let (is_index_exist, i) = vector::find(&validator_set.active_validators, |v| { + let v: &ValidatorInfo = v; + v.config.validator_index == index + }); + if (is_index_exist) { + let v_info = vector::borrow(&validator_set.active_validators, i); + return option::some(v_info.addr) + }; + let (is_index_exist, i) = vector::find(&validator_set.pending_inactive, |v| { + let v: &ValidatorInfo = v; + v.config.validator_index == index + }); + if (is_index_exist) { + let v_info = vector::borrow(&validator_set.pending_inactive, i); + return option::some(v_info.addr) + }; + }; + option::none() + } + + /// Returns committee size + public(friend) fun get_committee_size() : u64 + acquires ValidatorSet + { + let commitee_size= 0; + if (exists(@supra_framework)) { + let validator_set = borrow_global(@supra_framework); + commitee_size = vector::length(&validator_set.active_validators) + vector::length(&validator_set.pending_inactive); + }; + commitee_size + } + + /// Returns pool addresses of current committee including pending inactive + public(friend) fun get_committee_pool_addresses() : vector
+ acquires ValidatorSet + { + let pool_addresses= vector::empty(); + if (exists(@supra_framework)) { + let validator_set = borrow_global(@supra_framework); + vector::for_each_ref(&validator_set.active_validators, |validator_info| { + let validator_info: &ValidatorInfo = validator_info; + vector::push_back(&mut pool_addresses, validator_info.addr); + }); + vector::for_each_ref(&validator_set.pending_inactive, |validator_info| { + let validator_info: &ValidatorInfo = validator_info; + vector::push_back(&mut pool_addresses, validator_info.addr); + }); + }; + pool_addresses + } + /// Allow on chain governance to remove validators from the validator set. public fun remove_validators( supra_framework: &signer, diff --git a/aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move b/aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move new file mode 100644 index 00000000000..122871d34aa --- /dev/null +++ b/aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move @@ -0,0 +1,360 @@ +#[test_only] +module std::test_leader_ban_registry { + use std::bcs; + use std::option; + use std::vector; + use aptos_std::ed25519; + use supra_framework::supra_coin; + use supra_framework::coin; + use supra_framework::supra_coin::SupraCoin; + use supra_framework::stake; + use supra_framework::leader_ban_registry; + use supra_framework::leader_ban_registry_config; + use std::signer; + use supra_framework::account; + + fun setup_staking_modules( + sender: &signer, + validator_1: &signer, + validator_2: &signer, + validator_3: &signer, + validator_4: &signer + ) { + // initialise stake module + let (_v_1_s_key, v_1_p_key) = ed25519::generate_keys(); + let (_v_2_s_key, v_2_p_key) = ed25519::generate_keys(); + let (_v_3_s_key, v_3_p_key) = ed25519::generate_keys(); + let (_v_4_s_key, v_4_p_key) = ed25519::generate_keys(); + + stake::initialize_for_test(sender); + account::create_account_for_test(signer::address_of(validator_1)); + coin::register(validator_1); + supra_coin::mint(sender, signer::address_of(validator_1), 10000000000); + + account::create_account_for_test(signer::address_of(validator_2)); + coin::register(validator_2); + supra_coin::mint(sender, signer::address_of(validator_2), 10000000000); + + account::create_account_for_test(signer::address_of(validator_3)); + coin::register(validator_3); + supra_coin::mint(sender, signer::address_of(validator_3), 10000000000); + + account::create_account_for_test(signer::address_of(validator_4)); + coin::register(validator_4); + supra_coin::mint(sender, signer::address_of(validator_4), 10000000000); + + let active_coin = coin::withdraw(validator_1, 500); + let pending_coin = coin::withdraw(validator_1, 1000); + stake::create_stake_pool( + validator_1, + active_coin, + pending_coin, + 500000000 + ); + + let active_coin = coin::withdraw(validator_2, 500); + let pending_coin = coin::withdraw(validator_2, 1000); + stake::create_stake_pool( + validator_2, + active_coin, + pending_coin, + 500000000 + ); + + let active_coin = coin::withdraw(validator_3, 500); + let pending_coin = coin::withdraw(validator_3, 1000); + stake::create_stake_pool( + validator_3, + active_coin, + pending_coin, + 500000000 + ); + + let active_coin = coin::withdraw(validator_4, 500); + let pending_coin = coin::withdraw(validator_4, 1000); + stake::create_stake_pool( + validator_4, + active_coin, + pending_coin, + 500000000 + ); + + stake::join_validator_set_for_test( + &ed25519::public_key_to_unvalidated(&v_4_p_key), + validator_4, + signer::address_of(validator_4), + false + ); + stake::join_validator_set_for_test( + &ed25519::public_key_to_unvalidated(&v_3_p_key), + validator_3, + signer::address_of(validator_3), + false + ); + stake::join_validator_set_for_test( + &ed25519::public_key_to_unvalidated(&v_2_p_key), + validator_2, + signer::address_of(validator_2), + false + ); + stake::join_validator_set_for_test( + &ed25519::public_key_to_unvalidated(&v_1_p_key), + validator_1, + signer::address_of(validator_1), + true + ); // on epoch change + } + + #[ + test( + sender = @supra_framework, + validator_1 = @0xdead01, + validator_2 = @0xdead02, + validator_3 = @0xdead03, + validator_4 = @0xdead04 + ) + ] + fun test_ban_registy_e2e( + sender: &signer, + validator_1: &signer, + validator_2: &signer, + validator_3: &signer, + validator_4: &signer + ) { + // initialise ban registry config + let ban_params = leader_ban_registry_config::get_test_ban_registry_params_v0(); + let ban_config_bytes = bcs::to_bytes(&ban_params); + leader_ban_registry_config::initialize(sender, ban_config_bytes); + + // initialise ban registry + leader_ban_registry::initialize_leader_ban_registry(sender); + setup_staking_modules( + sender, + validator_1, + validator_2, + validator_3, + validator_4 + ); + + // ===== Part 1: Basic ban -> probation -> reinstatement ===== + // Config: initial_ban_duration=4, probation_duration=4, max_ban_duration=20, committee_size=4 + + // Round 0: No failures, registry empty + leader_ban_registry::update_ban_registry(0, 0, option::some(0), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 0, 1); + + // Round 1: Validator 2 (index 1) fails to propose -> banned + leader_ban_registry::update_ban_registry(0, 1, option::some(2), vector[1]); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 1, 2); + assert!( + signer::address_of(validator_2) + == leader_ban_registry::get_pool_address_from_vp( + vector::borrow(&ban_registry, 0) + ), + 3 + ); + + // Round 4: Ban still active (duration=4, rounds_served=3, remaining=1) + leader_ban_registry::update_ban_registry(0, 4, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 1, 4); + let vp = vector::borrow(&ban_registry, 0); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 100); + + // Round 5: Ban expires (rounds_served=4), transitions to probation + leader_ban_registry::update_ban_registry(0, 5, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 1, 5); // Still in registry (on probation) + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 101); + + // Round 9: Probation expires (rounds_served=4), fully reinstated + leader_ban_registry::update_ban_registry(0, 9, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 0, 6); + + // ===== Part 2: Consecutive bans via re-ban during probation ===== + + // Round 12: Validator 1 (index 0) fails -> banned, consecutive=0, duration=4 + leader_ban_registry::update_ban_registry(0, 12, option::some(1), vector[0]); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!( + signer::address_of(validator_1) + == leader_ban_registry::get_pool_address_from_vp(vp), + 7 + ); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 0, 8); + + // Round 16: Ban expires (duration=4) -> probation + leader_ban_registry::update_ban_registry(0, 16, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 102); + + // Round 17: Re-ban during probation -> consecutive=1, duration=8 + leader_ban_registry::update_ban_registry(0, 17, option::some(1), vector[0]); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 1, 9); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 103); + assert!(vector::length(&ban_registry) == 1, 10); + + // Round 25: Ban expires (duration=8) -> probation + leader_ban_registry::update_ban_registry(0, 25, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 104); + + // Round 26: Re-ban during probation -> consecutive=2, duration=16 + leader_ban_registry::update_ban_registry(0, 26, option::some(1), vector[0]); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 2, 11); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 105); + assert!(vector::length(&ban_registry) == 1, 12); + + // Round 42: Ban expires (duration=16) -> probation + leader_ban_registry::update_ban_registry(0, 42, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 106); + + // Round 43: Re-ban during probation -> consecutive=3, duration=min(32,20)=20 + leader_ban_registry::update_ban_registry(0, 43, option::some(1), vector[0]); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 3, 13); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 107); + assert!(vector::length(&ban_registry) == 1, 14); + + // Round 63: Ban expires (duration=20) -> probation + leader_ban_registry::update_ban_registry(0, 63, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 108); + + // Round 64: Re-ban during probation -> consecutive=4, duration=min(64,20)=20 + leader_ban_registry::update_ban_registry(0, 64, option::some(1), vector[0]); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 4, 15); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 109); + assert!(vector::length(&ban_registry) == 1, 16); + + // ===== Part 3: Natural expiry of max-duration ban ===== + // Ban at round 64 with consecutive=4, duration=20 + // Ban expires at round 84, probation starts at 84, probation expires at 88 + + // At round 83, the ban should still be active (1 round remaining) + leader_ban_registry::update_ban_registry(0, 83, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 1, 17); + let vp = vector::borrow(&ban_registry, 0); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 110); // Still banned + + // At round 84, the ban expires and validator transitions to probation + leader_ban_registry::update_ban_registry(0, 84, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 1, 18); // Still in registry (on probation) + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 111); // Now on probation + + // At round 87, probation should still be active (1 round remaining) + leader_ban_registry::update_ban_registry(0, 87, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 1, 19); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 112); + + // At round 88, probation expires and validator is fully reinstated + leader_ban_registry::update_ban_registry(0, 88, option::some(1), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 0, 20); // Fully removed from registry + + // ===== Part 4: Multi-validator banning with proposer limit ===== + // Now lets try to fail 3 of them + leader_ban_registry::update_ban_registry(0, 90, option::some(3), vector[0, 1, 2]); + let ban_registry = leader_ban_registry::get_ban_registry(); + // only 2 will be banned because of proposer limit of 2 + assert!(vector::length(&ban_registry) == 2, 21); + + // Re-ban both validators to increase consecutive count + // Round 94: re-ban, consecutive_bans=1, duration=8, resets from round 94 + leader_ban_registry::update_ban_registry( + 0, 90 + (4 * 1), option::some(2), vector[0, 1] + ); + // Round 98: re-ban, consecutive_bans=2, duration=16, resets from round 98 + leader_ban_registry::update_ban_registry( + 0, 90 + (4 * 2), option::some(2), vector[0, 1] + ); + + // ===== Part 5: Cross-epoch ban management ===== + // Now test ban expiry across epoch change WITHOUT re-banning + // Ban was set at round 98 with duration 16 + // First trigger epoch change + leader_ban_registry::on_new_epoch(); + + // In epoch 1, advance rounds without re-banning to let the ban expire naturally + // For validators banned at epoch 0 round 98: + // After on_new_epoch: rounds_served_in_previous_epochs = 0 + // (since epoch_earned == latest_view.epoch and round_earned == latest_view.round) + + // At epoch 1 round 0, ban should still be active (rounds_served = 0 + 0 = 0, need 16) + leader_ban_registry::update_ban_registry(1, 0, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 2, 22); + let vp = vector::borrow(&ban_registry, 0); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 113); + + // At epoch 1 round 15, ban should still be active (rounds_served = 0 + 15 = 15, need 16) + leader_ban_registry::update_ban_registry(1, 15, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 2, 23); + + // At epoch 1 round 16, ban expires and validators transition to probation + leader_ban_registry::update_ban_registry(1, 16, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 2, 24); // Still in registry (on probation) + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 114); + + // At epoch 1 round 19, probation still active (1 round remaining) + leader_ban_registry::update_ban_registry(1, 19, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 2, 25); + + // At epoch 1 round 20, probation expires and validators are fully reinstated + leader_ban_registry::update_ban_registry(1, 20, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 0, 26); + + // ===== Part 6: Re-ban during probation ===== + // Test: Re-banning during probation should increase consecutive count + // Ban validator 1 fresh + leader_ban_registry::update_ban_registry(1, 25, option::some(2), vector[0]); + let ban_registry = leader_ban_registry::get_ban_registry(); + assert!(vector::length(&ban_registry) == 1, 27); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 0, 115); + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 116); + + // Ban duration = 4 rounds, so ban expires at round 25 + 4 = 29 + // Transition to probation at round 29 + leader_ban_registry::update_ban_registry(1, 29, option::some(2), vector::empty()); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::is_on_probation_from_vp(vp), 117); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 0, 118); + + // Re-ban during probation should increase consecutive count and reset to banned state + leader_ban_registry::update_ban_registry(1, 30, option::some(2), vector[0]); + let ban_registry = leader_ban_registry::get_ban_registry(); + let vp = vector::borrow(&ban_registry, 0); + assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 1, 119); // Consecutive count increased + assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 120); // Back to banned state + + } +} diff --git a/aptos-move/framework/supra-framework/tests/test_leader_ban_registry_config.move b/aptos-move/framework/supra-framework/tests/test_leader_ban_registry_config.move new file mode 100644 index 00000000000..80839a1aeb7 --- /dev/null +++ b/aptos-move/framework/supra-framework/tests/test_leader_ban_registry_config.move @@ -0,0 +1,125 @@ +#[test_only] +module supra_framework::test_leader_ban_registry_config { + use std::bcs; + use std::vector; + use supra_framework::config_buffer; + use supra_framework::leader_ban_registry_config; + + #[test(sender = @0xdead)] + #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] + // signer is not valid + fun test_signer(sender: &signer) { + let ban_registry_param = + leader_ban_registry_config::get_test_ban_registry_params_v0(); + let config_bytes = bcs::to_bytes(&ban_registry_param); + leader_ban_registry_config::initialize(sender, config_bytes); + } + + #[test(sender = @supra_framework)] + #[ + expected_failure( + abort_code = 0x10001, location = supra_framework::leader_ban_registry_config + ) + ] + // Invalid config bytes + fun test_empty_config_value(sender: &signer) { + let config_bytes = vector::empty(); + leader_ban_registry_config::initialize(sender, config_bytes); + } + + #[test(sender = @supra_framework)] + #[ + expected_failure( + abort_code = 0x10003, location = supra_framework::leader_ban_registry_config + ) + ] + // Invalid version bytes + fun test_invalid_config_value(sender: &signer) { + let ban_registry_param = + leader_ban_registry_config::get_test_ban_registry_params_v0(); + let config_bytes = bcs::to_bytes(&ban_registry_param); + vector::push_back(&mut config_bytes, 0); + leader_ban_registry_config::initialize(sender, config_bytes); + } + + public fun init_ban_registry_params(sender: &signer) { + let ban_registry_param = + leader_ban_registry_config::get_test_ban_registry_params_v0(); + let config_bytes = bcs::to_bytes(&ban_registry_param); + leader_ban_registry_config::initialize(sender, config_bytes); + } + + #[test(sender = @supra_framework)] + public fun test_init_config_value(sender: &signer) { + init_ban_registry_params(sender); + assert!(leader_ban_registry_config::check_ban_registry_params_exist(sender), 1); + assert!( + leader_ban_registry_config::check_ban_registry_params_v0_exist(sender), 2 + ); + } + + #[test(sender = @supra_framework)] + #[ + expected_failure( + abort_code = 0x80004, location = supra_framework::leader_ban_registry_config + ) + ] + // Already initialised + fun test_init_config_value_reinit(sender: &signer) { + init_ban_registry_params(sender); + init_ban_registry_params(sender); + } + + #[test(sender = @supra_framework)] + fun test_on_epoch_change(sender: &signer) { + config_buffer::initialize(sender); + assert!( + !leader_ban_registry_config::check_ban_registry_params_exist(sender), 1 + ); + let ban_registry_param = + leader_ban_registry_config::get_test_ban_registry_params_v0(); + let config_bytes = bcs::to_bytes(&ban_registry_param); + leader_ban_registry_config::set_for_next_epoch(sender, config_bytes, 0); + leader_ban_registry_config::on_new_epoch(sender); + assert!(leader_ban_registry_config::check_ban_registry_params_exist(sender), 1); + assert!( + leader_ban_registry_config::check_ban_registry_params_v0_exist(sender), 2 + ); + + let updated_initial_e_denied = 3; + let updated_max_e_denied = 8; + let updated_minimum_u_proposers = 6; + let updated_probation_elections = 2; + + let ban_registry_param = + leader_ban_registry_config::get_custom_ban_registry_params_v0( + updated_initial_e_denied, + updated_max_e_denied, + updated_minimum_u_proposers, + updated_probation_elections + ); + let config_bytes = bcs::to_bytes(&ban_registry_param); + leader_ban_registry_config::set_for_next_epoch(sender, config_bytes, 0); + leader_ban_registry_config::on_new_epoch(sender); + assert!( + leader_ban_registry_config::get_initial_elections_denied() + == updated_initial_e_denied, + 3 + ); + assert!( + leader_ban_registry_config::get_max_elections_denied() + == updated_max_e_denied, + 4 + ); + assert!( + leader_ban_registry_config::get_minimum_unbanned_proposers() + == updated_minimum_u_proposers, + 5 + ); + assert!( + leader_ban_registry_config::get_probation_elections() + == updated_probation_elections, + 6 + ); + } +} diff --git a/aptos-move/framework/supra-stdlib/doc/decode_bcs.md b/aptos-move/framework/supra-stdlib/doc/decode_bcs.md new file mode 100644 index 00000000000..42393b8d8d4 --- /dev/null +++ b/aptos-move/framework/supra-stdlib/doc/decode_bcs.md @@ -0,0 +1,729 @@ + + + +# Module `0x1::decode_bcs` + +This module implements BCS (de)serialization in Move. +Full specification can be found here: https://github.com/diem/bcs + + +- [Struct `BCS`](#0x1_decode_bcs_BCS) +- [Constants](#@Constants_0) +- [Function `to_bytes`](#0x1_decode_bcs_to_bytes) +- [Function `new`](#0x1_decode_bcs_new) +- [Function `into_remainder_bytes`](#0x1_decode_bcs_into_remainder_bytes) +- [Function `peel_bool`](#0x1_decode_bcs_peel_bool) +- [Function `peel_u8`](#0x1_decode_bcs_peel_u8) +- [Function `peel_u16`](#0x1_decode_bcs_peel_u16) +- [Function `peel_u32`](#0x1_decode_bcs_peel_u32) +- [Function `peel_u64`](#0x1_decode_bcs_peel_u64) +- [Function `peel_u128`](#0x1_decode_bcs_peel_u128) +- [Function `peel_u256`](#0x1_decode_bcs_peel_u256) +- [Function `peel_vec_length`](#0x1_decode_bcs_peel_vec_length) +- [Function `peel_vec_bool`](#0x1_decode_bcs_peel_vec_bool) +- [Function `peel_vec_u8`](#0x1_decode_bcs_peel_vec_u8) +- [Function `peel_vec_u16`](#0x1_decode_bcs_peel_vec_u16) +- [Function `peel_vec_u32`](#0x1_decode_bcs_peel_vec_u32) +- [Function `peel_vec_u64`](#0x1_decode_bcs_peel_vec_u64) +- [Function `peel_vec_u128`](#0x1_decode_bcs_peel_vec_u128) +- [Function `peel_vec_u256`](#0x1_decode_bcs_peel_vec_u256) +- [Function `peel_vec_vec_u8`](#0x1_decode_bcs_peel_vec_vec_u8) +- [Function `peel_vec_vec_vec_u8`](#0x1_decode_bcs_peel_vec_vec_vec_u8) +- [Specification](#@Specification_1) + + +
use 0x1::bcs;
+use 0x1::vector;
+
+ + + + + +## Struct `BCS` + +A helper struct that saves resources on operations. For better +vector performance, it stores reversed bytes of the BCS and +enables use of vector::pop_back. + + +
struct BCS has copy, drop, store
+
+ + + +
+Fields + + +
+
+bytes: vector<u8> +
+
+ +
+
+ + +
+ + + +## Constants + + + + +For when ULEB byte is out of range (or not found). + + +
const ELenOutOfRange: u64 = 2;
+
+ + + + + +For when the boolean value different than 0 or 1. + + +
const ENotBool: u64 = 1;
+
+ + + + + +For when bytes length is less than required for deserialization. + + +
const EOutOfRange: u64 = 0;
+
+ + + + + +## Function `to_bytes` + +Get BCS serialized bytes for any value. +Re-exports stdlib bcs::to_bytes. + + +
public fun to_bytes<T>(value: &T): vector<u8>
+
+ + + +
+Implementation + + +
public fun to_bytes<T>(value: &T): vector<u8> {
+    bcs::to_bytes(value)
+}
+
+ + + +
+ + + +## Function `new` + +Creates a new instance of BCS wrapper that holds inversed +bytes for better performance. + + +
public fun new(bytes: vector<u8>): decode_bcs::BCS
+
+ + + +
+Implementation + + +
public fun new(bytes: vector<u8>): BCS {
+    v::reverse(&mut bytes);
+    BCS { bytes }
+}
+
+ + + +
+ + + +## Function `into_remainder_bytes` + +Unpack the BCS struct returning the leftover bytes. +Useful for passing the data further after partial deserialization. + + +
public fun into_remainder_bytes(bcs: decode_bcs::BCS): vector<u8>
+
+ + + +
+Implementation + + +
public fun into_remainder_bytes(bcs: BCS): vector<u8> {
+    let BCS { bytes } = bcs;
+    v::reverse(&mut bytes);
+    bytes
+}
+
+ + + +
+ + + +## Function `peel_bool` + +Read a bool value from bcs-serialized bytes. + + +
public fun peel_bool(bcs: &mut decode_bcs::BCS): bool
+
+ + + +
+Implementation + + +
public fun peel_bool(bcs: &mut BCS): bool {
+    let value = peel_u8(bcs);
+    if (value == 0) {
+        false
+    } else if (value == 1) {
+        true
+    } else {
+        abort ENotBool
+    }
+}
+
+ + + +
+ + + +## Function `peel_u8` + +Read u8 value from bcs-serialized bytes. + + +
public fun peel_u8(bcs: &mut decode_bcs::BCS): u8
+
+ + + +
+Implementation + + +
public fun peel_u8(bcs: &mut BCS): u8 {
+    assert!(v::length(&bcs.bytes) >= 1, EOutOfRange);
+    v::pop_back(&mut bcs.bytes)
+}
+
+ + + +
+ + + +## Function `peel_u16` + +Read u16 value from bcs-serialized bytes. + + +
public fun peel_u16(bcs: &mut decode_bcs::BCS): u16
+
+ + + +
+Implementation + + +
public fun peel_u16(bcs: &mut BCS): u16 {
+    assert!(v::length(&bcs.bytes) >= 2, EOutOfRange);
+    let (value, i) = (0u16, 0u8);
+    while (i < 16) {
+        let byte = (v::pop_back(&mut bcs.bytes) as u16);
+        value = value | (byte << i);
+        i = i + 8;
+    };
+    value
+}
+
+ + + +
+ + + +## Function `peel_u32` + +Read u32 value from bcs-serialized bytes. + + +
public fun peel_u32(bcs: &mut decode_bcs::BCS): u32
+
+ + + +
+Implementation + + +
public fun peel_u32(bcs: &mut BCS): u32 {
+    assert!(v::length(&bcs.bytes) >= 4, EOutOfRange);
+    let (value, i) = (0u32, 0u8);
+    while (i < 32) {
+        let byte = (v::pop_back(&mut bcs.bytes) as u32);
+        value = value | (byte << i);
+        i = i + 8;
+    };
+    value
+}
+
+ + + +
+ + + +## Function `peel_u64` + +Read u64 value from bcs-serialized bytes. + + +
public fun peel_u64(bcs: &mut decode_bcs::BCS): u64
+
+ + + +
+Implementation + + +
public fun peel_u64(bcs: &mut BCS): u64 {
+    assert!(v::length(&bcs.bytes) >= 8, EOutOfRange);
+    let (value, i) = (0u64, 0u8);
+    while (i < 64) {
+        let byte = (v::pop_back(&mut bcs.bytes) as u64);
+        value = value | (byte << i);
+        i = i + 8;
+    };
+    value
+}
+
+ + + +
+ + + +## Function `peel_u128` + +Read u128 value from bcs-serialized bytes. + + +
public fun peel_u128(bcs: &mut decode_bcs::BCS): u128
+
+ + + +
+Implementation + + +
public fun peel_u128(bcs: &mut BCS): u128 {
+    assert!(v::length(&bcs.bytes) >= 16, EOutOfRange);
+
+    let (value, i) = (0u128, 0u8);
+    while (i < 128) {
+        let byte = (v::pop_back(&mut bcs.bytes) as u128);
+        value = value | (byte << i);
+        i = i + 8;
+    };
+
+    value
+}
+
+ + + +
+ + + +## Function `peel_u256` + +Read u256 value from bcs-serialized bytes. + + +
public fun peel_u256(bcs: &mut decode_bcs::BCS): u256
+
+ + + +
+Implementation + + +
public fun peel_u256(bcs: &mut BCS): u256 {
+    assert!(v::length(&bcs.bytes) >= 16, EOutOfRange);
+
+    let (value, i) = (0u256, 0u8);
+    while (i < 255) {
+        let byte = (v::pop_back(&mut bcs.bytes) as u256);
+        value = value | (byte << i);
+        i = i + 8;
+    };
+
+    value
+}
+
+ + + +
+ + + +## Function `peel_vec_length` + +Read ULEB bytes expecting a vector length. Result should +then be used to perform peel_* operation LEN times. + +In BCS vector length is implemented with ULEB128; +See more here: https://en.wikipedia.org/wiki/LEB128 + + +
public fun peel_vec_length(bcs: &mut decode_bcs::BCS): u64
+
+ + + +
+Implementation + + +
public fun peel_vec_length(bcs: &mut BCS): u64 {
+    let (total, shift, len) = (0u64, 0, 0);
+    while (true) {
+        assert!(len <= 4, ELenOutOfRange);
+        let byte = (v::pop_back(&mut bcs.bytes) as u64);
+        len = len + 1;
+        total = total | ((byte & 0x7f) << shift);
+        if ((byte & 0x80) == 0) {
+            break
+        };
+        shift = shift + 7;
+    };
+    total
+}
+
+ + + +
+ + + +## Function `peel_vec_bool` + +Peel a vector of bool from serialized bytes. + + +
public fun peel_vec_bool(bcs: &mut decode_bcs::BCS): vector<bool>
+
+ + + +
+Implementation + + +
public fun peel_vec_bool(bcs: &mut BCS): vector<bool> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_bool(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_u8` + +Peel a vector of u8 (eg string) from serialized bytes. + + +
public fun peel_vec_u8(bcs: &mut decode_bcs::BCS): vector<u8>
+
+ + + +
+Implementation + + +
public fun peel_vec_u8(bcs: &mut BCS): vector<u8> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_u8(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_u16` + +Peel a vector of u16 (eg string) from serialized bytes. + + +
public fun peel_vec_u16(bcs: &mut decode_bcs::BCS): vector<u16>
+
+ + + +
+Implementation + + +
public fun peel_vec_u16(bcs: &mut BCS): vector<u16> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_u16(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_u32` + +Peel a vector of u32 (eg string) from serialized bytes. + + +
public fun peel_vec_u32(bcs: &mut decode_bcs::BCS): vector<u32>
+
+ + + +
+Implementation + + +
public fun peel_vec_u32(bcs: &mut BCS): vector<u32> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_u32(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_u64` + +Peel a vector of u64 from serialized bytes. + + +
public fun peel_vec_u64(bcs: &mut decode_bcs::BCS): vector<u64>
+
+ + + +
+Implementation + + +
public fun peel_vec_u64(bcs: &mut BCS): vector<u64> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_u64(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_u128` + +Peel a vector of u128 from serialized bytes. + + +
public fun peel_vec_u128(bcs: &mut decode_bcs::BCS): vector<u128>
+
+ + + +
+Implementation + + +
public fun peel_vec_u128(bcs: &mut BCS): vector<u128> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_u128(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_u256` + +Peel a vector of u256 from serialized bytes. + + +
public fun peel_vec_u256(bcs: &mut decode_bcs::BCS): vector<u256>
+
+ + + +
+Implementation + + +
public fun peel_vec_u256(bcs: &mut BCS): vector<u256> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_u256(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_vec_u8` + +Peel a vector<vector<u8>> (eg vec of string) from serialized bytes. + + +
public fun peel_vec_vec_u8(bcs: &mut decode_bcs::BCS): vector<vector<u8>>
+
+ + + +
+Implementation + + +
public fun peel_vec_vec_u8(bcs: &mut BCS): vector<vector<u8>> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_vec_u8(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Function `peel_vec_vec_vec_u8` + +Peel a vector<vector<vector<u8>>> (eg vec of string) from serialized bytes. + + +
public fun peel_vec_vec_vec_u8(bcs: &mut decode_bcs::BCS): vector<vector<vector<u8>>>
+
+ + + +
+Implementation + + +
public fun peel_vec_vec_vec_u8(bcs: &mut BCS): vector<vector<vector<u8>>> {
+    let (len, i, res) = (peel_vec_length(bcs), 0, vector[]);
+    while (i < len) {
+        v::push_back(&mut res, peel_vec_vec_u8(bcs));
+        i = i + 1;
+    };
+    res
+}
+
+ + + +
+ + + +## Specification + + + +
pragma verify = false;
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-stdlib/doc/overview.md b/aptos-move/framework/supra-stdlib/doc/overview.md index 08a5aa31ff6..e880ae5616a 100644 --- a/aptos-move/framework/supra-stdlib/doc/overview.md +++ b/aptos-move/framework/supra-stdlib/doc/overview.md @@ -15,6 +15,7 @@ This is the reference documentation of the Supra standard library extension. - [`0x1::bls12381_bulletproofs`](bls12381_bulletproofs.md#0x1_bls12381_bulletproofs) - [`0x1::bls12381_pedersen`](bls12381_pedersen.md#0x1_bls12381_pedersen) - [`0x1::bls12381_scalar`](bls12381_scalar.md#0x1_bls12381_scalar) +- [`0x1::decode_bcs`](decode_bcs.md#0x1_decode_bcs) - [`0x1::enumerable_map`](enumerable_map.md#0x1_enumerable_map) - [`0x1::eth_trie`](eth_trie.md#0x1_eth_trie) - [`0x1::rlp`](rlp.md#0x1_rlp) diff --git a/aptos-move/framework/supra-stdlib/sources/decode_bcs.move b/aptos-move/framework/supra-stdlib/sources/decode_bcs.move new file mode 100644 index 00000000000..5bf4aaca7df --- /dev/null +++ b/aptos-move/framework/supra-stdlib/sources/decode_bcs.move @@ -0,0 +1,370 @@ +/// This module implements BCS (de)serialization in Move. +/// Full specification can be found here: https://github.com/diem/bcs +module supra_std::decode_bcs { + use std::vector as v; + use std::bcs; + + /// For when bytes length is less than required for deserialization. + const EOutOfRange: u64 = 0; + + /// For when the boolean value different than `0` or `1`. + const ENotBool: u64 = 1; + + /// For when ULEB byte is out of range (or not found). + const ELenOutOfRange: u64 = 2; + + /// A helper struct that saves resources on operations. For better + /// vector performance, it stores reversed bytes of the BCS and + /// enables use of `vector::pop_back`. + struct BCS has store, copy, drop { + bytes: vector + } + + /// Get BCS serialized bytes for any value. + /// Re-exports stdlib `bcs::to_bytes`. + public fun to_bytes(value: &T): vector { + bcs::to_bytes(value) + } + + /// Creates a new instance of BCS wrapper that holds inversed + /// bytes for better performance. + public fun new(bytes: vector): BCS { + v::reverse(&mut bytes); + BCS { bytes } + } + + /// Unpack the `BCS` struct returning the leftover bytes. + /// Useful for passing the data further after partial deserialization. + public fun into_remainder_bytes(bcs: BCS): vector { + let BCS { bytes } = bcs; + v::reverse(&mut bytes); + bytes + } + + /// Read a `bool` value from bcs-serialized bytes. + public fun peel_bool(bcs: &mut BCS): bool { + let value = peel_u8(bcs); + if (value == 0) { + false + } else if (value == 1) { + true + } else { + abort ENotBool + } + } + + /// Read `u8` value from bcs-serialized bytes. + public fun peel_u8(bcs: &mut BCS): u8 { + assert!(v::length(&bcs.bytes) >= 1, EOutOfRange); + v::pop_back(&mut bcs.bytes) + } + + /// Read `u16` value from bcs-serialized bytes. + public fun peel_u16(bcs: &mut BCS): u16 { + assert!(v::length(&bcs.bytes) >= 2, EOutOfRange); + let (value, i) = (0u16, 0u8); + while (i < 16) { + let byte = (v::pop_back(&mut bcs.bytes) as u16); + value = value | (byte << i); + i = i + 8; + }; + value + } + + /// Read `u32` value from bcs-serialized bytes. + public fun peel_u32(bcs: &mut BCS): u32 { + assert!(v::length(&bcs.bytes) >= 4, EOutOfRange); + let (value, i) = (0u32, 0u8); + while (i < 32) { + let byte = (v::pop_back(&mut bcs.bytes) as u32); + value = value | (byte << i); + i = i + 8; + }; + value + } + + /// Read `u64` value from bcs-serialized bytes. + public fun peel_u64(bcs: &mut BCS): u64 { + assert!(v::length(&bcs.bytes) >= 8, EOutOfRange); + let (value, i) = (0u64, 0u8); + while (i < 64) { + let byte = (v::pop_back(&mut bcs.bytes) as u64); + value = value | (byte << i); + i = i + 8; + }; + value + } + + /// Read `u128` value from bcs-serialized bytes. + public fun peel_u128(bcs: &mut BCS): u128 { + assert!(v::length(&bcs.bytes) >= 16, EOutOfRange); + + let (value, i) = (0u128, 0u8); + while (i < 128) { + let byte = (v::pop_back(&mut bcs.bytes) as u128); + value = value | (byte << i); + i = i + 8; + }; + + value + } + + /// Read `u256` value from bcs-serialized bytes. + public fun peel_u256(bcs: &mut BCS): u256 { + assert!(v::length(&bcs.bytes) >= 16, EOutOfRange); + + let (value, i) = (0u256, 0u8); + while (i < 255) { + let byte = (v::pop_back(&mut bcs.bytes) as u256); + value = value | (byte << i); + i = i + 8; + }; + + value + } + + // === Vector === + + /// Read ULEB bytes expecting a vector length. Result should + /// then be used to perform `peel_*` operation LEN times. + /// + /// In BCS `vector` length is implemented with ULEB128; + /// See more here: https://en.wikipedia.org/wiki/LEB128 + public fun peel_vec_length(bcs: &mut BCS): u64 { + let (total, shift, len) = (0u64, 0, 0); + while (true) { + assert!(len <= 4, ELenOutOfRange); + let byte = (v::pop_back(&mut bcs.bytes) as u64); + len = len + 1; + total = total | ((byte & 0x7f) << shift); + if ((byte & 0x80) == 0) { + break + }; + shift = shift + 7; + }; + total + } + + /// Peel a vector of `bool` from serialized bytes. + public fun peel_vec_bool(bcs: &mut BCS): vector { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_bool(bcs)); + i = i + 1; + }; + res + } + + /// Peel a vector of `u8` (eg string) from serialized bytes. + public fun peel_vec_u8(bcs: &mut BCS): vector { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_u8(bcs)); + i = i + 1; + }; + res + } + + /// Peel a vector of `u16` (eg string) from serialized bytes. + public fun peel_vec_u16(bcs: &mut BCS): vector { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_u16(bcs)); + i = i + 1; + }; + res + } + + /// Peel a vector of `u32` (eg string) from serialized bytes. + public fun peel_vec_u32(bcs: &mut BCS): vector { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_u32(bcs)); + i = i + 1; + }; + res + } + + /// Peel a vector of `u64` from serialized bytes. + public fun peel_vec_u64(bcs: &mut BCS): vector { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_u64(bcs)); + i = i + 1; + }; + res + } + + /// Peel a vector of `u128` from serialized bytes. + public fun peel_vec_u128(bcs: &mut BCS): vector { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_u128(bcs)); + i = i + 1; + }; + res + } + + /// Peel a vector of `u256` from serialized bytes. + public fun peel_vec_u256(bcs: &mut BCS): vector { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_u256(bcs)); + i = i + 1; + }; + res + } + + /// Peel a `vector>` (eg vec of string) from serialized bytes. + public fun peel_vec_vec_u8(bcs: &mut BCS): vector> { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_vec_u8(bcs)); + i = i + 1; + }; + res + } + + /// Peel a `vector>>` (eg vec of string) from serialized bytes. + public fun peel_vec_vec_vec_u8(bcs: &mut BCS): vector>> { + let (len, i, res) = (peel_vec_length(bcs), 0, vector[]); + while (i < len) { + v::push_back(&mut res, peel_vec_vec_u8(bcs)); + i = i + 1; + }; + res + } + // TODO: re-enable once bit-wise operators in peel_vec_length are supported in the prover + spec module { pragma verify = false; } + + // === Tests === + + #[test_only] + struct Info has drop { a: bool, b: u8, c: u64, d: u128, k: vector, s: address } + + #[test] + #[expected_failure(abort_code = ELenOutOfRange)] + fun test_uleb_len_fail() { + let value = vector[0xff, 0xff, 0xff, 0xff, 0xff]; + let bytes = new(to_bytes(&value)); + let _fail = peel_vec_length(&mut bytes); + abort 2 // TODO: make this test fail + } + + #[test] + #[expected_failure(abort_code = ENotBool)] + fun test_bool_fail() { + let bytes = new(to_bytes(&10u8)); + let _fail = peel_bool(&mut bytes); + } + + #[test] + fun test_bcs() { + + { // boolean: true + let value = true; + let bytes = new(to_bytes(&value)); + assert!(value == peel_bool(&mut bytes), 0); + }; + + { // boolean: false + let value = false; + let bytes = new(to_bytes(&value)); + assert!(value == peel_bool(&mut bytes), 0); + }; + + { // u8 + let value = 100u8; + let bytes = new(to_bytes(&value)); + assert!(value == peel_u8(&mut bytes), 0); + }; + + { // u64 (4 bytes) + let value = 1000100u64; + let bytes = new(to_bytes(&value)); + assert!(value == peel_u64(&mut bytes), 0); + }; + + { // u64 (8 bytes) + let value = 100000000000000u64; + let bytes = new(to_bytes(&value)); + assert!(value == peel_u64(&mut bytes), 0); + }; + + { // u128 (16 bytes) + let value = 100000000000000000000000000u128; + let bytes = new(to_bytes(&value)); + assert!(value == peel_u128(&mut bytes), 0); + }; + + { // vector length + let value = vector[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; + let bytes = new(to_bytes(&value)); + assert!(v::length(&value) == peel_vec_length(&mut bytes), 0); + }; + + { // vector length (more data) + let value = vector[ + 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,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,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,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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ]; + + let bytes = new(to_bytes(&value)); + assert!(v::length(&value) == peel_vec_length(&mut bytes), 0); + }; + + { // full deserialization test (ordering) + let info = Info { a: true, b: 100, c: 9999, d: 112333, k: vector[true, false, true, false], s: @0xAAAAAAAAAAA }; + let bytes = new(to_bytes(&info)); + + assert!(info.a == peel_bool(&mut bytes), 0); + assert!(info.b == peel_u8(&mut bytes), 0); + assert!(info.c == peel_u64(&mut bytes), 0); + assert!(info.d == peel_u128(&mut bytes), 0); + + let len = peel_vec_length(&mut bytes); + + assert!(v::length(&info.k) == len, 0); + + }; + + { // read vector of bytes directly + let value = vector[ + vector[1,2,3,4,5], + vector[1,2,3,4,5], + vector[1,2,3,4,5] + ]; + let bytes = new(to_bytes(&value)); + assert!(value == peel_vec_vec_u8(&mut bytes), 0); + }; + + { // read vector of bytes directly + let value = vector[1,2,3,4,5]; + let bytes = new(to_bytes(&value)); + assert!(value == peel_vec_u8(&mut bytes), 0); + }; + + { // read vector of bytes directly + let value = vector[1,2,3,4,5]; + let bytes = new(to_bytes(&value)); + assert!(value == peel_vec_u64(&mut bytes), 0); + }; + + { // read vector of bytes directly + let value = vector[1,2,3,4,5]; + let bytes = new(to_bytes(&value)); + assert!(value == peel_vec_u128(&mut bytes), 0); + }; + + { // read vector of bytes directly + let value = vector[true, false, true, false]; + let bytes = new(to_bytes(&value)); + assert!(value == peel_vec_bool(&mut bytes), 0); + }; + + } +} \ No newline at end of file From 90c00aa70a967c051d2e11e28b6f12632b482054 Mon Sep 17 00:00:00 2001 From: Jayanth G B Date: Thu, 12 Mar 2026 13:56:38 +0530 Subject: [PATCH 11/31] Update aptos-framework-test.yaml (#345) --- .github/workflows/aptos-framework-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/aptos-framework-test.yaml b/.github/workflows/aptos-framework-test.yaml index b5707ecab49..9920b27f362 100644 --- a/.github/workflows/aptos-framework-test.yaml +++ b/.github/workflows/aptos-framework-test.yaml @@ -22,7 +22,7 @@ env: jobs: build: - runs-on: ghr-elastic-supra-aptos-core-runner + runs-on: [self-hosted, do-ephemeral] timeout-minutes: 90 steps: - name: Install SSH Client From f3040a441d5c418c83cdb682969bb4c9d44a9b43 Mon Sep 17 00:00:00 2001 From: Yogesh <155965081+supra-yoga@users.noreply.github.com> Date: Mon, 16 Mar 2026 11:30:46 +0530 Subject: [PATCH 12/31] Fixes for issues reported in pentesting audit (#338) --- aptos-move/aptos-vm/src/gas.rs | 2 +- .../sources/aggregator_v2/aggregator_v2.move | 4 +- .../sources/automation_registry.move | 34 +++ .../sources/committee_map.move | 246 +++++++++++++++--- .../sources/fungible_asset.move | 48 ++-- .../sources/multisig_voting.move | 6 +- 6 files changed, 280 insertions(+), 60 deletions(-) diff --git a/aptos-move/aptos-vm/src/gas.rs b/aptos-move/aptos-vm/src/gas.rs index 8f7ff2a35b0..d3ea7abc255 100644 --- a/aptos-move/aptos-vm/src/gas.rs +++ b/aptos-move/aptos-vm/src/gas.rs @@ -341,7 +341,7 @@ pub(crate) fn check_gas_for_parameters( speculative_warn!( log_context, format!( - "[VM] Gas unit error; min {}, submitted {}", + "[VM] Gas unit error; max {}, submitted {}", txn_gas_params.max_price_per_gas_unit, txn_gas_metadata.gas_unit_price ), diff --git a/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move b/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move index 6b8ce7fd9a8..77d00e22275 100644 --- a/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move +++ b/aptos-move/framework/supra-framework/sources/aggregator_v2/aggregator_v2.move @@ -38,7 +38,7 @@ module supra_framework::aggregator_v2 { /// The generic type supplied to the aggregator is not supported. const EUNSUPPORTED_AGGREGATOR_TYPE: u64 = 7; - /// Arguments passed to concat exceed max limit of 256 bytes (for prefix and suffix together). + /// Arguments passed to concat exceed max limit of 1024 bytes (for prefix and suffix together). const ECONCAT_STRING_LENGTH_TOO_LARGE: u64 = 8; /// The native aggregator function, that is in the move file, is not yet supported. @@ -194,7 +194,7 @@ module supra_framework::aggregator_v2 { /// Concatenates `before`, `snapshot` and `after` into a single string. /// snapshot passed needs to have integer type - currently supported types are u64 and u128. /// Raises EUNSUPPORTED_AGGREGATOR_SNAPSHOT_TYPE if called with another type. - /// If length of prefix and suffix together exceed 256 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised. + /// If length of prefix and suffix together exceed 1024 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised. /// /// Parallelism info: This operation enables parallelism. public native fun derive_string_concat(before: String, snapshot: &AggregatorSnapshot, after: String): DerivedStringSnapshot; diff --git a/aptos-move/framework/supra-framework/sources/automation_registry.move b/aptos-move/framework/supra-framework/sources/automation_registry.move index 15965aec1d9..405e7859420 100644 --- a/aptos-move/framework/supra-framework/sources/automation_registry.move +++ b/aptos-move/framework/supra-framework/sources/automation_registry.move @@ -820,6 +820,40 @@ module supra_framework::automation_registry { enumerable_map::get_value(®istry_state.main.tasks, task_index) } + /// Retrieves specific metadata details of an automation task entry by its task index. + /// + /// 1. `u64` - The task index. + /// 2. `address` - The owner of the task. + /// 3. `vector` - The payload transaction (encoded). + /// 4. `u64` - The expiry time of the task (timestamp). + /// 5. `vector` - The hash of the transaction. + /// 6. `u64` - The maximum gas amount allowed for the task. + /// 7. `u64` - The gas price cap for executing the task. + /// 8. `u64` - The automation fee cap for the current epoch. + /// 9. `vector>` - Auxiliary data related to the task (can be multiple items). + /// 10. `u64` - The time at which the task was registered (timestamp). + /// 11. `u8` - The state of the task (e.g., active, cancelled, completed). + /// 12. `u64` - The locked fee reserved for the next epoch execution. + // `deconstruct_task_metadata_v2` introduces task index in it's return list + public fun deconstruct_task_metadata_v2( + task_metadata: &AutomationTaskMetaData + ): (u64, address, vector, u64, vector, u64, u64, u64, vector>, u64, u8, u64) { + ( + task_metadata.task_index, + task_metadata.owner, + task_metadata.payload_tx, + task_metadata.expiry_time, + task_metadata.tx_hash, + task_metadata.max_gas_amount, + task_metadata.gas_price_cap, + task_metadata.automation_fee_cap_for_epoch, + task_metadata.aux_data, + task_metadata.registration_time, + task_metadata.state, + task_metadata.locked_fee_for_next_epoch + ) + } + /// Retrieves specific metadata details of an automation task entry by its task index. /// /// 1. `address` - The owner of the task. diff --git a/aptos-move/framework/supra-framework/sources/committee_map.move b/aptos-move/framework/supra-framework/sources/committee_map.move index 25c9a3135a3..2a6bf35ea0f 100644 --- a/aptos-move/framework/supra-framework/sources/committee_map.move +++ b/aptos-move/framework/supra-framework/sources/committee_map.move @@ -16,20 +16,35 @@ module supra_framework::committee_map { use aptos_std::simple_map::{Self, SimpleMap}; use supra_framework::account::{Self, new_event_handle}; - /// The number of committee is not equal to the number of committee member - const INVALID_COMMITTEE_NUMBERS: u64 = 4; + /// The number of committees is not equal to the number of committee members + const EINVALID_COMMITTEE_NUMBERS: u64 = 4; /// The node is not found in the committee - const NODE_NOT_FOUND: u64 = 5; + const ENODE_NOT_FOUND: u64 = 5; /// The committee is not found - const INVALID_COMMITTEE_ID: u64 = 6; + const EINVALID_COMMITTEE_ID: u64 = 6; /// The committee type is invalid - const INVALID_COMMITTEE_TYPE: u64 = 7; + const EINVALID_COMMITTEE_TYPE: u64 = 7; /// The number of nodes in the committee is invalid - const INVALID_NODE_NUMBERS: u64 = 8; + const EINVALID_NODE_NUMBERS: u64 = 8; + + /// The number of nodes in the CLAN is invalid + const EINVALID_CLAN_NODE_NUMBERS: u64 = 9; + + /// The number of nodes in the FAMILY is invalid + const EINVALID_FAMILIY_NODE_NUMBERS: u64 = 10; + + /// The number of nodes in the TRIBE is invalid + const EINVALID_TRIBE_NODE_NUMBERS: u64 = 11; + + /// The number of nodes in the committee is ZERO + const EZERO_COMMITTEE_NODE_NUMBER: u64 = 12; + + /// The number of nodes in the CLAN is too small or even + const ECLAN_TOO_SMALL_OR_EVEN_NODES_IN_CLAN: u64 = 13; /// Define the CommitteeType as constants const FAMILY: u8 = 1; @@ -138,7 +153,7 @@ module supra_framework::committee_map { } /// Internal - Assert if the node exists in the committee fun ensure_node_address_exist(committee: &CommitteeInfo, node_address: address) { - assert!(does_node_exist(committee, node_address), error::invalid_argument(NODE_NOT_FOUND)) + assert!(does_node_exist(committee, node_address), error::invalid_argument(ENODE_NOT_FOUND)) } /// Internal - create OwnerCap @@ -183,20 +198,27 @@ module supra_framework::committee_map { // Function to validate the committee type from an integer fun validate_committee_type(committee_type: u8, num_of_nodes: u64): u8 { - assert!(committee_type >= FAMILY && committee_type <= TRIBE, INVALID_COMMITTEE_TYPE); + assert!(committee_type >= FAMILY && committee_type <= TRIBE, EINVALID_COMMITTEE_TYPE); if (committee_type == FAMILY) { // f+1, number of nodes in a family committee should be greater than 1 - assert!(num_of_nodes > 1, INVALID_NODE_NUMBERS); + assert!(num_of_nodes > 1, EINVALID_FAMILIY_NODE_NUMBERS); } else if (committee_type == CLAN) { - // 2f+1, number of nodes in a clan committee should be odd and greater than 3 - assert!(num_of_nodes >= 3 && num_of_nodes % 2 == 1, INVALID_NODE_NUMBERS); + // 2f+1, number of nodes in a clan committee should be odd and greater than or equal to 3 + assert!(num_of_nodes >= 3 && num_of_nodes % 2 == 1, ECLAN_TOO_SMALL_OR_EVEN_NODES_IN_CLAN); } else { - // 3f+1, number of nodes in a tribe committee should be in the format of 3f+1 and greater than 4 - assert!(num_of_nodes >= 4 && (num_of_nodes - 1) % 3 == 0, INVALID_NODE_NUMBERS); + // 3f+1, number of nodes in a tribe committee should be in the format of 3f+1 and greater than or equal to 4 + assert!(num_of_nodes >= 4 && (num_of_nodes - 1) % 3 == 0, EINVALID_TRIBE_NODE_NUMBERS); }; committee_type } + /// Ensures removing exactly one member keeps the committee type invariants valid. + fun assert_removal_allowed(committee: &CommitteeInfo) { + let current_num_of_nodes = simple_map::length(&committee.map); + assert!(current_num_of_nodes > 0, EZERO_COMMITTEE_NODE_NUMBER); + validate_committee_type(committee.committee_type, current_num_of_nodes - 1); + } + #[view] /// Get the committee's node vector and committee type public fun get_committee_info(com_store_addr: address, id: u64): (vector, u8) acquires CommitteeInfoStore { @@ -249,7 +271,7 @@ module supra_framework::committee_map { let committee = simple_map::borrow(&committee_store.committee_map, &id); let (addrs, nodes) = simple_map::to_vec_pair(committee.map); let (flag, index) = vector::index_of(&addrs, &node_address); - assert!(flag, error::invalid_argument(NODE_NOT_FOUND)); + assert!(flag, error::invalid_argument(ENODE_NOT_FOUND)); let node_info = vector::borrow(&nodes, index); NodeData { @@ -332,31 +354,31 @@ module supra_framework::committee_map { rpc_port: vector, committee_type: u8 ) acquires CommitteeInfoStore, SupraCommitteeEventHandler { - // Assert the length of the vector for two are the same + // Assert the length of the vector for two is the same let node_address_len = vector::length(&node_addresses); assert!( node_address_len == vector::length(&ip_public_address), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&node_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&network_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&cg_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&network_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&rpc_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); // Only the OwnerCap capability can access it let _acquire = &capability::acquire(owner_signer, &OwnerCap {}); @@ -430,31 +452,31 @@ module supra_framework::committee_map { let ids_len = vector::length(&ids); assert!( ids_len == vector::length(&node_addresses_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&ip_public_address_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&node_public_key_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&network_public_key_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&cg_public_key_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&network_port_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&rpc_por_bulkt), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); while (vector::length(&ids) != 0) { let id = vector::pop_back(&mut ids); @@ -494,7 +516,7 @@ module supra_framework::committee_map { let committee_store = borrow_global_mut(com_store_addr); assert!( simple_map::contains_key(&committee_store.committee_map, &id), - error::invalid_argument(INVALID_COMMITTEE_ID) + error::invalid_argument(EINVALID_COMMITTEE_ID) ); let (id, committee_info) = simple_map::remove(&mut committee_store.committee_map, &id); // Also remove the node_to_committee_map @@ -503,7 +525,7 @@ module supra_framework::committee_map { let addr = vector::pop_back(&mut addrs); assert!( simple_map::contains_key(&committee_store.node_to_committee_map, &addr), - error::invalid_argument(NODE_NOT_FOUND) + error::invalid_argument(ENODE_NOT_FOUND) ); simple_map::remove(&mut committee_store.node_to_committee_map, &addr); }; @@ -545,6 +567,27 @@ module supra_framework::committee_map { let _acquire = &capability::acquire(owner_signer, &OwnerCap {}); let committee_store = borrow_global_mut(com_store_addr); + let event_handler = borrow_global_mut(get_committeeInfo_address(owner_signer)); + + // If the node is already associated with another committee, remove the stale entry first. + if (simple_map::contains_key(&committee_store.node_to_committee_map, &node_address)) { + let old_committee_id = *simple_map::borrow(&committee_store.node_to_committee_map, &node_address); + if (old_committee_id != id && simple_map::contains_key(&committee_store.committee_map, &old_committee_id)) { + let old_committee = simple_map::borrow_mut(&mut committee_store.committee_map, &old_committee_id); + if (does_node_exist(old_committee, node_address)) { + assert_removal_allowed(old_committee); + let (_, old_node_info) = simple_map::remove(&mut old_committee.map, &node_address); + emit_event( + &mut event_handler.remove_committee_member, + RemoveCommitteeMemberEvent { + committee_id: old_committee_id, + committee_member: old_node_info + } + ) + } + } + }; + let committee = simple_map::borrow_mut(&mut committee_store.committee_map, &id); let node_info = NodeInfo { ip_public_address: copy ip_public_address, @@ -554,7 +597,6 @@ module supra_framework::committee_map { network_port: network_port, rpc_port: rpc_port, }; - let event_handler = borrow_global_mut(get_committeeInfo_address(owner_signer)); if (!does_node_exist(committee, node_address)) { emit_event( &mut event_handler.add_committee_member, @@ -592,31 +634,31 @@ module supra_framework::committee_map { // Assert the length of the vector for two are the same assert!( vector::length(&ids) == vector::length(&node_addresses), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&ip_public_address), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&node_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&network_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&cg_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&network_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&rpc_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); while (vector::length(&ids) != 0) { let id = vector::pop_back(&mut ids); @@ -655,6 +697,7 @@ module supra_framework::committee_map { let committee_store = borrow_global_mut(com_store_addr); let committee = simple_map::borrow_mut(&mut committee_store.committee_map, &id); ensure_node_address_exist(committee, node_address); + assert_removal_allowed(committee); let (_, node_info) = simple_map::remove(&mut committee.map, &node_address); let event_handler = borrow_global_mut(get_committeeInfo_address(owner_signer)); emit_event( @@ -793,7 +836,7 @@ module supra_framework::committee_map { owner_signer, resource_address, 1, - @0x1, + @0x3, vector[123], vector[123], vector[123], @@ -880,6 +923,131 @@ module supra_framework::committee_map { ); } + #[test(owner_signer = @0xCEFEF)] + #[expected_failure(abort_code = EINVALID_FAMILIY_NODE_NUMBERS, location = Self)] + public entry fun test_remove_committee_member_type_validation( + owner_signer: &signer + ) acquires CommitteeInfoStore, SupraCommitteeEventHandler { + set_up_test(owner_signer); + let resource_address = account::create_resource_address(&@0xCEFEF, SEED_COMMITTEE); + upsert_committee( + owner_signer, + resource_address, + 1, + vector[@0x1, @0x2], + vector[vector[123], vector[124]], + vector[vector[123], vector[124]], + vector[vector[123], vector[124]], + vector[vector[123], vector[124]], + vector[123, 124], + vector[123, 124], + FAMILY + ); + remove_committee_member(owner_signer, resource_address, 1, @0x1); + } + + #[test(owner_signer = @0xCEFEF)] + #[expected_failure(abort_code = EINVALID_FAMILIY_NODE_NUMBERS, location = Self)] + public entry fun test_transfer_member_type_validation( + owner_signer: &signer + ) acquires CommitteeInfoStore, SupraCommitteeEventHandler { + set_up_test(owner_signer); + let resource_address = account::create_resource_address(&@0xCEFEF, SEED_COMMITTEE); + upsert_committee( + owner_signer, + resource_address, + 1, + vector[@0x1, @0x2], + vector[vector[123], vector[124]], + vector[vector[123], vector[124]], + vector[vector[123], vector[124]], + vector[vector[123], vector[124]], + vector[123, 124], + vector[123, 124], + FAMILY + ); + upsert_committee( + owner_signer, + resource_address, + 2, + vector[@0x3, @0x4], + vector[vector[125], vector[126]], + vector[vector[125], vector[126]], + vector[vector[125], vector[126]], + vector[vector[125], vector[126]], + vector[125, 126], + vector[125, 126], + FAMILY + ); + upsert_committee_member( + owner_signer, + resource_address, + 2, + @0x1, + vector[127], + vector[127], + vector[127], + vector[127], + 127, + 127 + ); + } + + #[test(owner_signer = @0xCEFEF)] + public entry fun test_transfer_committee_member_removes_old_committee_entry( + owner_signer: &signer + ) acquires CommitteeInfoStore, SupraCommitteeEventHandler { + set_up_test(owner_signer); + let resource_address = account::create_resource_address(&@0xCEFEF, SEED_COMMITTEE); + upsert_committee( + owner_signer, + resource_address, + 1, + vector[@0x1, @0x2, @0x5], + vector[vector[123], vector[124], vector[125]], + vector[vector[123], vector[124], vector[125]], + vector[vector[123], vector[124], vector[125]], + vector[vector[123], vector[124], vector[125]], + vector[123, 124, 125], + vector[123, 124, 125], + 1 + ); + upsert_committee( + owner_signer, + resource_address, + 2, + vector[@0x3, @0x4], + vector[vector[125], vector[126]], + vector[vector[125], vector[126]], + vector[vector[125], vector[126]], + vector[vector[125], vector[126]], + vector[125, 126], + vector[125, 126], + 1 + ); + upsert_committee_member( + owner_signer, + resource_address, + 2, + @0x1, + vector[127], + vector[127], + vector[127], + vector[127], + 127, + 127 + ); + + let (exists_in_old_committee, _) = find_node_in_committee(resource_address, 1, @0x1); + assert!(!exists_in_old_committee, 1); + assert!(get_committee_id(resource_address, @0x1) == 2, 2); + let (exists_in_new_committee, _) = find_node_in_committee(resource_address, 2, @0x1); + assert!(exists_in_new_committee, 3); + + // Should succeed because node_to_committee_map and committee maps stay in sync. + remove_committee(owner_signer, resource_address, 1); + } + #[test(owner_signer = @0xCEFEF)] public entry fun test_update_dkg_flag( owner_signer: &signer diff --git a/aptos-move/framework/supra-framework/sources/fungible_asset.move b/aptos-move/framework/supra-framework/sources/fungible_asset.move index c0faf2b387c..2fb46269cc6 100644 --- a/aptos-move/framework/supra-framework/sources/fungible_asset.move +++ b/aptos-move/framework/supra-framework/sources/fungible_asset.move @@ -893,21 +893,35 @@ module supra_framework::fungible_asset { ) acquires Metadata { let metadata_address = object::object_address(&metadata_ref.metadata); let mutable_metadata = borrow_global_mut(metadata_address); - - if (option::is_some(&name)){ - mutable_metadata.name = option::extract(&mut name); + + if (option::is_some(&name)) { + let new_name = option::destroy_some(name); + assert!(string::length(&new_name) <= MAX_NAME_LENGTH, error::out_of_range(ENAME_TOO_LONG)); + mutable_metadata.name = new_name; }; - if (option::is_some(&symbol)){ - mutable_metadata.symbol = option::extract(&mut symbol); + + if (option::is_some(&symbol)) { + let new_symbol = option::destroy_some(symbol); + assert!(string::length(&new_symbol) <= MAX_SYMBOL_LENGTH, error::out_of_range(ESYMBOL_TOO_LONG)); + mutable_metadata.symbol = new_symbol; }; - if (option::is_some(&decimals)){ - mutable_metadata.decimals = option::extract(&mut decimals); + + if (option::is_some(&decimals)) { + let new_decimals = option::destroy_some(decimals); + assert!(new_decimals <= MAX_DECIMALS, error::out_of_range(EDECIMALS_TOO_LARGE)); + mutable_metadata.decimals = new_decimals; }; - if (option::is_some(&icon_uri)){ - mutable_metadata.icon_uri = option::extract(&mut icon_uri); + + if (option::is_some(&icon_uri)) { + let new_icon_uri = option::destroy_some(icon_uri); + assert!(string::length(&new_icon_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG)); + mutable_metadata.icon_uri = new_icon_uri; }; - if (option::is_some(&project_uri)){ - mutable_metadata.project_uri = option::extract(&mut project_uri); + + if (option::is_some(&project_uri)) { + let new_project_uri = option::destroy_some(project_uri); + assert!(string::length(&new_project_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG)); + mutable_metadata.project_uri = new_project_uri; }; } @@ -1246,13 +1260,13 @@ module supra_framework::fungible_asset { mutate_metadata( &mutate_metadata_ref, option::some(string::utf8(b"mutated_name")), - option::some(string::utf8(b"mutated_symbol")), + option::some(string::utf8(b"m_symbol")), option::none(), option::none(), option::none() ); assert!(name(metadata) == string::utf8(b"mutated_name"), 8); - assert!(symbol(metadata) == string::utf8(b"mutated_symbol"), 9); + assert!(symbol(metadata) == string::utf8(b"m_symbol"), 9); assert!(decimals(metadata) == 0, 10); assert!(icon_uri(metadata) == string::utf8(b"http://www.example.com/favicon.ico"), 11); assert!(project_uri(metadata) == string::utf8(b"http://www.example.com"), 12); @@ -1327,13 +1341,13 @@ module supra_framework::fungible_asset { mutate_metadata( &mutate_metadata_ref, option::some(string::utf8(b"mutated_name")), - option::some(string::utf8(b"mutated_symbol")), + option::some(string::utf8(b"m_symbol")), option::some(10), option::some(string::utf8(b"http://www.mutated-example.com/favicon.ico")), option::some(string::utf8(b"http://www.mutated-example.com")) ); assert!(name(metadata) == string::utf8(b"mutated_name"), 1); - assert!(symbol(metadata) == string::utf8(b"mutated_symbol"), 2); + assert!(symbol(metadata) == string::utf8(b"m_symbol"), 2); assert!(decimals(metadata) == 10, 3); assert!(icon_uri(metadata) == string::utf8(b"http://www.mutated-example.com/favicon.ico"), 4); assert!(project_uri(metadata) == string::utf8(b"http://www.mutated-example.com"), 5); @@ -1349,13 +1363,13 @@ module supra_framework::fungible_asset { mutate_metadata( &mutate_metadata_ref, option::some(string::utf8(b"mutated_name")), - option::some(string::utf8(b"mutated_symbol")), + option::some(string::utf8(b"m_symbol")), option::none(), option::none(), option::none() ); assert!(name(metadata) == string::utf8(b"mutated_name"), 8); - assert!(symbol(metadata) == string::utf8(b"mutated_symbol"), 9); + assert!(symbol(metadata) == string::utf8(b"m_symbol"), 9); assert!(decimals(metadata) == 0, 10); assert!(icon_uri(metadata) == string::utf8(b"http://www.example.com/favicon.ico"), 11); assert!(project_uri(metadata) == string::utf8(b"http://www.example.com"), 12); diff --git a/aptos-move/framework/supra-framework/sources/multisig_voting.move b/aptos-move/framework/supra-framework/sources/multisig_voting.move index 193c24865e8..7c36e16803c 100644 --- a/aptos-move/framework/supra-framework/sources/multisig_voting.move +++ b/aptos-move/framework/supra-framework/sources/multisig_voting.move @@ -657,7 +657,11 @@ module supra_framework::multisig_voting { ): u64 acquires VotingForum { if (is_voting_closed(voting_forum_address, proposal_id)) { let proposal = get_proposal(voting_forum_address, proposal_id); - if (proposal.yes_votes >= proposal.min_vote_threshold) { + let yes_votes = proposal.yes_votes; + let no_votes = proposal.no_votes; + + if (yes_votes > no_votes && + yes_votes + no_votes >= proposal.min_vote_threshold) { PROPOSAL_STATE_SUCCEEDED } else { PROPOSAL_STATE_FAILED From f487d9b0e5809ea199b7addbd7f91f8af835c6c8 Mon Sep 17 00:00:00 2001 From: Yogesh <155965081+supra-yoga@users.noreply.github.com> Date: Wed, 1 Apr 2026 13:37:02 +0530 Subject: [PATCH 13/31] Update all related Gas schedule parameters as per SUP#3 proposal (#348) --- aptos-move/aptos-gas-schedule-updator/src/lib.rs | 8 +++++--- .../src/gas_schedule/transaction.rs | 16 ++++++++-------- aptos-move/e2e-move-tests/src/harness.rs | 2 +- config/global-constants/src/lib.rs | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/aptos-move/aptos-gas-schedule-updator/src/lib.rs b/aptos-move/aptos-gas-schedule-updator/src/lib.rs index ea4184315f9..9442d92e140 100644 --- a/aptos-move/aptos-gas-schedule-updator/src/lib.rs +++ b/aptos-move/aptos-gas-schedule-updator/src/lib.rs @@ -14,7 +14,6 @@ use aptos_gas_schedule::{ use aptos_package_builder::PackageBuilder; use aptos_types::on_chain_config::GasScheduleV2; use clap::Parser; -use move_core_types::account_address::AccountAddress; use move_model::{code_writer::CodeWriter, emit, emitln, model::Loc}; use std::path::{Path, PathBuf}; @@ -73,8 +72,11 @@ fn generate_script(gas_schedule: &GasScheduleV2) -> Result { emitln!( writer, - "let framework_signer = supra_governance::supra_resolve(proposal_id, @{});\n", - AccountAddress::ONE, + "let framework_signer = supra_governance::resolve_supra_multi_step_proposal( + proposal_id, + @supra_framework, + vector::empty() + );\n" ); emit!(writer, "let gas_schedule_blob: vector = "); diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs index d7f4b30e008..f9bee7c0fcf 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs @@ -175,34 +175,34 @@ crate::gas_schedule::macros::define_gas_parameters!( [ legacy_storage_fee_per_state_slot_create: FeePerSlot, { 7..=13 => "storage_fee_per_state_slot_create", 14.. => "legacy_storage_fee_per_state_slot_create" }, - 50000, + 50000000, ], [ storage_fee_per_state_slot: FeePerSlot, { 14.. => "storage_fee_per_state_slot" }, // 0.8 million SUPRA for 2 billion state slots - 40_000, + 40_000_000, ], [ legacy_storage_fee_per_excess_state_byte: FeePerByte, { 7..=13 => "storage_fee_per_excess_state_byte", 14.. => "legacy_storage_fee_per_excess_state_byte" }, - 50, + 50_000, ], [ storage_fee_per_state_byte: FeePerByte, { 14.. => "storage_fee_per_state_byte" }, // 0.8 million SUPRA for 2 TB state bytes - 40, + 40_000, ], [ legacy_storage_fee_per_event_byte: FeePerByte, { 7..=13 => "storage_fee_per_event_byte", 14.. => "legacy_storage_fee_per_event_byte" }, - 20, + 20_000, ], [ legacy_storage_fee_per_transaction_byte: FeePerByte, { 7..=13 => "storage_fee_per_transaction_byte", 14.. => "legacy_storage_fee_per_transaction_byte" }, - 20, + 20_000, ], [ max_execution_gas: InternalGas, @@ -227,12 +227,12 @@ crate::gas_schedule::macros::define_gas_parameters!( [ max_storage_fee: Fee, { 7.. => "max_storage_fee" }, - 2_0000_0000, // 2 SUPRA + 2_000_0000_0000, // 2000 SUPRA ], [ max_storage_fee_gov: Fee, { RELEASE_V1_13.. => "max_storage_fee.gov" }, - 2_0000_0000, + 2_000_0000_0000, ], [ dependency_per_module: InternalGas, diff --git a/aptos-move/e2e-move-tests/src/harness.rs b/aptos-move/e2e-move-tests/src/harness.rs index ef2925fb553..1f6f92b8254 100644 --- a/aptos-move/e2e-move-tests/src/harness.rs +++ b/aptos-move/e2e-move-tests/src/harness.rs @@ -91,7 +91,7 @@ pub enum BlockSplit { } impl MoveHarness { - const DEFAULT_MAX_GAS_PER_TXN: u64 = 2_000_000; + const DEFAULT_MAX_GAS_PER_TXN: u64 = 100_000_000; /// Creates a new harness. pub fn new() -> Self { diff --git a/config/global-constants/src/lib.rs b/config/global-constants/src/lib.rs index dd5330ee384..ef88fd7d768 100644 --- a/config/global-constants/src/lib.rs +++ b/config/global-constants/src/lib.rs @@ -24,7 +24,7 @@ pub const GENESIS_WAYPOINT: &str = "genesis-waypoint"; #[cfg(any(test, feature = "testing"))] pub const GAS_UNIT_PRICE: u64 = 0; #[cfg(not(any(test, feature = "testing")))] -pub const GAS_UNIT_PRICE: u64 = 100; +pub const GAS_UNIT_PRICE: u64 = 100_000; #[cfg(any(test, feature = "testing"))] pub const MAX_GAS_AMOUNT: u64 = 100_000_000; From da5ffb07f230bac3eafc2678fc099d899d25e284 Mon Sep 17 00:00:00 2001 From: Hamza Saleem Date: Sun, 12 Apr 2026 00:57:34 -0700 Subject: [PATCH 14/31] Feature/dkg integration (#302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update validator pub keys to support dkg * adds blockmetadata flag * featureflag for blockmetadataext * add consenses_key support for past version * add clan, family committee structure * update dkg module to handle new dkg * change dkg.move to use DkgNodeConfig * on going changes * moved dkg transaction validation to aptosvm * adds dkg transaction to post bls pk shares * removed author from dkgmeta * supra dkg feature flag * update validator pub keys to support dkg * adds blockmetadata flag * featureflag for blockmetadataext * add consenses_key support for past version * add clan, family committee structure * update dkg module to handle new dkg * change dkg.move to use DkgNodeConfig * on going changes * moved dkg transaction validation to aptosvm * adds dkg transaction to post bls pk shares * removed author from dkgmeta * supra dkg feature flag * rebase with dev * add dkg validator transaction validation * adds family check in dkg transaction validation * minor * adds feature gating for validator transaction execution * update dkg transaction execution validation * temporarily support old consensus key * added identity to dkg node config * added dkg events * add consensus key rust type * add dkg event try from for Contract event * changes to get dkg move state * added DKGResharing struct * emit dkg update events * impl from dkg events to contract event * to_bytes for consensuskey * update crypto version * update crypto * update crypto * update crypto * update crypto * update crypto * validator key change and refactor * Revert "validator key change and refactor" This reverts commit 3d14a9897f085d037698e8e3bf0dbdf9f47a4684. * updated validator public keys and refactoring * ongoing changes * add gas params for supra_stdlib * fmt * ongoing changes to address comments * ongoing changes * minor fixes * adds new method for ValidatorPublicKeys * new methods for DkgNodeConfig and DkgCommittee * update dkg committee to use validator address as identity * add copyright statements * Update validator_public_keys.move (#305) * Update validator_public_keys.move * Add functions for new CertificateThresholdType constant tags (BCFT and Clan Majority) * addressing comments * rename * fix docs * minor fix * resharing config changed to per receiver committee * add epoch, chain_id in onchainaggcommitments * update validator committee keys after dkg * fix test public key * changes to support arbitrary threshold types * dkg for validity & quorum keys * [#2300] Feature flag. * Sc/task/issue 2242 patch2 (#306) * add supra bcft cert feature flag * update md file * addressing comments * made compatible with the new key format * added a fallback to the old format * parsing ed key by `try_from` instead of bcs * Update dkg.md * fixes * conditional consensus key based on bls flag * update validator_config to use ValidatorPublicKeys * update ValidatorPublicKeys to include bcft keys * update gas ver * add supra_stdlib gas params to_on_chain_gas_schedule * add randomness tag to block_prologue_ext * temporarily mark randomness biasable * add SUPRA_DKG to default features * dkg module fixes * fix dkg transactions error handling in vm * added dkg config * dkg handles all bls key types * remove dkg meta set condition for pk shares * adds dkg threshold type for receiver committees * removed error status DKG_META_NOT_SET * distinguish error code for future/past epochs * fixed leader ban test cases * dkg for bcft and clan majority * update crypto version * adds next_epoch_validator_consensus_infos_for_dkg * feat: changes related to the transaction inclusion proof feature (#341) * feat(types,accumulator): Add features for transactions inclusions and events emissions proofs. - RLP's `Encodable` trait implementation for Contract Events. - `get_proof_by_position` method for Merkle Accumulator. * feat: add `EventV2` api type * chore: cargo feature optimization * refactor(aptos-api-types): transformed `Event` to `EventV1` and applied Full-Clone on `EventV2` * feat: add `hash` in `EventV1` with serialization disabled * docs: fix oai docs for `EventV1` * feat(aptos_api_types): add `try_into_v2_events` to convert `ContractEvent` to `EventV2` * feat: add `SUPRA_TRANSACTIONS_INCLUSION_PROOFS` feature flag * feat: replace rlp encoding with custom encoding to generate event hash * chore: replace `alloy` with `sha3` for `Keccak256` impl * fix: Keccack256 hash implementation using `sha3` --------- Co-authored-by: Nikita Puzankov Co-authored-by: Simon Chen * fix: ensure `hash_bytes` gets updated with finalized hash * Updated crypto ref to revision containing ref to bicycl-rs with fully-qualified SSH submodule refs. * update crypto * Updated minimum GAS_UNIT_PRICE from 100 to 100_000 in accordance with the outcome of https://vote.supra.com/proposal/3. (#344) * test fixes * make order of dkg committee consistent with new epoch committee * Fixed DKG config to account for BCFT flag and added missing threshold. Added comments. Regenerated docs. * Fixed DKG config and removed unnecessary test. * Discovered that DKG config is initialised during genesis before feature flags are set, so updated implementation accordingly and added notes. Also fixed supra_governance::reconfigure. * Formatting. * Started work towards adding leader ban registry config to genesis. (#346) * Started work towards adding leader ban registry config to genesis. * added remaining changes for the leader ban config at genesis * added deserilization step * added deserilization step * added deserilization step * fixed leader ban registry package for ban parameters * decoded correct version of params --------- Co-authored-by: Dhaval Purohit * Formatting. * Added TypeTags for UpdateNetworkAndFullnodeAddressesEvent and RotateConsensusKeyEvent. * Added fixes for leader ban registry view (#350) * added fixes for leader ban registry view * fixed the test according to updated changes * PR comments addressed * addressing comments * reverse pending active order for next_validator_consensus_infos --------- Co-authored-by: simonchen-supra Co-authored-by: Isaac Doidge Co-authored-by: Mateusz Zając Co-authored-by: Dhaval Purohit Co-authored-by: Panchal Vedant Co-authored-by: Nikita Puzankov Co-authored-by: Isaac Doidge <30425649+isaacdoidge@users.noreply.github.com> --- .cargo/config.toml | 6 + .cursorrules | 32 + Cargo.lock | 4918 +++++++++++------ Cargo.toml | 6 +- api/src/events.rs | 2 +- api/src/tests/multisig_transactions_test.rs | 30 +- api/src/transactions.rs | 5 +- api/test-context/move/Move.toml | 2 +- api/types/Cargo.toml | 1 + api/types/src/convert.rs | 36 +- api/types/src/lib.rs | 4 +- api/types/src/transaction.rs | 212 +- .../src/execute_pending_block.rs | 12 +- .../aptos-e2e-comparison-testing/Cargo.toml | 1 - aptos-move/aptos-gas-algebra/src/algebra.rs | 2 +- aptos-move/aptos-gas-profiling/src/erased.rs | 6 +- .../src/gas_schedule/aptos_framework.rs | 4 +- .../src/gas_schedule/mod.rs | 11 + .../src/gas_schedule/supra_stdlib.rs | 21 + aptos-move/aptos-gas-schedule/src/ver.rs | 3 +- aptos-move/aptos-release-builder/Cargo.toml | 2 +- .../src/components/feature_flags.rs | 16 + .../src/components/framework.rs | 13 +- .../src/components/mod.rs | 3 +- .../aptos-release-builder/src/validate.rs | 2 +- .../aptos-transaction-benchmarks/Cargo.toml | 2 +- .../src/aptos_test_harness.rs | 2 +- .../src/rest_interface.rs | 11 +- .../samples/do-nothing/Move.toml | 2 +- aptos-move/aptos-vm-profiling/Cargo.toml | 2 +- aptos-move/aptos-vm/Cargo.toml | 11 +- aptos-move/aptos-vm/src/aptos_vm.rs | 170 +- aptos-move/aptos-vm/src/aptos_vm_viewer.rs | 19 +- .../src/automated_transaction_processor.rs | 63 +- ...tomation_registry_transaction_processor.rs | 38 +- aptos-move/aptos-vm/src/gas.rs | 71 +- aptos-move/aptos-vm/src/lib.rs | 18 +- .../src/move_vm_ext/session/session_id.rs | 9 +- .../aptos-vm/src/system_module_names.rs | 1 + .../aptos-vm/src/transaction_metadata.rs | 38 +- .../aptos-vm/src/transaction_validation.rs | 17 +- aptos-move/aptos-vm/src/validator_txns/dkg.rs | 103 +- aptos-move/aptos-vm/src/validator_txns/mod.rs | 17 +- .../verifier/transaction_arg_validation.rs | 87 +- aptos-move/e2e-move-tests/src/lib.rs | 5 +- .../e2e-move-tests/src/supra_governance.rs | 5 +- .../src/tests/fungible_asset.rs | 30 +- .../test/Move.toml | 1 - aptos-move/e2e-move-tests/src/tests/vote.rs | 43 +- aptos-move/e2e-tests/Cargo.toml | 2 +- aptos-move/e2e-testsuite/Cargo.toml | 6 +- .../src/tests/automated_transactions.rs | 12 +- .../src/tests/automation_registration.rs | 113 +- .../src/tests/genesis_initializations.rs | 10 +- aptos-move/e2e-testsuite/src/tests/mod.rs | 4 +- .../e2e-testsuite/src/tests/vm_viewer.rs | 22 +- aptos-move/framework/Cargo.toml | 1 + aptos-move/framework/aptos-stdlib/Move.toml | 2 +- .../framework/aptos-stdlib/sources/any.move | 2 +- .../framework/aptos-token-objects/Move.toml | 2 +- aptos-move/framework/aptos-token/Move.toml | 2 +- .../src/aptos_framework_sdk_builder.rs | 16 +- aptos-move/framework/move-stdlib/Cargo.toml | 2 +- .../framework/move-stdlib/doc/features.md | 251 + .../move-stdlib/sources/configs/features.move | 55 + .../natives/automation_registry_callbacks.rs | 22 +- .../cryptography/bls12381_bulletproofs.rs | 19 +- .../natives/cryptography/bls12381_scalar.rs | 47 +- .../src/natives/cryptography/class_groups.rs | 78 + .../src/natives/cryptography/eth_trie.rs | 40 +- .../framework/src/natives/cryptography/mod.rs | 7 +- aptos-move/framework/src/natives/mod.rs | 18 +- aptos-move/framework/src/natives/rlp.rs | 246 +- aptos-move/framework/src/release_bundle.rs | 19 +- .../supra-framework/doc/aggregator_v2.md | 4 +- .../doc/automation_registry.md | 54 + .../framework/supra-framework/doc/block.md | 144 +- .../supra-framework/doc/committee_map.md | 191 +- .../framework/supra-framework/doc/dkg.md | 385 +- .../supra-framework/doc/dkg_committee.md | 499 ++ .../supra-framework/doc/dkg_config.md | 574 ++ .../supra-framework/doc/evm_config.md | 17 + .../supra-framework/doc/fungible_asset.md | 34 +- .../framework/supra-framework/doc/genesis.md | 672 ++- .../doc/leader_ban_registry.md | 1165 ++++ .../doc/leader_ban_registry_config.md | 541 ++ .../supra-framework/doc/multisig_voting.md | 6 +- .../framework/supra-framework/doc/overview.md | 5 + .../supra-framework/doc/randomness.md | 37 +- .../supra-framework/doc/reconfiguration.md | 2 + .../doc/reconfiguration_with_dkg.md | 68 +- .../framework/supra-framework/doc/stake.md | 1761 ++++-- .../supra-framework/doc/supra_governance.md | 301 +- .../doc/validator_public_keys.md | 985 ++++ .../doc/vesting_without_staking.md | 2 +- .../supra-framework/sources/block.move | 161 +- .../sources/configs/config_buffer.move | 1 + .../sources/configs/dkg_config.move | 411 ++ .../supra-framework/sources/dkg.move | 150 +- .../supra-framework/sources/dkg.spec.move | 15 +- .../sources/dkg_committee.move | 123 + .../supra-framework/sources/genesis.move | 852 +-- .../sources/leader_ban_registry.move | 235 +- .../sources/pbo_delegation_pool.move | 2 +- .../supra-framework/sources/randomness.move | 123 +- .../sources/reconfiguration_with_dkg.move | 48 +- .../supra-framework/sources/stake.move | 1989 ++++--- .../supra-framework/sources/stake.spec.move | 11 +- .../sources/supra_governance.move | 579 +- .../sources/validator_public_keys.move | 259 + .../sources/vesting_without_staking.move | 72 +- .../delegation_pool_integration_tests.move | 2 +- .../tests/test_leader_ban_registry.move | 57 +- .../supra-stdlib/doc/class_groups.md | 125 + .../supra-stdlib/doc/consensus_key.md | 285 + .../framework/supra-stdlib/doc/overview.md | 1 + .../supra-stdlib/sources/class_groups.move | 48 + aptos-move/framework/tests/move_unit_test.rs | 4 +- aptos-move/move-examples/Cargo.toml | 2 +- aptos-move/move-examples/cli_args/Move.toml | 2 +- aptos-move/move-examples/event/Move.toml | 1 - .../fungible_asset/stablecoin/Move.toml | 4 +- .../move-examples/hello_prover/Move.toml | 2 - .../mint_nft/3-Adding-Admin/Move.toml | 2 +- .../4-Getting-Production-Ready/Move.toml | 2 +- .../my_first_dapp/move/Move.toml | 2 +- aptos-move/move-examples/raffle/Move.toml | 2 +- .../move-examples/tic-tac-toe/Move.toml | 1 - .../upgrade_and_govern/genesis/Move.toml | 2 +- .../upgrade_and_govern/upgrade/Move.toml | 2 +- aptos-move/vm-genesis/Cargo.toml | 13 +- aptos-move/vm-genesis/src/lib.rs | 82 +- aptos-node/Cargo.toml | 19 +- config/global-constants/src/lib.rs | 2 + config/src/config/identity_config.rs | 2 +- consensus/Cargo.toml | 12 +- consensus/src/epoch_manager.rs | 2 +- consensus/src/payload_client/mixed.rs | 8 +- .../fairness/conflict_key/entry_fun.rs | 8 +- .../fairness/conflict_key/entry_fun_module.rs | 4 +- consensus/src/util/mod.rs | 1 + crates/aptos-collections/Cargo.toml | 2 +- crates/aptos-crypto/Cargo.toml | 6 + crates/aptos-crypto/src/hash.rs | 5 +- crates/aptos-dkg/Cargo.toml | 2 +- crates/aptos-faucet/cli/Cargo.toml | 1 - crates/aptos-faucet/core/Cargo.toml | 12 +- .../core/src/checkers/redis_ratelimit.rs | 2 +- crates/aptos-faucet/metrics-server/Cargo.toml | 2 +- crates/aptos-genesis/src/builder.rs | 6 +- crates/aptos-genesis/src/config.rs | 8 +- crates/aptos-genesis/src/lib.rs | 8 +- crates/aptos-genesis/src/mainnet.rs | 9 +- crates/aptos-id-generator/Cargo.toml | 1 - crates/aptos-infallible/Cargo.toml | 1 - crates/aptos-keygen/Cargo.toml | 1 - crates/aptos-log-derive/Cargo.toml | 2 - crates/aptos-network-checker/Cargo.toml | 1 - crates/aptos-profiler/Cargo.toml | 1 - crates/aptos-proptest-helpers/Cargo.toml | 2 - crates/aptos-rate-limiter/Cargo.toml | 1 - crates/aptos-retrier/Cargo.toml | 1 - crates/aptos-rosetta-cli/Cargo.toml | 1 - crates/aptos-rosetta/src/types/objects.rs | 5 +- crates/aptos-temppath/Cargo.toml | 2 - crates/aptos/Cargo.toml | 9 +- crates/aptos/src/account/multisig_account.rs | 13 +- crates/aptos/src/common/types.rs | 4 +- crates/aptos/src/genesis/mod.rs | 2 + crates/aptos/src/governance/mod.rs | 74 +- crates/aptos/src/lib.rs | 2 +- crates/aptos/src/move_tool/mod.rs | 5 +- crates/aptos/src/move_tool/stored_package.rs | 5 +- crates/aptos/src/node/mod.rs | 2 +- crates/aptos/src/supra_specific.rs | 7 +- crates/fallible/Cargo.toml | 2 - crates/indexer/Cargo.toml | 10 +- crates/indexer/src/indexer/fetcher.rs | 3 + .../coin_models/account_transactions.rs | 4 +- .../src/models/coin_models/coin_activities.rs | 2 +- crates/indexer/src/models/events.rs | 2 +- .../models/token_models/token_activities.rs | 2 +- .../token_models/v2_token_activities.rs | 2 +- .../src/models/token_models/v2_token_utils.rs | 6 +- crates/indexer/src/models/transactions.rs | 1 + crates/proxy/Cargo.toml | 2 - crates/supra/src/lib.rs | 6 +- .../validator-transaction-pool/src/tests.rs | 14 +- dkg/src/agg_trx_producer.rs | 2 +- dkg/src/counters.rs | 6 +- dkg/src/dkg_manager/mod.rs | 2 +- dkg/src/dkg_manager/tests.rs | 2 +- dkg/src/epoch_manager.rs | 2 +- dkg/src/lib.rs | 2 +- dkg/src/transcript_aggregation/mod.rs | 2 +- dkg/src/transcript_aggregation/tests.rs | 2 +- dkg/src/types.rs | 2 +- .../indexer-grpc-fullnode/src/convert.rs | 83 +- .../indexer-grpc-table-info/Cargo.toml | 2 +- .../indexer-grpc-utils/src/cache_operator.rs | 4 +- .../src/boolean_transaction_filter.rs | 1 + .../nft-metadata-crawler-parser/Cargo.toml | 10 +- execution/block-partitioner/Cargo.toml | 1 - execution/executor-benchmark/Cargo.toml | 8 +- execution/executor-service/Cargo.toml | 2 +- execution/executor-types/src/lib.rs | 2 +- execution/executor/Cargo.toml | 7 +- .../executor/src/components/chunk_output.rs | 10 +- keyless/circuit/Cargo.toml | 7 +- mempool/Cargo.toml | 7 +- network/framework/Cargo.toml | 21 +- protos/python/pyproject.toml | 2 +- protos/rust/src/pb/aptos.transaction.v1.rs | 74 +- .../rust/src/pb/aptos.transaction.v1.serde.rs | 703 ++- rust-toolchain.toml | 2 +- sdk/src/transaction_builder.rs | 4 +- storage/accumulator/src/lib.rs | 19 + storage/aptosdb/Cargo.toml | 21 +- .../src/backup_types/transaction/analysis.rs | 5 +- storage/indexer_schemas/Cargo.toml | 7 +- storage/jellyfish-merkle/Cargo.toml | 7 +- testsuite/forge/Cargo.toml | 9 +- testsuite/fuzzer/.cargo/config.toml | 22 +- testsuite/pyproject.toml | 2 +- testsuite/smoke-test/Cargo.toml | 11 +- .../evm/hardhat-examples/package-lock.json | 3334 +++++++++-- .../extensions/async/move-async-vm/Cargo.toml | 4 +- .../move-table-extension/Cargo.toml | 4 +- .../move/move-binary-format/Cargo.toml | 7 +- .../bytecode-verifier-tests/Cargo.toml | 4 +- .../move-bytecode-verifier/fuzz/Cargo.toml | 4 +- third_party/move/move-core/types/Cargo.toml | 4 +- .../move/move-core/types/src/vm_status.rs | 21 +- .../diem-framework/crates/crypto/Cargo.toml | 31 +- third_party/move/move-prover/lab/Cargo.toml | 6 +- .../lab/data/aptos-framework/prover.toml | 20 +- .../lab/data/diem-framework/prover.toml | 18 +- .../lab/data/mono/mono_backend.toml | 1 + .../current_boogie_1.toml | 20 +- .../current_boogie_2.toml | 20 +- .../current_boogie_3.toml | 20 +- .../new_boogie_1.toml | 20 +- .../new_boogie_2.toml | 20 +- .../new_boogie_3.toml | 20 +- .../current_boogie_1.toml | 18 +- .../current_boogie_2.toml | 18 +- .../current_boogie_3.toml | 18 +- .../new-boogie-aptos-stdlib/new_boogie_1.toml | 18 +- .../new-boogie-aptos-stdlib/new_boogie_2.toml | 18 +- .../new-boogie-aptos-stdlib/new_boogie_3.toml | 18 +- .../current_boogie.toml | 18 +- .../new-boogie-diem-framework/new_boogie.toml | 18 +- .../new_boogie_1.toml | 18 +- .../new_boogie_2.toml | 18 +- .../new_boogie_3.toml | 18 +- .../lab/data/test/prover_stdlib.toml | 4 +- .../move/move-vm/integration-tests/Cargo.toml | 8 +- .../move/move-vm/paranoid-tests/Cargo.toml | 4 +- third_party/move/move-vm/types/Cargo.toml | 4 +- .../transactional-test-runner/Cargo.toml | 4 +- .../multiple_deps_rename/Move.toml | 4 +- .../multiple_deps_rename_one/Move.toml | 2 +- .../model/multiple_deps_rename/Move.toml | 4 +- .../no_path_set_for_dependency/Move.toml | 2 +- .../Move.toml | 2 +- .../resolution/dep_good_digest/Move.toml | 2 +- .../resolution/multiple_deps_rename/Move.toml | 4 +- .../resolution/one_dep_bad_digest/Move.toml | 2 +- .../move/tools/move-unit-test/Cargo.toml | 4 +- types/Cargo.toml | 14 +- types/src/account_config/events/coin.rs | 10 +- types/src/account_config/events/fa.rs | 8 +- types/src/account_config/events/mod.rs | 8 +- types/src/{dkg => aptos_dkg}/dummy_dkg/mod.rs | 2 +- .../src/{dkg => aptos_dkg}/dummy_dkg/tests.rs | 2 +- types/src/aptos_dkg/mod.rs | 219 + types/src/{dkg => aptos_dkg}/real_dkg/mod.rs | 2 +- .../real_dkg/rounding/mod.rs | 0 .../real_dkg/rounding/tests.rs | 2 +- types/src/contract_event.rs | 101 +- types/src/dkg/dkg_committee.rs | 55 + types/src/dkg/events.rs | 46 + types/src/dkg/mod.rs | 261 +- types/src/dkg/state.rs | 70 + types/src/dkg/transactions.rs | 77 + types/src/lib.rs | 2 + types/src/on_chain_config/aptos_features.rs | 12 + .../on_chain_config/automation_registry.rs | 13 +- .../src/on_chain_config/evm_genesis_config.rs | 21 +- .../on_chain_config/leader_ban_registry.rs | 95 + types/src/on_chain_config/mod.rs | 26 +- types/src/proof/definition.rs | 24 +- types/src/proof/position/mod.rs | 6 +- types/src/proptest_types.rs | 17 +- types/src/stake_pool.rs | 36 +- .../src/transaction/automated_transaction.rs | 42 +- types/src/transaction/automation.rs | 92 +- types/src/transaction/mod.rs | 30 +- types/src/transaction/multisig.rs | 44 +- .../transaction/user_transaction_context.rs | 1 - types/src/unit_tests/automation.rs | 44 +- types/src/unit_tests/mod.rs | 2 +- types/src/validator_config.rs | 24 +- types/src/validator_info.rs | 9 +- types/src/validator_public_keys.rs | 82 + types/src/validator_txn.rs | 27 +- vm-validator/Cargo.toml | 2 +- vm-validator/src/mocks/mock_vm_validator.rs | 11 +- 308 files changed, 20288 insertions(+), 6703 deletions(-) create mode 100644 .cursorrules create mode 100644 aptos-move/aptos-gas-schedule/src/gas_schedule/supra_stdlib.rs create mode 100644 aptos-move/framework/src/natives/cryptography/class_groups.rs create mode 100644 aptos-move/framework/supra-framework/doc/dkg_committee.md create mode 100644 aptos-move/framework/supra-framework/doc/dkg_config.md create mode 100644 aptos-move/framework/supra-framework/doc/leader_ban_registry.md create mode 100644 aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md create mode 100644 aptos-move/framework/supra-framework/doc/validator_public_keys.md create mode 100644 aptos-move/framework/supra-framework/sources/configs/dkg_config.move create mode 100644 aptos-move/framework/supra-framework/sources/dkg_committee.move create mode 100644 aptos-move/framework/supra-framework/sources/validator_public_keys.move create mode 100644 aptos-move/framework/supra-stdlib/doc/class_groups.md create mode 100644 aptos-move/framework/supra-stdlib/doc/consensus_key.md create mode 100644 aptos-move/framework/supra-stdlib/sources/class_groups.move rename types/src/{dkg => aptos_dkg}/dummy_dkg/mod.rs (98%) rename types/src/{dkg => aptos_dkg}/dummy_dkg/tests.rs (99%) create mode 100644 types/src/aptos_dkg/mod.rs rename types/src/{dkg => aptos_dkg}/real_dkg/mod.rs (99%) rename types/src/{dkg => aptos_dkg}/real_dkg/rounding/mod.rs (100%) rename types/src/{dkg => aptos_dkg}/real_dkg/rounding/tests.rs (99%) create mode 100644 types/src/dkg/dkg_committee.rs create mode 100644 types/src/dkg/events.rs create mode 100644 types/src/dkg/state.rs create mode 100644 types/src/dkg/transactions.rs create mode 100644 types/src/on_chain_config/leader_ban_registry.rs create mode 100644 types/src/validator_public_keys.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 07145d29e29..6b1bf7358cd 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -34,6 +34,8 @@ rustflags = [ "--cfg", "tokio_unstable", "-C", + "linker=clang", + "-C", "link-arg=-fuse-ld=lld", "-C", "force-frame-pointers=yes", @@ -55,3 +57,7 @@ rustflags = [ "-C", "link-arg=/STACK:8000000", # Set stack to 8 MB ] + +[env] +CMAKE_POLICY_VERSION_MINIMUM = "3.5" +CXXFLAGS = "-include cstdint" # Needed for `librocksdb-sys` build diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 00000000000..fd8b71bdf30 --- /dev/null +++ b/.cursorrules @@ -0,0 +1,32 @@ +# Supra Move Development Rules + +CRITICAL: This is a Supra Move project, NOT Aptos Move. Never use aptos_framework. + +## Framework Rules: +1. ALWAYS use supra_framework:: instead of aptos_framework:: +2. Available namespaces: supra_framework::, std:: +3. Main modules in supra_framework: config_buffer, create_signer, system_addresses, block, reconfiguration, reconfiguration_with_dkg, genesis, automation_registry, event, randomness, state_storage, transaction_fee, util, fungible_asset, multisig_account, function_info, validator_consensus_info, dispatchable_fungible_asset, aggregator_v2, aggregator_factory, chain_id, chain_status, consensus_config, execution_config, gas_schedule, pbo_delegation_pool, staking_config, staking_contract, storage_gas, supra_config, supra_governance, timestamp, transaction_validation, version, vesting, vesting_without_staking, supra_coin, account, supra_account +4. Standard library modules: vector, table, borrow_mut, error, features, option, signer, string, fixed_point32 + +## Code Generation Rules: +- Use supra_framework::account for account operations +- Use supra_framework::supra_coin for native token operations +- Use supra_framework::timestamp for time operations +- Use supra_framework::event for event handling +- Use std::vector for vector operations +- Use std::table for table operations + +## Example Patterns: +```move +module supra_framework::example { + use supra_framework::account; + use supra_framework::signer; + use std::vector; + + public fun init(account: &signer) { + // Supra Move code + } +} +``` + +When generating Move code, ALWAYS use the Supra Move framework patterns above. \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 8e4aa24a6aa..a421b5f5879 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,18 +31,18 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" @@ -56,9 +56,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -96,19 +96,19 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.11", + "getrandom 0.2.17", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.11", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -131,15 +131,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - -[[package]] -name = "android-tzdata" -version = "0.1.1" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" @@ -167,50 +161,52 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] @@ -221,9 +217,9 @@ checksum = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" dependencies = [ "backtrace", ] @@ -277,9 +273,9 @@ dependencies = [ "bcs 0.1.4", "bollard", "chrono", - "clap 4.4.14", + "clap 4.5.58", "clap_complete", - "dashmap", + "dashmap 5.5.3", "diesel", "diesel-async", "dirs", @@ -314,7 +310,7 @@ dependencies = [ "shadow-rs", "supra-aptos", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "toml 0.7.8", "tonic", @@ -362,7 +358,7 @@ dependencies = [ "aptos-system-utils", "aptos-types", "bcs 0.1.4", - "http", + "http 0.2.12", "hyper", "sha256", "tokio", @@ -525,6 +521,7 @@ dependencies = [ "poem-openapi-derive", "serde", "serde_json", + "sha3 0.9.1", ] [[package]] @@ -552,7 +549,7 @@ dependencies = [ "async-trait", "bcs 0.1.4", "bytes", - "clap 4.4.14", + "clap 4.5.58", "csv", "futures", "itertools 0.12.1", @@ -568,11 +565,11 @@ dependencies = [ "serde", "serde_json", "serde_yaml 0.8.26", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-io-timeout", "tokio-stream", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "warp", ] @@ -641,7 +638,7 @@ dependencies = [ "concurrent-queue", "criterion", "crossbeam", - "dashmap", + "dashmap 5.5.3", "derivative", "fail", "itertools 0.12.1", @@ -650,7 +647,7 @@ dependencies = [ "move-vm-types", "num_cpus", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "proptest", "proptest-derive", "rand 0.7.3", @@ -668,9 +665,9 @@ dependencies = [ "aptos-metrics-core", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "criterion", - "dashmap", + "dashmap 5.5.3", "itertools 0.12.1", "jemallocator", "move-core-types", @@ -718,10 +715,10 @@ dependencies = [ "anyhow", "camino", "chrono", - "clap 4.4.14", + "clap 4.5.58", "clap-verbosity-flag", "determinator", - "env_logger", + "env_logger 0.10.2", "guppy", "log", "reqwest", @@ -745,7 +742,7 @@ name = "aptos-cli-common" version = "1.0.0" dependencies = [ "anstyle", - "clap 4.4.14", + "clap 4.5.58", "clap_complete", ] @@ -765,7 +762,7 @@ dependencies = [ "aptos-validator-interface", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "futures", "itertools 0.12.1", "move-compiler", @@ -792,7 +789,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -822,7 +819,7 @@ dependencies = [ "serde_merge", "serde_yaml 0.8.26", "tempfile", - "thiserror", + "thiserror 1.0.69", "url", ] @@ -875,8 +872,8 @@ dependencies = [ "bytes", "chrono", "claims", - "clap 4.4.14", - "dashmap", + "clap 4.5.58", + "dashmap 5.5.3", "enum_dispatch", "fail", "futures", @@ -904,7 +901,7 @@ dependencies = [ "sha3 0.9.1", "strum_macros 0.24.3", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-retry", "tokio-stream", @@ -922,7 +919,7 @@ dependencies = [ "futures", "move-core-types", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -993,7 +990,7 @@ dependencies = [ "curve25519-dalek-ng", "digest 0.9.0", "ed25519-dalek 1.0.1", - "ff 0.13.0", + "ff 0.13.1", "hex", "hkdf 0.10.0", "libsecp256k1", @@ -1014,15 +1011,16 @@ dependencies = [ "serde-name", "serde_bytes", "serde_json", - "sha2 0.10.8", + "sha2 0.10.9", "sha2 0.9.9", "sha3 0.9.1", "signature 2.2.0", "static_assertions", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", "trybuild", "typenum", + "utoipa", "x25519-dalek", ] @@ -1061,7 +1059,7 @@ dependencies = [ "async-trait", "bcs 0.1.4", "claims", - "dashmap", + "dashmap 5.5.3", "futures", "itertools 0.12.1", "maplit", @@ -1069,7 +1067,7 @@ dependencies = [ "ordered-float 3.9.2", "rand 0.8.5", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -1096,7 +1094,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -1131,9 +1129,9 @@ dependencies = [ "bcs 0.1.4", "byteorder", "claims", - "clap 4.4.14", + "clap 4.5.58", "crossbeam-channel", - "dashmap", + "dashmap 5.5.3", "either", "hex", "indicatif 0.15.0", @@ -1168,7 +1166,7 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "bytes", - "dashmap", + "dashmap 5.5.3", "move-core-types", "rand 0.7.3", ] @@ -1208,7 +1206,7 @@ dependencies = [ "aptos-types", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "itertools 0.12.1", "tokio", ] @@ -1223,7 +1221,7 @@ dependencies = [ "aptos-logger", "aptos-move-debugger", "aptos-push-metrics", - "clap 4.4.14", + "clap 4.5.58", "jemallocator", "tokio", ] @@ -1240,7 +1238,7 @@ dependencies = [ "blst", "blstrs 0.7.1", "criterion", - "ff 0.13.0", + "ff 0.13.1", "group 0.13.0", "hex", "merlin", @@ -1339,7 +1337,7 @@ dependencies = [ "move-binary-format", "move-core-types", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1350,7 +1348,7 @@ dependencies = [ "aptos-logger", "aptos-types", "claims", - "dashmap", + "dashmap 5.5.3", "proptest", "proptest-derive", "rayon", @@ -1387,7 +1385,7 @@ dependencies = [ "arr_macro", "bcs 0.1.4", "bytes", - "dashmap", + "dashmap 5.5.3", "fail", "itertools 0.12.1", "move-core-types", @@ -1429,7 +1427,7 @@ dependencies = [ "async-trait", "bcs 0.1.4", "chrono", - "clap 4.4.14", + "clap 4.5.58", "derivative", "indicatif 0.15.0", "itertools 0.12.1", @@ -1462,16 +1460,16 @@ dependencies = [ "aptos-types", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "crossbeam-channel", "ctrlc", - "dashmap", + "dashmap 5.5.3", "itertools 0.12.1", "num_cpus", "once_cell", "rayon", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1511,7 +1509,7 @@ dependencies = [ "itertools 0.12.1", "once_cell", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1542,7 +1540,7 @@ dependencies = [ "aptos-vm", "aptos-vm-logging", "aptos-vm-types", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "move-core-types", "once_cell", "rayon", @@ -1564,7 +1562,7 @@ dependencies = [ name = "aptos-fallible" version = "0.1.0" dependencies = [ - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1575,7 +1573,7 @@ dependencies = [ "aptos-faucet-core", "aptos-logger", "aptos-sdk", - "clap 4.4.14", + "clap 4.5.58", "tokio", ] @@ -1591,7 +1589,7 @@ dependencies = [ "aptos-sdk", "async-trait", "captcha", - "clap 4.4.14", + "clap 4.5.58", "deadpool-redis", "enum_dispatch", "futures", @@ -1632,7 +1630,7 @@ dependencies = [ "anyhow", "aptos-faucet-core", "aptos-logger", - "clap 4.4.14", + "clap 4.5.58", "tokio", ] @@ -1644,8 +1642,8 @@ dependencies = [ "aptos-logger", "aptos-node-checker", "aptos-sdk", - "clap 4.4.14", - "env_logger", + "clap 4.5.58", + "env_logger 0.10.2", "futures", "gcp-bigquery-client", "reqwest", @@ -1681,7 +1679,7 @@ dependencies = [ "aptos-transaction-generator-lib", "async-trait", "chrono", - "clap 4.4.14", + "clap 4.5.58", "either", "futures", "hex", @@ -1701,7 +1699,7 @@ dependencies = [ "serde_yaml 0.8.26", "tempfile", "termcolor", - "thiserror", + "thiserror 1.0.69", "tokio", "url", ] @@ -1721,7 +1719,7 @@ dependencies = [ "aptos-testcases", "async-trait", "chrono", - "clap 4.4.14", + "clap 4.5.58", "futures", "jemallocator", "once_cell", @@ -1764,8 +1762,9 @@ dependencies = [ "bulletproofs 5.0.0", "byteorder", "claims", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", + "crypto", "curve25519-dalek-ng", "either", "eth_trie", @@ -1800,13 +1799,13 @@ dependencies = [ "rlp", "serde", "serde_bytes", - "sha2 0.10.8", + "sha2 0.10.9", "sha2 0.9.9", "sha3 0.9.1", - "siphasher", + "siphasher 0.3.11", "smallvec", "tempfile", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", ] @@ -1831,12 +1830,12 @@ dependencies = [ "aptos-language-e2e-tests", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "float-cmp", "move-binary-format", "move-core-types", "move-ir-compiler", - "nalgebra", + "nalgebra 0.32.6", "walkdir", ] @@ -1895,7 +1894,7 @@ dependencies = [ "aptos-package-builder", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "move-core-types", "move-model", "tempfile", @@ -1933,7 +1932,7 @@ dependencies = [ "base64 0.13.1", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "ureq", ] @@ -1989,7 +1988,7 @@ dependencies = [ "aptos-moving-average", "aptos-protos", "async-trait", - "clap 4.4.14", + "clap 4.5.58", "futures", "futures-core", "jemallocator", @@ -2017,7 +2016,7 @@ dependencies = [ "aptos-protos", "aptos-transaction-filter", "async-trait", - "clap 4.4.14", + "clap 4.5.58", "futures", "jemallocator", "once_cell", @@ -2043,7 +2042,7 @@ dependencies = [ "aptos-metrics-core", "aptos-moving-average", "async-trait", - "clap 4.4.14", + "clap 4.5.58", "futures", "jemallocator", "once_cell", @@ -2157,7 +2156,7 @@ dependencies = [ "aptos-system-utils", "async-trait", "backtrace", - "clap 4.4.14", + "clap 4.5.58", "prometheus", "serde", "serde_yaml 0.8.26", @@ -2197,7 +2196,7 @@ dependencies = [ "tempfile", "tokio", "tokio-stream", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tonic", ] @@ -2213,7 +2212,7 @@ dependencies = [ "base64 0.13.1", "chrono", "cloud-storage", - "dashmap", + "dashmap 5.5.3", "futures", "itertools 0.12.1", "lz4", @@ -2226,7 +2225,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tonic", "tracing", "url", @@ -2289,7 +2288,7 @@ dependencies = [ "rand 0.7.3", "rayon", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2333,7 +2332,7 @@ version = "0.1.0" dependencies = [ "anyhow", "aptos-types", - "http", + "http 0.2.12", "move-core-types", "reqwest", "serde", @@ -2368,7 +2367,7 @@ dependencies = [ "num-traits", "rand 0.7.3", "rand_chacha 0.3.1", - "rsa 0.9.6", + "rsa 0.9.10", "serde_json", "sha2 0.9.9", "tempfile", @@ -2418,7 +2417,7 @@ dependencies = [ "regex", "serde", "serde-big-array", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -2454,7 +2453,7 @@ dependencies = [ "ark-ff", "ark-serialize", "bcs 0.1.4", - "dashmap", + "dashmap 5.5.3", "hex", "hyper", "jsonwebtoken 8.3.0", @@ -2522,7 +2521,7 @@ dependencies = [ "hex", "ledger-apdu", "ledger-transport-hid", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2609,7 +2608,7 @@ dependencies = [ "rand 0.7.3", "rayon", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -2624,7 +2623,7 @@ dependencies = [ "claims", "futures", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -2662,7 +2661,7 @@ dependencies = [ "aptos-vm-logging", "aptos-vm-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "regex", "reqwest", "tokio", @@ -2689,7 +2688,7 @@ dependencies = [ "aptos-gas-schedule", "aptos-types", "aptos-vm", - "clap 4.4.14", + "clap 4.5.58", "move-cli", "move-package", "move-prover", @@ -2738,7 +2737,7 @@ dependencies = [ "bytes", "claims", "crossbeam", - "dashmap", + "dashmap 5.5.3", "derivative", "move-binary-format", "move-core-types", @@ -2778,7 +2777,7 @@ dependencies = [ "pin-project", "serde", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "url", ] @@ -2824,11 +2823,11 @@ dependencies = [ "serde", "serde_bytes", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-retry", "tokio-stream", - "tokio-util 0.7.10", + "tokio-util 0.7.18", ] [[package]] @@ -2882,7 +2881,7 @@ dependencies = [ "aptos-logger", "aptos-network", "aptos-types", - "clap 4.4.14", + "clap 4.5.58", "futures", "serde", "tokio", @@ -2926,7 +2925,7 @@ dependencies = [ "backoff", "bytes", "chrono", - "clap 4.4.14", + "clap 4.5.58", "diesel", "diesel_migrations", "field_count", @@ -3002,7 +3001,7 @@ dependencies = [ "aptos-validator-transaction-pool", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "either", "fail", "futures", @@ -3032,7 +3031,7 @@ dependencies = [ "aptos-sdk", "aptos-transaction-emitter-lib", "async-trait", - "clap 4.4.14", + "clap 4.5.58", "futures", "once_cell", "poem", @@ -3042,7 +3041,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml 0.8.26", - "thiserror", + "thiserror 1.0.69", "tokio", "url", ] @@ -3103,7 +3102,7 @@ dependencies = [ "aptos-mempool", "aptos-storage-interface", "aptos-types", - "clap 4.4.14", + "clap 4.5.58", ] [[package]] @@ -3143,7 +3142,7 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -3175,7 +3174,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -3187,7 +3186,7 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3249,7 +3248,7 @@ dependencies = [ "futures", "pin-project", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", ] [[package]] @@ -3271,7 +3270,7 @@ dependencies = [ "aptos-temppath", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "futures", "git2 0.16.1", "handlebars", @@ -3336,13 +3335,13 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "bytes", - "clap 4.4.14", + "clap 4.5.58", "hex", "move-core-types", "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "url", ] @@ -3380,7 +3379,7 @@ dependencies = [ "aptos-types", "aptos-warp-webserver", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "futures", "hex", "itertools 0.12.1", @@ -3404,7 +3403,7 @@ dependencies = [ "aptos-logger", "aptos-rosetta", "aptos-types", - "clap 4.4.14", + "clap 4.5.58", "serde", "serde_json", "tokio", @@ -3445,7 +3444,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3484,7 +3483,7 @@ dependencies = [ "proptest", "rand 0.7.3", "rayon", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3521,7 +3520,7 @@ dependencies = [ "aptos-framework", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "heck 0.4.1", "move-core-types", "once_cell", @@ -3545,7 +3544,7 @@ dependencies = [ "crossbeam-channel", "once_cell", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tonic", "tonic-reflection", @@ -3569,7 +3568,7 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3581,7 +3580,7 @@ dependencies = [ "proptest", "serde", "static_assertions", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3592,7 +3591,7 @@ dependencies = [ "aptos-infallible", "claims", "crossbeam", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "proptest", "proptest-derive", "rayon", @@ -3642,7 +3641,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", ] @@ -3663,14 +3662,14 @@ dependencies = [ "assert_unordered", "bcs 0.1.4", "crossbeam-channel", - "dashmap", + "dashmap 5.5.3", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "proptest", "proptest-derive", "rayon", "serde", - "thiserror", + "thiserror 1.0.69", "threadpool", ] @@ -3681,7 +3680,7 @@ dependencies = [ "aptos-config", "aptos-network", "aptos-storage-service-types", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3694,7 +3693,7 @@ dependencies = [ "claims", "futures", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -3721,7 +3720,7 @@ dependencies = [ "bcs 0.1.4", "bytes", "claims", - "dashmap", + "dashmap 5.5.3", "futures", "maplit", "mini-moka", @@ -3729,7 +3728,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "serde", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -3748,7 +3747,7 @@ dependencies = [ "proptest", "rand 0.7.3", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3758,7 +3757,7 @@ dependencies = [ "anyhow", "aptos-profiler", "async-mutex", - "http", + "http 0.2.12", "hyper", "lazy_static", "mime", @@ -3842,7 +3841,7 @@ dependencies = [ "bcs 0.1.4", "chrono", "claims", - "clap 4.4.14", + "clap 4.5.58", "debug-ignore", "flate2", "futures", @@ -3859,7 +3858,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml 0.8.26", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "url", @@ -3913,7 +3912,7 @@ dependencies = [ "enum_dispatch", "futures", "pin-project", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-test", ] @@ -3934,7 +3933,7 @@ dependencies = [ "aptos-types", "aptos-vm", "aptos-vm-logging", - "clap 4.4.14", + "clap 4.5.58", "criterion", "criterion-cpu-time", "num_cpus", @@ -3952,7 +3951,7 @@ dependencies = [ "aptos-logger", "aptos-sdk", "aptos-transaction-emitter-lib", - "clap 4.4.14", + "clap 4.5.58", "futures", "rand 0.7.3", "tokio", @@ -3974,7 +3973,7 @@ dependencies = [ "aptos-transaction-generator-lib", "aptos-types", "async-trait", - "clap 4.4.14", + "clap 4.5.58", "futures", "itertools 0.12.1", "once_cell", @@ -3998,7 +3997,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml 0.8.26", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4011,7 +4010,7 @@ dependencies = [ "aptos-logger", "aptos-sdk", "async-trait", - "clap 4.4.14", + "clap 4.5.58", "move-binary-format", "once_cell", "rand 0.7.3", @@ -4036,7 +4035,7 @@ dependencies = [ "aptos-vm", "aptos-vm-genesis", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "datatest-stable", "hex", @@ -4059,7 +4058,7 @@ dependencies = [ name = "aptos-types" version = "0.0.3" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "anyhow", "aptos-bitvec", "aptos-crypto", @@ -4081,12 +4080,13 @@ dependencies = [ "claims", "coset", "criterion", + "crypto", "derivative", "derive-getters", - "derive_more 2.0.1", + "derive_more 2.1.1", "fixed", "fxhash", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "itertools 0.12.1", "jsonwebtoken 8.3.0", @@ -4114,7 +4114,7 @@ dependencies = [ "regex", "reqwest", "ring 0.16.20", - "rsa 0.9.6", + "rsa 0.9.10", "serde", "serde-big-array", "serde_bytes", @@ -4123,9 +4123,10 @@ dependencies = [ "serde_yaml 0.8.26", "strum 0.24.1", "strum_macros 0.24.3", - "thiserror", + "thiserror 1.0.69", "tokio", "url", + "utoipa", ] [[package]] @@ -4178,7 +4179,7 @@ dependencies = [ "proptest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "ureq", ] @@ -4216,7 +4217,8 @@ dependencies = [ "bytes", "claims", "crossbeam-channel", - "derive_more 2.0.1", + "crypto", + "derive_more 2.1.1", "fail", "futures", "hex", @@ -4244,7 +4246,7 @@ dependencies = [ "aptos-language-e2e-tests", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "move-binary-format", "move-core-types", ] @@ -4262,6 +4264,7 @@ dependencies = [ "aptos-vm", "bcs 0.1.4", "bytes", + "crypto", "move-core-types", "move-vm-runtime", "move-vm-types", @@ -4300,7 +4303,7 @@ dependencies = [ "aptos-types", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "glob", "move-binary-format", "move-core-types", @@ -4388,18 +4391,21 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "9ded5f9a03ac8f24d1b8a25101ee812cd32cdc8c50a4c50237de2c4915850e73" +dependencies = [ + "rustversion", +] [[package]] name = "ark-bls12-381" @@ -4439,7 +4445,7 @@ dependencies = [ "blake2", "derivative", "digest 0.10.7", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -4472,7 +4478,7 @@ dependencies = [ "derivative", "digest 0.10.7", "itertools 0.10.5", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "paste", "rustc_version", @@ -4495,7 +4501,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", "proc-macro2", "quote", @@ -4550,7 +4556,7 @@ dependencies = [ "ark-serialize-derive", "ark-std", "digest 0.10.7", - "num-bigint 0.4.4", + "num-bigint 0.4.6", ] [[package]] @@ -4610,9 +4616,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -4631,9 +4637,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ascii-canvas" @@ -4641,7 +4647,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" dependencies = [ - "term", + "term 0.7.0", ] [[package]] @@ -4682,12 +4688,11 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" dependencies = [ "concurrent-queue", - "event-listener 4.0.3", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -4695,15 +4700,15 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.8.0" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ - "async-lock 3.2.0", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.2.0", + "fastrand 2.3.0", + "futures-lite 2.6.1", + "pin-project-lite", "slab", ] @@ -4713,154 +4718,125 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.5.0", "async-executor", - "async-io 2.2.2", - "async-lock 3.2.0", + "async-io", + "async-lock", "blocking", - "futures-lite 2.2.0", + "futures-lite 2.6.1", "once_cell", ] [[package]] name = "async-io" -version = "1.13.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ - "async-lock 2.8.0", "autocfg", "cfg-if", "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.27", - "slab", - "socket2 0.4.10", - "waker-fn", -] - -[[package]] -name = "async-io" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" -dependencies = [ - "async-lock 3.2.0", - "cfg-if", - "concurrent-queue", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.6.1", "parking", - "polling 3.3.1", - "rustix 0.38.28", + "polling 3.11.0", + "rustix 1.1.3", "slab", - "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", + "windows-sys 0.61.2", ] [[package]] name = "async-lock" -version = "3.2.0" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.4.1", "event-listener-strategy", "pin-project-lite", ] [[package]] name = "async-mutex" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +checksum = "73112ce9e1059d8604242af62c7ec8e5975ac58ac251686c8403b45e8a6fe778" dependencies = [ "event-listener 2.5.3", ] [[package]] name = "async-object-pool" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb901c30ebc2fc4ab46395bbfbdba9542c16559d853645d75190c3056caf3bc" +checksum = "333c456b97c3f2d50604e8b2624253b7f787208cb72eb75e64b0ad11b221652c" dependencies = [ "async-std", ] [[package]] name = "async-process" -version = "1.8.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-channel 2.5.0", + "async-io", + "async-lock", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.28", - "windows-sys 0.48.0", + "event-listener 5.4.1", + "futures-lite 2.6.1", + "rustix 1.1.3", ] [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ - "async-io 2.2.2", - "async-lock 2.8.0", + "async-io", + "async-lock", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.28", + "rustix 1.1.3", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] name = "async-std" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" dependencies = [ "async-channel 1.9.0", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", + "futures-lite 2.6.1", "gloo-timers", "kv-log-macro", "log", @@ -4874,9 +4850,9 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -4885,30 +4861,30 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "async-task" -version = "4.7.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -4942,9 +4918,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" @@ -4957,7 +4933,7 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", + "http 0.2.12", "http-body", "hyper", "itoa", @@ -4988,7 +4964,7 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", + "http 0.2.12", "http-body", "hyper", "itoa", @@ -5014,7 +4990,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", + "http 0.2.12", "http-body", "mime", "tower-layer", @@ -5030,7 +5006,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", + "http 0.2.12", "http-body", "mime", "rustversion", @@ -5048,9 +5024,9 @@ dependencies = [ [[package]] name = "az" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" [[package]] name = "backoff" @@ -5059,7 +5035,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ "futures-core", - "getrandom 0.2.11", + "getrandom 0.2.17", "instant", "pin-project-lite", "rand 0.8.5", @@ -5068,17 +5044,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-link", ] [[package]] @@ -5101,9 +5077,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.6" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79fed4cdb43e993fcdadc7e58a09fd0e3e649c4436fa11da71c9f1f3ee7feb9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" @@ -5113,40 +5089,30 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "basic-cookies" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb53b6b315f924c7f113b162e53b3901c05fc9966baf84d201dfcc7432a4bb38" +checksum = "67bd8fd42c16bdb08688243dc5f0cc117a3ca9efeeaba3a345a18a6159ad96f7" dependencies = [ "lalrpop", "lalrpop-util", "regex", ] -[[package]] -name = "basic-toml" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" -dependencies = [ - "serde", -] - [[package]] name = "bb8" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98b4b0f25f18bcdc3ac72bdb486ed0acf7e185221fd4dc985bc15db5800b0ba2" +checksum = "d89aabfae550a5c44b43ab941844ffcd2e993cb6900b342debf59e9ea74acdb8" dependencies = [ "async-trait", - "futures-channel", "futures-util", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "tokio", ] @@ -5156,7 +5122,7 @@ version = "0.1.4" source = "git+https://github.com/aptos-labs/bcs.git?rev=d31fab9d81748e2594be5cd5cdf845786a30562d#d31fab9d81748e2594be5cd5cdf845786a30562d" dependencies = [ "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -5166,7 +5132,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b6598a2f5d564fb7855dc6b06fd1c38cff5a72bd8b863a4d021938497b440a" dependencies = [ "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -5177,7 +5143,7 @@ checksum = "9ae286c2cb403324ab644c7cc68dceb25fe52ca9429908a726d7ed272c1edf7b" dependencies = [ "bellpepper-core", "byteorder", - "ff 0.13.0", + "ff 0.13.1", ] [[package]] @@ -5188,9 +5154,9 @@ checksum = "1d8abb418570756396d722841b19edfec21d4e89e1cf8990610663040ecb1aea" dependencies = [ "blake2s_simd", "byteorder", - "ff 0.13.0", + "ff 0.13.1", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -5213,15 +5179,28 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bicycl_rs" +version = "0.1.0" +source = "git+ssh://git@github.com/Entropy-Foundation/bicycl-rs?rev=e67e3ab#e67e3ab867ce4e2f302534c868d0dec24c59b043" +dependencies = [ + "gmp-mpfr-sys", + "libc", + "rand 0.8.5", + "serde", + "serde_bytes", + "sha3 0.10.8", +] + [[package]] name = "bigdecimal" -version = "0.4.2" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06619be423ea5bb86c95f087d5707942791a08a85530df0db2209a3ecfb8bc9" +checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" dependencies = [ "autocfg", "libm", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-integer", "num-traits", "serde", @@ -5238,11 +5217,11 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.69.4" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -5253,7 +5232,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -5262,7 +5241,16 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", ] [[package]] @@ -5271,11 +5259,17 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bit_field" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" [[package]] name = "bitflags" @@ -5285,9 +5279,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bitmaps" @@ -5343,24 +5337,24 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +checksum = "b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3" dependencies = [ "arrayref", - "arrayvec 0.7.4", - "constant_time_eq 0.3.0", + "arrayvec 0.7.6", + "constant_time_eq 0.4.2", ] [[package]] name = "blake2s_simd" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" +checksum = "ee29928bad1e3f94c9d1528da29e07a1d3d04817ae8332de1e8b846c8439f4b3" dependencies = [ "arrayref", - "arrayvec 0.7.4", - "constant_time_eq 0.3.0", + "arrayvec 0.7.6", + "constant_time_eq 0.4.2", ] [[package]] @@ -5409,27 +5403,33 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ - "async-channel 2.1.1", - "async-lock 3.2.0", + "async-channel 2.5.0", "async-task", - "fastrand 2.0.1", "futures-io", - "futures-lite 2.2.0", + "futures-lite 2.6.1", "piper", - "tracing", ] [[package]] name = "blst" -version = "0.3.11" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" dependencies = [ "cc", "glob", @@ -5461,7 +5461,7 @@ checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" dependencies = [ "blst", "byte-slice-cast", - "ff 0.13.0", + "ff 0.13.1", "group 0.13.0", "pairing 0.23.0", "rand_core 0.6.4", @@ -5485,7 +5485,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "serde", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", "zeroize", ] @@ -5496,13 +5496,13 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f03db470b3c0213c47e978da93200259a1eb4dae2e5512cba9955e2b540a6fc6" dependencies = [ - "base64 0.21.6", + "base64 0.21.7", "bollard-stubs", "bytes", "futures-core", "futures-util", "hex", - "http", + "http 0.2.12", "hyper", "hyperlocal", "log", @@ -5512,9 +5512,9 @@ dependencies = [ "serde_json", "serde_repr", "serde_urlencoded", - "thiserror", + "thiserror 1.0.69", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "url", "winapi 0.3.9", ] @@ -5532,22 +5532,12 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata 0.1.10", -] - -[[package]] -name = "bstr" -version = "1.9.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", + "regex-automata", "serde", ] @@ -5568,7 +5558,7 @@ dependencies = [ "serde_derive", "sha3 0.9.1", "subtle-ng", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -5589,20 +5579,20 @@ dependencies = [ "serde_derive", "sha3 0.10.8", "subtle", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "byte-slice-cast" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "byte-tools" @@ -5645,15 +5635,15 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" [[package]] name = "byteorder" @@ -5663,21 +5653,20 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] [[package]] name = "bzip2-sys" -version = "0.1.11+1.0.8" +version = "0.1.13+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" dependencies = [ "cc", - "libc", "pkg-config", ] @@ -5692,7 +5681,7 @@ name = "calc-dep-sizes" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "futures", "move-binary-format", "move-core-types", @@ -5702,11 +5691,11 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -5725,11 +5714,21 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.6" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -5739,24 +5738,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", - "cargo-platform", - "semver", + "cargo-platform 0.1.9", + "semver 1.0.27", "serde", "serde_json", ] [[package]] name = "cargo_metadata" -version = "0.18.1" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" dependencies = [ "camino", - "cargo-platform", - "semver", + "cargo-platform 0.3.2", + "semver 1.0.27", "serde", "serde_json", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -5779,12 +5778,14 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.0.83" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ + "find-msvc-tools", "jobserver", "libc", + "shlex", ] [[package]] @@ -5798,9 +5799,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.15.6" +version = "0.20.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6100bc57b6209840798d95cb2775684849d332f7bd788db2a8c8caf7ef82a41a" +checksum = "78cef5b5a1a6827c7322ae2a636368a573006b27cfa76c7ebd53e834daeaab6a" dependencies = [ "smallvec", "target-lexicon", @@ -5808,44 +5809,49 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-link", ] [[package]] name = "chrono-tz" -version = "0.8.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d7b79e99bfaa0d47da0687c43aa3b7381938a62ad3a6498599039321f660b7" +checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" dependencies = [ "chrono", "chrono-tz-build", - "phf", + "phf 0.11.3", ] [[package]] name = "chrono-tz-build" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" dependencies = [ "parse-zoneinfo", - "phf", + "phf 0.11.3", "phf_codegen", ] @@ -5857,9 +5863,9 @@ checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -5868,18 +5874,18 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", - "half 1.8.2", + "half 2.7.1", ] [[package]] @@ -5903,9 +5909,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -5923,7 +5929,7 @@ dependencies = [ "bitflags 1.3.2", "strsim 0.8.0", "textwrap 0.11.0", - "unicode-width 0.1.11", + "unicode-width 0.1.14", "vec_map", ] @@ -5941,48 +5947,48 @@ dependencies = [ "once_cell", "strsim 0.10.0", "termcolor", - "textwrap 0.16.0", + "textwrap 0.16.2", ] [[package]] name = "clap" -version = "4.4.14" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" +checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806" dependencies = [ "clap_builder", - "clap_derive 4.4.7", + "clap_derive 4.5.55", ] [[package]] name = "clap-verbosity-flag" -version = "2.1.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c90e95e5bd4e8ac34fa6f37c774b0c6f8ed06ea90c79931fd448fcf941a9767" +checksum = "34c77f67047557f62582784fd7482884697731b2932c7d37ced54bce2312e1e2" dependencies = [ - "clap 4.4.14", + "clap 4.5.58", "log", ] [[package]] name = "clap_builder" -version = "4.4.14" +version = "4.5.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" +checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", - "strsim 0.10.0", + "clap_lex 1.0.0", + "strsim 0.11.1", ] [[package]] name = "clap_complete" -version = "4.4.6" +version = "4.5.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97aeaa95557bd02f23fbb662f981670c3d20c5a26e69f7354b28f57092437fcd" +checksum = "c757a3b7e39161a4e56f9365141ada2a6c915a8622c408ab6bb4b5d047371031" dependencies = [ - "clap 4.4.14", + "clap 4.5.58", ] [[package]] @@ -6000,14 +6006,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -6021,9 +6027,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" [[package]] name = "clear_on_drop" @@ -6076,7 +6082,7 @@ checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "serde", "termcolor", - "unicode-width 0.1.11", + "unicode-width 0.1.14", ] [[package]] @@ -6087,32 +6093,32 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "colored" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "combine" -version = "4.6.6" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ "bytes", "futures-core", "memchr", "pin-project-lite", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", ] [[package]] @@ -6120,7 +6126,7 @@ name = "compute-module-expansion-size" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "futures", "move-binary-format", "move-core-types", @@ -6130,24 +6136,37 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] [[package]] name = "console" -version = "0.15.7" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ - "encode_unicode 0.3.6", - "lazy_static", + "encode_unicode", "libc", - "unicode-width 0.1.11", - "windows-sys 0.45.0", + "once_cell", + "unicode-width 0.2.2", + "windows-sys 0.59.0", +] + +[[package]] +name = "console" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.2", + "windows-sys 0.61.2", ] [[package]] @@ -6202,24 +6221,24 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_fn" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -6234,9 +6253,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "constant_time_eq" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "convert_case" @@ -6246,24 +6265,13 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "convert_case" -version = "0.7.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" dependencies = [ "unicode-segmentation", ] -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "cookie" version = "0.17.0" @@ -6271,12 +6279,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ "aes-gcm", - "base64 0.21.6", + "base64 0.21.7", "hkdf 0.12.4", "hmac 0.12.1", "percent-encoding", "rand 0.8.5", - "sha2 0.10.8", + "sha2 0.10.9", "subtle", "time", "version_check", @@ -6284,12 +6292,12 @@ dependencies = [ [[package]] name = "cookie_store" -version = "0.16.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" +checksum = "387461abbc748185c3a6e1673d826918b450b87ff22639429c694619a83b6cf6" dependencies = [ - "cookie 0.16.2", - "idna 0.2.3", + "cookie", + "idna 0.3.0", "log", "publicsuffix", "serde", @@ -6311,15 +6319,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "core_affinity" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622892f5635ce1fc38c8f16dfc938553ed64af482edb5e150bf4caedbfcb2304" +checksum = "a034b3a7b624016c6e13f5df875747cc25f884156aad2abd12b6c46797971342" dependencies = [ "libc", "num_cpus", @@ -6328,37 +6336,56 @@ dependencies = [ [[package]] name = "coset" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99c214bbc5c8b4518856d79cae4d323feaa881ecf3e31b5af6572bb5313c11d5" +checksum = "f4c8cc80f631f8307b887faca24dcc3abc427cd0367f6eb6188f6e8f5b7ad8fb" dependencies = [ "ciborium", "ciborium-io", ] +[[package]] +name = "cpp_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a4fc172d5c7797a79e4f0e976bec2d4b80b39989d48d58386aaa9a533ff389" +dependencies = [ + "libc", +] + [[package]] name = "cpp_demangle" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" dependencies = [ "cfg-if", ] [[package]] -name = "cpufeatures" -version = "0.2.12" +name = "cpp_std" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "dc6acdfb694abd411532cd836467462172cf3f9b78d3d3aff28a69d676665339" dependencies = [ - "libc", + "cpp_core", + "ritual_build", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -6424,18 +6451,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -6452,18 +6479,18 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -6474,8 +6501,8 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio", - "parking_lot 0.12.1", + "mio 0.8.11", + "parking_lot 0.12.5", "signal-hook", "signal-hook-mio", "winapi 0.3.9", @@ -6490,8 +6517,8 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio", - "parking_lot 0.12.1", + "mio 0.8.11", + "parking_lot 0.12.5", "signal-hook", "signal-hook-mio", "winapi 0.3.9", @@ -6508,9 +6535,36 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto" +version = "0.1.0" +source = "git+ssh://git@github.com/Entropy-Foundation/crypto?rev=d045a68#d045a6875200975fb60c34ac74be08eef5b164b4" +dependencies = [ + "base64 0.22.1", + "bicycl_rs", + "bincode", + "blst", + "blsttc", + "cpp_std", + "ed25519-dalek 2.2.0", + "hex", + "lazy_static", + "miracl_core_bls12381", + "rand 0.8.5", + "rand_chacha 0.2.2", + "rand_core 0.6.4", + "rayon", + "serde", + "sha3 0.10.8", + "statrs", + "thiserror 1.0.69", + "tiny-keccak", + "zeroize", +] [[package]] name = "crypto-bigint" @@ -6536,9 +6590,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array 0.14.7", "rand_core 0.6.4", @@ -6567,21 +6621,21 @@ dependencies = [ [[package]] name = "csv" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" dependencies = [ "csv-core", "itoa", "ryu", - "serde", + "serde_core", ] [[package]] name = "csv-core" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" dependencies = [ "memchr", ] @@ -6597,34 +6651,35 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.2" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" dependencies = [ - "nix 0.27.1", - "windows-sys 0.52.0", + "dispatch2", + "nix 0.30.1", + "windows-sys 0.61.2", ] [[package]] name = "curl" -version = "0.4.44" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" +checksum = "79fc3b6dd0b87ba36e565715bf9a2ced221311db47bd18011676f24a6066edbc" dependencies = [ "curl-sys", "libc", "openssl-probe", "openssl-sys", "schannel", - "socket2 0.4.10", - "winapi 0.3.9", + "socket2 0.6.2", + "windows-sys 0.59.0", ] [[package]] name = "curl-sys" -version = "0.4.70+curl-8.5.0" +version = "0.4.85+curl-8.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0333d8849afe78a4c8102a429a446bfdd055832af071945520e835ae2d841e" +checksum = "c0efa6142b5ecc05f6d3eaa39e6af4888b9d3939273fb592c92b7088a8cf3fdb" dependencies = [ "cc", "libc", @@ -6633,7 +6688,7 @@ dependencies = [ "openssl-sys", "pkg-config", "vcpkg", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -6673,7 +6728,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -6712,12 +6767,22 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.9" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core 0.20.9", - "darling_macro 0.20.9", + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -6750,16 +6815,30 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.9" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.11.1", + "syn 2.0.114", +] + +[[package]] +name = "darling_core" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -6786,13 +6865,24 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core 0.20.9", + "darling_core 0.21.3", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -6802,17 +6892,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.12", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.12", ] [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] name = "datatest-stable" @@ -6850,9 +6954,9 @@ dependencies = [ [[package]] name = "deadpool-runtime" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63dfa964fe2a66f3fde91fc70b267fe193d822c7e603e2a675a49a7f46ad3f49" +checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" dependencies = [ "tokio", ] @@ -6888,9 +6992,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid 0.9.6", "pem-rfc7468 0.7.0", @@ -6899,12 +7003,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] @@ -6932,83 +7036,84 @@ checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "derive_builder" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling 0.20.9", + "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "derive_builder_macro" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.114", ] [[package]] name = "derive_more" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ - "convert_case 0.7.1", + "convert_case 0.10.0", "proc-macro2", "quote", - "syn 2.0.48", + "rustc_version", + "syn 2.0.114", "unicode-xid", ] @@ -7023,7 +7128,7 @@ dependencies = [ "guppy", "guppy-workspace-hack", "once_cell", - "petgraph 0.6.4", + "petgraph 0.6.5", "rayon", "serde", "toml 0.5.11", @@ -7031,23 +7136,23 @@ dependencies = [ [[package]] name = "deunicode" -version = "1.4.2" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" +checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" [[package]] name = "diesel" -version = "2.1.4" +version = "2.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" +checksum = "ff236accb9a5069572099f0b350a92e9560e8e63a9b8d546162f4a5e03026bb2" dependencies = [ "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.10.0", "byteorder", "chrono", "diesel_derives", "itoa", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-integer", "num-traits", "pq-sys", @@ -7071,14 +7176,14 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.1.2" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" +checksum = "14701062d6bed917b5c7103bdffaee1e4609279e240488ad24e7bd979ca6866c" dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -7098,7 +7203,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -7209,11 +7314,34 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.10.0", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "doc-comment" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +checksum = "780955b8b195a21ab8e4ac6b60dd1dbdcec1dc6c51c0617964b08c81785e12c9" [[package]] name = "dotenv" @@ -7229,9 +7357,9 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "dw" @@ -7256,9 +7384,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "e2e-move-tests" @@ -7301,7 +7429,7 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", + "der 0.7.10", "digest 0.10.7", "elliptic-curve", "rfc6979", @@ -7346,14 +7474,15 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ "curve25519-dalek 4.1.3", "ed25519 2.2.3", + "rand_core 0.6.4", "serde", - "sha2 0.10.8", + "sha2 0.10.9", "signature 2.2.0", "subtle", "zeroize", @@ -7368,14 +7497,14 @@ dependencies = [ "derivation-path", "ed25519-dalek 1.0.1", "hmac 0.12.1", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] name = "either" -version = "1.9.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" @@ -7387,7 +7516,7 @@ dependencies = [ "base64ct", "crypto-bigint 0.5.5", "digest 0.10.7", - "ff 0.13.0", + "ff 0.13.1", "generic-array 0.14.7", "group 0.13.0", "pem-rfc7468 0.7.0", @@ -7402,19 +7531,13 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.2" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" dependencies = [ "log", ] -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - [[package]] name = "encode_unicode" version = "1.0.0" @@ -7423,30 +7546,39 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "enum_dispatch" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", +] + +[[package]] +name = "env_filter" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +dependencies = [ + "log", ] [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -7455,6 +7587,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +dependencies = [ + "env_filter", + "log", +] + [[package]] name = "environmental" version = "1.1.4" @@ -7463,9 +7605,9 @@ checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" @@ -7478,12 +7620,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -7502,10 +7644,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3aeb0284b473041df2419a28e3cdf0c64a78d2b9511af4b6e40bad3964b172" dependencies = [ "ethereum-types 0.14.1", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "keccak-hash", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "rlp", ] @@ -7522,7 +7664,7 @@ dependencies = [ "serde", "serde_json", "sha3 0.10.8", - "thiserror", + "thiserror 1.0.69", "uint", ] @@ -7603,9 +7745,9 @@ dependencies = [ [[package]] name = "ethnum" -version = "1.5.0" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" +checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" [[package]] name = "event-listener" @@ -7615,20 +7757,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "4.0.3" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -7637,11 +7768,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.4.1", "pin-project-lite", ] @@ -7719,13 +7850,12 @@ dependencies = [ [[package]] name = "exr" -version = "1.71.0" +version = "1.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" +checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be" dependencies = [ "bit_field", - "flume", - "half 2.2.1", + "half 2.7.1", "lebe", "miniz_oxide", "rayon-core", @@ -7739,7 +7869,7 @@ version = "0.1.0" dependencies = [ "anyhow", "atty", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "move-to-yul", "serde_json", @@ -7757,20 +7887,33 @@ dependencies = [ ] [[package]] -name = "fallible-iterator" -version = "0.2.0" +name = "failure" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] [[package]] -name = "fallible_collections" -version = "0.4.9" +name = "failure_derive" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88c69768c0a15262df21899142bc6df9b9b823546d4b4b9a7bc2d6c448ec6fd" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "hashbrown 0.13.2", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + [[package]] name = "fastrand" version = "1.9.0" @@ -7782,15 +7925,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fdeflate" -version = "0.3.3" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ "simd-adler32", ] @@ -7808,9 +7951,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "bitvec 1.0.1", "byteorder", @@ -7821,12 +7964,11 @@ dependencies = [ [[package]] name = "ff_derive" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f54704be45ed286151c5e11531316eaef5b8f5af7d597b806fdb8af108d84a" +checksum = "f10d12652036b0e99197587c6ba87a8fc3031986499973c030d8b44fcc151b60" dependencies = [ "addchain", - "cfg-if", "num-bigint 0.3.3", "num-integer", "num-traits", @@ -7868,16 +8010,21 @@ checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" [[package]] name = "filetime" -version = "0.2.23" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", - "windows-sys 0.52.0", + "libredox", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "findshlibs" version = "0.10.2" @@ -7890,21 +8037,15 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "fixed" -version = "1.25.1" +version = "1.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e29e5681dc8556fb9df1409e95eae050e12e8776394313da3546dcb8cf390c73" +checksum = "c566da967934c6c7ee0458a9773de9b2a685bd2ce26a3b28ddfc740e640182f5" dependencies = [ "az", "bytemuck", - "half 2.2.1", + "half 2.7.1", "typenum", ] @@ -7944,14 +8085,21 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "flate2" -version = "1.0.28" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -7967,7 +8115,7 @@ dependencies = [ "log", "nu-ansi-term 0.49.0", "regex", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -7979,21 +8127,18 @@ dependencies = [ "num-traits", ] -[[package]] -name = "flume" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" -dependencies = [ - "spin 0.9.8", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -8021,7 +8166,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -8038,18 +8183,18 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] name = "fragile" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" +checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" [[package]] name = "fst" @@ -8071,9 +8216,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -8086,9 +8231,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -8096,15 +8241,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -8113,9 +8258,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -8134,11 +8279,11 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.2.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand 2.0.1", + "fastrand 2.3.0", "futures-core", "futures-io", "parking", @@ -8147,38 +8292,38 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -8246,7 +8391,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "time", "tokio", "tokio-stream", @@ -8267,7 +8412,7 @@ dependencies = [ "aptos-network", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "move-core-types", "rand 0.7.3", "serde", @@ -8332,32 +8477,57 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] -name = "ghash" -version = "0.5.0" +name = "getrandom" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ - "opaque-debug 0.3.0", - "polyval", + "cfg-if", + "libc", + "r-efi", + "wasip2", ] [[package]] -name = "gif" -version = "0.12.0" +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug 0.3.1", + "polyval", +] + +[[package]] +name = "gif" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b" dependencies = [ "color_quant", "weezl", @@ -8365,9 +8535,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "git2" @@ -8399,39 +8569,39 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" dependencies = [ "aho-corasick", - "bstr 1.9.0", + "bstr", "log", - "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-automata", + "regex-syntax", ] [[package]] name = "globwalk" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "ignore", "walkdir", ] [[package]] name = "gloo-timers" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ "futures-channel", "futures-core", @@ -8439,16 +8609,27 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gmp-mpfr-sys" +version = "1.6.8" +source = "git+ssh://git@github.com/Entropy-Foundation/gmp-mpfr-sys.git?branch=master#6d5c91968d809b692df0abdcc3d93ce3588ff7ad" +dependencies = [ + "cc", + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "goldenfile" -version = "1.6.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a67453a3b358bd8213aedafd4feed75eecab9fb04bed26ba6fdf94694be560" +checksum = "4ce2238f730d493a06ef6746713fe0b56acecc88485892ae65c50d2db9bf977b" dependencies = [ "scopeguard", "similar-asserts", + "static_assertions", "tempfile", - "yansi 1.0.0-rc.1", + "yansi", ] [[package]] @@ -8458,7 +8639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "931bedb2264cb00f914b0a6a5c304e34865c34306632d3932e0951a073e4a67d" dependencies = [ "async-trait", - "base64 0.21.6", + "base64 0.21.7", "google-cloud-metadata", "google-cloud-token", "home", @@ -8466,7 +8647,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "time", "tokio", "tracing", @@ -8480,7 +8661,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96e4ad0802d3f416f62e7ce01ac1460898ee0efc98f8b45cd4aab7611607012f" dependencies = [ "reqwest", - "thiserror", + "thiserror 1.0.69", "tokio", ] @@ -8491,7 +8672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22c57ca1d971d7c6f852c02eda4e87e88b1247b6ed8be9fa5b2768c68b0f2ca5" dependencies = [ "async-stream", - "base64 0.21.6", + "base64 0.21.7", "bytes", "futures-util", "google-cloud-auth", @@ -8506,8 +8687,8 @@ dependencies = [ "rsa 0.6.1", "serde", "serde_json", - "sha2 0.10.8", - "thiserror", + "sha2 0.10.9", + "thiserror 1.0.69", "time", "tokio", "tracing", @@ -8532,7 +8713,7 @@ dependencies = [ "ff 0.12.1", "rand 0.8.5", "rand_core 0.6.4", - "rand_xorshift", + "rand_xorshift 0.3.0", "subtle", ] @@ -8542,35 +8723,35 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff 0.13.1", "rand 0.8.5", "rand_core 0.6.4", - "rand_xorshift", + "rand_xorshift 0.3.0", "subtle", ] [[package]] name = "guppy" -version = "0.17.5" +version = "0.17.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34e99a7734579b834a076ef11789783c153c6eb5fb3520ed15bc41f483f0f317" +checksum = "a502977572076a42d585dd12f04bccf9c9cafdd4546e99878c072460b904e115" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "camino", - "cargo_metadata 0.18.1", + "cargo_metadata 0.23.1", "cfg-if", "debug-ignore", - "fixedbitset 0.4.2", + "fixedbitset 0.5.7", "guppy-summaries", "guppy-workspace-hack", - "indexmap 2.2.5", - "itertools 0.12.1", + "indexmap 2.13.0", + "itertools 0.14.0", "nested", "once_cell", - "pathdiff", - "petgraph 0.6.4", + "pathdiff 0.2.3", + "petgraph 0.8.3", "rayon", - "semver", + "semver 1.0.27", "serde", "serde_json", "smallvec", @@ -8589,7 +8770,7 @@ dependencies = [ "cfg-if", "diffus", "guppy-workspace-hack", - "semver", + "semver 1.0.27", "serde", "toml 0.5.11", ] @@ -8602,36 +8783,38 @@ checksum = "92620684d99f750bae383ecb3be3748142d6095760afd5cbcf2261e9a279d780" [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 2.2.5", + "http 0.2.12", + "indexmap 2.13.0", "slab", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tracing", ] [[package]] name = "half" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "half" -version = "2.2.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ + "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -8645,7 +8828,7 @@ dependencies = [ "pest_derive", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -8678,26 +8861,41 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", ] [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "hdrhistogram" version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.21.6", + "base64 0.21.7", "byteorder", "flate2", "nom", @@ -8710,10 +8908,10 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.6", + "base64 0.21.7", "bytes", "headers-core", - "http", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -8725,7 +8923,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http", + "http 0.2.12", ] [[package]] @@ -8760,9 +8958,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -8858,11 +9062,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -8884,15 +9088,25 @@ checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", "itoa", ] +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -8900,7 +9114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", "pin-project-lite", ] @@ -8912,9 +9126,9 @@ checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -8931,7 +9145,7 @@ dependencies = [ "assert-json-diff", "async-object-pool", "async-trait", - "base64 0.21.6", + "base64 0.21.7", "basic-cookies", "crossbeam-utils", "form_urlencoded", @@ -8961,28 +9175,28 @@ dependencies = [ [[package]] name = "humantime" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http", + "http 0.2.12", "http-body", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -8995,7 +9209,7 @@ version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ - "http", + "http 0.2.12", "hyper", "log", "rustls 0.20.9", @@ -9011,10 +9225,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", + "http 0.2.12", "hyper", "log", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", @@ -9060,14 +9274,15 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -9082,22 +9297,98 @@ dependencies = [ ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "icu_collections" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] [[package]] -name = "idna" -version = "0.2.3" +name = "icu_locale_core" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.3.0" @@ -9118,17 +9409,38 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + [[package]] name = "ignore" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" dependencies = [ "crossbeam-deque", "globset", "log", "memchr", - "regex-automata 0.4.6", + "regex-automata", "same-file", "walkdir", "winapi-util", @@ -9150,9 +9462,9 @@ dependencies = [ [[package]] name = "image" -version = "0.24.7" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", @@ -9160,7 +9472,6 @@ dependencies = [ "exr", "gif", "jpeg-decoder", - "num-rational 0.4.1", "num-traits", "png", "qoi", @@ -9182,7 +9493,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.9", + "parity-scale-codec 3.7.5", ] [[package]] @@ -9214,13 +9525,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.114", ] [[package]] @@ -9260,13 +9571,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.16.1", "serde", + "serde_core", ] [[package]] @@ -9275,7 +9587,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4" dependencies = [ - "console", + "console 0.16.2", "lazy_static", "number_prefix 0.3.0", "regex", @@ -9287,10 +9599,10 @@ version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ - "console", + "console 0.15.11", "number_prefix 0.4.0", "portable-atomic", - "unicode-width 0.2.0", + "unicode-width 0.2.2", "web-time", ] @@ -9302,17 +9614,17 @@ checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" [[package]] name = "inferno" -version = "0.11.19" +version = "0.11.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321f0f839cd44a4686e9504b0a62b4d69a50b62072144c71c68f5873c167b8d9" +checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88" dependencies = [ - "ahash 0.8.11", - "clap 4.4.14", + "ahash 0.8.12", + "clap 4.5.58", "crossbeam-channel", "crossbeam-utils", - "dashmap", - "env_logger", - "indexmap 2.2.5", + "dashmap 6.1.0", + "env_logger 0.11.9", + "indexmap 2.13.0", "is-terminal", "itoa", "log", @@ -9325,18 +9637,18 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ "generic-array 0.14.7", ] [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", "js-sys", @@ -9351,10 +9663,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ab388864246d58a276e60e7569a833d9cc4cd75c66e5ca77c177dad38e59996" dependencies = [ "ahash 0.7.8", - "dashmap", + "dashmap 5.5.3", "hashbrown 0.12.3", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.5", ] [[package]] @@ -9372,16 +9684,16 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] [[package]] name = "ipnet" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iprange" @@ -9394,20 +9706,26 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.28", - "windows-sys 0.52.0", + "hermit-abi 0.5.2", + "libc", + "windows-sys 0.61.2", ] [[package]] name = "is_debug" -version = "1.0.1" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fe266d2e243c931d8190177f20bf7f24eed45e96f39e87dc49a27b32d12d407" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "isahc" @@ -9423,7 +9741,7 @@ dependencies = [ "encoding_rs", "event-listener 2.5.3", "futures-lite 1.13.0", - "http", + "http 0.2.12", "log", "mime", "once_cell", @@ -9436,6 +9754,15 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.10.5" @@ -9463,11 +9790,20 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jemalloc-sys" @@ -9491,28 +9827,30 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.4", "libc", ] [[package]] name = "jpeg-decoder" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" dependencies = [ "rayon", ] [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -9558,12 +9896,12 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.6", + "base64 0.21.7", "pem 1.1.1", "ring 0.16.20", "serde", "serde_json", - "simple_asn1 0.6.2", + "simple_asn1 0.6.3", ] [[package]] @@ -9578,7 +9916,7 @@ dependencies = [ "hmac 0.12.1", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -9597,9 +9935,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -9614,6 +9952,16 @@ dependencies = [ "tiny-keccak", ] +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "kube" version = "0.65.0" @@ -9638,7 +9986,7 @@ dependencies = [ "dirs-next", "either", "futures", - "http", + "http 0.2.12", "http-body", "hyper", "hyper-rustls 0.23.2", @@ -9653,7 +10001,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml 0.8.26", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-util 0.6.10", "tower", @@ -9669,13 +10017,13 @@ checksum = "c52b6ab05d160691083430f6f431707a4e05b64903f2ffa0095ee5efde759117" dependencies = [ "chrono", "form_urlencoded", - "http", + "http 0.2.12", "json-patch", "k8s-openapi", "once_cell", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9702,33 +10050,33 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.19.12" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", - "bit-set", - "diff", + "bit-set 0.5.3", "ena", - "is-terminal", - "itertools 0.10.5", + "itertools 0.11.0", "lalrpop-util", - "petgraph 0.6.4", + "petgraph 0.6.5", + "pico-args", "regex", - "regex-syntax 0.6.29", + "regex-syntax", "string_cache", - "term", + "term 0.7.0", "tiny-keccak", "unicode-xid", + "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.19.12" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ - "regex", + "regex-automata", ] [[package]] @@ -9758,11 +10106,11 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin 0.9.8", ] [[package]] @@ -9771,11 +10119,17 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "lebe" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "ledger-apdu" @@ -9811,7 +10165,7 @@ dependencies = [ "ledger-transport", "libc", "log", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -9822,19 +10176,18 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.181" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d" dependencies = [ "arbitrary", "cc", - "once_cell", ] [[package]] @@ -9853,25 +10206,25 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-link", ] [[package]] name = "libm" -version = "0.2.8" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libnghttp2-sys" -version = "0.1.9+1.58.0" +version = "0.1.11+1.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b57e858af2798e167e709b9d969325b6d8e9d50232fcbc494d7d54f976854a64" +checksum = "1b6c24e48a7167cffa7119da39d577fa482e66c688a4aac016bee862e1a713c4" dependencies = [ "cc", "libc", @@ -9879,13 +10232,13 @@ dependencies = [ [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.10.0", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.7.1", ] [[package]] @@ -9905,12 +10258,12 @@ dependencies = [ [[package]] name = "libsecp256k1" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +checksum = "e79019718125edc905a079a70cfa5f3820bc76139fc91d6f9abc27ea2a887139" dependencies = [ "arrayref", - "base64 0.13.1", + "base64 0.22.1", "digest 0.9.0", "hmac-drbg", "libsecp256k1-core", @@ -9978,9 +10331,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.13" +version = "1.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f526fdd09d99e19742883e43de41e1aa9e36db0c7ab7f935165d611c5cccc66" +checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" dependencies = [ "cc", "libc", @@ -10002,43 +10355,47 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "listener" version = "0.1.0" dependencies = [ "bytes", - "clap 4.4.14", + "clap 4.5.58", "tokio", ] +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "lodepng" -version = "3.9.2" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f56ff9bcd5721ab172b73eac8a7d4e9439f47a98581e666178dbe7df97e13" +checksum = "77a32335d22e44238e2bb0b4d726964d18952ce1f1279ec3305305d2c61539eb" dependencies = [ "crc32fast", - "fallible_collections", "flate2", "libc", "rgb", @@ -10046,11 +10403,11 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" dependencies = [ - "serde", + "serde_core", "value-bag", ] @@ -10074,19 +10431,18 @@ dependencies = [ [[package]] name = "lz4" -version = "1.25.0" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6eab492fe7f8651add23237ea56dbf11b3c4ff762ab83d40a47f11433421f91" +checksum = "a20b523e860d03443e98350ceaac5e71c6ba89aea7d960769ec3ce37f4de5af4" dependencies = [ - "libc", "lz4-sys", ] [[package]] name = "lz4-sys" -version = "1.9.5" +version = "1.11.1+lz4-1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" +checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" dependencies = [ "cc", "libc", @@ -10106,19 +10462,13 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "matchit" version = "0.5.0" @@ -10133,9 +10483,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "matrixmultiply" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08" dependencies = [ "autocfg", "rawpointer", @@ -10153,9 +10503,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -10168,12 +10518,12 @@ dependencies = [ [[package]] name = "memory-stats" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f79cf9964c5c9545493acda1263f1912f8d2c56c8a2ffee2606cb960acaacc" +checksum = "c73f5c649995a115e1a0220b35e4df0a1294500477f97a91d0660fb5abeb574a" dependencies = [ "libc", - "winapi 0.3.9", + "windows-sys 0.52.0", ] [[package]] @@ -10216,9 +10566,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -10232,7 +10582,7 @@ checksum = "c325dfab65f261f386debee8b0969da215b3fa0037e74c8a1234db7ba986d803" dependencies = [ "crossbeam-channel", "crossbeam-utils", - "dashmap", + "dashmap 5.5.3", "skeptic", "smallvec", "tagptr", @@ -10247,11 +10597,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "adler", + "adler2", "simd-adler32", ] @@ -10263,19 +10613,36 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.48.0", ] [[package]] -name = "mirai-annotations" -version = "1.12.0" +name = "mio" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.61.2", +] [[package]] -name = "mockall" -version = "0.11.4" +name = "miracl_core_bls12381" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07cbe42e2a8dd41df582fb8e00fc24d920b5561cc301fcb6d14e2e0434b500f" + +[[package]] +name = "mirai-annotations" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" + +[[package]] +name = "mockall" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" dependencies = [ @@ -10320,7 +10687,7 @@ dependencies = [ "anyhow", "aptos-framework", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "move-binary-format", ] @@ -10450,7 +10817,7 @@ name = "move-bytecode-viewer" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "crossterm 0.26.1", "move-binary-format", "move-bytecode-source-map", @@ -10464,7 +10831,7 @@ name = "move-cli" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "colored", "datatest-stable", @@ -10512,7 +10879,7 @@ version = "0.0.1" dependencies = [ "anyhow", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "datatest-stable", "hex", @@ -10548,7 +10915,7 @@ dependencies = [ "abstract-domain-derive", "anyhow", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "datatest-stable", "ethnum", @@ -10569,7 +10936,7 @@ dependencies = [ "move-stackless-bytecode", "move-stdlib", "move-symbol-pool", - "num 0.4.1", + "num 0.4.3", "once_cell", "petgraph 0.5.1", "walkdir", @@ -10599,9 +10966,9 @@ dependencies = [ "bcs 0.1.4", "bytes", "ethnum", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", - "num 0.4.1", + "num 0.4.3", "once_cell", "primitive-types 0.10.1", "proptest", @@ -10612,7 +10979,7 @@ dependencies = [ "serde", "serde_bytes", "serde_json", - "thiserror", + "thiserror 1.0.69", "uint", ] @@ -10622,7 +10989,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "codespan", "colored", "move-binary-format", @@ -10639,7 +11006,7 @@ name = "move-disassembler" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "colored", "move-binary-format", "move-bytecode-source-map", @@ -10655,7 +11022,7 @@ name = "move-docgen" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "codespan", "codespan-reporting", "datatest-stable", @@ -10708,7 +11075,7 @@ name = "move-explain" version = "0.1.0" dependencies = [ "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "move-command-line-common", "move-core-types", ] @@ -10719,7 +11086,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.5.58", "move-binary-format", "move-bytecode-source-map", "move-bytecode-verifier", @@ -10797,7 +11164,7 @@ dependencies = [ "move-ir-types", "move-prover-test-utils", "move-symbol-pool", - "num 0.4.1", + "num 0.4.3", "num-traits", "once_cell", "regex", @@ -10809,7 +11176,7 @@ name = "move-package" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "colored", "datatest-stable", "evm-exec-utils", @@ -10839,7 +11206,7 @@ dependencies = [ "termcolor", "toml 0.7.8", "walkdir", - "whoami", + "whoami 1.6.1", ] [[package]] @@ -10848,7 +11215,7 @@ version = "0.1.0" dependencies = [ "anyhow", "atty", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "datatest-stable", "itertools 0.12.1", @@ -10866,7 +11233,7 @@ dependencies = [ "move-stackless-bytecode", "once_cell", "serde", - "shell-words", + "shell-words 1.1.1", "simplelog", "tempfile", "toml 0.7.8", @@ -10891,7 +11258,7 @@ dependencies = [ "move-model", "move-prover-bytecode-pipeline", "move-stackless-bytecode", - "num 0.4.1", + "num 0.4.3", "once_cell", "pretty", "rand 0.7.3", @@ -10917,7 +11284,7 @@ dependencies = [ "move-stackless-bytecode", "move-stackless-bytecode-test-utils", "serde", - "shell-words", + "shell-words 1.1.1", "tempfile", "walkdir", ] @@ -10960,7 +11327,7 @@ dependencies = [ "move-core-types", "move-model", "move-stackless-bytecode-test-utils", - "num 0.4.1", + "num 0.4.3", "paste", "petgraph 0.5.1", ] @@ -11042,7 +11409,7 @@ version = "0.1.0" dependencies = [ "anyhow", "atty", - "clap 4.4.14", + "clap 4.5.58", "codespan", "codespan-reporting", "datatest-stable", @@ -11073,7 +11440,7 @@ name = "move-transactional-test-runner" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "datatest-stable", "difference", "move-binary-format", @@ -11105,7 +11472,7 @@ version = "0.1.0" dependencies = [ "anyhow", "better_any", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "colored", "datatest-stable", @@ -11168,7 +11535,7 @@ dependencies = [ "better_any", "bytes", "fail", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "lazy_static", "lru 0.7.8", @@ -11179,7 +11546,7 @@ dependencies = [ "move-ir-compiler", "move-vm-types", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "proptest", "serde", "sha3 0.9.1", @@ -11238,7 +11605,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 0.2.12", "httparse", "log", "memchr", @@ -11250,29 +11617,46 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.3" +version = "0.32.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa" +checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4" dependencies = [ "approx", "matrixmultiply", "nalgebra-macros", - "num-complex 0.4.4", - "num-rational 0.4.1", + "num-complex 0.4.6", + "num-rational 0.4.2", + "num-traits", + "simba 0.8.1", + "typenum", +] + +[[package]] +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx", + "matrixmultiply", + "num-complex 0.4.6", + "num-rational 0.4.2", "num-traits", - "simba", + "rand 0.8.5", + "rand_distr", + "simba 0.9.1", "typenum", ] [[package]] name = "nalgebra-macros" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.114", ] [[package]] @@ -11283,19 +11667,18 @@ checksum = "40a3eb6b7c682b65d1f631ec3176829d72ab450b3aacdd3f719bf220822e59ac" dependencies = [ "libc", "once_cell", - "parking_lot 0.12.1", - "thiserror", + "parking_lot 0.12.5", + "thiserror 1.0.69", "widestring", "winapi 0.3.9", ] [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -11318,7 +11701,7 @@ dependencies = [ "blake2s_simd", "blstrs 0.7.1", "byteorder", - "ff 0.13.0", + "ff 0.13.1", "generic-array 0.14.7", "log", "pasta_curves", @@ -11334,9 +11717,9 @@ checksum = "ca2b420f638f07fe83056b55ea190bb815f609ec5a35e7017884a10f78839c9e" [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" @@ -11355,8 +11738,20 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.10.0", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.10.0", "cfg-if", + "cfg_aliases", "libc", ] @@ -11390,18 +11785,18 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "ntapi" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" dependencies = [ "winapi 0.3.9", ] [[package]] name = "ntest" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da8ec6d2b73d45307e926f5af46809768581044384637af6b3f3fe7c3c88f512" +checksum = "54d1aa56874c2152c24681ed0df95ee155cc06c5c61b78e2d1e8c0cae8bc5326" dependencies = [ "ntest_test_cases", "ntest_timeout", @@ -11409,9 +11804,9 @@ dependencies = [ [[package]] name = "ntest_test_cases" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be7d33be719c6f4d09e64e27c1ef4e73485dc4cc1f4d22201f89860a7fe22e22" +checksum = "6913433c6319ef9b2df316bb8e3db864a41724c2bb8f12555e07dc4ec69d3db1" dependencies = [ "proc-macro2", "quote", @@ -11420,11 +11815,11 @@ dependencies = [ [[package]] name = "ntest_timeout" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066b468120587a402f0b47d8f80035c921f6a46f8209efd0632a89a16f5188a4" +checksum = "9224be3459a0c1d6e9b0f42ab0e76e98b29aef5aba33c0487dfcf47ea08b5150" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 1.0.109", @@ -11432,21 +11827,20 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "c073d3c1930d0751774acf49e66653acecb416c3a54c6ec095a9b11caddb5a68" dependencies = [ - "overload", - "winapi 0.3.9", + "windows-sys 0.48.0", ] [[package]] name = "nu-ansi-term" -version = "0.49.0" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c073d3c1930d0751774acf49e66653acecb416c3a54c6ec095a9b11caddb5a68" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -11465,15 +11859,15 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint 0.4.4", - "num-complex 0.4.4", + "num-bigint 0.4.6", + "num-complex 0.4.6", "num-integer", "num-iter", - "num-rational 0.4.1", + "num-rational 0.4.2", "num-traits", ] @@ -11502,22 +11896,20 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" dependencies = [ - "byteorder", "lazy_static", "libm", "num-integer", @@ -11539,13 +11931,19 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + [[package]] name = "num-derive" version = "0.3.3" @@ -11563,25 +11961,24 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "itoa", ] [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -11594,7 +11991,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-integer", "num-traits", ] @@ -11613,21 +12010,20 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-integer", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -11635,19 +12031,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.5.2", "libc", ] [[package]] name = "num_threads" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" dependencies = [ "libc", ] @@ -11672,29 +12068,68 @@ checksum = "60080faccd4ca50ad0b801b2be686136376b13f691f6eac84817e40973b2e1bb" dependencies = [ "anyhow", "itertools 0.10.5", - "num 0.4.1", + "num 0.4.3", +] + +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-system-configuration" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7216bd11cbda54ccabcab84d523dc93b858ec75ecfb3a7d89513fa22464da396" +dependencies = [ + "objc2-core-foundation", ] [[package]] name = "object" -version = "0.32.2" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "opaque-debug" @@ -11704,17 +12139,17 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.10.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -11731,20 +12166,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -11805,12 +12240,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owo-colors" version = "3.5.0" @@ -11826,7 +12255,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -11835,7 +12264,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" dependencies = [ - "unicode-width 0.1.11", + "unicode-width 0.1.14", ] [[package]] @@ -11862,7 +12291,7 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bitvec 0.20.4", "byte-slice-cast", "impl-trait-for-tuples", @@ -11872,15 +12301,17 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bitvec 1.0.1", "byte-slice-cast", + "const_format", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.9", + "parity-scale-codec-derive 3.7.5", + "rustversion", "serde", ] @@ -11898,21 +12329,21 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.114", ] [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -11927,12 +12358,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.12", ] [[package]] @@ -11951,22 +12382,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.48.5", + "windows-link", ] [[package]] name = "parse-zoneinfo" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" dependencies = [ "regex", ] @@ -12010,15 +12441,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "499cff8432e71c5f8784d9645aac0f9fca604d67f59b68a606170b5e229c6538" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.10.0", "ciborium", "coset", "data-encoding", - "indexmap 2.2.5", + "indexmap 2.13.0", "rand 0.8.5", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.9", "strum 0.25.0", "typeshare", ] @@ -12030,7 +12461,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ "blake2b_simd", - "ff 0.13.0", + "ff 0.13.1", "group 0.13.0", "hex", "lazy_static", @@ -12042,15 +12473,21 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3bf70094d203e07844da868b634207e71bfab254fe713171fae9a6e751ccf31" + +[[package]] +name = "pathdiff" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" dependencies = [ "camino", ] @@ -12124,26 +12561,25 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.7.6" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" dependencies = [ "memchr", - "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" dependencies = [ "pest", "pest_generator", @@ -12151,26 +12587,25 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" dependencies = [ - "once_cell", "pest", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -12185,86 +12620,113 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.2.5", + "indexmap 2.13.0", +] + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset 0.5.7", + "hashbrown 0.15.5", + "indexmap 2.13.0", ] [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_shared 0.11.3", +] + +[[package]] +name = "phf" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_shared 0.11.2", + "phf_shared 0.13.1", + "serde", ] [[package]] name = "phf_codegen" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" dependencies = [ "phf_generator", - "phf_shared 0.11.2", + "phf_shared 0.11.3", ] [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "phf_shared 0.11.2", + "phf_shared 0.11.3", "rand 0.8.5", ] [[package]] name = "phf_shared" -version = "0.10.0" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher", + "siphasher 1.0.2", ] [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ - "siphasher", + "siphasher 1.0.2", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -12274,12 +12736,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand 2.3.0", "futures-io", ] @@ -12300,7 +12762,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der 0.7.8", + "der 0.7.10", "pkcs8 0.10.2", "spki 0.7.3", ] @@ -12322,21 +12784,21 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", + "der 0.7.10", "spki 0.7.3", ] [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -12347,24 +12809,24 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] [[package]] name = "png" -version = "0.17.10" +version = "0.17.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -12383,15 +12845,15 @@ dependencies = [ "async-trait", "bytes", "chrono", - "cookie 0.17.0", + "cookie", "futures-util", "headers", - "http", + "http 0.2.12", "hyper", "mime", "multer", "nix 0.27.1", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "percent-encoding", "pin-project-lite", "poem-derive", @@ -12404,12 +12866,12 @@ dependencies = [ "serde_urlencoded", "smallvec", "tempfile", - "thiserror", + "thiserror 1.0.69", "time", "tokio", "tokio-rustls 0.24.1", "tokio-stream", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tracing", "wildmatch", ] @@ -12420,10 +12882,10 @@ version = "1.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ddcf4680d8d867e1e375116203846acb088483fa2070244f90589f458bbb31" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -12434,7 +12896,7 @@ checksum = "e69c569eb0671cc85e65cfb6bd960d0168d24732ff58825227b4d2a10167ba91" dependencies = [ "base64 0.13.1", "bytes", - "derive_more 0.99.17", + "derive_more 0.99.20", "futures-util", "mime", "num-traits", @@ -12445,8 +12907,8 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "serde_yaml 0.9.30", - "thiserror", + "serde_yaml 0.9.34+deprecated", + "thiserror 1.0.69", "tokio", "url", ] @@ -12458,7 +12920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "274cf13f710999977a3c1e396c2a5000d104075a7127ce6470fbdae4706be621" dependencies = [ "darling 0.14.4", - "http", + "http 0.2.12", "indexmap 1.9.3", "mime", "proc-macro-crate 1.3.1", @@ -12466,7 +12928,7 @@ dependencies = [ "quote", "regex", "syn 1.0.109", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -12487,27 +12949,27 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.5.2", "pin-project-lite", - "rustix 0.38.28", - "tracing", - "windows-sys 0.52.0", + "rustix 1.1.3", + "windows-sys 0.61.2", ] [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", "universal-hash", ] @@ -12533,9 +12995,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "poseidon-ark" @@ -12549,33 +13011,42 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.6" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" +checksum = "3ee9dd5fe15055d2b6806f4736aa0c9637217074e224bbec46d4041b91bb9491" dependencies = [ - "base64 0.21.6", + "base64 0.22.1", "byteorder", "bytes", "fallible-iterator", "hmac 0.12.1", "md-5", "memchr", - "rand 0.8.5", - "sha2 0.10.8", + "rand 0.9.2", + "sha2 0.10.9", "stringprep", ] [[package]] name = "postgres-types" -version = "0.2.6" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +checksum = "54b858f82211e84682fecd373f68e1ceae642d8d751a1ebd13f33de6257b3e20" dependencies = [ "bytes", "fallible-iterator", "postgres-protocol", ] +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -12596,20 +13067,23 @@ dependencies = [ "log", "nix 0.26.4", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "protobuf", "protobuf-codegen-pure", "smallvec", "symbolic-demangle", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "pq-sys" @@ -12642,15 +13116,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" dependencies = [ "predicates-core", "termtree", @@ -12668,12 +13142,12 @@ dependencies = [ [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", - "yansi 0.5.1", + "yansi", ] [[package]] @@ -12688,6 +13162,16 @@ dependencies = [ "structopt", ] +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.114", +] + [[package]] name = "prettytable-rs" version = "0.10.0" @@ -12695,11 +13179,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" dependencies = [ "csv", - "encode_unicode 1.0.0", + "encode_unicode", "is-terminal", "lazy_static", - "term", - "unicode-width 0.1.11", + "term 0.7.0", + "unicode-width 0.1.14", ] [[package]] @@ -12750,14 +13234,23 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" dependencies = [ - "toml_datetime", + "toml_datetime 0.6.3", "toml_edit 0.20.2", ] +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.10+spec-1.0.0", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -12796,9 +13289,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -12826,16 +13319,16 @@ checksum = "8bccbff07d5ed689c4087d20d7307a52ab6141edeedf487c3876a55b86cf63df" [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if", "fnv", "lazy_static", "memchr", - "parking_lot 0.12.1", - "thiserror", + "parking_lot 0.12.5", + "thiserror 1.0.69", ] [[package]] @@ -12865,19 +13358,18 @@ dependencies = [ [[package]] name = "proptest" -version = "1.4.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.4.1", - "lazy_static", + "bit-set 0.8.0", + "bit-vec 0.8.0", + "bitflags 2.10.0", "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rand_xorshift", - "regex-syntax 0.8.2", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift 0.4.0", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -12896,9 +13388,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", "prost-derive", @@ -12906,22 +13398,22 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "prost-types" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ "prost", ] @@ -12957,7 +13449,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", - "clap 4.4.14", + "clap 4.5.58", "codespan-reporting", "itertools 0.12.1", "log", @@ -12978,27 +13470,27 @@ checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" [[package]] name = "public-suffix" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca346b8ff0739660876c8d96a6f9de5cd9b4cd87500bb0ce92485318c674afe" +checksum = "51315bca45305dd8aa64b831b33e71abac528ca8058c0651346a39b8d3009498" [[package]] name = "publicsuffix" -version = "2.2.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" dependencies = [ - "idna 0.3.0", + "idna 1.1.0", "psl-types", ] [[package]] name = "pulldown-cmark" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "memchr", "unicase", ] @@ -13058,25 +13550,31 @@ dependencies = [ [[package]] name = "quick_cache" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347e1a588d1de074eeb3c00eadff93db4db65aeb62aee852b1efd0949fe65b6c" +checksum = "eb55a1aa7668676bb93926cd4e9cdfe60f03bb866553bcca9112554911b6d3dc" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "equivalent", - "hashbrown 0.14.3", - "parking_lot 0.12.1", + "hashbrown 0.14.5", + "parking_lot 0.12.5", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "r2d2" version = "0.8.10" @@ -13084,7 +13582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "scheduled-thread-pool", ] @@ -13125,6 +13623,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -13145,6 +13653,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -13160,12 +13678,31 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.11", + "getrandom 0.2.17", ] [[package]] -name = "rand_hc" -version = "0.2.0" +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ @@ -13190,6 +13727,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -13217,9 +13763,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -13227,9 +13773,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -13253,7 +13799,7 @@ dependencies = [ "ryu", "sha1_smol", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "url", ] @@ -13278,103 +13824,97 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" +dependencies = [ + "bitflags 2.10.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.11", + "getrandom 0.2.17", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "ref-cast" -version = "1.0.22" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.22" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.2" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.6", + "base64 0.21.7", "bytes", - "cookie 0.16.2", + "cookie", "cookie_store", "encoding_rs", "futures-core", "futures-util", "h2", - "http", + "http 0.2.12", "http-body", "hyper", "hyper-rustls 0.24.2", @@ -13388,16 +13928,17 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls 0.21.12", "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls 0.24.1", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tower-service", "url", "wasm-bindgen", @@ -13410,17 +13951,17 @@ dependencies = [ [[package]] name = "reqwest-middleware" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a3e86aa6053e59030e7ce2d2a3b258dd08fc2d337d52f73f6cb480f5858690" +checksum = "5a735987236a8e238bf0296c7e351b999c188ccc11477f311b82b55c93984216" dependencies = [ "anyhow", "async-trait", - "http", + "http 0.2.12", "reqwest", "serde", "task-local-extensions", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -13433,8 +13974,8 @@ dependencies = [ "async-trait", "chrono", "futures", - "getrandom 0.2.11", - "http", + "getrandom 0.2.17", + "http 0.2.12", "hyper", "parking_lot 0.11.2", "reqwest", @@ -13475,18 +14016,18 @@ dependencies = [ [[package]] name = "rfc7239" -version = "0.1.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087317b3cf7eb481f13bd9025d729324b7cd068d6f470e2d76d049e191f5ba47" +checksum = "4a82f1d1e38e9a85bb58ffcfadf22ed6f2c94e8cd8581ec2b0f80a2a6858350f" dependencies = [ "uncased", ] [[package]] name = "rgb" -version = "0.8.37" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" dependencies = [ "bytemuck", ] @@ -13508,16 +14049,16 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", - "getrandom 0.2.11", + "cfg-if", + "getrandom 0.2.17", "libc", - "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -13529,6 +14070,40 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "ritual_build" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f86c36bf720176c6d573d0827cd5b2b9f1c6a3450dc237374a35ce0f2268835" +dependencies = [ + "log", + "ritual_common", +] + +[[package]] +name = "ritual_common" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d30de34c9683bedc6f0b1f5a3ef0bb613df7ff7e1833c767eeed45f1a9d2af" +dependencies = [ + "bincode", + "dunce", + "failure", + "itertools 0.8.2", + "lazy_static", + "log", + "num_cpus", + "pathdiff 0.1.0", + "regex", + "semver 0.9.0", + "serde", + "serde_derive", + "serde_json", + "shell-words 0.1.0", + "term-painter", + "toml 0.4.10", +] + [[package]] name = "rlp" version = "0.5.2" @@ -13582,9 +14157,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ "const-oid 0.9.6", "digest 0.10.7", @@ -13594,7 +14169,7 @@ dependencies = [ "pkcs1 0.7.5", "pkcs8 0.10.2", "rand_core 0.6.4", - "sha2 0.10.8", + "sha2 0.10.9", "signature 2.2.0", "spki 0.7.3", "subtle", @@ -13656,9 +14231,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" @@ -13674,11 +14249,11 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver", + "semver 1.0.27", ] [[package]] @@ -13697,29 +14272,28 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.27" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "errno", - "io-lifetimes", "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] [[package]] name = "rustix" -version = "0.38.28" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.4.12", - "windows-sys 0.52.0", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] [[package]] @@ -13736,12 +14310,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.17.7", + "ring 0.17.14", "rustls-webpki 0.101.7", "sct", ] @@ -13753,24 +14327,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", - "ring 0.17.7", + "ring 0.17.14", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] [[package]] name = "rustls" -version = "0.23.7" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebbbdb961df0ad3f2652da8f3fdc4b36122f568f968f45ad3316f26c025c677b" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "log", "once_cell", - "ring 0.17.7", + "ring 0.17.14", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki 0.103.9", "subtle", "zeroize", ] @@ -13789,12 +14363,12 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.1", + "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", "security-framework", @@ -13815,24 +14389,26 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.6", + "base64 0.21.7", ] [[package]] name = "rustls-pemfile" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.21.6", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-webpki" @@ -13840,32 +14416,43 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", + "ring 0.17.14", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring 0.17.14", + "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "rustls-webpki" -version = "0.102.2" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ - "ring 0.17.7", + "ring 0.17.14", "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -13875,15 +14462,15 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "safe_arch" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" dependencies = [ "bytemuck", ] @@ -13905,7 +14492,7 @@ checksum = "5c55b744399c25532d63a0d2789b109df8d46fc93752d46b0782991a931a782f" dependencies = [ "bitvec 0.20.4", "cfg-if", - "derive_more 0.99.17", + "derive_more 0.99.20", "parity-scale-codec 2.3.1", "scale-info-derive", ] @@ -13924,11 +14511,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -13937,17 +14524,40 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot 0.12.1", + "parking_lot 0.12.5", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", ] [[package]] name = "scoped-futures" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1473e24c637950c9bd38763220bea91ec3e095a89f672bbd7a10d03e77ba467" +checksum = "1b24aae2d0636530f359e9d5ef0c04669d11c5e756699b27a6a6d845d8329091" dependencies = [ - "cfg-if", - "pin-utils", + "pin-project-lite", ] [[package]] @@ -13968,7 +14578,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.14", "untrusted 0.9.0", ] @@ -13985,7 +14595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der 0.7.8", + "der 0.7.10", "generic-array 0.14.7", "pkcs8 0.10.2", "serdect", @@ -13995,11 +14605,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "core-foundation", "core-foundation-sys", "libc", @@ -14008,9 +14618,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -14018,13 +14628,13 @@ dependencies = [ [[package]] name = "self-replace" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7828a58998685d8bf5a3c5e7a3379a5867289c20828c3ee436280b44b598515" +checksum = "03ec815b5eab420ab893f63393878d89c90fdd94c0bcc44c07abb8ad95552fb7" dependencies = [ - "fastrand 1.9.0", + "fastrand 2.3.0", "tempfile", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -14039,7 +14649,7 @@ dependencies = [ "regex", "reqwest", "self-replace", - "semver", + "semver 1.0.27", "serde_json", "tempfile", "urlencoding", @@ -14049,29 +14659,46 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "sender" version = "0.1.0" dependencies = [ "bytes", - "clap 4.4.14", + "clap 4.5.58", "event-listener 2.5.3", "tokio", ] [[package]] name = "serde" -version = "1.0.197" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -14109,7 +14736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12c47087018ec281d1cdab673d36aea22d816b54d498264029c05d5fa1910da6" dependencies = [ "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -14119,7 +14746,7 @@ source = "git+https://github.com/aptos-labs/serde-reflection?rev=73b6bbf748334b7 dependencies = [ "once_cell", "serde", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -14134,11 +14761,12 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.14" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -14147,31 +14775,42 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ - "half 1.8.2", + "half 1.8.3", "serde", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.13.0", "itoa", - "ryu", + "memchr", "serde", + "serde_core", + "zmij", ] [[package]] @@ -14182,7 +14821,20 @@ checksum = "606e91878516232ac3b16c12e063d4468d762f16d77e7aef14a1f2326c5f409b" dependencies = [ "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", +] + +[[package]] +name = "serde_norway" +version = "0.9.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e408f29489b5fd500fab51ff1484fc859bb655f32c671f307dcd733b72e8168c" +dependencies = [ + "indexmap 2.13.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml-norway", ] [[package]] @@ -14197,24 +14849,33 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.18" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -14229,16 +14890,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" dependencies = [ - "base64 0.21.6", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.5", - "serde", + "indexmap 2.13.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -14246,14 +14909,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" dependencies = [ - "darling 0.20.9", + "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -14270,11 +14933,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.30" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.13.0", "itoa", "ryu", "serde", @@ -14314,9 +14977,9 @@ dependencies = [ [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" @@ -14328,14 +14991,14 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", ] [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -14344,14 +15007,14 @@ dependencies = [ [[package]] name = "sha256" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" +checksum = "f880fc8562bdeb709793f00eb42a2ad0e672c4f883bbe59122b926eca935c8f6" dependencies = [ "async-trait", "bytes", "hex", - "sha2 0.10.8", + "sha2 0.10.9", "tokio", ] @@ -14377,7 +15040,7 @@ dependencies = [ "block-buffer 0.9.0", "digest 0.9.0", "keccak", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", ] [[package]] @@ -14414,9 +15077,15 @@ dependencies = [ [[package]] name = "shell-words" -version = "1.1.0" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39acde55a154c4cd3ae048ac78cc21c25f3a0145e44111b523279113dce0d94a" + +[[package]] +name = "shell-words" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" [[package]] name = "shlex" @@ -14426,9 +15095,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" dependencies = [ "libc", "signal-hook-registry", @@ -14436,21 +15105,22 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", - "mio", + "mio 0.8.11", "signal-hook", ] [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -14477,7 +15147,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" dependencies = [ "approx", - "num-complex 0.4.4", + "num-complex 0.4.6", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "simba" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c99284beb21666094ba2b75bbceda012e610f5479dfcc2d6e2426f53197ffd95" +dependencies = [ + "approx", + "num-complex 0.4.6", "num-traits", "paste", "wide", @@ -14485,27 +15168,27 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "similar" -version = "2.4.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" dependencies = [ - "bstr 0.2.17", + "bstr", "unicode-segmentation", ] [[package]] name = "similar-asserts" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e041bb827d1bfca18f213411d51b665309f1afb37a04a5d1464530e13779fc0f" +checksum = "b5b441962c817e33508847a22bd82f03a30cff43642dc2fae8b050566121eb9a" dependencies = [ - "console", + "console 0.15.11", "similar", ] @@ -14522,13 +15205,13 @@ dependencies = [ [[package]] name = "simple_asn1" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ - "num-bigint 0.4.4", + "num-bigint 0.4.6", "num-traits", - "thiserror", + "thiserror 2.0.18", "time", ] @@ -14549,6 +15232,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + [[package]] name = "sized-chunks" version = "0.6.5" @@ -14576,18 +15265,15 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "slug" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" +checksum = "882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724" dependencies = [ "deunicode", "wasm-bindgen", @@ -14606,15 +15292,15 @@ dependencies = [ [[package]] name = "smallbitvec" -version = "2.5.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75ce4f9dc4a41b4c3476cc925f1efb11b66df373a8fde5d4b8915fa91b5d995e" +checksum = "d31d263dd118560e1a492922182ab6ca6dc1d03a3bf54e7699993f31a4150e3f" [[package]] name = "smallvec" -version = "1.13.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smawk" @@ -14722,22 +15408,22 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.10" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", - "winapi 0.3.9", + "windows-sys 0.52.0", ] [[package]] name = "socket2" -version = "0.5.5" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] @@ -14751,9 +15437,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "spki" @@ -14772,14 +15455,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der 0.7.10", ] [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -14787,6 +15470,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "statrs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" +dependencies = [ + "approx", + "nalgebra 0.33.2", + "num-traits", + "rand 0.8.5", +] + [[package]] name = "status-line" version = "0.2.0" @@ -14805,26 +15500,25 @@ checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" [[package]] name = "string_cache" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", - "once_cell", - "parking_lot 0.12.1", - "phf_shared 0.10.0", + "parking_lot 0.12.5", + "phf_shared 0.11.3", "precomputed-hash", ] [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] @@ -14886,9 +15580,9 @@ dependencies = [ [[package]] name = "strum" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" [[package]] name = "strum_macros" @@ -14913,7 +15607,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -14926,14 +15620,14 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "subtle-ng" @@ -14948,7 +15642,7 @@ dependencies = [ "anyhow", "aptos-types", "async-trait", - "clap 4.4.14", + "clap 4.5.58", "reqwest", ] @@ -14988,9 +15682,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -15003,6 +15697,29 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "sysinfo" version = "0.28.4" @@ -15053,9 +15770,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.40" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" dependencies = [ "filetime", "libc", @@ -15064,23 +15781,28 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.13" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "target-spec" -version = "3.1.0" +version = "3.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a8e795b1824524d13cdf04f73cf8b4f244ce86c96b4d2a83a6ca1a753d2752" +checksum = "585c173ce474b6257cfb2a107949e48eb1ab9cae21cecbdf13401ae3be4a411a" dependencies = [ "cfg-expr", "guppy-workspace-hack", "serde", "target-lexicon", - "unicode-ident", ] +[[package]] +name = "target-triple" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" + [[package]] name = "task-local-extensions" version = "0.1.4" @@ -15092,22 +15814,22 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" dependencies = [ - "cfg-if", - "fastrand 2.0.1", - "redox_syscall 0.4.1", - "rustix 0.38.28", - "windows-sys 0.52.0", + "fastrand 2.3.0", + "getrandom 0.4.1", + "once_cell", + "rustix 1.1.3", + "windows-sys 0.61.2", ] [[package]] name = "tera" -version = "1.19.1" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" +checksum = "e8004bca281f2d32df3bacd59bc67b312cb4c70cea46cbd79dbe8ac5ed206722" dependencies = [ "chrono", "chrono-tz", @@ -15122,7 +15844,17 @@ dependencies = [ "serde", "serde_json", "slug", - "unic-segment", + "unicode-segmentation", +] + +[[package]] +name = "term" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" +dependencies = [ + "kernel32-sys", + "winapi 0.2.8", ] [[package]] @@ -15136,6 +15868,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "term-painter" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcaa948f0e3e38470cd8dc8dcfe561a75c9e43f28075bb183845be2b9b3c08cf" +dependencies = [ + "term 0.4.6", +] + [[package]] name = "termcolor" version = "1.1.3" @@ -15147,9 +15888,9 @@ dependencies = [ [[package]] name = "termtree" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "test-case" @@ -15169,7 +15910,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -15180,7 +15921,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", "test-case-core", ] @@ -15188,9 +15929,9 @@ dependencies = [ name = "test-generation" version = "0.1.0" dependencies = [ - "clap 4.4.14", + "clap 4.5.58", "crossbeam-channel", - "getrandom 0.2.11", + "getrandom 0.2.17", "hex", "itertools 0.12.1", "module-generation", @@ -15214,7 +15955,7 @@ name = "testdiff" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.5.58", "once_cell", "regex", "walkdir", @@ -15226,7 +15967,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width 0.1.11", + "unicode-width 0.1.14", ] [[package]] @@ -15236,7 +15977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd05616119e612a8041ef58f2b578906cc2531a6069047ae092cfb86a325d835" dependencies = [ "smawk", - "unicode-width 0.1.11", + "unicode-width 0.1.14", ] [[package]] @@ -15247,43 +15988,62 @@ checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d" dependencies = [ "smawk", "unicode-linebreak", - "unicode-width 0.1.11", + "unicode-width 0.1.14", ] [[package]] name = "textwrap" -version = "0.16.0" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" + +[[package]] +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] [[package]] name = "thiserror" -version = "1.0.61" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -15297,9 +16057,9 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" dependencies = [ "flate2", "jpeg-decoder", @@ -15308,32 +16068,34 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", "libc", + "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ + "num-conv", "time-core", ] @@ -15350,7 +16112,7 @@ dependencies = [ "rand 0.7.3", "rustc-hash", "sha2 0.9.9", - "thiserror", + "thiserror 1.0.69", "unicode-normalization", "wasm-bindgen", "zeroize", @@ -15365,6 +16127,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -15377,9 +16149,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -15392,29 +16164,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "backtrace", "bytes", "libc", - "mio", - "num_cpus", - "parking_lot 0.12.1", + "mio 1.1.1", + "parking_lot 0.12.5", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2 0.6.2", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-io-timeout" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +checksum = "0bd86198d9ee903fedd2f9a2e72014287c0d9167e4ae43b5853007205dda1b76" dependencies = [ "pin-project-lite", "tokio", @@ -15422,13 +16192,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] @@ -15443,9 +16213,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.10" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +checksum = "dcea47c8f71744367793f16c2db1f11cb859d28f436bdb4ca9193eb1f787ee42" dependencies = [ "async-trait", "byteorder", @@ -15454,17 +16224,17 @@ dependencies = [ "futures-channel", "futures-util", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "percent-encoding", - "phf", + "phf 0.13.1", "pin-project-lite", "postgres-protocol", "postgres-types", - "rand 0.8.5", - "socket2 0.5.5", + "rand 0.9.2", + "socket2 0.6.2", "tokio", - "tokio-util 0.7.10", - "whoami", + "tokio-util 0.7.18", + "whoami 2.1.1", ] [[package]] @@ -15495,21 +16265,31 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.12", "tokio", ] [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.23.7", + "rustls 0.22.4", "rustls-pki-types", "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls 0.23.36", + "tokio", +] + [[package]] name = "tokio-scoped" version = "0.2.0" @@ -15522,9 +16302,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -15533,12 +16313,10 @@ dependencies = [ [[package]] name = "tokio-test" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b3cbabd3ae862100094ae433e1def582cf86451b4e9bf83aa7ac1d8a7d719" +checksum = "3f6d24790a10a7af737693a3e8f1d03faef7e6ca0cc99aae5066f533766de545" dependencies = [ - "async-stream", - "bytes", "futures-core", "tokio", "tokio-stream", @@ -15546,9 +16324,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", @@ -15572,9 +16350,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -15582,7 +16360,15 @@ dependencies = [ "futures-sink", "pin-project-lite", "tokio", - "tracing", +] + +[[package]] +name = "toml" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" +dependencies = [ + "serde", ] [[package]] @@ -15602,11 +16388,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", "toml_edit 0.19.15", ] +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap 2.13.0", + "serde_core", + "serde_spanned 1.0.4", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.14", +] + [[package]] name = "toml_datetime" version = "0.6.3" @@ -15616,17 +16417,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.13.0", "serde", - "serde_spanned", - "toml_datetime", - "winnow", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "winnow 0.5.40", ] [[package]] @@ -15635,11 +16445,38 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.2.5", - "toml_datetime", - "winnow", + "indexmap 2.13.0", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.14", +] + +[[package]] +name = "toml_parser" +version = "1.0.7+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "247eaa3197818b831697600aadf81514e577e0cba5eab10f7e064e78ae154df1" +dependencies = [ + "winnow 0.7.14", ] +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + [[package]] name = "tonic" version = "0.11.0" @@ -15652,19 +16489,19 @@ dependencies = [ "bytes", "flate2", "h2", - "http", + "http 0.2.12", "http-body", "hyper", "hyper-timeout", "percent-encoding", "pin-project", "prost", - "rustls-native-certs 0.7.0", - "rustls-pemfile 2.1.1", - "strum 0.26.2", + "rustls-native-certs 0.7.3", + "rustls-pemfile 2.2.0", + "strum 0.26.3", "strum_macros 0.26.4", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.4", "tokio-stream", "tower", "tower-layer", @@ -15700,7 +16537,7 @@ dependencies = [ "rand 0.8.5", "slab", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tower-layer", "tower-service", "tracing", @@ -15717,7 +16554,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", + "http 0.2.12", "http-body", "http-range-header", "pin-project-lite", @@ -15736,7 +16573,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", + "http 0.2.12", "http-body", "http-range-header", "pin-project-lite", @@ -15747,21 +16584,21 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -15771,20 +16608,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -15813,9 +16650,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -15823,14 +16660,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", - "nu-ansi-term 0.46.0", + "nu-ansi-term 0.50.3", "once_cell", - "regex", + "regex-automata", "serde", "serde_json", "sharded-slab", @@ -15874,9 +16711,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" dependencies = [ "serde", "stable_deref_trait", @@ -15890,17 +16727,17 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.88" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76de4f783e610194f6c98bfd53f9fc52bb2e0d02c947621e8a0f4ecc799b2880" +checksum = "5f614c21bd3a61bad9501d75cbb7686f00386c806d7f456778432c25cf86948a" dependencies = [ - "basic-toml", "glob", - "once_cell", "serde", "serde_derive", "serde_json", + "target-triple", "termcolor", + "toml 0.9.12+spec-1.1.0", ] [[package]] @@ -15913,24 +16750,24 @@ dependencies = [ "cassowary", "crossterm 0.25.0", "unicode-segmentation", - "unicode-width 0.1.11", + "unicode-width 0.1.14", ] [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.4.0", "httparse", "log", "rand 0.8.5", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", ] @@ -15943,15 +16780,15 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "typenum" -version = "1.17.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "typeshare" -version = "1.0.1" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f44d1a2f454cb35fbe05b218c410792697e76bd868f48d3a418f2cd1a7d527d6" +checksum = "da1bf9fe204f358ffea7f8f779b53923a20278b3ab8e8d97962c5e1b3a54edb7" dependencies = [ "chrono", "serde", @@ -15961,12 +16798,12 @@ dependencies = [ [[package]] name = "typeshare-annotation" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc670d0e358428857cc3b4bf504c691e572fccaec9542ff09212d3f13d74b7a9" +checksum = "621963e302416b389a1ec177397e9e62de849a78bd8205d428608553def75350" dependencies = [ "quote", - "syn 1.0.109", + "syn 2.0.114", ] [[package]] @@ -15992,18 +16829,18 @@ dependencies = [ [[package]] name = "tzdb_data" -version = "0.1.1" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629555d2921f3f0dc0de98699415a8b2b61dfcd3a0b082a327f7ed748bbb2b76" +checksum = "310d19de36af75a78ec83fdb325bf4e3a13ab0ab77b7b1a13fabbd059e9b525b" dependencies = [ "tz-rs", ] [[package]] name = "ucd-trie" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uint" @@ -16025,83 +16862,30 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "uncased" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" dependencies = [ "version_check", ] -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" -dependencies = [ - "unic-ucd-segment", -] - -[[package]] -name = "unic-ucd-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicase" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "unicode-linebreak" @@ -16111,36 +16895,42 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -16154,9 +16944,15 @@ dependencies = [ [[package]] name = "unsafe-libyaml" -version = "0.2.10" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "unsafe-libyaml-norway" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" +checksum = "b39abd59bf32521c7f2301b52d05a6a2c975b6003521cbd0c6dc1582f0a22104" [[package]] name = "untrusted" @@ -16189,14 +16985,15 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna 1.1.0", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -16207,17 +17004,17 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utcnow" -version = "0.2.4" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b10d49a98e3bbd9b73084a7b15f96c5b2136d5a2e2799b99d19a2774d8519d1f" +checksum = "c3d1b903f7711bad0f9c1716c1497bf3db4289c53a2985ba42ac2f2e04047bd9" dependencies = [ - "autocfg", "const_fn", "errno", "js-sys", "libc", - "rustix 0.38.28", - "wasi 0.11.0+wasi-snapshot-preview1", + "rustix 0.38.44", + "rustversion", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", "winapi 0.3.9", ] @@ -16228,42 +17025,76 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "uuid" -version = "1.6.1" +name = "utoipa" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993" dependencies = [ - "getrandom 0.2.11", + "indexmap 2.13.0", "serde", + "serde_json", + "serde_norway", + "utoipa-gen", ] [[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "value-bag" -version = "1.5.0" +name = "utoipa-gen" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd65ff0de3304a013e6dfeb7324e1cd389a8a000e582e3c9c9fae82ced778e26" +checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "uuid", +] [[package]] -name = "variant_count" -version = "1.1.0" +name = "uuid" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ - "quote", - "syn 1.0.109", + "getrandom 0.3.4", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "value-bag" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" + +[[package]] +name = "variant_count" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1935e10c6f04d22688d07c0790f2fc0e1b1c5c2c55bc0cc87ed67656e587dd8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", ] [[package]] @@ -16286,30 +17117,30 @@ checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] [[package]] name = "waker-fn" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -16326,15 +17157,15 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" +checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" dependencies = [ "bytes", "futures-channel", "futures-util", "headers", - "http", + "http 0.2.12", "hyper", "log", "mime", @@ -16342,16 +17173,15 @@ dependencies = [ "multer", "percent-encoding", "pin-project", - "rustls-pemfile 1.0.4", + "rustls-pemfile 2.2.0", "scoped-tls", "serde", "serde_json", "serde_urlencoded", "tokio", - "tokio-rustls 0.24.1", - "tokio-stream", + "tokio-rustls 0.25.0", "tokio-tungstenite", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tower-service", "tracing", ] @@ -16365,7 +17195,7 @@ dependencies = [ "hyper", "once_cell", "reqwest", - "thiserror", + "thiserror 1.0.69", "unicase", "warp", ] @@ -16378,9 +17208,36 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] [[package]] name = "wasite" @@ -16389,47 +17246,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] -name = "wasm-bindgen" -version = "0.2.89" +name = "wasite" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "66fe902b4a6b8028a753d5424909b764ccf79b7a209eac9bf97e59cda9f71a42" dependencies = [ - "cfg-if", - "wasm-bindgen-macro", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.89" +name = "wasm-bindgen" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ - "bumpalo", - "log", + "cfg-if", "once_cell", - "proc-macro2", - "quote", - "syn 2.0.48", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -16437,28 +17293,53 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.48", - "wasm-bindgen-backend", + "syn 2.0.114", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.13.0", + "wasm-encoder", + "wasmparser", +] [[package]] name = "wasm-streams" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -16482,11 +17363,23 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.10.0", + "hashbrown 0.15.5", + "indexmap 2.13.0", + "semver 1.0.27", +] + [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -16508,21 +17401,21 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.7", + "ring 0.17.14", "untrusted 0.9.0", ] [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "weezl" -version = "0.1.7" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "which" @@ -16533,25 +17426,38 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.28", + "rustix 0.38.44", ] [[package]] name = "whoami" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fec781d48b41f8163426ed18e8fc2864c12937df9ce54c88ede7bd47270893e" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" dependencies = [ - "redox_syscall 0.4.1", - "wasite", + "libredox", + "wasite 0.1.0", + "web-sys", +] + +[[package]] +name = "whoami" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6a5b12f9df4f978d2cfdb1bd3bac52433f44393342d7ee9c25f5a1c14c0f45d" +dependencies = [ + "libc", + "libredox", + "objc2-system-configuration", + "wasite 1.0.2", "web-sys", ] [[package]] name = "wide" -version = "0.7.13" +version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c68938b57b33da363195412cfc5fc37c9ed49aa9cfe2156fde64b8d2c9498242" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" dependencies = [ "bytemuck", "safe_arch", @@ -16565,9 +17471,9 @@ checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" [[package]] name = "wildmatch" -version = "2.3.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495ec47bf3c1345005f40724f0269362c8556cbc43aed0526ed44cae1d35fceb" +checksum = "29333c3ea1ba8b17211763463ff24ee84e41c78224c16b001cd907e663a38c68" [[package]] name = "winapi" @@ -16585,6 +17491,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -16593,11 +17505,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "winapi 0.3.9", + "windows-sys 0.61.2", ] [[package]] @@ -16608,11 +17520,61 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.52.0" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-targets 0.52.0", + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", ] [[package]] @@ -16639,7 +17601,34 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", ] [[package]] @@ -16674,17 +17663,35 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -16701,9 +17708,15 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -16719,9 +17732,15 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -16737,9 +17756,27 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -16755,9 +17792,15 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -16773,9 +17816,15 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -16791,9 +17840,15 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -16809,15 +17864,30 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.5.33" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7520bbdec7211caa7c4e682eb1fbe07abe20cee6756b6e00f537c82c11816aa" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -16832,6 +17902,100 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.13.0", + "prettyplease", + "syn 2.0.114", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.114", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.10.0", + "indexmap 2.13.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.13.0", + "log", + "semver 1.0.27", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + [[package]] name = "wyz" version = "0.2.0" @@ -16859,13 +18023,12 @@ dependencies = [ [[package]] name = "xattr" -version = "1.2.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914566e6413e7fa959cc394fb30e563ba80f3541fbd40816d4c05a0fc3f2a0f1" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", - "linux-raw-sys 0.4.12", - "rustix 0.38.28", + "rustix 1.1.3", ] [[package]] @@ -16879,15 +18042,32 @@ dependencies = [ [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] -name = "yansi" -version = "1.0.0-rc.1" +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure 0.13.2", +] [[package]] name = "yup-oauth2" @@ -16897,9 +18077,9 @@ checksum = "b61da40aeb0907a65f7fb5c1de83c5a224d6a9ebb83bf918588a2bb744d636b8" dependencies = [ "anyhow", "async-trait", - "base64 0.21.6", + "base64 0.21.7", "futures", - "http", + "http 0.2.12", "hyper", "hyper-rustls 0.24.2", "itertools 0.12.1", @@ -16924,47 +18104,101 @@ checksum = "57b52f3d4b300ffa9400cd78caebaaa6ef5a0189d08ec134624e2b8f3890b6e0" dependencies = [ "smt2parser", "structopt", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", + "synstructure 0.13.2", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.114", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", ] [[package]] @@ -16982,37 +18216,49 @@ dependencies = [ [[package]] name = "zipsign-api" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413a546ada9dbcd0b9a3e0b0880581279e35047bce9797e523b3408e1df607c" +checksum = "dba6063ff82cdbd9a765add16d369abe81e520f836054e997c2db217ceca40c0" dependencies = [ - "ed25519-dalek 2.1.1", - "thiserror", + "ed25519-dalek 2.2.0", + "thiserror 2.0.18", ] +[[package]] +name = "zlib-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" + +[[package]] +name = "zmij" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" + [[package]] name = "zstd" -version = "0.13.0" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.0.0" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index c40673ebf10..9e3e8943adf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -536,6 +536,7 @@ criterion-cpu-time = "0.1.0" crossbeam = "0.8.1" crossbeam-channel = "0.5.4" crossterm = "0.26.1" +crypto = { git = "ssh://git@github.com/Entropy-Foundation/crypto", rev = "d045a68" } csv = "1.2.1" curve25519-dalek = "3" curve25519-dalek-ng = "4" @@ -547,7 +548,7 @@ derivation-path = "0.2.0" derive_builder = "0.20.0" derive-getters = "0.5.0" determinator = "0.12.0" -derive_more = { version = "2.0.1",features = ["full"] } +derive_more = { version = "2.0.1", features = ["full"] } diesel = "2.1" # Use the crate version once this feature gets released on crates.io: # https://github.com/weiznich/diesel_async/commit/e165e8c96a6c540ebde2d6d7c52df5c5620a4bf1 @@ -741,7 +742,7 @@ shell-words = "1.0.0" siphasher = "0.3.10" serde = { version = "1.0.193", features = ["derive", "rc"] } serde-big-array = "0.5.1" -serde_bytes = "0.11.6" +serde_bytes = "0.11.19" serde_json = { version = "1.0.81", features = [ "preserve_order", "arbitrary_precision", @@ -808,6 +809,7 @@ ureq = { version = "1.5.4", features = [ "native-tls", ], default_features = false } url = { version = "2.4.0", features = ["serde"] } +utoipa = { version = "5.3.1", features = ["preserve_order", "yaml"] } uuid = { version = "1.0.0", features = ["v4", "serde"] } variant_count = "1.1.0" walkdir = "2.3.3" diff --git a/api/src/events.rs b/api/src/events.rs index 49c4fad21ce..230fde21e9e 100644 --- a/api/src/events.rs +++ b/api/src/events.rs @@ -170,7 +170,7 @@ impl EventsApi { page.limit(&latest_ledger_info)?, ledger_version, ) - .context(format!("Failed to find events by key {}", event_key)) + .context(format!("Failed to find events by key {event_key}")) .map_err(|err| { BasicErrorWith404::internal_with_code( err, diff --git a/api/src/tests/multisig_transactions_test.rs b/api/src/tests/multisig_transactions_test.rs index a01ccf1c9f5..43dcb4aa453 100644 --- a/api/src/tests/multisig_transactions_test.rs +++ b/api/src/tests/multisig_transactions_test.rs @@ -98,16 +98,12 @@ async fn test_multisig_transaction_to_update_owners() { // There should be 4 owners now. assert_multisig_tx_executed(&mut context, multisig_account, add_owners_payload, 1).await; - assert_owners( - &context, - multisig_account, - vec![ - owner_account_1.address(), - owner_account_2.address(), - owner_account_3.address(), - owner_account_4.address(), - ], - ) + assert_owners(&context, multisig_account, vec![ + owner_account_1.address(), + owner_account_2.address(), + owner_account_3.address(), + owner_account_4.address(), + ]) .await; let remove_owners_payload = bcs::to_bytes(&MultisigTransactionPayload::EntryFunction( @@ -136,15 +132,11 @@ async fn test_multisig_transaction_to_update_owners() { .await; // There should be 3 owners now that owner 4 has been kicked out. assert_multisig_tx_executed(&mut context, multisig_account, remove_owners_payload, 2).await; - assert_owners( - &context, - multisig_account, - vec![ - owner_account_1.address(), - owner_account_2.address(), - owner_account_3.address(), - ], - ) + assert_owners(&context, multisig_account, vec![ + owner_account_1.address(), + owner_account_2.address(), + owner_account_3.address(), + ]) .await; } diff --git a/api/src/transactions.rs b/api/src/transactions.rs index b2e647ada32..ee7a7768d99 100644 --- a/api/src/transactions.rs +++ b/api/src/transactions.rs @@ -1080,8 +1080,7 @@ impl TransactionsApi { ledger_info, params.automated_function(), )?; - - } + }, } } }, @@ -1418,7 +1417,7 @@ impl TransactionsApi { auto_payload.module_id(), &auto_payload.function().into(), ) - } + }, } } else { "Multisig::unknown".to_string() diff --git a/api/test-context/move/Move.toml b/api/test-context/move/Move.toml index bb81e10e4a5..e9934c35cdf 100644 --- a/api/test-context/move/Move.toml +++ b/api/test-context/move/Move.toml @@ -3,7 +3,7 @@ name = "TransactationTests" version = "0.0.0" [addresses] -entry_func_failed= "0x1" +entry_func_failed = "0x1" [dependencies] AptosFramework = { local = "../../../aptos-move/framework/aptos-framework" } diff --git a/api/types/Cargo.toml b/api/types/Cargo.toml index 4f395c7457d..8de154148cf 100644 --- a/api/types/Cargo.toml +++ b/api/types/Cargo.toml @@ -36,6 +36,7 @@ poem-openapi = { workspace = true } poem-openapi-derive = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } +sha3 = { workspace = true } [package.metadata.cargo-machete] ignored = ["async-trait", "poem", "poem-openapi-derive"] diff --git a/api/types/src/convert.rs b/api/types/src/convert.rs index 6d192715360..a4e63181109 100644 --- a/api/types/src/convert.rs +++ b/api/types/src/convert.rs @@ -3,17 +3,16 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::transaction::{ - AutomationRegistrationParams, AutomationRegistrationParamsV1, AutomationRegistrationParamsV2, -}; use crate::{ transaction::{ - BlockEpilogueTransaction, DecodedTableData, DeleteModule, DeleteResource, DeleteTableItem, - DeletedTableData, MultisigPayload, MultisigTransactionPayload, StateCheckpointTransaction, - UserTransactionRequestInner, WriteModule, WriteResource, WriteTableItem, + AutomationRegistrationParams, AutomationRegistrationParamsV1, + AutomationRegistrationParamsV2, BlockEpilogueTransaction, DecodedTableData, DeleteModule, + DeleteResource, DeleteTableItem, DeletedTableData, MultisigPayload, + MultisigTransactionPayload, StateCheckpointTransaction, UserTransactionRequestInner, + WriteModule, WriteResource, WriteTableItem, }, view::{ViewFunction, ViewRequest}, - Address, Bytecode, DirectWriteSet, EntryFunctionId, EntryFunctionPayload, Event, + Address, Bytecode, DirectWriteSet, EntryFunctionId, EntryFunctionPayload, EventV1, EventV2, HexEncodedBytes, MoveFunction, MoveModuleBytecode, MoveResource, MoveScriptBytecode, MoveType, MoveValue, PendingTransaction, ResourceGroup, ScriptPayload, ScriptWriteSet, SubmitTransactionRequest, Transaction, TransactionInfo, TransactionOnChainData, @@ -25,10 +24,6 @@ use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_logger::{sample, sample::SampleRate}; use aptos_resource_viewer::AptosValueAnnotator; use aptos_storage_interface::DbReader; -use aptos_types::transaction::automation::RegistrationParams; -use aptos_types::transaction::Transaction::{ - AutomationRegistryTransaction, SystemAutomatedTransaction, -}; use aptos_types::{ access_path::{AccessPath, Path}, chain_id::ChainId, @@ -40,8 +35,11 @@ use aptos_types::{ StateView, }, transaction::{ + automation::RegistrationParams, BlockEndInfo, BlockEpiloguePayload, EntryFunction, ExecutionStatus, Multisig, - RawTransaction, Script, SignedTransaction, TransactionAuxiliaryData, + RawTransaction, Script, SignedTransaction, + Transaction::{AutomationRegistryTransaction, SystemAutomatedTransaction}, + TransactionAuxiliaryData, }, vm_status::AbortLocation, write_set::WriteOp, @@ -148,7 +146,6 @@ impl<'a, S: StateView> MoveConverter<'a, S> { let resources_with_tag: Vec<(StructTag, Vec)> = bcs::from_bytes::(bytes) .map(|map| { map.into_iter() - .map(|(key, value)| (key, value)) .collect::>() })?; @@ -617,7 +614,18 @@ impl<'a, S: StateView> MoveConverter<'a, S> { })) } - pub fn try_into_events(&self, events: &[ContractEvent]) -> Result> { + pub fn try_into_events(&self, events: &[ContractEvent]) -> Result> { + let mut ret = vec![]; + for event in events { + let data = self + .inner + .view_value(event.type_tag(), event.event_data())?; + ret.push((event, MoveValue::try_from(data)?.json()?).into()); + } + Ok(ret) + } + + pub fn try_into_v2_events(&self, events: &[ContractEvent]) -> Result> { let mut ret = vec![]; for event in events { let data = self diff --git a/api/types/src/lib.rs b/api/types/src/lib.rs index ccb1da50d0a..6a527915062 100644 --- a/api/types/src/lib.rs +++ b/api/types/src/lib.rs @@ -46,8 +46,8 @@ use std::str::FromStr; pub use table::{RawTableItemRequest, TableItemRequest}; pub use transaction::{ AccountSignature, BlockMetadataTransaction, DeleteModule, DeleteResource, DeleteTableItem, - DirectWriteSet, Ed25519Signature, EncodeSubmissionRequest, EntryFunctionPayload, Event, - FeePayerSignature, GasEstimation, GasEstimationBcs, GenesisPayload, GenesisTransaction, + DirectWriteSet, Ed25519Signature, EncodeSubmissionRequest, EntryFunctionPayload, EventV1, + EventV2, FeePayerSignature, GasEstimation, GasEstimationBcs, GenesisPayload, GenesisTransaction, MultiAgentSignature, MultiEd25519Signature, MultiKeySignature, MultisigPayload, MultisigTransactionPayload, PendingTransaction, PublicKey, ScriptPayload, ScriptWriteSet, Signature, SingleKeySignature, SubmitTransactionRequest, Transaction, TransactionData, diff --git a/api/types/src/transaction.rs b/api/types/src/transaction.rs index 69481e060cb..bc33720b67a 100755 --- a/api/types/src/transaction.rs +++ b/api/types/src/transaction.rs @@ -8,7 +8,7 @@ use crate::{ MoveModuleBytecode, MoveModuleId, MoveResource, MoveScriptBytecode, MoveStructTag, MoveType, MoveValue, VerifyInput, VerifyInputWithRecursion, U64, }; -use anyhow::{bail, Context as AnyhowContext}; +use anyhow::{anyhow, bail, Context as AnyhowContext, Error as AnyhowError}; use aptos_crypto::{ ed25519::{self, Ed25519PublicKey, ED25519_PUBLIC_KEY_LENGTH, ED25519_SIGNATURE_LENGTH}, multi_ed25519::{self, MultiEd25519PublicKey, BITMAP_NUM_OF_BYTES, MAX_NUM_OF_KEYS}, @@ -19,10 +19,11 @@ use aptos_crypto::{ use aptos_types::{ account_address::AccountAddress, aggregate_signature::AggregateSignature, + aptos_dkg::{DKGTranscript, DKGTranscriptMetadata}, block_metadata::BlockMetadata, block_metadata_ext::BlockMetadataExt, contract_event::{ContractEvent, EventWithVersion}, - dkg::{DKGTranscript, DKGTranscriptMetadata}, + dkg::transactions::DKGTransactionData, jwks::{jwk::JWK, ProviderJWKs, QuorumCertifiedUpdate}, keyless, transaction::{ @@ -39,6 +40,7 @@ use once_cell::sync::Lazy; use poem_openapi::{Object, Union}; use poem_openapi_derive::Enum; use serde::{Deserialize, Serialize}; +use sha3::{digest::FixedOutput, Digest, Keccak256}; use std::{ boxed::Box, convert::{From, Into, TryFrom, TryInto}, @@ -65,6 +67,7 @@ static DUMMY_SEQUENCE_NUMBER: Lazy = Lazy::new(|| U64::from(0)); /// This is a combination enum of an onchain transaction and a pending transaction. /// When the transaction is still in mempool, it will be pending. If it's been committed to the /// chain, it will show up as OnChain. +#[allow(clippy::large_enum_variant)] #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum TransactionData { /// A committed transaction @@ -289,7 +292,7 @@ impl &SignedTransaction, TransactionInfo, TransactionPayload, - Vec, + Vec, u64, )> for Transaction { @@ -298,7 +301,7 @@ impl &SignedTransaction, TransactionInfo, TransactionPayload, - Vec, + Vec, u64, ), ) -> Self { @@ -316,7 +319,7 @@ impl &UserAutomatedTransaction, TransactionInfo, TransactionPayload, - Vec, + Vec, u64, )> for Transaction { @@ -325,7 +328,7 @@ impl &UserAutomatedTransaction, TransactionInfo, TransactionPayload, - Vec, + Vec, u64, ), ) -> Self { @@ -351,8 +354,8 @@ impl } } -impl From<(TransactionInfo, WriteSetPayload, Vec)> for Transaction { - fn from((info, payload, events): (TransactionInfo, WriteSetPayload, Vec)) -> Self { +impl From<(TransactionInfo, WriteSetPayload, Vec)> for Transaction { + fn from((info, payload, events): (TransactionInfo, WriteSetPayload, Vec)) -> Self { Transaction::GenesisTransaction(GenesisTransaction { info, payload: GenesisPayload::WriteSetPayload(payload), @@ -361,8 +364,8 @@ impl From<(TransactionInfo, WriteSetPayload, Vec)> for Transaction { } } -impl From<(&BlockMetadata, TransactionInfo, Vec)> for Transaction { - fn from((txn, info, events): (&BlockMetadata, TransactionInfo, Vec)) -> Self { +impl From<(&BlockMetadata, TransactionInfo, Vec)> for Transaction { + fn from((txn, info, events): (&BlockMetadata, TransactionInfo, Vec)) -> Self { Transaction::BlockMetadataTransaction(BlockMetadataTransaction { info, id: txn.id().into(), @@ -377,8 +380,8 @@ impl From<(&BlockMetadata, TransactionInfo, Vec)> for Transaction { } } -impl From<(&BlockMetadataExt, TransactionInfo, Vec)> for Transaction { - fn from((txn, info, events): (&BlockMetadataExt, TransactionInfo, Vec)) -> Self { +impl From<(&BlockMetadataExt, TransactionInfo, Vec)> for Transaction { + fn from((txn, info, events): (&BlockMetadataExt, TransactionInfo, Vec)) -> Self { Transaction::BlockMetadataTransaction(BlockMetadataTransaction { info, id: txn.id().into(), @@ -481,7 +484,7 @@ pub struct UserTransaction { #[oai(flatten)] pub request: UserTransactionRequest, /// Events generated by the transaction - pub events: Vec, + pub events: Vec, pub timestamp: U64, } @@ -495,7 +498,7 @@ pub struct AutomatedTransaction { #[oai(flatten)] pub meta: AutomatedTaskMeta, /// Events generated by the transaction - pub events: Vec, + pub events: Vec, pub timestamp: U64, } @@ -649,7 +652,7 @@ pub struct GenesisTransaction { pub info: TransactionInfo, pub payload: GenesisPayload, /// Events emitted during genesis - pub events: Vec, + pub events: Vec, } /// A block metadata transaction @@ -665,7 +668,7 @@ pub struct BlockMetadataTransaction { pub epoch: U64, pub round: U64, /// The events emitted at the block creation - pub events: Vec, + pub events: Vec, /// Previous block votes pub previous_block_votes_bitvec: Vec, pub proposer: Address, @@ -683,6 +686,7 @@ pub struct BlockMetadataTransaction { )] pub enum ValidatorTransaction { ObservedJwkUpdate(JWKUpdateTransaction), + Dkg(DKGTransaction), DkgResult(DKGResultTransaction), } @@ -693,6 +697,7 @@ impl ValidatorTransaction { "validator_transaction__observed_jwk_update" }, ValidatorTransaction::DkgResult(_) => "validator_transaction__dkg_result", + ValidatorTransaction::Dkg(_) => "validator_transaction__dkg", } } @@ -700,6 +705,7 @@ impl ValidatorTransaction { match self { ValidatorTransaction::ObservedJwkUpdate(t) => &t.info, ValidatorTransaction::DkgResult(t) => &t.info, + ValidatorTransaction::Dkg(t) => &t.info, } } @@ -707,6 +713,7 @@ impl ValidatorTransaction { match self { ValidatorTransaction::ObservedJwkUpdate(t) => &mut t.info, ValidatorTransaction::DkgResult(t) => &mut t.info, + ValidatorTransaction::Dkg(t) => &mut t.info, } } @@ -714,13 +721,15 @@ impl ValidatorTransaction { match self { ValidatorTransaction::ObservedJwkUpdate(t) => t.timestamp, ValidatorTransaction::DkgResult(t) => t.timestamp, + ValidatorTransaction::Dkg(t) => t.timestamp, } } - pub fn events(&self) -> &[Event] { + pub fn events(&self) -> &[EventV1] { match self { ValidatorTransaction::ObservedJwkUpdate(t) => &t.events, ValidatorTransaction::DkgResult(t) => &t.events, + ValidatorTransaction::Dkg(t) => &t.events, } } } @@ -729,7 +738,7 @@ impl From<( aptos_types::validator_txn::ValidatorTransaction, TransactionInfo, - Vec, + Vec, u64, )> for ValidatorTransaction { @@ -737,11 +746,19 @@ impl (txn, info, events, timestamp): ( aptos_types::validator_txn::ValidatorTransaction, TransactionInfo, - Vec, + Vec, u64, ), ) -> Self { match txn { + aptos_types::validator_txn::ValidatorTransaction::DKG(dkg_transaction_data) => { + Self::Dkg(DKGTransaction { + info, + events, + timestamp: U64::from(timestamp), + dkg_transaction_data: dkg_transaction_data.into(), + }) + }, aptos_types::validator_txn::ValidatorTransaction::DKGResult(dkg_transcript) => { Self::DkgResult(DKGResultTransaction { info, @@ -767,7 +784,7 @@ pub struct JWKUpdateTransaction { #[serde(flatten)] #[oai(flatten)] pub info: TransactionInfo, - pub events: Vec, + pub events: Vec, pub timestamp: U64, pub quorum_certified_update: ExportedQuorumCertifiedUpdate, } @@ -839,19 +856,19 @@ pub struct DKGResultTransaction { #[serde(flatten)] #[oai(flatten)] pub info: TransactionInfo, - pub events: Vec, + pub events: Vec, pub timestamp: U64, - pub dkg_transcript: ExportedDKGTranscript, + pub dkg_transcript: ExportedDKGResultTranscript, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] -pub struct ExportedDKGTranscript { +pub struct ExportedDKGResultTranscript { pub epoch: U64, pub author: Address, pub payload: HexEncodedBytes, } -impl From for ExportedDKGTranscript { +impl From for ExportedDKGResultTranscript { fn from(value: DKGTranscript) -> Self { let DKGTranscript { metadata, @@ -866,9 +883,115 @@ impl From for ExportedDKGTranscript { } } +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] +pub struct ExportedDKGTransactionData { + /// The epoch number for the dkg + pub epoch: U64, + /// The author of the dkg transaction + pub author: Address, + /// The bls multi signature of the clan committee certifying the payload of the transaction + pub bls_aggregate_signature: Vec, + /// indices of the clan committee nodes that signed the bls multisignature + pub signer_indices_clan_committee: Vec, + /// type of the dkg transaction: (DKGMeta = 0), (PublicKeyShares = 1) + pub transaction_type: u8, + /// raw serialized payload of the transaction + pub payload: HexEncodedBytes, +} + +impl From for ExportedDKGTransactionData { + fn from(value: DKGTransactionData) -> Self { + let epoch = *value.metadata().epoch(); + let author = *value.metadata().author(); + let bls_aggregate_signature = value.metadata().bls_aggregate_signature().clone(); + let signer_indices_clan_committee = + value.metadata().signer_indices_clan_committee().clone(); + let transaction_type = value.metadata().transaction_type().clone(); + let transcript_bytes = value.data_bytes().clone(); + + Self { + epoch: epoch.into(), + author: author.into(), + bls_aggregate_signature: bls_aggregate_signature.into(), + signer_indices_clan_committee: signer_indices_clan_committee.into(), + payload: HexEncodedBytes::from(transcript_bytes), + transaction_type: transaction_type as u8, + } + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] +pub struct DKGTransaction { + #[serde(flatten)] + #[oai(flatten)] + info: TransactionInfo, + events: Vec, + timestamp: U64, + pub dkg_transaction_data: ExportedDKGTransactionData, +} + /// An event from a transaction #[derive(Clone, Debug, Deserialize, Eq, Object, PartialEq, Serialize)] -pub struct Event { +pub struct EventV1 { + // The globally unique identifier of this event stream. + pub guid: EventGuid, + // The sequence number of the event + pub sequence_number: U64, + #[serde(rename = "type")] + #[oai(rename = "type")] + pub typ: MoveType, + /// The JSON representation of the event + pub data: serde_json::Value, + /// The hash of the event, derived from `keccak256`. + /// + /// TODO: Yes, you are correct—this is a hack that saves us from making a large number of changes + /// in the `rpc_node` just to support `EventV2`. Please do not take this hack lightly; take a + /// moment to think about the amount of work it actually saves. + /// + /// After a clear-cut refactor in `api-types` in `smr-moonshot`, we should be in a position to + /// remove this hacky solution. + #[serde(skip)] + #[oai(skip)] + pub hash: Option, +} + +impl From<(&ContractEvent, serde_json::Value)> for EventV1 { + fn from((event, data): (&ContractEvent, serde_json::Value)) -> Self { + let mut hasher = Keccak256::new(); + hasher.update(event.as_bytes_for_hash()); + let mut hash_bytes: [u8; 32] = [0u8; 32]; + hasher.finalize_into((&mut hash_bytes).into()); + let hash = Some(HashValue(aptos_crypto::HashValue::new(hash_bytes))); + + match event { + ContractEvent::V1(v1) => Self { + guid: (*v1.key()).into(), + sequence_number: v1.sequence_number().into(), + typ: v1.type_tag().clone().into(), + data, + hash, + }, + ContractEvent::V2(v2) => Self { + guid: *DUMMY_GUID, + sequence_number: *DUMMY_SEQUENCE_NUMBER, + typ: v2.type_tag().clone().into(), + data, + hash, + }, + } + } +} + +/// An event from a transaction with it's hash. +/// This type is a v2 of [EventV1] with the hash. +/// +/// The `hash` field is computed by: +/// 1. Encoding the `event` structure using `as_bytes_for_hash` method of [`ContractEvent`]. +/// 2. Hashing the resulting byte array using the `Keccak-256`. +// Note: For API types versioning, our team follows a full-clone approach over composition +// due to its flexibility. Therefore, a full clone is used here instead of composition. +#[derive(Clone, Debug, Deserialize, Eq, Object, PartialEq, Serialize)] +pub struct EventV2 { // The globally unique identifier of this event stream. pub guid: EventGuid, // The sequence number of the event @@ -878,27 +1001,57 @@ pub struct Event { pub typ: MoveType, /// The JSON representation of the event pub data: serde_json::Value, + /// The hash of the event, derived from `keccak256`. + pub hash: HashValue, } -impl From<(&ContractEvent, serde_json::Value)> for Event { +impl From<(&ContractEvent, serde_json::Value)> for EventV2 { fn from((event, data): (&ContractEvent, serde_json::Value)) -> Self { + let mut hasher = Keccak256::new(); + hasher.update(event.as_bytes_for_hash()); + let mut hash_bytes: [u8; 32] = [0u8; 32]; + hasher.finalize_into((&mut hash_bytes).into()); + let hash = HashValue(aptos_crypto::HashValue::new(hash_bytes)); + match event { ContractEvent::V1(v1) => Self { guid: (*v1.key()).into(), sequence_number: v1.sequence_number().into(), typ: v1.type_tag().clone().into(), data, + hash, }, ContractEvent::V2(v2) => Self { guid: *DUMMY_GUID, sequence_number: *DUMMY_SEQUENCE_NUMBER, typ: v2.type_tag().clone().into(), data, + hash, }, } } } +impl TryFrom for EventV2 { + type Error = AnyhowError; + fn try_from(event_v1: EventV1) -> Result { + let EventV1 { + guid, + sequence_number, + typ, + data, + hash, + } = event_v1; + Ok(Self { + guid, + sequence_number, + typ, + data, + hash: hash.ok_or(anyhow!("Event hash is missing in `EventV1`"))?, + }) + } +} + /// An event from a transaction with a version #[derive(Clone, Debug, Deserialize, Eq, Object, PartialEq, Serialize)] pub struct VersionedEvent { @@ -1090,6 +1243,7 @@ impl AutomationRegistrationParams { }; Some(params_v1) } + pub fn into_v2(self) -> Option { let AutomationRegistrationParams::V2(params_v2) = self else { return None; @@ -1209,7 +1363,7 @@ pub struct ScriptWriteSet { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Object)] pub struct DirectWriteSet { pub changes: Vec, - pub events: Vec, + pub events: Vec, } /// A final state change of a transaction on a resource or module @@ -2376,8 +2530,8 @@ impl FromStr for TransactionId { impl fmt::Display for TransactionId { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Self::Hash(h) => write!(f, "hash({})", h), - Self::Version(v) => write!(f, "version({})", v), + Self::Hash(h) => write!(f, "hash({h})"), + Self::Version(v) => write!(f, "version({v})"), } } } diff --git a/aptos-move/aptos-debugger/src/execute_pending_block.rs b/aptos-move/aptos-debugger/src/execute_pending_block.rs index 8611f2978dd..767caea0a96 100644 --- a/aptos-move/aptos-debugger/src/execute_pending_block.rs +++ b/aptos-move/aptos-debugger/src/execute_pending_block.rs @@ -73,13 +73,13 @@ impl Command { // "Getting block {:?} from {consensus_db_path:?}.", // self.block_id // ); - // let cmd = aptos_consensus::util::db_tool::Command { - // db_dir: consensus_db_path, - // block_id: self.block_id, - // }; - // cmd.dump_pending_txns()? + // let cmd = aptos_consensus::util::db_tool::Command { + // db_dir: consensus_db_path, + // block_id: self.block_id, + // }; + // cmd.dump_pending_txns()? // } - else { + else { unreachable!("Must provide one target."); }; diff --git a/aptos-move/aptos-e2e-comparison-testing/Cargo.toml b/aptos-move/aptos-e2e-comparison-testing/Cargo.toml index e28cf89d1a5..6f2738929ac 100644 --- a/aptos-move/aptos-e2e-comparison-testing/Cargo.toml +++ b/aptos-move/aptos-e2e-comparison-testing/Cargo.toml @@ -31,4 +31,3 @@ serde = { workspace = true } tempfile = { workspace = true } tokio = { workspace = true } url = { workspace = true } - diff --git a/aptos-move/aptos-gas-algebra/src/algebra.rs b/aptos-move/aptos-gas-algebra/src/algebra.rs index 2a317eb79ec..3a27496c0c4 100644 --- a/aptos-move/aptos-gas-algebra/src/algebra.rs +++ b/aptos-move/aptos-gas-algebra/src/algebra.rs @@ -20,7 +20,7 @@ pub type AbstractValueSizePerArg = GasQuantity>; pub enum GasUnit {} /// Unit of the Aptos network's native coin. -pub enum SUPRA {} +pub enum SUPRA {} /// Alternative unit of the Aptos network's native coin. 1 quant = 10^-8 Supra coins. pub enum Quant {} diff --git a/aptos-move/aptos-gas-profiling/src/erased.rs b/aptos-move/aptos-gas-profiling/src/erased.rs index 7fbf230d7f9..e32c810e2e7 100644 --- a/aptos-move/aptos-gas-profiling/src/erased.rs +++ b/aptos-move/aptos-gas-profiling/src/erased.rs @@ -296,7 +296,11 @@ impl StorageFees { TypeErasedStorageFees { total: self.total, - tree: Node::new_with_children("storage fees (SUPRA)", (Fee::zero(), Fee::zero()), nodes), + tree: Node::new_with_children( + "storage fees (SUPRA)", + (Fee::zero(), Fee::zero()), + nodes, + ), } } } diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs index 44e9352546c..80de653e89d 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs @@ -7,7 +7,9 @@ use crate::{ gas_feature_versions::{RELEASE_V1_14, RELEASE_V1_8, RELEASE_V1_9_SKIPPED}, gas_schedule::NativeGasParameters, - ver::gas_feature_versions::{RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_16_SUPRA_V1_6_0, RELEASE_V1_16_SUPRA_V1_7_14}, + ver::gas_feature_versions::{ + RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_16_SUPRA_V1_6_0, RELEASE_V1_16_SUPRA_V1_7_14, + }, }; use aptos_gas_algebra::{ InternalGas, InternalGasPerAbstractValueUnit, InternalGasPerArg, InternalGasPerByte, diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/mod.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/mod.rs index e38b7e0878e..d5a69f786b3 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/mod.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/mod.rs @@ -9,6 +9,7 @@ mod instr; mod macros; mod misc; mod move_stdlib; +mod supra_stdlib; mod table; mod transaction; @@ -16,6 +17,7 @@ pub use aptos_framework::AptosFrameworkGasParameters; pub use instr::InstructionGasParameters; pub use misc::{AbstractValueSizeGasParameters, MiscGasParameters}; pub use move_stdlib::MoveStdlibGasParameters; +pub use supra_stdlib::SupraStdlibGasParameters; pub use table::TableGasParameters; pub use transaction::TransactionGasParameters; @@ -29,6 +31,7 @@ pub mod gas_params { use super::*; pub use aptos_framework::gas_params as aptos_framework; pub use move_stdlib::gas_params as move_stdlib; + pub use supra_stdlib::gas_params as supra_stdlib; pub use table::gas_params as table; } } @@ -140,6 +143,7 @@ impl InitialGasSchedule for VMGasParameters { #[derive(Debug, Clone)] pub struct NativeGasParameters { pub move_stdlib: MoveStdlibGasParameters, + pub supra_stdlib: SupraStdlibGasParameters, pub table: TableGasParameters, pub aptos_framework: AptosFrameworkGasParameters, } @@ -154,6 +158,10 @@ impl FromOnChainGasSchedule for NativeGasParameters { gas_schedule, feature_version, )?, + supra_stdlib: FromOnChainGasSchedule::from_on_chain_gas_schedule( + gas_schedule, + feature_version, + )?, table: FromOnChainGasSchedule::from_on_chain_gas_schedule( gas_schedule, feature_version, @@ -170,6 +178,7 @@ impl ToOnChainGasSchedule for NativeGasParameters { fn to_on_chain_gas_schedule(&self, feature_version: u64) -> Vec<(String, u64)> { let mut entries = self.move_stdlib.to_on_chain_gas_schedule(feature_version); entries.extend(self.table.to_on_chain_gas_schedule(feature_version)); + entries.extend(self.supra_stdlib.to_on_chain_gas_schedule(feature_version)); entries.extend( self.aptos_framework .to_on_chain_gas_schedule(feature_version), @@ -182,6 +191,7 @@ impl NativeGasParameters { pub fn zeros() -> Self { Self { move_stdlib: MoveStdlibGasParameters::zeros(), + supra_stdlib: SupraStdlibGasParameters::zeros(), table: TableGasParameters::zeros(), aptos_framework: AptosFrameworkGasParameters::zeros(), } @@ -192,6 +202,7 @@ impl InitialGasSchedule for NativeGasParameters { fn initial() -> Self { Self { move_stdlib: InitialGasSchedule::initial(), + supra_stdlib: InitialGasSchedule::initial(), table: InitialGasSchedule::initial(), aptos_framework: InitialGasSchedule::initial(), } diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/supra_stdlib.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/supra_stdlib.rs new file mode 100644 index 00000000000..2c1423e801d --- /dev/null +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/supra_stdlib.rs @@ -0,0 +1,21 @@ +// Copyright (c) 2025 Supra. + +//! This module defines the gas parameters for Supra Stdlib. + +use crate::{ + gas_schedule::NativeGasParameters, ver::gas_feature_versions::RELEASE_V1_16_SUPRA_V1_8_0, +}; +use aptos_gas_algebra::{InternalGas, InternalGasPerArg}; + +crate::gas_schedule::macros::define_gas_parameters!( + SupraStdlibGasParameters, + "supra_stdlib", + NativeGasParameters => .supra_stdlib, + [ + // Note(Gas): this initial value is guesswork. + [class_groups_per_pubkey_deserialize: InternalGasPerArg, { RELEASE_V1_16_SUPRA_V1_8_0.. => "class.groups.per_pubkey_deserialize" }, 400684], + // Note(Gas): this initial value is guesswork. + [class_groups_pop: InternalGas, { RELEASE_V1_16_SUPRA_V1_8_0.. => "class.groups.pop" }, 206000000], + + ] +); diff --git a/aptos-move/aptos-gas-schedule/src/ver.rs b/aptos-move/aptos-gas-schedule/src/ver.rs index b1c44ddeca2..0aad7bc6e02 100644 --- a/aptos-move/aptos-gas-schedule/src/ver.rs +++ b/aptos-move/aptos-gas-schedule/src/ver.rs @@ -73,7 +73,7 @@ /// global operations. /// - V1 /// - TBA -pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_16_SUPRA_V1_7_14; +pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_16_SUPRA_V1_8_0; pub mod gas_feature_versions { pub const RELEASE_V1_8: u64 = 11; @@ -89,4 +89,5 @@ pub mod gas_feature_versions { pub const RELEASE_V1_16_SUPRA_V1_5_1: u64 = 22; pub const RELEASE_V1_16_SUPRA_V1_6_0: u64 = 23; pub const RELEASE_V1_16_SUPRA_V1_7_14: u64 = 24; + pub const RELEASE_V1_16_SUPRA_V1_8_0: u64 = 25; } diff --git a/aptos-move/aptos-release-builder/Cargo.toml b/aptos-move/aptos-release-builder/Cargo.toml index a42cff88383..a3a361bcf34 100644 --- a/aptos-move/aptos-release-builder/Cargo.toml +++ b/aptos-move/aptos-release-builder/Cargo.toml @@ -14,7 +14,7 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } -aptos = { workspace = true, features = [ "no-upload-proposal" ] } +aptos = { workspace = true, features = ["no-upload-proposal"] } aptos-api-types = { workspace = true } aptos-build-info = { workspace = true } aptos-crypto = { workspace = true } diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs index 8cfc9b1a410..5592ff1fe93 100644 --- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs +++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs @@ -130,6 +130,10 @@ pub enum FeatureFlag { SupraRLPEncode, SupraDelegationPoolIdentity, SupraAutomationV2, + SupraBlsKeys, + SupraBcftCertificates, + SUPRA_DKG, + SupraTransactionInclusionProofs, } fn generate_features_blob(writer: &CodeWriter, data: &[u64]) { @@ -340,6 +344,12 @@ impl From for AptosFeatureFlag { AptosFeatureFlag::SUPRA_DELEGATION_POOL_IDENTITY }, FeatureFlag::SupraAutomationV2 => AptosFeatureFlag::SUPRA_AUTOMATION_V2, + FeatureFlag::SupraBlsKeys => AptosFeatureFlag::SUPRA_BLS_KEYS, + FeatureFlag::SupraBcftCertificates => AptosFeatureFlag::SUPRA_BCFT_CERTIFICATES, + FeatureFlag::SUPRA_DKG => AptosFeatureFlag::SUPRA_DKG, + FeatureFlag::SupraTransactionInclusionProofs => { + AptosFeatureFlag::SUPRA_TRANSACTIONS_INCLUSION_PROOFS + }, } } } @@ -479,6 +489,12 @@ impl From for FeatureFlag { FeatureFlag::SupraDelegationPoolIdentity }, AptosFeatureFlag::SUPRA_AUTOMATION_V2 => FeatureFlag::SupraAutomationV2, + AptosFeatureFlag::SUPRA_BLS_KEYS => FeatureFlag::SupraBlsKeys, + AptosFeatureFlag::SUPRA_BCFT_CERTIFICATES => FeatureFlag::SupraBcftCertificates, + AptosFeatureFlag::SUPRA_DKG => FeatureFlag::SUPRA_DKG, + AptosFeatureFlag::SUPRA_TRANSACTIONS_INCLUSION_PROOFS => { + FeatureFlag::SupraTransactionInclusionProofs + }, } } } diff --git a/aptos-move/aptos-release-builder/src/components/framework.rs b/aptos-move/aptos-release-builder/src/components/framework.rs index d95c585d8e4..34633d0aba0 100644 --- a/aptos-move/aptos-release-builder/src/components/framework.rs +++ b/aptos-move/aptos-release-builder/src/components/framework.rs @@ -104,10 +104,18 @@ pub fn generate_upgrade_proposals( // If we're generating a single-step proposal on testnet if is_testnet && next_execution_hash.is_empty() { - release.generate_script_proposal_testnet(account, move_script_path.clone())?; + release.generate_script_proposal_testnet( + account, + move_script_path.clone(), + todo!("function_name"), + )?; // If we're generating a single-step proposal on mainnet } else if next_execution_hash.is_empty() { - release.generate_script_proposal(account, move_script_path.clone())?; + release.generate_script_proposal( + account, + move_script_path.clone(), + todo!("function_name"), + )?; // If we're generating a multi-step proposal } else { let next_execution_hash_bytes = if result.is_empty() { @@ -119,6 +127,7 @@ pub fn generate_upgrade_proposals( account, move_script_path.clone(), next_execution_hash_bytes, + todo!("function_name"), )?; }; diff --git a/aptos-move/aptos-release-builder/src/components/mod.rs b/aptos-move/aptos-release-builder/src/components/mod.rs index 378404cbb62..f7eb27c7163 100644 --- a/aptos-move/aptos-release-builder/src/components/mod.rs +++ b/aptos-move/aptos-release-builder/src/components/mod.rs @@ -3,11 +3,12 @@ use self::framework::FrameworkReleaseConfig; use crate::{ - aptos_core_path, supra_framework_path, + aptos_core_path, components::{ feature_flags::Features, oidc_providers::OidcProviderOp, randomness_config::ReleaseFriendlyRandomnessConfig, }, + supra_framework_path, }; use anyhow::{anyhow, bail, Context, Result}; use aptos::governance::GenerateExecutionHash; diff --git a/aptos-move/aptos-release-builder/src/validate.rs b/aptos-move/aptos-release-builder/src/validate.rs index 6ef044e123e..a3a51dcd8d3 100644 --- a/aptos-move/aptos-release-builder/src/validate.rs +++ b/aptos-move/aptos-release-builder/src/validate.rs @@ -1,7 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{supra_framework_path, components::ProposalMetadata, ExecutionMode, ReleaseConfig}; +use crate::{components::ProposalMetadata, supra_framework_path, ExecutionMode, ReleaseConfig}; use anyhow::Result; use aptos::{ common::types::CliCommand, diff --git a/aptos-move/aptos-transaction-benchmarks/Cargo.toml b/aptos-move/aptos-transaction-benchmarks/Cargo.toml index 4bb90c07a41..546fce69899 100644 --- a/aptos-move/aptos-transaction-benchmarks/Cargo.toml +++ b/aptos-move/aptos-transaction-benchmarks/Cargo.toml @@ -21,7 +21,7 @@ aptos-language-e2e-tests = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-node-resource-metrics = { workspace = true } -aptos-push-metrics = { workspace = true } +aptos-push-metrics = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } aptos-vm-logging = { workspace = true } diff --git a/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs b/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs index 70f66aa5fd4..0e48566b3e7 100644 --- a/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs +++ b/aptos-move/aptos-transactional-test-harness/src/aptos_test_harness.rs @@ -556,7 +556,7 @@ impl<'a> AptosTestAdapter<'a> { let txn = RawTransaction::new( aptos_test_root_address(), parameters.sequence_number, - aptos_cached_packages::aptos_stdlib::aptos_account_create_account(account_addr), + aptos_cached_packages::aptos_stdlib::supra_account_create_account(account_addr), parameters.max_gas_amount, parameters.gas_unit_price, parameters.expiration_timestamp_secs, diff --git a/aptos-move/aptos-validator-interface/src/rest_interface.rs b/aptos-move/aptos-validator-interface/src/rest_interface.rs index 87697d7f2a1..e8c7cebf383 100644 --- a/aptos-move/aptos-validator-interface/src/rest_interface.rs +++ b/aptos-move/aptos-validator-interface/src/rest_interface.rs @@ -284,11 +284,12 @@ impl AptosValidatorInterface for RestDebuggerInterface { TransactionPayload::Multisig(multi_sig) if multi_sig.transaction_payload.is_some() => { - match multi_sig.transaction_payload.clone().unwrap() { - aptos_types::transaction::MultisigTransactionPayload::EntryFunction(e) => - Some(e.clone()), - _ => None, - } + match multi_sig.transaction_payload.clone().unwrap() { + aptos_types::transaction::MultisigTransactionPayload::EntryFunction(e) => { + Some(e.clone()) + }, + _ => None, + } }, TransactionPayload::EntryFunction(e) => Some(e.clone()), _ => None, diff --git a/aptos-move/aptos-vm-benchmarks/samples/do-nothing/Move.toml b/aptos-move/aptos-vm-benchmarks/samples/do-nothing/Move.toml index aedf01f521f..f2d30f35457 100644 --- a/aptos-move/aptos-vm-benchmarks/samples/do-nothing/Move.toml +++ b/aptos-move/aptos-vm-benchmarks/samples/do-nothing/Move.toml @@ -3,4 +3,4 @@ name = 'do-nothing' version = '1.0.0' [dependencies] AptosFramework = { local = "../../../framework/aptos-framework" } -AptosStdlib = { local = "../../../framework/aptos-stdlib" } \ No newline at end of file +AptosStdlib = { local = "../../../framework/aptos-stdlib" } diff --git a/aptos-move/aptos-vm-profiling/Cargo.toml b/aptos-move/aptos-vm-profiling/Cargo.toml index 68bfadfcd39..fd466f43897 100644 --- a/aptos-move/aptos-vm-profiling/Cargo.toml +++ b/aptos-move/aptos-vm-profiling/Cargo.toml @@ -35,7 +35,7 @@ move-vm-types = { workspace = true } [[bin]] name = "main" -path = "src/main.rs" +path = "src/main.rs" [[bin]] name = "run-move" diff --git a/aptos-move/aptos-vm/Cargo.toml b/aptos-move/aptos-vm/Cargo.toml index c2755c55302..16ffdb366ae 100644 --- a/aptos-move/aptos-vm/Cargo.toml +++ b/aptos-move/aptos-vm/Cargo.toml @@ -20,7 +20,7 @@ aptos-block-partitioner = { workspace = true } aptos-crypto = { workspace = true } aptos-crypto-derive = { workspace = true } aptos-experimental-runtimes = { workspace = true } -aptos-framework = { workspace = true } +aptos-framework = { workspace = true } aptos-gas-algebra = { workspace = true } aptos-gas-meter = { workspace = true } aptos-gas-schedule = { workspace = true } @@ -42,6 +42,7 @@ bcs = { workspace = true } bytes = { workspace = true } claims = { workspace = true } crossbeam-channel = { workspace = true } +crypto = { workspace = true } derive_more = { workspace = true } fail = { workspace = true } futures = { workspace = true } @@ -68,6 +69,12 @@ rand_core = { workspace = true } [features] default = [] -fuzzing = ["move-core-types/fuzzing", "move-binary-format/fuzzing", "move-vm-types/fuzzing", "aptos-framework/fuzzing", "aptos-types/fuzzing"] +fuzzing = [ + "move-core-types/fuzzing", + "move-binary-format/fuzzing", + "move-vm-types/fuzzing", + "aptos-framework/fuzzing", + "aptos-types/fuzzing", +] failpoints = ["fail/failpoints", "move-vm-runtime/failpoints"] testing = ["move-unit-test", "aptos-framework/testing"] diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs index b861c82d6e9..ab4ceeb0c14 100644 --- a/aptos-move/aptos-vm/src/aptos_vm.rs +++ b/aptos-move/aptos-vm/src/aptos_vm.rs @@ -3,8 +3,8 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::automated_transaction_processor::AutomatedTransactionProcessor; use crate::{ + automated_transaction_processor::AutomatedTransactionProcessor, block_executor::{AptosTransactionOutput, BlockAptosVM}, counters::*, data_cache::{AsMoveResolver, StorageAdapter}, @@ -27,7 +27,10 @@ use crate::{ }; use anyhow::anyhow; use aptos_block_executor::txn_commit_hook::NoOpTransactionCommitHook; -use aptos_crypto::HashValue; +use aptos_crypto::{ + bls12381::{PublicKey, Signature}, + HashValue, +}; use aptos_framework::{ natives::{code::PublishRequest, randomness::RandomnessContext}, RuntimeModuleMetadataV1, @@ -39,7 +42,6 @@ use aptos_logger::{enabled, prelude::*, Level}; use aptos_metrics_core::TimerHelper; #[cfg(any(test, feature = "testing"))] use aptos_types::state_store::StateViewId; -use aptos_types::transaction::automation::{AutomationTaskType, RegistrationParams}; use aptos_types::{ account_config::{self, new_block_event_key, AccountResource}, block_executor::{ @@ -49,16 +51,22 @@ use aptos_types::{ block_metadata::BlockMetadata, block_metadata_ext::{BlockMetadataExt, BlockMetadataWithRandomness}, chain_id::ChainId, + dkg::{ + state::DKGState, + transactions::{DKGTransactionData, DKGTransactionType}, + }, fee_statement::FeeStatement, move_utils::as_move_value::AsMoveValue, on_chain_config::{ - new_epoch_event_key, ApprovedExecutionHashes, ConfigStorage, FeatureFlag, Features, - OnChainConfig, TimedFeatureFlag, TimedFeatures, + new_epoch_event_key, ApprovedExecutionHashes, ConfigStorage, ConfigurationResource, + FeatureFlag, Features, OnChainConfig, TimedFeatureFlag, TimedFeatures, }, randomness::Randomness, state_store::{StateView, TStateView}, transaction::{ - authenticator::AnySignature, signature_verified_transaction::SignatureVerifiedTransaction, + authenticator::AnySignature, + automation::{AutomationTaskType, RegistrationParams}, + signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, EntryFunction, ExecutionError, ExecutionStatus, ModuleBundle, Multisig, MultisigTransactionPayload, Script, SignedTransaction, Transaction, TransactionAuxiliaryData, TransactionOutput, TransactionPayload, TransactionStatus, @@ -152,8 +160,10 @@ macro_rules! unwrap_or_discard { }; } -use crate::automation_registry_transaction_processor::AutomationRegistryTransactionProcessor; -use crate::gas::check_automation_task_gas; +use crate::{ + automation_registry_transaction_processor::AutomationRegistryTransactionProcessor, + gas::check_automation_task_gas, +}; pub(crate) use unwrap_or_discard; pub(crate) fn get_system_transaction_output( @@ -1013,8 +1023,11 @@ impl AptosVM { [(module_id.address(), module_id.name())], )?; } - let args = registration_params - .serialized_args_with_sender_and_parent_hash(sender, txn_metadata.txn_app_hash.clone(), self.features()); + let args = registration_params.serialized_args_with_sender_and_parent_hash( + sender, + txn_metadata.txn_app_hash.clone(), + self.features(), + ); session.execute_function_bypass_visibility( registration_params.module_id(), @@ -2345,11 +2358,21 @@ impl AptosVM { randomness .as_ref() .map(Randomness::randomness_cloned) + .unwrap_or_default() .as_move_value(), ]; let storage = TraversalStorage::new(); + // During the first epoch in which the feature is activated, threshold keys have not yet been established (they + // are produced at the end of that epoch via DKG), so randomness remains biasable for that epoch. + if self.features().is_enabled(FeatureFlag::SUPRA_DKG){ + session + .get_native_extensions() + .get_mut::() + .mark_unbiasable(); + } + session .execute_function_bypass_visibility( &BLOCK_MODULE, @@ -2693,14 +2716,14 @@ impl AptosVM { self.process_validator_transaction(resolver, txn.clone(), log_context)?; (vm_status, output) }, - Transaction::AutomatedTransaction(txn) => AutomatedTransactionProcessor::new( - self, AutomationTaskType::User, - ) - .execute_transaction(resolver, txn, log_context), - Transaction::SystemAutomatedTransaction(txn) => AutomatedTransactionProcessor::new( - self, AutomationTaskType::System, - ) - .execute_transaction(resolver, txn, log_context), + Transaction::AutomatedTransaction(txn) => { + AutomatedTransactionProcessor::new(self, AutomationTaskType::User) + .execute_transaction(resolver, txn, log_context) + }, + Transaction::SystemAutomatedTransaction(txn) => { + AutomatedTransactionProcessor::new(self, AutomationTaskType::System) + .execute_transaction(resolver, txn, log_context) + }, Transaction::AutomationRegistryTransaction(txn) => { AutomationRegistryTransactionProcessor::new(self).execute_transaction( resolver, @@ -2724,10 +2747,7 @@ impl AptosVM { } fn check_multisig_task_registration_support(&self) -> Result<(), VMStatus> { - if !self - .features() - .is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2) - { + if !self.features().is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2) { return Err(VMStatus::Error { status_code: StatusCode::FEATURE_UNDER_GATING, sub_status: None, @@ -2907,6 +2927,111 @@ impl VMValidator for AptosVM { result } + + fn validate_dkg_validator_transaction( + &self, + dkg_transaction: DKGTransactionData, + resolver: &impl AptosMoveResolver, + ) -> VMValidatorResult { + if !self.features().is_enabled(FeatureFlag::SUPRA_DKG) { + return VMValidatorResult::error(StatusCode::FEATURE_UNDER_GATING); + } + + let dkg_state = match OnChainConfig::fetch_config(resolver) { + Some(state) => state, + None => return VMValidatorResult::error(StatusCode::RESOURCE_DOES_NOT_EXIST), + }; + + let config_resource = match ConfigurationResource::fetch_config(resolver) { + Some(cfg) => cfg, + None => return VMValidatorResult::error(StatusCode::RESOURCE_DOES_NOT_EXIST), + }; + + let DKGState { in_progress, .. } = dkg_state; + let in_progress_session_state = match in_progress { + Some(session) => session, + None => return VMValidatorResult::error(StatusCode::DKG_SESSION_NOT_IN_PROGRESS), + }; + + // Check epoch number. + if *dkg_transaction.metadata().epoch() > config_resource.epoch() { + return VMValidatorResult::error(StatusCode::DKG_TRANSACTION_FUTURE_EPOCH_NUM); + } + if *dkg_transaction.metadata().epoch() < config_resource.epoch() { + return VMValidatorResult::error(StatusCode::DKG_TRANSACTION_PAST_EPOCH_NUM); + } + + match dkg_transaction.metadata().transaction_type() { + DKGTransactionType::DKGMeta => { + // dkg meta should not be already set + if in_progress_session_state.dkg_meta_transcript.len() != 0 { + return VMValidatorResult::error(StatusCode::DKG_META_ALREADY_SET); + } + }, + DKGTransactionType::PublicKeyShares => { + // for public shares trasaction, dkg meta should be already set + // but it is possible due to network asynchrony, that public shares transaction is processed before dkg meta transaction + // in which case, dkg meta is not set yet + // so we cannot impose this condition + }, + } + + let dealer_committee = &in_progress_session_state.metadata.dealer_committee; + let randomness_seed = &in_progress_session_state.metadata.randomness_seed; + + if dkg_transaction.data_bytes().is_empty() + || dkg_transaction + .metadata() + .bls_aggregate_signature() + .is_empty() + || dkg_transaction + .metadata() + .signer_indices_clan_committee() + .is_empty() + { + return VMValidatorResult::error(StatusCode::DKG_TRANSACTION_NOT_VALID); + } + + // verify clan committee multi-signature on the transaction data + let signer_bls_pubkeys = match aptos_types::dkg::get_clan_nodes_bls_keys_from_indices( + dealer_committee, + &dkg_transaction.metadata().signer_indices_clan_committee(), + randomness_seed, + ) { + Ok(bls_keys) => bls_keys, + Err(_) => { + return VMValidatorResult::error(StatusCode::DKG_FAILED_TO_GET_CLAN_NODE_PUBKEYS); + }, + }; + + let agg_sig = match Signature::try_from( + dkg_transaction + .metadata() + .bls_aggregate_signature() + .as_slice(), + ) { + Ok(sig) => sig, + Err(_) => { + return VMValidatorResult::error(StatusCode::DKG_FAILED_TO_DESER_AGG_SIG); + }, + }; + + let agg_pk = match PublicKey::aggregate(signer_bls_pubkeys.iter().collect()) { + Ok(pk) => pk, + Err(_) => { + return VMValidatorResult::error(StatusCode::DKG_FAILED_TO_AGGREGATE_PUBLIC_KEYS); + }, + }; + + if agg_sig + .verify_aggregate_arbitrary_msg(&[dkg_transaction.data_bytes().as_slice()], &[&agg_pk]) + .is_err() + { + return VMValidatorResult::error(StatusCode::DKG_AGG_SIG_VERIFICATION_FAILED); + } + + VMValidatorResult::new(None, 0) + } } // Ensure encapsulation of AptosVM APIs by using a wrapper. @@ -2942,7 +3067,6 @@ impl AptosSimulationVM { .expect("Materializing aggregator V1 deltas should never fail"); (vm_status, txn_output) } - } fn create_account_if_does_not_exist( diff --git a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs index ca71dcc958e..a5ce78285ef 100644 --- a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs +++ b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs @@ -1,12 +1,19 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 -use crate::aptos_vm::get_or_vm_startup_failure; -use crate::gas::{make_prod_gas_meter, ProdGasMeter}; -use crate::move_vm_ext::SessionId::Void; -use crate::AptosVM; -use aptos_types::state_store::StateView; -use aptos_types::transaction::{ViewFunction, ViewFunctionOutput}; +use crate::{ + aptos_vm::get_or_vm_startup_failure, + gas::{make_prod_gas_meter, ProdGasMeter}, + move_vm_ext::SessionId::Void, + AptosVM, +}; +use aptos_types::{ + state_store::StateView, + transaction::{ViewFunction, ViewFunctionOutput}, +}; use aptos_vm_logging::log_schema::AdapterLogSchema; /// Move VM with only view function API. diff --git a/aptos-move/aptos-vm/src/automated_transaction_processor.rs b/aptos-move/aptos-vm/src/automated_transaction_processor.rs index 91a3ce4f2da..84d3eb76430 100644 --- a/aptos-move/aptos-vm/src/automated_transaction_processor.rs +++ b/aptos-move/aptos-vm/src/automated_transaction_processor.rs @@ -1,31 +1,40 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 -use crate::aptos_vm::{get_or_vm_startup_failure, unwrap_or_discard}; -use crate::counters::TXN_GAS_USAGE; -use crate::errors::discarded_output; -use crate::gas::{check_gas, make_prod_gas_meter}; -use crate::move_vm_ext::session::user_transaction_sessions::epilogue::EpilogueSession; -use crate::move_vm_ext::session::user_transaction_sessions::prologue::PrologueSession; -use crate::move_vm_ext::session::user_transaction_sessions::user::UserSession; -use crate::move_vm_ext::{AptosMoveResolver, SessionExt}; -use crate::transaction_metadata::TransactionMetadata; -use crate::{transaction_validation, AptosVM}; +use crate::{ + aptos_vm::{get_or_vm_startup_failure, unwrap_or_discard}, + counters::TXN_GAS_USAGE, + errors::discarded_output, + gas::{check_gas, make_prod_gas_meter}, + move_vm_ext::{ + session::user_transaction_sessions::{ + epilogue::EpilogueSession, prologue::PrologueSession, user::UserSession, + }, + AptosMoveResolver, SessionExt, + }, + transaction_metadata::TransactionMetadata, + transaction_validation, AptosVM, +}; use aptos_gas_algebra::Gas; use aptos_gas_meter::{AptosGasMeter, GasAlgebra}; use aptos_gas_schedule::VMGasParameters; -use aptos_types::fee_statement::FeeStatement; -use aptos_types::on_chain_config::FeatureFlag; -use aptos_types::transaction::automated_transaction::AutomatedTransaction; -use aptos_types::transaction::automation::AutomationTaskType; -use aptos_types::transaction::{ - EntryFunction, ExecutionStatus, TransactionAuxiliaryData, TransactionPayload, TransactionStatus, +use aptos_types::{ + fee_statement::FeeStatement, + on_chain_config::FeatureFlag, + transaction::{ + automated_transaction::AutomatedTransaction, automation::AutomationTaskType, EntryFunction, + ExecutionStatus, TransactionAuxiliaryData, TransactionPayload, TransactionStatus, + }, }; use aptos_vm_logging::log_schema::AdapterLogSchema; -use aptos_vm_types::change_set::VMChangeSet; -use aptos_vm_types::output::VMOutput; -use aptos_vm_types::storage::change_set_configs::ChangeSetConfigs; -use aptos_vm_types::storage::StorageGasParameters; +use aptos_vm_types::{ + change_set::VMChangeSet, + output::VMOutput, + storage::{change_set_configs::ChangeSetConfigs, StorageGasParameters}, +}; use fail::fail_point; use move_binary_format::errors::Location; use move_core_types::vm_status::{StatusCode, VMStatus}; @@ -75,10 +84,7 @@ impl<'m> AutomatedTransactionProcessor<'m> { log_context, )?; - if self - .features() - .is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2) - { + if self.features().is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2) { transaction_validation::run_automated_transaction_prologue_v2( session, transaction_data, @@ -245,6 +251,7 @@ impl<'m> AutomatedTransactionProcessor<'m> { traversal_context, ) } + pub(crate) fn execute_transaction_impl<'a>( &self, resolver: &impl AptosMoveResolver, @@ -506,12 +513,8 @@ impl<'m> AutomatedTransactionProcessor<'m> { /// This function is utilized to define fee-statement of VMOutput. fn get_fee_statement_for_output(&self, fee_statement: FeeStatement) -> FeeStatement { match self.task_type { - AutomationTaskType::User => { - fee_statement - } - AutomationTaskType::System => { - FeeStatement::zero() - } + AutomationTaskType::User => fee_statement, + AutomationTaskType::System => FeeStatement::zero(), } } } diff --git a/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs b/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs index 60dd1f27510..71125163f6d 100644 --- a/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs +++ b/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs @@ -1,24 +1,29 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2025 Supra. // SPDX-License-Identifier: Apache-2.0 -use crate::aptos_vm::{get_or_vm_startup_failure, get_system_transaction_output}; -use crate::counters::SYSTEM_TRANSACTIONS_EXECUTED; -use crate::errors::discarded_output; -use crate::move_vm_ext::{AptosMoveResolver, SessionExt, SessionId}; -use crate::AptosVM; -use aptos_types::account_config; -use aptos_types::fee_statement::FeeStatement; -use aptos_types::on_chain_config::FeatureFlag; -use aptos_types::transaction::automation::AutomationRegistryRecord; -use aptos_types::transaction::{ExecutionStatus, TransactionStatus}; +use crate::{ + aptos_vm::{get_or_vm_startup_failure, get_system_transaction_output}, + counters::SYSTEM_TRANSACTIONS_EXECUTED, + errors::discarded_output, + gas::make_prod_gas_meter, + move_vm_ext::{AptosMoveResolver, SessionExt, SessionId}, + AptosVM, +}; +use aptos_types::{ + account_config, + fee_statement::FeeStatement, + on_chain_config::FeatureFlag, + transaction::{automation::AutomationRegistryRecord, ExecutionStatus, TransactionStatus}, +}; use aptos_vm_logging::log_schema::AdapterLogSchema; -use aptos_vm_types::output::VMOutput; -use aptos_vm_types::storage::change_set_configs::ChangeSetConfigs; +use aptos_vm_types::{output::VMOutput, storage::change_set_configs::ChangeSetConfigs}; use move_binary_format::errors::VMError; use move_core_types::vm_status::{StatusCode, VMStatus}; use move_vm_runtime::module_traversal::{TraversalContext, TraversalStorage}; use std::ops::Deref; -use crate::gas::make_prod_gas_meter; pub struct AutomationRegistryTransactionProcessor<'m> { aptos_vm: &'m AptosVM, @@ -57,10 +62,9 @@ impl<'m> AutomationRegistryTransactionProcessor<'m> { discarded_output(StatusCode::FEATURE_UNDER_GATING), )); } - let gas_params = - get_or_vm_startup_failure(&self.gas_params_internal(), log_context)? - .vm - .clone(); + let gas_params = get_or_vm_startup_failure(&self.gas_params_internal(), log_context)? + .vm + .clone(); let max_gas_amount = gas_params.txn.maximum_number_of_gas_units; let mut gas_meter = make_prod_gas_meter( self.gas_feature_version(), diff --git a/aptos-move/aptos-vm/src/gas.rs b/aptos-move/aptos-vm/src/gas.rs index d3ea7abc255..045a0830e45 100644 --- a/aptos-move/aptos-vm/src/gas.rs +++ b/aptos-move/aptos-vm/src/gas.rs @@ -11,18 +11,20 @@ use aptos_gas_schedule::{ }; use aptos_logger::{enabled, Level}; use aptos_memory_usage_tracker::MemoryTrackedGasMeter; -use aptos_types::on_chain_config::{ConfigStorage, FeatureFlag, Features, GasSchedule, GasScheduleV2, OnChainConfig}; -use aptos_types::transaction::{RawTransaction, TransactionPayload}; -use aptos_types::transaction::automation::RegistrationParams; +use aptos_types::{ + on_chain_config::{ + ConfigStorage, FeatureFlag, Features, GasSchedule, GasScheduleV2, OnChainConfig, + }, + transaction::{automation::RegistrationParams, RawTransaction, TransactionPayload}, +}; use aptos_vm_logging::{log_schema::AdapterLogSchema, speculative_log, speculative_warn}; use aptos_vm_types::storage::{ io_pricing::IoPricing, space_pricing::DiskSpacePricing, StorageGasParameters, }; use move_core_types::{ - gas_algebra::NumArgs, + gas_algebra::{NumArgs, NumBytes}, vm_status::{StatusCode, VMStatus}, }; -use move_core_types::gas_algebra::NumBytes; /// This is used until gas version 18, which introduces a configurable entry for this. const MAXIMUM_APPROVED_TRANSACTION_SIZE_LEGACY: u64 = 1024 * 1024; @@ -123,7 +125,7 @@ pub fn make_prod_gas_meter( } /// Invariants facilitating gas checks of the transactions. -pub (crate) struct TransactionGasCheckInvariants { +pub(crate) struct TransactionGasCheckInvariants { pub(crate) gas_unit_price: FeePerGasUnit, pub(crate) max_gas_amount: Gas, pub(crate) transaction_size: NumBytes, @@ -147,9 +149,21 @@ pub(crate) fn check_gas( transaction_size: txn_metadata.transaction_size, script_size: txn_metadata.script_size, is_keyless: txn_metadata.is_keyless(), - is_account_init_for_sponsored_transaction: crate::aptos_vm::is_account_init_for_sponsored_transaction(txn_metadata, features, resolver)?, + is_account_init_for_sponsored_transaction: + crate::aptos_vm::is_account_init_for_sponsored_transaction( + txn_metadata, + features, + resolver, + )?, }; - check_gas_for_parameters(gas_params, gas_feature_version, features, txn_gas_metadata, is_approved_gov_script, log_context) + check_gas_for_parameters( + gas_params, + gas_feature_version, + features, + txn_gas_metadata, + is_approved_gov_script, + log_context, + ) } /// Checks gas parameters and maps the gas related error status code to Automation invariants. @@ -165,11 +179,11 @@ pub(crate) fn check_automation_task_gas( log_context: &AdapterLogSchema, ) -> Result<(), VMStatus> { if !features.is_enabled(FeatureFlag::SUPRA_AUTOMATION_PAYLOAD_GAS_CHECK) { - return Ok(()) + return Ok(()); } - let size_in_bytes = RawTransaction::estimate_size_in_bytes( - TransactionPayload::EntryFunction(registration_params.automated_function().clone()), - ); + let size_in_bytes = RawTransaction::estimate_size_in_bytes(TransactionPayload::EntryFunction( + registration_params.automated_function().clone(), + )); let gas_check_invariants = TransactionGasCheckInvariants { gas_unit_price: registration_params.gas_price_cap().into(), max_gas_amount: registration_params.max_gas_amount().into(), @@ -189,33 +203,35 @@ pub(crate) fn check_automation_task_gas( match results { Ok(_) => Ok(()), Err(VMStatus::Error { - status_code, sub_status, message - } )=> { + status_code, + sub_status, + message, + }) => { let mapped_status = match status_code { StatusCode::EXCEEDED_MAX_TRANSACTION_SIZE => { StatusCode::AUTOMATION_PAYLOAD_EXCEEDED_MAX_TRANSACTION_SIZE - } + }, StatusCode::MAX_GAS_UNITS_EXCEEDS_MAX_GAS_UNITS_BOUND => { StatusCode::AUTOMATION_TASK_MAX_GAS_UNITS_EXCEEDS_MAX_GAS_UNITS_BOUND - } + }, StatusCode::MAX_GAS_UNITS_BELOW_MIN_TRANSACTION_GAS_UNITS => { StatusCode::AUTOMATION_TASK_MAX_GAS_UNITS_BELOW_MIN_TRANSACTION_GAS_UNITS - } + }, StatusCode::GAS_UNIT_PRICE_BELOW_MIN_BOUND => { StatusCode::AUTOMATION_TASK_GAS_PRICE_CAP_BELOW_MIN_BOUND - } + }, StatusCode::GAS_UNIT_PRICE_ABOVE_MAX_BOUND => { StatusCode::AUTOMATION_TASK_GAS_PRICE_CAP_ABOVE_MAX_BOUND - } - _ => status_code + }, + _ => status_code, }; Err(VMStatus::Error { status_code: mapped_status, sub_status, message, }) - } - Err(v) => Err(v), + }, + Err(v) => Err(v), } } @@ -278,8 +294,7 @@ pub(crate) fn check_gas_for_parameters( log_context, format!( "[VM] Gas unit error; max {}, submitted {}", - txn_gas_params.maximum_number_of_gas_units, - txn_gas_metadata.max_gas_amount + txn_gas_params.maximum_number_of_gas_units, txn_gas_metadata.max_gas_amount ), ); return Err(VMStatus::error( @@ -306,8 +321,7 @@ pub(crate) fn check_gas_for_parameters( log_context, format!( "[VM] Gas unit error; min {}, submitted {}", - total_rounded, - txn_gas_metadata.max_gas_amount + total_rounded, txn_gas_metadata.max_gas_amount ), ); return Err(VMStatus::error( @@ -326,8 +340,7 @@ pub(crate) fn check_gas_for_parameters( log_context, format!( "[VM] Gas unit error; min {}, submitted {}", - txn_gas_params.min_price_per_gas_unit, - txn_gas_metadata.gas_unit_price + txn_gas_params.min_price_per_gas_unit, txn_gas_metadata.gas_unit_price ), ); return Err(VMStatus::error( @@ -356,7 +369,7 @@ pub(crate) fn check_gas_for_parameters( // gas to cover storage, execution, and IO costs. // TODO: This isn't the cleaning code, thus we localize it just here and will remove it // once accountv2 is available and we no longer need to create accounts. - if txn_gas_metadata.is_account_init_for_sponsored_transaction { + if txn_gas_metadata.is_account_init_for_sponsored_transaction { let gas_unit_price: u64 = txn_gas_metadata.gas_unit_price.into(); let max_gas_amount: u64 = txn_gas_metadata.max_gas_amount.into(); let pricing = DiskSpacePricing::new(gas_feature_version, features); diff --git a/aptos-move/aptos-vm/src/lib.rs b/aptos-move/aptos-vm/src/lib.rs index 06b851ff393..b5575c49fbf 100644 --- a/aptos-move/aptos-vm/src/lib.rs +++ b/aptos-move/aptos-vm/src/lib.rs @@ -107,6 +107,9 @@ pub mod counters; pub mod data_cache; pub mod aptos_vm; +pub mod aptos_vm_viewer; +mod automated_transaction_processor; +mod automation_registry_transaction_processor; pub mod block_executor; mod errors; pub mod gas; @@ -123,16 +126,17 @@ pub mod transaction_metadata; mod transaction_validation; pub mod validator_txns; pub mod verifier; -mod automated_transaction_processor; -pub mod aptos_vm_viewer; -mod automation_registry_transaction_processor; pub use crate::aptos_vm::{AptosSimulationVM, AptosVM}; -use crate::sharded_block_executor::{executor_client::ExecutorClient, ShardedBlockExecutor}; +use crate::{ + move_vm_ext::AptosMoveResolver, + sharded_block_executor::{executor_client::ExecutorClient, ShardedBlockExecutor}, +}; use aptos_types::{ block_executor::{ config::BlockExecutorConfigFromOnchain, partitioner::PartitionedTransactions, }, + dkg::transactions::DKGTransactionData, state_store::StateView, transaction::{ signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, @@ -151,6 +155,12 @@ pub trait VMValidator { transaction: SignedTransaction, state_view: &impl StateView, ) -> VMValidatorResult; + + fn validate_dkg_validator_transaction( + &self, + dkg_transaction: DKGTransactionData, + resolver: &impl AptosMoveResolver, + ) -> VMValidatorResult; } /// This trait describes the VM's execution interface. diff --git a/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs b/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs index f4888975447..e678dbac982 100644 --- a/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs +++ b/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs @@ -6,11 +6,10 @@ use aptos_crypto::{hash::CryptoHash, HashValue}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use aptos_types::{ block_metadata::BlockMetadata, block_metadata_ext::BlockMetadataExt, - validator_txn::ValidatorTransaction, + transaction::automation::AutomationRegistryRecord, validator_txn::ValidatorTransaction, }; use move_core_types::account_address::AccountAddress; use serde::{Deserialize, Serialize}; -use aptos_types::transaction::automation::AutomationRegistryRecord; #[derive(BCSCryptoHash, Clone, CryptoHasher, Deserialize, Serialize)] pub enum SessionId { @@ -53,7 +52,7 @@ pub enum SessionId { }, AutomationRegistryTxn { id: HashValue, - } + }, } impl SessionId { @@ -90,9 +89,7 @@ impl SessionId { } pub fn automation_registry_action(record: &AutomationRegistryRecord) -> Self { - Self::AutomationRegistryTxn { - id: record.hash() - } + Self::AutomationRegistryTxn { id: record.hash() } } pub fn run_on_abort(txn_metadata: &TransactionMetadata) -> Self { diff --git a/aptos-move/aptos-vm/src/system_module_names.rs b/aptos-move/aptos-vm/src/system_module_names.rs index e921704b64e..04223d8dd89 100644 --- a/aptos-move/aptos-vm/src/system_module_names.rs +++ b/aptos-move/aptos-vm/src/system_module_names.rs @@ -38,6 +38,7 @@ pub static RECONFIGURATION_WITH_DKG_MODULE: Lazy = Lazy::new(|| { }); pub const FINISH_WITH_DKG_RESULT: &IdentStr = ident_str!("finish_with_dkg_result"); +pub const SET_DKG_META: &IdentStr = ident_str!("set_dkg_meta"); pub static JWKS_MODULE: Lazy = Lazy::new(|| { ModuleId::new( diff --git a/aptos-move/aptos-vm/src/transaction_metadata.rs b/aptos-move/aptos-vm/src/transaction_metadata.rs index 5d9947af7bf..5c5575aff26 100644 --- a/aptos-move/aptos-vm/src/transaction_metadata.rs +++ b/aptos-move/aptos-vm/src/transaction_metadata.rs @@ -5,16 +5,17 @@ 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, transaction::{ - user_transaction_context::UserTransactionContext, EntryFunction, Multisig, - SignedTransaction, TransactionPayload, + automated_transaction::AutomatedTransaction, + user_transaction_context::{ + PayloadTypeReference, PayloadTypeReferenceContext, UserTransactionContext, + }, + EntryFunction, Multisig, SignedTransaction, TransactionPayload, }, }; -use aptos_types::transaction::user_transaction_context::{PayloadTypeReference, PayloadTypeReferenceContext}; pub type PayloadTypeReferenceMeta = PayloadTypeReference; pub struct TransactionMetadata { @@ -40,11 +41,16 @@ pub struct TransactionMetadata { impl TransactionMetadata { pub fn new(txn: &SignedTransaction) -> Self { let payload_type_reference = match txn.payload() { - TransactionPayload::Script(_) | - TransactionPayload::ModuleBundle(_) => PayloadTypeReferenceMeta::Other, - TransactionPayload::EntryFunction(e) => PayloadTypeReferenceMeta::UserEntryFunction(e.clone()), + TransactionPayload::Script(_) | TransactionPayload::ModuleBundle(_) => { + PayloadTypeReferenceMeta::Other + }, + TransactionPayload::EntryFunction(e) => { + PayloadTypeReferenceMeta::UserEntryFunction(e.clone()) + }, TransactionPayload::Multisig(m) => PayloadTypeReferenceMeta::Multisig(m.clone()), - TransactionPayload::AutomationRegistration(_) => PayloadTypeReferenceMeta::AutomationRegistration, + TransactionPayload::AutomationRegistration(_) => { + PayloadTypeReferenceMeta::AutomationRegistration + }, }; Self { sender: txn.sender(), @@ -161,9 +167,15 @@ impl TransactionMetadata { pub fn as_user_transaction_context(&self) -> UserTransactionContext { let payload_type_reference = match &self.payload_type_reference { PayloadTypeReferenceMeta::Other => PayloadTypeReferenceContext::Other, - PayloadTypeReferenceMeta::UserEntryFunction(e) => PayloadTypeReferenceContext::UserEntryFunction(e.as_entry_function_payload()), - PayloadTypeReferenceMeta::Multisig(m) => PayloadTypeReferenceContext::Multisig(m.as_multisig_payload()), - PayloadTypeReferenceMeta::AutomationRegistration => PayloadTypeReferenceContext::AutomationRegistration, + PayloadTypeReferenceMeta::UserEntryFunction(e) => { + PayloadTypeReferenceContext::UserEntryFunction(e.as_entry_function_payload()) + }, + PayloadTypeReferenceMeta::Multisig(m) => { + PayloadTypeReferenceContext::Multisig(m.as_multisig_payload()) + }, + PayloadTypeReferenceMeta::AutomationRegistration => { + PayloadTypeReferenceContext::AutomationRegistration + }, }; UserTransactionContext::new( self.sender, @@ -195,7 +207,9 @@ impl From<&AutomatedTransaction> for TransactionMetadata { script_hash: vec![], script_size: NumBytes::zero(), is_keyless: false, - payload_type_reference: PayloadTypeReferenceMeta::UserEntryFunction(txn.payload().clone().into_entry_function()), + payload_type_reference: PayloadTypeReferenceMeta::UserEntryFunction( + txn.payload().clone().into_entry_function(), + ), txn_app_hash: txn.hash().to_vec(), } } diff --git a/aptos-move/aptos-vm/src/transaction_validation.rs b/aptos-move/aptos-vm/src/transaction_validation.rs index b6e8d5fd3a6..30bb859ec2b 100644 --- a/aptos-move/aptos-vm/src/transaction_validation.rs +++ b/aptos-move/aptos-vm/src/transaction_validation.rs @@ -5,7 +5,7 @@ use crate::{ errors::{convert_epilogue_error, convert_prologue_error, expect_only_successful_execution}, move_vm_ext::SessionExt, system_module_names::{ - EMIT_FEE_STATEMENT, MULTISIG_ACCOUNT_MODULE, TRANSACTION_FEE_MODULE, + EMIT_FEE_STATEMENT, EMIT_GAS_ASSESSMENT, MULTISIG_ACCOUNT_MODULE, TRANSACTION_FEE_MODULE, VALIDATE_MULTISIG_TRANSACTION, }, testing::{maybe_raise_injected_error, InjectedError}, @@ -13,8 +13,10 @@ use crate::{ }; use aptos_gas_algebra::Gas; use aptos_types::{ - account_config::constants::CORE_CODE_ADDRESS, fee_statement::FeeStatement, - on_chain_config::Features, transaction::Multisig, + account_config::constants::CORE_CODE_ADDRESS, + fee_statement::FeeStatement, + on_chain_config::Features, + transaction::{automation::AutomationTaskType, Multisig}, }; use aptos_vm_logging::log_schema::AdapterLogSchema; use fail::fail_point; @@ -30,8 +32,6 @@ use move_core_types::{ use move_vm_runtime::{logging::expect_no_verification_errors, module_traversal::TraversalContext}; use move_vm_types::gas::UnmeteredGasMeter; use once_cell::sync::Lazy; -use aptos_types::transaction::automation::AutomationTaskType; -use crate::system_module_names::EMIT_GAS_ASSESSMENT; pub static APTOS_TRANSACTION_VALIDATION: Lazy = Lazy::new(|| TransactionValidation { @@ -41,7 +41,8 @@ pub static APTOS_TRANSACTION_VALIDATION: Lazy = script_prologue_name: Identifier::new("script_prologue").unwrap(), multi_agent_prologue_name: Identifier::new("multi_agent_script_prologue").unwrap(), automated_txn_prologue_name: Identifier::new("automated_transaction_prologue").unwrap(), - automated_txn_prologue_v2_name: Identifier::new("automated_transaction_prologue_v2").unwrap(), + automated_txn_prologue_v2_name: Identifier::new("automated_transaction_prologue_v2") + .unwrap(), user_epilogue_name: Identifier::new("epilogue").unwrap(), user_epilogue_gas_payer_name: Identifier::new("epilogue_gas_payer").unwrap(), automated_txn_epilogue_name: Identifier::new("automated_transaction_epilogue").unwrap(), @@ -387,10 +388,10 @@ fn run_automated_txn_epilogue( match task_type { AutomationTaskType::User => { emit_fee_statement(session, fee_statement, traversal_context)?; - } + }, AutomationTaskType::System => { emit_as_gas_assessment(session, fee_statement, traversal_context)?; - } + }, } } diff --git a/aptos-move/aptos-vm/src/validator_txns/dkg.rs b/aptos-move/aptos-vm/src/validator_txns/dkg.rs index dd5f77dd174..309777b5ea2 100644 --- a/aptos-move/aptos-vm/src/validator_txns/dkg.rs +++ b/aptos-move/aptos-vm/src/validator_txns/dkg.rs @@ -5,131 +5,108 @@ use crate::{ aptos_vm::get_or_vm_startup_failure, errors::expect_only_successful_execution, move_vm_ext::{AptosMoveResolver, SessionId}, - system_module_names::{FINISH_WITH_DKG_RESULT, RECONFIGURATION_WITH_DKG_MODULE}, - validator_txns::dkg::{ - ExecutionFailure::{Expected, Unexpected}, - ExpectedFailure::*, - }, - AptosVM, + system_module_names::{FINISH_WITH_DKG_RESULT, RECONFIGURATION_WITH_DKG_MODULE, SET_DKG_META}, + AptosVM, VMValidator, }; use aptos_types::{ - dkg::{DKGState, DKGTrait, DKGTranscript, DefaultDKG}, + dkg::transactions::{DKGTransactionData, DKGTransactionType}, fee_statement::FeeStatement, move_utils::as_move_value::AsMoveValue, - on_chain_config::{ConfigurationResource, OnChainConfig}, transaction::{ExecutionStatus, TransactionStatus}, + vm_status::DiscardedVMStatus, }; use aptos_vm_logging::log_schema::AdapterLogSchema; use aptos_vm_types::output::VMOutput; use move_core_types::{ account_address::AccountAddress, value::{serialize_values, MoveValue}, - vm_status::{AbortLocation, StatusCode, VMStatus}, + vm_status::VMStatus, }; use move_vm_runtime::module_traversal::{TraversalContext, TraversalStorage}; use move_vm_types::gas::UnmeteredGasMeter; -#[derive(Debug)] -enum ExpectedFailure { - // Move equivalent: `errors::invalid_argument(*)` - EpochNotCurrent = 0x10001, - TranscriptDeserializationFailed = 0x10002, - TranscriptVerificationFailed = 0x10003, - - // Move equivalent: `errors::invalid_state(*)` - MissingResourceDKGState = 0x30001, - MissingResourceInprogressDKGSession = 0x30002, - MissingResourceConfiguration = 0x30003, -} - enum ExecutionFailure { - Expected(ExpectedFailure), + Expected(DiscardedVMStatus), Unexpected(VMStatus), } impl AptosVM { - pub(crate) fn process_dkg_result( + pub(crate) fn process_dkg_transaction( &self, resolver: &impl AptosMoveResolver, log_context: &AdapterLogSchema, session_id: SessionId, - dkg_transcript: DKGTranscript, + dkg_transaction_data: DKGTransactionData, ) -> Result<(VMStatus, VMOutput), VMStatus> { - match self.process_dkg_result_inner(resolver, log_context, session_id, dkg_transcript) { + match self.process_dkg_transaction_inner( + resolver, + log_context, + session_id, + dkg_transaction_data, + ) { Ok((vm_status, vm_output)) => Ok((vm_status, vm_output)), - Err(Expected(failure)) => { + Err(ExecutionFailure::Expected(status)) => { // Pretend we are inside Move, and expected failures are like Move aborts. Ok(( - VMStatus::MoveAbort(AbortLocation::Script, failure as u64), - VMOutput::empty_with_status(TransactionStatus::Discard(StatusCode::ABORTED)), + VMStatus::error(status, None), + VMOutput::empty_with_status(TransactionStatus::Discard(status)), )) }, - Err(Unexpected(vm_status)) => Err(vm_status), + Err(ExecutionFailure::Unexpected(vm_status)) => Err(vm_status), } } - fn process_dkg_result_inner( + fn process_dkg_transaction_inner( &self, resolver: &impl AptosMoveResolver, log_context: &AdapterLogSchema, session_id: SessionId, - dkg_node: DKGTranscript, + dkg_transaction: DKGTransactionData, ) -> Result<(VMStatus, VMOutput), ExecutionFailure> { - let dkg_state = OnChainConfig::fetch_config(resolver) - .ok_or_else(|| Expected(MissingResourceDKGState))?; - let config_resource = ConfigurationResource::fetch_config(resolver) - .ok_or_else(|| Expected(MissingResourceConfiguration))?; - let DKGState { in_progress, .. } = dkg_state; - let in_progress_session_state = - in_progress.ok_or_else(|| Expected(MissingResourceInprogressDKGSession))?; - - // Check epoch number. - if dkg_node.metadata.epoch != config_resource.epoch() { - return Err(Expected(EpochNotCurrent)); + // Verify the dkg transaction before execution + if let Some(status) = self + .validate_dkg_validator_transaction(dkg_transaction.clone(), resolver) + .status() + { + return Err(ExecutionFailure::Expected(status)); } - // Deserialize transcript and verify it. - let pub_params = DefaultDKG::new_public_params(&in_progress_session_state.metadata); - let transcript = bcs::from_bytes::<::Transcript>( - dkg_node.transcript_bytes.as_slice(), - ) - .map_err(|_| Expected(TranscriptDeserializationFailed))?; - - DefaultDKG::verify_transcript(&pub_params, &transcript) - .map_err(|_| Expected(TranscriptVerificationFailed))?; + let (function_name, args) = match dkg_transaction.metadata().transaction_type() { + DKGTransactionType::DKGMeta => (SET_DKG_META, vec![dkg_transaction + .data_bytes() + .as_move_value()]), + DKGTransactionType::PublicKeyShares => (FINISH_WITH_DKG_RESULT, vec![ + MoveValue::Signer(AccountAddress::ONE), + dkg_transaction.data_bytes().as_move_value(), + ]), + }; // All check passed, invoke VM to publish DKG result on chain. let mut gas_meter = UnmeteredGasMeter; let mut session = self.new_session(resolver, session_id, None); - let args = vec![ - MoveValue::Signer(AccountAddress::ONE), - dkg_node.transcript_bytes.as_move_value(), - ]; let module_storage = TraversalStorage::new(); session .execute_function_bypass_visibility( &RECONFIGURATION_WITH_DKG_MODULE, - FINISH_WITH_DKG_RESULT, + function_name, vec![], serialize_values(&args), &mut gas_meter, &mut TraversalContext::new(&module_storage), ) - .map_err(|e| { - expect_only_successful_execution(e, FINISH_WITH_DKG_RESULT.as_str(), log_context) - }) - .map_err(|r| Unexpected(r.unwrap_err()))?; + .map_err(|e| expect_only_successful_execution(e, function_name.as_str(), log_context)) + .map_err(|r| ExecutionFailure::Unexpected(r.unwrap_err()))?; let output = crate::aptos_vm::get_system_transaction_output( session, FeeStatement::zero(), ExecutionStatus::Success, &get_or_vm_startup_failure(&self.storage_gas_params, log_context) - .map_err(Unexpected)? + .map_err(ExecutionFailure::Unexpected)? .change_set_configs, ) - .map_err(Unexpected)?; + .map_err(ExecutionFailure::Unexpected)?; Ok((VMStatus::Executed, output)) } diff --git a/aptos-move/aptos-vm/src/validator_txns/mod.rs b/aptos-move/aptos-vm/src/validator_txns/mod.rs index 1c6c020fec1..b19c9c120d0 100644 --- a/aptos-move/aptos-vm/src/validator_txns/mod.rs +++ b/aptos-move/aptos-vm/src/validator_txns/mod.rs @@ -5,10 +5,10 @@ use crate::{ move_vm_ext::{AptosMoveResolver, SessionId}, AptosVM, }; -use aptos_types::validator_txn::ValidatorTransaction; +use aptos_types::{on_chain_config::FeatureFlag, validator_txn::ValidatorTransaction}; use aptos_vm_logging::log_schema::AdapterLogSchema; use aptos_vm_types::output::VMOutput; -use move_core_types::vm_status::VMStatus; +use move_core_types::vm_status::{StatusCode, VMStatus}; impl AptosVM { pub(crate) fn process_validator_transaction( @@ -19,12 +19,21 @@ impl AptosVM { ) -> Result<(VMStatus, VMOutput), VMStatus> { let session_id = SessionId::validator_txn(&txn); match txn { - ValidatorTransaction::DKGResult(dkg_node) => { - self.process_dkg_result(resolver, log_context, session_id, dkg_node) + ValidatorTransaction::DKG(dkg_node) => { + if !self.features().is_enabled(FeatureFlag::SUPRA_DKG) { + return Err(VMStatus::error(StatusCode::FEATURE_UNDER_GATING, None)); + } + + self.process_dkg_transaction(resolver, log_context, session_id, dkg_node) }, ValidatorTransaction::ObservedJWKUpdate(jwk_update) => { self.process_jwk_update(resolver, log_context, session_id, jwk_update) }, + ValidatorTransaction::DKGResult(_) => Err(VMStatus::Error { + status_code: StatusCode::UNREACHABLE, + sub_status: None, + message: Some("Unsupported ValidatorTransaction variant".to_string()), + }), } } } diff --git a/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs b/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs index 2616217a98c..3267afdb0a6 100644 --- a/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs +++ b/aptos-move/aptos-vm/src/verifier/transaction_arg_validation.rs @@ -39,13 +39,10 @@ pub(crate) struct FunctionId { type ConstructorMap = Lazy>; static OLD_ALLOWED_STRUCTS: ConstructorMap = Lazy::new(|| { - [( - "0x1::string::String", - FunctionId { - module_id: ModuleId::new(AccountAddress::ONE, Identifier::from(ident_str!("string"))), - func_name: ident_str!("utf8"), - }, - )] + [("0x1::string::String", FunctionId { + module_id: ModuleId::new(AccountAddress::ONE, Identifier::from(ident_str!("string"))), + func_name: ident_str!("utf8"), + })] .into_iter() .map(|(s, validator)| (s.to_string(), validator)) .collect() @@ -53,56 +50,32 @@ static OLD_ALLOWED_STRUCTS: ConstructorMap = Lazy::new(|| { static NEW_ALLOWED_STRUCTS: ConstructorMap = Lazy::new(|| { [ - ( - "0x1::string::String", - FunctionId { - module_id: ModuleId::new( - AccountAddress::ONE, - Identifier::from(ident_str!("string")), - ), - func_name: ident_str!("utf8"), - }, - ), - ( - "0x1::object::Object", - FunctionId { - module_id: ModuleId::new( - AccountAddress::ONE, - Identifier::from(ident_str!("object")), - ), - func_name: ident_str!("address_to_object"), - }, - ), - ( - "0x1::option::Option", - FunctionId { - module_id: ModuleId::new( - AccountAddress::ONE, - Identifier::from(ident_str!("option")), - ), - func_name: ident_str!("from_vec"), - }, - ), - ( - "0x1::fixed_point32::FixedPoint32", - FunctionId { - module_id: ModuleId::new( - AccountAddress::ONE, - Identifier::from(ident_str!("fixed_point32")), - ), - func_name: ident_str!("create_from_raw_value"), - }, - ), - ( - "0x1::fixed_point64::FixedPoint64", - FunctionId { - module_id: ModuleId::new( - AccountAddress::ONE, - Identifier::from(ident_str!("fixed_point64")), - ), - func_name: ident_str!("create_from_raw_value"), - }, - ), + ("0x1::string::String", FunctionId { + module_id: ModuleId::new(AccountAddress::ONE, Identifier::from(ident_str!("string"))), + func_name: ident_str!("utf8"), + }), + ("0x1::object::Object", FunctionId { + module_id: ModuleId::new(AccountAddress::ONE, Identifier::from(ident_str!("object"))), + func_name: ident_str!("address_to_object"), + }), + ("0x1::option::Option", FunctionId { + module_id: ModuleId::new(AccountAddress::ONE, Identifier::from(ident_str!("option"))), + func_name: ident_str!("from_vec"), + }), + ("0x1::fixed_point32::FixedPoint32", FunctionId { + module_id: ModuleId::new( + AccountAddress::ONE, + Identifier::from(ident_str!("fixed_point32")), + ), + func_name: ident_str!("create_from_raw_value"), + }), + ("0x1::fixed_point64::FixedPoint64", FunctionId { + module_id: ModuleId::new( + AccountAddress::ONE, + Identifier::from(ident_str!("fixed_point64")), + ), + func_name: ident_str!("create_from_raw_value"), + }), ] .into_iter() .map(|(s, validator)| (s.to_string(), validator)) diff --git a/aptos-move/e2e-move-tests/src/lib.rs b/aptos-move/e2e-move-tests/src/lib.rs index f90cede8c72..0d122e884a8 100644 --- a/aptos-move/e2e-move-tests/src/lib.rs +++ b/aptos-move/e2e-move-tests/src/lib.rs @@ -3,10 +3,10 @@ pub mod aggregator; pub mod aggregator_v2; -pub mod supra_governance; pub mod harness; pub mod resource_groups; pub mod stake; +pub mod supra_governance; pub mod transaction_fee; use anyhow::bail; @@ -28,7 +28,8 @@ impl PackageHooks for AptosPackageHooks { fn custom_package_info_fields(&self) -> Vec { vec![UPGRADE_POLICY_CUSTOM_FIELD.to_string()] } -// sbjoshi changed + + // sbjoshi changed fn custom_dependency_key(&self) -> Option { Some("supra".to_string()) } diff --git a/aptos-move/e2e-move-tests/src/supra_governance.rs b/aptos-move/e2e-move-tests/src/supra_governance.rs index 485a39da0c3..d0d73489e4e 100644 --- a/aptos-move/e2e-move-tests/src/supra_governance.rs +++ b/aptos-move/e2e-move-tests/src/supra_governance.rs @@ -53,9 +53,6 @@ pub fn supra_vote( ) -> TransactionStatus { harness.run_transaction_payload( account, - aptos_stdlib::supra_governance_supra_vote( - proposal_id, - should_pass, - ), + aptos_stdlib::supra_governance_supra_vote(proposal_id, should_pass), ) } diff --git a/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs b/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs index 3851247d57d..fcf482d10fb 100644 --- a/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs +++ b/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs @@ -2,19 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{assert_success, tests::common, MoveHarness}; -use aptos_types::account_address::{self, AccountAddress}; +use aptos_cached_packages::aptos_stdlib; +use aptos_language_e2e_tests::account::{Account, TransactionBuilder}; +use aptos_types::{ + account_address::{self, AccountAddress}, + account_config::AccountResource, + on_chain_config::FeatureFlag, +}; use move_core_types::{ identifier::Identifier, language_storage::{StructTag, TypeTag}, + move_resource::MoveStructType, }; use once_cell::sync::Lazy; use serde::Deserialize; use std::str::FromStr; -use aptos_cached_packages::aptos_stdlib; -use aptos_language_e2e_tests::account::{Account, TransactionBuilder}; -use aptos_types::account_config::AccountResource; -use aptos_types::on_chain_config::FeatureFlag; -use move_core_types::move_resource::MoveStructType; #[derive(Debug, Deserialize, Eq, PartialEq)] struct FungibleStore { @@ -279,7 +281,7 @@ fn test_sponsered_tx() { "0x{}::managed_fungible_token::get_metadata", (*alice.address()).to_hex() )) - .unwrap(), + .unwrap(), vec![], vec![], ) @@ -295,7 +297,7 @@ fn test_sponsered_tx() { "0x{}::managed_fungible_asset::mint_to_primary_stores", (*alice.address()).to_hex() )) - .unwrap(), + .unwrap(), vec![], vec![ bcs::to_bytes(&metadata).unwrap(), @@ -319,10 +321,7 @@ fn test_sponsered_tx() { sender_hex ); let module_src = module_src_string.as_str(); - let payload = aptos_stdlib::publish_module_source( - "test_module", - module_src - ); + let payload = aptos_stdlib::publish_module_source("test_module", module_src); let transaction = TransactionBuilder::new(bob.clone()) .fee_payer(alice.clone()) .payload(payload) @@ -336,7 +335,10 @@ fn test_sponsered_tx() { // Make sure bob's account is created let exists = h.exists_resource(bob.address(), AccountResource::struct_tag()); - assert!(exists, "Bob's account should exist after the sponsored transaction"); + assert!( + exists, + "Bob's account should exist after the sponsored transaction" + ); let result = h.run_entry_function( &alice, @@ -344,7 +346,7 @@ fn test_sponsered_tx() { "0x{}::managed_fungible_asset::transfer_between_primary_stores", (*alice.address()).to_hex() )) - .unwrap(), + .unwrap(), vec![], vec![ bcs::to_bytes(&metadata).unwrap(), diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/test/Move.toml b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/test/Move.toml index f0123a1a751..d37cbbbda4b 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/test/Move.toml +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/test/Move.toml @@ -5,4 +5,3 @@ version = "0.0.0" [dependencies] MoveStdlib = { local = "../../../../../framework/move-stdlib" } AptosStdlib = { local = "../../../../../framework/aptos-stdlib" } - diff --git a/aptos-move/e2e-move-tests/src/tests/vote.rs b/aptos-move/e2e-move-tests/src/tests/vote.rs index 4f1adc35be5..24293b9970a 100644 --- a/aptos-move/e2e-move-tests/src/tests/vote.rs +++ b/aptos-move/e2e-move-tests/src/tests/vote.rs @@ -1,10 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{ - supra_governance::*, assert_abort, assert_success, - tests::common, MoveHarness, -}; +use crate::{assert_abort, assert_success, supra_governance::*, tests::common, MoveHarness}; use aptos_types::account_address::AccountAddress; use once_cell::sync::Lazy; use std::collections::BTreeMap; @@ -34,12 +31,7 @@ fn test_supra_vote() { true )); // Voters can vote on a voting proposal. - assert_success!(supra_vote( - &mut harness, - &voter, - proposal_id, - true - )); + assert_success!(supra_vote(&mut harness, &voter, proposal_id, true)); // Enable partial governance voting. In production, it requires governance. let core_resources = @@ -51,15 +43,7 @@ fn test_supra_vote() { assert_success!(harness.run(txn)); // If a voter has already voted on a proposal before partial voting is enabled, the voter cannot vote on the proposal again. - assert_abort!( - supra_vote( - &mut harness, - &voter, - proposal_id, - true - ), - 0x8000D - ); + assert_abort!(supra_vote(&mut harness, &voter, proposal_id, true), 0x8000D); assert_success!(supra_create_proposal_v2( &mut harness, @@ -73,27 +57,12 @@ fn test_supra_vote() { // Cannot vote on a non-exist proposal. let wrong_proposal_id: u64 = 2; assert_abort!( - supra_vote( - &mut harness, - &voter, - wrong_proposal_id, - true - ), + supra_vote(&mut harness, &voter, wrong_proposal_id, true), 25863 ); proposal_id = 1; // A voter can vote on a proposal multiple times with both Yes/No. - assert_success!(supra_vote( - &mut harness, - &voter, - proposal_id, - true - )); - assert_success!(supra_vote( - &mut harness, - &voter, - proposal_id, - false - )); + assert_success!(supra_vote(&mut harness, &voter, proposal_id, true)); + assert_success!(supra_vote(&mut harness, &voter, proposal_id, false)); } diff --git a/aptos-move/e2e-tests/Cargo.toml b/aptos-move/e2e-tests/Cargo.toml index 859110fee43..6c707d1f5f9 100644 --- a/aptos-move/e2e-tests/Cargo.toml +++ b/aptos-move/e2e-tests/Cargo.toml @@ -17,7 +17,7 @@ anyhow = { workspace = true } aptos-abstract-gas-usage = { workspace = true } aptos-bitvec = { workspace = true } aptos-block-executor = { workspace = true } -aptos-cached-packages ={ workspace = true } +aptos-cached-packages = { workspace = true } aptos-crypto = { workspace = true, features = ["fuzzing"] } aptos-framework = { workspace = true } aptos-gas-algebra = { workspace = true } diff --git a/aptos-move/e2e-testsuite/Cargo.toml b/aptos-move/e2e-testsuite/Cargo.toml index c06a16c83ec..0c96321aebe 100644 --- a/aptos-move/e2e-testsuite/Cargo.toml +++ b/aptos-move/e2e-testsuite/Cargo.toml @@ -35,7 +35,7 @@ serde = { workspace = true, features = ["derive"] } [features] default = [ - "aptos-cached-packages/fuzzing", - "move-core-types/fuzzing", - "aptos-types/fuzzing", + "aptos-cached-packages/fuzzing", + "move-core-types/fuzzing", + "aptos-types/fuzzing", ] diff --git a/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs b/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs index cf821b96a89..931f7b3611a 100644 --- a/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs +++ b/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs @@ -1,3 +1,6 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 @@ -139,8 +142,7 @@ fn check_automated_transaction_successful_execution() { panic!("Automated transaction should successfully build: {maybe_automated_txn:?}") }; - let result = test_context - .execute_tagged_transaction(automated_txn.clone().into()); + let result = test_context.execute_tagged_transaction(automated_txn.clone().into()); AutomationRegistrationTestContext::check_discarded_output( result, StatusCode::NO_ACTIVE_AUTOMATED_TASK, @@ -162,8 +164,7 @@ fn check_automated_transaction_successful_execution() { // Execute automated transaction one more time which should be success, as task is already become active after epoch change let sender_address = test_context.sender_account_address(); let sender_seq_num = test_context.account_sequence_number(sender_address); - let output = test_context - .execute_and_apply_transaction(automated_txn.clone().into()); + let output = test_context.execute_and_apply_transaction(automated_txn.clone().into()); assert_eq!( output.status(), &TransactionStatus::Keep(ExecutionStatus::Success), @@ -187,8 +188,7 @@ fn check_automated_transaction_successful_execution() { let BuilderResult::Success(automated_txn) = maybe_automated_txn else { panic!("Automated transaction should successfully build") }; - let result = test_context - .execute_tagged_transaction(automated_txn.clone().into()); + let result = test_context.execute_tagged_transaction(automated_txn.clone().into()); AutomationRegistrationTestContext::check_discarded_output( result, StatusCode::NO_ACTIVE_AUTOMATED_TASK, diff --git a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs index fdfbf02f3aa..73648ec2e11 100644 --- a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs +++ b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs @@ -1,3 +1,6 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 @@ -8,38 +11,34 @@ use aptos_language_e2e_tests::{ data_store::FakeDataStore, executor::FakeExecutor, }; -use aptos_types::account_address::create_multisig_account_address; -use aptos_types::transaction::automation::Priority; -use aptos_types::transaction::{ExecutionError, Multisig, MultisigTransactionPayload}; use aptos_types::{ + account_address::create_multisig_account_address, + contract_event::ContractEvent, on_chain_config::{ AutomationCycleDetails, AutomationCycleInfo, AutomationCycleState, FeatureFlag, OnChainConfig, }, transaction::{ automation::{ - AutomationRegistryAction, AutomationRegistryRecord, AutomationTaskMetaData, + AutomationRegistryAction, AutomationRegistryRecord, AutomationTaskMetaData, Priority, RegistrationParams, }, - EntryFunction, ExecutionStatus, SignedTransaction, Transaction, TransactionOutput, - TransactionPayload, TransactionStatus, + EntryFunction, ExecutionError, ExecutionStatus, Multisig, MultisigTransactionPayload, + SignedTransaction, Transaction, TransactionOutput, TransactionPayload, TransactionStatus, }, }; use aptos_vm::aptos_vm_viewer::AptosVMViewer; use move_core_types::{ account_address::AccountAddress, value::{serialize_values, MoveValue}, - vm_status::StatusCode, + vm_status::{StatusCode, StatusCode::FEATURE_UNDER_GATING}, }; +use serde::{Deserialize, Serialize}; use std::{ ops::{Deref, DerefMut}, time::Instant, }; -use serde::{Serialize, Deserialize}; -use aptos_types::contract_event::ContractEvent; -use move_core_types::vm_status::StatusCode::FEATURE_UNDER_GATING; - const TIMESTAMP_NOW_SECONDS: &str = "0x1::timestamp::now_seconds"; const ACCOUNT_BALANCE: &str = "0x1::coin::balance"; const SUPRA_COIN: &str = "0x1::supra_coin::SupraCoin"; @@ -166,16 +165,12 @@ impl AutomationRegistrationTestContext { } else { (vec![], flag_value) }; - self.executor.exec( - "features", - "change_feature_flags_internal", - vec![], - vec![ + self.executor + .exec("features", "change_feature_flags_internal", vec![], vec![ MoveValue::Signer(acc).simple_serialize().unwrap(), bcs::to_bytes(&enabled).unwrap(), bcs::to_bytes(&disabled).unwrap(), - ], - ); + ]); } pub(crate) fn toggle_feature_with_registry_reconfig( @@ -395,11 +390,10 @@ impl AutomationRegistrationTestContext { } pub(crate) fn account_sequence_number(&mut self, account_address: AccountAddress) -> u64 { - let view_output = self.execute_view_function( - str::parse(ACCOUNT_SEQ_NUM).unwrap(), - vec![], - vec![account_address.to_vec()], - ); + let view_output = + self.execute_view_function(str::parse(ACCOUNT_SEQ_NUM).unwrap(), vec![], vec![ + account_address.to_vec(), + ]); let result = view_output.values.expect("Valid result"); assert_eq!(result.len(), 1); bcs::from_bytes::(&result[0]).unwrap() @@ -417,13 +411,12 @@ impl AutomationRegistrationTestContext { } pub(crate) fn get_task_details(&mut self, index: u64) -> AutomationTaskMetaData { - let view_output = self.execute_view_function( - str::parse(AUTOMATION_TASK_DETAILS).unwrap(), - vec![], - vec![MoveValue::U64(index) - .simple_serialize() - .expect("Successful serialization")], - ); + let view_output = + self.execute_view_function(str::parse(AUTOMATION_TASK_DETAILS).unwrap(), vec![], vec![ + MoveValue::U64(index) + .simple_serialize() + .expect("Successful serialization"), + ]); let result = view_output.values.expect("Valid result"); assert!(!result.is_empty()); bcs::from_bytes::(&result[0]) @@ -435,13 +428,11 @@ impl AutomationRegistrationTestContext { vm_viewer: &AptosVMViewer, ) -> AutomationTaskMetaData { let view_output = vm_viewer.execute_view_function( - to_view_function( - str::parse(AUTOMATION_TASK_DETAILS).unwrap(), - vec![], - vec![MoveValue::U64(index) + to_view_function(str::parse(AUTOMATION_TASK_DETAILS).unwrap(), vec![], vec![ + MoveValue::U64(index) .simple_serialize() - .expect("Successful serialization")], - ), + .expect("Successful serialization"), + ]), 50_000, ); let result = view_output.values.expect("Valid result"); @@ -807,14 +798,11 @@ fn check_automation_registry_actions_on_cycle_transition() { let result = test_context .execute_tagged_transaction(Transaction::AutomationRegistryTransaction(registry_action)); let status = result.status().status().expect("Expected execution status"); - assert!(matches!( - status, - ExecutionStatus::MoveAbort { - location: _, - code: _, - info: _ - } - )); + assert!(matches!(status, ExecutionStatus::MoveAbort { + location: _, + code: _, + info: _ + })); test_context.advance_chain_time_in_secs(600); @@ -848,14 +836,11 @@ fn check_automation_registry_actions_on_cycle_transition() { ); let status = result.status().status().expect("Expected execution status"); - assert!(matches!( - status, - ExecutionStatus::MoveAbort { - location: _, - code: _, - info: _ - } - )); + assert!(matches!(status, ExecutionStatus::MoveAbort { + location: _, + code: _, + info: _ + })); test_context.execute_and_apply_transaction(Transaction::AutomationRegistryTransaction( registry_action_for_task0, @@ -946,14 +931,11 @@ fn check_automation_registry_actions_on_cycle_suspension() { .execute_tagged_transaction(Transaction::AutomationRegistryTransaction(registry_action)); let status = result.status().status().expect("Expected execution status"); - assert!(matches!( - status, - ExecutionStatus::MoveAbort { - location: _, - code: _, - info: _ - } - )); + assert!(matches!(status, ExecutionStatus::MoveAbort { + location: _, + code: _, + info: _ + })); } #[test] @@ -972,7 +954,6 @@ fn check_automation_registry_actions_when_automation_cycle_disabled() { )); } - #[derive(Clone, Debug, Serialize, Deserialize)] struct TransactionExecutionFailed { multisig_address: AccountAddress, @@ -984,11 +965,12 @@ struct TransactionExecutionFailed { } fn find_transaction_error(events: &[ContractEvent]) -> Vec { - events.iter().filter(|e| e.is_v2()) + events + .iter() + .filter(|e| e.is_v2()) .map(|e| bcs::from_bytes::(e.event_data())) .filter_map(|d| d.ok()) .collect() - } #[test] @@ -1017,7 +999,9 @@ fn check_system_automation_task_registration() { let failed_event = find_transaction_error(output.events()); assert_eq!(failed_event.len(), 1); let expected_execution_error = ExecutionError { - abort_location: "0000000000000000000000000000000000000000000000000000000000000001::automation_registry".to_string(), + abort_location: + "0000000000000000000000000000000000000000000000000000000000000001::automation_registry" + .to_string(), error_type: "MoveAbort".to_string(), error_code: 41, }; @@ -1047,7 +1031,6 @@ fn check_system_automation_task_registration() { }; assert_eq!(expected_execution_error, failed_event[0].execution_error); - // Try without multisig payload specified let proposal_txn = test_context.create_system_automation_task_registration_proposal(7, &multisig); diff --git a/aptos-move/e2e-testsuite/src/tests/genesis_initializations.rs b/aptos-move/e2e-testsuite/src/tests/genesis_initializations.rs index c8b33d98a23..35900083066 100644 --- a/aptos-move/e2e-testsuite/src/tests/genesis_initializations.rs +++ b/aptos-move/e2e-testsuite/src/tests/genesis_initializations.rs @@ -20,7 +20,10 @@ fn test_timestamp_time_has_started() { "timestamp", "set_time_has_started", vec![], - serialize_values(&vec![MoveValue::Signer(account_address), MoveValue::U64(12)]), + serialize_values(&vec![ + MoveValue::Signer(account_address), + MoveValue::U64(12), + ]), ); println!("{:?}", output); assert_eq!(output.unwrap_err().move_abort_code(), Some(327683)); @@ -29,7 +32,10 @@ fn test_timestamp_time_has_started() { "timestamp", "set_time_has_started", vec![], - serialize_values(&vec![MoveValue::Signer(CORE_CODE_ADDRESS), MoveValue::U64(12)]), + serialize_values(&vec![ + MoveValue::Signer(CORE_CODE_ADDRESS), + MoveValue::U64(12), + ]), ); } diff --git a/aptos-move/e2e-testsuite/src/tests/mod.rs b/aptos-move/e2e-testsuite/src/tests/mod.rs index ccf3b1ad3db..3740847ae73 100644 --- a/aptos-move/e2e-testsuite/src/tests/mod.rs +++ b/aptos-move/e2e-testsuite/src/tests/mod.rs @@ -13,6 +13,8 @@ //! Set env REGENERATE_GOLDENFILES to update the golden files when running tests.. mod account_universe; +mod automated_transactions; +mod automation_registration; mod create_account; mod data_store; mod execution_strategies; @@ -26,6 +28,4 @@ mod peer_to_peer; mod scripts; mod transaction_fuzzer; mod verify_txn; -mod automation_registration; -mod automated_transactions; mod vm_viewer; diff --git a/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs b/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs index 1209722c90a..7f5b7ea6a58 100644 --- a/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs +++ b/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs @@ -1,20 +1,29 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 use aptos_language_e2e_tests::executor::FakeExecutor; -use aptos_types::move_utils::MemberId; -use aptos_types::transaction::{ViewFunction, ViewFunctionOutput}; +use aptos_logger::debug; +use aptos_types::{ + move_utils::MemberId, + transaction::{ViewFunction, ViewFunctionOutput}, +}; use aptos_vm::aptos_vm_viewer::AptosVMViewer; use move_core_types::language_storage::TypeTag; use std::time::Instant; -use aptos_logger::debug; const TIMESTAMP_NOW_SECONDS: &str = "0x1::timestamp::now_seconds"; const ACCOUNT_BALANCE: &str = "0x1::coin::balance"; const ACCOUNT_SEQ_NUM: &str = "0x1::account::get_sequence_number"; const SUPRA_COIN: &str = "0x1::supra_coin::SupraCoin"; -pub(crate) fn to_view_function(fn_ref: MemberId, ty_args: Vec, args: Vec>) -> ViewFunction { +pub(crate) fn to_view_function( + fn_ref: MemberId, + ty_args: Vec, + args: Vec>, +) -> ViewFunction { ViewFunction::new(fn_ref.module_id, fn_ref.member_id, ty_args, args) } @@ -73,7 +82,10 @@ fn test_vm_viewer() { let viewer_ifc_time = Instant::now(); let time = Instant::now(); let vm_viewer = AptosVMViewer::new(test_executor.data_store()); - debug!("AptosVMViewer creation time: {}", time.elapsed().as_secs_f64()); + debug!( + "AptosVMViewer creation time: {}", + time.elapsed().as_secs_f64() + ); let actual_results = accounts .iter() .map(|account| { diff --git a/aptos-move/framework/Cargo.toml b/aptos-move/framework/Cargo.toml index 261d7ec9a99..b457b1be835 100644 --- a/aptos-move/framework/Cargo.toml +++ b/aptos-move/framework/Cargo.toml @@ -43,6 +43,7 @@ codespan-reporting = { workspace = true } # is because the `dalek-cryptography/bulletproofs` works with version 2 of `dalek-cryptography/curve25519-dalek` and # we work with version 3. Instead, we use `zkcrypto/bulleproofs` which relies on `zkcrypto/curve25519-dalek-ng`. curve25519-dalek = { package = "curve25519-dalek-ng", version = "4" } +crypto = { workspace = true } either = { workspace = true } eth_trie = { workspace = true } flate2 = { workspace = true } diff --git a/aptos-move/framework/aptos-stdlib/Move.toml b/aptos-move/framework/aptos-stdlib/Move.toml index 1a58e9243fb..889da54293f 100644 --- a/aptos-move/framework/aptos-stdlib/Move.toml +++ b/aptos-move/framework/aptos-stdlib/Move.toml @@ -6,7 +6,7 @@ version = "1.0.0" std = "0x1" aptos_std = "0x1" supra_framework = "0x1" -Extensions = "0x1" # For Prover to instantiate `{{Ext}}` in prelude. +Extensions = "0x1" # For Prover to instantiate `{{Ext}}` in prelude. [dependencies] MoveStdlib = { local = "../move-stdlib" } diff --git a/aptos-move/framework/aptos-stdlib/sources/any.move b/aptos-move/framework/aptos-stdlib/sources/any.move index 2d778d4300e..88b9f4dd780 100644 --- a/aptos-move/framework/aptos-stdlib/sources/any.move +++ b/aptos-move/framework/aptos-stdlib/sources/any.move @@ -62,4 +62,4 @@ module aptos_std::any { assert!(unpack(pack(22)) == 22, 1); assert!(unpack(pack(S { x: 22 })) == S { x: 22 }, 2); } -} +} \ No newline at end of file diff --git a/aptos-move/framework/aptos-token-objects/Move.toml b/aptos-move/framework/aptos-token-objects/Move.toml index b19f4e4cad9..d5f24a3cdb7 100644 --- a/aptos-move/framework/aptos-token-objects/Move.toml +++ b/aptos-move/framework/aptos-token-objects/Move.toml @@ -10,4 +10,4 @@ aptos_token_objects = "0x4" [dependencies] MoveStdlib = { local = "../move-stdlib" } -SupraFramework = { local = "../supra-framework"} +SupraFramework = { local = "../supra-framework" } diff --git a/aptos-move/framework/aptos-token/Move.toml b/aptos-move/framework/aptos-token/Move.toml index deba7e4b55a..454d3eb0b82 100644 --- a/aptos-move/framework/aptos-token/Move.toml +++ b/aptos-move/framework/aptos-token/Move.toml @@ -9,4 +9,4 @@ aptos_token = "0x3" [dependencies] MoveStdlib = { local = "../move-stdlib" } -SupraFramework = { local = "../supra-framework"} +SupraFramework = { local = "../supra-framework" } diff --git a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs index 56e348c4b75..6021de2c273 100644 --- a/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs +++ b/aptos-move/framework/cached-packages/src/aptos_framework_sdk_builder.rs @@ -1007,7 +1007,7 @@ pub enum EntryFunctionCall { }, /// Change epoch immediately. - /// If `RECONFIGURE_WITH_DKG` is enabled and we are in the middle of a DKG, + /// If `SUPRA_DKG` is enabled and we are in the middle of a DKG, /// stop waiting for DKG and enter the new epoch without randomness. /// /// WARNING: currently only used by tests. In most cases you should use `reconfigure()` instead. @@ -1021,12 +1021,12 @@ pub enum EntryFunctionCall { /// Manually reconfigure. Called at the end of a governance txn that alters on-chain configs. /// /// WARNING: this function always ensures a reconfiguration starts, but when the reconfiguration finishes depends. - /// - If feature `RECONFIGURE_WITH_DKG` is disabled, it finishes immediately. + /// - If feature `SUPRA_DKG` is disabled, it finishes immediately. /// - At the end of the calling transaction, we will be in a new epoch. - /// - If feature `RECONFIGURE_WITH_DKG` is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes. + /// - If feature `SUPRA_DKG` is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes. /// /// This behavior affects when an update of an on-chain config (e.g. `ConsensusConfig`, `Features`) takes effect, - /// since such updates are applied whenever we enter an new epoch. + /// since such updates are applied whenever we enter a new epoch. SupraGovernanceReconfigure {}, /// Create a single-step proposal with the backing `stake_pool`. @@ -4932,7 +4932,7 @@ pub fn supra_governance_add_supra_approved_script_hash_script( } /// Change epoch immediately. -/// If `RECONFIGURE_WITH_DKG` is enabled and we are in the middle of a DKG, +/// If `SUPRA_DKG` is enabled and we are in the middle of a DKG, /// stop waiting for DKG and enter the new epoch without randomness. /// /// WARNING: currently only used by tests. In most cases you should use `reconfigure()` instead. @@ -4972,12 +4972,12 @@ pub fn supra_governance_force_end_epoch_test_only() -> TransactionPayload { /// Manually reconfigure. Called at the end of a governance txn that alters on-chain configs. /// /// WARNING: this function always ensures a reconfiguration starts, but when the reconfiguration finishes depends. -/// - If feature `RECONFIGURE_WITH_DKG` is disabled, it finishes immediately. +/// - If feature `SUPRA_DKG` is disabled, it finishes immediately. /// - At the end of the calling transaction, we will be in a new epoch. -/// - If feature `RECONFIGURE_WITH_DKG` is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes. +/// - If feature `SUPRA_DKG` is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes. /// /// This behavior affects when an update of an on-chain config (e.g. `ConsensusConfig`, `Features`) takes effect, -/// since such updates are applied whenever we enter an new epoch. +/// since such updates are applied whenever we enter a new epoch. pub fn supra_governance_reconfigure() -> TransactionPayload { TransactionPayload::EntryFunction(EntryFunction::new( ModuleId::new( diff --git a/aptos-move/framework/move-stdlib/Cargo.toml b/aptos-move/framework/move-stdlib/Cargo.toml index e02f9290530..9fe073eeeec 100644 --- a/aptos-move/framework/move-stdlib/Cargo.toml +++ b/aptos-move/framework/move-stdlib/Cargo.toml @@ -29,4 +29,4 @@ move-unit-test = { path = "../../../third_party/move/tools/move-unit-test" } tempfile = "3.2.0" [features] -testing = [] \ No newline at end of file +testing = [] diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md index 55d8e15c2a9..d1044ad9144 100644 --- a/aptos-move/framework/move-stdlib/doc/features.md +++ b/aptos-move/framework/move-stdlib/doc/features.md @@ -147,6 +147,14 @@ return true. - [Function `supra_delegation_pool_identity_enabled`](#0x1_features_supra_delegation_pool_identity_enabled) - [Function `get_supra_automation_v2_feature`](#0x1_features_get_supra_automation_v2_feature) - [Function `supra_automation_v2_enabled`](#0x1_features_supra_automation_v2_enabled) +- [Function `get_supra_validator_identity_v2_feature`](#0x1_features_get_supra_validator_identity_v2_feature) +- [Function `supra_validator_identity_v2_enabled`](#0x1_features_supra_validator_identity_v2_enabled) +- [Function `get_supra_bcft_certificates_feature`](#0x1_features_get_supra_bcft_certificates_feature) +- [Function `supra_bcft_certificates_enabled`](#0x1_features_supra_bcft_certificates_enabled) +- [Function `get_supra_dkg_feature`](#0x1_features_get_supra_dkg_feature) +- [Function `supra_dkg_enabled`](#0x1_features_supra_dkg_enabled) +- [Function `get_supra_transactions_inclusion_proofs_feature`](#0x1_features_get_supra_transactions_inclusion_proofs_feature) +- [Function `supra_transactions_inclusion_proofs_enabled`](#0x1_features_supra_transactions_inclusion_proofs_enabled) - [Function `change_feature_flags`](#0x1_features_change_feature_flags) - [Function `change_feature_flags_internal`](#0x1_features_change_feature_flags_internal) - [Function `change_feature_flags_for_next_epoch`](#0x1_features_change_feature_flags_for_next_epoch) @@ -924,6 +932,31 @@ Lifetime: transient + + +Whether BCFT certificate thresholds are enabled. + +Lifetime: permanent + + +
const SUPRA_BCFT_CERTIFICATES: u64 = 98;
+
+ + + + + +Whether the functionality related to the new validator identity representation is enabled. +This flag should only be enabled after all Validators have updated their keys to the new format, including the BLS keys. + +Lifetime: permanent + + +
const SUPRA_BLS_KEYS: u64 = 97;
+
+ + + Whether the automation task sync on block basis is enabled. @@ -946,6 +979,20 @@ Lifetime: permanent + + +Whether the APIs related to the DKG feature are enabled. SUPRA_BLS_KEYS must be enabled first, +as the new validator identity format is a prerequisite for the DKG. The default DKG configuration +also requires SUPRA_BCFT_CERTIFICATES to be enabled first. + +Lifetime: transient + + +
const SUPRA_DKG: u64 = 99;
+
+ + + Whether the APIs related to the eth_trie feature are enabled. @@ -983,6 +1030,18 @@ Lifetime: transient + + +Whether transactions inclusion proofs are enabled. + +Lifetime: permanent + + +
const SUPRA_TRANSACTIONS_INCLUSION_PROOFS: u64 = 100;
+
+ + + Whether the transaction context extension is enabled. This feature allows the module @@ -3793,6 +3852,198 @@ Lifetime: transient + + + + +## Function `get_supra_validator_identity_v2_feature` + + + +
public fun get_supra_validator_identity_v2_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_supra_validator_identity_v2_feature(): u64 {
+    SUPRA_BLS_KEYS
+}
+
+ + + +
+ + + +## Function `supra_validator_identity_v2_enabled` + + + +
public fun supra_validator_identity_v2_enabled(): bool
+
+ + + +
+Implementation + + +
public fun supra_validator_identity_v2_enabled(): bool acquires Features {
+    is_enabled(SUPRA_BLS_KEYS)
+}
+
+ + + +
+ + + +## Function `get_supra_bcft_certificates_feature` + + + +
public fun get_supra_bcft_certificates_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_supra_bcft_certificates_feature(): u64 {
+    SUPRA_BCFT_CERTIFICATES
+}
+
+ + + +
+ + + +## Function `supra_bcft_certificates_enabled` + + + +
public fun supra_bcft_certificates_enabled(): bool
+
+ + + +
+Implementation + + +
public fun supra_bcft_certificates_enabled(): bool acquires Features {
+    is_enabled(SUPRA_BCFT_CERTIFICATES)
+}
+
+ + + +
+ + + +## Function `get_supra_dkg_feature` + + + +
public fun get_supra_dkg_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_supra_dkg_feature(): u64 {
+    SUPRA_DKG
+}
+
+ + + +
+ + + +## Function `supra_dkg_enabled` + + + +
public fun supra_dkg_enabled(): bool
+
+ + + +
+Implementation + + +
public fun supra_dkg_enabled(): bool acquires Features {
+    is_enabled(SUPRA_DKG)
+}
+
+ + + +
+ + + +## Function `get_supra_transactions_inclusion_proofs_feature` + + + +
public fun get_supra_transactions_inclusion_proofs_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_supra_transactions_inclusion_proofs_feature(): u64 {
+    SUPRA_TRANSACTIONS_INCLUSION_PROOFS
+}
+
+ + + +
+ + + +## Function `supra_transactions_inclusion_proofs_enabled` + + + +
public fun supra_transactions_inclusion_proofs_enabled(): bool
+
+ + + +
+Implementation + + +
public fun supra_transactions_inclusion_proofs_enabled(): bool acquires Features {
+    is_enabled(SUPRA_TRANSACTIONS_INCLUSION_PROOFS)
+}
+
+ + +
diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.move b/aptos-move/framework/move-stdlib/sources/configs/features.move index a47728b2992..811e68ec897 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.move @@ -784,6 +784,61 @@ module std::features { is_enabled(SUPRA_AUTOMATION_V2) } + /// Whether the functionality related to the new validator identity representation is enabled. + /// This flag should only be enabled after all Validators have updated their keys to the new format, including the BLS keys. + /// + /// Lifetime: permanent + const SUPRA_BLS_KEYS: u64 = 97; + + public fun get_supra_validator_identity_v2_feature(): u64 { + SUPRA_BLS_KEYS + } + + public fun supra_validator_identity_v2_enabled(): bool acquires Features { + is_enabled(SUPRA_BLS_KEYS) + } + + /// Whether BCFT certificate thresholds are enabled. + /// + /// Lifetime: permanent + const SUPRA_BCFT_CERTIFICATES: u64 = 98; + + public fun get_supra_bcft_certificates_feature(): u64 { + SUPRA_BCFT_CERTIFICATES + } + + public fun supra_bcft_certificates_enabled(): bool acquires Features { + is_enabled(SUPRA_BCFT_CERTIFICATES) + } + + /// Whether the APIs related to the DKG feature are enabled. `SUPRA_BLS_KEYS` must be enabled first, + /// as the new validator identity format is a prerequisite for the DKG. The default DKG configuration + /// also requires `SUPRA_BCFT_CERTIFICATES` to be enabled first. + /// + /// Lifetime: transient + const SUPRA_DKG: u64 = 99; + + public fun get_supra_dkg_feature(): u64 { + SUPRA_DKG + } + + public fun supra_dkg_enabled(): bool acquires Features { + is_enabled(SUPRA_DKG) + } + + /// Whether transactions inclusion proofs are enabled. + /// + /// Lifetime: permanent + const SUPRA_TRANSACTIONS_INCLUSION_PROOFS: u64 = 100; + + public fun get_supra_transactions_inclusion_proofs_feature(): u64 { + SUPRA_TRANSACTIONS_INCLUSION_PROOFS + } + + public fun supra_transactions_inclusion_proofs_enabled(): bool acquires Features { + is_enabled(SUPRA_TRANSACTIONS_INCLUSION_PROOFS) + } + // ============================================================================================ // Feature Flag Implementation diff --git a/aptos-move/framework/src/natives/automation_registry_callbacks.rs b/aptos-move/framework/src/natives/automation_registry_callbacks.rs index 3daa57f9357..462756d9fd1 100644 --- a/aptos-move/framework/src/natives/automation_registry_callbacks.rs +++ b/aptos-move/framework/src/natives/automation_registry_callbacks.rs @@ -1,16 +1,13 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2025 Supra. // SPDX-License-Identifier: Apache-2.0 -use aptos_native_interface::{ - SafeNativeBuilder, SafeNativeContext, SafeNativeResult, -}; +use aptos_native_interface::{SafeNativeBuilder, SafeNativeContext, SafeNativeResult}; use move_vm_runtime::native_functions::NativeFunction; -use move_vm_types::{ - loaded_data::runtime_types::Type, - values::{Value}, -}; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; use smallvec::{smallvec, SmallVec}; -use std::{collections::VecDeque}; - +use std::collections::VecDeque; /*************************************************************************************************** * native fun to check whether the binary has been updated which supports automation registry @@ -36,9 +33,10 @@ fn native_automation_cycle_management_support( pub fn make_all( builder: &SafeNativeBuilder, ) -> impl Iterator + '_ { - let natives = [ - ("native_automation_cycle_management_support", native_automation_cycle_management_support), - ]; + let natives = [( + "native_automation_cycle_management_support", + native_automation_cycle_management_support, + )]; builder.make_named_natives(natives) } diff --git a/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs b/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs index 882534c3fb1..01530e3accc 100644 --- a/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs +++ b/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs @@ -1,24 +1,24 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. +use crate::natives::cryptography::bulletproofs::abort_codes; use aptos_crypto::bulletproofs::MAX_RANGE_BITS; use aptos_gas_schedule::gas_params::natives::aptos_framework::*; use aptos_native_interface::{ safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError, SafeNativeResult, }; +use blsttc::G1Projective; use bulletproofs_bls12381::{BulletproofGens, PedersenGens, RangeProof}; use merlin::Transcript; use move_core_types::gas_algebra::{NumArgs, NumBytes}; use move_vm_runtime::native_functions::NativeFunction; -use move_vm_types::{ - loaded_data::runtime_types::Type, - values::{Value}, -}; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; use once_cell::sync::Lazy; use smallvec::{smallvec, SmallVec}; use std::collections::VecDeque; -use blsttc::G1Projective; -use crate::natives::cryptography::bulletproofs::abort_codes; /// The Bulletproofs library only seems to support proving [0, 2^{num_bits}) ranges where num_bits is /// either 8, 16, 32 or 64. @@ -30,9 +30,7 @@ fn deserialize_g1(vec: Vec) -> Result { if vec.len() != 48 { return Err(()); } - let array: [u8; 48] = vec - .try_into() - .map_err(|_| ())?; + let array: [u8; 48] = vec.try_into().map_err(|_| ())?; let g1_option = G1Projective::from_compressed(&array); @@ -73,7 +71,6 @@ fn native_verify_range_proof( })?; let pg = { - let rand_base = deserialize_g1(rand_base_bytes).map_err(|_| SafeNativeError::Abort { abort_code: abort_codes::NFE_DESERIALIZE_RANGE_PROOF, })?; @@ -107,7 +104,7 @@ fn verify_range_proof( context.charge( BULLETPROOFS_BASE + BULLETPROOFS_PER_BYTE_RANGEPROOF_DESERIALIZE - * NumBytes::new(proof_bytes.len() as u64), + * NumBytes::new(proof_bytes.len() as u64), )?; let range_proof = match RangeProof::from_bytes(proof_bytes) { diff --git a/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs b/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs index 2ba8948b0f9..1a544baa646 100644 --- a/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs +++ b/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs @@ -1,16 +1,21 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. -use std::collections::VecDeque; -use smallvec::{smallvec, SmallVec}; +use aptos_gas_schedule::gas_params::natives::aptos_framework::{ + HASH_KECCAK256_BASE, HASH_KECCAK256_PER_BYTE, +}; +use aptos_native_interface::{ + safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult, +}; use blst::blst_scalar; -use aptos_gas_schedule::gas_params::natives::aptos_framework::{HASH_KECCAK256_BASE, HASH_KECCAK256_PER_BYTE}; -use aptos_native_interface::{safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult}; -use move_core_types::gas_algebra::{NumBytes}; +use blsttc::{group::ff::Field, Fr}; +use move_core_types::gas_algebra::NumBytes; use move_vm_runtime::native_functions::NativeFunction; -use move_vm_types::loaded_data::runtime_types::Type; -use move_vm_types::values::Value; -use blsttc::Fr; -use blsttc::group::ff::Field; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; +use smallvec::{smallvec, SmallVec}; +use std::collections::VecDeque; /// Native function for computing hash to scalar for BLS12-381. /// @@ -27,25 +32,23 @@ fn native_hash_to_scalar( _ty_args: Vec, mut arguments: VecDeque, ) -> SafeNativeResult> { - let msg: Vec = safely_pop_arg!(arguments, Vec); let dst: Vec = safely_pop_arg!(arguments, Vec); let cost = HASH_KECCAK256_BASE - + HASH_KECCAK256_PER_BYTE * (NumBytes::new(msg.len() as u64) + NumBytes::new(dst.len() as u64)); + + HASH_KECCAK256_PER_BYTE + * (NumBytes::new(msg.len() as u64) + NumBytes::new(dst.len() as u64)); context.charge(cost)?; let scalar_fr: Fr; - if let Some(scalar) = blst_scalar::hash_to(&msg, &dst){ - if let Ok(fr_scalar) = scalar.try_into(){ + if let Some(scalar) = blst_scalar::hash_to(&msg, &dst) { + if let Ok(fr_scalar) = scalar.try_into() { scalar_fr = fr_scalar; - } - else { + } else { scalar_fr = Fr::zero(); } - } - else { + } else { scalar_fr = Fr::zero(); } @@ -57,12 +60,10 @@ pub fn make_all( ) -> impl Iterator + '_ { let mut natives = vec![]; - natives.extend([ - ( - "native_hash_to_scalar", - native_hash_to_scalar as RawSafeNative, - ), - ]); + natives.extend([( + "native_hash_to_scalar", + native_hash_to_scalar as RawSafeNative, + )]); builder.make_named_natives(natives) } diff --git a/aptos-move/framework/src/natives/cryptography/class_groups.rs b/aptos-move/framework/src/natives/cryptography/class_groups.rs new file mode 100644 index 00000000000..fafeae1360e --- /dev/null +++ b/aptos-move/framework/src/natives/cryptography/class_groups.rs @@ -0,0 +1,78 @@ +// Copyright (c) 2025 Supra. + +/*************************************************************************************************** + * native fun class_group_validate_pubkey + * + * gas cost: per_pubkey_deserialize_cost + pop_proof_validation + * + * where +? indicates that the expression stops evaluating there if the previous gas-charging step + * failed + **************************************************************************************************/ +use aptos_gas_schedule::gas_params::natives::supra_stdlib::{ + CLASS_GROUPS_PER_PUBKEY_DESERIALIZE, CLASS_GROUPS_POP, +}; +use aptos_native_interface::{ + safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult, +}; +#[cfg(feature = "testing")] +use crypto::bls12381::cl_utils::rng; +use move_core_types::gas_algebra::NumArgs; +use move_vm_runtime::native_functions::NativeFunction; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; +use smallvec::{smallvec, SmallVec}; +use std::collections::VecDeque; + +fn native_class_group_validate_pubkey( + context: &mut SafeNativeContext, + _ty_args: Vec, + mut arguments: VecDeque, +) -> SafeNativeResult> { + debug_assert!(_ty_args.is_empty()); + debug_assert!(arguments.len() == 1); + + context.charge(CLASS_GROUPS_PER_PUBKEY_DESERIALIZE * NumArgs::one())?; + context.charge(CLASS_GROUPS_POP)?; + + let pk_bytes = safely_pop_arg!(arguments, Vec); + match crypto::cg_public_key::CGEncryptionKeyBls12381::try_from(pk_bytes.as_slice()) { + Ok(_) => Ok(smallvec![Value::bool(true)]), + Err(_) => Ok(smallvec![Value::bool(false)]), + } +} + +#[cfg(feature = "testing")] +pub fn native_generate_keys( + _context: &mut SafeNativeContext, + _ty_args: Vec, + _arguments: VecDeque, +) -> SafeNativeResult> { + let (sk, pk) = crypto::bls12381::cg_encryption::keygen(&mut rng(), &vec![]).unwrap(); + + Ok(smallvec![ + Value::vector_u8(bcs::to_bytes(&sk).unwrap()), + Value::vector_u8(pk.to_vec()), + ]) +} + +/*************************************************************************************************** + * module + * + **************************************************************************************************/ +pub fn make_all( + builder: &SafeNativeBuilder, +) -> impl Iterator + '_ { + let mut natives = vec![]; + + natives.extend([( + "validate_pubkey_internal", + native_class_group_validate_pubkey as RawSafeNative, + )]); + + #[cfg(feature = "testing")] + natives.append(&mut vec![( + "generate_keys_internal", + native_generate_keys as RawSafeNative, + )]); + + builder.make_named_natives(natives) +} diff --git a/aptos-move/framework/src/natives/cryptography/eth_trie.rs b/aptos-move/framework/src/natives/cryptography/eth_trie.rs index 96c14893035..6dc32154c90 100644 --- a/aptos-move/framework/src/natives/cryptography/eth_trie.rs +++ b/aptos-move/framework/src/natives/cryptography/eth_trie.rs @@ -1,19 +1,25 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. -use std::collections::VecDeque; -use std::sync::Arc; +use aptos_gas_schedule::gas_params::natives::aptos_framework::{ + ETH_TRIE_PROOF_BASE, ETH_TRIE_PROOF_DECODE_BASE, ETH_TRIE_PROOF_DECODE_PER_BYTE, + ETH_TRIE_PROOF_HASH_BASE, ETH_TRIE_PROOF_HASH_PER_BYTE, +}; +use aptos_native_interface::{ + safely_pop_arg, safely_pop_vec_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, + SafeNativeResult, +}; +use eth_trie::{EthTrie, MemoryDB, Trie, DB}; use keccak_hash::{keccak, H256}; -use move_vm_types::values::Value; -use move_vm_types::loaded_data::runtime_types::Type; -use eth_trie::{EthTrie, Trie, DB}; -use eth_trie::MemoryDB; -use smallvec::{smallvec, SmallVec}; use move_core_types::gas_algebra::{NumArgs, NumBytes}; use move_vm_runtime::native_functions::NativeFunction; -use aptos_native_interface::{safely_pop_arg, safely_pop_vec_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult}; -use aptos_gas_schedule::gas_params::natives::aptos_framework::{ETH_TRIE_PROOF_BASE, ETH_TRIE_PROOF_DECODE_BASE, ETH_TRIE_PROOF_DECODE_PER_BYTE, ETH_TRIE_PROOF_HASH_BASE, ETH_TRIE_PROOF_HASH_PER_BYTE}; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; #[cfg(feature = "testing")] use rand::Rng; +use smallvec::{smallvec, SmallVec}; +use std::{collections::VecDeque, sync::Arc}; /// The minimum length (in bytes) for an encoded node to be stored by hash. const HASHED_LENGTH: usize = 32; @@ -45,8 +51,10 @@ pub fn native_verify_proof_eth_trie( let total_proof_bytes = proof.iter().map(|node| node.len() as u64).sum::(); context.charge( - (ETH_TRIE_PROOF_HASH_BASE + ETH_TRIE_PROOF_DECODE_BASE) * NumArgs::new(proof.len() as u64) + - (ETH_TRIE_PROOF_HASH_PER_BYTE + ETH_TRIE_PROOF_DECODE_PER_BYTE) * NumBytes::new(total_proof_bytes))?; + (ETH_TRIE_PROOF_HASH_BASE + ETH_TRIE_PROOF_DECODE_BASE) * NumArgs::new(proof.len() as u64) + + (ETH_TRIE_PROOF_HASH_PER_BYTE + ETH_TRIE_PROOF_DECODE_PER_BYTE) + * NumBytes::new(total_proof_bytes), + )?; // Convert the root (a Vec) into a H256 hash. let root_hash = H256::from_slice(&root); @@ -155,12 +163,10 @@ pub fn make_all( native_generate_random_trie as RawSafeNative, )]); - natives.extend([ - ( - "native_verify_proof_eth_trie", - native_verify_proof_eth_trie as RawSafeNative, - ), - ]); + natives.extend([( + "native_verify_proof_eth_trie", + native_verify_proof_eth_trie as RawSafeNative, + )]); builder.make_named_natives(natives) } diff --git a/aptos-move/framework/src/natives/cryptography/mod.rs b/aptos-move/framework/src/natives/cryptography/mod.rs index 5231d4bdba0..c1dd6e64fed 100644 --- a/aptos-move/framework/src/natives/cryptography/mod.rs +++ b/aptos-move/framework/src/natives/cryptography/mod.rs @@ -3,14 +3,15 @@ pub mod algebra; pub mod bls12381; +pub mod bls12381_bulletproofs; +pub mod bls12381_scalar; pub mod bulletproofs; +pub mod class_groups; pub mod ed25519; +pub mod eth_trie; mod helpers; pub mod multi_ed25519; pub mod ristretto255; pub mod ristretto255_point; pub mod ristretto255_scalar; pub mod secp256k1; -pub mod eth_trie; -pub mod bls12381_scalar; -pub mod bls12381_bulletproofs; diff --git a/aptos-move/framework/src/natives/mod.rs b/aptos-move/framework/src/natives/mod.rs index 83802f992d7..3e25412b8b0 100644 --- a/aptos-move/framework/src/natives/mod.rs +++ b/aptos-move/framework/src/natives/mod.rs @@ -4,6 +4,7 @@ pub mod account; pub mod aggregator_natives; +mod automation_registry_callbacks; pub mod code; pub mod consensus_config; pub mod create_signer; @@ -16,13 +17,12 @@ pub mod hash; pub mod object; pub mod object_code_deployment; pub mod randomness; +pub mod rlp; pub mod state_storage; pub mod string_utils; pub mod transaction_context; pub mod type_info; pub mod util; -pub mod rlp; -mod automation_registry_callbacks; pub mod vector_utils; use crate::natives::cryptography::multi_ed25519; @@ -60,7 +60,10 @@ pub fn all_natives( add_natives_from_module!("genesis", create_signer::make_all(builder)); add_natives_from_module!("multi_ed25519", multi_ed25519::make_all(builder)); add_natives_from_module!("bls12381", cryptography::bls12381::make_all(builder)); - add_natives_from_module!("bls12381_scalar", cryptography::bls12381_scalar::make_all(builder)); + add_natives_from_module!( + "bls12381_scalar", + cryptography::bls12381_scalar::make_all(builder) + ); add_natives_from_module!("eth_trie", cryptography::eth_trie::make_all(builder)); add_natives_from_module!("secp256k1", cryptography::secp256k1::make_all(builder)); add_natives_from_module!("aptos_hash", hash::make_all(builder)); @@ -80,6 +83,10 @@ pub fn all_natives( "bls12381_bulletproofs", cryptography::bls12381_bulletproofs::make_all(builder) ); + add_natives_from_module!( + "class_groups", + cryptography::class_groups::make_all(builder) + ); add_natives_from_module!( "transaction_context", transaction_context::make_all(builder) @@ -100,7 +107,10 @@ pub fn all_natives( dispatchable_fungible_asset::make_all(builder) ); add_natives_from_module!("rlp", rlp::make_all(builder)); - add_natives_from_module!("automation_registry", automation_registry_callbacks::make_all(builder)); + add_natives_from_module!( + "automation_registry", + automation_registry_callbacks::make_all(builder) + ); add_natives_from_module!("vector_utils", vector_utils::make_all(builder)); make_table_from_iter(framework_addr, natives) diff --git a/aptos-move/framework/src/natives/rlp.rs b/aptos-move/framework/src/natives/rlp.rs index edf1881076c..413bb9cf867 100644 --- a/aptos-move/framework/src/natives/rlp.rs +++ b/aptos-move/framework/src/natives/rlp.rs @@ -1,17 +1,24 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. -use std::collections::VecDeque; +use aptos_gas_schedule::gas_params::natives::aptos_framework::{ + RLP_ENCODE_DECODE_BASE, RLP_ENCODE_DECODE_PER_BYTE, UTIL_FROM_BYTES_BASE, + UTIL_FROM_BYTES_PER_BYTE, +}; +use aptos_native_interface::{ + safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError, + SafeNativeResult, +}; use ark_std::iterable::Iterable; use keccak_hash::H256; +use move_core_types::{account_address::AccountAddress, gas_algebra::NumBytes}; +use move_vm_runtime::native_functions::NativeFunction; +use move_vm_types::{loaded_data::runtime_types::Type, values::Value}; use rlp::Rlp; use smallvec::{smallvec, SmallVec}; -use aptos_gas_schedule::gas_params::natives::aptos_framework::{RLP_ENCODE_DECODE_BASE, RLP_ENCODE_DECODE_PER_BYTE, UTIL_FROM_BYTES_BASE, UTIL_FROM_BYTES_PER_BYTE}; -use aptos_native_interface::{safely_pop_arg, RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeError, SafeNativeResult}; -use move_core_types::account_address::AccountAddress; -use move_core_types::gas_algebra::{NumBytes}; -use move_vm_runtime::native_functions::NativeFunction; -use move_vm_types::loaded_data::runtime_types::Type; -use move_vm_types::values::Value; +use std::collections::VecDeque; const E_DECODE_FAILURE: u64 = 0x1; const E_INVALID_TYPE_ARG: u64 = 0x2; @@ -24,8 +31,7 @@ macro_rules! rlp_encode_scalar { ($context:expr, $args:ident, $rust_ty:ty, $num_bytes:expr) => {{ let x: $rust_ty = safely_pop_arg!($args, $rust_ty); $context.charge( - RLP_ENCODE_DECODE_BASE + - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new($num_bytes) + RLP_ENCODE_DECODE_BASE + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new($num_bytes), )?; let encoded_data = rlp::encode(&x).to_vec(); Ok(smallvec![Value::vector_u8(encoded_data)]) @@ -39,8 +45,8 @@ macro_rules! rlp_decode_scalar { let encoded_data: Vec = safely_pop_arg!($args, Vec); // Gas charge $context.charge( - RLP_ENCODE_DECODE_BASE + - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64) + RLP_ENCODE_DECODE_BASE + + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64), )?; // RLP decode match rlp::decode::<$rust_ty>(&encoded_data) { @@ -57,7 +63,11 @@ macro_rules! rlp_encode_list { ($data:expr, $rust_ty:ty, $err_code:expr) => {{ let vec_t: Vec<$rust_ty> = match bcs::from_bytes(&$data) { Ok(val) => val, - Err(_) => return Err(SafeNativeError::Abort { abort_code: $err_code }), + Err(_) => { + return Err(SafeNativeError::Abort { + abort_code: $err_code, + }) + }, }; let encoded = rlp::encode_list(&vec_t).to_vec(); Ok(smallvec![Value::vector_u8(encoded)]) @@ -69,7 +79,9 @@ macro_rules! rlp_decode_list { ($rlp:expr, $rust_ty:ty, $build_value_fn:expr, $err_code:expr) => {{ match $rlp.as_list::<$rust_ty>() { Ok(decoded) => Ok(smallvec![$build_value_fn(decoded)]), - Err(_) => Err(SafeNativeError::Abort { abort_code: $err_code }), + Err(_) => Err(SafeNativeError::Abort { + abort_code: $err_code, + }), } }}; } @@ -86,33 +98,34 @@ fn native_rlp_encode( ty_args: Vec, mut args: VecDeque, ) -> SafeNativeResult> { - if ty_args.len() != 1 { - return Err(SafeNativeError::Abort { abort_code: E_INVALID_TYPE_ARG }); + return Err(SafeNativeError::Abort { + abort_code: E_INVALID_TYPE_ARG, + }); } let inner_ty = &ty_args[0]; match inner_ty { - Type::Bool => rlp_encode_scalar!(context, args, bool, 1), - Type::U8 => rlp_encode_scalar!(context, args, u8, 1), - Type::U16 => rlp_encode_scalar!(context, args, u16, 2), - Type::U32 => rlp_encode_scalar!(context, args, u32, 4), - Type::U64 => rlp_encode_scalar!(context, args, u64, 8), - Type::U128 => rlp_encode_scalar!(context, args, u128, 16), + Type::Bool => rlp_encode_scalar!(context, args, bool, 1), + Type::U8 => rlp_encode_scalar!(context, args, u8, 1), + Type::U16 => rlp_encode_scalar!(context, args, u16, 2), + Type::U32 => rlp_encode_scalar!(context, args, u32, 4), + Type::U64 => rlp_encode_scalar!(context, args, u64, 8), + Type::U128 => rlp_encode_scalar!(context, args, u128, 16), // address is custom Type::Address => { let addr: AccountAddress = safely_pop_arg!(args, AccountAddress); let addr_bytes = addr.into_bytes(); context.charge( - RLP_ENCODE_DECODE_BASE + - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(addr_bytes.len() as u64) + RLP_ENCODE_DECODE_BASE + + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(addr_bytes.len() as u64), )?; let addr = H256::from(addr_bytes); let encoded_data = rlp::encode(&addr).to_vec(); Ok(smallvec![Value::vector_u8(encoded_data)]) - } + }, // vector is also custom Type::Vector(inner_type) => { @@ -121,17 +134,21 @@ fn native_rlp_encode( Type::U8 => { let bytes: Vec = safely_pop_arg!(args, Vec); context.charge( - RLP_ENCODE_DECODE_BASE + - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(bytes.len() as u64) + RLP_ENCODE_DECODE_BASE + + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(bytes.len() as u64), )?; let encoded_data = rlp::encode(&bytes).to_vec(); Ok(smallvec![Value::vector_u8(encoded_data)]) - } - _ => Err(SafeNativeError::Abort { abort_code: E_UNSUPPORTED_TYPE }), + }, + _ => Err(SafeNativeError::Abort { + abort_code: E_UNSUPPORTED_TYPE, + }), } - } + }, - _ => Err(SafeNativeError::Abort { abort_code: E_UNSUPPORTED_TYPE }), + _ => Err(SafeNativeError::Abort { + abort_code: E_UNSUPPORTED_TYPE, + }), } } @@ -140,56 +157,65 @@ fn native_rlp_decode( ty_args: Vec, mut args: VecDeque, ) -> SafeNativeResult> { - if ty_args.len() != 1 { - return Err(SafeNativeError::Abort { abort_code: E_INVALID_TYPE_ARG }); + return Err(SafeNativeError::Abort { + abort_code: E_INVALID_TYPE_ARG, + }); } let inner_ty = &ty_args[0]; match inner_ty { - Type::Bool => rlp_decode_scalar!(context, args, bool, Value::bool), - Type::U8 => rlp_decode_scalar!(context, args, u8, Value::u8), - Type::U16 => rlp_decode_scalar!(context, args, u16, Value::u16), - Type::U32 => rlp_decode_scalar!(context, args, u32, Value::u32), - Type::U64 => rlp_decode_scalar!(context, args, u64, Value::u64), - Type::U128 => rlp_decode_scalar!(context, args, u128, Value::u128), + Type::Bool => rlp_decode_scalar!(context, args, bool, Value::bool), + Type::U8 => rlp_decode_scalar!(context, args, u8, Value::u8), + Type::U16 => rlp_decode_scalar!(context, args, u16, Value::u16), + Type::U32 => rlp_decode_scalar!(context, args, u32, Value::u32), + Type::U64 => rlp_decode_scalar!(context, args, u64, Value::u64), + Type::U128 => rlp_decode_scalar!(context, args, u128, Value::u128), Type::Address => { let encoded_data: Vec = safely_pop_arg!(args, Vec); context.charge( - RLP_ENCODE_DECODE_BASE + - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64) + RLP_ENCODE_DECODE_BASE + + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64), )?; // address => decode as Vec, then convert match rlp::decode::>(&encoded_data) { - Ok(addr_bytes) => { - match AccountAddress::from_bytes(addr_bytes) { - Ok(addr) => Ok(smallvec![Value::address(addr)]), - Err(_) => Err(SafeNativeError::Abort { abort_code: E_DECODE_FAILURE }), - } + Ok(addr_bytes) => match AccountAddress::from_bytes(addr_bytes) { + Ok(addr) => Ok(smallvec![Value::address(addr)]), + Err(_) => Err(SafeNativeError::Abort { + abort_code: E_DECODE_FAILURE, + }), }, - Err(_) => Err(SafeNativeError::Abort { abort_code: E_DECODE_FAILURE }), + Err(_) => Err(SafeNativeError::Abort { + abort_code: E_DECODE_FAILURE, + }), } - } + }, Type::Vector(inner_type) => { match &**inner_type { // only vector encoding is supported Type::U8 => { let encoded_data: Vec = safely_pop_arg!(args, Vec); context.charge( - RLP_ENCODE_DECODE_BASE + - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64) + RLP_ENCODE_DECODE_BASE + + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64), )?; match rlp::decode::>(&encoded_data) { Ok(decoded_bytes) => Ok(smallvec![Value::vector_u8(decoded_bytes)]), - Err(_) => Err(SafeNativeError::Abort { abort_code: E_DECODE_FAILURE }), + Err(_) => Err(SafeNativeError::Abort { + abort_code: E_DECODE_FAILURE, + }), } - } - _ => Err(SafeNativeError::Abort { abort_code: E_UNSUPPORTED_TYPE }), + }, + _ => Err(SafeNativeError::Abort { + abort_code: E_UNSUPPORTED_TYPE, + }), } - } + }, - _ => Err(SafeNativeError::Abort { abort_code: E_UNSUPPORTED_TYPE }), + _ => Err(SafeNativeError::Abort { + abort_code: E_UNSUPPORTED_TYPE, + }), } } @@ -205,41 +231,44 @@ fn native_rlp_encode_list_scalar( ty_args: Vec, mut args: VecDeque, ) -> SafeNativeResult> { - if ty_args.len() != 1 { - return Err(SafeNativeError::Abort { abort_code: E_INVALID_TYPE_ARG }); + return Err(SafeNativeError::Abort { + abort_code: E_INVALID_TYPE_ARG, + }); } let inner_ty = &ty_args[0]; let data: Vec = safely_pop_arg!(args, Vec); let total_data_bytes = data.len() as u64; context.charge( - RLP_ENCODE_DECODE_BASE+ - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(total_data_bytes))?; + RLP_ENCODE_DECODE_BASE + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(total_data_bytes), + )?; match inner_ty { Type::Bool => { rlp_encode_list!(data, bool, E_ENCODE_FAILURE) - } + }, Type::U8 => { rlp_encode_list!(data, u8, E_ENCODE_FAILURE) - } + }, Type::U16 => { rlp_encode_list!(data, u16, E_ENCODE_FAILURE) - } + }, Type::U32 => { rlp_encode_list!(data, u32, E_ENCODE_FAILURE) - } + }, Type::U64 => { rlp_encode_list!(data, u64, E_ENCODE_FAILURE) - } + }, Type::U128 => { rlp_encode_list!(data, u128, E_ENCODE_FAILURE) - } + }, Type::Address => { // Address is a bit more custom - let data: Vec = bcs::from_bytes(&data) - .map_err(|_| SafeNativeError::Abort { abort_code: E_ENCODE_FAILURE })?; + let data: Vec = + bcs::from_bytes(&data).map_err(|_| SafeNativeError::Abort { + abort_code: E_ENCODE_FAILURE, + })?; let mut address_vec = vec![]; for addr in data { @@ -249,10 +278,10 @@ fn native_rlp_encode_list_scalar( } let encoded_data = rlp::encode_list(&address_vec).to_vec(); Ok(smallvec![Value::vector_u8(encoded_data)]) - } - _ => { - Err(SafeNativeError::Abort { abort_code: E_UNSUPPORTED_TYPE }) - } + }, + _ => Err(SafeNativeError::Abort { + abort_code: E_UNSUPPORTED_TYPE, + }), } } @@ -261,16 +290,17 @@ fn native_rlp_decode_list_scalar( ty_args: Vec, mut args: VecDeque, ) -> SafeNativeResult> { - if ty_args.len() != 1 { - return Err(SafeNativeError::Abort { abort_code: E_INVALID_TYPE_ARG }); + return Err(SafeNativeError::Abort { + abort_code: E_INVALID_TYPE_ARG, + }); } let inner_ty = &ty_args[0]; let encoded_data: Vec = safely_pop_arg!(args, Vec); context.charge( - RLP_ENCODE_DECODE_BASE+ - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64) + RLP_ENCODE_DECODE_BASE + + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64), )?; let rlp = Rlp::new(&encoded_data); @@ -307,17 +337,23 @@ fn native_rlp_decode_list_scalar( } match AccountAddress::from_bytes(address_bytes) { Ok(addr) => address_vec.push(addr), - Err(_) => return Err(SafeNativeError::Abort { - abort_code: E_DECODE_FAILURE, - }), + Err(_) => { + return Err(SafeNativeError::Abort { + abort_code: E_DECODE_FAILURE, + }) + }, } } Ok(smallvec![Value::vector_address(address_vec)]) }, - Err(_) => Err(SafeNativeError::Abort { abort_code: E_DECODE_FAILURE }), + Err(_) => Err(SafeNativeError::Abort { + abort_code: E_DECODE_FAILURE, + }), } }, - _ => Err(SafeNativeError::Abort { abort_code: E_UNSUPPORTED_TYPE }), + _ => Err(SafeNativeError::Abort { + abort_code: E_UNSUPPORTED_TYPE, + }), } } @@ -326,14 +362,14 @@ fn native_rlp_encode_list_byte_array( _ty_args: Vec, mut args: VecDeque, ) -> SafeNativeResult> { - let data: Vec = safely_pop_arg!(args, Vec); let total_data_bytes = data.len() as u64; context.charge( - RLP_ENCODE_DECODE_BASE+ - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(total_data_bytes))?; - let data: Vec> = bcs::from_bytes(&data) - .map_err(|_| SafeNativeError::Abort { abort_code: E_ENCODE_FAILURE })?; + RLP_ENCODE_DECODE_BASE + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(total_data_bytes), + )?; + let data: Vec> = bcs::from_bytes(&data).map_err(|_| SafeNativeError::Abort { + abort_code: E_ENCODE_FAILURE, + })?; let encoded_data = rlp::encode_list::, _>(&data).to_vec(); Ok(smallvec![Value::vector_u8(encoded_data)]) } @@ -343,11 +379,10 @@ fn native_rlp_decode_list_byte_array( _ty_args: Vec, mut args: VecDeque, ) -> SafeNativeResult> { - let encoded_data: Vec = safely_pop_arg!(args, Vec); context.charge( - RLP_ENCODE_DECODE_BASE+ - RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64) + RLP_ENCODE_DECODE_BASE + + RLP_ENCODE_DECODE_PER_BYTE * NumBytes::new(encoded_data.len() as u64), )?; let rlp = Rlp::new(&encoded_data); @@ -356,14 +391,17 @@ fn native_rlp_decode_list_byte_array( Ok(decoded) => { //serialize and return data context.charge( - UTIL_FROM_BYTES_BASE+ - UTIL_FROM_BYTES_PER_BYTE * NumBytes::new(encoded_data.len() as u64) + UTIL_FROM_BYTES_BASE + + UTIL_FROM_BYTES_PER_BYTE * NumBytes::new(encoded_data.len() as u64), )?; - let serialized_data = bcs::to_bytes(&decoded) - .map_err(|_| SafeNativeError::Abort { abort_code: E_DECODE_FAILURE })?; + let serialized_data = bcs::to_bytes(&decoded).map_err(|_| SafeNativeError::Abort { + abort_code: E_DECODE_FAILURE, + })?; Ok(smallvec![Value::vector_u8(serialized_data)]) }, - Err(_) => Err(SafeNativeError::Abort { abort_code: E_DECODE_FAILURE }), + Err(_) => Err(SafeNativeError::Abort { + abort_code: E_DECODE_FAILURE, + }), } } @@ -375,12 +413,22 @@ pub fn make_all( natives.extend([ ("native_rlp_encode", native_rlp_encode as RawSafeNative), ("native_rlp_decode", native_rlp_decode as RawSafeNative), - - ("native_rlp_encode_list_scalar", native_rlp_encode_list_scalar as RawSafeNative), - ("native_rlp_decode_list_scalar", native_rlp_decode_list_scalar as RawSafeNative), - - ("native_rlp_encode_list_byte_array", native_rlp_encode_list_byte_array as RawSafeNative), - ("native_rlp_decode_list_byte_array", native_rlp_decode_list_byte_array as RawSafeNative), + ( + "native_rlp_encode_list_scalar", + native_rlp_encode_list_scalar as RawSafeNative, + ), + ( + "native_rlp_decode_list_scalar", + native_rlp_decode_list_scalar as RawSafeNative, + ), + ( + "native_rlp_encode_list_byte_array", + native_rlp_encode_list_byte_array as RawSafeNative, + ), + ( + "native_rlp_decode_list_byte_array", + native_rlp_decode_list_byte_array as RawSafeNative, + ), ]); builder.make_named_natives(natives) diff --git a/aptos-move/framework/src/release_bundle.rs b/aptos-move/framework/src/release_bundle.rs index 20c7fbdcd13..3899efb0f70 100644 --- a/aptos-move/framework/src/release_bundle.rs +++ b/aptos-move/framework/src/release_bundle.rs @@ -3,6 +3,7 @@ use crate::{built_package::BuiltPackage, natives::code::PackageMetadata, path_in_crate}; use anyhow::Context; +use aptos_crypto::HashValue; use aptos_types::account_address::AccountAddress; use move_binary_format::{access::ModuleAccess, errors::PartialVMError, CompiledModule}; use move_command_line_common::files::{extension_equals, find_filenames, MOVE_EXTENSION}; @@ -10,7 +11,6 @@ use move_core_types::language_storage::ModuleId; use move_model::{code_writer::CodeWriter, emit, emitln, model::Loc}; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, path::PathBuf}; -use aptos_crypto::HashValue; /// A release bundle consists of a list of release packages. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] @@ -184,9 +184,16 @@ impl ReleasePackage { for_address: AccountAddress, out: PathBuf, next_execution_hash: Option, - function_name: String + function_name: String, ) -> anyhow::Result<()> { - self.generate_script_proposal_impl(for_address, out, true, true, next_execution_hash, function_name) + self.generate_script_proposal_impl( + for_address, + out, + true, + true, + next_execution_hash, + function_name, + ) } fn generate_script_proposal_impl( @@ -208,7 +215,11 @@ impl ReleasePackage { // The Sha2-256 digest here is the combined hash of all the hashes of the `.move` files and // the manifest file(Move.toml) in the source package. // Check [move_package::resolution::digest::compile_digest] - emitln!(writer, "// source package's SHA2-256 digest: {}", self.metadata.source_digest); + emitln!( + writer, + "// source package's SHA2-256 digest: {}", + self.metadata.source_digest + ); emitln!(writer, "script {"); writer.indent(); emitln!(writer, "use std::vector;"); diff --git a/aptos-move/framework/supra-framework/doc/aggregator_v2.md b/aptos-move/framework/supra-framework/doc/aggregator_v2.md index 842ad22ecda..f5e3fdf0497 100644 --- a/aptos-move/framework/supra-framework/doc/aggregator_v2.md +++ b/aptos-move/framework/supra-framework/doc/aggregator_v2.md @@ -217,7 +217,7 @@ and any calls will raise this error. -Arguments passed to concat exceed max limit of 256 bytes (for prefix and suffix together). +Arguments passed to concat exceed max limit of 1024 bytes (for prefix and suffix together).
const ECONCAT_STRING_LENGTH_TOO_LARGE: u64 = 8;
@@ -705,7 +705,7 @@ Useful for when object is sometimes created via string_concat(), and sometimes d
 Concatenates before, snapshot and after into a single string.
 snapshot passed needs to have integer type - currently supported types are u64 and u128.
 Raises EUNSUPPORTED_AGGREGATOR_SNAPSHOT_TYPE if called with another type.
-If length of prefix and suffix together exceed 256 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised.
+If length of prefix and suffix together exceed 1024 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised.
 
 Parallelism info: This operation enables parallelism.
 
diff --git a/aptos-move/framework/supra-framework/doc/automation_registry.md b/aptos-move/framework/supra-framework/doc/automation_registry.md
index 4ebcdd03c97..c69be63dd5f 100644
--- a/aptos-move/framework/supra-framework/doc/automation_registry.md
+++ b/aptos-move/framework/supra-framework/doc/automation_registry.md
@@ -73,6 +73,7 @@ This contract is part of the Supra Framework and is designed to manage automated
 -  [Function `get_registry_total_locked_balance`](#0x1_automation_registry_get_registry_total_locked_balance)
 -  [Function `get_active_task_ids`](#0x1_automation_registry_get_active_task_ids)
 -  [Function `get_task_details`](#0x1_automation_registry_get_task_details)
+-  [Function `deconstruct_task_metadata_v2`](#0x1_automation_registry_deconstruct_task_metadata_v2)
 -  [Function `deconstruct_task_metadata`](#0x1_automation_registry_deconstruct_task_metadata)
 -  [Function `get_task_owner`](#0x1_automation_registry_get_task_owner)
 -  [Function `get_task_details_bulk`](#0x1_automation_registry_get_task_details_bulk)
@@ -3530,6 +3531,59 @@ Error will be returned if entry with specified task index does not exist.
 
 
 
+
+
+
+
+## Function `deconstruct_task_metadata_v2`
+
+Retrieves specific metadata details of an automation task entry by its task index.
+
+1. u64                     - The task index.
+2. address                 - The owner of the task.
+3. vector<u8>              - The payload transaction (encoded).
+4. u64                     - The expiry time of the task (timestamp).
+5. vector<u8>              - The hash of the transaction.
+6. u64                     - The maximum gas amount allowed for the task.
+7. u64                     - The gas price cap for executing the task.
+8. u64                     - The automation fee cap for the current epoch.
+9. vector<vector<u8>>      - Auxiliary data related to the task (can be multiple items).
+10. u64                    - The time at which the task was registered (timestamp).
+11. u8                     - The state of the task (e.g., active, cancelled, completed).
+12. u64                    - The locked fee reserved for the next epoch execution.
+
+
+
public fun deconstruct_task_metadata_v2(task_metadata: &automation_registry::AutomationTaskMetaData): (u64, address, vector<u8>, u64, vector<u8>, u64, u64, u64, vector<vector<u8>>, u64, u8, u64)
+
+ + + +
+Implementation + + +
public fun deconstruct_task_metadata_v2(
+    task_metadata: &AutomationTaskMetaData
+): (u64, address, vector<u8>, u64, vector<u8>, u64, u64, u64, vector<vector<u8>>, u64, u8, u64) {
+    (
+        task_metadata.task_index,
+        task_metadata.owner,
+        task_metadata.payload_tx,
+        task_metadata.expiry_time,
+        task_metadata.tx_hash,
+        task_metadata.max_gas_amount,
+        task_metadata.gas_price_cap,
+        task_metadata.automation_fee_cap_for_epoch,
+        task_metadata.aux_data,
+        task_metadata.registration_time,
+        task_metadata.state,
+        task_metadata.locked_fee_for_next_epoch
+    )
+}
+
+ + +
diff --git a/aptos-move/framework/supra-framework/doc/block.md b/aptos-move/framework/supra-framework/doc/block.md index ac1d7e8bf1f..2660db6a19b 100644 --- a/aptos-move/framework/supra-framework/doc/block.md +++ b/aptos-move/framework/supra-framework/doc/block.md @@ -46,6 +46,7 @@ This module defines a struct storing the metadata of the block and new block eve use 0x1::error; use 0x1::event; use 0x1::features; +use 0x1::leader_ban_registry; use 0x1::option; use 0x1::randomness; use 0x1::reconfiguration; @@ -426,23 +427,34 @@ This can only be called during Genesis. Implementation -
public(friend) fun initialize(supra_framework: &signer, epoch_interval_microsecs: u64) {
+
public(friend) fun initialize(
+    supra_framework: &signer, epoch_interval_microsecs: u64
+) {
     system_addresses::assert_supra_framework(supra_framework);
-    assert!(epoch_interval_microsecs != 0, error::invalid_argument(EZERO_EPOCH_INTERVAL));
+    assert!(
+        epoch_interval_microsecs != 0,
+        error::invalid_argument(EZERO_EPOCH_INTERVAL)
+    );
 
-    move_to<CommitHistory>(supra_framework, CommitHistory {
-        max_capacity: 2000,
-        next_idx: 0,
-        table: table_with_length::new(),
-    });
+    move_to<CommitHistory>(
+        supra_framework,
+        CommitHistory {
+            max_capacity: 2000,
+            next_idx: 0,
+            table: table_with_length::new()
+        }
+    );
 
     move_to<BlockResource>(
         supra_framework,
         BlockResource {
             height: 0,
             epoch_interval: epoch_interval_microsecs,
-            new_block_events: account::new_event_handle<NewBlockEvent>(supra_framework),
-            update_epoch_interval_events: account::new_event_handle<UpdateEpochIntervalEvent>(supra_framework),
+            new_block_events: account::new_event_handle<NewBlockEvent>(
+                supra_framework
+            ),
+            update_epoch_interval_events: account::new_event_handle<
+                UpdateEpochIntervalEvent>(supra_framework)
         }
     );
 }
@@ -470,11 +482,10 @@ Initialize the commit history resource if it's not in genesis.
 
 
public fun initialize_commit_history(fx: &signer, max_capacity: u32) {
     assert!(max_capacity != 0, error::invalid_argument(EZERO_MAX_CAPACITY));
-    move_to<CommitHistory>(fx, CommitHistory {
-        max_capacity,
-        next_idx: 0,
-        table: table_with_length::new(),
-    });
+    move_to<CommitHistory>(
+        fx,
+        CommitHistory { max_capacity, next_idx: 0, table: table_with_length::new() }
+    );
 }
 
@@ -500,8 +511,7 @@ Can only be called as part of the Supra governance proposal process established
public fun update_epoch_interval_microsecs(
-    supra_framework: &signer,
-    new_epoch_interval: u64,
+    supra_framework: &signer, new_epoch_interval: u64
 ) acquires BlockResource {
     system_addresses::assert_supra_framework(supra_framework);
     assert!(new_epoch_interval != 0, error::invalid_argument(EZERO_EPOCH_INTERVAL));
@@ -511,13 +521,11 @@ Can only be called as part of the Supra governance proposal process established
     block_resource.epoch_interval = new_epoch_interval;
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            UpdateEpochInterval { old_epoch_interval, new_epoch_interval },
-        );
+        event::emit(UpdateEpochInterval { old_epoch_interval, new_epoch_interval });
     };
     event::emit_event<UpdateEpochIntervalEvent>(
         &mut block_resource.update_epoch_interval_events,
-        UpdateEpochIntervalEvent { old_epoch_interval, new_epoch_interval },
+        UpdateEpochIntervalEvent { old_epoch_interval, new_epoch_interval }
     );
 }
 
@@ -583,7 +591,7 @@ Return epoch interval in seconds. // Blocks can only be produced by a valid proposer or by the VM itself for Nil blocks (no user txs). assert!( proposer == @vm_reserved || stake::is_current_epoch_validator(proposer), - error::permission_denied(EINVALID_PROPOSER), + error::permission_denied(EINVALID_PROPOSER) ); let proposer_index = option::none(); @@ -603,7 +611,7 @@ Return epoch interval in seconds. previous_block_votes_bitvec, proposer, failed_proposer_indices, - time_microseconds: timestamp, + time_microseconds: timestamp }; let new_block_event_v2 = NewBlock { hash, @@ -613,9 +621,14 @@ Return epoch interval in seconds. previous_block_votes_bitvec, proposer, failed_proposer_indices, - time_microseconds: timestamp, + time_microseconds: timestamp }; - emit_new_block_event(vm, &mut block_metadata_ref.new_block_events, new_block_event, new_block_event_v2); + emit_new_block_event( + vm, + &mut block_metadata_ref.new_block_events, + new_block_event, + new_block_event_v2 + ); if (features::collect_and_distribute_gas_fees()) { // Assign the fees collected from the previous block to the previous block proposer. @@ -631,6 +644,13 @@ Return epoch interval in seconds. stake::update_performance_statistics(proposer_index, failed_proposer_indices); state_storage::on_new_block(reconfiguration::current_epoch()); + leader_ban_registry::update_ban_registry( + epoch, + round, + proposer_index, + failed_proposer_indices + ); + automation_registry::monitor_cycle_end(); block_metadata_ref.epoch_interval @@ -668,16 +688,17 @@ The runtime always runs this before executing the transactions in a block. previous_block_votes_bitvec: vector<u8>, timestamp: u64 ) acquires BlockResource, CommitHistory { - let epoch_interval = block_prologue_common( - &vm, - hash, - epoch, - round, - proposer, - failed_proposer_indices, - previous_block_votes_bitvec, - timestamp - ); + let epoch_interval = + block_prologue_common( + &vm, + hash, + epoch, + round, + proposer, + failed_proposer_indices, + previous_block_votes_bitvec, + timestamp + ); randomness::on_new_block(&vm, epoch, round, option::none()); if (timestamp - reconfiguration::last_reconfiguration_time() >= epoch_interval) { reconfiguration::reconfigure(); @@ -696,7 +717,7 @@ The runtime always runs this before executing the transactions in a block. block_prologue() but trigger reconfiguration with DKG after epoch timed out. -
fun block_prologue_ext(vm: signer, hash: address, epoch: u64, round: u64, proposer: address, failed_proposer_indices: vector<u64>, previous_block_votes_bitvec: vector<u8>, timestamp: u64, randomness_seed: option::Option<vector<u8>>)
+
fun block_prologue_ext(vm: signer, hash: address, epoch: u64, round: u64, proposer: address, failed_proposer_indices: vector<u64>, previous_block_votes_bitvec: vector<u8>, timestamp: u64, randomness_seed_vec: vector<u8>)
 
@@ -714,18 +735,26 @@ The runtime always runs this before executing the transactions in a block. failed_proposer_indices: vector<u64>, previous_block_votes_bitvec: vector<u8>, timestamp: u64, - randomness_seed: Option<vector<u8>>, + randomness_seed_vec: vector<u8> ) acquires BlockResource, CommitHistory { - let epoch_interval = block_prologue_common( - &vm, - hash, - epoch, - round, - proposer, - failed_proposer_indices, - previous_block_votes_bitvec, - timestamp - ); + let randomness_seed = + if (vector::length(&randomness_seed_vec) == 0) { + option::none() + } else { + option::some(randomness_seed_vec) + }; + + let epoch_interval = + block_prologue_common( + &vm, + hash, + epoch, + round, + proposer, + failed_proposer_indices, + previous_block_votes_bitvec, + timestamp + ); randomness::on_new_block(&vm, epoch, round, randomness_seed); if (timestamp - reconfiguration::last_reconfiguration_time() >= epoch_interval) { @@ -792,16 +821,20 @@ Emit the event and update height and global timestamp if (table_with_length::contains(&commit_history_ref.table, idx)) { table_with_length::remove(&mut commit_history_ref.table, idx); }; - table_with_length::add(&mut commit_history_ref.table, idx, copy new_block_event); + table_with_length::add( + &mut commit_history_ref.table, idx, copy new_block_event + ); spec { assume idx + 1 <= MAX_U32; }; commit_history_ref.next_idx = (idx + 1) % commit_history_ref.max_capacity; }; - timestamp::update_global_time(vm, new_block_event.proposer, new_block_event.time_microseconds); + timestamp::update_global_time( + vm, new_block_event.proposer, new_block_event.time_microseconds + ); assert!( event::counter(event_handle) == new_block_event.height, - error::invalid_argument(ENUM_NEW_BLOCK_EVENTS_DOES_NOT_MATCH_BLOCK_HEIGHT), + error::invalid_argument(ENUM_NEW_BLOCK_EVENTS_DOES_NOT_MATCH_BLOCK_HEIGHT) ); if (std::features::module_event_migration_enabled()) { event::emit(new_block_event_v2); @@ -845,7 +878,7 @@ reconfiguration event. previous_block_votes_bitvec: vector::empty(), proposer: @vm_reserved, failed_proposer_indices: vector::empty(), - time_microseconds: timestamp::now_microseconds(), + time_microseconds: timestamp::now_microseconds() }, NewBlock { hash: genesis_id, @@ -855,7 +888,7 @@ reconfiguration event. previous_block_votes_bitvec: vector::empty(), proposer: @vm_reserved, failed_proposer_indices: vector::empty(), - time_microseconds: timestamp::now_microseconds(), + time_microseconds: timestamp::now_microseconds() } ); } @@ -883,8 +916,7 @@ new block event for WriteSetPayload.
public fun emit_writeset_block_event(
-    vm_signer: &signer,
-    fake_block_hash: address
+    vm_signer: &signer, fake_block_hash: address
 ) acquires BlockResource, CommitHistory {
     system_addresses::assert_vm(vm_signer);
     let block_metadata_ref = borrow_global_mut<BlockResource>(@supra_framework);
@@ -901,7 +933,7 @@ new block event for WriteSetPayload.
             previous_block_votes_bitvec: vector::empty(),
             proposer: @vm_reserved,
             failed_proposer_indices: vector::empty(),
-            time_microseconds: timestamp::now_microseconds(),
+            time_microseconds: timestamp::now_microseconds()
         },
         NewBlock {
             hash: fake_block_hash,
@@ -911,7 +943,7 @@ new block event for WriteSetPayload.
             previous_block_votes_bitvec: vector::empty(),
             proposer: @vm_reserved,
             failed_proposer_indices: vector::empty(),
-            time_microseconds: timestamp::now_microseconds(),
+            time_microseconds: timestamp::now_microseconds()
         }
     );
 }
@@ -1265,7 +1297,7 @@ The BlockResource existed under the @supra_framework.
 ### Function `block_prologue_ext`
 
 
-
fun block_prologue_ext(vm: signer, hash: address, epoch: u64, round: u64, proposer: address, failed_proposer_indices: vector<u64>, previous_block_votes_bitvec: vector<u8>, timestamp: u64, randomness_seed: option::Option<vector<u8>>)
+
fun block_prologue_ext(vm: signer, hash: address, epoch: u64, round: u64, proposer: address, failed_proposer_indices: vector<u64>, previous_block_votes_bitvec: vector<u8>, timestamp: u64, randomness_seed_vec: vector<u8>)
 
diff --git a/aptos-move/framework/supra-framework/doc/committee_map.md b/aptos-move/framework/supra-framework/doc/committee_map.md index 88ce2e20ed0..a14ca00f3a0 100644 --- a/aptos-move/framework/supra-framework/doc/committee_map.md +++ b/aptos-move/framework/supra-framework/doc/committee_map.md @@ -36,6 +36,7 @@ requirements: - [Function `get_committeeInfo_address`](#0x1_committee_map_get_committeeInfo_address) - [Function `init_module`](#0x1_committee_map_init_module) - [Function `validate_committee_type`](#0x1_committee_map_validate_committee_type) +- [Function `assert_removal_allowed`](#0x1_committee_map_assert_removal_allowed) - [Function `get_committee_info`](#0x1_committee_map_get_committee_info) - [Function `get_committee_ids`](#0x1_committee_map_get_committee_ids) - [Function `get_committee_id`](#0x1_committee_map_get_committee_id) @@ -646,62 +647,112 @@ Capability that grants an owner the right to perform action. - + -Define the CommitteeType as constants +The number of nodes in the CLAN is too small or even -
const FAMILY: u8 = 1;
+
const ECLAN_TOO_SMALL_OR_EVEN_NODES_IN_CLAN: u64 = 13;
 
- + + +The number of nodes in the CLAN is invalid + + +
const EINVALID_CLAN_NODE_NUMBERS: u64 = 9;
+
+ + + + The committee is not found -
const INVALID_COMMITTEE_ID: u64 = 6;
+
const EINVALID_COMMITTEE_ID: u64 = 6;
 
- + -The number of committee is not equal to the number of committee member +The number of committees is not equal to the number of committee members -
const INVALID_COMMITTEE_NUMBERS: u64 = 4;
+
const EINVALID_COMMITTEE_NUMBERS: u64 = 4;
 
- + The committee type is invalid -
const INVALID_COMMITTEE_TYPE: u64 = 7;
+
const EINVALID_COMMITTEE_TYPE: u64 = 7;
+
+ + + + + +The number of nodes in the FAMILY is invalid + + +
const EINVALID_FAMILIY_NODE_NUMBERS: u64 = 10;
 
- + The number of nodes in the committee is invalid -
const INVALID_NODE_NUMBERS: u64 = 8;
+
const EINVALID_NODE_NUMBERS: u64 = 8;
 
- + + +The number of nodes in the TRIBE is invalid + + +
const EINVALID_TRIBE_NODE_NUMBERS: u64 = 11;
+
+ + + + The node is not found in the committee -
const NODE_NOT_FOUND: u64 = 5;
+
const ENODE_NOT_FOUND: u64 = 5;
+
+ + + + + +The number of nodes in the committee is ZERO + + +
const EZERO_COMMITTEE_NODE_NUMBER: u64 = 12;
+
+ + + + + +Define the CommitteeType as constants + + +
const FAMILY: u8 = 1;
 
@@ -766,7 +817,7 @@ Internal - Assert if the node exists in the committee
fun ensure_node_address_exist(committee: &CommitteeInfo, node_address: address) {
-    assert!(does_node_exist(committee, node_address), error::invalid_argument(NODE_NOT_FOUND))
+    assert!(does_node_exist(committee, node_address), error::invalid_argument(ENODE_NOT_FOUND))
 }
 
@@ -930,16 +981,16 @@ Its Initial function which will be executed automatically while deployed package
fun validate_committee_type(committee_type: u8, num_of_nodes: u64): u8 {
-    assert!(committee_type >= FAMILY && committee_type <= TRIBE, INVALID_COMMITTEE_TYPE);
+    assert!(committee_type >= FAMILY && committee_type <= TRIBE, EINVALID_COMMITTEE_TYPE);
     if (committee_type == FAMILY) {
         // f+1, number of nodes in a family committee should be greater than 1
-        assert!(num_of_nodes > 1, INVALID_NODE_NUMBERS);
+        assert!(num_of_nodes > 1, EINVALID_FAMILIY_NODE_NUMBERS);
     } else if (committee_type == CLAN) {
-        // 2f+1, number of nodes in a clan committee should be odd and greater than 3
-        assert!(num_of_nodes >= 3 && num_of_nodes % 2 == 1, INVALID_NODE_NUMBERS);
+        // 2f+1, number of nodes in a clan committee should be odd and greater than or equal to 3
+        assert!(num_of_nodes >= 3 && num_of_nodes % 2 == 1, ECLAN_TOO_SMALL_OR_EVEN_NODES_IN_CLAN);
     } else {
-        // 3f+1, number of nodes in a tribe committee should be in the format of 3f+1 and greater than 4
-        assert!(num_of_nodes >= 4 && (num_of_nodes - 1) % 3 == 0, INVALID_NODE_NUMBERS);
+        // 3f+1, number of nodes in a tribe committee should be in the format of 3f+1 and greater than or equal to 4
+        assert!(num_of_nodes >= 4 && (num_of_nodes - 1) % 3 == 0, EINVALID_TRIBE_NODE_NUMBERS);
     };
     committee_type
 }
@@ -947,6 +998,33 @@ Its Initial function which will be executed automatically while deployed package
 
 
 
+
+
+
+
+## Function `assert_removal_allowed`
+
+Ensures removing exactly one member keeps the committee type invariants valid.
+
+
+
fun assert_removal_allowed(committee: &committee_map::CommitteeInfo)
+
+ + + +
+Implementation + + +
fun assert_removal_allowed(committee: &CommitteeInfo) {
+    let current_num_of_nodes = simple_map::length(&committee.map);
+    assert!(current_num_of_nodes > 0, EZERO_COMMITTEE_NODE_NUMBER);
+    validate_committee_type(committee.committee_type, current_num_of_nodes - 1);
+}
+
+ + +
@@ -1076,7 +1154,7 @@ Get the node's information let committee = simple_map::borrow(&committee_store.committee_map, &id); let (addrs, nodes) = simple_map::to_vec_pair(committee.map); let (flag, index) = vector::index_of(&addrs, &node_address); - assert!(flag, error::invalid_argument(NODE_NOT_FOUND)); + assert!(flag, error::invalid_argument(ENODE_NOT_FOUND)); let node_info = vector::borrow(&nodes, index); NodeData { @@ -1259,31 +1337,31 @@ This function is used to add a new committee to the store rpc_port: vector<u16>, committee_type: u8 ) acquires CommitteeInfoStore, SupraCommitteeEventHandler { - // Assert the length of the vector for two are the same + // Assert the length of the vector for two is the same let node_address_len = vector::length(&node_addresses); assert!( node_address_len == vector::length(&ip_public_address), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&node_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&network_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&cg_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&network_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( node_address_len == vector::length(&rpc_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); // Only the OwnerCap capability can access it let _acquire = &capability::acquire(owner_signer, &OwnerCap {}); @@ -1377,31 +1455,31 @@ Add the committee in bulk let ids_len = vector::length(&ids); assert!( ids_len == vector::length(&node_addresses_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&ip_public_address_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&node_public_key_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&network_public_key_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&cg_public_key_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&network_port_bulk), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( ids_len == vector::length(&rpc_por_bulkt), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); while (vector::length(&ids) != 0) { let id = vector::pop_back(&mut ids); @@ -1461,7 +1539,7 @@ Remove the committee from the store let committee_store = borrow_global_mut<CommitteeInfoStore>(com_store_addr); assert!( simple_map::contains_key(&committee_store.committee_map, &id), - error::invalid_argument(INVALID_COMMITTEE_ID) + error::invalid_argument(EINVALID_COMMITTEE_ID) ); let (id, committee_info) = simple_map::remove(&mut committee_store.committee_map, &id); // Also remove the node_to_committee_map @@ -1470,7 +1548,7 @@ Remove the committee from the store let addr = vector::pop_back(&mut addrs); assert!( simple_map::contains_key(&committee_store.node_to_committee_map, &addr), - error::invalid_argument(NODE_NOT_FOUND) + error::invalid_argument(ENODE_NOT_FOUND) ); simple_map::remove(&mut committee_store.node_to_committee_map, &addr); }; @@ -1552,6 +1630,27 @@ Upsert the node to the committee let _acquire = &capability::acquire(owner_signer, &OwnerCap {}); let committee_store = borrow_global_mut<CommitteeInfoStore>(com_store_addr); + let event_handler = borrow_global_mut<SupraCommitteeEventHandler>(get_committeeInfo_address(owner_signer)); + + // If the node is already associated with another committee, remove the stale entry first. + if (simple_map::contains_key(&committee_store.node_to_committee_map, &node_address)) { + let old_committee_id = *simple_map::borrow(&committee_store.node_to_committee_map, &node_address); + if (old_committee_id != id && simple_map::contains_key(&committee_store.committee_map, &old_committee_id)) { + let old_committee = simple_map::borrow_mut(&mut committee_store.committee_map, &old_committee_id); + if (does_node_exist(old_committee, node_address)) { + assert_removal_allowed(old_committee); + let (_, old_node_info) = simple_map::remove(&mut old_committee.map, &node_address); + emit_event( + &mut event_handler.remove_committee_member, + RemoveCommitteeMemberEvent { + committee_id: old_committee_id, + committee_member: old_node_info + } + ) + } + } + }; + let committee = simple_map::borrow_mut(&mut committee_store.committee_map, &id); let node_info = NodeInfo { ip_public_address: copy ip_public_address, @@ -1561,7 +1660,6 @@ Upsert the node to the committee network_port: network_port, rpc_port: rpc_port, }; - let event_handler = borrow_global_mut<SupraCommitteeEventHandler>(get_committeeInfo_address(owner_signer)); if (!does_node_exist(committee, node_address)) { emit_event( &mut event_handler.add_committee_member, @@ -1619,31 +1717,31 @@ Upsert nodes to the committee // Assert the length of the vector for two are the same assert!( vector::length(&ids) == vector::length(&node_addresses), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&ip_public_address), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&node_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&network_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&cg_public_key), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&network_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); assert!( vector::length(&ids) == vector::length(&rpc_port), - error::invalid_argument(INVALID_COMMITTEE_NUMBERS) + error::invalid_argument(EINVALID_COMMITTEE_NUMBERS) ); while (vector::length(&ids) != 0) { let id = vector::pop_back(&mut ids); @@ -1702,6 +1800,7 @@ Remove the node from the committee let committee_store = borrow_global_mut<CommitteeInfoStore>(com_store_addr); let committee = simple_map::borrow_mut(&mut committee_store.committee_map, &id); ensure_node_address_exist(committee, node_address); + assert_removal_allowed(committee); let (_, node_info) = simple_map::remove(&mut committee.map, &node_address); let event_handler = borrow_global_mut<SupraCommitteeEventHandler>(get_committeeInfo_address(owner_signer)); emit_event( diff --git a/aptos-move/framework/supra-framework/doc/dkg.md b/aptos-move/framework/supra-framework/doc/dkg.md index 6ae6728a12c..56657d41dd1 100644 --- a/aptos-move/framework/supra-framework/doc/dkg.md +++ b/aptos-move/framework/supra-framework/doc/dkg.md @@ -6,44 +6,55 @@ DKG on-chain states and helper functions. -- [Struct `DKGSessionMetadata`](#0x1_dkg_DKGSessionMetadata) - [Struct `DKGStartEvent`](#0x1_dkg_DKGStartEvent) +- [Struct `DKGMetaSetEvent`](#0x1_dkg_DKGMetaSetEvent) +- [Struct `DKGFinishEvent`](#0x1_dkg_DKGFinishEvent) +- [Struct `DKGSessionMetadata`](#0x1_dkg_DKGSessionMetadata) - [Struct `DKGSessionState`](#0x1_dkg_DKGSessionState) - [Resource `DKGState`](#0x1_dkg_DKGState) +- [Struct `OnChainAggregateCommitment`](#0x1_dkg_OnChainAggregateCommitment) +- [Struct `OnChainAggregateCommitmentAllCommittees`](#0x1_dkg_OnChainAggregateCommitmentAllCommittees) - [Constants](#@Constants_0) - [Function `initialize`](#0x1_dkg_initialize) - [Function `start`](#0x1_dkg_start) +- [Function `set_dkg_meta`](#0x1_dkg_set_dkg_meta) - [Function `finish`](#0x1_dkg_finish) - [Function `try_clear_incomplete_session`](#0x1_dkg_try_clear_incomplete_session) - [Function `incomplete_session`](#0x1_dkg_incomplete_session) +- [Function `last_completed_session`](#0x1_dkg_last_completed_session) - [Function `session_dealer_epoch`](#0x1_dkg_session_dealer_epoch) - [Specification](#@Specification_1) - [Function `initialize`](#@Specification_1_initialize) - [Function `start`](#@Specification_1_start) + - [Function `set_dkg_meta`](#@Specification_1_set_dkg_meta) - [Function `finish`](#@Specification_1_finish) - [Function `try_clear_incomplete_session`](#@Specification_1_try_clear_incomplete_session) - [Function `incomplete_session`](#@Specification_1_incomplete_session) -
use 0x1::error;
+
use 0x1::any;
+use 0x1::dkg_committee;
+use 0x1::error;
 use 0x1::event;
 use 0x1::option;
-use 0x1::randomness_config;
+use 0x1::stake;
+use 0x1::string;
 use 0x1::system_addresses;
 use 0x1::timestamp;
-use 0x1::validator_consensus_info;
+use 0x1::type_info;
+use 0x1::vector;
 
- + -## Struct `DKGSessionMetadata` +## Struct `DKGStartEvent` -This can be considered as the public input of DKG. -
struct DKGSessionMetadata has copy, drop, store
+
#[event]
+struct DKGStartEvent has drop, store
 
@@ -54,25 +65,69 @@ This can be considered as the public input of DKG.
-dealer_epoch: u64 +session_metadata: dkg::DKGSessionMetadata
-randomness_config: randomness_config::RandomnessConfig +start_time_us: u64
+
+ + + + + + +## Struct `DKGMetaSetEvent` + + + +
#[event]
+struct DKGMetaSetEvent has drop, store
+
+ + + +
+Fields + + +
-dealer_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo> +dkg_meta_transcript: vector<u8>
+
+ + +
+ + + +## Struct `DKGFinishEvent` + + + +
#[event]
+struct DKGFinishEvent has drop, store
+
+ + + +
+Fields + + +
-target_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo> +target_committees_public_key_shares: vector<u8>
@@ -82,14 +137,14 @@ This can be considered as the public input of DKG.
- + -## Struct `DKGStartEvent` +## Struct `DKGSessionMetadata` +This can be considered as the public input of DKG. -
#[event]
-struct DKGStartEvent has drop, store
+
struct DKGSessionMetadata has copy, drop, store
 
@@ -100,13 +155,25 @@ This can be considered as the public input of DKG.
-session_metadata: dkg::DKGSessionMetadata +dealer_epoch: u64
-start_time_us: u64 +randomness_seed: vector<u8> +
+
+ +
+
+dealer_committee: dkg_committee::DkgCommittee +
+
+ +
+
+target_committees: vector<dkg_committee::ReceiverCommittee>
@@ -147,7 +214,13 @@ The validator set of epoch x works together for an DKG output for t
-transcript: vector<u8> +dkg_meta_transcript: vector<u8> +
+
+ +
+
+target_committees_public_key_shares: vector<u8>
@@ -189,6 +262,96 @@ The completed and in-progress DKG sessions.
+ + + + +## Struct `OnChainAggregateCommitment` + + + +
struct OnChainAggregateCommitment has copy, drop
+
+ + + +
+Fields + + +
+
+bls12381_commitment_g: vector<u8> +
+
+ +
+
+bls12381_commitment_evals: vector<vector<u8>> +
+
+ +
+
+dealer_ids: vector<u32> +
+
+ +
+
+committee_index: u32 +
+
+ +
+
+epoch: u64 +
+
+ +
+
+chain_id: u8 +
+
+ +
+
+threshold_type: u8 +
+
+ +
+
+ + +
+ + + +## Struct `OnChainAggregateCommitmentAllCommittees` + + + +
struct OnChainAggregateCommitmentAllCommittees has copy, drop
+
+ + + +
+Fields + + +
+
+commitments: vector<dkg::OnChainAggregateCommitment> +
+
+ +
+
+ +
@@ -196,11 +359,29 @@ The completed and in-progress DKG sessions. ## Constants - + + + + +
const EDKG_INVALID_PK_SHARES: u64 = 4;
+
+ + + + + + + +
const EDKG_META_ALREADY_SET: u64 = 2;
+
+ + + + -
const EDKG_IN_PROGRESS: u64 = 1;
+
const EDKG_META_NOT_SET: u64 = 3;
 
@@ -209,7 +390,7 @@ The completed and in-progress DKG sessions. -
const EDKG_NOT_IN_PROGRESS: u64 = 2;
+
const EDKG_NOT_IN_PROGRESS: u64 = 1;
 
@@ -221,7 +402,7 @@ The completed and in-progress DKG sessions. Called in genesis to initialize on-chain states. -
public fun initialize(supra_framework: &signer)
+
public(friend) fun initialize(supra_framework: &signer)
 
@@ -230,7 +411,7 @@ Called in genesis to initialize on-chain states. Implementation -
public fun initialize(supra_framework: &signer) {
+
public(friend) fun initialize(supra_framework: &signer) {
     system_addresses::assert_supra_framework(supra_framework);
     if (!exists<DKGState>(@supra_framework)) {
         move_to<DKGState>(
@@ -240,7 +421,7 @@ Called in genesis to initialize on-chain states.
                 in_progress: std::option::none(),
             }
         );
-    }
+    };
 }
 
@@ -256,7 +437,7 @@ Mark on-chain DKG state as in-progress. Notify validators to start DKG. Abort if a DKG is already in progress. -
public(friend) fun start(dealer_epoch: u64, randomness_config: randomness_config::RandomnessConfig, dealer_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>, target_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>)
+
public(friend) fun start(dealer_epoch: u64, randomness_seed: vector<u8>, dealer_committee: dkg_committee::DkgCommittee, target_committees: vector<dkg_committee::ReceiverCommittee>)
 
@@ -267,22 +448,23 @@ Abort if a DKG is already in progress.
public(friend) fun start(
     dealer_epoch: u64,
-    randomness_config: RandomnessConfig,
-    dealer_validator_set: vector<ValidatorConsensusInfo>,
-    target_validator_set: vector<ValidatorConsensusInfo>,
+    randomness_seed: vector<u8>,
+    dealer_committee: DkgCommittee,
+    target_committees: vector<ReceiverCommittee>
 ) acquires DKGState {
     let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
     let new_session_metadata = DKGSessionMetadata {
         dealer_epoch,
-        randomness_config,
-        dealer_validator_set,
-        target_validator_set,
+        randomness_seed,
+        dealer_committee,
+        target_committees,
     };
     let start_time_us = timestamp::now_microseconds();
     dkg_state.in_progress = std::option::some(DKGSessionState {
         metadata: new_session_metadata,
         start_time_us,
-        transcript: vector[],
+        dkg_meta_transcript: vector[],
+        target_committees_public_key_shares: vector[],
     });
 
     emit(DKGStartEvent {
@@ -294,18 +476,57 @@ Abort if a DKG is already in progress.
 
 
 
+
+
+
+
+## Function `set_dkg_meta`
+
+Family Node sets the DKGMeta for the in-progress DKG session
+The dkg transcript is assumed to have been already verified by the aptos VM in process_dkg_result method
+
+
+
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
+
+ + + +
+Implementation + + +
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
+acquires DKGState {
+    // ensure dkg is in progress
+    let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
+    assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS));
+
+    // we only add the first DKG Meta proposed and ignore the rest
+    let session = option::extract(&mut dkg_state.in_progress);
+    assert!(vector::length(&session.dkg_meta_transcript) == 0, error::already_exists(EDKG_META_ALREADY_SET));
+    session.dkg_meta_transcript = dkg_meta_all_committees;
+    dkg_state.in_progress = option::some(session);
+
+    emit(DKGMetaSetEvent {
+        dkg_meta_transcript: dkg_meta_all_committees,
+    });
+}
+
+ + +
## Function `finish` -Put a transcript into the currently incomplete DKG session, then mark it completed. - -Abort if DKG is not in progress. +Family Node sets the target_committees_public_key_shares for the in-progress DKG session and +marks the incomplete DKG session completed. +The target_committees_public_key_shares is assumed to be verified by the aptos VM before calling this function -
public(friend) fun finish(transcript: vector<u8>)
+
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
 
@@ -314,13 +535,46 @@ Abort if DKG is not in progress. Implementation -
public(friend) fun finish(transcript: vector<u8>) acquires DKGState {
+
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
+acquires DKGState {
+    // ensure dkg is in progress
     let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
     assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS));
+
+    // DKG meta should be already set before `finish` is called
     let session = option::extract(&mut dkg_state.in_progress);
-    session.transcript = transcript;
+    assert!(vector::length(&session.dkg_meta_transcript) > 0, error::already_exists(EDKG_META_NOT_SET));
+
+    session.target_committees_public_key_shares = target_committees_public_key_shares;
     dkg_state.last_completed = option::some(session);
     dkg_state.in_progress = option::none();
+
+    // propagate updated keys to stake.move for all threshold types
+    let public_key_shares_all_comms_serialized
+        = any::new(type_info::type_name<OnChainAggregateCommitmentAllCommittees>(), target_committees_public_key_shares);
+    let public_key_shares_all_comms = any::unpack<OnChainAggregateCommitmentAllCommittees>(public_key_shares_all_comms_serialized);
+
+    // Build a vector of DkgCommitteeOutput for all committees
+    let committee_outputs = vector[];
+    let i = 0;
+    let len = vector::length(&public_key_shares_all_comms.commitments);
+    while (i < len) {
+        let commitment = vector::borrow(&public_key_shares_all_comms.commitments, i);
+        // As the first index contains the committee's threshold public key, we can skip that
+        let evals = vector::slice(&commitment.bls12381_commitment_evals, 1, vector::length(&commitment.bls12381_commitment_evals));
+
+        vector::push_back(
+            &mut committee_outputs,
+            new_dkg_committee_output(commitment.threshold_type, evals)
+        );
+        i = i + 1;
+    };
+
+    // Set all keys for all threshold types
+    stake::set_dkg_output_keys(committee_outputs);
+    emit(DKGFinishEvent {
+        target_committees_public_key_shares,
+    });
 }
 
@@ -384,6 +638,35 @@ Return the incomplete DKG session state, if it exists. + + + + +## Function `last_completed_session` + +Return the last completed DKG session state, if it exists. + + +
public fun last_completed_session(): option::Option<dkg::DKGSessionState>
+
+ + + +
+Implementation + + +
public fun last_completed_session(): Option<DKGSessionState> acquires DKGState {
+    if (exists<DKGState>(@supra_framework)) {
+        borrow_global<DKGState>(@supra_framework).last_completed
+    } else {
+        option::none()
+    }
+}
+
+ + +
@@ -427,7 +710,7 @@ Return the dealer epoch of a DKGS ### Function `initialize` -
public fun initialize(supra_framework: &signer)
+
public(friend) fun initialize(supra_framework: &signer)
 
@@ -444,7 +727,7 @@ Return the dealer epoch of a DKGS ### Function `start` -
public(friend) fun start(dealer_epoch: u64, randomness_config: randomness_config::RandomnessConfig, dealer_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>, target_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>)
+
public(friend) fun start(dealer_epoch: u64, randomness_seed: vector<u8>, dealer_committee: dkg_committee::DkgCommittee, target_committees: vector<dkg_committee::ReceiverCommittee>)
 
@@ -456,12 +739,30 @@ Return the dealer epoch of a DKGS + + +### Function `set_dkg_meta` + + +
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
+
+ + + + +
requires exists<DKGState>(@supra_framework);
+requires option::is_some(global<DKGState>(@supra_framework).in_progress);
+aborts_if false;
+
+ + + ### Function `finish` -
public(friend) fun finish(transcript: vector<u8>)
+
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
 
diff --git a/aptos-move/framework/supra-framework/doc/dkg_committee.md b/aptos-move/framework/supra-framework/doc/dkg_committee.md new file mode 100644 index 00000000000..ef0093c6bfe --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/dkg_committee.md @@ -0,0 +1,499 @@ + + + +# Module `0x1::dkg_committee` + + + +- [Struct `DkgNodeConfig`](#0x1_dkg_committee_DkgNodeConfig) +- [Struct `DkgCommittee`](#0x1_dkg_committee_DkgCommittee) +- [Struct `ReceiverCommittee`](#0x1_dkg_committee_ReceiverCommittee) +- [Struct `DkgCommitteeOutput`](#0x1_dkg_committee_DkgCommitteeOutput) +- [Constants](#@Constants_0) +- [Function `new_dkg_node_config`](#0x1_dkg_committee_new_dkg_node_config) +- [Function `get_addr`](#0x1_dkg_committee_get_addr) +- [Function `get_dkg_pubkey`](#0x1_dkg_committee_get_dkg_pubkey) +- [Function `len`](#0x1_dkg_committee_len) +- [Function `get_committee`](#0x1_dkg_committee_get_committee) +- [Function `new_dkg_committee`](#0x1_dkg_committee_new_dkg_committee) +- [Function `new_dkg_committee_from_validator_consensus_info`](#0x1_dkg_committee_new_dkg_committee_from_validator_consensus_info) +- [Function `new_receiver_committee`](#0x1_dkg_committee_new_receiver_committee) +- [Function `new_dkg_committee_output`](#0x1_dkg_committee_new_dkg_committee_output) +- [Function `get_dkg_committee_output_threshold_type`](#0x1_dkg_committee_get_dkg_committee_output_threshold_type) +- [Function `get_dkg_committee_output_keys`](#0x1_dkg_committee_get_dkg_committee_output_keys) + + +
use 0x1::bcs;
+use 0x1::validator_consensus_info;
+use 0x1::validator_public_keys;
+use 0x1::vector;
+
+ + + + + +## Struct `DkgNodeConfig` + + + +
struct DkgNodeConfig has copy, drop, store
+
+ + + +
+Fields + + +
+
+addr: address +
+
+ +
+
+identity: vector<u8> +
+
+ +
+
+dkg_pubkey: vector<u8> +
+
+ +
+
+ + +
+ + + +## Struct `DkgCommittee` + + + +
struct DkgCommittee has copy, drop, store
+
+ + + +
+Fields + + +
+
+committee: vector<dkg_committee::DkgNodeConfig> +
+
+ +
+
+threshold_type: validator_public_keys::CertificateThresholdType +
+
+ +
+
+ + +
+ + + +## Struct `ReceiverCommittee` + + + +
struct ReceiverCommittee has copy, drop, store
+
+ + + +
+Fields + + +
+
+is_resharing: bool +
+
+ +
+
+dkg_threshold_type: validator_public_keys::CertificateThresholdType +
+
+ +
+
+committee: dkg_committee::DkgCommittee +
+
+ +
+
+ + +
+ + + +## Struct `DkgCommitteeOutput` + +Input for DKG key output - contains threshold type and keys for one committee + + +
struct DkgCommitteeOutput has copy, drop
+
+ + + +
+Fields + + +
+
+threshold_type: u8 +
+
+ The threshold type (0=validity, 1=quorum, 2=unanimous, etc.) +
+
+keys: vector<vector<u8>> +
+
+ Public key shares for each validator (indexed by validator position) +
+
+ + +
+ + + +## Constants + + + + + + +
const EINVALID_DKG_COMMITTEE_SIZE: u64 = 1;
+
+ + + + + +## Function `new_dkg_node_config` + + + +
public fun new_dkg_node_config(addr: address, identity: vector<u8>, dkg_pubkey: vector<u8>): dkg_committee::DkgNodeConfig
+
+ + + +
+Implementation + + +
public fun new_dkg_node_config(
+    addr: address, identity: vector<u8>, dkg_pubkey: vector<u8>
+): DkgNodeConfig {
+    DkgNodeConfig { addr, identity, dkg_pubkey }
+}
+
+ + + +
+ + + +## Function `get_addr` + + + +
public fun get_addr(dkg_node: &dkg_committee::DkgNodeConfig): address
+
+ + + +
+Implementation + + +
public fun get_addr(dkg_node: &DkgNodeConfig): address {
+    dkg_node.addr
+}
+
+ + + +
+ + + +## Function `get_dkg_pubkey` + + + +
public fun get_dkg_pubkey(dkg_node: &dkg_committee::DkgNodeConfig): vector<u8>
+
+ + + +
+Implementation + + +
public fun get_dkg_pubkey(dkg_node: &DkgNodeConfig): vector<u8> {
+    dkg_node.dkg_pubkey
+}
+
+ + + +
+ + + +## Function `len` + + + +
public fun len(committee: &dkg_committee::DkgCommittee): u64
+
+ + + +
+Implementation + + +
public fun len(committee: &DkgCommittee): u64 {
+    vector::length(&committee.committee)
+}
+
+ + + +
+ + + +## Function `get_committee` + + + +
public fun get_committee(dkg_committee: &dkg_committee::DkgCommittee): vector<dkg_committee::DkgNodeConfig>
+
+ + + +
+Implementation + + +
public fun get_committee(dkg_committee: &DkgCommittee): vector<DkgNodeConfig> {
+    dkg_committee.committee
+}
+
+ + + +
+ + + +## Function `new_dkg_committee` + + + +
public fun new_dkg_committee(committee: vector<dkg_committee::DkgNodeConfig>, threshold_type: validator_public_keys::CertificateThresholdType): dkg_committee::DkgCommittee
+
+ + + +
+Implementation + + +
public fun new_dkg_committee(
+    committee: vector<DkgNodeConfig>, threshold_type: CertificateThresholdType
+): DkgCommittee {
+    assert!(vector::length(&committee) > 0, EINVALID_DKG_COMMITTEE_SIZE);
+    DkgCommittee { committee, threshold_type }
+}
+
+ + + +
+ + + +## Function `new_dkg_committee_from_validator_consensus_info` + + + +
public fun new_dkg_committee_from_validator_consensus_info(validator_committee: vector<validator_consensus_info::ValidatorConsensusInfo>, threshold_type: validator_public_keys::CertificateThresholdType): dkg_committee::DkgCommittee
+
+ + + +
+Implementation + + +
public fun new_dkg_committee_from_validator_consensus_info(
+    validator_committee: vector<ValidatorConsensusInfo>,
+    threshold_type: CertificateThresholdType
+): DkgCommittee {
+    assert!(vector::length(&validator_committee) > 0, EINVALID_DKG_COMMITTEE_SIZE);
+
+    // The order of the committee members is important for DKG.
+    // The order should correspond to the order of the validator committee.
+    // The output of the DKG has keys in the same order as the committee.
+    let dkg_committee = vector[];
+    vector::for_each(
+        validator_committee,
+        |x| {
+            let validator_keys_bytes = validator_consensus_info::get_pk_bytes(&x);
+            let addr = validator_consensus_info::get_addr(&x);
+            vector::push_back(
+                &mut dkg_committee,
+                DkgNodeConfig {
+                    addr,
+                    identity: bcs::to_bytes(&addr),
+                    dkg_pubkey: validator_keys_bytes
+                }
+            );
+        }
+    );
+
+    DkgCommittee { committee: dkg_committee, threshold_type }
+}
+
+ + + +
+ + + +## Function `new_receiver_committee` + + + +
public fun new_receiver_committee(is_resharing: bool, dkg_threshold_type: validator_public_keys::CertificateThresholdType, committee: dkg_committee::DkgCommittee): dkg_committee::ReceiverCommittee
+
+ + + +
+Implementation + + +
public fun new_receiver_committee(
+    is_resharing: bool,
+    dkg_threshold_type: CertificateThresholdType,
+    committee: DkgCommittee
+): ReceiverCommittee {
+    ReceiverCommittee { is_resharing, dkg_threshold_type, committee }
+}
+
+ + + +
+ + + +## Function `new_dkg_committee_output` + +Create a new DkgCommitteeOutput + + +
public fun new_dkg_committee_output(threshold_type: u8, keys: vector<vector<u8>>): dkg_committee::DkgCommitteeOutput
+
+ + + +
+Implementation + + +
public fun new_dkg_committee_output(
+    threshold_type: u8, keys: vector<vector<u8>>
+): DkgCommitteeOutput {
+    DkgCommitteeOutput { threshold_type, keys }
+}
+
+ + + +
+ + + +## Function `get_dkg_committee_output_threshold_type` + +Get threshold type from DkgCommitteeOutput + + +
public fun get_dkg_committee_output_threshold_type(output: &dkg_committee::DkgCommitteeOutput): u8
+
+ + + +
+Implementation + + +
public fun get_dkg_committee_output_threshold_type(
+    output: &DkgCommitteeOutput
+): u8 {
+    output.threshold_type
+}
+
+ + + +
+ + + +## Function `get_dkg_committee_output_keys` + +Get keys from DkgCommitteeOutput + + +
public fun get_dkg_committee_output_keys(output: &dkg_committee::DkgCommitteeOutput): vector<vector<u8>>
+
+ + + +
+Implementation + + +
public fun get_dkg_committee_output_keys(output: &DkgCommitteeOutput): vector<vector<u8>> {
+    output.keys
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/dkg_config.md b/aptos-move/framework/supra-framework/doc/dkg_config.md new file mode 100644 index 00000000000..e259fd00e0f --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/dkg_config.md @@ -0,0 +1,574 @@ + + + +# Module `0x1::dkg_config` + +DKG configuration module for configurable DKG parameters. +This config can be updated via governance and takes effect at the next epoch. + + +- [Struct `ReceiverCommitteeConfig`](#0x1_dkg_config_ReceiverCommitteeConfig) +- [Resource `DkgConfig`](#0x1_dkg_config_DkgConfig) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_dkg_config_initialize) +- [Function `set_for_next_epoch`](#0x1_dkg_config_set_for_next_epoch) +- [Function `has_key_threshold_type`](#0x1_dkg_config_has_key_threshold_type) +- [Function `on_new_epoch`](#0x1_dkg_config_on_new_epoch) +- [Function `new`](#0x1_dkg_config_new) +- [Function `new_receiver_committee_config`](#0x1_dkg_config_new_receiver_committee_config) +- [Function `default`](#0x1_dkg_config_default) +- [Function `current`](#0x1_dkg_config_current) +- [Function `get_dealer_committee_threshold_type`](#0x1_dkg_config_get_dealer_committee_threshold_type) +- [Function `get_receiver_committee_configs`](#0x1_dkg_config_get_receiver_committee_configs) +- [Function `get_is_resharing`](#0x1_dkg_config_get_is_resharing) +- [Function `get_committee_threshold_type`](#0x1_dkg_config_get_committee_threshold_type) +- [Function `get_dkg_threshold_type`](#0x1_dkg_config_get_dkg_threshold_type) + + +
use 0x1::config_buffer;
+use 0x1::error;
+use 0x1::system_addresses;
+use 0x1::validator_public_keys;
+
+ + + + + +## Struct `ReceiverCommitteeConfig` + +Configuration for a single receiver committee in DKG. + + +
struct ReceiverCommitteeConfig has copy, drop, store
+
+ + + +
+Fields + + +
+
+is_resharing: bool +
+
+ Whether this committee uses resharing from the previous epoch's public key. +
+
+committee_threshold_type: validator_public_keys::CertificateThresholdType +
+
+ The threshold type for this committee (e.g., quorum, clan_majority). +
+
+dkg_threshold_type: validator_public_keys::CertificateThresholdType +
+
+ The threshold type for output keys in DKG for this committee (e.g., validity, quorum). +
+
+ + +
+ + + +## Resource `DkgConfig` + +Main DKG configuration stored at @supra_framework. +Controls DKG parameters that can be updated via governance. + + +
struct DkgConfig has copy, drop, store, key
+
+ + + +
+Fields + + +
+
+dealer_committee_threshold_type: validator_public_keys::CertificateThresholdType +
+
+ Threshold type for the dealer committee. (e.g., quorum, clan_majority). +
+
+receiver_committees: vector<dkg_config::ReceiverCommitteeConfig> +
+
+ Configuration for each receiver committee. + Default: [(false, validity), (false, quorum)] +
+
+ + +
+ + + +## Constants + + + + +Error: Receiver committees vector cannot be empty. + + +
const EEMPTY_RECEIVER_COMMITTEES: u64 = 1;
+
+ + + + + +Error: Cannot enable resharing for a threshold type that doesn't exist in current config. + + +
const ERESHARING_FOR_NONEXISTENT_THRESHOLD_TYPE: u64 = 2;
+
+ + + + + +## Function `initialize` + +Initialize DKG config during genesis. + + +
public(friend) fun initialize(framework: &signer)
+
+ + + +
+Implementation + + +
public(friend) fun initialize(framework: &signer) {
+    system_addresses::assert_supra_framework(framework);
+    if (!exists<DkgConfig>(@supra_framework)) {
+        move_to(framework, default());
+    }
+}
+
+ + + +
+ + + +## Function `set_for_next_epoch` + +Set a new DKG config for the next epoch. +This can only be called by on-chain governance. +Example usage: +``` +let new_config = dkg_config::new( +quorum_certificate_type(), +vector[ +dkg_config::new_receiver_committee_config(true, validity_certificate_type()), +dkg_config::new_receiver_committee_config(true, quorum_certificate_type()), +] +); +dkg_config::set_for_next_epoch(&framework_signer, new_config); +supra_governance::reconfigure(&framework_signer); +``` + + +
public fun set_for_next_epoch(framework: &signer, new_config: dkg_config::DkgConfig)
+
+ + + +
+Implementation + + +
public fun set_for_next_epoch(
+    framework: &signer, new_config: DkgConfig
+) acquires DkgConfig {
+    system_addresses::assert_supra_framework(framework);
+
+    // Validate: receiver_committees cannot be empty
+    assert!(
+        vector::length(&new_config.receiver_committees) > 0,
+        error::invalid_argument(EEMPTY_RECEIVER_COMMITTEES)
+    );
+
+    // Validate: if resharing is enabled for a dkg threshold type, it must exist in current config
+    let current_config = current();
+    let i = 0;
+    let len = vector::length(&new_config.receiver_committees);
+    while (i < len) {
+        let new_rc = vector::borrow(&new_config.receiver_committees, i);
+        if (new_rc.is_resharing) {
+            // Check if this threshold type exists in current config
+            assert!(
+                has_key_threshold_type(¤t_config, new_rc.dkg_threshold_type),
+                error::invalid_argument(ERESHARING_FOR_NONEXISTENT_THRESHOLD_TYPE)
+            );
+        };
+        i = i + 1;
+    };
+
+    config_buffer::upsert(new_config);
+}
+
+ + + +
+ + + +## Function `has_key_threshold_type` + +Check if a threshold type exists in the config's receiver committees. + + +
fun has_key_threshold_type(config: &dkg_config::DkgConfig, threshold_type: validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
fun has_key_threshold_type(
+    config: &DkgConfig, threshold_type: CertificateThresholdType
+): bool {
+    let i = 0;
+    let len = vector::length(&config.receiver_committees);
+    while (i < len) {
+        let rc = vector::borrow(&config.receiver_committees, i);
+        if (rc.dkg_threshold_type == threshold_type) {
+            return true
+        };
+        i = i + 1;
+    };
+    false
+}
+
+ + + +
+ + + +## Function `on_new_epoch` + +Apply any pending DKG config at epoch boundary. +Called from reconfiguration_with_dkg::finish(). + + +
public(friend) fun on_new_epoch(framework: &signer)
+
+ + + +
+Implementation + + +
public(friend) fun on_new_epoch(framework: &signer) acquires DkgConfig {
+    system_addresses::assert_supra_framework(framework);
+    if (config_buffer::does_exist<DkgConfig>()) {
+        let new_config = config_buffer::extract<DkgConfig>();
+        if (exists<DkgConfig>(@supra_framework)) {
+            *borrow_global_mut<DkgConfig>(@supra_framework) = new_config;
+        } else {
+            move_to(framework, new_config);
+        }
+    }
+}
+
+ + + +
+ + + +## Function `new` + +Create a new DkgConfig. + + +
public fun new(dealer_committee_threshold_type: validator_public_keys::CertificateThresholdType, receiver_committees: vector<dkg_config::ReceiverCommitteeConfig>): dkg_config::DkgConfig
+
+ + + +
+Implementation + + +
public fun new(
+    dealer_committee_threshold_type: CertificateThresholdType,
+    receiver_committees: vector<ReceiverCommitteeConfig>
+): DkgConfig {
+    DkgConfig { dealer_committee_threshold_type, receiver_committees }
+}
+
+ + + +
+ + + +## Function `new_receiver_committee_config` + +Create a new ReceiverCommitteeConfig. + + +
public fun new_receiver_committee_config(is_resharing: bool, committee_threshold_type: validator_public_keys::CertificateThresholdType, dkg_threshold_type: validator_public_keys::CertificateThresholdType): dkg_config::ReceiverCommitteeConfig
+
+ + + +
+Implementation + + +
public fun new_receiver_committee_config(
+    is_resharing: bool,
+    committee_threshold_type: CertificateThresholdType,
+    dkg_threshold_type: CertificateThresholdType
+): ReceiverCommitteeConfig {
+    ReceiverCommitteeConfig {
+        is_resharing,
+        committee_threshold_type,
+        dkg_threshold_type
+    }
+}
+
+ + + +
+ + + +## Function `default` + +Returns the default DKG configuration. + +Assumes that the SUPRA_BCFT_CERTIFICATES feature flag is enabled. + + +
public fun default(): dkg_config::DkgConfig
+
+ + + +
+Implementation + + +
public fun default(): DkgConfig {
+    DkgConfig {
+        dealer_committee_threshold_type: quorum_certificate_type(),
+        receiver_committees: vector[
+            ReceiverCommitteeConfig {
+                is_resharing: false,
+                committee_threshold_type: quorum_certificate_type(),
+                dkg_threshold_type: bcft_quorum_certificate_type()
+            },
+            ReceiverCommitteeConfig {
+                is_resharing: false,
+                committee_threshold_type: quorum_certificate_type(),
+                dkg_threshold_type: bcft_validity_certificate_type()
+            },
+            ReceiverCommitteeConfig {
+                is_resharing: false,
+                committee_threshold_type: quorum_certificate_type(),
+                dkg_threshold_type: clan_majority_certificate_type()
+            }
+        ]
+    }
+}
+
+ + + +
+ + + +## Function `current` + +Get the current DKG config. + + +
public fun current(): dkg_config::DkgConfig
+
+ + + +
+Implementation + + +
public fun current(): DkgConfig acquires DkgConfig {
+    if (exists<DkgConfig>(@supra_framework)) {
+        *borrow_global<DkgConfig>(@supra_framework)
+    } else {
+        // This branch should not be executed:
+        //     1. If the network is started from genesis then the default config should be
+        //        applied during genesis.
+        //     2. If the DKG feature flag is enabled in an existing network, then governance
+        //        should set a config before enabling the feature flag.
+        //
+        // This branch exists as a fallback that ensures that the `BlockMetadata` transaction
+        // does not fail in case of misconfiguration.
+        default()
+    }
+}
+
+ + + +
+ + + +## Function `get_dealer_committee_threshold_type` + +Get the dealer threshold type from the config. + + +
public fun get_dealer_committee_threshold_type(config: &dkg_config::DkgConfig): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun get_dealer_committee_threshold_type(config: &DkgConfig):
+    CertificateThresholdType {
+    config.dealer_committee_threshold_type
+}
+
+ + + +
+ + + +## Function `get_receiver_committee_configs` + +Get the receiver committee configs from the DkgConfig. + + +
public fun get_receiver_committee_configs(config: &dkg_config::DkgConfig): vector<dkg_config::ReceiverCommitteeConfig>
+
+ + + +
+Implementation + + +
public fun get_receiver_committee_configs(config: &DkgConfig):
+    vector<ReceiverCommitteeConfig> {
+    config.receiver_committees
+}
+
+ + + +
+ + + +## Function `get_is_resharing` + +Get is_resharing from a ReceiverCommitteeConfig. + + +
public fun get_is_resharing(config: &dkg_config::ReceiverCommitteeConfig): bool
+
+ + + +
+Implementation + + +
public fun get_is_resharing(config: &ReceiverCommitteeConfig): bool {
+    config.is_resharing
+}
+
+ + + +
+ + + +## Function `get_committee_threshold_type` + +Get committee_threshold_type from a ReceiverCommitteeConfig. + + +
public fun get_committee_threshold_type(config: &dkg_config::ReceiverCommitteeConfig): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun get_committee_threshold_type(
+    config: &ReceiverCommitteeConfig
+): CertificateThresholdType {
+    config.committee_threshold_type
+}
+
+ + + +
+ + + +## Function `get_dkg_threshold_type` + +Get dkg_threshold_type from a ReceiverCommitteeConfig. + + +
public fun get_dkg_threshold_type(config: &dkg_config::ReceiverCommitteeConfig): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun get_dkg_threshold_type(config: &ReceiverCommitteeConfig):
+    CertificateThresholdType {
+    config.dkg_threshold_type
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/evm_config.md b/aptos-move/framework/supra-framework/doc/evm_config.md index 6a60a5adffc..266294bb013 100644 --- a/aptos-move/framework/supra-framework/doc/evm_config.md +++ b/aptos-move/framework/supra-framework/doc/evm_config.md @@ -11,6 +11,7 @@ - [Function `set_for_next_epoch`](#0x1_evm_config_set_for_next_epoch) - [Function `on_new_epoch`](#0x1_evm_config_on_new_epoch) - [Specification](#@Specification_1) + - [Function `initialize`](#@Specification_1_initialize) - [Function `set_for_next_epoch`](#@Specification_1_set_for_next_epoch) - [Function `on_new_epoch`](#@Specification_1_on_new_epoch) @@ -172,6 +173,22 @@ Otherwise, move the new config to supra_framework. + + +### Function `initialize` + + +
public(friend) fun initialize(supra_framework: &signer, config: vector<u8>)
+
+ + + + +
pragma aborts_if_is_strict = false;
+
+ + + ### Function `set_for_next_epoch` diff --git a/aptos-move/framework/supra-framework/doc/fungible_asset.md b/aptos-move/framework/supra-framework/doc/fungible_asset.md index a29fc11d266..bd0b0fbff9e 100644 --- a/aptos-move/framework/supra-framework/doc/fungible_asset.md +++ b/aptos-move/framework/supra-framework/doc/fungible_asset.md @@ -3009,20 +3009,34 @@ Mutate specified fields of the fungible asset's object::object_address(&metadata_ref.metadata); let mutable_metadata = borrow_global_mut<Metadata>(metadata_address); - if (option::is_some(&name)){ - mutable_metadata.name = option::extract(&mut name); + if (option::is_some(&name)) { + let new_name = option::destroy_some(name); + assert!(string::length(&new_name) <= MAX_NAME_LENGTH, error::out_of_range(ENAME_TOO_LONG)); + mutable_metadata.name = new_name; }; - if (option::is_some(&symbol)){ - mutable_metadata.symbol = option::extract(&mut symbol); + + if (option::is_some(&symbol)) { + let new_symbol = option::destroy_some(symbol); + assert!(string::length(&new_symbol) <= MAX_SYMBOL_LENGTH, error::out_of_range(ESYMBOL_TOO_LONG)); + mutable_metadata.symbol = new_symbol; }; - if (option::is_some(&decimals)){ - mutable_metadata.decimals = option::extract(&mut decimals); + + if (option::is_some(&decimals)) { + let new_decimals = option::destroy_some(decimals); + assert!(new_decimals <= MAX_DECIMALS, error::out_of_range(EDECIMALS_TOO_LARGE)); + mutable_metadata.decimals = new_decimals; }; - if (option::is_some(&icon_uri)){ - mutable_metadata.icon_uri = option::extract(&mut icon_uri); + + if (option::is_some(&icon_uri)) { + let new_icon_uri = option::destroy_some(icon_uri); + assert!(string::length(&new_icon_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG)); + mutable_metadata.icon_uri = new_icon_uri; }; - if (option::is_some(&project_uri)){ - mutable_metadata.project_uri = option::extract(&mut project_uri); + + if (option::is_some(&project_uri)) { + let new_project_uri = option::destroy_some(project_uri); + assert!(string::length(&new_project_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG)); + mutable_metadata.project_uri = new_project_uri; }; }
diff --git a/aptos-move/framework/supra-framework/doc/genesis.md b/aptos-move/framework/supra-framework/doc/genesis.md index 585539cb61c..68589c74226 100644 --- a/aptos-move/framework/supra-framework/doc/genesis.md +++ b/aptos-move/framework/supra-framework/doc/genesis.md @@ -19,6 +19,7 @@ - [Function `initialize_supra_native_automation_v2`](#0x1_genesis_initialize_supra_native_automation_v2) - [Function `initialize_core_resources_and_supra_coin`](#0x1_genesis_initialize_core_resources_and_supra_coin) - [Function `initialize_evm_genesis_config`](#0x1_genesis_initialize_evm_genesis_config) +- [Function `initialize_leader_ban_registry_config`](#0x1_genesis_initialize_leader_ban_registry_config) - [Function `create_accounts`](#0x1_genesis_create_accounts) - [Function `create_account`](#0x1_genesis_create_account) - [Function `create_multiple_multisig_accounts_with_schema`](#0x1_genesis_create_multiple_multisig_accounts_with_schema) @@ -59,12 +60,15 @@ use 0x1::coin; use 0x1::consensus_config; use 0x1::create_signer; +use 0x1::dkg_config; use 0x1::error; use 0x1::evm_genesis_config; use 0x1::execution_config; use 0x1::features; use 0x1::fixed_point32; use 0x1::gas_schedule; +use 0x1::leader_ban_registry; +use 0x1::leader_ban_registry_config; use 0x1::multisig_account; use 0x1::option; use 0x1::pbo_delegation_pool; @@ -580,14 +584,13 @@ Genesis step 1: Initialize supra framework account and core modules on chain. rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, - genesis_timestamp_in_microseconds: u64, + genesis_timestamp_in_microseconds: u64 ) { // Initialize the supra framework account. This is the account where system resources and modules will be // deployed to. This will be entirely managed by on-chain governance and no entities have the key or privileges // to use this account. - let (supra_framework_account, supra_framework_signer_cap) = account::create_framework_reserved_account( - @supra_framework - ); + let (supra_framework_account, supra_framework_signer_cap) = + account::create_framework_reserved_account(@supra_framework); // Initialize account configs on supra framework account. account::initialize(&supra_framework_account); @@ -596,21 +599,27 @@ Genesis step 1: Initialize supra framework account and core modules on chain. b"script_prologue", b"module_prologue", b"multi_agent_script_prologue", - b"epilogue", + b"epilogue" ); // Give the decentralized on-chain governance control over the core framework account. - supra_governance::store_signer_cap(&supra_framework_account, @supra_framework, supra_framework_signer_cap); + supra_governance::store_signer_cap( + &supra_framework_account, @supra_framework, supra_framework_signer_cap + ); // put reserved framework reserved accounts under supra governance let framework_reserved_addresses = vector<address>[@0x2, @0x3, @0x4, @0x5, @0x6, @0x7, @0x8, @0x9, @0xa]; while (!vector::is_empty(&framework_reserved_addresses)) { let address = vector::pop_back<address>(&mut framework_reserved_addresses); - let (_, framework_signer_cap) = account::create_framework_reserved_account(address); - supra_governance::store_signer_cap(&supra_framework_account, address, framework_signer_cap); + let (_, framework_signer_cap) = + account::create_framework_reserved_account(address); + supra_governance::store_signer_cap( + &supra_framework_account, address, framework_signer_cap + ); }; consensus_config::initialize(&supra_framework_account, consensus_config); + dkg_config::initialize(&supra_framework_account); execution_config::set(&supra_framework_account, execution_config); supra_config::initialize(&supra_framework_account, supra_config); version::initialize(&supra_framework_account, initial_version); @@ -623,7 +632,7 @@ Genesis step 1: Initialize supra framework account and core modules on chain. allow_validator_set_change, rewards_rate, rewards_rate_denominator, - voting_power_increase_limit, + voting_power_increase_limit ); storage_gas::initialize(&supra_framework_account); gas_schedule::initialize(&supra_framework_account, gas_schedule); @@ -636,7 +645,9 @@ Genesis step 1: Initialize supra framework account and core modules on chain. reconfiguration::initialize(&supra_framework_account); block::initialize(&supra_framework_account, epoch_interval_microsecs); state_storage::initialize(&supra_framework_account); - timestamp::set_time_has_started(&supra_framework_account, genesis_timestamp_in_microseconds); + timestamp::set_time_has_started( + &supra_framework_account, genesis_timestamp_in_microseconds + ); }
@@ -704,9 +715,8 @@ Deprecated in favoor of initialize_supra_native_automation_v2. _congestion_threshold_percentage: u8, _congestion_base_fee_in_quants_per_sec: u64, _congestion_exponent: u8, - _task_capacity: u16, -) { -} + _task_capacity: u16 +) {}
@@ -742,7 +752,7 @@ Genesis step 3: Initialize Supra Native Automation. cycle_duration: u64, sys_task_duration_cap_in_secs: u64, sys_registry_max_gas_cap: u64, - sys_task_capacity: u16, + sys_task_capacity: u16 ) { automation_registry::initialize( supra_framework, @@ -757,7 +767,7 @@ Genesis step 3: Initialize Supra Native Automation. task_capacity, sys_task_duration_cap_in_secs, sys_registry_max_gas_cap, - sys_task_capacity, + sys_task_capacity ) }
@@ -783,8 +793,7 @@ Only called for testnets and e2e tests.
fun initialize_core_resources_and_supra_coin(
-    supra_framework: &signer,
-    core_resources_auth_key: vector<u8>,
+    supra_framework: &signer, core_resources_auth_key: vector<u8>
 ) {
     let (burn_cap, mint_cap) = supra_coin::initialize(supra_framework);
     coin::create_coin_conversion_map(supra_framework);
@@ -798,8 +807,12 @@ Only called for testnets and e2e tests.
 
     let core_resources = account::create_account(@core_resources);
     supra_account::register_supra(&core_resources); // register Supra store
-    account::rotate_authentication_key_internal(&core_resources, core_resources_auth_key);
-    supra_coin::configure_accounts_for_test(supra_framework, &core_resources, mint_cap);
+    account::rotate_authentication_key_internal(
+        &core_resources, core_resources_auth_key
+    );
+    supra_coin::configure_accounts_for_test(
+        supra_framework, &core_resources, mint_cap
+    );
 }
 
@@ -824,8 +837,7 @@ Initialize the EVM genesis config.
fun initialize_evm_genesis_config(
-    supra_framework: &signer,
-    evm_genesis_config: vector<u8>,
+    supra_framework: &signer, evm_genesis_config: vector<u8>
 ) {
     evm_genesis_config::initialize(supra_framework, evm_genesis_config);
 }
@@ -833,6 +845,36 @@ Initialize the EVM genesis config.
 
 
 
+
+
+
+
+## Function `initialize_leader_ban_registry_config`
+
+Initialize the leader ban config
+
+
+
fun initialize_leader_ban_registry_config(supra_framework: &signer, leader_ban_registry_config: vector<u8>)
+
+ + + +
+Implementation + + +
fun initialize_leader_ban_registry_config(
+    supra_framework: &signer, leader_ban_registry_config: vector<u8>
+) {
+    leader_ban_registry_config::initialize(
+        supra_framework, leader_ban_registry_config
+    );
+    leader_ban_registry::initialize_leader_ban_registry(supra_framework);
+}
+
+ + +
@@ -850,22 +892,27 @@ Initialize the EVM genesis config. Implementation -
fun create_accounts(supra_framework: &signer, accounts: vector<AccountMap>) {
+
fun create_accounts(
+    supra_framework: &signer, accounts: vector<AccountMap>
+) {
     let unique_accounts = vector::empty();
-    vector::for_each_ref(&accounts, |account_map| {
-        let account_map: &AccountMap = account_map;
-        assert!(
-            !vector::contains(&unique_accounts, &account_map.account_address),
-            error::already_exists(EDUPLICATE_ACCOUNT),
-        );
-        vector::push_back(&mut unique_accounts, account_map.account_address);
+    vector::for_each_ref(
+        &accounts,
+        |account_map| {
+            let account_map: &AccountMap = account_map;
+            assert!(
+                !vector::contains(&unique_accounts, &account_map.account_address),
+                error::already_exists(EDUPLICATE_ACCOUNT)
+            );
+            vector::push_back(&mut unique_accounts, account_map.account_address);
 
-        create_account(
-            supra_framework,
-            account_map.account_address,
-            account_map.balance,
-        );
-    });
+            create_account(
+                supra_framework,
+                account_map.account_address,
+                account_map.balance
+            );
+        }
+    );
 }
 
@@ -890,7 +937,9 @@ If it exists, it just returns the signer. Implementation -
fun create_account(supra_framework: &signer, account_address: address, balance: u64): signer {
+
fun create_account(
+    supra_framework: &signer, account_address: address, balance: u64
+): signer {
     if (account::exists_at(account_address)) {
         create_signer(account_address)
     } else {
@@ -935,8 +984,17 @@ If it exists, it just returns the signer.
     let counter = 0;
     let result = vector::empty();
     while (counter < num_of_accounts) {
-        let account_addr = create_multisig_account_with_balance(supra_framework, owner, additional_owners,
-            num_signatures_required, metadata_keys, metadata_values, timeout_duration, balance);
+        let account_addr =
+            create_multisig_account_with_balance(
+                supra_framework,
+                owner,
+                additional_owners,
+                num_signatures_required,
+                metadata_keys,
+                metadata_values,
+                timeout_duration,
+                balance
+            );
         vector::push_back(&mut result, account_addr);
         counter = counter + 1;
     };
@@ -971,11 +1029,17 @@ If it exists, it just returns the signer.
     metadata_keys: vector<String>,
     metadata_values: vector<vector<u8>>,
     timeout_duration: u64,
-    balance: u64,
+    balance: u64
 ): address {
-    assert!(account::exists_at(owner), error::invalid_argument(EACCOUNT_DOES_NOT_EXIST));
     assert!(
-        vector::all(&additional_owners, |ao_addr|{ account::exists_at(*ao_addr) }),
+        account::exists_at(owner),
+        error::invalid_argument(EACCOUNT_DOES_NOT_EXIST)
+    );
+    assert!(
+        vector::all(
+            &additional_owners,
+            |ao_addr| { account::exists_at(*ao_addr) }
+        ),
         error::invalid_argument(EACCOUNT_DOES_NOT_EXIST)
     );
     let addr = multisig_account::get_next_multisig_account_address(owner);
@@ -1016,90 +1080,104 @@ If it exists, it just returns the signer.
 
fun create_employee_validators(
     employee_vesting_start: u64,
     employee_vesting_period_duration: u64,
-    employees: vector<EmployeeAccountMap>,
+    employees: vector<EmployeeAccountMap>
 ) {
     let unique_accounts = vector::empty();
 
-    vector::for_each_ref(&employees, |employee_group| {
-        let j = 0;
-        let employee_group: &EmployeeAccountMap = employee_group;
-        let num_employees_in_group = vector::length(&employee_group.accounts);
-
-        let buy_ins = simple_map::create();
-
-        while (j < num_employees_in_group) {
-            let account = vector::borrow(&employee_group.accounts, j);
+    vector::for_each_ref(
+        &employees,
+        |employee_group| {
+            let j = 0;
+            let employee_group: &EmployeeAccountMap = employee_group;
+            let num_employees_in_group = vector::length(&employee_group.accounts);
+
+            let buy_ins = simple_map::create();
+
+            while (j < num_employees_in_group) {
+                let account = vector::borrow(&employee_group.accounts, j);
+                assert!(
+                    !vector::contains(&unique_accounts, account),
+                    error::already_exists(EDUPLICATE_ACCOUNT)
+                );
+                vector::push_back(&mut unique_accounts, *account);
+
+                let employee = create_signer(*account);
+                let total = coin::balance<SupraCoin>(*account);
+                let coins = coin::withdraw<SupraCoin>(&employee, total);
+                simple_map::add(&mut buy_ins, *account, coins);
+
+                j = j + 1;
+            };
+
+            let j = 0;
+            let num_vesting_events = vector::length(
+                &employee_group.vesting_schedule_numerator
+            );
+            let schedule = vector::empty();
+
+            while (j < num_vesting_events) {
+                let numerator = vector::borrow(
+                    &employee_group.vesting_schedule_numerator, j
+                );
+                let event =
+                    fixed_point32::create_from_rational(
+                        *numerator,
+                        employee_group.vesting_schedule_denominator
+                    );
+                vector::push_back(&mut schedule, event);
+
+                j = j + 1;
+            };
+
+            let vesting_schedule =
+                vesting::create_vesting_schedule(
+                    schedule,
+                    employee_vesting_start,
+                    employee_vesting_period_duration
+                );
+
+            let admin = employee_group.validator.validator_config.owner_address;
+            let admin_signer = &create_signer(admin);
+            let contract_address =
+                vesting::create_vesting_contract(
+                    admin_signer,
+                    &employee_group.accounts,
+                    buy_ins,
+                    vesting_schedule,
+                    admin,
+                    employee_group.validator.validator_config.operator_address,
+                    employee_group.validator.validator_config.voter_address,
+                    employee_group.validator.commission_percentage,
+                    x""
+                );
+            let pool_address = vesting::stake_pool_address(contract_address);
+
+            if (employee_group.beneficiary_resetter != @0x0) {
+                vesting::set_beneficiary_resetter(
+                    admin_signer,
+                    contract_address,
+                    employee_group.beneficiary_resetter
+                );
+            };
+
+            let validator = &employee_group.validator.validator_config;
             assert!(
-                !vector::contains(&unique_accounts, account),
-                error::already_exists(EDUPLICATE_ACCOUNT),
+                account::exists_at(validator.owner_address),
+                error::not_found(EACCOUNT_DOES_NOT_EXIST)
             );
-            vector::push_back(&mut unique_accounts, *account);
-
-            let employee = create_signer(*account);
-            let total = coin::balance<SupraCoin>(*account);
-            let coins = coin::withdraw<SupraCoin>(&employee, total);
-            simple_map::add(&mut buy_ins, *account, coins);
-
-            j = j + 1;
-        };
-
-        let j = 0;
-        let num_vesting_events = vector::length(&employee_group.vesting_schedule_numerator);
-        let schedule = vector::empty();
-
-        while (j < num_vesting_events) {
-            let numerator = vector::borrow(&employee_group.vesting_schedule_numerator, j);
-            let event = fixed_point32::create_from_rational(
-                *numerator,
-                employee_group.vesting_schedule_denominator
+            assert!(
+                account::exists_at(validator.operator_address),
+                error::not_found(EACCOUNT_DOES_NOT_EXIST)
             );
-            vector::push_back(&mut schedule, event);
-
-            j = j + 1;
-        };
-
-        let vesting_schedule = vesting::create_vesting_schedule(
-            schedule,
-            employee_vesting_start,
-            employee_vesting_period_duration,
-        );
-
-        let admin = employee_group.validator.validator_config.owner_address;
-        let admin_signer = &create_signer(admin);
-        let contract_address = vesting::create_vesting_contract(
-            admin_signer,
-            &employee_group.accounts,
-            buy_ins,
-            vesting_schedule,
-            admin,
-            employee_group.validator.validator_config.operator_address,
-            employee_group.validator.validator_config.voter_address,
-            employee_group.validator.commission_percentage,
-            x"",
-        );
-        let pool_address = vesting::stake_pool_address(contract_address);
-
-        if (employee_group.beneficiary_resetter != @0x0) {
-            vesting::set_beneficiary_resetter(admin_signer, contract_address, employee_group.beneficiary_resetter);
-        };
-
-        let validator = &employee_group.validator.validator_config;
-        assert!(
-            account::exists_at(validator.owner_address),
-            error::not_found(EACCOUNT_DOES_NOT_EXIST),
-        );
-        assert!(
-            account::exists_at(validator.operator_address),
-            error::not_found(EACCOUNT_DOES_NOT_EXIST),
-        );
-        assert!(
-            account::exists_at(validator.voter_address),
-            error::not_found(EACCOUNT_DOES_NOT_EXIST),
-        );
-        if (employee_group.validator.join_during_genesis) {
-            initialize_validator(pool_address, validator);
-        };
-    });
+            assert!(
+                account::exists_at(validator.voter_address),
+                error::not_found(EACCOUNT_DOES_NOT_EXIST)
+            );
+            if (employee_group.validator.join_during_genesis) {
+                initialize_validator(pool_address, validator);
+            };
+        }
+    );
 }
 
@@ -1126,12 +1204,17 @@ DEPRECATED
fun create_initialize_validators_with_commission(
     supra_framework: &signer,
     use_staking_contract: bool,
-    validators: vector<ValidatorConfigurationWithCommission>,
+    validators: vector<ValidatorConfigurationWithCommission>
 ) {
-    vector::for_each_ref(&validators, |validator| {
-        let validator: &ValidatorConfigurationWithCommission = validator;
-        create_initialize_validator(supra_framework, validator, use_staking_contract);
-    });
+    vector::for_each_ref(
+        &validators,
+        |validator| {
+            let validator: &ValidatorConfigurationWithCommission = validator;
+            create_initialize_validator(
+                supra_framework, validator, use_staking_contract
+            );
+        }
+    );
 }
 
@@ -1166,18 +1249,27 @@ encoded in a single BCS byte array. Implementation -
fun create_initialize_validators(supra_framework: &signer, validators: vector<ValidatorConfiguration>) {
+
fun create_initialize_validators(
+    supra_framework: &signer, validators: vector<ValidatorConfiguration>
+) {
     let validators_with_commission = vector::empty();
-    vector::for_each_reverse(validators, |validator| {
-        let validator_with_commission = ValidatorConfigurationWithCommission {
-            validator_config: validator,
-            commission_percentage: 0,
-            join_during_genesis: true,
-        };
-        vector::push_back(&mut validators_with_commission, validator_with_commission);
-    });
+    vector::for_each_reverse(
+        validators,
+        |validator| {
+            let validator_with_commission = ValidatorConfigurationWithCommission {
+                validator_config: validator,
+                commission_percentage: 0,
+                join_during_genesis: true
+            };
+            vector::push_back(
+                &mut validators_with_commission, validator_with_commission
+            );
+        }
+    );
 
-    create_initialize_validators_with_commission(supra_framework, false, validators_with_commission);
+    create_initialize_validators_with_commission(
+        supra_framework, false, validators_with_commission
+    );
 }
 
@@ -1203,34 +1295,40 @@ encoded in a single BCS byte array.
fun create_initialize_validator(
     supra_framework: &signer,
     commission_config: &ValidatorConfigurationWithCommission,
-    use_staking_contract: bool,
+    use_staking_contract: bool
 ) {
     let validator = &commission_config.validator_config;
 
-    let owner = &create_account(supra_framework, validator.owner_address, validator.stake_amount);
+    let owner =
+        &create_account(
+            supra_framework, validator.owner_address, validator.stake_amount
+        );
     create_account(supra_framework, validator.operator_address, 0);
     create_account(supra_framework, validator.voter_address, 0);
 
     // Initialize the stake pool and join the validator set.
-    let pool_address = if (use_staking_contract) {
-        staking_contract::create_staking_contract(
-            owner,
-            validator.operator_address,
-            validator.voter_address,
-            validator.stake_amount,
-            commission_config.commission_percentage,
-            x"",
-        );
-        staking_contract::stake_pool_address(validator.owner_address, validator.operator_address)
-    } else {
-        stake::initialize_stake_owner(
-            owner,
-            validator.stake_amount,
-            validator.operator_address,
-            validator.voter_address,
-        );
-        validator.owner_address
-    };
+    let pool_address =
+        if (use_staking_contract) {
+            staking_contract::create_staking_contract(
+                owner,
+                validator.operator_address,
+                validator.voter_address,
+                validator.stake_amount,
+                commission_config.commission_percentage,
+                x""
+            );
+            staking_contract::stake_pool_address(
+                validator.owner_address, validator.operator_address
+            )
+        } else {
+            stake::initialize_stake_owner(
+                owner,
+                validator.stake_amount,
+                validator.operator_address,
+                validator.voter_address
+            );
+            validator.owner_address
+        };
 
     if (commission_config.join_during_genesis) {
         initialize_validator(pool_address, validator);
@@ -1259,20 +1357,32 @@ encoded in a single BCS byte array.
 
 
fun create_pbo_delegation_pools(
     pbo_delegator_configs: vector<PboDelegatorConfiguration>,
-    delegation_percentage: u64,
+    delegation_percentage: u64
 ) {
     let unique_accounts: vector<address> = vector::empty();
     assert!(
         delegation_percentage != 0 && delegation_percentage <= 100,
         error::invalid_argument(EPERCENTAGE_INVALID)
     );
-    vector::for_each_ref(&pbo_delegator_configs, |pbo_delegator_config| {
-        let pbo_delegator_config: &PboDelegatorConfiguration = pbo_delegator_config;
-        assert!(!vector::contains(&unique_accounts, &pbo_delegator_config.delegator_config.owner_address),
-            error::invalid_argument(EDUPLICATE_ACCOUNT));
-        vector::push_back(&mut unique_accounts, pbo_delegator_config.delegator_config.owner_address);
-        create_pbo_delegation_pool(pbo_delegator_config, delegation_percentage);
-    });
+    vector::for_each_ref(
+        &pbo_delegator_configs,
+        |pbo_delegator_config| {
+            let pbo_delegator_config: &PboDelegatorConfiguration =
+                pbo_delegator_config;
+            assert!(
+                !vector::contains(
+                    &unique_accounts,
+                    &pbo_delegator_config.delegator_config.owner_address
+                ),
+                error::invalid_argument(EDUPLICATE_ACCOUNT)
+            );
+            vector::push_back(
+                &mut unique_accounts,
+                pbo_delegator_config.delegator_config.owner_address
+            );
+            create_pbo_delegation_pool(pbo_delegator_config, delegation_percentage);
+        }
+    );
 }
 
@@ -1296,33 +1406,40 @@ encoded in a single BCS byte array.
fun create_pbo_delegation_pool(
-    pbo_delegator_config: &PboDelegatorConfiguration,
-    delegation_percentage: u64,
+    pbo_delegator_config: &PboDelegatorConfiguration, delegation_percentage: u64
 ) {
     assert!(
         delegation_percentage != 0 && delegation_percentage <= 100,
         error::invalid_argument(EPERCENTAGE_INVALID)
     );
     let unique_accounts: vector<address> = vector::empty();
-    vector::for_each_ref(&pbo_delegator_config.delegator_config.delegator_addresses, |delegator_address| {
-        let delegator_address: &address = delegator_address;
-        assert!(
-            !vector::contains(&unique_accounts, delegator_address),
-            error::already_exists(EDUPLICATE_ACCOUNT),
-        );
-        vector::push_back(&mut unique_accounts, *delegator_address);
-    });
-    let owner_signer = create_signer(pbo_delegator_config.delegator_config.owner_address);
+    vector::for_each_ref(
+        &pbo_delegator_config.delegator_config.delegator_addresses,
+        |delegator_address| {
+            let delegator_address: &address = delegator_address;
+            assert!(
+                !vector::contains(&unique_accounts, delegator_address),
+                error::already_exists(EDUPLICATE_ACCOUNT)
+            );
+            vector::push_back(&mut unique_accounts, *delegator_address);
+        }
+    );
+    let owner_signer =
+        create_signer(pbo_delegator_config.delegator_config.owner_address);
     // get a list of delegator addresses, withdraw the coin from them and merge them into a single account
-    let delegator_addresses = pbo_delegator_config.delegator_config.delegator_addresses;
+    let delegator_addresses =
+        pbo_delegator_config.delegator_config.delegator_addresses;
     let coinInitialization = coin::zero<SupraCoin>();
-    vector::for_each(delegator_addresses, |delegator_address| {
-        let delegator = &create_signer(delegator_address);
-        let total = coin::balance<SupraCoin>(delegator_address);
-        let withdraw_amount = total * delegation_percentage / 100;
-        let coins = coin::withdraw<SupraCoin>(delegator, withdraw_amount);
-        coin::merge(&mut coinInitialization, coins);
-    });
+    vector::for_each(
+        delegator_addresses,
+        |delegator_address| {
+            let delegator = &create_signer(delegator_address);
+            let total = coin::balance<SupraCoin>(delegator_address);
+            let withdraw_amount = total * delegation_percentage / 100;
+            let coins = coin::withdraw<SupraCoin>(delegator, withdraw_amount);
+            coin::merge(&mut coinInitialization, coins);
+        }
+    );
     pbo_delegation_pool::initialize_delegation_pool(
         &owner_signer,
         option::some(pbo_delegator_config.multisig_admin),
@@ -1333,13 +1450,15 @@ encoded in a single BCS byte array.
         coinInitialization,
         pbo_delegator_config.unlock_schedule_numerators,
         pbo_delegator_config.unlock_schedule_denominator,
-        pbo_delegator_config.unlock_startup_time_from_now + timestamp::now_seconds(),
-        pbo_delegator_config.unlock_period_duration,
+        pbo_delegator_config.unlock_startup_time_from_now
+            + timestamp::now_seconds(),
+        pbo_delegator_config.unlock_period_duration
     );
 
-    let pool_address = pbo_delegation_pool::get_owned_pool_address(
-        pbo_delegator_config.delegator_config.owner_address
-    );
+    let pool_address =
+        pbo_delegation_pool::get_owned_pool_address(
+            pbo_delegator_config.delegator_config.owner_address
+        );
     let validator = pbo_delegator_config.delegator_config.validator.validator_config;
     pbo_delegation_pool::set_operator(&owner_signer, validator.operator_address);
     pbo_delegation_pool::set_delegated_voter(&owner_signer, validator.voter_address);
@@ -1370,18 +1489,20 @@ encoded in a single BCS byte array.
 Implementation
 
 
-
fun assert_validator_addresses_check(validator: &ValidatorConfiguration) {
+
fun assert_validator_addresses_check(
+    validator: &ValidatorConfiguration
+) {
     assert!(
         account::exists_at(validator.owner_address),
-        error::not_found(EACCOUNT_DOES_NOT_EXIST),
+        error::not_found(EACCOUNT_DOES_NOT_EXIST)
     );
     assert!(
         account::exists_at(validator.operator_address),
-        error::not_found(EACCOUNT_DOES_NOT_EXIST),
+        error::not_found(EACCOUNT_DOES_NOT_EXIST)
     );
     assert!(
         account::exists_at(validator.voter_address),
-        error::not_found(EACCOUNT_DOES_NOT_EXIST),
+        error::not_found(EACCOUNT_DOES_NOT_EXIST)
     );
 }
 
@@ -1409,66 +1530,95 @@ encoded in a single BCS byte array. vesting_pool_map: vector<VestingPoolsMap> ) { let unique_accounts: vector<address> = vector::empty(); - vector::for_each_ref(&vesting_pool_map, |pool_config|{ - let pool_config: &VestingPoolsMap = pool_config; - let schedule = vector::empty(); - let schedule_length = vector::length(&pool_config.vesting_numerators); - assert!(schedule_length != 0, error::invalid_argument(EVESTING_SCHEDULE_IS_ZERO)); - assert!(pool_config.vesting_denominator != 0, error::invalid_argument(EDENOMINATOR_IS_ZERO)); - assert!(pool_config.vpool_locking_percentage != 0 && pool_config.vpool_locking_percentage <= 100, - error::invalid_argument(EPERCENTAGE_INVALID)); - //check the sum of numerator are <= denominator. - let sum = vector::fold(pool_config.vesting_numerators, 0, |acc, x| acc + x); - // Check that total of all fraction in `vesting_schedule` is not greater than 1 - assert!(sum <= pool_config.vesting_denominator, - error::invalid_argument(ENUMERATOR_GREATER_THAN_DENOMINATOR)); - //assert that withdrawal_address is registered to receive SupraCoin - assert!( - coin::is_account_registered<SupraCoin>(pool_config.withdrawal_address), - error::invalid_argument(EACCOUNT_NOT_REGISTERED_FOR_COIN) - ); - //assertion on admin_address? - let admin = create_signer(pool_config.admin_address); - - //Create the vesting schedule - let j = 0; - while (j < schedule_length) { - let numerator = *vector::borrow(&pool_config.vesting_numerators, j); - assert!(numerator != 0, error::invalid_argument(ENUMERATOR_IS_ZERO)); - let event = fixed_point32::create_from_rational(numerator, pool_config.vesting_denominator); - vector::push_back(&mut schedule, event); - j = j + 1; - }; - - let vesting_schedule = vesting_without_staking::create_vesting_schedule( - schedule, - timestamp::now_seconds() + pool_config.cliff_period_in_seconds, - pool_config.period_duration_in_seconds, - ); - - let buy_ins = simple_map::create(); - let num_shareholders = vector::length(&pool_config.shareholders); - assert!(num_shareholders != 0, error::invalid_argument(ENO_SHAREHOLDERS)); - let j = 0; - while (j < num_shareholders) { - let shareholder = *vector::borrow(&pool_config.shareholders, j); - assert!(!vector::contains(&unique_accounts, &shareholder), error::already_exists(EDUPLICATE_ACCOUNT)); - vector::push_back(&mut unique_accounts, shareholder); - let shareholder_signer = create_signer(shareholder); - let amount = coin::balance<SupraCoin>(shareholder); - let amount_to_extract = (amount * (pool_config.vpool_locking_percentage as u64)) / 100; - let coin_share = coin::withdraw<SupraCoin>(&shareholder_signer, amount_to_extract); - simple_map::add(&mut buy_ins, shareholder, coin_share); - j = j + 1; - }; - vesting_without_staking::create_vesting_contract( - &admin, - buy_ins, - vesting_schedule, - pool_config.withdrawal_address, - VESTING_CONTRACT_SEED - ); - }); + vector::for_each_ref( + &vesting_pool_map, + |pool_config| { + let pool_config: &VestingPoolsMap = pool_config; + let schedule = vector::empty(); + let schedule_length = vector::length(&pool_config.vesting_numerators); + assert!( + schedule_length != 0, + error::invalid_argument(EVESTING_SCHEDULE_IS_ZERO) + ); + assert!( + pool_config.vesting_denominator != 0, + error::invalid_argument(EDENOMINATOR_IS_ZERO) + ); + assert!( + pool_config.vpool_locking_percentage != 0 + && pool_config.vpool_locking_percentage <= 100, + error::invalid_argument(EPERCENTAGE_INVALID) + ); + //check the sum of numerator are <= denominator. + let sum = vector::fold( + pool_config.vesting_numerators, + 0, + |acc, x| acc + x + ); + // Check that total of all fraction in `vesting_schedule` is not greater than 1 + assert!( + sum <= pool_config.vesting_denominator, + error::invalid_argument(ENUMERATOR_GREATER_THAN_DENOMINATOR) + ); + //assert that withdrawal_address is registered to receive SupraCoin + assert!( + coin::is_account_registered<SupraCoin>(pool_config.withdrawal_address), + error::invalid_argument(EACCOUNT_NOT_REGISTERED_FOR_COIN) + ); + //assertion on admin_address? + let admin = create_signer(pool_config.admin_address); + + //Create the vesting schedule + let j = 0; + while (j < schedule_length) { + let numerator = *vector::borrow(&pool_config.vesting_numerators, j); + assert!(numerator != 0, error::invalid_argument(ENUMERATOR_IS_ZERO)); + let event = + fixed_point32::create_from_rational( + numerator, pool_config.vesting_denominator + ); + vector::push_back(&mut schedule, event); + j = j + 1; + }; + + let vesting_schedule = + vesting_without_staking::create_vesting_schedule( + schedule, + timestamp::now_seconds() + pool_config.cliff_period_in_seconds, + pool_config.period_duration_in_seconds + ); + + let buy_ins = simple_map::create(); + let num_shareholders = vector::length(&pool_config.shareholders); + assert!(num_shareholders != 0, error::invalid_argument(ENO_SHAREHOLDERS)); + let j = 0; + while (j < num_shareholders) { + let shareholder = *vector::borrow(&pool_config.shareholders, j); + assert!( + !vector::contains(&unique_accounts, &shareholder), + error::already_exists(EDUPLICATE_ACCOUNT) + ); + vector::push_back(&mut unique_accounts, shareholder); + let shareholder_signer = create_signer(shareholder); + let amount = coin::balance<SupraCoin>(shareholder); + let amount_to_extract = + (amount * (pool_config.vpool_locking_percentage as u64)) / 100; + let coin_share = + coin::withdraw<SupraCoin>( + &shareholder_signer, amount_to_extract + ); + simple_map::add(&mut buy_ins, shareholder, coin_share); + j = j + 1; + }; + vesting_without_staking::create_vesting_contract( + &admin, + buy_ins, + vesting_schedule, + pool_config.withdrawal_address, + VESTING_CONTRACT_SEED + ); + } + ); }
@@ -1491,19 +1641,21 @@ encoded in a single BCS byte array. Implementation -
fun initialize_validator(pool_address: address, validator: &ValidatorConfiguration) {
+
fun initialize_validator(
+    pool_address: address, validator: &ValidatorConfiguration
+) {
     let operator = &create_signer(validator.operator_address);
 
     stake::rotate_consensus_key_genesis(
         operator,
         pool_address,
-        validator.consensus_pubkey,
+        validator.consensus_pubkey
     );
     stake::update_network_and_fullnode_addresses(
         operator,
         pool_address,
         validator.network_addresses,
-        validator.full_node_network_addresses,
+        validator.full_node_network_addresses
     );
     stake::join_validator_set_internal(operator, pool_address);
 }
@@ -1602,10 +1754,12 @@ The last step of genesis.
         rewards_rate,
         rewards_rate_denominator,
         voting_power_increase_limit,
-        0,
+        0
 
     );
-    features::change_feature_flags_for_verification(supra_framework, vector[1, 2, 11], vector[]);
+    features::change_feature_flags_for_verification(
+        supra_framework, vector[1, 2, 11], vector[]
+    );
     initialize_supra_coin(supra_framework);
     supra_governance::initialize_for_verification(
         supra_framework,
@@ -1613,10 +1767,12 @@ The last step of genesis.
         // required_proposer_stake,
         voting_duration_secs,
         supra_min_voting_threshold,
-        voters,
+        voters
     );
     create_accounts(supra_framework, accounts);
-    create_employee_validators(employee_vesting_start, employee_vesting_period_duration, employees);
+    create_employee_validators(
+        employee_vesting_start, employee_vesting_period_duration, employees
+    );
     create_initialize_validators_with_commission(supra_framework, true, validators);
     set_genesis_end(supra_framework);
 }
diff --git a/aptos-move/framework/supra-framework/doc/leader_ban_registry.md b/aptos-move/framework/supra-framework/doc/leader_ban_registry.md
new file mode 100644
index 00000000000..61973eb553f
--- /dev/null
+++ b/aptos-move/framework/supra-framework/doc/leader_ban_registry.md
@@ -0,0 +1,1165 @@
+
+
+
+# Module `0x1::leader_ban_registry`
+
+Maintains the list of banned validators and updates counters on every epoch.
+
+This implementation assumes that each validator is elected once every n consensus rounds on expectation,
+where n is the number of validators in the consensus committee (i.e. the ValidatorSet).
+
+
+-  [Struct `ActiveBan`](#0x1_leader_ban_registry_ActiveBan)
+-  [Struct `ValidatorBans`](#0x1_leader_ban_registry_ValidatorBans)
+-  [Resource `BanRegistry`](#0x1_leader_ban_registry_BanRegistry)
+-  [Resource `LatestView`](#0x1_leader_ban_registry_LatestView)
+-  [Struct `Banned`](#0x1_leader_ban_registry_Banned)
+-  [Struct `ReinstatedWithProbation`](#0x1_leader_ban_registry_ReinstatedWithProbation)
+-  [Struct `Reinstated`](#0x1_leader_ban_registry_Reinstated)
+-  [Constants](#@Constants_0)
+-  [Function `initialize_leader_ban_registry`](#0x1_leader_ban_registry_initialize_leader_ban_registry)
+-  [Function `get_ban_registry`](#0x1_leader_ban_registry_get_ban_registry)
+-  [Function `get_latest_view`](#0x1_leader_ban_registry_get_latest_view)
+-  [Function `get_initial_ban_duration`](#0x1_leader_ban_registry_get_initial_ban_duration)
+-  [Function `get_max_ban_duration`](#0x1_leader_ban_registry_get_max_ban_duration)
+-  [Function `get_probation_duration`](#0x1_leader_ban_registry_get_probation_duration)
+-  [Function `get_remaining_ban_duration`](#0x1_leader_ban_registry_get_remaining_ban_duration)
+-  [Function `get_remaining_probation_duration`](#0x1_leader_ban_registry_get_remaining_probation_duration)
+-  [Function `update_ban_registry`](#0x1_leader_ban_registry_update_ban_registry)
+-  [Function `ban_failed_proposers`](#0x1_leader_ban_registry_ban_failed_proposers)
+-  [Function `reinstate_expired_bans`](#0x1_leader_ban_registry_reinstate_expired_bans)
+-  [Function `on_new_epoch`](#0x1_leader_ban_registry_on_new_epoch)
+-  [Function `remaining_ban_duration`](#0x1_leader_ban_registry_remaining_ban_duration)
+-  [Function `remaining_probation_duration`](#0x1_leader_ban_registry_remaining_probation_duration)
+-  [Function `can_be_banned`](#0x1_leader_ban_registry_can_be_banned)
+-  [Function `assert_registry_initialized`](#0x1_leader_ban_registry_assert_registry_initialized)
+
+
+
use 0x1::error;
+use 0x1::event;
+use 0x1::features;
+use 0x1::leader_ban_registry_config;
+use 0x1::math64;
+use 0x1::option;
+use 0x1::stake;
+use 0x1::system_addresses;
+use 0x1::vector;
+
+ + + + + +## Struct `ActiveBan` + +Information about a ban that is currently in effect for a validator. + + +
struct ActiveBan has copy, drop, store
+
+ + + +
+Fields + + +
+
+epoch_earned: u64 +
+
+ The consensus epoch in which the current ban was issued (if on_probation is false) or + when its probation period started (if on_probation is true). +
+
+round_earned: u64 +
+
+ The consensus round in which the current ban was issued (if on_probation is false) or + when its probation period started (if on_probation is true). +
+
+rounds_served_in_previous_epochs: u64 +
+
+ Round count incremented on every epoch change +
+
+on_probation: bool +
+
+ If true then the current ban period has expired and the validator is currently on probation; i.e., it is + eligible for election but will be banned for a longer period if it once again fails to propose a canonical + block when elected. If true then the other fields of this struct denote the consensus view in which + the probation period started. +
+
+ + +
+ + + +## Struct `ValidatorBans` + +Holds validator metrics regarding duration pool address etc + + +
struct ValidatorBans has copy, drop, store
+
+ + + +
+Fields + + +
+
+active: leader_ban_registry::ActiveBan +
+
+ Information about the ban that is currently in effect. +
+
+consecutive_bans: u32 +
+
+ The number of consecutive probations that this validator has failed. +
+
+pool_address: address +
+
+ Validator's pool address +
+
+ + +
+ + + +## Resource `BanRegistry` + +Holds ban registry + + +
struct BanRegistry has drop, store, key
+
+ + + +
+Fields + + +
+
+bans: vector<leader_ban_registry::ValidatorBans> +
+
+ List of validator active bans with pool address +
+
+ + +
+ + + +## Resource `LatestView` + +Holds latest processed round and epoch + + +
struct LatestView has copy, drop, store, key
+
+ + + +
+Fields + + +
+
+epoch: u64 +
+
+ Epoch +
+
+round: u64 +
+
+ Round +
+
+ + +
+ + + +## Struct `Banned` + +Emits when validator receives a ban or consucutive ban occurred + + +
#[event]
+struct Banned has drop, store
+
+ + + +
+Fields + + +
+
+pool_address: address +
+
+ Validator's pool address +
+
+epoch: u64 +
+
+ Epoch +
+
+round: u64 +
+
+ Round +
+
+consecutive_bans: u32 +
+
+ The number of consecutive probations that this validator has failed. +
+
+ + +
+ + + +## Struct `ReinstatedWithProbation` + +Emitted when a validator's ban is lifted and its probation period starts. A validator that is on probation is +eligible for election again, but will be banned for longer if it once again fails to propose a canonical block. + + +
#[event]
+struct ReinstatedWithProbation has drop, store
+
+ + + +
+Fields + + +
+
+pool_address: address +
+
+ Validator's pool address +
+
+epoch: u64 +
+
+ Epoch +
+
+round: u64 +
+
+ Round +
+
+ + +
+ + + +## Struct `Reinstated` + +Emitted when a validator's probation period ends without the validator earning a new ban. + + +
#[event]
+struct Reinstated has drop, store
+
+ + + +
+Fields + + +
+
+pool_address: address +
+
+ Validator's pool address +
+
+epoch: u64 +
+
+ Epoch +
+
+round: u64 +
+
+ Round +
+
+ + +
+ + + +## Constants + + + + +Leader ban registry already initialized + + +
const EBAN_REGISTRY_ALREADY_EXISTS: u64 = 1;
+
+ + + + + +Leader ban registry not initialized + + +
const EBAN_REGISTRY_NOT_INITIALIZED: u64 = 2;
+
+ + + + + +Latest view already initialized + + +
const ELATEST_VIEW_ALREADY_EXISTS: u64 = 3;
+
+ + + + + +## Function `initialize_leader_ban_registry` + +Initialise leader ban registry + + +
public(friend) fun initialize_leader_ban_registry(supra_framework: &signer)
+
+ + + +
+Implementation + + +
public(friend) fun initialize_leader_ban_registry(
+    supra_framework: &signer
+) {
+    system_addresses::assert_supra_framework(supra_framework);
+    assert!(
+        !exists<BanRegistry>(@supra_framework),
+        error::already_exists(EBAN_REGISTRY_ALREADY_EXISTS)
+    );
+    assert!(
+        !exists<LatestView>(@supra_framework),
+        error::already_exists(EBAN_REGISTRY_ALREADY_EXISTS)
+    );
+    move_to(supra_framework, BanRegistry { bans: vector::empty() });
+    move_to(supra_framework, LatestView { epoch: 0, round: 0 });
+}
+
+ + + +
+ + + +## Function `get_ban_registry` + +Returns list of validators active ban with it's pool address + + +
#[view]
+public fun get_ban_registry(): vector<leader_ban_registry::ValidatorBans>
+
+ + + +
+Implementation + + +
public fun get_ban_registry(): vector<ValidatorBans> acquires BanRegistry {
+    if (!exists<BanRegistry>(@supra_framework)) {
+        return vector::empty()
+    };
+    let ban_registry = borrow_global<BanRegistry>(@supra_framework);
+    ban_registry.bans
+}
+
+ + + +
+ + + +## Function `get_latest_view` + +Return latest view + + +
#[view]
+public fun get_latest_view(): leader_ban_registry::LatestView
+
+ + + +
+Implementation + + +
public fun get_latest_view(): LatestView acquires LatestView {
+    if (!exists<LatestView>(@supra_framework)) {
+        return LatestView { epoch: 0, round: 0 }
+    };
+    let latest_view = borrow_global<LatestView>(@supra_framework);
+    *latest_view
+}
+
+ + + +
+ + + +## Function `get_initial_ban_duration` + +Returns the number of consensus rounds that a validator is banned for when it fails to propose a +canonical block when elected as leader whilst not on probation. + + +
#[view]
+public fun get_initial_ban_duration(): u64
+
+ + + +
+Implementation + + +
public fun get_initial_ban_duration(): u64 {
+    let initial_elections_denied =
+        leader_ban_registry_config::get_initial_elections_denied();
+    let committee_size = stake::get_committee_size();
+    committee_size * (initial_elections_denied as u64)
+}
+
+ + + +
+ + + +## Function `get_max_ban_duration` + +Returns the maximum number of consensus rounds that a validator may banned for when it repeatedly fails to +propose a canonical block when elected as leader whilst on probation. + + +
#[view]
+public fun get_max_ban_duration(): u64
+
+ + + +
+Implementation + + +
public fun get_max_ban_duration(): u64 {
+    let max_elections_denied = leader_ban_registry_config::get_max_elections_denied();
+    let committee_size = stake::get_committee_size();
+    committee_size * (max_elections_denied as u64)
+}
+
+ + + +
+ + + +## Function `get_probation_duration` + +Returns the number of consensus rounds that a validator is considered to be on probation for after having +served its most recent ban. + + +
#[view]
+public fun get_probation_duration(): u64
+
+ + + +
+Implementation + + +
public fun get_probation_duration(): u64 {
+    let probation_elections = leader_ban_registry_config::get_probation_elections();
+    let committee_size = stake::get_committee_size();
+    committee_size * (probation_elections as u64)
+}
+
+ + + +
+ + + +## Function `get_remaining_ban_duration` + +Returns the number of consensus rounds remaining in the ban for the validator with the given +pool address. Returns 0 if the validator is not banned (including if it is on probation). + + +
#[view]
+public fun get_remaining_ban_duration(pool_address: address): u64
+
+ + + +
+Implementation + + +
public fun get_remaining_ban_duration(
+    pool_address: address
+): u64 acquires BanRegistry, LatestView {
+    if (!exists<BanRegistry>(@supra_framework)
+        || !exists<LatestView>(@supra_framework)) {
+        return 0
+    };
+    let ban_registry = borrow_global<BanRegistry>(@supra_framework);
+    let latest_view = borrow_global<LatestView>(@supra_framework);
+    let (found, index) = vector::find(
+        &ban_registry.bans,
+        |v| {
+            let v: &ValidatorBans = v;
+            v.pool_address == pool_address && !v.active.on_probation
+        }
+    );
+    if (found) {
+        remaining_ban_duration(
+            vector::borrow(&ban_registry.bans, index), latest_view
+        )
+    } else { 0 }
+}
+
+ + + +
+ + + +## Function `get_remaining_probation_duration` + +Returns the number of consensus rounds remaining in the probation period for the validator +with the given pool address. Returns 0 if the validator is not on probation. + + +
#[view]
+public fun get_remaining_probation_duration(pool_address: address): u64
+
+ + + +
+Implementation + + +
public fun get_remaining_probation_duration(
+    pool_address: address
+): u64 acquires BanRegistry, LatestView {
+    if (!exists<BanRegistry>(@supra_framework)
+        || !exists<LatestView>(@supra_framework)) {
+        return 0
+    };
+    let ban_registry = borrow_global<BanRegistry>(@supra_framework);
+    let latest_view = borrow_global<LatestView>(@supra_framework);
+    let (found, index) = vector::find(
+        &ban_registry.bans,
+        |v| {
+            let v: &ValidatorBans = v;
+            v.pool_address == pool_address && v.active.on_probation
+        }
+    );
+    if (found) {
+        let probation_dur = get_probation_duration();
+        remaining_probation_duration(
+            vector::borrow(&ban_registry.bans, index),
+            latest_view,
+            probation_dur
+        )
+    } else { 0 }
+}
+
+ + + +
+ + + +## Function `update_ban_registry` + +Add or update the ban registry as per block metadata + + +
public(friend) fun update_ban_registry(current_epoch: u64, current_round: u64, proposer_index: option::Option<u64>, failed_proposer_indices: vector<u64>)
+
+ + + +
+Implementation + + +
public(friend) fun update_ban_registry(
+    current_epoch: u64,
+    current_round: u64,
+    proposer_index: Option<u64>,
+    failed_proposer_indices: vector<u64>
+) acquires BanRegistry, LatestView {
+    if (!exists<BanRegistry>(@supra_framework)) { return };
+    if (!exists<LatestView>(@supra_framework)) { return };
+    let ban_registry = borrow_global_mut<BanRegistry>(@supra_framework);
+    let latest_view = borrow_global_mut<LatestView>(@supra_framework);
+    latest_view.epoch = current_epoch;
+    latest_view.round = current_round;
+
+    // ban the failed proposers
+    ban_failed_proposers(latest_view, failed_proposer_indices, ban_registry);
+
+    // remove expired bans
+    reinstate_expired_bans(latest_view, ban_registry);
+}
+
+ + + +
+ + + +## Function `ban_failed_proposers` + +Adds failed proposer indices to ban registry + + +
fun ban_failed_proposers(latest_view: &leader_ban_registry::LatestView, failed_proposer_indices: vector<u64>, ban_registry: &mut leader_ban_registry::BanRegistry)
+
+ + + +
+Implementation + + +
fun ban_failed_proposers(
+    latest_view: &LatestView,
+    failed_proposer_indices: vector<u64>,
+    ban_registry: &mut BanRegistry
+) {
+    let initial_ban_duration = get_initial_ban_duration();
+    if (initial_ban_duration == 0) { return };
+
+    vector::for_each(
+        failed_proposer_indices,
+        |failed_validator_index| {
+            let validator_pool_address_opt =
+                stake::get_pool_address_from_index(failed_validator_index);
+
+            if (option::is_some(&validator_pool_address_opt)) {
+                let validator_pool_address =
+                    option::extract(&mut validator_pool_address_opt);
+                let (is_banned, index) = vector::find(
+                    &ban_registry.bans,
+                    |v| {
+                        let v: &ValidatorBans = v;
+                        validator_pool_address == v.pool_address
+                    }
+                );
+                if (is_banned) {
+                    // Validator is already in registry (either banned or on probation).
+                    // Re-banning resets the ban period and increases consecutive count.
+                    // If the consensus code is implemented correctly then the validator should
+                    // not be re-banned whilst serving a ban as it should not be eligible for election
+                    // when banned (i.e. this branch should only be taken when a validator is on probation).
+                    let bans = vector::borrow_mut(&mut ban_registry.bans, index);
+                    bans.consecutive_bans = bans.consecutive_bans + 1;
+                    bans.active.round_earned = latest_view.round;
+                    bans.active.epoch_earned = latest_view.epoch;
+                    bans.active.rounds_served_in_previous_epochs = 0;
+                    bans.active.on_probation = false; // Reset to banned state
+
+                    if (features::module_event_enabled()) {
+                        event::emit(
+                            Banned {
+                                pool_address: validator_pool_address,
+                                epoch: latest_view.epoch,
+                                round: latest_view.round,
+                                consecutive_bans: bans.consecutive_bans
+                            }
+                        );
+                    }
+                } else {
+                    let ban_registry_len = vector::length(&ban_registry.bans);
+                    if (can_be_banned(ban_registry_len)) {
+                        let ban_with_address = ValidatorBans {
+                            active: ActiveBan {
+                                epoch_earned: latest_view.epoch,
+                                round_earned: latest_view.round,
+                                rounds_served_in_previous_epochs: 0,
+                                on_probation: false
+                            },
+                            consecutive_bans: 0,
+                            pool_address: validator_pool_address
+                        };
+                        vector::push_back(&mut ban_registry.bans, ban_with_address);
+
+                        if (features::module_event_enabled()) {
+                            event::emit(
+                                Banned {
+                                    pool_address: ban_with_address.pool_address,
+                                    epoch: ban_with_address.active.epoch_earned,
+                                    round: ban_with_address.active.round_earned,
+                                    consecutive_bans: ban_with_address.consecutive_bans
+                                }
+                            );
+                        }
+                    }
+                };
+            };
+        }
+    );
+}
+
+ + + +
+ + + +## Function `reinstate_expired_bans` + +Handles ban and probation expiry: +- When probation expires: removes from registry, emits Reinstated +- When ban expires and probation_duration > 0: transitions to probation, emits ReinstatedWithProbation +- When ban expires and probation_duration == 0: removes from registry, emits Reinstated + + +
fun reinstate_expired_bans(latest_view: &leader_ban_registry::LatestView, ban_registry: &mut leader_ban_registry::BanRegistry)
+
+ + + +
+Implementation + + +
fun reinstate_expired_bans(
+    latest_view: &LatestView, ban_registry: &mut BanRegistry
+) {
+    let probation_duration = get_probation_duration();
+
+    // First pass: remove validators whose probation has expired.
+    // Done before ban-to-probation transitions to avoid iterating just-transitioned validators.
+    // Always runs (even when probation_duration == 0) to clean up validators that were already
+    // on probation before a config change set probation_duration to 0.
+    let pool_addresses_for_full_reinstatement = vector::empty();
+    vector::for_each_ref(
+        &ban_registry.bans,
+        |v| {
+            let v: &ValidatorBans = v;
+            if (v.active.on_probation
+                && remaining_probation_duration(v, latest_view, probation_duration)
+                    == 0) {
+                vector::push_back(
+                    &mut pool_addresses_for_full_reinstatement, v.pool_address
+                );
+            }
+        }
+    );
+
+    vector::for_each_ref(
+        &pool_addresses_for_full_reinstatement,
+        |p| {
+            let (found, index) = vector::find(
+                &ban_registry.bans,
+                |v| {
+                    let v: &ValidatorBans = v;
+                    &v.pool_address == p
+                }
+            );
+            if (found) {
+                vector::swap_remove(&mut ban_registry.bans, index);
+
+                if (features::module_event_enabled()) {
+                    event::emit(
+                        Reinstated {
+                            epoch: latest_view.epoch,
+                            round: latest_view.round,
+                            pool_address: *p
+                        }
+                    )
+                }
+            }
+        }
+    );
+
+    // Second pass: handle expired bans
+    let pool_addresses_with_expired_bans = vector::empty();
+    vector::for_each_ref(
+        &ban_registry.bans,
+        |v| {
+            let v: &ValidatorBans = v;
+            if (!v.active.on_probation
+                && remaining_ban_duration(v, latest_view) == 0) {
+                vector::push_back(
+                    &mut pool_addresses_with_expired_bans, v.pool_address
+                );
+            }
+        }
+    );
+
+    if (probation_duration > 0) {
+        // Transition expired bans to probation
+        vector::for_each_ref(
+            &pool_addresses_with_expired_bans,
+            |p| {
+                let (found, index) = vector::find(
+                    &ban_registry.bans,
+                    |v| {
+                        let v: &ValidatorBans = v;
+                        &v.pool_address == p
+                    }
+                );
+                if (found) {
+                    let ban = vector::borrow_mut(&mut ban_registry.bans, index);
+                    ban.active.on_probation = true;
+                    // Reset active fields so probation duration is calculated from this point
+                    ban.active.epoch_earned = latest_view.epoch;
+                    ban.active.round_earned = latest_view.round;
+                    ban.active.rounds_served_in_previous_epochs = 0;
+
+                    if (features::module_event_enabled()) {
+                        event::emit(
+                            ReinstatedWithProbation {
+                                epoch: latest_view.epoch,
+                                round: latest_view.round,
+                                pool_address: *p
+                            }
+                        )
+                    }
+                }
+            }
+        );
+    } else {
+        // No probation period - directly remove validators whose ban expired
+        vector::for_each_ref(
+            &pool_addresses_with_expired_bans,
+            |p| {
+                let (found, index) = vector::find(
+                    &ban_registry.bans,
+                    |v| {
+                        let v: &ValidatorBans = v;
+                        &v.pool_address == p
+                    }
+                );
+                if (found) {
+                    vector::swap_remove(&mut ban_registry.bans, index);
+
+                    if (features::module_event_enabled()) {
+                        event::emit(
+                            Reinstated {
+                                epoch: latest_view.epoch,
+                                round: latest_view.round,
+                                pool_address: *p
+                            }
+                        )
+                    }
+                }
+            }
+        );
+    };
+}
+
+ + + +
+ + + +## Function `on_new_epoch` + +Increments the total number of consensus rounds served by each banned validator and removes +registry entries for validators that have left the validator set. + +The number of rounds in each epoch may vary due to network asynchrony, so we must record the +number of rounds served in previous epochs to be able to ensure that a banned validator serves its +full ban period when its ban span multiple epochs. + + +
public(friend) fun on_new_epoch()
+
+ + + +
+Implementation + + +
public(friend) fun on_new_epoch() acquires BanRegistry, LatestView {
+    if (!exists<LatestView>(@supra_framework)) { return };
+    if (!exists<BanRegistry>(@supra_framework)) { return };
+    let latest_view = borrow_global<LatestView>(@supra_framework);
+    let ban_registry = borrow_global_mut<BanRegistry>(@supra_framework);
+
+    // The pool addresses of the validators for the new epoch.
+    let new_committee_pool_addresses = stake::get_committee_pool_addresses();
+    // The pool addresses of the validators that have left the committee.
+    let retired_validators = vector::empty();
+    vector::for_each_mut(
+        &mut ban_registry.bans,
+        |v| {
+            let v: &mut ValidatorBans = v;
+            if (vector::contains(&new_committee_pool_addresses, &v.pool_address)) {
+                if (latest_view.epoch > v.active.epoch_earned) {
+                    v.active.rounds_served_in_previous_epochs =
+                        v.active.rounds_served_in_previous_epochs
+                            + latest_view.round;
+                } else if (latest_view.epoch == v.active.epoch_earned
+                    && latest_view.round > v.active.round_earned) {
+                    v.active.rounds_served_in_previous_epochs =
+                        latest_view.round - v.active.round_earned;
+                };
+                // else: The ban hasn't started yet.
+            } else {
+                vector::push_back(&mut retired_validators, v.pool_address)
+            }
+        }
+    );
+
+    vector::for_each_ref(
+        &retired_validators,
+        |p| {
+            let (is_banned, index) = vector::find(
+                &ban_registry.bans,
+                |v| {
+                    let v: &ValidatorBans = v;
+                    &v.pool_address == p
+                }
+            );
+            if (is_banned) {
+                vector::swap_remove(&mut ban_registry.bans, index);
+
+                if (features::module_event_enabled()) {
+                    event::emit(
+                        Reinstated {
+                            pool_address: *p,
+                            epoch: latest_view.epoch,
+                            round: latest_view.round
+                        }
+                    );
+                }
+            }
+        }
+    );
+}
+
+ + + +
+ + + +## Function `remaining_ban_duration` + +Calculate the number of rounds remaining in a given ban (not including probation). + + +
fun remaining_ban_duration(ban: &leader_ban_registry::ValidatorBans, latest_view: &leader_ban_registry::LatestView): u64
+
+ + + +
+Implementation + + +
fun remaining_ban_duration(
+    ban: &ValidatorBans, latest_view: &LatestView
+): u64 {
+    let initial_ban_duration = get_initial_ban_duration();
+    let max_ban_duration = get_max_ban_duration();
+    let duration = initial_ban_duration * pow(2, (ban.consecutive_bans as u64));
+    let duration = min(duration, max_ban_duration);
+    let rounds_served =
+        if (latest_view.epoch > ban.active.epoch_earned) {
+            ban.active.rounds_served_in_previous_epochs + latest_view.round
+        } else if (latest_view.epoch == ban.active.epoch_earned
+            && latest_view.round > ban.active.round_earned) {
+            latest_view.round - ban.active.round_earned
+        } else {
+            // The ban hasn't started yet.
+            0
+        };
+    if (duration > rounds_served) {
+        duration - rounds_served
+    } else { 0 }
+}
+
+ + + +
+ + + +## Function `remaining_probation_duration` + +Calculate the number of rounds remaining in probation. +Probation duration is constant and does not scale with consecutive bans. + + +
fun remaining_probation_duration(ban: &leader_ban_registry::ValidatorBans, latest_view: &leader_ban_registry::LatestView, probation_duration: u64): u64
+
+ + + +
+Implementation + + +
fun remaining_probation_duration(
+    ban: &ValidatorBans, latest_view: &LatestView, probation_duration: u64
+): u64 {
+    let rounds_served =
+        if (latest_view.epoch > ban.active.epoch_earned) {
+            ban.active.rounds_served_in_previous_epochs + latest_view.round
+        } else if (latest_view.epoch == ban.active.epoch_earned
+            && latest_view.round > ban.active.round_earned) {
+            latest_view.round - ban.active.round_earned
+        } else {
+            // The ban hasn't started yet.
+            0
+        };
+    if (probation_duration > rounds_served) {
+        probation_duration - rounds_served
+    } else { 0 }
+}
+
+ + + +
+ + + +## Function `can_be_banned` + +Returns true until ban registry size + minimum proposers required count less than committee size + + +
fun can_be_banned(ban_registry_len: u64): bool
+
+ + + +
+Implementation + + +
fun can_be_banned(ban_registry_len: u64): bool {
+    let minimum_unbanned_proposers =
+        leader_ban_registry_config::get_minimum_unbanned_proposers();
+    let committee_size = stake::get_committee_size();
+    committee_size > ban_registry_len + (minimum_unbanned_proposers as u64)
+}
+
+ + + +
+ + + +## Function `assert_registry_initialized` + +Validates registry initialised if not aborted with EBAN_REGISTRY_NOT_INITIALIZED + + +
fun assert_registry_initialized()
+
+ + + +
+Implementation + + +
fun assert_registry_initialized() {
+    assert!(
+        exists<BanRegistry>(@supra_framework),
+        error::invalid_state(EBAN_REGISTRY_NOT_INITIALIZED)
+    );
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md b/aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md new file mode 100644 index 00000000000..ec26a067e25 --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md @@ -0,0 +1,541 @@ + + + +# Module `0x1::leader_ban_registry_config` + +Provides the config related to leader ban registry + + +- [Resource `BanRegistryParameters`](#0x1_leader_ban_registry_config_BanRegistryParameters) +- [Resource `BanRegistryParametersV0`](#0x1_leader_ban_registry_config_BanRegistryParametersV0) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_leader_ban_registry_config_initialize) +- [Function `set_for_next_epoch`](#0x1_leader_ban_registry_config_set_for_next_epoch) +- [Function `on_new_epoch`](#0x1_leader_ban_registry_config_on_new_epoch) +- [Function `get_ban_registry_params`](#0x1_leader_ban_registry_config_get_ban_registry_params) +- [Function `get_ban_registry_params_v0`](#0x1_leader_ban_registry_config_get_ban_registry_params_v0) +- [Function `get_initial_elections_denied`](#0x1_leader_ban_registry_config_get_initial_elections_denied) +- [Function `get_max_elections_denied`](#0x1_leader_ban_registry_config_get_max_elections_denied) +- [Function `get_minimum_unbanned_proposers`](#0x1_leader_ban_registry_config_get_minimum_unbanned_proposers) +- [Function `get_probation_elections`](#0x1_leader_ban_registry_config_get_probation_elections) +- [Function `deserialise_v0_params`](#0x1_leader_ban_registry_config_deserialise_v0_params) + + +
use 0x1::config_buffer;
+use 0x1::decode_bcs;
+use 0x1::error;
+use 0x1::option;
+use 0x1::system_addresses;
+
+ + + + + +## Resource `BanRegistryParameters` + +Holds ban registry parameters bytes and it's version + + +
struct BanRegistryParameters has drop, store, key
+
+ + + +
+Fields + + +
+
+config: vector<u8> +
+
+ Denotes config bcs bytes +
+
+version: u8 +
+
+ Denotes config version +
+
+ + +
+ + + +## Resource `BanRegistryParametersV0` + +Ban registry parameters v0 + + +
struct BanRegistryParametersV0 has drop, store, key
+
+ + + +
+Fields + + +
+
+initial_elections_denied: u8 +
+
+ Denotes initial election count denied +
+
+max_elections_denied: u32 +
+
+ Denotes max election count denied +
+
+minimum_unbanned_proposers: u8 +
+
+ Denotes the minimum number of validators that must remain eligible for proposal. This + helps to preserve liveness in the presence of extended periods of network asynchrony. +
+
+probation_elections: u8 +
+
+ Denotes the number of elections a validator must serve on probation after ban expires. + The ban duration compounds each time a validator is banned whilst on probation, and + resets to the base duration if the validator passes probation. +
+
+ + +
+ + + +## Constants + + + + +The BanRegistryParameters already initialised + + +
const EALREADY_INITIALISED: u64 = 4;
+
+ + + + + +The provided on chain config bytes are empty or invalid + + +
const EINVALID_CONFIG: u64 = 1;
+
+ + + + + +The provided on chain config version should be equal or greater than existing + + +
const EINVALID_VERSION: u64 = 2;
+
+ + + + + +Decoding from version bytes failed + + +
const EINVALID_VERSION_BYTES: u64 = 3;
+
+ + + + + +## Function `initialize` + +Publishes the BanRegistryParameters config. + + +
public(friend) fun initialize(supra_framework: &signer, config: vector<u8>)
+
+ + + +
+Implementation + + +
public(friend) fun initialize(
+    supra_framework: &signer, config: vector<u8>
+) {
+    system_addresses::assert_supra_framework(supra_framework);
+    assert!(vector::length(&config) != 0, error::invalid_argument(EINVALID_CONFIG));
+    assert!(
+        !exists<BanRegistryParameters>(@supra_framework),
+        error::already_exists(EALREADY_INITIALISED)
+    );
+    let v0 = deserialise_v0_params(config);
+    if (option::is_none(&v0)) {
+        abort error::invalid_argument(EINVALID_VERSION_BYTES)
+    };
+    // we always init with version 0
+    move_to(supra_framework, BanRegistryParameters { config, version: 0 });
+    let v0_params = option::extract(&mut v0);
+    move_to(supra_framework, v0_params);
+}
+
+ + + +
+ + + +## Function `set_for_next_epoch` + +This can be called by on-chain governance to update on-chain configs for the next epoch. +Example usage: +``` +supra_framework::leader_ban_registry_config::set_for_next_epoch(&framework_signer, some_config_bytes, version); +supra_framework::supra_governance::reconfigure(&framework_signer); +``` + + +
public fun set_for_next_epoch(account: &signer, config: vector<u8>, version: u8)
+
+ + + +
+Implementation + + +
public fun set_for_next_epoch(
+    account: &signer, config: vector<u8>, version: u8
+) acquires BanRegistryParameters {
+    system_addresses::assert_supra_framework(account);
+    assert!(vector::length(&config) != 0, error::invalid_argument(EINVALID_CONFIG));
+    if (exists<BanRegistryParameters>(@supra_framework)) {
+        let ban_registry_params =
+            borrow_global<BanRegistryParameters>(@supra_framework);
+        assert!(
+            version >= ban_registry_params.version,
+            error::invalid_argument(EINVALID_VERSION)
+        );
+    };
+    std::config_buffer::upsert<BanRegistryParameters>(
+        BanRegistryParameters { config, version }
+    );
+}
+
+ + + +
+ + + +## Function `on_new_epoch` + +Only used in reconfigurations to apply the pending BanRegistryParameters, if there is any. + + +
public(friend) fun on_new_epoch(framework: &signer)
+
+ + + +
+Implementation + + +
public(friend) fun on_new_epoch(
+    framework: &signer
+) acquires BanRegistryParameters, BanRegistryParametersV0 {
+    system_addresses::assert_supra_framework(framework);
+    if (config_buffer::does_exist<BanRegistryParameters>()) {
+        let new_config = config_buffer::extract<BanRegistryParameters>();
+        if (exists<BanRegistryParameters>(@supra_framework)) {
+            *borrow_global_mut<BanRegistryParameters>(@supra_framework) = new_config;
+        } else {
+            move_to(framework, new_config);
+        };
+        let params = borrow_global<BanRegistryParameters>(@supra_framework);
+        if (params.version == 0) {
+            let v0 = deserialise_v0_params(params.config);
+            // This is to prevent abort on new epoch if deserialise failed.
+            if (option::is_some(&v0)) {
+                let ban_registry_params = option::extract(&mut v0);
+                if (exists<BanRegistryParametersV0>(@supra_framework)) {
+                    *borrow_global_mut<BanRegistryParametersV0>(@supra_framework) = ban_registry_params;
+                } else {
+                    move_to(framework, ban_registry_params);
+                }
+            }
+        }
+        // later version can be assigned here
+    }
+}
+
+ + + +
+ + + +## Function `get_ban_registry_params` + + + +
#[view]
+public fun get_ban_registry_params(): (vector<u8>, u8)
+
+ + + +
+Implementation + + +
public fun get_ban_registry_params(): (vector<u8>, u8) acquires BanRegistryParameters {
+    if (exists<BanRegistryParameters>(@supra_framework)) {
+        let ban_registry_config =
+            borrow_global<BanRegistryParameters>(@supra_framework);
+        return (ban_registry_config.config, ban_registry_config.version)
+    };
+    (vector::empty(), 0)
+}
+
+ + + +
+ + + +## Function `get_ban_registry_params_v0` + + + +
#[view]
+public fun get_ban_registry_params_v0(): (u8, u32, u8, u8)
+
+ + + +
+Implementation + + +
public fun get_ban_registry_params_v0(): (u8, u32, u8, u8) acquires BanRegistryParameters, BanRegistryParametersV0 {
+    if (exists<BanRegistryParameters>(@supra_framework)) {
+        let ban_registry_config =
+            borrow_global<BanRegistryParameters>(@supra_framework);
+        if (ban_registry_config.version == 0) {
+            let ban_registry_params =
+                borrow_global<BanRegistryParametersV0>(@supra_framework);
+            return (
+                ban_registry_params.initial_elections_denied,
+                ban_registry_params.max_elections_denied,
+                ban_registry_params.minimum_unbanned_proposers,
+                ban_registry_params.probation_elections
+            )
+        }
+    };
+    (0, 0, 0, 0)
+}
+
+ + + +
+ + + +## Function `get_initial_elections_denied` + +Provide initial election denied value + + +
public fun get_initial_elections_denied(): u8
+
+ + + +
+Implementation + + +
public fun get_initial_elections_denied(): u8 acquires BanRegistryParameters, BanRegistryParametersV0 {
+    if (exists<BanRegistryParameters>(@supra_framework)) {
+        let ban_registry_config =
+            borrow_global<BanRegistryParameters>(@supra_framework);
+        if (ban_registry_config.version == 0) {
+            let ban_registry_params =
+                borrow_global<BanRegistryParametersV0>(@supra_framework);
+            return ban_registry_params.initial_elections_denied
+        }
+    };
+    0
+}
+
+ + + +
+ + + +## Function `get_max_elections_denied` + +Provide max election denied value + + +
public fun get_max_elections_denied(): u32
+
+ + + +
+Implementation + + +
public fun get_max_elections_denied(): u32 acquires BanRegistryParameters, BanRegistryParametersV0 {
+    if (exists<BanRegistryParameters>(@supra_framework)) {
+        let ban_registry_config =
+            borrow_global<BanRegistryParameters>(@supra_framework);
+        if (ban_registry_config.version == 0) {
+            let ban_registry_params =
+                borrow_global<BanRegistryParametersV0>(@supra_framework);
+            return ban_registry_params.max_elections_denied
+        }
+    };
+    0
+}
+
+ + + +
+ + + +## Function `get_minimum_unbanned_proposers` + +Provide minimum unbanned proposers value + + +
public fun get_minimum_unbanned_proposers(): u8
+
+ + + +
+Implementation + + +
public fun get_minimum_unbanned_proposers(): u8 acquires BanRegistryParameters, BanRegistryParametersV0 {
+    if (exists<BanRegistryParameters>(@supra_framework)) {
+        let ban_registry_config =
+            borrow_global<BanRegistryParameters>(@supra_framework);
+        if (ban_registry_config.version == 0) {
+            let ban_registry_params =
+                borrow_global<BanRegistryParametersV0>(@supra_framework);
+            return ban_registry_params.minimum_unbanned_proposers
+        }
+    };
+    0
+}
+
+ + + +
+ + + +## Function `get_probation_elections` + +Provide probation elections value + + +
public fun get_probation_elections(): u8
+
+ + + +
+Implementation + + +
public fun get_probation_elections(): u8 acquires BanRegistryParameters, BanRegistryParametersV0 {
+    if (exists<BanRegistryParameters>(@supra_framework)) {
+        let ban_registry_config =
+            borrow_global<BanRegistryParameters>(@supra_framework);
+        if (ban_registry_config.version == 0) {
+            let ban_registry_params =
+                borrow_global<BanRegistryParametersV0>(@supra_framework);
+            return ban_registry_params.probation_elections
+        }
+    };
+    0
+}
+
+ + + +
+ + + +## Function `deserialise_v0_params` + +Decoding bytes to BanRegistryParametersV0 using bcs + + +
fun deserialise_v0_params(bytes: vector<u8>): option::Option<leader_ban_registry_config::BanRegistryParametersV0>
+
+ + + +
+Implementation + + +
fun deserialise_v0_params(bytes: vector<u8>): Option<BanRegistryParametersV0> {
+    let bcs_bytes = decode_bcs::new(bytes);
+    let initial_elections_denied: u8 = decode_bcs::peel_u8(&mut bcs_bytes);
+    let max_elections_denied: u32 = decode_bcs::peel_u32(&mut bcs_bytes);
+    let minimum_unbanned_proposers: u8 = decode_bcs::peel_u8(&mut bcs_bytes);
+    let probation_elections: u8 = decode_bcs::peel_u8(&mut bcs_bytes);
+    // making sure no bytes left to decode means correct parameter version
+    if (vector::length(&decode_bcs::into_remainder_bytes(bcs_bytes)) == 0) {
+        return option::some(
+            BanRegistryParametersV0 {
+                initial_elections_denied,
+                max_elections_denied,
+                minimum_unbanned_proposers,
+                probation_elections
+            }
+        )
+    };
+    option::none<BanRegistryParametersV0>()
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/multisig_voting.md b/aptos-move/framework/supra-framework/doc/multisig_voting.md index 313d6cd509d..f222d783c16 100644 --- a/aptos-move/framework/supra-framework/doc/multisig_voting.md +++ b/aptos-move/framework/supra-framework/doc/multisig_voting.md @@ -1557,7 +1557,11 @@ Return the state of the proposal with given id. ): u64 acquires VotingForum { if (is_voting_closed<ProposalType>(voting_forum_address, proposal_id)) { let proposal = get_proposal<ProposalType>(voting_forum_address, proposal_id); - if (proposal.yes_votes >= proposal.min_vote_threshold) { + let yes_votes = proposal.yes_votes; + let no_votes = proposal.no_votes; + + if (yes_votes > no_votes && + yes_votes + no_votes >= proposal.min_vote_threshold) { PROPOSAL_STATE_SUCCEEDED } else { PROPOSAL_STATE_FAILED diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 202e9563f64..9c2cd430980 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -28,6 +28,8 @@ This is the reference documentation of the Supra framework. - [`0x1::create_signer`](create_signer.md#0x1_create_signer) - [`0x1::dispatchable_fungible_asset`](dispatchable_fungible_asset.md#0x1_dispatchable_fungible_asset) - [`0x1::dkg`](dkg.md#0x1_dkg) +- [`0x1::dkg_committee`](dkg_committee.md#0x1_dkg_committee) +- [`0x1::dkg_config`](dkg_config.md#0x1_dkg_config) - [`0x1::event`](event.md#0x1_event) - [`0x1::evm_genesis_config`](evm_genesis_config.md#0x1_evm_genesis_config) - [`0x1::execution_config`](execution_config.md#0x1_execution_config) @@ -40,6 +42,8 @@ This is the reference documentation of the Supra framework. - [`0x1::jwk_consensus_config`](jwk_consensus_config.md#0x1_jwk_consensus_config) - [`0x1::jwks`](jwks.md#0x1_jwks) - [`0x1::keyless_account`](keyless_account.md#0x1_keyless_account) +- [`0x1::leader_ban_registry`](leader_ban_registry.md#0x1_leader_ban_registry) +- [`0x1::leader_ban_registry_config`](leader_ban_registry_config.md#0x1_leader_ban_registry_config) - [`0x1::managed_coin`](managed_coin.md#0x1_managed_coin) - [`0x1::multisig_account`](multisig_account.md#0x1_multisig_account) - [`0x1::multisig_voting`](multisig_voting.md#0x1_multisig_voting) @@ -73,6 +77,7 @@ This is the reference documentation of the Supra framework. - [`0x1::transaction_validation`](transaction_validation.md#0x1_transaction_validation) - [`0x1::util`](util.md#0x1_util) - [`0x1::validator_consensus_info`](validator_consensus_info.md#0x1_validator_consensus_info) +- [`0x1::validator_public_keys`](validator_public_keys.md#0x1_validator_public_keys) - [`0x1::version`](version.md#0x1_version) - [`0x1::vesting`](vesting.md#0x1_vesting) - [`0x1::vesting_without_staking`](vesting_without_staking.md#0x1_vesting_without_staking) diff --git a/aptos-move/framework/supra-framework/doc/randomness.md b/aptos-move/framework/supra-framework/doc/randomness.md index 0b5c30f89a6..9c7a222406f 100644 --- a/aptos-move/framework/supra-framework/doc/randomness.md +++ b/aptos-move/framework/supra-framework/doc/randomness.md @@ -221,11 +221,10 @@ Must be called in tests to initialize the initialize(framework: &signer) { system_addresses::assert_supra_framework(framework); if (!exists<PerBlockRandomness>(@supra_framework)) { - move_to(framework, PerBlockRandomness { - epoch: 0, - round: 0, - seed: option::none(), - }); + move_to( + framework, + PerBlockRandomness { epoch: 0, round: 0, seed: option::none() } + ); } }
@@ -250,7 +249,12 @@ Invoked in block prologues to update the block-level randomness seed. Implementation -
public(friend) fun on_new_block(vm: &signer, epoch: u64, round: u64, seed_for_new_block: Option<vector<u8>>) acquires PerBlockRandomness {
+
public(friend) fun on_new_block(
+    vm: &signer,
+    epoch: u64,
+    round: u64,
+    seed_for_new_block: Option<vector<u8>>
+) acquires PerBlockRandomness {
     system_addresses::assert_vm(vm);
     if (exists<PerBlockRandomness>(@supra_framework)) {
         let randomness = borrow_global_mut<PerBlockRandomness>(@supra_framework);
@@ -832,7 +836,7 @@ If n is 0, returns the empty vector.
 
     let values = vector[];
 
-    if(n == 0) {
+    if (n == 0) {
         return vector[]
     };
 
@@ -896,7 +900,15 @@ Compute (a + b) % m, assuming m >= 1, 0 <= a < m, 0&
     let a_clone = a;
     let neg_b = m - b;
     let a_less = a < neg_b;
-    take_first(if (a_less) { a + b } else { a_clone - neg_b }, if (!a_less) { a_clone - neg_b } else { a + b })
+    take_first(
+        if (a_less) { a + b }
+        else {
+            a_clone - neg_b
+        },
+        if (!a_less) {
+            a_clone - neg_b
+        } else { a + b }
+    )
 }
 
@@ -919,7 +931,9 @@ Compute (a + b) % m, assuming m >= 1, 0 <= a < m, 0& Implementation -
fun take_first(x: u256, _y: u256 ): u256 { x }
+
fun take_first(x: u256, _y: u256): u256 {
+    x
+}
 
@@ -944,9 +958,8 @@ Compute (a + b) % m, assuming m >= 1, 0 <= a < m, 0&
fun safe_add_mod_for_verification(a: u256, b: u256, m: u256): u256 {
     let neg_b = m - b;
-    if (a < neg_b) {
-        a + b
-    } else {
+    if (a < neg_b) { a + b }
+    else {
         a - neg_b
     }
 }
diff --git a/aptos-move/framework/supra-framework/doc/reconfiguration.md b/aptos-move/framework/supra-framework/doc/reconfiguration.md
index faec6cc5dee..db75ed16279 100644
--- a/aptos-move/framework/supra-framework/doc/reconfiguration.md
+++ b/aptos-move/framework/supra-framework/doc/reconfiguration.md
@@ -38,6 +38,7 @@ to synchronize configuration changes for the validators.
 use 0x1::error;
 use 0x1::event;
 use 0x1::features;
+use 0x1::leader_ban_registry;
 use 0x1::reconfiguration_state;
 use 0x1::signer;
 use 0x1::stake;
@@ -415,6 +416,7 @@ Signal validators to start using new configuration. Must be called from friend c
 
     // Call stake to compute the new validator set and distribute rewards and transaction fees.
     stake::on_new_epoch();
+    leader_ban_registry::on_new_epoch();
     storage_gas::on_reconfig();
 
     assert!(current_time > config_ref.last_reconfiguration_time, error::invalid_state(EINVALID_BLOCK_TIME));
diff --git a/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md b/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md
index c7273caaf5e..13284f3c4f4 100644
--- a/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md
+++ b/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md
@@ -7,6 +7,7 @@ Reconfiguration with DKG helper functions.
 
 
 -  [Function `try_start`](#0x1_reconfiguration_with_dkg_try_start)
+-  [Function `set_dkg_meta`](#0x1_reconfiguration_with_dkg_set_dkg_meta)
 -  [Function `finish`](#0x1_reconfiguration_with_dkg_finish)
 -  [Function `finish_with_dkg_result`](#0x1_reconfiguration_with_dkg_finish_with_dkg_result)
 -  [Specification](#@Specification_0)
@@ -18,6 +19,8 @@ Reconfiguration with DKG helper functions.
 
use 0x1::automation_registry;
 use 0x1::consensus_config;
 use 0x1::dkg;
+use 0x1::dkg_committee;
+use 0x1::dkg_config;
 use 0x1::evm_genesis_config;
 use 0x1::execution_config;
 use 0x1::features;
@@ -25,7 +28,9 @@ Reconfiguration with DKG helper functions.
 use 0x1::jwk_consensus_config;
 use 0x1::jwks;
 use 0x1::keyless_account;
+use 0x1::leader_ban_registry_config;
 use 0x1::option;
+use 0x1::randomness;
 use 0x1::randomness_api_v0_config;
 use 0x1::randomness_config;
 use 0x1::randomness_config_seqnum;
@@ -35,6 +40,7 @@ Reconfiguration with DKG helper functions.
 use 0x1::supra_config;
 use 0x1::system_addresses;
 use 0x1::validator_consensus_info;
+use 0x1::validator_public_keys;
 use 0x1::version;
 
@@ -67,17 +73,71 @@ Do nothing if one is already in progress. }; reconfiguration_state::on_reconfig_start(); let cur_epoch = reconfiguration::current_epoch(); + let randomness_seed = randomness::bytes(32); + + // Get DKG configuration (dealer threshold type and receiver committee configs) + let config = dkg_config::current(); + let receiver_configs = dkg_config::get_receiver_committee_configs(&config); + + // Build receiver committees from config + let receiver_committees = vector[]; + let i = 0; + let len = vector::length(&receiver_configs); + while (i < len) { + let rc = vector::borrow(&receiver_configs, i); + vector::push_back( + &mut receiver_committees, + new_receiver_committee( + dkg_config::get_is_resharing(rc), + dkg_config::get_dkg_threshold_type(rc), + new_dkg_committee_from_validator_consensus_info( + stake::next_epoch_validator_consensus_infos_for_dkg(), + dkg_config::get_committee_threshold_type(rc) + ) + ) + ); + i = i + 1; + }; + + // DKG for configured receiver committees dkg::start( cur_epoch, - randomness_config::current(), - stake::cur_validator_consensus_infos(), - stake::next_validator_consensus_infos() + randomness_seed, + new_dkg_committee_from_validator_consensus_info( + stake::cur_validator_consensus_infos(), + dkg_config::get_dealer_committee_threshold_type(&config) + ), + receiver_committees ); }
+ + + + +## Function `set_dkg_meta` + + + +
fun set_dkg_meta(dkg_meta: vector<u8>)
+
+ + + +
+Implementation + + +
fun set_dkg_meta(dkg_meta: vector<u8>) {
+    dkg::set_dkg_meta(dkg_meta);
+}
+
+ + +
@@ -112,10 +172,12 @@ Run the default reconfiguration to enter the new epoch. jwk_consensus_config::on_new_epoch(framework); jwks::on_new_epoch(framework); keyless_account::on_new_epoch(framework); + leader_ban_registry_config::on_new_epoch(framework); randomness_config_seqnum::on_new_epoch(framework); randomness_config::on_new_epoch(framework); randomness_api_v0_config::on_new_epoch(framework); evm_genesis_config::on_new_epoch(framework); + dkg_config::on_new_epoch(framework); reconfiguration::reconfigure(); }
diff --git a/aptos-move/framework/supra-framework/doc/stake.md b/aptos-move/framework/supra-framework/doc/stake.md index 113f9e9e709..e6cdc709cc8 100644 --- a/aptos-move/framework/supra-framework/doc/stake.md +++ b/aptos-move/framework/supra-framework/doc/stake.md @@ -79,6 +79,9 @@ or if their stake drops below the min required, they would get removed at the en - [Function `stake_pool_exists`](#0x1_stake_stake_pool_exists) - [Function `initialize`](#0x1_stake_initialize) - [Function `store_supra_coin_mint_cap`](#0x1_stake_store_supra_coin_mint_cap) +- [Function `get_pool_address_from_index`](#0x1_stake_get_pool_address_from_index) +- [Function `get_committee_size`](#0x1_stake_get_committee_size) +- [Function `get_committee_pool_addresses`](#0x1_stake_get_committee_pool_addresses) - [Function `remove_validators`](#0x1_stake_remove_validators) - [Function `initialize_stake_owner`](#0x1_stake_initialize_stake_owner) - [Function `initialize_validator`](#0x1_stake_initialize_validator) @@ -95,6 +98,7 @@ or if their stake drops below the min required, they would get removed at the en - [Function `reactivate_stake`](#0x1_stake_reactivate_stake) - [Function `reactivate_stake_with_cap`](#0x1_stake_reactivate_stake_with_cap) - [Function `rotate_consensus_key_internal`](#0x1_stake_rotate_consensus_key_internal) +- [Function `set_dkg_output_keys`](#0x1_stake_set_dkg_output_keys) - [Function `rotate_consensus_key_genesis`](#0x1_stake_rotate_consensus_key_genesis) - [Function `rotate_consensus_key`](#0x1_stake_rotate_consensus_key) - [Function `update_network_and_fullnode_addresses`](#0x1_stake_update_network_and_fullnode_addresses) @@ -112,6 +116,10 @@ or if their stake drops below the min required, they would get removed at the en - [Function `on_new_epoch`](#0x1_stake_on_new_epoch) - [Function `cur_validator_consensus_infos`](#0x1_stake_cur_validator_consensus_infos) - [Function `next_validator_consensus_infos`](#0x1_stake_next_validator_consensus_infos) +- [Function `next_epoch_validator_consensus_infos_for_dkg`](#0x1_stake_next_epoch_validator_consensus_infos_for_dkg) +- [Function `compute_next_validator_set_internal`](#0x1_stake_compute_next_validator_set_internal) +- [Function `calculate_candidate_reward`](#0x1_stake_calculate_candidate_reward) +- [Function `collect_candidate_fee`](#0x1_stake_collect_candidate_fee) - [Function `validator_consensus_infos_from_validator_set`](#0x1_stake_validator_consensus_infos_from_validator_set) - [Function `addresses_from_validator_infos`](#0x1_stake_addresses_from_validator_infos) - [Function `update_stake_pool`](#0x1_stake_update_stake_pool) @@ -172,8 +180,10 @@ or if their stake drops below the min required, they would get removed at the en
use 0x1::account;
+use 0x1::bls12381;
 use 0x1::chain_status;
 use 0x1::coin;
+use 0x1::dkg_committee;
 use 0x1::ed25519;
 use 0x1::error;
 use 0x1::event;
@@ -189,6 +199,7 @@ or if their stake drops below the min required, they would get removed at the en
 use 0x1::table;
 use 0x1::timestamp;
 use 0x1::validator_consensus_info;
+use 0x1::validator_public_keys;
 use 0x1::vector;
 
@@ -1657,6 +1668,16 @@ Account is already a validator or pending validator. + + +Invalid DKG public key shares. + + +
const EDKG_INVALID_PK_SHARES: u64 = 21;
+
+ + + Table to store collected transaction fees for each validator already exists. @@ -1902,7 +1923,9 @@ Used by transaction_feeImplementation -
public(friend) fun initialize_validator_fees(supra_framework: &signer) {
+
public(friend) fun initialize_validator_fees(
+    supra_framework: &signer
+) {
     system_addresses::assert_supra_framework(supra_framework);
     assert!(
         !exists<ValidatorFees>(@supra_framework),
@@ -1932,8 +1955,11 @@ Stores the transaction fee collected to the specified validator address.
 Implementation
 
 
-
public(friend) fun add_transaction_fee(validator_addr: address, fee: Coin<SupraCoin>) acquires ValidatorFees {
-    let fees_table = &mut borrow_global_mut<ValidatorFees>(@supra_framework).fees_table;
+
public(friend) fun add_transaction_fee(
+    validator_addr: address, fee: Coin<SupraCoin>
+) acquires ValidatorFees {
+    let fees_table =
+        &mut borrow_global_mut<ValidatorFees>(@supra_framework).fees_table;
     if (table::contains(fees_table, validator_addr)) {
         let collected_fee = table::borrow_mut(fees_table, validator_addr);
         coin::merge(collected_fee, fee);
@@ -1996,9 +2022,8 @@ This will throw an error if there's no stake pool at pool_address.
 
public fun get_remaining_lockup_secs(pool_address: address): u64 acquires StakePool {
     assert_stake_pool_exists(pool_address);
     let lockup_time = borrow_global<StakePool>(pool_address).locked_until_secs;
-    if (lockup_time <= timestamp::now_seconds()) {
-        0
-    } else {
+    if (lockup_time <= timestamp::now_seconds()) { 0 }
+    else {
         lockup_time - timestamp::now_seconds()
     }
 }
@@ -2033,7 +2058,7 @@ The returned amounts are for (active, inactive, pending_active, pending_inactive
         coin::value(&stake_pool.active),
         coin::value(&stake_pool.inactive),
         coin::value(&stake_pool.pending_active),
-        coin::value(&stake_pool.pending_inactive),
+        coin::value(&stake_pool.pending_inactive)
     )
 }
 
@@ -2061,11 +2086,17 @@ Returns the validator's state.
public fun get_validator_state(pool_address: address): u64 acquires ValidatorSet {
     let validator_set = borrow_global<ValidatorSet>(@supra_framework);
-    if (option::is_some(&find_validator(&validator_set.pending_active, pool_address))) {
+    if (option::is_some(
+        &find_validator(&validator_set.pending_active, pool_address)
+    )) {
         VALIDATOR_STATUS_PENDING_ACTIVE
-    } else if (option::is_some(&find_validator(&validator_set.active_validators, pool_address))) {
+    } else if (option::is_some(
+        &find_validator(&validator_set.active_validators, pool_address)
+    )) {
         VALIDATOR_STATUS_ACTIVE
-    } else if (option::is_some(&find_validator(&validator_set.pending_inactive, pool_address))) {
+    } else if (option::is_some(
+        &find_validator(&validator_set.pending_inactive, pool_address)
+    )) {
         VALIDATOR_STATUS_PENDING_INACTIVE
     } else {
         VALIDATOR_STATUS_INACTIVE
@@ -2095,17 +2126,20 @@ This is the same as the validator's total active and pending_inactive stake.
 Implementation
 
 
-
public fun get_current_epoch_voting_power(pool_address: address): u64 acquires StakePool, ValidatorSet {
+
public fun get_current_epoch_voting_power(
+    pool_address: address
+): u64 acquires StakePool, ValidatorSet {
     assert_stake_pool_exists(pool_address);
     let validator_state = get_validator_state(pool_address);
     // Both active and pending inactive validators can still vote in the current epoch.
-    if (validator_state == VALIDATOR_STATUS_ACTIVE || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE) {
-        let active_stake = coin::value(&borrow_global<StakePool>(pool_address).active);
-        let pending_inactive_stake = coin::value(&borrow_global<StakePool>(pool_address).pending_inactive);
+    if (validator_state == VALIDATOR_STATUS_ACTIVE
+        || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE) {
+        let active_stake =
+            coin::value(&borrow_global<StakePool>(pool_address).active);
+        let pending_inactive_stake =
+            coin::value(&borrow_global<StakePool>(pool_address).pending_inactive);
         active_stake + pending_inactive_stake
-    } else {
-        0
-    }
+    } else { 0 }
 }
 
@@ -2236,10 +2270,18 @@ Return the number of successful and failed proposals for the proposal at the giv Implementation -
public fun get_current_epoch_proposal_counts(validator_index: u64): (u64, u64) acquires ValidatorPerformance {
-    let validator_performances = &borrow_global<ValidatorPerformance>(@supra_framework).validators;
-    let validator_performance = vector::borrow(validator_performances, validator_index);
-    (validator_performance.successful_proposals, validator_performance.failed_proposals)
+
public fun get_current_epoch_proposal_counts(
+    validator_index: u64
+): (u64, u64) acquires ValidatorPerformance {
+    let validator_performances =
+        &borrow_global<ValidatorPerformance>(@supra_framework).validators;
+    let validator_performance = vector::borrow(
+        validator_performances, validator_index
+    );
+    (
+        validator_performance.successful_proposals,
+        validator_performance.failed_proposals
+    )
 }
 
@@ -2269,7 +2311,11 @@ Return the validator's config. ): (vector<u8>, vector<u8>, vector<u8>) acquires ValidatorConfig { assert_stake_pool_exists(pool_address); let validator_config = borrow_global<ValidatorConfig>(pool_address); - (validator_config.consensus_pubkey, validator_config.network_addresses, validator_config.fullnode_addresses) + ( + validator_config.consensus_pubkey, + validator_config.network_addresses, + validator_config.fullnode_addresses + ) }
@@ -2321,18 +2367,19 @@ Initialize validator set to the core resource account.
public(friend) fun initialize(supra_framework: &signer) {
     system_addresses::assert_supra_framework(supra_framework);
 
-    move_to(supra_framework, ValidatorSet {
-        consensus_scheme: 0,
-        active_validators: vector::empty(),
-        pending_active: vector::empty(),
-        pending_inactive: vector::empty(),
-        total_voting_power: 0,
-        total_joining_power: 0,
-    });
-
-    move_to(supra_framework, ValidatorPerformance {
-        validators: vector::empty(),
-    });
+    move_to(
+        supra_framework,
+        ValidatorSet {
+            consensus_scheme: 0,
+            active_validators: vector::empty(),
+            pending_active: vector::empty(),
+            pending_inactive: vector::empty(),
+            total_voting_power: 0,
+            total_joining_power: 0
+        }
+    );
+
+    move_to(supra_framework, ValidatorPerformance { validators: vector::empty() });
 }
 
@@ -2357,7 +2404,9 @@ Beyond genesis, no one can create SupraCoin mint/burn capabilities. Implementation -
public(friend) fun store_supra_coin_mint_cap(supra_framework: &signer, mint_cap: MintCapability<SupraCoin>) {
+
public(friend) fun store_supra_coin_mint_cap(
+    supra_framework: &signer, mint_cap: MintCapability<SupraCoin>
+) {
     system_addresses::assert_supra_framework(supra_framework);
     move_to(supra_framework, SupraCoinCapabilities { mint_cap })
 }
@@ -2365,6 +2414,135 @@ Beyond genesis, no one can create SupraCoin mint/burn capabilities.
 
 
 
+
+
+
+
+## Function `get_pool_address_from_index`
+
+To get validator pool address from validator index
+
+
+
public(friend) fun get_pool_address_from_index(index: u64): option::Option<address>
+
+ + + +
+Implementation + + +
public(friend) fun get_pool_address_from_index(
+    index: u64
+): Option<address> acquires ValidatorSet {
+    if (exists<ValidatorSet>(@supra_framework)) {
+        let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+        // it can happen that some validator may added a leave request in between
+        // this can change the order of indexes in active validator
+        // so need to iterate through all until find pool address in active and  pending_active
+        let (is_index_exist, i) = vector::find(
+            &validator_set.active_validators,
+            |v| {
+                let v: &ValidatorInfo = v;
+                v.config.validator_index == index
+            }
+        );
+        if (is_index_exist) {
+            let v_info = vector::borrow(&validator_set.active_validators, i);
+            return option::some(v_info.addr)
+        };
+        let (is_index_exist, i) = vector::find(
+            &validator_set.pending_inactive,
+            |v| {
+                let v: &ValidatorInfo = v;
+                v.config.validator_index == index
+            }
+        );
+        if (is_index_exist) {
+            let v_info = vector::borrow(&validator_set.pending_inactive, i);
+            return option::some(v_info.addr)
+        };
+    };
+    option::none()
+}
+
+ + + +
+ + + +## Function `get_committee_size` + +Returns committee size + + +
public(friend) fun get_committee_size(): u64
+
+ + + +
+Implementation + + +
public(friend) fun get_committee_size(): u64 acquires ValidatorSet {
+    let commitee_size = 0;
+    if (exists<ValidatorSet>(@supra_framework)) {
+        let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+        commitee_size = vector::length(&validator_set.active_validators)
+            + vector::length(&validator_set.pending_inactive);
+    };
+    commitee_size
+}
+
+ + + +
+ + + +## Function `get_committee_pool_addresses` + +Returns pool addresses of current committee including pending inactive + + +
public(friend) fun get_committee_pool_addresses(): vector<address>
+
+ + + +
+Implementation + + +
public(friend) fun get_committee_pool_addresses(): vector<address> acquires ValidatorSet {
+    let pool_addresses = vector::empty();
+    if (exists<ValidatorSet>(@supra_framework)) {
+        let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+        vector::for_each_ref(
+            &validator_set.active_validators,
+            |validator_info| {
+                let validator_info: &ValidatorInfo = validator_info;
+                vector::push_back(&mut pool_addresses, validator_info.addr);
+            }
+        );
+        vector::for_each_ref(
+            &validator_set.pending_inactive,
+            |validator_info| {
+                let validator_info: &ValidatorInfo = validator_info;
+                vector::push_back(&mut pool_addresses, validator_info.addr);
+            }
+        );
+    };
+    pool_addresses
+}
+
+ + +
@@ -2384,8 +2562,7 @@ Allow on chain governance to remove validators from the validator set.
public fun remove_validators(
-    supra_framework: &signer,
-    validators: &vector<address>,
+    supra_framework: &signer, validators: &vector<address>
 ) acquires ValidatorSet {
     assert_reconfig_not_in_progress();
     system_addresses::assert_supra_framework(supra_framework);
@@ -2406,14 +2583,17 @@ Allow on chain governance to remove validators from the validator set.
             invariant spec_validator_indices_are_valid(active_validators);
             invariant spec_validators_are_initialized(pending_inactive);
             invariant spec_validator_indices_are_valid(pending_inactive);
-            invariant ghost_active_num + ghost_pending_inactive_num == len(active_validators) + len(pending_inactive);
+            invariant ghost_active_num + ghost_pending_inactive_num
+                == len(active_validators) + len(pending_inactive);
         };
         i < len_validators
     }) {
         let validator = *vector::borrow(validators, i);
         let validator_index = find_validator(active_validators, validator);
         if (option::is_some(&validator_index)) {
-            let validator_info = vector::swap_remove(active_validators, *option::borrow(&validator_index));
+            let validator_info = vector::swap_remove(
+                active_validators, *option::borrow(&validator_index)
+            );
             vector::push_back(pending_inactive, validator_info);
             spec {
                 update ghost_active_num = ghost_active_num - 1;
@@ -2452,15 +2632,18 @@ to set later.
     owner: &signer,
     initial_stake_amount: u64,
     operator: address,
-    voter: address,
+    voter: address
 ) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet {
     initialize_owner(owner);
-    move_to(owner, ValidatorConfig {
-        consensus_pubkey: vector::empty(),
-        network_addresses: vector::empty(),
-        fullnode_addresses: vector::empty(),
-        validator_index: 0,
-    });
+    move_to(
+        owner,
+        ValidatorConfig {
+            consensus_pubkey: vector::empty(),
+            network_addresses: vector::empty(),
+            fullnode_addresses: vector::empty(),
+            validator_index: 0
+        }
+    );
 
     if (initial_stake_amount != 0) {
         add_stake(owner, initial_stake_amount);
@@ -2500,19 +2683,32 @@ Initialize the validator account and give ownership to the signing account.
     account: &signer,
     consensus_pubkey: vector<u8>,
     network_addresses: vector<u8>,
-    fullnode_addresses: vector<u8>,
+    fullnode_addresses: vector<u8>
 ) acquires AllowedValidators {
+
     // Checks the public key is valid to prevent rogue-key attacks.
-    let valid_public_key = ed25519::new_validated_public_key_from_bytes(consensus_pubkey);
-    assert!(option::is_some(&valid_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY));
+    if (std::features::supra_validator_identity_v2_enabled()) {
+        let _valid_public_key =
+            validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey);
+    } else {
+        let valid_public_key =
+            ed25519::new_validated_public_key_from_bytes(consensus_pubkey);
+        assert!(
+            option::is_some(&valid_public_key),
+            error::invalid_argument(EINVALID_PUBLIC_KEY)
+        );
+    };
 
     initialize_owner(account);
-    move_to(account, ValidatorConfig {
-        consensus_pubkey,
-        network_addresses,
-        fullnode_addresses,
-        validator_index: 0,
-    });
+    move_to(
+        account,
+        ValidatorConfig {
+            consensus_pubkey,
+            network_addresses,
+            fullnode_addresses,
+            validator_index: 0
+        }
+    );
 }
 
@@ -2538,32 +2734,48 @@ Initialize the validator account and give ownership to the signing account.
fun initialize_owner(owner: &signer) acquires AllowedValidators {
     let owner_address = signer::address_of(owner);
     assert!(is_allowed(owner_address), error::not_found(EINELIGIBLE_VALIDATOR));
-    assert!(!stake_pool_exists(owner_address), error::already_exists(EALREADY_REGISTERED));
-
-    move_to(owner, StakePool {
-        active: coin::zero<SupraCoin>(),
-        pending_active: coin::zero<SupraCoin>(),
-        pending_inactive: coin::zero<SupraCoin>(),
-        inactive: coin::zero<SupraCoin>(),
-        locked_until_secs: 0,
-        operator_address: owner_address,
-        delegated_voter: owner_address,
-        // Events.
-        initialize_validator_events: account::new_event_handle<RegisterValidatorCandidateEvent>(owner),
-        set_operator_events: account::new_event_handle<SetOperatorEvent>(owner),
-        add_stake_events: account::new_event_handle<AddStakeEvent>(owner),
-        reactivate_stake_events: account::new_event_handle<ReactivateStakeEvent>(owner),
-        rotate_consensus_key_events: account::new_event_handle<RotateConsensusKeyEvent>(owner),
-        update_network_and_fullnode_addresses_events: account::new_event_handle<UpdateNetworkAndFullnodeAddressesEvent>(
-            owner
-        ),
-        increase_lockup_events: account::new_event_handle<IncreaseLockupEvent>(owner),
-        join_validator_set_events: account::new_event_handle<JoinValidatorSetEvent>(owner),
-        distribute_rewards_events: account::new_event_handle<DistributeRewardsEvent>(owner),
-        unlock_stake_events: account::new_event_handle<UnlockStakeEvent>(owner),
-        withdraw_stake_events: account::new_event_handle<WithdrawStakeEvent>(owner),
-        leave_validator_set_events: account::new_event_handle<LeaveValidatorSetEvent>(owner),
-    });
+    assert!(
+        !stake_pool_exists(owner_address),
+        error::already_exists(EALREADY_REGISTERED)
+    );
+
+    move_to(
+        owner,
+        StakePool {
+            active: coin::zero<SupraCoin>(),
+            pending_active: coin::zero<SupraCoin>(),
+            pending_inactive: coin::zero<SupraCoin>(),
+            inactive: coin::zero<SupraCoin>(),
+            locked_until_secs: 0,
+            operator_address: owner_address,
+            delegated_voter: owner_address,
+            // Events.
+            initialize_validator_events: account::new_event_handle<
+                RegisterValidatorCandidateEvent>(owner),
+            set_operator_events: account::new_event_handle<SetOperatorEvent>(owner),
+            add_stake_events: account::new_event_handle<AddStakeEvent>(owner),
+            reactivate_stake_events: account::new_event_handle<ReactivateStakeEvent>(
+                owner
+            ),
+            rotate_consensus_key_events: account::new_event_handle<
+                RotateConsensusKeyEvent>(owner),
+            update_network_and_fullnode_addresses_events: account::new_event_handle<
+                UpdateNetworkAndFullnodeAddressesEvent>(owner),
+            increase_lockup_events: account::new_event_handle<IncreaseLockupEvent>(
+                owner
+            ),
+            join_validator_set_events: account::new_event_handle<JoinValidatorSetEvent>(
+                owner
+            ),
+            distribute_rewards_events: account::new_event_handle<DistributeRewardsEvent>(
+                owner
+            ),
+            unlock_stake_events: account::new_event_handle<UnlockStakeEvent>(owner),
+            withdraw_stake_events: account::new_event_handle<WithdrawStakeEvent>(owner),
+            leave_validator_set_events: account::new_event_handle<
+                LeaveValidatorSetEvent>(owner)
+        }
+    );
 
     move_to(owner, OwnerCapability { pool_address: owner_address });
 }
@@ -2617,8 +2829,13 @@ staking pool.
 Implementation
 
 
-
public fun deposit_owner_cap(owner: &signer, owner_cap: OwnerCapability) {
-    assert!(!exists<OwnerCapability>(signer::address_of(owner)), error::not_found(EOWNER_CAP_ALREADY_EXISTS));
+
public fun deposit_owner_cap(
+    owner: &signer, owner_cap: OwnerCapability
+) {
+    assert!(
+        !exists<OwnerCapability>(signer::address_of(owner)),
+        error::not_found(EOWNER_CAP_ALREADY_EXISTS)
+    );
     move_to(owner, owner_cap);
 }
 
@@ -2668,7 +2885,9 @@ Allows an owner to change the operator of the stake pool. Implementation -
public entry fun set_operator(owner: &signer, new_operator: address) acquires OwnerCapability, StakePool {
+
public entry fun set_operator(
+    owner: &signer, new_operator: address
+) acquires OwnerCapability, StakePool {
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -2696,7 +2915,9 @@ Allows an account with ownership capability to change the operator of the stake
 Implementation
 
 
-
public fun set_operator_with_cap(owner_cap: &OwnerCapability, new_operator: address) acquires StakePool {
+
public fun set_operator_with_cap(
+    owner_cap: &OwnerCapability, new_operator: address
+) acquires StakePool {
     let pool_address = owner_cap.pool_address;
     assert_stake_pool_exists(pool_address);
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
@@ -2704,22 +2925,12 @@ Allows an account with ownership capability to change the operator of the stake
     stake_pool.operator_address = new_operator;
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            SetOperator {
-                pool_address,
-                old_operator,
-                new_operator,
-            },
-        );
+        event::emit(SetOperator { pool_address, old_operator, new_operator });
     };
 
     event::emit_event(
         &mut stake_pool.set_operator_events,
-        SetOperatorEvent {
-            pool_address,
-            old_operator,
-            new_operator,
-        },
+        SetOperatorEvent { pool_address, old_operator, new_operator }
     );
 }
 
@@ -2744,7 +2955,9 @@ Allows an owner to change the delegated voter of the stake pool. Implementation -
public entry fun set_delegated_voter(owner: &signer, new_voter: address) acquires OwnerCapability, StakePool {
+
public entry fun set_delegated_voter(
+    owner: &signer, new_voter: address
+) acquires OwnerCapability, StakePool {
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -2772,7 +2985,9 @@ Allows an owner to change the delegated voter of the stake pool.
 Implementation
 
 
-
public fun set_delegated_voter_with_cap(owner_cap: &OwnerCapability, new_voter: address) acquires StakePool {
+
public fun set_delegated_voter_with_cap(
+    owner_cap: &OwnerCapability, new_voter: address
+) acquires StakePool {
     let pool_address = owner_cap.pool_address;
     assert_stake_pool_exists(pool_address);
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
@@ -2800,7 +3015,9 @@ Add amount of coins from the Implementation
 
 
-
public entry fun add_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool, ValidatorSet {
+
public entry fun add_stake(
+    owner: &signer, amount: u64
+) acquires OwnerCapability, StakePool, ValidatorSet {
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -2828,7 +3045,9 @@ Add coins into pool_address. this requires the corresp
 Implementation
 
 
-
public fun add_stake_with_cap(owner_cap: &OwnerCapability, coins: Coin<SupraCoin>) acquires StakePool, ValidatorSet {
+
public fun add_stake_with_cap(
+    owner_cap: &OwnerCapability, coins: Coin<SupraCoin>
+) acquires StakePool, ValidatorSet {
     assert_reconfig_not_in_progress();
     let pool_address = owner_cap.pool_address;
     assert_stake_pool_exists(pool_address);
@@ -2844,8 +3063,11 @@ Add coins into pool_address. this requires the corresp
     // Inactive validator's total stake will be tracked when they join the validator set.
     let validator_set = borrow_global_mut<ValidatorSet>(@supra_framework);
     // Search directly rather using get_validator_state to save on unnecessary loops.
-    if (option::is_some(&find_validator(&validator_set.active_validators, pool_address)) ||
-        option::is_some(&find_validator(&validator_set.pending_active, pool_address))) {
+    if (option::is_some(
+        &find_validator(&validator_set.active_validators, pool_address)
+    ) || option::is_some(
+        &find_validator(&validator_set.pending_active, pool_address)
+    )) {
         update_voting_power_increase(amount);
     };
 
@@ -2858,24 +3080,19 @@ Add coins into pool_address. this requires the corresp
         coin::merge<SupraCoin>(&mut stake_pool.active, coins);
     };
 
-    let (_, maximum_stake) = staking_config::get_required_stake(&staking_config::get());
+    let (_, maximum_stake) =
+        staking_config::get_required_stake(&staking_config::get());
     let voting_power = get_next_epoch_voting_power(stake_pool);
-    assert!(voting_power <= maximum_stake, error::invalid_argument(ESTAKE_EXCEEDS_MAX));
+    assert!(
+        voting_power <= maximum_stake, error::invalid_argument(ESTAKE_EXCEEDS_MAX)
+    );
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            AddStake {
-                pool_address,
-                amount_added: amount,
-            },
-        );
+        event::emit(AddStake { pool_address, amount_added: amount });
     };
     event::emit_event(
         &mut stake_pool.add_stake_events,
-        AddStakeEvent {
-            pool_address,
-            amount_added: amount,
-        },
+        AddStakeEvent { pool_address, amount_added: amount }
     );
 }
 
@@ -2928,7 +3145,9 @@ Move amount of coins from pending_inactive to active. Implementation -
public fun reactivate_stake_with_cap(owner_cap: &OwnerCapability, amount: u64) acquires StakePool {
+
public fun reactivate_stake_with_cap(
+    owner_cap: &OwnerCapability, amount: u64
+) acquires StakePool {
     assert_reconfig_not_in_progress();
     let pool_address = owner_cap.pool_address;
     assert_stake_pool_exists(pool_address);
@@ -2945,19 +3164,11 @@ Move amount of coins from pending_inactive to active.
     coin::merge(&mut stake_pool.active, reactivated_coins);
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            ReactivateStake {
-                pool_address,
-                amount,
-            },
-        );
+        event::emit(ReactivateStake { pool_address, amount });
     };
     event::emit_event(
         &mut stake_pool.reactivate_stake_events,
-        ReactivateStakeEvent {
-            pool_address,
-            amount,
-        },
+        ReactivateStakeEvent { pool_address, amount }
     );
 }
 
@@ -2985,24 +3196,52 @@ Move amount of coins from pending_inactive to active. operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>, - genesis: bool, + genesis: bool ) acquires StakePool, ValidatorConfig { assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut<StakePool>(pool_address); - assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR)); + assert!( + signer::address_of(operator) == stake_pool.operator_address, + error::unauthenticated(ENOT_OPERATOR) + ); - assert!(exists<ValidatorConfig>(pool_address), error::not_found(EVALIDATOR_CONFIG)); + assert!( + exists<ValidatorConfig>(pool_address), + error::not_found(EVALIDATOR_CONFIG) + ); let validator_info = borrow_global_mut<ValidatorConfig>(pool_address); let old_consensus_pubkey = validator_info.consensus_pubkey; // Checks the public key is valid to prevent rogue-key attacks. if (!genesis) { - let validated_public_key = ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); - assert!(option::is_some(&validated_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY)); + if (std::features::supra_validator_identity_v2_enabled()) { + let _valid_public_key = + validator_public_keys::validator_public_keys_from_bytes( + new_consensus_pubkey + ); + } else { + let valid_public_key = + ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); + assert!( + option::is_some(&valid_public_key), + error::invalid_argument(EINVALID_PUBLIC_KEY) + ); + }; } else { - let validated_public_key = ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); - assert!(option::is_some(&validated_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY)); + if (std::features::supra_validator_identity_v2_enabled()) { + let _valid_public_key = + validator_public_keys::validator_public_keys_from_bytes( + new_consensus_pubkey + ); + } else { + let valid_public_key = + ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); + assert!( + option::is_some(&valid_public_key), + error::invalid_argument(EINVALID_PUBLIC_KEY) + ); + }; }; validator_info.consensus_pubkey = new_consensus_pubkey; @@ -3011,8 +3250,8 @@ Move amount of coins from pending_inactive to active. RotateConsensusKey { pool_address, old_consensus_pubkey, - new_consensus_pubkey, - }, + new_consensus_pubkey + } ); }; event::emit_event( @@ -3020,14 +3259,126 @@ Move amount of coins from pending_inactive to active. RotateConsensusKeyEvent { pool_address, old_consensus_pubkey, - new_consensus_pubkey, - }, + new_consensus_pubkey + } ); }
+ + + + +## Function `set_dkg_output_keys` + +Set DKG output keys for all provided threshold types. +Each DkgCommitteeOutput contains a threshold_type and corresponding keys for all validators. + + +
public(friend) fun set_dkg_output_keys(committee_outputs: vector<dkg_committee::DkgCommitteeOutput>)
+
+ + + +
+Implementation + + +
public(friend) fun set_dkg_output_keys(
+    committee_outputs: vector<dkg_committee::DkgCommitteeOutput>
+) acquires ValidatorConfig, ValidatorFees, ValidatorPerformance, ValidatorSet, StakePool {
+    if (vector::is_empty(&committee_outputs)) { return };
+
+    let next_validator_infos = next_validator_consensus_infos();
+    let num_validators = vector::length(&next_validator_infos);
+
+    // Validate all committee outputs have correct number of keys
+    let num_outputs = vector::length(&committee_outputs);
+    let j = 0;
+    while (j < num_outputs) {
+        let output = vector::borrow(&committee_outputs, j);
+        assert!(
+            num_validators
+                == vector::length(
+                    &dkg_committee::get_dkg_committee_output_keys(output)
+                ),
+            error::invalid_argument(EDKG_INVALID_PK_SHARES)
+        );
+        j = j + 1;
+    };
+
+    // Iterate over each validator
+    let i = 0;
+    while (i < num_validators) {
+        let val_info = vector::borrow(&next_validator_infos, i);
+        let addr = validator_consensus_info::get_addr(val_info);
+        let validator_config = borrow_global_mut<ValidatorConfig>(addr);
+        let old_consensus_pubkey = validator_config.consensus_pubkey;
+
+        // Load current public keys
+        let pub_keys =
+            validator_public_keys::validator_public_keys_from_bytes(
+                old_consensus_pubkey
+            );
+
+        // Apply all threshold key updates for this validator
+        let k = 0;
+        while (k < num_outputs) {
+            let output = vector::borrow(&committee_outputs, k);
+            let output_keys = dkg_committee::get_dkg_committee_output_keys(output);
+            let key_bytes = vector::borrow(&output_keys, i);
+
+            // Deserialize the key
+            let key_opt = aptos_std::bls12381::public_key_from_bytes(*key_bytes);
+            assert!(
+                option::is_some(&key_opt),
+                error::invalid_argument(EINVALID_PUBLIC_KEY)
+            );
+            let new_key = option::extract(&mut key_opt);
+
+            // Rotate the key based on threshold type
+            validator_public_keys::rotate_supra_bls_threshold_key_by_type(
+                &mut pub_keys,
+                dkg_committee::get_dkg_committee_output_threshold_type(output),
+                new_key
+            );
+            k = k + 1;
+        };
+
+        // Serialize and save updated keys
+        let new_consensus_pubkey =
+            validator_public_keys::public_key_to_bytes(pub_keys);
+        validator_config.consensus_pubkey = new_consensus_pubkey;
+
+        // Emit events
+        let stake_pool = borrow_global_mut<StakePool>(addr);
+        if (std::features::module_event_migration_enabled()) {
+            event::emit(
+                RotateConsensusKey {
+                    pool_address: addr,
+                    old_consensus_pubkey,
+                    new_consensus_pubkey
+                }
+            );
+        };
+        event::emit_event(
+            &mut stake_pool.rotate_consensus_key_events,
+            RotateConsensusKeyEvent {
+                pool_address: addr,
+                old_consensus_pubkey,
+                new_consensus_pubkey
+            }
+        );
+
+        i = i + 1;
+    };
+}
+
+ + +
@@ -3049,11 +3400,14 @@ only for genesis
public(friend) fun rotate_consensus_key_genesis(
-    operator: &signer,
-    pool_address: address,
-    new_consensus_pubkey: vector<u8>,
+    operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>
 ) acquires StakePool, ValidatorConfig {
-    rotate_consensus_key_internal(operator, pool_address, new_consensus_pubkey, true);
+    rotate_consensus_key_internal(
+        operator,
+        pool_address,
+        new_consensus_pubkey,
+        true
+    );
 }
 
@@ -3078,11 +3432,14 @@ Rotate the consensus key of the validator, it'll take effect in next epoch.
public entry fun rotate_consensus_key(
-    operator: &signer,
-    pool_address: address,
-    new_consensus_pubkey: vector<u8>,
+    operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>
 ) acquires StakePool, ValidatorConfig {
-    rotate_consensus_key_internal(operator, pool_address, new_consensus_pubkey, false);
+    rotate_consensus_key_internal(
+        operator,
+        pool_address,
+        new_consensus_pubkey,
+        false
+    );
 }
 
@@ -3110,13 +3467,19 @@ Update the network and full node addresses of the validator. This only takes eff operator: &signer, pool_address: address, new_network_addresses: vector<u8>, - new_fullnode_addresses: vector<u8>, + new_fullnode_addresses: vector<u8> ) acquires StakePool, ValidatorConfig { assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut<StakePool>(pool_address); - assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR)); - assert!(exists<ValidatorConfig>(pool_address), error::not_found(EVALIDATOR_CONFIG)); + assert!( + signer::address_of(operator) == stake_pool.operator_address, + error::unauthenticated(ENOT_OPERATOR) + ); + assert!( + exists<ValidatorConfig>(pool_address), + error::not_found(EVALIDATOR_CONFIG) + ); let validator_info = borrow_global_mut<ValidatorConfig>(pool_address); let old_network_addresses = validator_info.network_addresses; validator_info.network_addresses = new_network_addresses; @@ -3130,8 +3493,8 @@ Update the network and full node addresses of the validator. This only takes eff old_network_addresses, new_network_addresses, old_fullnode_addresses, - new_fullnode_addresses, - }, + new_fullnode_addresses + } ); }; event::emit_event( @@ -3141,8 +3504,8 @@ Update the network and full node addresses of the validator. This only takes eff old_network_addresses, new_network_addresses, old_fullnode_addresses, - new_fullnode_addresses, - }, + new_fullnode_addresses + } ); } @@ -3204,8 +3567,13 @@ directly inactive if it's not from an active validator. let stake_pool = borrow_global_mut<StakePool>(pool_address); let old_locked_until_secs = stake_pool.locked_until_secs; - let new_locked_until_secs = timestamp::now_seconds() + staking_config::get_recurring_lockup_duration(&config); - assert!(old_locked_until_secs < new_locked_until_secs, error::invalid_argument(EINVALID_LOCKUP)); + let new_locked_until_secs = + timestamp::now_seconds() + + staking_config::get_recurring_lockup_duration(&config); + assert!( + old_locked_until_secs < new_locked_until_secs, + error::invalid_argument(EINVALID_LOCKUP) + ); stake_pool.locked_until_secs = new_locked_until_secs; if (std::features::module_event_migration_enabled()) { @@ -3213,8 +3581,8 @@ directly inactive if it's not from an active validator. IncreaseLockup { pool_address, old_locked_until_secs, - new_locked_until_secs, - }, + new_locked_until_secs + } ); }; event::emit_event( @@ -3222,8 +3590,8 @@ directly inactive if it's not from an active validator. IncreaseLockupEvent { pool_address, old_locked_until_secs, - new_locked_until_secs, - }, + new_locked_until_secs + } ); }
@@ -3249,12 +3617,11 @@ This can only called by the operator of the validator/staking pool.
public entry fun join_validator_set(
-    operator: &signer,
-    pool_address: address
+    operator: &signer, pool_address: address
 ) acquires StakePool, ValidatorConfig, ValidatorSet {
     assert!(
         staking_config::get_allow_validator_set_change(&staking_config::get()),
-        error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED),
+        error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED)
     );
 
     join_validator_set_internal(operator, pool_address);
@@ -3287,16 +3654,18 @@ This internal version can only be called by the Genesis module during Genesis.
 
 
 
public(friend) fun join_validator_set_internal(
-    operator: &signer,
-    pool_address: address
+    operator: &signer, pool_address: address
 ) acquires StakePool, ValidatorConfig, ValidatorSet {
     assert_reconfig_not_in_progress();
     assert_stake_pool_exists(pool_address);
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
-    assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR));
+    assert!(
+        signer::address_of(operator) == stake_pool.operator_address,
+        error::unauthenticated(ENOT_OPERATOR)
+    );
     assert!(
         get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE,
-        error::invalid_state(EALREADY_ACTIVE_VALIDATOR),
+        error::invalid_state(EALREADY_ACTIVE_VALIDATOR)
     );
 
     let config = staking_config::get();
@@ -3310,7 +3679,10 @@ This internal version can only be called by the Genesis module during Genesis.
 
     // Add validator to pending_active, to be activated in the next epoch.
     let validator_config = borrow_global_mut<ValidatorConfig>(pool_address);
-    assert!(!vector::is_empty(&validator_config.consensus_pubkey), error::invalid_argument(EINVALID_PUBLIC_KEY));
+    assert!(
+        !vector::is_empty(&validator_config.consensus_pubkey),
+        error::invalid_argument(EINVALID_PUBLIC_KEY)
+    );
 
     // Validate the current validator set size has not exceeded the limit.
     let validator_set = borrow_global_mut<ValidatorSet>(@supra_framework);
@@ -3318,17 +3690,19 @@ This internal version can only be called by the Genesis module during Genesis.
         &mut validator_set.pending_active,
         generate_validator_info(pool_address, stake_pool, *validator_config)
     );
-    let validator_set_size = vector::length(&validator_set.active_validators) + vector::length(
-        &validator_set.pending_active
+    let validator_set_size = vector::length(&validator_set.active_validators)
+        + vector::length(&validator_set.pending_active);
+    assert!(
+        validator_set_size <= MAX_VALIDATOR_SET_SIZE,
+        error::invalid_argument(EVALIDATOR_SET_TOO_LARGE)
     );
-    assert!(validator_set_size <= MAX_VALIDATOR_SET_SIZE, error::invalid_argument(EVALIDATOR_SET_TOO_LARGE));
 
     if (std::features::module_event_migration_enabled()) {
         event::emit(JoinValidatorSet { pool_address });
     };
     event::emit_event(
         &mut stake_pool.join_validator_set_events,
-        JoinValidatorSetEvent { pool_address },
+        JoinValidatorSetEvent { pool_address }
     );
 }
 
@@ -3385,9 +3759,7 @@ Unlock amount from the active stake. Only possible if the lockup ha
public fun unlock_with_cap(amount: u64, owner_cap: &OwnerCapability) acquires StakePool {
     assert_reconfig_not_in_progress();
     // Short-circuit if amount to unlock is 0 so we don't emit events.
-    if (amount == 0) {
-        return
-    };
+    if (amount == 0) { return };
 
     // Unlocked coins are moved to pending_inactive. When the current lockup cycle expires, they will be moved into
     // inactive in the earliest possible epoch transition.
@@ -3400,19 +3772,11 @@ Unlock amount from the active stake. Only possible if the lockup ha
     coin::merge<SupraCoin>(&mut stake_pool.pending_inactive, unlocked_stake);
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            UnlockStake {
-                pool_address,
-                amount_unlocked: amount,
-            },
-        );
+        event::emit(UnlockStake { pool_address, amount_unlocked: amount });
     };
     event::emit_event(
         &mut stake_pool.unlock_stake_events,
-        UnlockStakeEvent {
-            pool_address,
-            amount_unlocked: amount,
-        },
+        UnlockStakeEvent { pool_address, amount_unlocked: amount }
     );
 }
 
@@ -3438,8 +3802,7 @@ Withdraw from account's inacti
public entry fun withdraw(
-    owner: &signer,
-    withdraw_amount: u64
+    owner: &signer, withdraw_amount: u64
 ) acquires OwnerCapability, StakePool, ValidatorSet {
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
@@ -3470,8 +3833,7 @@ Withdraw from pool_address's inactive stake with the corresponding
 
 
 
public fun withdraw_with_cap(
-    owner_cap: &OwnerCapability,
-    withdraw_amount: u64
+    owner_cap: &OwnerCapability, withdraw_amount: u64
 ): Coin<SupraCoin> acquires StakePool, ValidatorSet {
     assert_reconfig_not_in_progress();
     let pool_address = owner_cap.pool_address;
@@ -3480,9 +3842,10 @@ Withdraw from pool_address's inactive stake with the corresponding
     // There's an edge case where a validator unlocks their stake and leaves the validator set before
     // the stake is fully unlocked (the current lockup cycle has not expired yet).
     // This can leave their stake stuck in pending_inactive even after the current lockup cycle expires.
-    if (get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE &&
-        timestamp::now_seconds() >= stake_pool.locked_until_secs) {
-        let pending_inactive_stake = coin::extract_all(&mut stake_pool.pending_inactive);
+    if (get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE
+        && timestamp::now_seconds() >= stake_pool.locked_until_secs) {
+        let pending_inactive_stake =
+            coin::extract_all(&mut stake_pool.pending_inactive);
         coin::merge(&mut stake_pool.inactive, pending_inactive_stake);
     };
 
@@ -3491,19 +3854,11 @@ Withdraw from pool_address's inactive stake with the corresponding
     if (withdraw_amount == 0) return coin::zero<SupraCoin>();
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            WithdrawStake {
-                pool_address,
-                amount_withdrawn: withdraw_amount,
-            },
-        );
+        event::emit(WithdrawStake { pool_address, amount_withdrawn: withdraw_amount });
     };
     event::emit_event(
         &mut stake_pool.withdraw_stake_events,
-        WithdrawStakeEvent {
-            pool_address,
-            amount_withdrawn: withdraw_amount,
-        },
+        WithdrawStakeEvent { pool_address, amount_withdrawn: withdraw_amount }
     );
 
     coin::extract(&mut stake_pool.inactive, withdraw_amount)
@@ -3536,27 +3891,32 @@ Can only be called by the operator of the validator/staking pool.
 
 
 
public entry fun leave_validator_set(
-    operator: &signer,
-    pool_address: address
+    operator: &signer, pool_address: address
 ) acquires StakePool, ValidatorSet {
     assert_reconfig_not_in_progress();
     let config = staking_config::get();
     assert!(
         staking_config::get_allow_validator_set_change(&config),
-        error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED),
+        error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED)
     );
 
     assert_stake_pool_exists(pool_address);
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
     // Account has to be the operator.
-    assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR));
+    assert!(
+        signer::address_of(operator) == stake_pool.operator_address,
+        error::unauthenticated(ENOT_OPERATOR)
+    );
 
     let validator_set = borrow_global_mut<ValidatorSet>(@supra_framework);
     // If the validator is still pending_active, directly kick the validator out.
-    let maybe_pending_active_index = find_validator(&validator_set.pending_active, pool_address);
+    let maybe_pending_active_index =
+        find_validator(&validator_set.pending_active, pool_address);
     if (option::is_some(&maybe_pending_active_index)) {
         vector::swap_remove(
-            &mut validator_set.pending_active, option::extract(&mut maybe_pending_active_index));
+            &mut validator_set.pending_active,
+            option::extract(&mut maybe_pending_active_index)
+        );
 
         // Decrease the voting power increase as the pending validator's voting power was added when they requested
         // to join. Now that they changed their mind, their voting power should not affect the joining limit of this
@@ -3566,17 +3926,27 @@ Can only be called by the operator of the validator/staking pool.
         // rounding error somewhere that can lead to an underflow, we still want to allow this transaction to
         // succeed.
         if (validator_set.total_joining_power > validator_stake) {
-            validator_set.total_joining_power = validator_set.total_joining_power - validator_stake;
+            validator_set.total_joining_power =
+                validator_set.total_joining_power - validator_stake;
         } else {
             validator_set.total_joining_power = 0;
         };
     } else {
         // Validate that the validator is already part of the validator set.
-        let maybe_active_index = find_validator(&validator_set.active_validators, pool_address);
-        assert!(option::is_some(&maybe_active_index), error::invalid_state(ENOT_VALIDATOR));
+        let maybe_active_index =
+            find_validator(&validator_set.active_validators, pool_address);
+        assert!(
+            option::is_some(&maybe_active_index),
+            error::invalid_state(ENOT_VALIDATOR)
+        );
         let validator_info = vector::swap_remove(
-            &mut validator_set.active_validators, option::extract(&mut maybe_active_index));
-        assert!(vector::length(&validator_set.active_validators) != 0, error::invalid_state(ELAST_VALIDATOR));
+            &mut validator_set.active_validators,
+            option::extract(&mut maybe_active_index)
+        );
+        assert!(
+            vector::length(&validator_set.active_validators) != 0,
+            error::invalid_state(ELAST_VALIDATOR)
+        );
         vector::push_back(&mut validator_set.pending_inactive, validator_info);
 
         if (std::features::module_event_migration_enabled()) {
@@ -3584,9 +3954,7 @@ Can only be called by the operator of the validator/staking pool.
         };
         event::emit_event(
             &mut stake_pool.leave_validator_set_events,
-            LeaveValidatorSetEvent {
-                pool_address,
-            },
+            LeaveValidatorSetEvent { pool_address }
         );
     };
 }
@@ -3617,7 +3985,8 @@ when the epoch starts.
 
public fun is_current_epoch_validator(pool_address: address): bool acquires ValidatorSet {
     assert_stake_pool_exists(pool_address);
     let validator_state = get_validator_state(pool_address);
-    validator_state == VALIDATOR_STATUS_ACTIVE || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE
+    validator_state == VALIDATOR_STATUS_ACTIVE
+        || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE
 }
 
@@ -3643,8 +4012,7 @@ This function cannot abort.
public(friend) fun update_performance_statistics(
-    proposer_index: Option<u64>,
-    failed_proposer_indices: vector<u64>
+    proposer_index: Option<u64>, failed_proposer_indices: vector<u64>
 ) acquires ValidatorPerformance {
     // Validator set cannot change until the end of the epoch, so the validator index in arguments should
     // match with those of the validators in ValidatorPerformance resource.
@@ -3661,7 +4029,9 @@ This function cannot abort.
         // Here, and in all other vector::borrow, skip any validator indices that are out of bounds,
         // this ensures that this function doesn't abort if there are out of bounds errors.
         if (cur_proposer_index < validator_len) {
-            let validator = vector::borrow_mut(&mut validator_perf.validators, cur_proposer_index);
+            let validator = vector::borrow_mut(
+                &mut validator_perf.validators, cur_proposer_index
+            );
             spec {
                 assume validator.successful_proposals + 1 <= MAX_U64;
             };
@@ -3674,17 +4044,25 @@ This function cannot abort.
     while ({
         spec {
             invariant len(validator_perf.validators) == validator_len;
-            invariant (option::spec_is_some(ghost_proposer_idx) && option::spec_borrow(
-                ghost_proposer_idx
-            ) < validator_len) ==>
-                (validator_perf.validators[option::spec_borrow(ghost_proposer_idx)].successful_proposals ==
-                    ghost_valid_perf.validators[option::spec_borrow(ghost_proposer_idx)].successful_proposals + 1);
+            invariant (
+                option::spec_is_some(ghost_proposer_idx)
+                    && option::spec_borrow(ghost_proposer_idx) < validator_len
+            ) ==>
+                (
+                    validator_perf.validators[option::spec_borrow(ghost_proposer_idx)]
+                    .successful_proposals
+                        == ghost_valid_perf.validators[option::spec_borrow(
+                            ghost_proposer_idx
+                        )].successful_proposals + 1
+                );
         };
         f < f_len
     }) {
         let validator_index = *vector::borrow(&failed_proposer_indices, f);
         if (validator_index < validator_len) {
-            let validator = vector::borrow_mut(&mut validator_perf.validators, validator_index);
+            let validator = vector::borrow_mut(
+                &mut validator_perf.validators, validator_index
+            );
             spec {
                 assume validator.failed_proposals + 1 <= MAX_U64;
             };
@@ -3724,24 +4102,29 @@ power.
 Implementation
 
 
-
public(friend) fun on_new_epoch(
-) acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+
public(friend) fun on_new_epoch() acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
     let validator_set = borrow_global_mut<ValidatorSet>(@supra_framework);
     let config = staking_config::get();
     let validator_perf = borrow_global_mut<ValidatorPerformance>(@supra_framework);
 
     // Process pending stake and distribute transaction fees and rewards for each currently active validator.
-    vector::for_each_ref(&validator_set.active_validators, |validator| {
-        let validator: &ValidatorInfo = validator;
-        update_stake_pool(validator_perf, validator.addr, &config);
-    });
+    vector::for_each_ref(
+        &validator_set.active_validators,
+        |validator| {
+            let validator: &ValidatorInfo = validator;
+            update_stake_pool(validator_perf, validator.addr, &config);
+        }
+    );
 
     // Process pending stake and distribute transaction fees and rewards for each currently pending_inactive validator
     // (requested to leave but not removed yet).
-    vector::for_each_ref(&validator_set.pending_inactive, |validator| {
-        let validator: &ValidatorInfo = validator;
-        update_stake_pool(validator_perf, validator.addr, &config);
-    });
+    vector::for_each_ref(
+        &validator_set.pending_inactive,
+        |validator| {
+            let validator: &ValidatorInfo = validator;
+            update_stake_pool(validator_perf, validator.addr, &config);
+        }
+    );
 
     // Activate currently pending_active validators.
     append(&mut validator_set.active_validators, &mut validator_set.pending_active);
@@ -3764,18 +4147,23 @@ power.
         };
         i < vlen
     }) {
-        let old_validator_info = vector::borrow_mut(&mut validator_set.active_validators, i);
+        let old_validator_info = vector::borrow_mut(
+            &mut validator_set.active_validators, i
+        );
         let pool_address = old_validator_info.addr;
         let validator_config = borrow_global_mut<ValidatorConfig>(pool_address);
         let stake_pool = borrow_global_mut<StakePool>(pool_address);
-        let new_validator_info = generate_validator_info(pool_address, stake_pool, *validator_config);
+        let new_validator_info =
+            generate_validator_info(pool_address, stake_pool, *validator_config);
 
         // A validator needs at least the min stake required to join the validator set.
         if (new_validator_info.voting_power >= minimum_stake) {
             spec {
-                assume total_voting_power + new_validator_info.voting_power <= MAX_U128;
+                assume total_voting_power + new_validator_info.voting_power
+                    <= MAX_U128;
             };
-            total_voting_power = total_voting_power + (new_validator_info.voting_power as u128);
+            total_voting_power =
+                total_voting_power + (new_validator_info.voting_power as u128);
             vector::push_back(&mut next_epoch_validators, new_validator_info);
         };
         i = i + 1;
@@ -3787,7 +4175,8 @@ power.
 
     // Update validator indices, reset performance scores, and renew lockups.
     validator_perf.validators = vector::empty();
-    let recurring_lockup_duration_secs = staking_config::get_recurring_lockup_duration(&config);
+    let recurring_lockup_duration_secs =
+        staking_config::get_recurring_lockup_duration(&config);
     let vlen = vector::length(&validator_set.active_validators);
     let validator_index = 0;
     while ({
@@ -3798,37 +4187,47 @@ power.
             invariant 0 <= validator_index && validator_index <= vlen;
             invariant vlen == len(validator_set.active_validators);
             invariant forall i in 0..validator_index:
-                global<ValidatorConfig>(validator_set.active_validators[i].addr).validator_index < validator_index;
+                global<ValidatorConfig>(validator_set.active_validators[i].addr).validator_index
+                    < validator_index;
             invariant forall i in 0..validator_index:
-                validator_set.active_validators[i].config.validator_index < validator_index;
+                validator_set.active_validators[i].config.validator_index
+                    < validator_index;
             invariant len(validator_perf.validators) == validator_index;
         };
         validator_index < vlen
     }) {
-        let validator_info = vector::borrow_mut(&mut validator_set.active_validators, validator_index);
+        let validator_info = vector::borrow_mut(
+            &mut validator_set.active_validators, validator_index
+        );
         validator_info.config.validator_index = validator_index;
-        let validator_config = borrow_global_mut<ValidatorConfig>(validator_info.addr);
+        let validator_config =
+            borrow_global_mut<ValidatorConfig>(validator_info.addr);
         validator_config.validator_index = validator_index;
 
-        vector::push_back(&mut validator_perf.validators, IndividualValidatorPerformance {
-            successful_proposals: 0,
-            failed_proposals: 0,
-        });
+        vector::push_back(
+            &mut validator_perf.validators,
+            IndividualValidatorPerformance {
+                successful_proposals: 0,
+                failed_proposals: 0
+            }
+        );
 
         // Automatically renew a validator's lockup for validators that will still be in the validator set in the
         // next epoch.
         let stake_pool = borrow_global_mut<StakePool>(validator_info.addr);
         let now_secs = timestamp::now_seconds();
-        let reconfig_start_secs = if (chain_status::is_operating()) {
-            get_reconfig_start_time_secs()
-        } else {
-            now_secs
-        };
+        let reconfig_start_secs =
+            if (chain_status::is_operating()) {
+                get_reconfig_start_time_secs()
+            } else {
+                now_secs
+            };
         if (stake_pool.locked_until_secs <= reconfig_start_secs) {
             spec {
                 assume now_secs + recurring_lockup_duration_secs <= MAX_U64;
             };
-            stake_pool.locked_until_secs = now_secs + recurring_lockup_duration_secs;
+            stake_pool.locked_until_secs = now_secs
+                + recurring_lockup_duration_secs;
         };
 
         validator_index = validator_index + 1;
@@ -3887,87 +4286,159 @@ Return the ValidatorConsensusInfo of each current validator, sorted
 
 
 
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
-    // Init.
-    let cur_validator_set = borrow_global<ValidatorSet>(@supra_framework);
-    let staking_config = staking_config::get();
-    let validator_perf = borrow_global<ValidatorPerformance>(@supra_framework);
-    let (minimum_stake, _) = staking_config::get_required_stake(&staking_config);
-    let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate(&staking_config);
+    let new_validator_set = compute_next_validator_set_internal(false);
+    validator_consensus_infos_from_validator_set(&new_validator_set)
+}
+
- // Compute new validator set. - let new_active_validators = vector[]; - let num_new_actives = 0; - let candidate_idx = 0; - let new_total_power = 0; - let num_cur_actives = vector::length(&cur_validator_set.active_validators); - let num_cur_pending_actives = vector::length(&cur_validator_set.pending_active); - spec { - assume num_cur_actives + num_cur_pending_actives <= MAX_U64; - }; - let num_candidates = num_cur_actives + num_cur_pending_actives; - while ({ - spec { - invariant candidate_idx <= num_candidates; - invariant spec_validators_are_initialized(new_active_validators); - invariant len(new_active_validators) == num_new_actives; - invariant forall i in 0..len(new_active_validators): - new_active_validators[i].config.validator_index == i; - invariant num_new_actives <= candidate_idx; - invariant spec_validators_are_initialized(new_active_validators); - }; - candidate_idx < num_candidates + + + + + + +## Function `next_epoch_validator_consensus_infos_for_dkg` + +Same as next_validator_consensus_infos but uses the current-epoch config data for +validators that are already active. This is used when starting DKG: the committee +membership (active + pending_active) must reflect the next epoch, but node config +should reflect current-epoch for the active validators to ensure that validators that update +their configuration do not need to run two copies of themselves to participate in DKG. + + +
public fun next_epoch_validator_consensus_infos_for_dkg(): vector<validator_consensus_info::ValidatorConsensusInfo>
+
+ + + +
+Implementation + + +
public fun next_epoch_validator_consensus_infos_for_dkg(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+    // Use the current-epoch config snapshot for active validators so mid-epoch config changes
+    // do not take effect during DKG (use_current_config_for_actives=true).
+    let new_validator_set = compute_next_validator_set_internal(true);
+    validator_consensus_infos_from_validator_set(&new_validator_set)
+}
+
+ + + +
+ + + +## Function `compute_next_validator_set_internal` + +Computes the validator set for the next epoch. + +use_current_config_for_actives: when true, currently-active validators retain their +current-epoch ValidatorConfig snapshot instead of reading the latest on-chain value. +New joiners (pending_active) always read from ValidatorConfig regardless of this flag. + +pending_active is iterated in reverse to match the order produced by on_new_epoch +(which appends via pop_back). + + +
fun compute_next_validator_set_internal(use_current_config_for_actives: bool): stake::ValidatorSet
+
+ + + +
+Implementation + + +
fun compute_next_validator_set_internal(
+    use_current_config_for_actives: bool,
+): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+    // Init.
+    let cur_validator_set = borrow_global<ValidatorSet>(@supra_framework);
+    let staking_config = staking_config::get();
+    let validator_perf = borrow_global<ValidatorPerformance>(@supra_framework);
+    let (minimum_stake, _) = staking_config::get_required_stake(&staking_config);
+    let (rewards_rate, rewards_rate_denominator) =
+        staking_config::get_reward_rate(&staking_config);
+
+    // Compute new validator set.
+    let new_active_validators = vector[];
+    let num_new_actives = 0;
+    let candidate_idx = 0;
+    let new_total_power = 0;
+    let num_cur_actives = vector::length(&cur_validator_set.active_validators);
+    let num_cur_pending_actives = vector::length(&cur_validator_set.pending_active);
+    spec {
+        assume num_cur_actives + num_cur_pending_actives <= MAX_U64;
+    };
+    let num_candidates = num_cur_actives + num_cur_pending_actives;
+    while ({
+        spec {
+            invariant candidate_idx <= num_candidates;
+            invariant spec_validators_are_initialized(new_active_validators);
+            invariant len(new_active_validators) == num_new_actives;
+            invariant forall i in 0..len(new_active_validators):
+                new_active_validators[i].config.validator_index == i;
+            invariant num_new_actives <= candidate_idx;
+            invariant spec_validators_are_initialized(new_active_validators);
+        };
+        candidate_idx < num_candidates
     }) {
         let candidate_in_current_validator_set = candidate_idx < num_cur_actives;
-        let candidate = if (candidate_idx < num_cur_actives) {
-            vector::borrow(&cur_validator_set.active_validators, candidate_idx)
-        } else {
-            vector::borrow(&cur_validator_set.pending_active, candidate_idx - num_cur_actives)
-        };
+        let candidate =
+            if (candidate_idx < num_cur_actives) {
+                vector::borrow(&cur_validator_set.active_validators, candidate_idx)
+            } else {
+                let pending_idx =
+                    num_cur_pending_actives - 1 - (candidate_idx - num_cur_actives);
+                vector::borrow(&cur_validator_set.pending_active, pending_idx)
+            };
         let stake_pool = borrow_global<StakePool>(candidate.addr);
         let cur_active = coin::value(&stake_pool.active);
         let cur_pending_active = coin::value(&stake_pool.pending_active);
         let cur_pending_inactive = coin::value(&stake_pool.pending_inactive);
 
-        let cur_reward = if (candidate_in_current_validator_set && cur_active != 0) {
-            spec {
-                assert candidate.config.validator_index < len(validator_perf.validators);
-            };
-            let cur_perf = vector::borrow(&validator_perf.validators, candidate.config.validator_index);
-            spec {
-                assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64;
-            };
-            calculate_rewards_amount(cur_active, cur_perf.successful_proposals, cur_perf.successful_proposals + cur_perf.failed_proposals, rewards_rate, rewards_rate_denominator)
-        } else {
-            0
-        };
+        let cur_reward = calculate_candidate_reward(
+            candidate,
+            candidate_in_current_validator_set,
+            cur_active,
+            validator_perf,
+            rewards_rate,
+            rewards_rate_denominator
+        );
 
-        let cur_fee = 0;
-        if (features::collect_and_distribute_gas_fees()) {
-            let fees_table = &borrow_global<ValidatorFees>(@supra_framework).fees_table;
-            if (table::contains(fees_table, candidate.addr)) {
-                let fee_coin = table::borrow(fees_table, candidate.addr);
-                cur_fee = coin::value(fee_coin);
-            }
-        };
+        let cur_fee = collect_candidate_fee(candidate.addr);
 
-        let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
+        let lockup_expired =
+            get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
         spec {
-            assume cur_active + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
-            assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward + cur_fee <= MAX_U64;
+            assume cur_active + cur_pending_active + cur_reward + cur_fee
+                <= MAX_U64;
+            assume cur_active + cur_pending_inactive + cur_pending_active
+                + cur_reward + cur_fee <= MAX_U64;
         };
         let new_voting_power =
             cur_active
-            + if (lockup_expired) { 0 } else { cur_pending_inactive }
-            + cur_pending_active
-            + cur_reward + cur_fee;
+                + if (lockup_expired) { 0 }
+                else {
+                    cur_pending_inactive
+                } + cur_pending_active + cur_reward + cur_fee;
 
         if (new_voting_power >= minimum_stake) {
-            let config = *borrow_global<ValidatorConfig>(candidate.addr);
+            let config =
+                if (use_current_config_for_actives && candidate_in_current_validator_set) {
+                    // Use the current-epoch config snapshot so that any mid-epoch changes
+                    // (consensus key, network addresses, etc.) only take effect after the
+                    // epoch transition, not during DKG.
+                    candidate.config
+                } else {
+                    *borrow_global<ValidatorConfig>(candidate.addr)
+                };
             config.validator_index = num_new_actives;
             let new_validator_info = ValidatorInfo {
                 addr: candidate.addr,
                 voting_power: new_voting_power,
-                config,
+                config
             };
 
             // Update ValidatorSet.
@@ -3977,21 +4448,100 @@ Return the ValidatorConsensusInfo of each current validator, sorted
             new_total_power = new_total_power + (new_voting_power as u128);
             vector::push_back(&mut new_active_validators, new_validator_info);
             num_new_actives = num_new_actives + 1;
-
         };
         candidate_idx = candidate_idx + 1;
     };
 
-    let new_validator_set = ValidatorSet {
+    ValidatorSet {
         consensus_scheme: cur_validator_set.consensus_scheme,
         active_validators: new_active_validators,
         pending_inactive: vector[],
         pending_active: vector[],
         total_voting_power: new_total_power,
-        total_joining_power: 0,
-    };
+        total_joining_power: 0
+    }
+}
+
- validator_consensus_infos_from_validator_set(&new_validator_set) + + +
+ + + +## Function `calculate_candidate_reward` + +Computes the reward earned by a candidate validator for the current epoch. +Returns 0 for pending-active validators (not yet in the active set) or validators +with no active stake. + + +
fun calculate_candidate_reward(candidate: &stake::ValidatorInfo, candidate_in_current_validator_set: bool, cur_active: u64, validator_perf: &stake::ValidatorPerformance, rewards_rate: u64, rewards_rate_denominator: u64): u64
+
+ + + +
+Implementation + + +
fun calculate_candidate_reward(
+    candidate: &ValidatorInfo,
+    candidate_in_current_validator_set: bool,
+    cur_active: u64,
+    validator_perf: &ValidatorPerformance,
+    rewards_rate: u64,
+    rewards_rate_denominator: u64,
+): u64 {
+    if (candidate_in_current_validator_set && cur_active != 0) {
+        spec {
+            assert candidate.config.validator_index < len(validator_perf.validators);
+        };
+        let cur_perf = vector::borrow(
+            &validator_perf.validators, candidate.config.validator_index
+        );
+        spec {
+            assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64;
+        };
+        calculate_rewards_amount(
+            cur_active,
+            cur_perf.successful_proposals,
+            cur_perf.successful_proposals + cur_perf.failed_proposals,
+            rewards_rate,
+            rewards_rate_denominator
+        )
+    } else { 0 }
+}
+
+ + + +
+ + + +## Function `collect_candidate_fee` + +Returns the accumulated gas fees assigned to candidate_addr, or 0 if fee collection +is disabled or no fees have been recorded for this validator. + + +
fun collect_candidate_fee(candidate_addr: address): u64
+
+ + + +
+Implementation + + +
fun collect_candidate_fee(candidate_addr: address): u64 acquires ValidatorFees {
+    if (features::collect_and_distribute_gas_fees()) {
+        let fees_table = &borrow_global<ValidatorFees>(@supra_framework).fees_table;
+        if (table::contains(fees_table, candidate_addr)) {
+            coin::value(table::borrow(fees_table, candidate_addr))
+        } else { 0 }
+    } else { 0 }
 }
 
@@ -4014,7 +4564,9 @@ Return the ValidatorConsensusInfo of each current validator, sorted Implementation -
fun validator_consensus_infos_from_validator_set(validator_set: &ValidatorSet): vector<ValidatorConsensusInfo> {
+
fun validator_consensus_infos_from_validator_set(
+    validator_set: &ValidatorSet
+): vector<ValidatorConsensusInfo> {
     let validator_consensus_infos = vector[];
 
     let num_active = vector::length(&validator_set.active_validators);
@@ -4028,54 +4580,83 @@ Return the ValidatorConsensusInfo of each current validator, sorted
     let idx = 0;
     while ({
         spec {
-            invariant idx <= len(validator_set.active_validators) + len(validator_set.pending_inactive);
+            invariant idx
+                <= len(validator_set.active_validators)
+                    + len(validator_set.pending_inactive);
             invariant len(validator_consensus_infos) == idx;
-            invariant len(validator_consensus_infos) <= len(validator_set.active_validators) + len(validator_set.pending_inactive);
+            invariant len(validator_consensus_infos)
+                <= len(validator_set.active_validators)
+                    + len(validator_set.pending_inactive);
         };
         idx < total
     }) {
-        vector::push_back(&mut validator_consensus_infos, validator_consensus_info::default());
+        vector::push_back(
+            &mut validator_consensus_infos, validator_consensus_info::default()
+        );
         idx = idx + 1;
     };
     spec {
-        assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
-        assert spec_validator_indices_are_valid_config(validator_set.active_validators,
-            len(validator_set.active_validators) + len(validator_set.pending_inactive));
+        assert len(validator_consensus_infos)
+            == len(validator_set.active_validators)
+                + len(validator_set.pending_inactive);
+        assert spec_validator_indices_are_valid_config(
+            validator_set.active_validators,
+            len(validator_set.active_validators)
+                + len(validator_set.pending_inactive)
+        );
     };
 
-    vector::for_each_ref(&validator_set.active_validators, |obj| {
-        let vi: &ValidatorInfo = obj;
-        spec {
-            assume len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
-            assert vi.config.validator_index < len(validator_consensus_infos);
-        };
-        let vci = vector::borrow_mut(&mut validator_consensus_infos, vi.config.validator_index);
-        *vci = validator_consensus_info::new(
-            vi.addr,
-            vi.config.consensus_pubkey,
-            vi.voting_power
-        );
-        spec {
-            assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
-        };
-    });
+    vector::for_each_ref(
+        &validator_set.active_validators,
+        |obj| {
+            let vi: &ValidatorInfo = obj;
+            spec {
+                assume len(validator_consensus_infos)
+                    == len(validator_set.active_validators)
+                        + len(validator_set.pending_inactive);
+                assert vi.config.validator_index < len(validator_consensus_infos);
+            };
+            let vci = vector::borrow_mut(
+                &mut validator_consensus_infos, vi.config.validator_index
+            );
+            *vci = validator_consensus_info::new(
+                vi.addr,
+                vi.config.consensus_pubkey,
+                vi.voting_power
+            );
+            spec {
+                assert len(validator_consensus_infos)
+                    == len(validator_set.active_validators)
+                        + len(validator_set.pending_inactive);
+            };
+        }
+    );
 
-    vector::for_each_ref(&validator_set.pending_inactive, |obj| {
-        let vi: &ValidatorInfo = obj;
-        spec {
-            assume len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
-            assert vi.config.validator_index < len(validator_consensus_infos);
-        };
-        let vci = vector::borrow_mut(&mut validator_consensus_infos, vi.config.validator_index);
-        *vci = validator_consensus_info::new(
-            vi.addr,
-            vi.config.consensus_pubkey,
-            vi.voting_power
-        );
-        spec {
-            assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive);
-        };
-    });
+    vector::for_each_ref(
+        &validator_set.pending_inactive,
+        |obj| {
+            let vi: &ValidatorInfo = obj;
+            spec {
+                assume len(validator_consensus_infos)
+                    == len(validator_set.active_validators)
+                        + len(validator_set.pending_inactive);
+                assert vi.config.validator_index < len(validator_consensus_infos);
+            };
+            let vci = vector::borrow_mut(
+                &mut validator_consensus_infos, vi.config.validator_index
+            );
+            *vci = validator_consensus_info::new(
+                vi.addr,
+                vi.config.consensus_pubkey,
+                vi.voting_power
+            );
+            spec {
+                assert len(validator_consensus_infos)
+                    == len(validator_set.active_validators)
+                        + len(validator_set.pending_inactive);
+            };
+        }
+    );
 
     validator_consensus_infos
 }
@@ -4101,10 +4682,13 @@ Return the ValidatorConsensusInfo of each current validator, sorted
 
 
 
fun addresses_from_validator_infos(infos: &vector<ValidatorInfo>): vector<address> {
-    vector::map_ref(infos, |obj| {
-        let info: &ValidatorInfo = obj;
-        info.addr
-    })
+    vector::map_ref(
+        infos,
+        |obj| {
+            let info: &ValidatorInfo = obj;
+            info.addr
+        }
+    )
 }
 
@@ -4137,43 +4721,54 @@ This function shouldn't abort.
fun update_stake_pool(
     validator_perf: &ValidatorPerformance,
     pool_address: address,
-    staking_config: &StakingConfig,
+    staking_config: &StakingConfig
 ) acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorFees {
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
     let validator_config = borrow_global<ValidatorConfig>(pool_address);
-    let cur_validator_perf = vector::borrow(&validator_perf.validators, validator_config.validator_index);
+    let cur_validator_perf = vector::borrow(
+        &validator_perf.validators, validator_config.validator_index
+    );
     let num_successful_proposals = cur_validator_perf.successful_proposals;
     spec {
         // The following addition should not overflow because `num_total_proposals` cannot be larger than 86400,
         // the maximum number of proposals in a day (1 proposal per second).
-        assume cur_validator_perf.successful_proposals + cur_validator_perf.failed_proposals <= MAX_U64;
+        assume cur_validator_perf.successful_proposals
+            + cur_validator_perf.failed_proposals <= MAX_U64;
     };
-    let num_total_proposals = cur_validator_perf.successful_proposals + cur_validator_perf.failed_proposals;
-    let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate(staking_config);
-    let rewards_active = distribute_rewards(
-        &mut stake_pool.active,
-        num_successful_proposals,
-        num_total_proposals,
-        rewards_rate,
-        rewards_rate_denominator
-    );
-    let rewards_pending_inactive = distribute_rewards(
-        &mut stake_pool.pending_inactive,
-        num_successful_proposals,
-        num_total_proposals,
-        rewards_rate,
-        rewards_rate_denominator
-    );
+    let num_total_proposals =
+        cur_validator_perf.successful_proposals
+            + cur_validator_perf.failed_proposals;
+    let (rewards_rate, rewards_rate_denominator) =
+        staking_config::get_reward_rate(staking_config);
+    let rewards_active =
+        distribute_rewards(
+            &mut stake_pool.active,
+            num_successful_proposals,
+            num_total_proposals,
+            rewards_rate,
+            rewards_rate_denominator
+        );
+    let rewards_pending_inactive =
+        distribute_rewards(
+            &mut stake_pool.pending_inactive,
+            num_successful_proposals,
+            num_total_proposals,
+            rewards_rate,
+            rewards_rate_denominator
+        );
     spec {
         assume rewards_active + rewards_pending_inactive <= MAX_U64;
     };
     let rewards_amount = rewards_active + rewards_pending_inactive;
     // Pending active stake can now be active.
-    coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active));
+    coin::merge(
+        &mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active)
+    );
 
     // Additionally, distribute transaction fees.
     if (features::collect_and_distribute_gas_fees()) {
-        let fees_table = &mut borrow_global_mut<ValidatorFees>(@supra_framework).fees_table;
+        let fees_table =
+            &mut borrow_global_mut<ValidatorFees>(@supra_framework).fees_table;
         if (table::contains(fees_table, pool_address)) {
             let coin = table::remove(fees_table, pool_address);
             coin::merge(&mut stake_pool.active, coin);
@@ -4185,7 +4780,7 @@ This function shouldn't abort.
     if (get_reconfig_start_time_secs() >= current_lockup_expiration) {
         coin::merge(
             &mut stake_pool.inactive,
-            coin::extract_all(&mut stake_pool.pending_inactive),
+            coin::extract_all(&mut stake_pool.pending_inactive)
         );
     };
 
@@ -4194,10 +4789,7 @@ This function shouldn't abort.
     };
     event::emit_event(
         &mut stake_pool.distribute_rewards_events,
-        DistributeRewardsEvent {
-            pool_address,
-            rewards_amount,
-        },
+        DistributeRewardsEvent { pool_address, rewards_amount }
     );
 }
 
@@ -4256,7 +4848,7 @@ Calculate the rewards amount. num_successful_proposals: u64, num_total_proposals: u64, rewards_rate: u64, - rewards_rate_denominator: u64, + rewards_rate_denominator: u64 ): u64 { spec { // The following condition must hold because @@ -4267,13 +4859,14 @@ Calculate the rewards amount. }; // The rewards amount is equal to (stake amount * rewards rate * performance multiplier). // We do multiplication in u128 before division to avoid the overflow and minimize the rounding error. - let rewards_numerator = (stake_amount as u128) * (rewards_rate as u128) * (num_successful_proposals as u128); - let rewards_denominator = (rewards_rate_denominator as u128) * (num_total_proposals as u128); + let rewards_numerator = + (stake_amount as u128) * (rewards_rate as u128) + * (num_successful_proposals as u128); + let rewards_denominator = + (rewards_rate_denominator as u128) * (num_total_proposals as u128); if (rewards_denominator != 0) { ((rewards_numerator / rewards_denominator) as u64) - } else { - 0 - } + } else { 0 } }
@@ -4302,22 +4895,22 @@ Mint rewards corresponding to current epoch's acquires SupraCoinCapabilities { let stake_amount = coin::value(stake); - let rewards_amount = if (stake_amount != 0) { - calculate_rewards_amount( - stake_amount, - num_successful_proposals, - num_total_proposals, - rewards_rate, - rewards_rate_denominator - ) - } else { - 0 - }; + let rewards_amount = + if (stake_amount != 0) { + calculate_rewards_amount( + stake_amount, + num_successful_proposals, + num_total_proposals, + rewards_rate, + rewards_rate_denominator + ) + } else { 0 }; if (rewards_amount != 0) { - let mint_cap = &borrow_global<SupraCoinCapabilities>(@supra_framework).mint_cap; + let mint_cap = + &borrow_global<SupraCoinCapabilities>(@supra_framework).mint_cap; let rewards = coin::mint(rewards_amount, mint_cap); coin::merge(stake, rewards); }; @@ -4407,13 +5000,11 @@ Mint rewards corresponding to current epoch's Implementation -
fun generate_validator_info(addr: address, stake_pool: &StakePool, config: ValidatorConfig): ValidatorInfo {
+
fun generate_validator_info(
+    addr: address, stake_pool: &StakePool, config: ValidatorConfig
+): ValidatorInfo {
     let voting_power = get_next_epoch_voting_power(stake_pool);
-    ValidatorInfo {
-        addr,
-        voting_power,
-        config,
-    }
+    ValidatorInfo { addr, voting_power, config }
 }
 
@@ -4442,7 +5033,8 @@ Returns validator's next epoch voting power, including pending_active, active, a let value_active = coin::value(&stake_pool.active); let value_pending_inactive = coin::value(&stake_pool.pending_inactive); spec { - assume value_pending_active + value_active + value_pending_inactive <= MAX_U64; + assume value_pending_active + value_active + value_pending_inactive + <= MAX_U64; }; value_pending_active + value_active + value_pending_inactive } @@ -4470,14 +5062,19 @@ Returns validator's next epoch voting power, including pending_active, active, a
fun update_voting_power_increase(increase_amount: u64) acquires ValidatorSet {
     let validator_set = borrow_global_mut<ValidatorSet>(@supra_framework);
     let voting_power_increase_limit =
-        (staking_config::get_voting_power_increase_limit(&staking_config::get()) as u128);
-    validator_set.total_joining_power = validator_set.total_joining_power + (increase_amount as u128);
+        (
+            staking_config::get_voting_power_increase_limit(&staking_config::get()) as u128
+        );
+    validator_set.total_joining_power =
+        validator_set.total_joining_power + (increase_amount as u128);
 
     // Only validator voting power increase if the current validator set's voting power > 0.
     if (validator_set.total_voting_power != 0) {
         assert!(
-            validator_set.total_joining_power <= validator_set.total_voting_power * voting_power_increase_limit / 100,
-            error::invalid_argument(EVOTING_POWER_INCREASE_EXCEEDS_LIMIT),
+            validator_set.total_joining_power
+                <= validator_set.total_voting_power * voting_power_increase_limit
+                    / 100,
+            error::invalid_argument(EVOTING_POWER_INCREASE_EXCEEDS_LIMIT)
         );
     }
 }
@@ -4503,7 +5100,10 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
fun assert_stake_pool_exists(pool_address: address) {
-    assert!(stake_pool_exists(pool_address), error::invalid_argument(ESTAKE_POOL_DOES_NOT_EXIST));
+    assert!(
+        stake_pool_exists(pool_address),
+        error::invalid_argument(ESTAKE_POOL_DOES_NOT_EXIST)
+    );
 }
 
@@ -4527,8 +5127,7 @@ Returns validator's next epoch voting power, including pending_active, active, a
public fun configure_allowed_validators(
-    supra_framework: &signer,
-    accounts: vector<address>
+    supra_framework: &signer, accounts: vector<address>
 ) acquires AllowedValidators {
     let supra_framework_address = signer::address_of(supra_framework);
     system_addresses::assert_supra_framework(supra_framework);
@@ -4561,9 +5160,8 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
fun is_allowed(account: address): bool acquires AllowedValidators {
-    if (!exists<AllowedValidators>(@supra_framework)) {
-        true
-    } else {
+    if (!exists<AllowedValidators>(@supra_framework)) { true }
+    else {
         let allowed = borrow_global<AllowedValidators>(@supra_framework);
         vector::contains(&allowed.accounts, &account)
     }
@@ -4590,7 +5188,10 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
fun assert_owner_cap_exists(owner: address) {
-    assert!(exists<OwnerCapability>(owner), error::not_found(EOWNER_CAP_NOT_FOUND));
+    assert!(
+        exists<OwnerCapability>(owner),
+        error::not_found(EOWNER_CAP_NOT_FOUND)
+    );
 }
 
@@ -4614,7 +5215,10 @@ Returns validator's next epoch voting power, including pending_active, active, a
fun assert_reconfig_not_in_progress() {
-    assert!(!reconfiguration_state::is_in_progress(), error::invalid_state(ERECONFIGURATION_IN_PROGRESS));
+    assert!(
+        !reconfiguration_state::is_in_progress(),
+        error::invalid_state(ERECONFIGURATION_IN_PROGRESS)
+    );
 }
 
@@ -5003,11 +5607,7 @@ Returns validator's next epoch voting power, including pending_active, active, a -
let is_public_key_validated = ed25519::spec_public_key_validate_internal(
-    consensus_pubkey,
-);
-aborts_if !is_public_key_validated;
-let addr = signer::address_of(account);
+
let addr = signer::address_of(account);
 let post_addr = signer::address_of(account);
 let allowed = global<AllowedValidators>(@supra_framework);
 aborts_if exists<ValidatorConfig>(addr);
@@ -5207,10 +5807,6 @@ Returns validator's next epoch voting power, including pending_active, active, a
 aborts_if !exists<StakePool>(pool_address);
 aborts_if signer::address_of(operator) != pre_stake_pool.operator_address;
 aborts_if !exists<ValidatorConfig>(pool_address);
-let is_public_key_validated = ed25519::spec_public_key_validate_internal(
-    new_consensus_pubkey,
-);
-aborts_if !is_public_key_validated;
 modifies global<ValidatorConfig>(pool_address);
 include StakedValueNochange;
 ensures validator_info.consensus_pubkey == new_consensus_pubkey;
@@ -5542,6 +6138,301 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
+
+
+
+
+
schema AddStakeWithCapAbortsIfAndEnsures {
+    owner_cap: OwnerCapability;
+    amount: u64;
+    let pool_address = owner_cap.pool_address;
+    aborts_if !exists<StakePool>(pool_address);
+    let config = global<staking_config::StakingConfig>(@supra_framework);
+    let validator_set = global<ValidatorSet>(@supra_framework);
+    let voting_power_increase_limit = config.voting_power_increase_limit;
+    let post post_validator_set = global<ValidatorSet>(@supra_framework);
+    let update_voting_power_increase = amount != 0 && (spec_contains(validator_set.active_validators, pool_address)
+                                                       || spec_contains(validator_set.pending_active, pool_address));
+    aborts_if update_voting_power_increase && validator_set.total_joining_power + amount > MAX_U128;
+    ensures update_voting_power_increase ==> post_validator_set.total_joining_power == validator_set.total_joining_power + amount;
+    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
+            && validator_set.total_voting_power * voting_power_increase_limit > MAX_U128;
+    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
+            && validator_set.total_joining_power + amount > validator_set.total_voting_power * voting_power_increase_limit / 100;
+    let stake_pool = global<StakePool>(pool_address);
+    let post post_stake_pool = global<StakePool>(pool_address);
+    let value_pending_active = stake_pool.pending_active.value;
+    let value_active = stake_pool.active.value;
+    ensures amount != 0 && spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.pending_active.value == value_pending_active + amount;
+    ensures amount != 0 && !spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.active.value == value_active + amount;
+    let maximum_stake = config.maximum_stake;
+    let value_pending_inactive = stake_pool.pending_inactive.value;
+    let next_epoch_voting_power = value_pending_active + value_active + value_pending_inactive;
+    let voting_power = next_epoch_voting_power + amount;
+    aborts_if amount != 0 && voting_power > MAX_U64;
+    aborts_if amount != 0 && voting_power > maximum_stake;
+}
+
+ + + + + + + +
schema AddStakeAbortsIfAndEnsures {
+    owner: signer;
+    amount: u64;
+    let owner_address = signer::address_of(owner);
+    aborts_if !exists<OwnerCapability>(owner_address);
+    let owner_cap = global<OwnerCapability>(owner_address);
+    include AddStakeWithCapAbortsIfAndEnsures { owner_cap };
+}
+
+ + + + + + + +
fun spec_is_allowed(account: address): bool {
+   if (!exists<AllowedValidators>(@supra_framework)) {
+       true
+   } else {
+       let allowed = global<AllowedValidators>(@supra_framework);
+       contains(allowed.accounts, account)
+   }
+}
+
+ + + + + + + +
fun spec_find_validator(v: vector<ValidatorInfo>, addr: address): Option<u64>;
+
+ + + + + + + +
fun spec_validators_are_initialized(validators: vector<ValidatorInfo>): bool {
+   forall i in 0..len(validators):
+       spec_has_stake_pool(validators[i].addr) &&
+           spec_has_validator_config(validators[i].addr)
+}
+
+ + + + + + + +
fun spec_validators_are_initialized_addrs(addrs: vector<address>): bool {
+   forall i in 0..len(addrs):
+       spec_has_stake_pool(addrs[i]) &&
+           spec_has_validator_config(addrs[i])
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid(validators: vector<ValidatorInfo>): bool {
+   spec_validator_indices_are_valid_addr(validators, spec_validator_index_upper_bound()) &&
+       spec_validator_indices_are_valid_config(validators, spec_validator_index_upper_bound())
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid_addr(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
+   forall i in 0..len(validators):
+       global<ValidatorConfig>(validators[i].addr).validator_index < upper_bound
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid_config(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
+   forall i in 0..len(validators):
+       validators[i].config.validator_index < upper_bound
+}
+
+ + + + + + + +
fun spec_validator_indices_active_pending_inactive(validator_set: ValidatorSet): bool {
+   len(validator_set.pending_inactive) + len(validator_set.active_validators) == spec_validator_index_upper_bound()
+}
+
+ + + + + + + +
fun spec_validator_index_upper_bound(): u64 {
+   len(global<ValidatorPerformance>(@supra_framework).validators)
+}
+
+ + + + + + + +
fun spec_has_stake_pool(a: address): bool {
+   exists<StakePool>(a)
+}
+
+ + + + + + + +
fun spec_has_validator_config(a: address): bool {
+   exists<ValidatorConfig>(a)
+}
+
+ + + + + + + +
fun spec_rewards_amount(
+   stake_amount: u64,
+   num_successful_proposals: u64,
+   num_total_proposals: u64,
+   rewards_rate: u64,
+   rewards_rate_denominator: u64,
+): u64;
+
+ + + + + + + +
fun spec_contains(validators: vector<ValidatorInfo>, addr: address): bool {
+   exists i in 0..len(validators): validators[i].addr == addr
+}
+
+ + + + + + + +
fun spec_is_current_epoch_validator(pool_address: address): bool {
+   let validator_set = global<ValidatorSet>(@supra_framework);
+   !spec_contains(validator_set.pending_active, pool_address)
+       && (spec_contains(validator_set.active_validators, pool_address)
+       || spec_contains(validator_set.pending_inactive, pool_address))
+}
+
+ + + + + + + +
schema ResourceRequirement {
+    requires exists<SupraCoinCapabilities>(@supra_framework);
+    requires exists<ValidatorPerformance>(@supra_framework);
+    requires exists<ValidatorSet>(@supra_framework);
+    requires exists<StakingConfig>(@supra_framework);
+    requires exists<StakingRewardsConfig>(@supra_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
+    requires exists<timestamp::CurrentTimeMicroseconds>(@supra_framework);
+    requires exists<ValidatorFees>(@supra_framework);
+}
+
+ + + + + + + +
fun spec_get_reward_rate_1(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           0
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           let nominator = aptos_std::fixed_point64::spec_multiply_u128(denominator, epoch_rewards_rate);
+           nominator
+       }
+   } else {
+           config.rewards_rate
+   }
+}
+
+ + + + + + + +
fun spec_get_reward_rate_2(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           1
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           denominator
+       }
+   } else {
+           config.rewards_rate_denominator
+   }
+}
+
+ + + ### Function `update_stake_pool` diff --git a/aptos-move/framework/supra-framework/doc/supra_governance.md b/aptos-move/framework/supra-framework/doc/supra_governance.md index bd008ae0481..519acc9a387 100644 --- a/aptos-move/framework/supra-framework/doc/supra_governance.md +++ b/aptos-move/framework/supra-framework/doc/supra_governance.md @@ -81,7 +81,6 @@ on a proposal multiple times as long as the total voting power of these votes do
use 0x1::account;
-use 0x1::consensus_config;
 use 0x1::error;
 use 0x1::event;
 use 0x1::features;
@@ -635,9 +634,7 @@ Stores the signer capability for a given address.
 
 
 
public fun store_signer_cap(
-    supra_framework: &signer,
-    signer_address: address,
-    signer_cap: SignerCapability,
+    supra_framework: &signer, signer_address: address, signer_cap: SignerCapability
 ) acquires GovernanceResponsbility {
     system_addresses::assert_supra_framework(supra_framework);
     system_addresses::assert_framework_reserved(signer_address);
@@ -645,11 +642,14 @@ Stores the signer capability for a given address.
     if (!exists<GovernanceResponsbility>(@supra_framework)) {
         move_to(
             supra_framework,
-            GovernanceResponsbility { signer_caps: simple_map::create<address, SignerCapability>() }
+            GovernanceResponsbility {
+                signer_caps: simple_map::create<address, SignerCapability>()
+            }
         );
     };
 
-    let signer_caps = &mut borrow_global_mut<GovernanceResponsbility>(@supra_framework).signer_caps;
+    let signer_caps =
+        &mut borrow_global_mut<GovernanceResponsbility>(@supra_framework).signer_caps;
     simple_map::add(signer_caps, signer_address, signer_cap);
 }
 
@@ -680,26 +680,42 @@ This function is private because it's called directly from the vm. supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, - voters: vector<address>, + voters: vector<address> ) { multisig_voting::register<GovernanceProposal>(supra_framework); - assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS)); - assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE)); + assert!( + vector::length(&voters) >= min_voting_threshold + && min_voting_threshold > vector::length(&voters) / 2, + error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS) + ); + assert!( + min_voting_threshold > 1, + error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE) + ); - move_to(supra_framework, SupraGovernanceConfig { - voting_duration_secs, - min_voting_threshold, - voters, - }); - move_to(supra_framework, SupraGovernanceEvents { - create_proposal_events: account::new_event_handle<SupraCreateProposalEvent>(supra_framework), - update_config_events: account::new_event_handle<SupraUpdateConfigEvent>(supra_framework), - vote_events: account::new_event_handle<SupraVoteEvent>(supra_framework), - }); - move_to(supra_framework, ApprovedExecutionHashes { - hashes: simple_map::create<u64, vector<u8>>(), - }) + move_to( + supra_framework, + SupraGovernanceConfig { voting_duration_secs, min_voting_threshold, voters } + ); + move_to( + supra_framework, + SupraGovernanceEvents { + create_proposal_events: account::new_event_handle<SupraCreateProposalEvent>( + supra_framework + ), + update_config_events: account::new_event_handle<SupraUpdateConfigEvent>( + supra_framework + ), + vote_events: account::new_event_handle<SupraVoteEvent>(supra_framework) + } + ); + move_to( + supra_framework, + ApprovedExecutionHashes { + hashes: simple_map::create<u64, vector<u8>>() + } + ) }
@@ -728,35 +744,35 @@ SupraGovernance. supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, - voters: vector<address>, + voters: vector<address> ) acquires SupraGovernanceConfig, SupraGovernanceEvents { system_addresses::assert_supra_framework(supra_framework); - assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS)); - assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE)); + assert!( + vector::length(&voters) >= min_voting_threshold + && min_voting_threshold > vector::length(&voters) / 2, + error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS) + ); + assert!( + min_voting_threshold > 1, + error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE) + ); - let supra_governance_config = borrow_global_mut<SupraGovernanceConfig>(@supra_framework); + let supra_governance_config = + borrow_global_mut<SupraGovernanceConfig>(@supra_framework); supra_governance_config.voting_duration_secs = voting_duration_secs; supra_governance_config.min_voting_threshold = min_voting_threshold; supra_governance_config.voters = voters; if (std::features::module_event_migration_enabled()) { event::emit( - SupraUpdateConfig { - min_voting_threshold, - voting_duration_secs, - voters, - }, + SupraUpdateConfig { min_voting_threshold, voting_duration_secs, voters } ) }; let events = borrow_global_mut<SupraGovernanceEvents>(@supra_framework); event::emit_event<SupraUpdateConfigEvent>( &mut events.update_config_events, - SupraUpdateConfigEvent { - min_voting_threshold, - voting_duration_secs, - voters, - }, + SupraUpdateConfigEvent { min_voting_threshold, voting_duration_secs, voters } ); }
@@ -862,9 +878,15 @@ only the exact script with matching hash can be successfully executed. proposer: &signer, execution_hash: vector<u8>, metadata_location: vector<u8>, - metadata_hash: vector<u8>, + metadata_hash: vector<u8> ) acquires SupraGovernanceConfig, SupraGovernanceEvents { - supra_create_proposal_v2(proposer, execution_hash, metadata_location, metadata_hash, false); + supra_create_proposal_v2( + proposer, + execution_hash, + metadata_location, + metadata_hash, + false + ); }
@@ -895,7 +917,7 @@ only the exact script with matching hash can be successfully executed. execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, - is_multi_step_proposal: bool, + is_multi_step_proposal: bool ) acquires SupraGovernanceConfig, SupraGovernanceEvents { supra_create_proposal_v2_impl( proposer, @@ -935,38 +957,46 @@ Return proposal_id when a proposal is successfully created. execution_hash: vector<u8>, metadata_location: vector<u8>, metadata_hash: vector<u8>, - is_multi_step_proposal: bool, + is_multi_step_proposal: bool ): u64 acquires SupraGovernanceConfig, SupraGovernanceEvents { let proposer_address = signer::address_of(proposer); - let supra_governance_config = borrow_global<SupraGovernanceConfig>(@supra_framework); + let supra_governance_config = + borrow_global<SupraGovernanceConfig>(@supra_framework); - assert!(vector::contains(&supra_governance_config.voters, &proposer_address), error::permission_denied(EACCOUNT_NOT_AUTHORIZED)); + assert!( + vector::contains(&supra_governance_config.voters, &proposer_address), + error::permission_denied(EACCOUNT_NOT_AUTHORIZED) + ); - let proposal_expiration = timestamp::now_seconds() + supra_governance_config.voting_duration_secs; + let proposal_expiration = + timestamp::now_seconds() + supra_governance_config.voting_duration_secs; // Create and validate proposal metadata. - let proposal_metadata = create_proposal_metadata(metadata_location, metadata_hash); - - let proposal_id = multisig_voting::create_proposal_v2( - proposer_address, - @supra_framework, - governance_proposal::create_proposal(), - execution_hash, - supra_governance_config.min_voting_threshold, - supra_governance_config.voters, - proposal_expiration, - proposal_metadata, - is_multi_step_proposal, + let proposal_metadata = create_proposal_metadata( + metadata_location, metadata_hash ); + let proposal_id = + multisig_voting::create_proposal_v2( + proposer_address, + @supra_framework, + governance_proposal::create_proposal(), + execution_hash, + supra_governance_config.min_voting_threshold, + supra_governance_config.voters, + proposal_expiration, + proposal_metadata, + is_multi_step_proposal + ); + if (std::features::module_event_migration_enabled()) { event::emit( SupraCreateProposal { proposal_id, proposer: proposer_address, execution_hash, - proposal_metadata, - }, + proposal_metadata + } ); }; let events = borrow_global_mut<SupraGovernanceEvents>(@supra_framework); @@ -976,8 +1006,8 @@ Return proposal_id when a proposal is successfully created. proposal_id, proposer: proposer_address, execution_hash, - proposal_metadata, - }, + proposal_metadata + } ); proposal_id } @@ -1004,9 +1034,7 @@ Vote on proposal with proposal_id and all voting power from s
public entry fun supra_vote(
-    voter: &signer,
-    proposal_id: u64,
-    should_pass: bool,
+    voter: &signer, proposal_id: u64, should_pass: bool
 ) acquires ApprovedExecutionHashes, SupraGovernanceEvents, SupraGovernanceConfig {
     supra_vote_internal(voter, proposal_id, should_pass);
 }
@@ -1036,50 +1064,50 @@ cannot vote on the proposal even after partial governance voting is enabled.
 
 
 
fun supra_vote_internal(
-    voter: &signer,
-    proposal_id: u64,
-    should_pass: bool,
+    voter: &signer, proposal_id: u64, should_pass: bool
 ) acquires ApprovedExecutionHashes, SupraGovernanceEvents, SupraGovernanceConfig {
     let voter_address = signer::address_of(voter);
 
-    let supra_governance_config = borrow_global<SupraGovernanceConfig>(@supra_framework);
-    assert!(vector::contains(&supra_governance_config.voters, &signer::address_of(voter)), error::permission_denied(EACCOUNT_NOT_AUTHORIZED));
+    let supra_governance_config =
+        borrow_global<SupraGovernanceConfig>(@supra_framework);
+    assert!(
+        vector::contains(
+            &supra_governance_config.voters, &signer::address_of(voter)
+        ),
+        error::permission_denied(EACCOUNT_NOT_AUTHORIZED)
+    );
 
     // The voter's stake needs to be locked up at least as long as the proposal's expiration.
-    let proposal_expiration = multisig_voting::get_proposal_expiration_secs<GovernanceProposal>(
-        @supra_framework,
-        proposal_id
+    let proposal_expiration =
+        multisig_voting::get_proposal_expiration_secs<GovernanceProposal>(
+            @supra_framework, proposal_id
+        );
+    assert!(
+        timestamp::now_seconds() <= proposal_expiration,
+        error::invalid_argument(EPROPOSAL_IS_EXPIRE)
     );
-    assert!(timestamp::now_seconds() <= proposal_expiration, error::invalid_argument(EPROPOSAL_IS_EXPIRE));
 
     multisig_voting::vote<GovernanceProposal>(
         voter,
         &governance_proposal::create_empty_proposal(),
         @supra_framework,
         proposal_id,
-        should_pass,
+        should_pass
     );
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(
-            SupraVote {
-                proposal_id,
-                voter: voter_address,
-                should_pass,
-            },
-        );
+        event::emit(SupraVote { proposal_id, voter: voter_address, should_pass });
     };
     let events = borrow_global_mut<SupraGovernanceEvents>(@supra_framework);
     event::emit_event<SupraVoteEvent>(
         &mut events.vote_events,
-        SupraVoteEvent {
-            proposal_id,
-            voter: voter_address,
-            should_pass,
-        },
+        SupraVoteEvent { proposal_id, voter: voter_address, should_pass }
     );
 
-    let proposal_state = multisig_voting::get_proposal_state<GovernanceProposal>(@supra_framework, proposal_id);
+    let proposal_state =
+        multisig_voting::get_proposal_state<GovernanceProposal>(
+            @supra_framework, proposal_id
+        );
     if (proposal_state == PROPOSAL_STATE_SUCCEEDED) {
         add_supra_approved_script_hash(proposal_id);
     }
@@ -1105,7 +1133,9 @@ cannot vote on the proposal even after partial governance voting is enabled.
 Implementation
 
 
-
public entry fun add_supra_approved_script_hash_script(proposal_id: u64) acquires ApprovedExecutionHashes {
+
public entry fun add_supra_approved_script_hash_script(
+    proposal_id: u64
+) acquires ApprovedExecutionHashes {
     add_supra_approved_script_hash(proposal_id)
 }
 
@@ -1133,18 +1163,29 @@ are too large (e.g. module upgrades).
public fun add_supra_approved_script_hash(proposal_id: u64) acquires ApprovedExecutionHashes {
-    let approved_hashes = borrow_global_mut<ApprovedExecutionHashes>(@supra_framework);
+    let approved_hashes =
+        borrow_global_mut<ApprovedExecutionHashes>(@supra_framework);
 
     // Ensure the proposal can be resolved.
-    let proposal_state = multisig_voting::get_proposal_state<GovernanceProposal>(@supra_framework, proposal_id);
-    assert!(proposal_state == PROPOSAL_STATE_SUCCEEDED, error::invalid_argument(EPROPOSAL_NOT_RESOLVABLE_YET));
+    let proposal_state =
+        multisig_voting::get_proposal_state<GovernanceProposal>(
+            @supra_framework, proposal_id
+        );
+    assert!(
+        proposal_state == PROPOSAL_STATE_SUCCEEDED,
+        error::invalid_argument(EPROPOSAL_NOT_RESOLVABLE_YET)
+    );
 
-    let execution_hash = multisig_voting::get_execution_hash<GovernanceProposal>(@supra_framework, proposal_id);
+    let execution_hash =
+        multisig_voting::get_execution_hash<GovernanceProposal>(
+            @supra_framework, proposal_id
+        );
 
     // If this is a multi-step proposal, the proposal id will already exist in the ApprovedExecutionHashes map.
     // We will update execution hash in ApprovedExecutionHashes to be the next_execution_hash.
     if (simple_map::contains_key(&approved_hashes.hashes, &proposal_id)) {
-        let current_execution_hash = simple_map::borrow_mut(&mut approved_hashes.hashes, &proposal_id);
+        let current_execution_hash =
+            simple_map::borrow_mut(&mut approved_hashes.hashes, &proposal_id);
         *current_execution_hash = execution_hash;
     } else {
         simple_map::add(&mut approved_hashes.hashes, proposal_id, execution_hash);
@@ -1174,8 +1215,7 @@ than yes).
 
 
 
public fun supra_resolve(
-    proposal_id: u64,
-    signer_address: address
+    proposal_id: u64, signer_address: address
 ): signer acquires ApprovedExecutionHashes, GovernanceResponsbility {
     multisig_voting::resolve<GovernanceProposal>(@supra_framework, proposal_id);
     remove_supra_approved_hash(proposal_id);
@@ -1204,11 +1244,11 @@ Resolve a successful multi-step proposal. This would fail if the proposal is not
 
 
 
public fun resolve_supra_multi_step_proposal(
-    proposal_id: u64,
-    signer_address: address,
-    next_execution_hash: vector<u8>
+    proposal_id: u64, signer_address: address, next_execution_hash: vector<u8>
 ): signer acquires GovernanceResponsbility, ApprovedExecutionHashes {
-    multisig_voting::resolve_proposal_v2<GovernanceProposal>(@supra_framework, proposal_id, next_execution_hash);
+    multisig_voting::resolve_proposal_v2<GovernanceProposal>(
+        @supra_framework, proposal_id, next_execution_hash
+    );
     // If the current step is the last step of this multi-step proposal,
     // we will remove the execution hash from the ApprovedExecutionHashes map.
     if (vector::length(&next_execution_hash) == 0) {
@@ -1245,11 +1285,14 @@ Remove an approved proposal's execution script hash.
 
 
public fun remove_supra_approved_hash(proposal_id: u64) acquires ApprovedExecutionHashes {
     assert!(
-        multisig_voting::is_resolved<GovernanceProposal>(@supra_framework, proposal_id),
-        error::invalid_argument(EPROPOSAL_NOT_RESOLVED_YET),
+        multisig_voting::is_resolved<GovernanceProposal>(
+            @supra_framework, proposal_id
+        ),
+        error::invalid_argument(EPROPOSAL_NOT_RESOLVED_YET)
     );
 
-    let approved_hashes = &mut borrow_global_mut<ApprovedExecutionHashes>(@supra_framework).hashes;
+    let approved_hashes =
+        &mut borrow_global_mut<ApprovedExecutionHashes>(@supra_framework).hashes;
     if (simple_map::contains_key(approved_hashes, &proposal_id)) {
         simple_map::remove(approved_hashes, &proposal_id);
     };
@@ -1267,12 +1310,12 @@ Remove an approved proposal's execution script hash.
 Manually reconfigure. Called at the end of a governance txn that alters on-chain configs.
 
 WARNING: this function always ensures a reconfiguration starts, but when the reconfiguration finishes depends.
-- If feature RECONFIGURE_WITH_DKG is disabled, it finishes immediately.
+- If feature SUPRA_DKG is disabled, it finishes immediately.
 - At the end of the calling transaction, we will be in a new epoch.
-- If feature RECONFIGURE_WITH_DKG is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes.
+- If feature SUPRA_DKG is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes.
 
 This behavior affects when an update of an on-chain config (e.g. ConsensusConfig, Features) takes effect,
-since such updates are applied whenever we enter an new epoch.
+since such updates are applied whenever we enter a new epoch.
 
 
 
public entry fun reconfigure(supra_framework: &signer)
@@ -1286,7 +1329,11 @@ since such updates are applied whenever we enter an new epoch.
 
 
public entry fun reconfigure(supra_framework: &signer) {
     system_addresses::assert_supra_framework(supra_framework);
-    if (consensus_config::validator_txn_enabled() && randomness_config::enabled()) {
+
+    // The block executor should seed the randomness config with the digest of the last
+    // block of the first epoch in which the DKG is enabled, so the second conjunct should
+    // always be true once the first is true. We keep it for safety in case of regression.
+    if (features::supra_dkg_enabled() && randomness_config::enabled()) {
         reconfiguration_with_dkg::try_start();
     } else {
         reconfiguration_with_dkg::finish(supra_framework);
@@ -1303,7 +1350,7 @@ since such updates are applied whenever we enter an new epoch.
 ## Function `force_end_epoch`
 
 Change epoch immediately.
-If RECONFIGURE_WITH_DKG is enabled and we are in the middle of a DKG,
+If SUPRA_DKG is enabled and we are in the middle of a DKG,
 stop waiting for DKG and enter the new epoch without randomness.
 
 WARNING: currently only used by tests. In most cases you should use reconfigure() instead.
@@ -1346,7 +1393,9 @@ where the core resources account exists and has been granted power to mint Supra
 Implementation
 
 
-
public entry fun force_end_epoch_test_only(supra_framework: &signer) acquires GovernanceResponsbility {
+
public entry fun force_end_epoch_test_only(
+    supra_framework: &signer
+) acquires GovernanceResponsbility {
     let core_signer = get_signer_testnet_only(supra_framework, @0x1);
     system_addresses::assert_supra_framework(&core_signer);
     reconfiguration_with_dkg::finish(&core_signer);
@@ -1373,7 +1422,9 @@ Update feature flags and also trigger reconfiguration.
 Implementation
 
 
-
public fun toggle_features(supra_framework: &signer, enable: vector<u64>, disable: vector<u64>) {
+
public fun toggle_features(
+    supra_framework: &signer, enable: vector<u64>, disable: vector<u64>
+) {
     system_addresses::assert_supra_framework(supra_framework);
     features::change_feature_flags_for_next_epoch(supra_framework, enable, disable);
     reconfigure(supra_framework);
@@ -1401,10 +1452,14 @@ Only called in testnet where the core resources account exists and has been gran
 
 
 
public fun get_signer_testnet_only(
-    core_resources: &signer, signer_address: address): signer acquires GovernanceResponsbility {
+    core_resources: &signer, signer_address: address
+): signer acquires GovernanceResponsbility {
     system_addresses::assert_core_resource(core_resources);
     // Core resources account only has mint capability in tests/testnets.
-    assert!(supra_coin::has_mint_capability(core_resources), error::unauthenticated(EUNAUTHORIZED));
+    assert!(
+        supra_coin::has_mint_capability(core_resources),
+        error::unauthenticated(EUNAUTHORIZED)
+    );
     get_signer(signer_address)
 }
 
@@ -1430,8 +1485,10 @@ Return a signer for making changes to 0x1 as part of on-chain governance proposa
fun get_signer(signer_address: address): signer acquires GovernanceResponsbility {
-    let governance_responsibility = borrow_global<GovernanceResponsbility>(@supra_framework);
-    let signer_cap = simple_map::borrow(&governance_responsibility.signer_caps, &signer_address);
+    let governance_responsibility =
+        borrow_global<GovernanceResponsbility>(@supra_framework);
+    let signer_cap =
+        simple_map::borrow(&governance_responsibility.signer_caps, &signer_address);
     create_signer_with_capability(signer_cap)
 }
 
@@ -1456,11 +1513,16 @@ Return a signer for making changes to 0x1 as part of on-chain governance proposa
fun create_proposal_metadata(
-    metadata_location: vector<u8>,
-    metadata_hash: vector<u8>
+    metadata_location: vector<u8>, metadata_hash: vector<u8>
 ): SimpleMap<String, vector<u8>> {
-    assert!(string::length(&utf8(metadata_location)) <= 256, error::invalid_argument(EMETADATA_LOCATION_TOO_LONG));
-    assert!(string::length(&utf8(metadata_hash)) <= 256, error::invalid_argument(EMETADATA_HASH_TOO_LONG));
+    assert!(
+        string::length(&utf8(metadata_location)) <= 256,
+        error::invalid_argument(EMETADATA_LOCATION_TOO_LONG)
+    );
+    assert!(
+        string::length(&utf8(metadata_hash)) <= 256,
+        error::invalid_argument(EMETADATA_HASH_TOO_LONG)
+    );
 
     let metadata = simple_map::create<String, vector<u8>>();
     simple_map::add(&mut metadata, utf8(METADATA_LOCATION_KEY), metadata_location);
@@ -1493,9 +1555,14 @@ Return a signer for making changes to 0x1 as part of on-chain governance proposa
     supra_framework: &signer,
     voting_duration_secs: u64,
     supra_min_voting_threshold: u64,
-    voters: vector<address>,
+    voters: vector<address>
 ) {
-    initialize(supra_framework, voting_duration_secs, supra_min_voting_threshold, voters);
+    initialize(
+        supra_framework,
+        voting_duration_secs,
+        supra_min_voting_threshold,
+        voters
+    );
 }
 
diff --git a/aptos-move/framework/supra-framework/doc/validator_public_keys.md b/aptos-move/framework/supra-framework/doc/validator_public_keys.md new file mode 100644 index 00000000000..e0e357572d0 --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/validator_public_keys.md @@ -0,0 +1,985 @@ + + + +# Module `0x1::validator_public_keys` + + + +- [Struct `CertificateThresholdType`](#0x1_validator_public_keys_CertificateThresholdType) +- [Struct `InternalPublicKeys`](#0x1_validator_public_keys_InternalPublicKeys) +- [Struct `ValidatorPublicKeys`](#0x1_validator_public_keys_ValidatorPublicKeys) +- [Constants](#@Constants_0) +- [Function `validity_certificate_type`](#0x1_validator_public_keys_validity_certificate_type) +- [Function `quorum_certificate_type`](#0x1_validator_public_keys_quorum_certificate_type) +- [Function `unanimous_certificate_type`](#0x1_validator_public_keys_unanimous_certificate_type) +- [Function `bcft_validity_certificate_type`](#0x1_validator_public_keys_bcft_validity_certificate_type) +- [Function `bcft_quorum_certificate_type`](#0x1_validator_public_keys_bcft_quorum_certificate_type) +- [Function `bcft_fallback_view_change_certificate_type`](#0x1_validator_public_keys_bcft_fallback_view_change_certificate_type) +- [Function `clan_majority_certificate_type`](#0x1_validator_public_keys_clan_majority_certificate_type) +- [Function `is_validity_certificate_type`](#0x1_validator_public_keys_is_validity_certificate_type) +- [Function `is_quorum_certificate_type`](#0x1_validator_public_keys_is_quorum_certificate_type) +- [Function `is_unanimous_certificate_type`](#0x1_validator_public_keys_is_unanimous_certificate_type) +- [Function `is_bcft_validity_certificate_type`](#0x1_validator_public_keys_is_bcft_validity_certificate_type) +- [Function `is_bcft_quorum_certificate_type`](#0x1_validator_public_keys_is_bcft_quorum_certificate_type) +- [Function `is_bcft_fallback_view_change_certificate_type`](#0x1_validator_public_keys_is_bcft_fallback_view_change_certificate_type) +- [Function `is_clan_majority_certificate_type`](#0x1_validator_public_keys_is_clan_majority_certificate_type) +- [Function `validator_public_keys_from_bytes`](#0x1_validator_public_keys_validator_public_keys_from_bytes) +- [Function `public_key_to_bytes`](#0x1_validator_public_keys_public_key_to_bytes) +- [Function `get_network_key`](#0x1_validator_public_keys_get_network_key) +- [Function `get_supra_bls_multi_sig_pub_key`](#0x1_validator_public_keys_get_supra_bls_multi_sig_pub_key) +- [Function `get_supra_cg_key`](#0x1_validator_public_keys_get_supra_cg_key) +- [Function `get_supra_ed_key`](#0x1_validator_public_keys_get_supra_ed_key) +- [Function `rotate_supra_bls_threshold_validity_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_validity_key) +- [Function `rotate_supra_bls_threshold_quorum_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_quorum_key) +- [Function `rotate_supra_bls_threshold_unanimous_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_unanimous_key) +- [Function `rotate_supra_bls_threshold_bcft_validity_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_bcft_validity_key) +- [Function `rotate_supra_bls_threshold_bcft_quorum_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_bcft_quorum_key) +- [Function `rotate_supra_bls_threshold_bcft_fallback_view_change_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_bcft_fallback_view_change_key) +- [Function `rotate_supra_bls_threshold_clan_majority_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_clan_majority_key) +- [Function `rotate_supra_bls_threshold_key_by_type`](#0x1_validator_public_keys_rotate_supra_bls_threshold_key_by_type) + + +
use 0x1::any;
+use 0x1::bcs;
+use 0x1::bls12381;
+use 0x1::class_groups;
+use 0x1::ed25519;
+use 0x1::error;
+use 0x1::option;
+use 0x1::string;
+use 0x1::type_info;
+
+ + + + + +## Struct `CertificateThresholdType` + +Internal tag wrapper + + +
struct CertificateThresholdType has copy, drop, store
+
+ + + +
+Fields + + +
+
+tag: u8 +
+
+ +
+
+ + +
+ + + +## Struct `InternalPublicKeys` + +InternalPublicKeys consists of: +1. bls multisig key +2. bls threshold key shares for various certificate types +3. classgroup key +4. ed25519 key + + +
struct InternalPublicKeys has copy, drop, store
+
+ + + +
+Fields + + +
+
+bls_multisig_key: bls12381::PublicKey +
+
+ +
+
+bls_threshold_validity_certificate_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+bls_threshold_quorum_certificate_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+bls_threshold_unanimous_certificate_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+bls_threshold_bcft_validity_certificate_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+bls_threshold_bcft_quorum_certificate_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+bls_threshold_bcft_fallback_view_change_certificate_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+bls_threshold_clan_majority_certificate_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+class_group_key: class_groups::CGPublicKey +
+
+ +
+
+ed25519_key: ed25519::ValidatedPublicKey +
+
+ +
+
+ + +
+ + + +## Struct `ValidatorPublicKeys` + +ValidatorPublicKeys consists of: +1. network key +2. supra's internal keys + + +
struct ValidatorPublicKeys has copy, drop, store
+
+ + + +
+Fields + + +
+
+network_key: ed25519::ValidatedPublicKey +
+
+ +
+
+supra_keys: validator_public_keys::InternalPublicKeys +
+
+ +
+
+ + +
+ + + +## Constants + + + + +The size of a serialized bls12381 G1 public key, in bytes. + + +
const BLS12381_G1_PUBLIC_KEY_NUM_BYTES: u64 = 48;
+
+ + + + + +The integer should match the Rust enum value representation in CertificateThresholdType. +n - f - c, given there are f Byzantine nodes and c crash-only nodes in the [Committee] with n >= 3f + 2c + 1 nodes. + + +
const CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE: u8 = 5;
+
+ + + + + +The integer should match the Rust enum value representation in CertificateThresholdType +2f + c + 1, given there are f Byzantine nodes and c crash-only nodes in the [Committee] with n >= 3f + 2c + 1 nodes. + + +
const CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM: u8 = 4;
+
+ + + + + +The integer should match the Rust enum value representation in CertificateThresholdType. +f+1, given there are f Byzantine nodes and c crash-only nodes in the [Committee] with n >= 3f + 2c + 1 nodes. + + +
const CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY: u8 = 3;
+
+ + + + + +The integer should match the Rust enum value representation in CertificateThresholdType. +f+1, given there are f Byzantine nodes in the [Committee] with n >= 2f + 1 nodes. + + +
const CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY: u8 = 6;
+
+ + + + + +The integer should match the Rust enum value representation in CertificateThresholdType. +2f+1, given there are f Byzantine nodes in the [Committee] and n >= 3f + 1 nodes in total. + + +
const CERTIFICATE_THRESHOLD_TYPE_QUORUM: u8 = 1;
+
+ + + + + +The integer should match the Rust enum value representation in CertificateThresholdType. +n, where n is the total number of nodes in the [Committee]. + + +
const CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS: u8 = 2;
+
+ + + + + +The integer should match the Rust enum value representation in CertificateThresholdType. +f+1, given there are f Byzantine nodes in the [Committee]. + + +
const CERTIFICATE_THRESHOLD_TYPE_VALIDITY: u8 = 0;
+
+ + + + + +The size of a serialized ed25519 public key, in bytes. + + +
const ED25519_PUBLIC_KEY_NUM_BYTES: u64 = 32;
+
+ + + + + +Error: Unknown certificate threshold type. + + +
const EUNKNOWN_THRESHOLD_TYPE: u64 = 1;
+
+ + + + + +## Function `validity_certificate_type` + + + +
public fun validity_certificate_type(): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_VALIDITY } }
+
+ + + +
+ + + +## Function `quorum_certificate_type` + + + +
public fun quorum_certificate_type(): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_QUORUM } }
+
+ + + +
+ + + +## Function `unanimous_certificate_type` + + + +
public fun unanimous_certificate_type(): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun unanimous_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS } }
+
+ + + +
+ + + +## Function `bcft_validity_certificate_type` + + + +
public fun bcft_validity_certificate_type(): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun bcft_validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY } }
+
+ + + +
+ + + +## Function `bcft_quorum_certificate_type` + + + +
public fun bcft_quorum_certificate_type(): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun bcft_quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM } }
+
+ + + +
+ + + +## Function `bcft_fallback_view_change_certificate_type` + + + +
public fun bcft_fallback_view_change_certificate_type(): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun bcft_fallback_view_change_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE } }
+
+ + + +
+ + + +## Function `clan_majority_certificate_type` + + + +
public fun clan_majority_certificate_type(): validator_public_keys::CertificateThresholdType
+
+ + + +
+Implementation + + +
public fun clan_majority_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY } }
+
+ + + +
+ + + +## Function `is_validity_certificate_type` + + + +
public fun is_validity_certificate_type(t: &validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
public fun is_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_VALIDITY }
+
+ + + +
+ + + +## Function `is_quorum_certificate_type` + + + +
public fun is_quorum_certificate_type(t: &validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
public fun is_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_QUORUM }
+
+ + + +
+ + + +## Function `is_unanimous_certificate_type` + + + +
public fun is_unanimous_certificate_type(t: &validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
public fun is_unanimous_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS }
+
+ + + +
+ + + +## Function `is_bcft_validity_certificate_type` + + + +
public fun is_bcft_validity_certificate_type(t: &validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
public fun is_bcft_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY }
+
+ + + +
+ + + +## Function `is_bcft_quorum_certificate_type` + + + +
public fun is_bcft_quorum_certificate_type(t: &validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
public fun is_bcft_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM }
+
+ + + +
+ + + +## Function `is_bcft_fallback_view_change_certificate_type` + + + +
public fun is_bcft_fallback_view_change_certificate_type(t: &validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
public fun is_bcft_fallback_view_change_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE }
+
+ + + +
+ + + +## Function `is_clan_majority_certificate_type` + + + +
public fun is_clan_majority_certificate_type(t: &validator_public_keys::CertificateThresholdType): bool
+
+ + + +
+Implementation + + +
public fun is_clan_majority_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY }
+
+ + + +
+ + + +## Function `validator_public_keys_from_bytes` + + + +
public fun validator_public_keys_from_bytes(bytes: vector<u8>): validator_public_keys::ValidatorPublicKeys
+
+ + + +
+Implementation + + +
public fun validator_public_keys_from_bytes(bytes: vector<u8>): ValidatorPublicKeys{
+
+    // bcs deserialization
+    let bytes_serialized = any::new(type_info::type_name<ValidatorPublicKeys>(), bytes);
+    let validator_public_keys = any::unpack<ValidatorPublicKeys>(bytes_serialized);
+    validator_public_keys
+}
+
+ + + +
+ + + +## Function `public_key_to_bytes` + + + +
public fun public_key_to_bytes(pk: validator_public_keys::ValidatorPublicKeys): vector<u8>
+
+ + + +
+Implementation + + +
public fun public_key_to_bytes(pk: ValidatorPublicKeys): vector<u8>{
+    // bcs deserialization
+    bcs::to_bytes<ValidatorPublicKeys>(&pk)
+}
+
+ + + +
+ + + +## Function `get_network_key` + + + +
public fun get_network_key(pk: &validator_public_keys::ValidatorPublicKeys): ed25519::ValidatedPublicKey
+
+ + + +
+Implementation + + +
public fun get_network_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{
+    pk.network_key
+}
+
+ + + +
+ + + +## Function `get_supra_bls_multi_sig_pub_key` + + + +
public fun get_supra_bls_multi_sig_pub_key(pk: &validator_public_keys::ValidatorPublicKeys): bls12381::PublicKey
+
+ + + +
+Implementation + + +
public fun get_supra_bls_multi_sig_pub_key(pk: &ValidatorPublicKeys): bls12381::PublicKey{
+    pk.supra_keys.bls_multisig_key
+}
+
+ + + +
+ + + +## Function `get_supra_cg_key` + + + +
public fun get_supra_cg_key(pk: &validator_public_keys::ValidatorPublicKeys): class_groups::CGPublicKey
+
+ + + +
+Implementation + + +
public fun get_supra_cg_key(pk: &ValidatorPublicKeys): class_groups::CGPublicKey{
+    pk.supra_keys.class_group_key
+}
+
+ + + +
+ + + +## Function `get_supra_ed_key` + + + +
public fun get_supra_ed_key(pk: &validator_public_keys::ValidatorPublicKeys): ed25519::ValidatedPublicKey
+
+ + + +
+Implementation + + +
public fun get_supra_ed_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{
+    pk.supra_keys.ed25519_key
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_validity_key` + + + +
public fun rotate_supra_bls_threshold_validity_key(pk: &mut validator_public_keys::ValidatorPublicKeys, new_bls_threshold_validity_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_validity_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_validity_key: bls12381::PublicKey) {
+    pk.supra_keys.bls_threshold_validity_certificate_key = option::some(new_bls_threshold_validity_key);
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_quorum_key` + + + +
public fun rotate_supra_bls_threshold_quorum_key(pk: &mut validator_public_keys::ValidatorPublicKeys, new_bls_threshold_quorum_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_quorum_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_quorum_key: bls12381::PublicKey) {
+    pk.supra_keys.bls_threshold_quorum_certificate_key = option::some(new_bls_threshold_quorum_key);
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_unanimous_key` + + + +
public fun rotate_supra_bls_threshold_unanimous_key(pk: &mut validator_public_keys::ValidatorPublicKeys, new_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_unanimous_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    pk.supra_keys.bls_threshold_unanimous_certificate_key = option::some(new_key);
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_bcft_validity_key` + + + +
public fun rotate_supra_bls_threshold_bcft_validity_key(pk: &mut validator_public_keys::ValidatorPublicKeys, new_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_bcft_validity_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    pk.supra_keys.bls_threshold_bcft_validity_certificate_key = option::some(new_key);
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_bcft_quorum_key` + + + +
public fun rotate_supra_bls_threshold_bcft_quorum_key(pk: &mut validator_public_keys::ValidatorPublicKeys, new_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_bcft_quorum_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    pk.supra_keys.bls_threshold_bcft_quorum_certificate_key = option::some(new_key);
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_bcft_fallback_view_change_key` + + + +
public fun rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk: &mut validator_public_keys::ValidatorPublicKeys, new_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    pk.supra_keys.bls_threshold_bcft_fallback_view_change_certificate_key = option::some(new_key);
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_clan_majority_key` + + + +
public fun rotate_supra_bls_threshold_clan_majority_key(pk: &mut validator_public_keys::ValidatorPublicKeys, new_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_clan_majority_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    pk.supra_keys.bls_threshold_clan_majority_certificate_key = option::some(new_key);
+}
+
+ + + +
+ + + +## Function `rotate_supra_bls_threshold_key_by_type` + +Rotate a threshold key based on the threshold type tag. +threshold_type: 0=validity, 1=quorum, 2=unanimous, 3=bcft_validity, 4=bcft_quorum, 5=bcft_fallback_view_change, 6=clan_majority + + +
public fun rotate_supra_bls_threshold_key_by_type(pk: &mut validator_public_keys::ValidatorPublicKeys, threshold_type: u8, new_key: bls12381::PublicKey)
+
+ + + +
+Implementation + + +
public fun rotate_supra_bls_threshold_key_by_type(pk: &mut ValidatorPublicKeys, threshold_type: u8, new_key: bls12381::PublicKey) {
+    if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_VALIDITY) {
+        rotate_supra_bls_threshold_validity_key(pk, new_key);
+    } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_QUORUM) {
+        rotate_supra_bls_threshold_quorum_key(pk, new_key);
+    } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS) {
+        rotate_supra_bls_threshold_unanimous_key(pk, new_key);
+    } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY) {
+        rotate_supra_bls_threshold_bcft_validity_key(pk, new_key);
+    } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM) {
+        rotate_supra_bls_threshold_bcft_quorum_key(pk, new_key);
+    } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE) {
+        rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk, new_key);
+    } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY) {
+        rotate_supra_bls_threshold_clan_majority_key(pk, new_key);
+    } else {
+        abort error::invalid_argument(EUNKNOWN_THRESHOLD_TYPE)
+    };
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/vesting_without_staking.md b/aptos-move/framework/supra-framework/doc/vesting_without_staking.md index 976c5583991..0cd53c9ed17 100644 --- a/aptos-move/framework/supra-framework/doc/vesting_without_staking.md +++ b/aptos-move/framework/supra-framework/doc/vesting_without_staking.md @@ -1257,7 +1257,7 @@ Create a vesting schedule with the given schedule of distributions, a vesting st // last vesting fraction must be non zero to ensure that no amount remains unvested forever. assert!( fixed_point32::get_raw_value(*vector::borrow(&schedule, schedule_len - 1)) != - 0, + 0, error::invalid_argument(EEMPTY_VESTING_SCHEDULE), ); assert!( diff --git a/aptos-move/framework/supra-framework/sources/block.move b/aptos-move/framework/supra-framework/sources/block.move index cedf43e8427..57ba69cf03f 100644 --- a/aptos-move/framework/supra-framework/sources/block.move +++ b/aptos-move/framework/supra-framework/sources/block.move @@ -32,14 +32,14 @@ module supra_framework::block { epoch_interval: u64, /// Handle where events with the time of new blocks are emitted new_block_events: EventHandle, - update_epoch_interval_events: EventHandle, + update_epoch_interval_events: EventHandle } /// Store new block events as a move resource, internally using a circular buffer. struct CommitHistory has key { max_capacity: u32, next_idx: u32, - table: TableWithLength, + table: TableWithLength } /// Should be in-sync with NewBlockEvent rust struct in new_block.rs @@ -52,13 +52,13 @@ module supra_framework::block { proposer: address, failed_proposer_indices: vector, /// On-chain time during the block at the given height - time_microseconds: u64, + time_microseconds: u64 } /// Event emitted when a proposal is created. struct UpdateEpochIntervalEvent has drop, store { old_epoch_interval: u64, - new_epoch_interval: u64, + new_epoch_interval: u64 } #[event] @@ -72,14 +72,14 @@ module supra_framework::block { proposer: address, failed_proposer_indices: vector, /// On-chain time during the block at the given height - time_microseconds: u64, + time_microseconds: u64 } #[event] /// Event emitted when a proposal is created. struct UpdateEpochInterval has drop, store { old_epoch_interval: u64, - new_epoch_interval: u64, + new_epoch_interval: u64 } /// The number of new block events does not equal the current block height. @@ -92,23 +92,34 @@ module supra_framework::block { const EZERO_MAX_CAPACITY: u64 = 3; /// This can only be called during Genesis. - public(friend) fun initialize(supra_framework: &signer, epoch_interval_microsecs: u64) { + public(friend) fun initialize( + supra_framework: &signer, epoch_interval_microsecs: u64 + ) { system_addresses::assert_supra_framework(supra_framework); - assert!(epoch_interval_microsecs != 0, error::invalid_argument(EZERO_EPOCH_INTERVAL)); + assert!( + epoch_interval_microsecs != 0, + error::invalid_argument(EZERO_EPOCH_INTERVAL) + ); - move_to(supra_framework, CommitHistory { - max_capacity: 2000, - next_idx: 0, - table: table_with_length::new(), - }); + move_to( + supra_framework, + CommitHistory { + max_capacity: 2000, + next_idx: 0, + table: table_with_length::new() + } + ); move_to( supra_framework, BlockResource { height: 0, epoch_interval: epoch_interval_microsecs, - new_block_events: account::new_event_handle(supra_framework), - update_epoch_interval_events: account::new_event_handle(supra_framework), + new_block_events: account::new_event_handle( + supra_framework + ), + update_epoch_interval_events: account::new_event_handle< + UpdateEpochIntervalEvent>(supra_framework) } ); } @@ -116,18 +127,16 @@ module supra_framework::block { /// Initialize the commit history resource if it's not in genesis. public fun initialize_commit_history(fx: &signer, max_capacity: u32) { assert!(max_capacity != 0, error::invalid_argument(EZERO_MAX_CAPACITY)); - move_to(fx, CommitHistory { - max_capacity, - next_idx: 0, - table: table_with_length::new(), - }); + move_to( + fx, + CommitHistory { max_capacity, next_idx: 0, table: table_with_length::new() } + ); } /// Update the epoch interval. /// Can only be called as part of the Supra governance proposal process established by the SupraGovernance module. public fun update_epoch_interval_microsecs( - supra_framework: &signer, - new_epoch_interval: u64, + supra_framework: &signer, new_epoch_interval: u64 ) acquires BlockResource { system_addresses::assert_supra_framework(supra_framework); assert!(new_epoch_interval != 0, error::invalid_argument(EZERO_EPOCH_INTERVAL)); @@ -137,13 +146,11 @@ module supra_framework::block { block_resource.epoch_interval = new_epoch_interval; if (std::features::module_event_migration_enabled()) { - event::emit( - UpdateEpochInterval { old_epoch_interval, new_epoch_interval }, - ); + event::emit(UpdateEpochInterval { old_epoch_interval, new_epoch_interval }); }; event::emit_event( &mut block_resource.update_epoch_interval_events, - UpdateEpochIntervalEvent { old_epoch_interval, new_epoch_interval }, + UpdateEpochIntervalEvent { old_epoch_interval, new_epoch_interval } ); } @@ -153,7 +160,6 @@ module supra_framework::block { borrow_global(@supra_framework).epoch_interval / 1000000 } - fun block_prologue_common( vm: &signer, hash: address, @@ -170,7 +176,7 @@ module supra_framework::block { // Blocks can only be produced by a valid proposer or by the VM itself for Nil blocks (no user txs). assert!( proposer == @vm_reserved || stake::is_current_epoch_validator(proposer), - error::permission_denied(EINVALID_PROPOSER), + error::permission_denied(EINVALID_PROPOSER) ); let proposer_index = option::none(); @@ -190,7 +196,7 @@ module supra_framework::block { previous_block_votes_bitvec, proposer, failed_proposer_indices, - time_microseconds: timestamp, + time_microseconds: timestamp }; let new_block_event_v2 = NewBlock { hash, @@ -200,9 +206,14 @@ module supra_framework::block { previous_block_votes_bitvec, proposer, failed_proposer_indices, - time_microseconds: timestamp, + time_microseconds: timestamp }; - emit_new_block_event(vm, &mut block_metadata_ref.new_block_events, new_block_event, new_block_event_v2); + emit_new_block_event( + vm, + &mut block_metadata_ref.new_block_events, + new_block_event, + new_block_event_v2 + ); if (features::collect_and_distribute_gas_fees()) { // Assign the fees collected from the previous block to the previous block proposer. @@ -217,8 +228,13 @@ module supra_framework::block { // transition is the last block in the previous epoch. stake::update_performance_statistics(proposer_index, failed_proposer_indices); state_storage::on_new_block(reconfiguration::current_epoch()); - - leader_ban_registry::update_ban_registry(epoch, round, proposer_index, failed_proposer_indices); + + leader_ban_registry::update_ban_registry( + epoch, + round, + proposer_index, + failed_proposer_indices + ); automation_registry::monitor_cycle_end(); @@ -237,16 +253,17 @@ module supra_framework::block { previous_block_votes_bitvec: vector, timestamp: u64 ) acquires BlockResource, CommitHistory { - let epoch_interval = block_prologue_common( - &vm, - hash, - epoch, - round, - proposer, - failed_proposer_indices, - previous_block_votes_bitvec, - timestamp - ); + let epoch_interval = + block_prologue_common( + &vm, + hash, + epoch, + round, + proposer, + failed_proposer_indices, + previous_block_votes_bitvec, + timestamp + ); randomness::on_new_block(&vm, epoch, round, option::none()); if (timestamp - reconfiguration::last_reconfiguration_time() >= epoch_interval) { reconfiguration::reconfigure(); @@ -263,18 +280,26 @@ module supra_framework::block { failed_proposer_indices: vector, previous_block_votes_bitvec: vector, timestamp: u64, - randomness_seed: Option>, + randomness_seed_vec: vector ) acquires BlockResource, CommitHistory { - let epoch_interval = block_prologue_common( - &vm, - hash, - epoch, - round, - proposer, - failed_proposer_indices, - previous_block_votes_bitvec, - timestamp - ); + let randomness_seed = + if (vector::length(&randomness_seed_vec) == 0) { + option::none() + } else { + option::some(randomness_seed_vec) + }; + + let epoch_interval = + block_prologue_common( + &vm, + hash, + epoch, + round, + proposer, + failed_proposer_indices, + previous_block_votes_bitvec, + timestamp + ); randomness::on_new_block(&vm, epoch, round, randomness_seed); if (timestamp - reconfiguration::last_reconfiguration_time() >= epoch_interval) { @@ -301,16 +326,20 @@ module supra_framework::block { if (table_with_length::contains(&commit_history_ref.table, idx)) { table_with_length::remove(&mut commit_history_ref.table, idx); }; - table_with_length::add(&mut commit_history_ref.table, idx, copy new_block_event); + table_with_length::add( + &mut commit_history_ref.table, idx, copy new_block_event + ); spec { assume idx + 1 <= MAX_U32; }; commit_history_ref.next_idx = (idx + 1) % commit_history_ref.max_capacity; }; - timestamp::update_global_time(vm, new_block_event.proposer, new_block_event.time_microseconds); + timestamp::update_global_time( + vm, new_block_event.proposer, new_block_event.time_microseconds + ); assert!( event::counter(event_handle) == new_block_event.height, - error::invalid_argument(ENUM_NEW_BLOCK_EVENTS_DOES_NOT_MATCH_BLOCK_HEIGHT), + error::invalid_argument(ENUM_NEW_BLOCK_EVENTS_DOES_NOT_MATCH_BLOCK_HEIGHT) ); if (std::features::module_event_migration_enabled()) { event::emit(new_block_event_v2); @@ -334,7 +363,7 @@ module supra_framework::block { previous_block_votes_bitvec: vector::empty(), proposer: @vm_reserved, failed_proposer_indices: vector::empty(), - time_microseconds: timestamp::now_microseconds(), + time_microseconds: timestamp::now_microseconds() }, NewBlock { hash: genesis_id, @@ -344,7 +373,7 @@ module supra_framework::block { previous_block_votes_bitvec: vector::empty(), proposer: @vm_reserved, failed_proposer_indices: vector::empty(), - time_microseconds: timestamp::now_microseconds(), + time_microseconds: timestamp::now_microseconds() } ); } @@ -352,8 +381,7 @@ module supra_framework::block { /// Emit a `NewBlockEvent` event. This function will be invoked by write set script directly to generate the /// new block event for WriteSetPayload. public fun emit_writeset_block_event( - vm_signer: &signer, - fake_block_hash: address + vm_signer: &signer, fake_block_hash: address ) acquires BlockResource, CommitHistory { system_addresses::assert_vm(vm_signer); let block_metadata_ref = borrow_global_mut(@supra_framework); @@ -370,7 +398,7 @@ module supra_framework::block { previous_block_votes_bitvec: vector::empty(), proposer: @vm_reserved, failed_proposer_indices: vector::empty(), - time_microseconds: timestamp::now_microseconds(), + time_microseconds: timestamp::now_microseconds() }, NewBlock { hash: fake_block_hash, @@ -380,13 +408,15 @@ module supra_framework::block { previous_block_votes_bitvec: vector::empty(), proposer: @vm_reserved, failed_proposer_indices: vector::empty(), - time_microseconds: timestamp::now_microseconds(), + time_microseconds: timestamp::now_microseconds() } ); } #[test_only] - public fun initialize_for_test(account: &signer, epoch_interval_microsecs: u64) { + public fun initialize_for_test( + account: &signer, epoch_interval_microsecs: u64 + ) { initialize(account, epoch_interval_microsecs); } @@ -402,8 +432,7 @@ module supra_framework::block { #[test(supra_framework = @supra_framework, account = @0x123)] #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] public entry fun test_update_epoch_interval_unauthorized_should_fail( - supra_framework: signer, - account: signer, + supra_framework: signer, account: signer ) acquires BlockResource { account::create_account_for_test(@supra_framework); initialize(&supra_framework, 1); diff --git a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move index a2fa31c0cc8..6e0019d13d0 100644 --- a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move +++ b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move @@ -32,6 +32,7 @@ module supra_framework::config_buffer { friend supra_framework::randomness_config_seqnum; friend supra_framework::version; friend supra_framework::automation_registry; + friend supra_framework::dkg_config; friend supra_framework::leader_ban_registry_config; /// Config buffer operations failed with permission denied. diff --git a/aptos-move/framework/supra-framework/sources/configs/dkg_config.move b/aptos-move/framework/supra-framework/sources/configs/dkg_config.move new file mode 100644 index 00000000000..da159654853 --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/configs/dkg_config.move @@ -0,0 +1,411 @@ +// Copyright (c) 2026 Supra. +/// DKG configuration module for configurable DKG parameters. +/// This config can be updated via governance and takes effect at the next epoch. +module supra_framework::dkg_config { + use std::error; + use std::vector; + use supra_framework::config_buffer; + use supra_framework::features; + use supra_framework::system_addresses; + use supra_framework::validator_public_keys::{ + CertificateThresholdType, + bcft_quorum_certificate_type, + bcft_validity_certificate_type, + clan_majority_certificate_type, + quorum_certificate_type, + validity_certificate_type + }; + #[test_only] + use supra_framework::validator_public_keys::unanimous_certificate_type; + + friend supra_framework::genesis; + friend supra_framework::reconfiguration_with_dkg; + + /// Error: Receiver committees vector cannot be empty. + const EEMPTY_RECEIVER_COMMITTEES: u64 = 1; + /// Error: Cannot enable resharing for a threshold type that doesn't exist in current config. + const ERESHARING_FOR_NONEXISTENT_THRESHOLD_TYPE: u64 = 2; + + /// Configuration for a single receiver committee in DKG. + struct ReceiverCommitteeConfig has copy, drop, store { + /// Whether this committee uses resharing from the previous epoch's public key. + is_resharing: bool, + /// The threshold type for this committee (e.g., quorum, clan_majority). + committee_threshold_type: CertificateThresholdType, + /// The threshold type for output keys in DKG for this committee (e.g., validity, quorum). + dkg_threshold_type: CertificateThresholdType + } + + /// Main DKG configuration stored at @supra_framework. + /// Controls DKG parameters that can be updated via governance. + struct DkgConfig has copy, drop, key, store { + /// Threshold type for the dealer committee. (e.g., quorum, clan_majority). + dealer_committee_threshold_type: CertificateThresholdType, + /// Configuration for each receiver committee. + /// Default: [(false, validity), (false, quorum)] + receiver_committees: vector + } + + // ======================== + // Initialization + // ======================== + + // TODO: Add the ability to configure DKG during genesis via the genesis config files. + // This is not necessary for the initial release. + // + /// Initialize DKG config during genesis. + public(friend) fun initialize(framework: &signer) { + system_addresses::assert_supra_framework(framework); + if (!exists(@supra_framework)) { + move_to(framework, default()); + } + } + + // ======================== + // Config Update (Governance) + // ======================== + + /// Set a new DKG config for the next epoch. + /// This can only be called by on-chain governance. + /// Example usage: + /// ``` + /// let new_config = dkg_config::new( + /// quorum_certificate_type(), + /// vector[ + /// dkg_config::new_receiver_committee_config(true, validity_certificate_type()), + /// dkg_config::new_receiver_committee_config(true, quorum_certificate_type()), + /// ] + /// ); + /// dkg_config::set_for_next_epoch(&framework_signer, new_config); + /// supra_governance::reconfigure(&framework_signer); + /// ``` + public fun set_for_next_epoch( + framework: &signer, new_config: DkgConfig + ) acquires DkgConfig { + system_addresses::assert_supra_framework(framework); + + // Validate: receiver_committees cannot be empty + assert!( + vector::length(&new_config.receiver_committees) > 0, + error::invalid_argument(EEMPTY_RECEIVER_COMMITTEES) + ); + + // Validate: if resharing is enabled for a dkg threshold type, it must exist in current config + let current_config = current(); + let i = 0; + let len = vector::length(&new_config.receiver_committees); + while (i < len) { + let new_rc = vector::borrow(&new_config.receiver_committees, i); + if (new_rc.is_resharing) { + // Check if this threshold type exists in current config + assert!( + has_key_threshold_type(¤t_config, new_rc.dkg_threshold_type), + error::invalid_argument(ERESHARING_FOR_NONEXISTENT_THRESHOLD_TYPE) + ); + }; + i = i + 1; + }; + + config_buffer::upsert(new_config); + } + + /// Check if a threshold type exists in the config's receiver committees. + fun has_key_threshold_type( + config: &DkgConfig, threshold_type: CertificateThresholdType + ): bool { + let i = 0; + let len = vector::length(&config.receiver_committees); + while (i < len) { + let rc = vector::borrow(&config.receiver_committees, i); + if (rc.dkg_threshold_type == threshold_type) { + return true + }; + i = i + 1; + }; + false + } + + /// Apply any pending DKG config at epoch boundary. + /// Called from reconfiguration_with_dkg::finish(). + public(friend) fun on_new_epoch(framework: &signer) acquires DkgConfig { + system_addresses::assert_supra_framework(framework); + if (config_buffer::does_exist()) { + let new_config = config_buffer::extract(); + if (exists(@supra_framework)) { + *borrow_global_mut(@supra_framework) = new_config; + } else { + move_to(framework, new_config); + } + } + } + + // ======================== + // Constructors + // ======================== + + /// Create a new DkgConfig. + public fun new( + dealer_committee_threshold_type: CertificateThresholdType, + receiver_committees: vector + ): DkgConfig { + DkgConfig { dealer_committee_threshold_type, receiver_committees } + } + + /// Create a new ReceiverCommitteeConfig. + public fun new_receiver_committee_config( + is_resharing: bool, + committee_threshold_type: CertificateThresholdType, + dkg_threshold_type: CertificateThresholdType + ): ReceiverCommitteeConfig { + ReceiverCommitteeConfig { + is_resharing, + committee_threshold_type, + dkg_threshold_type + } + } + + /// Returns the default DKG configuration. + /// + /// Assumes that the `SUPRA_BCFT_CERTIFICATES` feature flag is enabled. + public fun default(): DkgConfig { + DkgConfig { + dealer_committee_threshold_type: quorum_certificate_type(), + receiver_committees: vector[ + ReceiverCommitteeConfig { + is_resharing: false, + committee_threshold_type: quorum_certificate_type(), + dkg_threshold_type: bcft_quorum_certificate_type() + }, + ReceiverCommitteeConfig { + is_resharing: false, + committee_threshold_type: quorum_certificate_type(), + dkg_threshold_type: bcft_validity_certificate_type() + }, + ReceiverCommitteeConfig { + is_resharing: false, + committee_threshold_type: quorum_certificate_type(), + dkg_threshold_type: clan_majority_certificate_type() + } + ] + } + } + + // ======================== + // Getters + // ======================== + + /// Get the current DKG config. + public fun current(): DkgConfig acquires DkgConfig { + if (exists(@supra_framework)) { + *borrow_global(@supra_framework) + } else { + // This branch should not be executed: + // 1. If the network is started from genesis then the default config should be + // applied during genesis. + // 2. If the DKG feature flag is enabled in an existing network, then governance + // should set a config before enabling the feature flag. + // + // This branch exists as a fallback that ensures that the `BlockMetadata` transaction + // does not fail in case of misconfiguration. + default() + } + } + + /// Get the dealer threshold type from the config. + public fun get_dealer_committee_threshold_type(config: &DkgConfig): + CertificateThresholdType { + config.dealer_committee_threshold_type + } + + /// Get the receiver committee configs from the DkgConfig. + public fun get_receiver_committee_configs(config: &DkgConfig): + vector { + config.receiver_committees + } + + /// Get is_resharing from a ReceiverCommitteeConfig. + public fun get_is_resharing(config: &ReceiverCommitteeConfig): bool { + config.is_resharing + } + + /// Get committee_threshold_type from a ReceiverCommitteeConfig. + public fun get_committee_threshold_type( + config: &ReceiverCommitteeConfig + ): CertificateThresholdType { + config.committee_threshold_type + } + + /// Get dkg_threshold_type from a ReceiverCommitteeConfig. + public fun get_dkg_threshold_type(config: &ReceiverCommitteeConfig): + CertificateThresholdType { + config.dkg_threshold_type + } + + // ======================== + // Tests + // ======================== + + #[test_only] + use supra_framework::account; + + #[test_only] + fun initialize_for_testing(framework: &signer) { + config_buffer::initialize(framework); + initialize(framework); + } + + #[test(framework = @0x1)] + fun test_set_for_next_epoch(framework: signer) acquires DkgConfig { + account::create_account_for_test(@0x1); + initialize_for_testing(&framework); + + // Create new config with resharing enabled + let new_config = + new( + validity_certificate_type(), // Change dealer to validity + vector[ + new_receiver_committee_config( + true, + quorum_certificate_type(), + bcft_quorum_certificate_type() + ), + new_receiver_committee_config( + true, + quorum_certificate_type(), + clan_majority_certificate_type() + ) + ] + ); + + // Stage for next epoch + set_for_next_epoch(&framework, new_config); + + // Config should not change yet + let config = current(); + assert!( + !get_is_resharing( + vector::borrow(&get_receiver_committee_configs(&config), 0) + ), + 1 + ); + + // Apply on new epoch + on_new_epoch(&framework); + + // Now config should be updated + let config = current(); + assert!( + get_dealer_committee_threshold_type(&config) == validity_certificate_type(), + 2 + ); + let receivers = get_receiver_committee_configs(&config); + assert!(get_is_resharing(vector::borrow(&receivers, 0)), 3); + assert!(get_is_resharing(vector::borrow(&receivers, 1)), 4); + } + + #[test(framework = @0x1)] + #[expected_failure(abort_code = 65537, location = Self)] + // EEMPTY_RECEIVER_COMMITTEES + fun test_set_for_next_epoch_empty_receivers_fails(framework: signer) acquires DkgConfig { + account::create_account_for_test(@0x1); + initialize_for_testing(&framework); + + // Try to set config with empty receiver committees - should fail + let bad_config = new( + quorum_certificate_type(), + vector[] // Empty! + ); + set_for_next_epoch(&framework, bad_config); + } + + #[test(framework = @0x1)] + #[expected_failure(abort_code = 65538, location = Self)] + // ERESHARING_FOR_NONEXISTENT_THRESHOLD_TYPE + fun test_set_for_next_epoch_resharing_nonexistent_type_fails( + framework: signer + ) acquires DkgConfig { + account::create_account_for_test(@0x1); + initialize_for_testing(&framework); + + // Default config has validity and quorum threshold types. + // Try to enable resharing for unanimous_certificate_type which doesn't exist. + let bad_config = + new( + quorum_certificate_type(), + vector[ + new_receiver_committee_config( + true, quorum_certificate_type(), unanimous_certificate_type() + ) // This type doesn't exist! + ] + ); + set_for_next_epoch(&framework, bad_config); + } + + #[test(framework = @0x1)] + fun test_set_for_next_epoch_resharing_existing_type_succeeds( + framework: signer + ) acquires DkgConfig { + account::create_account_for_test(@0x1); + initialize_for_testing(&framework); + + // Enable resharing for types that DO exist in current config (validity and quorum) + let good_config = + new( + quorum_certificate_type(), + vector[ + new_receiver_committee_config( + true, + quorum_certificate_type(), + bcft_quorum_certificate_type() + ), + new_receiver_committee_config( + true, + quorum_certificate_type(), + clan_majority_certificate_type() + ) + ] + ); + + // Should succeed + set_for_next_epoch(&framework, good_config); + on_new_epoch(&framework); + + let config = current(); + let receivers = get_receiver_committee_configs(&config); + assert!(get_is_resharing(vector::borrow(&receivers, 0)), 1); + assert!(get_is_resharing(vector::borrow(&receivers, 1)), 2); + } + + #[test(framework = @0x1)] + fun test_add_new_threshold_type_without_resharing_succeeds( + framework: signer + ) acquires DkgConfig { + account::create_account_for_test(@0x1); + initialize_for_testing(&framework); + + // Adding a new threshold type without resharing should succeed + let config_with_new_type = + new( + quorum_certificate_type(), + vector[ + new_receiver_committee_config( + false, quorum_certificate_type(), validity_certificate_type() + ), + new_receiver_committee_config( + false, quorum_certificate_type(), quorum_certificate_type() + ), + new_receiver_committee_config( + false, quorum_certificate_type(), unanimous_certificate_type() + ) // New type, no resharing + ] + ); + + // Should succeed because resharing is false + set_for_next_epoch(&framework, config_with_new_type); + on_new_epoch(&framework); + + let config = current(); + let receivers = get_receiver_committee_configs(&config); + assert!(vector::length(&receivers) == 3, 1); + } +} diff --git a/aptos-move/framework/supra-framework/sources/dkg.move b/aptos-move/framework/supra-framework/sources/dkg.move index 9721c2722bd..f06ca82fb93 100644 --- a/aptos-move/framework/supra-framework/sources/dkg.move +++ b/aptos-move/framework/supra-framework/sources/dkg.move @@ -1,26 +1,25 @@ +// Copyright (c) 2024 Supra. /// DKG on-chain states and helper functions. module supra_framework::dkg { + use std::dkg_committee::{DkgCommittee, ReceiverCommittee, new_dkg_committee_output}; use std::error; use std::option; - use std::option::Option; + use std::option::{Option}; + use std::vector; + use aptos_std::any; + use aptos_std::type_info; use supra_framework::event::emit; - use supra_framework::randomness_config::RandomnessConfig; use supra_framework::system_addresses; use supra_framework::timestamp; - use supra_framework::validator_consensus_info::ValidatorConsensusInfo; + use supra_framework::stake; + friend supra_framework::block; friend supra_framework::reconfiguration_with_dkg; - const EDKG_IN_PROGRESS: u64 = 1; - const EDKG_NOT_IN_PROGRESS: u64 = 2; - - /// This can be considered as the public input of DKG. - struct DKGSessionMetadata has copy, drop, store { - dealer_epoch: u64, - randomness_config: RandomnessConfig, - dealer_validator_set: vector, - target_validator_set: vector, - } + const EDKG_NOT_IN_PROGRESS: u64 = 1; + const EDKG_META_ALREADY_SET: u64 = 2; + const EDKG_META_NOT_SET: u64 = 3; + const EDKG_INVALID_PK_SHARES: u64 = 4; #[event] struct DKGStartEvent has drop, store { @@ -28,12 +27,31 @@ module supra_framework::dkg { start_time_us: u64, } + #[event] + struct DKGMetaSetEvent has drop, store { + dkg_meta_transcript: vector, + } + + #[event] + struct DKGFinishEvent has drop, store { + target_committees_public_key_shares: vector + } + + /// This can be considered as the public input of DKG. + struct DKGSessionMetadata has copy, drop, store { + dealer_epoch: u64, + randomness_seed: vector, + dealer_committee: DkgCommittee, + target_committees: vector, + } + /// The input and output of a DKG session. /// The validator set of epoch `x` works together for an DKG output for the target validator set of epoch `x+1`. struct DKGSessionState has copy, store, drop { metadata: DKGSessionMetadata, start_time_us: u64, - transcript: vector, + dkg_meta_transcript: vector, + target_committees_public_key_shares: vector } /// The completed and in-progress DKG sessions. @@ -42,8 +60,22 @@ module supra_framework::dkg { in_progress: Option, } + struct OnChainAggregateCommitment has copy, drop{ + bls12381_commitment_g: vector, + bls12381_commitment_evals: vector>, + dealer_ids: vector, + committee_index: u32, + epoch: u64, + chain_id: u8, + threshold_type: u8, + } + + struct OnChainAggregateCommitmentAllCommittees has copy, drop{ + commitments: vector, + } + /// Called in genesis to initialize on-chain states. - public fun initialize(supra_framework: &signer) { + public(friend) fun initialize(supra_framework: &signer) { system_addresses::assert_supra_framework(supra_framework); if (!exists(@supra_framework)) { move_to( @@ -53,29 +85,30 @@ module supra_framework::dkg { in_progress: std::option::none(), } ); - } + }; } /// Mark on-chain DKG state as in-progress. Notify validators to start DKG. /// Abort if a DKG is already in progress. public(friend) fun start( dealer_epoch: u64, - randomness_config: RandomnessConfig, - dealer_validator_set: vector, - target_validator_set: vector, + randomness_seed: vector, + dealer_committee: DkgCommittee, + target_committees: vector ) acquires DKGState { let dkg_state = borrow_global_mut(@supra_framework); let new_session_metadata = DKGSessionMetadata { dealer_epoch, - randomness_config, - dealer_validator_set, - target_validator_set, + randomness_seed, + dealer_committee, + target_committees, }; let start_time_us = timestamp::now_microseconds(); dkg_state.in_progress = std::option::some(DKGSessionState { metadata: new_session_metadata, start_time_us, - transcript: vector[], + dkg_meta_transcript: vector[], + target_committees_public_key_shares: vector[], }); emit(DKGStartEvent { @@ -84,16 +117,68 @@ module supra_framework::dkg { }); } - /// Put a transcript into the currently incomplete DKG session, then mark it completed. - /// - /// Abort if DKG is not in progress. - public(friend) fun finish(transcript: vector) acquires DKGState { + /// Family Node sets the DKGMeta for the in-progress DKG session + /// The dkg transcript is assumed to have been already verified by the aptos VM in `process_dkg_result` method + public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector) + acquires DKGState { + // ensure dkg is in progress let dkg_state = borrow_global_mut(@supra_framework); assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS)); + + // we only add the first DKG Meta proposed and ignore the rest + let session = option::extract(&mut dkg_state.in_progress); + assert!(vector::length(&session.dkg_meta_transcript) == 0, error::already_exists(EDKG_META_ALREADY_SET)); + session.dkg_meta_transcript = dkg_meta_all_committees; + dkg_state.in_progress = option::some(session); + + emit(DKGMetaSetEvent { + dkg_meta_transcript: dkg_meta_all_committees, + }); + } + + /// Family Node sets the `target_committees_public_key_shares` for the in-progress DKG session and + /// marks the incomplete DKG session completed. + ///The `target_committees_public_key_shares` is assumed to be verified by the aptos VM before calling this function + public(friend) fun finish(target_committees_public_key_shares: vector) + acquires DKGState { + // ensure dkg is in progress + let dkg_state = borrow_global_mut(@supra_framework); + assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS)); + + // DKG meta should be already set before `finish` is called let session = option::extract(&mut dkg_state.in_progress); - session.transcript = transcript; + assert!(vector::length(&session.dkg_meta_transcript) > 0, error::already_exists(EDKG_META_NOT_SET)); + + session.target_committees_public_key_shares = target_committees_public_key_shares; dkg_state.last_completed = option::some(session); dkg_state.in_progress = option::none(); + + // propagate updated keys to stake.move for all threshold types + let public_key_shares_all_comms_serialized + = any::new(type_info::type_name(), target_committees_public_key_shares); + let public_key_shares_all_comms = any::unpack(public_key_shares_all_comms_serialized); + + // Build a vector of DkgCommitteeOutput for all committees + let committee_outputs = vector[]; + let i = 0; + let len = vector::length(&public_key_shares_all_comms.commitments); + while (i < len) { + let commitment = vector::borrow(&public_key_shares_all_comms.commitments, i); + // As the first index contains the committee's threshold public key, we can skip that + let evals = vector::slice(&commitment.bls12381_commitment_evals, 1, vector::length(&commitment.bls12381_commitment_evals)); + + vector::push_back( + &mut committee_outputs, + new_dkg_committee_output(commitment.threshold_type, evals) + ); + i = i + 1; + }; + + // Set all keys for all threshold types + stake::set_dkg_output_keys(committee_outputs); + emit(DKGFinishEvent { + target_committees_public_key_shares, + }); } /// Delete the currently incomplete session, if it exists. @@ -114,6 +199,15 @@ module supra_framework::dkg { } } + /// Return the last completed DKG session state, if it exists. + public fun last_completed_session(): Option acquires DKGState { + if (exists(@supra_framework)) { + borrow_global(@supra_framework).last_completed + } else { + option::none() + } + } + /// Return the dealer epoch of a `DKGSessionState`. public fun session_dealer_epoch(session: &DKGSessionState): u64 { session.metadata.dealer_epoch diff --git a/aptos-move/framework/supra-framework/sources/dkg.spec.move b/aptos-move/framework/supra-framework/sources/dkg.spec.move index dcedf6065fd..99ffa012427 100644 --- a/aptos-move/framework/supra-framework/sources/dkg.spec.move +++ b/aptos-move/framework/supra-framework/sources/dkg.spec.move @@ -13,15 +13,22 @@ spec supra_framework::dkg { spec start( dealer_epoch: u64, - randomness_config: RandomnessConfig, - dealer_validator_set: vector, - target_validator_set: vector, + randomness_seed: vector, + dealer_committee: DkgCommittee, + target_committees: vector ) { aborts_if !exists(@supra_framework); aborts_if !exists(@supra_framework); } - spec finish(transcript: vector) { + spec set_dkg_meta(dkg_meta_all_committees: vector) { + use std::option; + requires exists(@supra_framework); + requires option::is_some(global(@supra_framework).in_progress); + aborts_if false; + } + + spec finish(target_committees_public_key_shares: vector) { use std::option; requires exists(@supra_framework); requires option::is_some(global(@supra_framework).in_progress); diff --git a/aptos-move/framework/supra-framework/sources/dkg_committee.move b/aptos-move/framework/supra-framework/sources/dkg_committee.move new file mode 100644 index 00000000000..6aa47ee2eca --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/dkg_committee.move @@ -0,0 +1,123 @@ +// Copyright (c) 2024 Supra. +module std::dkg_committee { + + use std::bcs; + use std::vector; + use supra_framework::validator_consensus_info; + use supra_framework::validator_consensus_info::ValidatorConsensusInfo; + use supra_framework::validator_public_keys::CertificateThresholdType; + + const EINVALID_DKG_COMMITTEE_SIZE: u64 = 1; + + struct DkgNodeConfig has copy, drop, store { + addr: address, + identity: vector, + dkg_pubkey: vector + } + + struct DkgCommittee has copy, drop, store { + committee: vector, + // The threshold type for the committee's Byzantine fault tolerance. + threshold_type: CertificateThresholdType + } + + struct ReceiverCommittee has copy, drop, store { + is_resharing: bool, + // The threshold type for the output key of the DKG process. + dkg_threshold_type: CertificateThresholdType, + committee: DkgCommittee + } + + public fun new_dkg_node_config( + addr: address, identity: vector, dkg_pubkey: vector + ): DkgNodeConfig { + DkgNodeConfig { addr, identity, dkg_pubkey } + } + + public fun get_addr(dkg_node: &DkgNodeConfig): address { + dkg_node.addr + } + + public fun get_dkg_pubkey(dkg_node: &DkgNodeConfig): vector { + dkg_node.dkg_pubkey + } + + public fun len(committee: &DkgCommittee): u64 { + vector::length(&committee.committee) + } + + public fun get_committee(dkg_committee: &DkgCommittee): vector { + dkg_committee.committee + } + + public fun new_dkg_committee( + committee: vector, threshold_type: CertificateThresholdType + ): DkgCommittee { + assert!(vector::length(&committee) > 0, EINVALID_DKG_COMMITTEE_SIZE); + DkgCommittee { committee, threshold_type } + } + + public fun new_dkg_committee_from_validator_consensus_info( + validator_committee: vector, + threshold_type: CertificateThresholdType + ): DkgCommittee { + assert!(vector::length(&validator_committee) > 0, EINVALID_DKG_COMMITTEE_SIZE); + + // The order of the committee members is important for DKG. + // The order should correspond to the order of the validator committee. + // The output of the DKG has keys in the same order as the committee. + let dkg_committee = vector[]; + vector::for_each( + validator_committee, + |x| { + let validator_keys_bytes = validator_consensus_info::get_pk_bytes(&x); + let addr = validator_consensus_info::get_addr(&x); + vector::push_back( + &mut dkg_committee, + DkgNodeConfig { + addr, + identity: bcs::to_bytes(&addr), + dkg_pubkey: validator_keys_bytes + } + ); + } + ); + + DkgCommittee { committee: dkg_committee, threshold_type } + } + + public fun new_receiver_committee( + is_resharing: bool, + dkg_threshold_type: CertificateThresholdType, + committee: DkgCommittee + ): ReceiverCommittee { + ReceiverCommittee { is_resharing, dkg_threshold_type, committee } + } + + /// Input for DKG key output - contains threshold type and keys for one committee + struct DkgCommitteeOutput has copy, drop { + /// The threshold type (0=validity, 1=quorum, 2=unanimous, etc.) + threshold_type: u8, + /// Public key shares for each validator (indexed by validator position) + keys: vector> + } + + /// Create a new DkgCommitteeOutput + public fun new_dkg_committee_output( + threshold_type: u8, keys: vector> + ): DkgCommitteeOutput { + DkgCommitteeOutput { threshold_type, keys } + } + + /// Get threshold type from DkgCommitteeOutput + public fun get_dkg_committee_output_threshold_type( + output: &DkgCommitteeOutput + ): u8 { + output.threshold_type + } + + /// Get keys from DkgCommitteeOutput + public fun get_dkg_committee_output_keys(output: &DkgCommitteeOutput): vector> { + output.keys + } +} diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index a56f60f0a0d..b202ff61e54 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -14,6 +14,7 @@ module supra_framework::genesis { use supra_framework::chain_status; use supra_framework::coin; use supra_framework::consensus_config; + use supra_framework::dkg_config; use supra_framework::execution_config; use supra_framework::supra_config; use supra_framework::evm_genesis_config; @@ -40,7 +41,7 @@ module supra_framework::genesis { use supra_framework::vesting_without_staking; #[test_only] - use aptos_std::ed25519; + use supra_std::validator_public_keys; #[verify_only] use std::features; @@ -57,10 +58,9 @@ module supra_framework::genesis { const EDENOMINATOR_IS_ZERO: u64 = 8; const EACCOUNT_NOT_REGISTERED_FOR_COIN: u64 = 9; - struct AccountMap has drop { account_address: address, - balance: u64, + balance: u64 } struct VestingPoolsMap has copy, drop { @@ -77,7 +77,7 @@ module supra_framework::genesis { // Cliff duration in seconds cliff_period_in_seconds: u64, // Each vesting period duration in seconds - period_duration_in_seconds: u64, + period_duration_in_seconds: u64 } struct EmployeeAccountMap has copy, drop { @@ -85,7 +85,7 @@ module supra_framework::genesis { validator: ValidatorConfigurationWithCommission, vesting_schedule_numerator: vector, vesting_schedule_denominator: u64, - beneficiary_resetter: address, + beneficiary_resetter: address } struct ValidatorConfiguration has copy, drop { @@ -95,13 +95,13 @@ module supra_framework::genesis { stake_amount: u64, consensus_pubkey: vector, network_addresses: vector, - full_node_network_addresses: vector, + full_node_network_addresses: vector } struct ValidatorConfigurationWithCommission has copy, drop { validator_config: ValidatorConfiguration, commission_percentage: u64, - join_during_genesis: bool, + join_during_genesis: bool } struct DelegatorConfiguration has copy, drop { @@ -109,7 +109,7 @@ module supra_framework::genesis { delegation_pool_creation_seed: vector, validator: ValidatorConfigurationWithCommission, delegator_addresses: vector
, - delegator_stakes: vector, + delegator_stakes: vector } struct PboDelegatorConfiguration has copy, drop { @@ -123,7 +123,7 @@ module supra_framework::genesis { //Time from `timestamp::now_seconds()` to start unlocking schedule unlock_startup_time_from_now: u64, //Time for each unlock - unlock_period_duration: u64, + unlock_period_duration: u64 } /// Genesis step 1: Initialize supra framework account and core modules on chain. @@ -142,14 +142,13 @@ module supra_framework::genesis { rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, - genesis_timestamp_in_microseconds: u64, + genesis_timestamp_in_microseconds: u64 ) { // Initialize the supra framework account. This is the account where system resources and modules will be // deployed to. This will be entirely managed by on-chain governance and no entities have the key or privileges // to use this account. - let (supra_framework_account, supra_framework_signer_cap) = account::create_framework_reserved_account( - @supra_framework - ); + let (supra_framework_account, supra_framework_signer_cap) = + account::create_framework_reserved_account(@supra_framework); // Initialize account configs on supra framework account. account::initialize(&supra_framework_account); @@ -158,21 +157,27 @@ module supra_framework::genesis { b"script_prologue", b"module_prologue", b"multi_agent_script_prologue", - b"epilogue", + b"epilogue" ); // Give the decentralized on-chain governance control over the core framework account. - supra_governance::store_signer_cap(&supra_framework_account, @supra_framework, supra_framework_signer_cap); + supra_governance::store_signer_cap( + &supra_framework_account, @supra_framework, supra_framework_signer_cap + ); // put reserved framework reserved accounts under supra governance let framework_reserved_addresses = vector
[@0x2, @0x3, @0x4, @0x5, @0x6, @0x7, @0x8, @0x9, @0xa]; while (!vector::is_empty(&framework_reserved_addresses)) { let address = vector::pop_back
(&mut framework_reserved_addresses); - let (_, framework_signer_cap) = account::create_framework_reserved_account(address); - supra_governance::store_signer_cap(&supra_framework_account, address, framework_signer_cap); + let (_, framework_signer_cap) = + account::create_framework_reserved_account(address); + supra_governance::store_signer_cap( + &supra_framework_account, address, framework_signer_cap + ); }; consensus_config::initialize(&supra_framework_account, consensus_config); + dkg_config::initialize(&supra_framework_account); execution_config::set(&supra_framework_account, execution_config); supra_config::initialize(&supra_framework_account, supra_config); version::initialize(&supra_framework_account, initial_version); @@ -185,7 +190,7 @@ module supra_framework::genesis { allow_validator_set_change, rewards_rate, rewards_rate_denominator, - voting_power_increase_limit, + voting_power_increase_limit ); storage_gas::initialize(&supra_framework_account); gas_schedule::initialize(&supra_framework_account, gas_schedule); @@ -198,7 +203,9 @@ module supra_framework::genesis { reconfiguration::initialize(&supra_framework_account); block::initialize(&supra_framework_account, epoch_interval_microsecs); state_storage::initialize(&supra_framework_account); - timestamp::set_time_has_started(&supra_framework_account, genesis_timestamp_in_microseconds); + timestamp::set_time_has_started( + &supra_framework_account, genesis_timestamp_in_microseconds + ); } /// Genesis step 2: Initialize Supra coin. @@ -226,9 +233,8 @@ module supra_framework::genesis { _congestion_threshold_percentage: u8, _congestion_base_fee_in_quants_per_sec: u64, _congestion_exponent: u8, - _task_capacity: u16, - ) { - } + _task_capacity: u16 + ) {} /// Genesis step 3: Initialize Supra Native Automation. public fun initialize_supra_native_automation_v2( @@ -244,7 +250,7 @@ module supra_framework::genesis { cycle_duration: u64, sys_task_duration_cap_in_secs: u64, sys_registry_max_gas_cap: u64, - sys_task_capacity: u16, + sys_task_capacity: u16 ) { automation_registry::initialize( supra_framework, @@ -259,15 +265,13 @@ module supra_framework::genesis { task_capacity, sys_task_duration_cap_in_secs, sys_registry_max_gas_cap, - sys_task_capacity, + sys_task_capacity ) } - /// Only called for testnets and e2e tests. fun initialize_core_resources_and_supra_coin( - supra_framework: &signer, - core_resources_auth_key: vector, + supra_framework: &signer, core_resources_auth_key: vector ) { let (burn_cap, mint_cap) = supra_coin::initialize(supra_framework); coin::create_coin_conversion_map(supra_framework); @@ -281,49 +285,59 @@ module supra_framework::genesis { let core_resources = account::create_account(@core_resources); supra_account::register_supra(&core_resources); // register Supra store - account::rotate_authentication_key_internal(&core_resources, core_resources_auth_key); - supra_coin::configure_accounts_for_test(supra_framework, &core_resources, mint_cap); + account::rotate_authentication_key_internal( + &core_resources, core_resources_auth_key + ); + supra_coin::configure_accounts_for_test( + supra_framework, &core_resources, mint_cap + ); } /// Initialize the EVM genesis config. fun initialize_evm_genesis_config( - supra_framework: &signer, - evm_genesis_config: vector, + supra_framework: &signer, evm_genesis_config: vector ) { evm_genesis_config::initialize(supra_framework, evm_genesis_config); } /// Initialize the leader ban config fun initialize_leader_ban_registry_config( - supra_framework: &signer, - leader_ban_registry_config: vector, + supra_framework: &signer, leader_ban_registry_config: vector ) { - leader_ban_registry_config::initialize(supra_framework, leader_ban_registry_config); + leader_ban_registry_config::initialize( + supra_framework, leader_ban_registry_config + ); leader_ban_registry::initialize_leader_ban_registry(supra_framework); } - - fun create_accounts(supra_framework: &signer, accounts: vector) { + fun create_accounts( + supra_framework: &signer, accounts: vector + ) { let unique_accounts = vector::empty(); - vector::for_each_ref(&accounts, |account_map| { - let account_map: &AccountMap = account_map; - assert!( - !vector::contains(&unique_accounts, &account_map.account_address), - error::already_exists(EDUPLICATE_ACCOUNT), - ); - vector::push_back(&mut unique_accounts, account_map.account_address); + vector::for_each_ref( + &accounts, + |account_map| { + let account_map: &AccountMap = account_map; + assert!( + !vector::contains(&unique_accounts, &account_map.account_address), + error::already_exists(EDUPLICATE_ACCOUNT) + ); + vector::push_back(&mut unique_accounts, account_map.account_address); - create_account( - supra_framework, - account_map.account_address, - account_map.balance, - ); - }); + create_account( + supra_framework, + account_map.account_address, + account_map.balance + ); + } + ); } /// This creates an funds an account if it doesn't exist. /// If it exists, it just returns the signer. - fun create_account(supra_framework: &signer, account_address: address, balance: u64): signer { + fun create_account( + supra_framework: &signer, account_address: address, balance: u64 + ): signer { if (account::exists_at(account_address)) { create_signer(account_address) } else { @@ -334,7 +348,6 @@ module supra_framework::genesis { } } - fun create_multiple_multisig_accounts_with_schema( supra_framework: &signer, owner: address, @@ -349,8 +362,17 @@ module supra_framework::genesis { let counter = 0; let result = vector::empty(); while (counter < num_of_accounts) { - let account_addr = create_multisig_account_with_balance(supra_framework, owner, additional_owners, - num_signatures_required, metadata_keys, metadata_values, timeout_duration, balance); + let account_addr = + create_multisig_account_with_balance( + supra_framework, + owner, + additional_owners, + num_signatures_required, + metadata_keys, + metadata_values, + timeout_duration, + balance + ); vector::push_back(&mut result, account_addr); counter = counter + 1; }; @@ -365,11 +387,17 @@ module supra_framework::genesis { metadata_keys: vector, metadata_values: vector>, timeout_duration: u64, - balance: u64, + balance: u64 ): address { - assert!(account::exists_at(owner), error::invalid_argument(EACCOUNT_DOES_NOT_EXIST)); assert!( - vector::all(&additional_owners, |ao_addr|{ account::exists_at(*ao_addr) }), + account::exists_at(owner), + error::invalid_argument(EACCOUNT_DOES_NOT_EXIST) + ); + assert!( + vector::all( + &additional_owners, + |ao_addr| { account::exists_at(*ao_addr) } + ), error::invalid_argument(EACCOUNT_DOES_NOT_EXIST) ); let addr = multisig_account::get_next_multisig_account_address(owner); @@ -390,90 +418,104 @@ module supra_framework::genesis { fun create_employee_validators( employee_vesting_start: u64, employee_vesting_period_duration: u64, - employees: vector, + employees: vector ) { let unique_accounts = vector::empty(); - vector::for_each_ref(&employees, |employee_group| { - let j = 0; - let employee_group: &EmployeeAccountMap = employee_group; - let num_employees_in_group = vector::length(&employee_group.accounts); - - let buy_ins = simple_map::create(); - - while (j < num_employees_in_group) { - let account = vector::borrow(&employee_group.accounts, j); + vector::for_each_ref( + &employees, + |employee_group| { + let j = 0; + let employee_group: &EmployeeAccountMap = employee_group; + let num_employees_in_group = vector::length(&employee_group.accounts); + + let buy_ins = simple_map::create(); + + while (j < num_employees_in_group) { + let account = vector::borrow(&employee_group.accounts, j); + assert!( + !vector::contains(&unique_accounts, account), + error::already_exists(EDUPLICATE_ACCOUNT) + ); + vector::push_back(&mut unique_accounts, *account); + + let employee = create_signer(*account); + let total = coin::balance(*account); + let coins = coin::withdraw(&employee, total); + simple_map::add(&mut buy_ins, *account, coins); + + j = j + 1; + }; + + let j = 0; + let num_vesting_events = vector::length( + &employee_group.vesting_schedule_numerator + ); + let schedule = vector::empty(); + + while (j < num_vesting_events) { + let numerator = vector::borrow( + &employee_group.vesting_schedule_numerator, j + ); + let event = + fixed_point32::create_from_rational( + *numerator, + employee_group.vesting_schedule_denominator + ); + vector::push_back(&mut schedule, event); + + j = j + 1; + }; + + let vesting_schedule = + vesting::create_vesting_schedule( + schedule, + employee_vesting_start, + employee_vesting_period_duration + ); + + let admin = employee_group.validator.validator_config.owner_address; + let admin_signer = &create_signer(admin); + let contract_address = + vesting::create_vesting_contract( + admin_signer, + &employee_group.accounts, + buy_ins, + vesting_schedule, + admin, + employee_group.validator.validator_config.operator_address, + employee_group.validator.validator_config.voter_address, + employee_group.validator.commission_percentage, + x"" + ); + let pool_address = vesting::stake_pool_address(contract_address); + + if (employee_group.beneficiary_resetter != @0x0) { + vesting::set_beneficiary_resetter( + admin_signer, + contract_address, + employee_group.beneficiary_resetter + ); + }; + + let validator = &employee_group.validator.validator_config; assert!( - !vector::contains(&unique_accounts, account), - error::already_exists(EDUPLICATE_ACCOUNT), + account::exists_at(validator.owner_address), + error::not_found(EACCOUNT_DOES_NOT_EXIST) ); - vector::push_back(&mut unique_accounts, *account); - - let employee = create_signer(*account); - let total = coin::balance(*account); - let coins = coin::withdraw(&employee, total); - simple_map::add(&mut buy_ins, *account, coins); - - j = j + 1; - }; - - let j = 0; - let num_vesting_events = vector::length(&employee_group.vesting_schedule_numerator); - let schedule = vector::empty(); - - while (j < num_vesting_events) { - let numerator = vector::borrow(&employee_group.vesting_schedule_numerator, j); - let event = fixed_point32::create_from_rational( - *numerator, - employee_group.vesting_schedule_denominator + assert!( + account::exists_at(validator.operator_address), + error::not_found(EACCOUNT_DOES_NOT_EXIST) ); - vector::push_back(&mut schedule, event); - - j = j + 1; - }; - - let vesting_schedule = vesting::create_vesting_schedule( - schedule, - employee_vesting_start, - employee_vesting_period_duration, - ); - - let admin = employee_group.validator.validator_config.owner_address; - let admin_signer = &create_signer(admin); - let contract_address = vesting::create_vesting_contract( - admin_signer, - &employee_group.accounts, - buy_ins, - vesting_schedule, - admin, - employee_group.validator.validator_config.operator_address, - employee_group.validator.validator_config.voter_address, - employee_group.validator.commission_percentage, - x"", - ); - let pool_address = vesting::stake_pool_address(contract_address); - - if (employee_group.beneficiary_resetter != @0x0) { - vesting::set_beneficiary_resetter(admin_signer, contract_address, employee_group.beneficiary_resetter); - }; - - let validator = &employee_group.validator.validator_config; - assert!( - account::exists_at(validator.owner_address), - error::not_found(EACCOUNT_DOES_NOT_EXIST), - ); - assert!( - account::exists_at(validator.operator_address), - error::not_found(EACCOUNT_DOES_NOT_EXIST), - ); - assert!( - account::exists_at(validator.voter_address), - error::not_found(EACCOUNT_DOES_NOT_EXIST), - ); - if (employee_group.validator.join_during_genesis) { - initialize_validator(pool_address, validator); - }; - }); + assert!( + account::exists_at(validator.voter_address), + error::not_found(EACCOUNT_DOES_NOT_EXIST) + ); + if (employee_group.validator.join_during_genesis) { + initialize_validator(pool_address, validator); + }; + } + ); } /// DEPRECATED @@ -481,12 +523,17 @@ module supra_framework::genesis { fun create_initialize_validators_with_commission( supra_framework: &signer, use_staking_contract: bool, - validators: vector, + validators: vector ) { - vector::for_each_ref(&validators, |validator| { - let validator: &ValidatorConfigurationWithCommission = validator; - create_initialize_validator(supra_framework, validator, use_staking_contract); - }); + vector::for_each_ref( + &validators, + |validator| { + let validator: &ValidatorConfigurationWithCommission = validator; + create_initialize_validator( + supra_framework, validator, use_staking_contract + ); + } + ); } /// DEPRECATED @@ -501,51 +548,66 @@ module supra_framework::genesis { /// /// Network address fields are a vector per account, where each entry is a vector of addresses /// encoded in a single BCS byte array. - fun create_initialize_validators(supra_framework: &signer, validators: vector) { + fun create_initialize_validators( + supra_framework: &signer, validators: vector + ) { let validators_with_commission = vector::empty(); - vector::for_each_reverse(validators, |validator| { - let validator_with_commission = ValidatorConfigurationWithCommission { - validator_config: validator, - commission_percentage: 0, - join_during_genesis: true, - }; - vector::push_back(&mut validators_with_commission, validator_with_commission); - }); + vector::for_each_reverse( + validators, + |validator| { + let validator_with_commission = ValidatorConfigurationWithCommission { + validator_config: validator, + commission_percentage: 0, + join_during_genesis: true + }; + vector::push_back( + &mut validators_with_commission, validator_with_commission + ); + } + ); - create_initialize_validators_with_commission(supra_framework, false, validators_with_commission); + create_initialize_validators_with_commission( + supra_framework, false, validators_with_commission + ); } fun create_initialize_validator( supra_framework: &signer, commission_config: &ValidatorConfigurationWithCommission, - use_staking_contract: bool, + use_staking_contract: bool ) { let validator = &commission_config.validator_config; - let owner = &create_account(supra_framework, validator.owner_address, validator.stake_amount); + let owner = + &create_account( + supra_framework, validator.owner_address, validator.stake_amount + ); create_account(supra_framework, validator.operator_address, 0); create_account(supra_framework, validator.voter_address, 0); // Initialize the stake pool and join the validator set. - let pool_address = if (use_staking_contract) { - staking_contract::create_staking_contract( - owner, - validator.operator_address, - validator.voter_address, - validator.stake_amount, - commission_config.commission_percentage, - x"", - ); - staking_contract::stake_pool_address(validator.owner_address, validator.operator_address) - } else { - stake::initialize_stake_owner( - owner, - validator.stake_amount, - validator.operator_address, - validator.voter_address, - ); - validator.owner_address - }; + let pool_address = + if (use_staking_contract) { + staking_contract::create_staking_contract( + owner, + validator.operator_address, + validator.voter_address, + validator.stake_amount, + commission_config.commission_percentage, + x"" + ); + staking_contract::stake_pool_address( + validator.owner_address, validator.operator_address + ) + } else { + stake::initialize_stake_owner( + owner, + validator.stake_amount, + validator.operator_address, + validator.voter_address + ); + validator.owner_address + }; if (commission_config.join_during_genesis) { initialize_validator(pool_address, validator); @@ -554,50 +616,69 @@ module supra_framework::genesis { fun create_pbo_delegation_pools( pbo_delegator_configs: vector, - delegation_percentage: u64, + delegation_percentage: u64 ) { let unique_accounts: vector
= vector::empty(); assert!( delegation_percentage != 0 && delegation_percentage <= 100, error::invalid_argument(EPERCENTAGE_INVALID) ); - vector::for_each_ref(&pbo_delegator_configs, |pbo_delegator_config| { - let pbo_delegator_config: &PboDelegatorConfiguration = pbo_delegator_config; - assert!(!vector::contains(&unique_accounts, &pbo_delegator_config.delegator_config.owner_address), - error::invalid_argument(EDUPLICATE_ACCOUNT)); - vector::push_back(&mut unique_accounts, pbo_delegator_config.delegator_config.owner_address); - create_pbo_delegation_pool(pbo_delegator_config, delegation_percentage); - }); + vector::for_each_ref( + &pbo_delegator_configs, + |pbo_delegator_config| { + let pbo_delegator_config: &PboDelegatorConfiguration = + pbo_delegator_config; + assert!( + !vector::contains( + &unique_accounts, + &pbo_delegator_config.delegator_config.owner_address + ), + error::invalid_argument(EDUPLICATE_ACCOUNT) + ); + vector::push_back( + &mut unique_accounts, + pbo_delegator_config.delegator_config.owner_address + ); + create_pbo_delegation_pool(pbo_delegator_config, delegation_percentage); + } + ); } fun create_pbo_delegation_pool( - pbo_delegator_config: &PboDelegatorConfiguration, - delegation_percentage: u64, + pbo_delegator_config: &PboDelegatorConfiguration, delegation_percentage: u64 ) { assert!( delegation_percentage != 0 && delegation_percentage <= 100, error::invalid_argument(EPERCENTAGE_INVALID) ); let unique_accounts: vector
= vector::empty(); - vector::for_each_ref(&pbo_delegator_config.delegator_config.delegator_addresses, |delegator_address| { - let delegator_address: &address = delegator_address; - assert!( - !vector::contains(&unique_accounts, delegator_address), - error::already_exists(EDUPLICATE_ACCOUNT), - ); - vector::push_back(&mut unique_accounts, *delegator_address); - }); - let owner_signer = create_signer(pbo_delegator_config.delegator_config.owner_address); + vector::for_each_ref( + &pbo_delegator_config.delegator_config.delegator_addresses, + |delegator_address| { + let delegator_address: &address = delegator_address; + assert!( + !vector::contains(&unique_accounts, delegator_address), + error::already_exists(EDUPLICATE_ACCOUNT) + ); + vector::push_back(&mut unique_accounts, *delegator_address); + } + ); + let owner_signer = + create_signer(pbo_delegator_config.delegator_config.owner_address); // get a list of delegator addresses, withdraw the coin from them and merge them into a single account - let delegator_addresses = pbo_delegator_config.delegator_config.delegator_addresses; + let delegator_addresses = + pbo_delegator_config.delegator_config.delegator_addresses; let coinInitialization = coin::zero(); - vector::for_each(delegator_addresses, |delegator_address| { - let delegator = &create_signer(delegator_address); - let total = coin::balance(delegator_address); - let withdraw_amount = total * delegation_percentage / 100; - let coins = coin::withdraw(delegator, withdraw_amount); - coin::merge(&mut coinInitialization, coins); - }); + vector::for_each( + delegator_addresses, + |delegator_address| { + let delegator = &create_signer(delegator_address); + let total = coin::balance(delegator_address); + let withdraw_amount = total * delegation_percentage / 100; + let coins = coin::withdraw(delegator, withdraw_amount); + coin::merge(&mut coinInitialization, coins); + } + ); pbo_delegation_pool::initialize_delegation_pool( &owner_signer, option::some(pbo_delegator_config.multisig_admin), @@ -608,13 +689,15 @@ module supra_framework::genesis { coinInitialization, pbo_delegator_config.unlock_schedule_numerators, pbo_delegator_config.unlock_schedule_denominator, - pbo_delegator_config.unlock_startup_time_from_now + timestamp::now_seconds(), - pbo_delegator_config.unlock_period_duration, + pbo_delegator_config.unlock_startup_time_from_now + + timestamp::now_seconds(), + pbo_delegator_config.unlock_period_duration ); - let pool_address = pbo_delegation_pool::get_owned_pool_address( - pbo_delegator_config.delegator_config.owner_address - ); + let pool_address = + pbo_delegation_pool::get_owned_pool_address( + pbo_delegator_config.delegator_config.owner_address + ); let validator = pbo_delegator_config.delegator_config.validator.validator_config; pbo_delegation_pool::set_operator(&owner_signer, validator.operator_address); pbo_delegation_pool::set_delegated_voter(&owner_signer, validator.voter_address); @@ -625,101 +708,133 @@ module supra_framework::genesis { }; } - fun assert_validator_addresses_check(validator: &ValidatorConfiguration) { + fun assert_validator_addresses_check( + validator: &ValidatorConfiguration + ) { assert!( account::exists_at(validator.owner_address), - error::not_found(EACCOUNT_DOES_NOT_EXIST), + error::not_found(EACCOUNT_DOES_NOT_EXIST) ); assert!( account::exists_at(validator.operator_address), - error::not_found(EACCOUNT_DOES_NOT_EXIST), + error::not_found(EACCOUNT_DOES_NOT_EXIST) ); assert!( account::exists_at(validator.voter_address), - error::not_found(EACCOUNT_DOES_NOT_EXIST), + error::not_found(EACCOUNT_DOES_NOT_EXIST) ); } - fun create_vesting_without_staking_pools( vesting_pool_map: vector ) { let unique_accounts: vector
= vector::empty(); - vector::for_each_ref(&vesting_pool_map, |pool_config|{ - let pool_config: &VestingPoolsMap = pool_config; - let schedule = vector::empty(); - let schedule_length = vector::length(&pool_config.vesting_numerators); - assert!(schedule_length != 0, error::invalid_argument(EVESTING_SCHEDULE_IS_ZERO)); - assert!(pool_config.vesting_denominator != 0, error::invalid_argument(EDENOMINATOR_IS_ZERO)); - assert!(pool_config.vpool_locking_percentage != 0 && pool_config.vpool_locking_percentage <= 100, - error::invalid_argument(EPERCENTAGE_INVALID)); - //check the sum of numerator are <= denominator. - let sum = vector::fold(pool_config.vesting_numerators, 0, |acc, x| acc + x); - // Check that total of all fraction in `vesting_schedule` is not greater than 1 - assert!(sum <= pool_config.vesting_denominator, - error::invalid_argument(ENUMERATOR_GREATER_THAN_DENOMINATOR)); - //assert that withdrawal_address is registered to receive SupraCoin - assert!( - coin::is_account_registered(pool_config.withdrawal_address), - error::invalid_argument(EACCOUNT_NOT_REGISTERED_FOR_COIN) - ); - //assertion on admin_address? - let admin = create_signer(pool_config.admin_address); - - //Create the vesting schedule - let j = 0; - while (j < schedule_length) { - let numerator = *vector::borrow(&pool_config.vesting_numerators, j); - assert!(numerator != 0, error::invalid_argument(ENUMERATOR_IS_ZERO)); - let event = fixed_point32::create_from_rational(numerator, pool_config.vesting_denominator); - vector::push_back(&mut schedule, event); - j = j + 1; - }; - - let vesting_schedule = vesting_without_staking::create_vesting_schedule( - schedule, - timestamp::now_seconds() + pool_config.cliff_period_in_seconds, - pool_config.period_duration_in_seconds, - ); - - let buy_ins = simple_map::create(); - let num_shareholders = vector::length(&pool_config.shareholders); - assert!(num_shareholders != 0, error::invalid_argument(ENO_SHAREHOLDERS)); - let j = 0; - while (j < num_shareholders) { - let shareholder = *vector::borrow(&pool_config.shareholders, j); - assert!(!vector::contains(&unique_accounts, &shareholder), error::already_exists(EDUPLICATE_ACCOUNT)); - vector::push_back(&mut unique_accounts, shareholder); - let shareholder_signer = create_signer(shareholder); - let amount = coin::balance(shareholder); - let amount_to_extract = (amount * (pool_config.vpool_locking_percentage as u64)) / 100; - let coin_share = coin::withdraw(&shareholder_signer, amount_to_extract); - simple_map::add(&mut buy_ins, shareholder, coin_share); - j = j + 1; - }; - vesting_without_staking::create_vesting_contract( - &admin, - buy_ins, - vesting_schedule, - pool_config.withdrawal_address, - VESTING_CONTRACT_SEED - ); - }); + vector::for_each_ref( + &vesting_pool_map, + |pool_config| { + let pool_config: &VestingPoolsMap = pool_config; + let schedule = vector::empty(); + let schedule_length = vector::length(&pool_config.vesting_numerators); + assert!( + schedule_length != 0, + error::invalid_argument(EVESTING_SCHEDULE_IS_ZERO) + ); + assert!( + pool_config.vesting_denominator != 0, + error::invalid_argument(EDENOMINATOR_IS_ZERO) + ); + assert!( + pool_config.vpool_locking_percentage != 0 + && pool_config.vpool_locking_percentage <= 100, + error::invalid_argument(EPERCENTAGE_INVALID) + ); + //check the sum of numerator are <= denominator. + let sum = vector::fold( + pool_config.vesting_numerators, + 0, + |acc, x| acc + x + ); + // Check that total of all fraction in `vesting_schedule` is not greater than 1 + assert!( + sum <= pool_config.vesting_denominator, + error::invalid_argument(ENUMERATOR_GREATER_THAN_DENOMINATOR) + ); + //assert that withdrawal_address is registered to receive SupraCoin + assert!( + coin::is_account_registered(pool_config.withdrawal_address), + error::invalid_argument(EACCOUNT_NOT_REGISTERED_FOR_COIN) + ); + //assertion on admin_address? + let admin = create_signer(pool_config.admin_address); + + //Create the vesting schedule + let j = 0; + while (j < schedule_length) { + let numerator = *vector::borrow(&pool_config.vesting_numerators, j); + assert!(numerator != 0, error::invalid_argument(ENUMERATOR_IS_ZERO)); + let event = + fixed_point32::create_from_rational( + numerator, pool_config.vesting_denominator + ); + vector::push_back(&mut schedule, event); + j = j + 1; + }; + + let vesting_schedule = + vesting_without_staking::create_vesting_schedule( + schedule, + timestamp::now_seconds() + pool_config.cliff_period_in_seconds, + pool_config.period_duration_in_seconds + ); + + let buy_ins = simple_map::create(); + let num_shareholders = vector::length(&pool_config.shareholders); + assert!(num_shareholders != 0, error::invalid_argument(ENO_SHAREHOLDERS)); + let j = 0; + while (j < num_shareholders) { + let shareholder = *vector::borrow(&pool_config.shareholders, j); + assert!( + !vector::contains(&unique_accounts, &shareholder), + error::already_exists(EDUPLICATE_ACCOUNT) + ); + vector::push_back(&mut unique_accounts, shareholder); + let shareholder_signer = create_signer(shareholder); + let amount = coin::balance(shareholder); + let amount_to_extract = + (amount * (pool_config.vpool_locking_percentage as u64)) / 100; + let coin_share = + coin::withdraw( + &shareholder_signer, amount_to_extract + ); + simple_map::add(&mut buy_ins, shareholder, coin_share); + j = j + 1; + }; + vesting_without_staking::create_vesting_contract( + &admin, + buy_ins, + vesting_schedule, + pool_config.withdrawal_address, + VESTING_CONTRACT_SEED + ); + } + ); } - fun initialize_validator(pool_address: address, validator: &ValidatorConfiguration) { + fun initialize_validator( + pool_address: address, validator: &ValidatorConfiguration + ) { let operator = &create_signer(validator.operator_address); stake::rotate_consensus_key_genesis( operator, pool_address, - validator.consensus_pubkey, + validator.consensus_pubkey ); stake::update_network_and_fullnode_addresses( operator, pool_address, validator.network_addresses, - validator.full_node_network_addresses, + validator.full_node_network_addresses ); stake::join_validator_set_internal(operator, pool_address); } @@ -778,10 +893,12 @@ module supra_framework::genesis { rewards_rate, rewards_rate_denominator, voting_power_increase_limit, - 0, + 0 ); - features::change_feature_flags_for_verification(supra_framework, vector[1, 2, 11], vector[]); + features::change_feature_flags_for_verification( + supra_framework, vector[1, 2, 11], vector[] + ); initialize_supra_coin(supra_framework); supra_governance::initialize_for_verification( supra_framework, @@ -789,10 +906,12 @@ module supra_framework::genesis { // required_proposer_stake, voting_duration_secs, supra_min_voting_threshold, - voters, + voters ); create_accounts(supra_framework, accounts); - create_employee_validators(employee_vesting_start, employee_vesting_period_duration, employees); + create_employee_validators( + employee_vesting_start, employee_vesting_period_duration, employees + ); create_initialize_validators_with_commission(supra_framework, true, validators); set_genesis_end(supra_framework); } @@ -817,7 +936,7 @@ module supra_framework::genesis { 1, 1, 30, - 0, + 0 ) } @@ -858,14 +977,8 @@ module supra_framework::genesis { let addr1 = @0x121345; let accounts = vector[ - AccountMap { - account_address: addr0, - balance: 12345, - }, - AccountMap { - account_address: addr1, - balance: 67890, - }, + AccountMap { account_address: addr0, balance: 12345 }, + AccountMap { account_address: addr1, balance: 67890 } ]; create_accounts(supra_framework, accounts); @@ -877,10 +990,20 @@ module supra_framework::genesis { } #[test_only] - fun generate_multisig_account(owner: &signer, addition_owner: vector
): address { + fun generate_multisig_account( + owner: &signer, addition_owner: vector
+ ): address { let owner_addr = aptos_std::signer::address_of(owner); - let multisig_addr = multisig_account::get_next_multisig_account_address(owner_addr); - multisig_account::create_with_owners(owner, addition_owner, 2, vector[], vector[], 300); + let multisig_addr = + multisig_account::get_next_multisig_account_address(owner_addr); + multisig_account::create_with_owners( + owner, + addition_owner, + 2, + vector[], + vector[], + 300 + ); multisig_addr } @@ -894,7 +1017,9 @@ module supra_framework::genesis { use std::features; let feature = features::get_new_accounts_default_to_fa_supra_store_feature(); - features::change_feature_flags_for_testing(supra_framework, vector[feature], vector[]); + features::change_feature_flags_for_testing( + supra_framework, vector[feature], vector[] + ); aggregator_factory::initialize_aggregator_factory_for_test(supra_framework); let (burn_cap, mint_cap) = supra_coin::initialize(supra_framework); @@ -904,9 +1029,14 @@ module supra_framework::genesis { supra_account::register_supra(&core_resources); // registers SUPRA store let sup_metadata = object::address_to_object(@supra_fungible_asset); - assert!(primary_fungible_store::primary_store_exists(@core_resources, sup_metadata), 2); + assert!( + primary_fungible_store::primary_store_exists(@core_resources, sup_metadata), + 2 + ); - supra_coin::configure_accounts_for_test(supra_framework, &core_resources, mint_cap); + supra_coin::configure_accounts_for_test( + supra_framework, &core_resources, mint_cap + ); coin::destroy_burn_cap(burn_cap); coin::destroy_mint_cap(mint_cap); } @@ -920,8 +1050,8 @@ module supra_framework::genesis { initialize_supra_coin(supra_framework); let owner = @0x121341; - let (_, pk_1) = stake::generate_identity(); - let _pk_1 = ed25519::unvalidated_public_key_to_bytes(&pk_1); + let (_sk_1, pk_1) = stake::generate_identity(); + let _pk_1 = validator_public_keys::public_key_to_bytes(pk_1); create_account(supra_framework, owner, 0); let validator_config_commission = ValidatorConfigurationWithCommission { validator_config: ValidatorConfiguration { @@ -931,10 +1061,10 @@ module supra_framework::genesis { stake_amount: 0, consensus_pubkey: _pk_1, network_addresses: x"222222", - full_node_network_addresses: x"333333", + full_node_network_addresses: x"333333" }, commission_percentage: 10, - join_during_genesis: true, + join_during_genesis: true }; let delegation_pool_creation_seed = x"121341"; let delegator_addresses = vector[@0x121342, @0x121343]; @@ -955,7 +1085,10 @@ module supra_framework::genesis { i = i + 1; }; let principle_lockup_time = 100; - let multisig = generate_multisig_account(&account::create_signer_for_test(owner), vector[@0x12134]); + let multisig = + generate_multisig_account( + &account::create_signer_for_test(owner), vector[@0x12134] + ); let pbo_delegator_config = PboDelegatorConfiguration { multisig_admin: multisig, unlock_period_duration: 12, @@ -967,8 +1100,8 @@ module supra_framework::genesis { validator: validator_config_commission, delegation_pool_creation_seed, delegator_addresses, - delegator_stakes, - }, + delegator_stakes + } }; create_pbo_delegation_pool(&pbo_delegator_config, delegation_percentage); let pool_address = pbo_delegation_pool::get_owned_pool_address(owner); @@ -983,10 +1116,10 @@ module supra_framework::genesis { initialize_supra_coin(supra_framework); let owner1 = @0x121341; create_account(supra_framework, owner1, 0); - let (_, pk_1) = stake::generate_identity(); - let (_, pk_2) = stake::generate_identity(); - let _pk_1 = ed25519::unvalidated_public_key_to_bytes(&pk_1); - let _pk_2 = ed25519::unvalidated_public_key_to_bytes(&pk_2); + let (_sk_1, pk_1) = stake::generate_identity(); + let (_sk_2, pk_2) = stake::generate_identity(); + let _pk_1 = validator_public_keys::public_key_to_bytes(pk_1); + let _pk_2 = validator_public_keys::public_key_to_bytes(pk_2); let validator_config_commission1 = ValidatorConfigurationWithCommission { validator_config: ValidatorConfiguration { owner_address: owner1, @@ -995,10 +1128,10 @@ module supra_framework::genesis { stake_amount: 100 * ONE_SUPRA, consensus_pubkey: _pk_1, network_addresses: x"222222", - full_node_network_addresses: x"333333", + full_node_network_addresses: x"333333" }, commission_percentage: 10, - join_during_genesis: true, + join_during_genesis: true }; let delegation_pool_creation_seed1 = x"121341"; let delegator_address1 = vector[@0x121342, @0x121343]; @@ -1019,7 +1152,10 @@ module supra_framework::genesis { i = i + 1; }; let principle_lockup_time1 = 100; - let multisig1 = generate_multisig_account(&account::create_signer_for_test(owner1), vector[@0x121342]); + let multisig1 = + generate_multisig_account( + &account::create_signer_for_test(owner1), vector[@0x121342] + ); let pbo_delegator_config1 = PboDelegatorConfiguration { multisig_admin: multisig1, unlock_period_duration: 12, @@ -1031,8 +1167,8 @@ module supra_framework::genesis { validator: validator_config_commission1, delegation_pool_creation_seed: delegation_pool_creation_seed1, delegator_addresses: delegator_address1, - delegator_stakes: delegator_stakes1, - }, + delegator_stakes: delegator_stakes1 + } }; let owner2 = @0x121344; @@ -1045,10 +1181,10 @@ module supra_framework::genesis { stake_amount: 100 * ONE_SUPRA, consensus_pubkey: _pk_2, network_addresses: x"222222", - full_node_network_addresses: x"333333", + full_node_network_addresses: x"333333" }, commission_percentage: 20, - join_during_genesis: true, + join_during_genesis: true }; let delegation_pool_creation_seed2 = x"121344"; let delegator_address2 = vector[@0x121345, @0x121346]; @@ -1057,12 +1193,22 @@ module supra_framework::genesis { let delegator_stakes2: vector = vector::empty(); while (j < vector::length(&delegator_address2)) { let bal = vector::borrow(&initial_balance2, j); - create_account(supra_framework, *vector::borrow(&delegator_address2, j), *bal); - vector::push_back(&mut delegator_stakes2, (*bal) * delegation_percentage / 100); + create_account( + supra_framework, + *vector::borrow(&delegator_address2, j), + *bal + ); + vector::push_back( + &mut delegator_stakes2, + (*bal) * delegation_percentage / 100 + ); j = j + 1; }; let principle_lockup_time2 = 200; - let multisig2 = generate_multisig_account(&account::create_signer_for_test(owner2), vector[@0x121347]); + let multisig2 = + generate_multisig_account( + &account::create_signer_for_test(owner2), vector[@0x121347] + ); let pbo_delegator_config2 = PboDelegatorConfiguration { multisig_admin: multisig2, unlock_period_duration: 12, @@ -1074,8 +1220,8 @@ module supra_framework::genesis { validator: validator_config_commission2, delegation_pool_creation_seed: delegation_pool_creation_seed2, delegator_addresses: delegator_address2, - delegator_stakes: delegator_stakes2, - }, + delegator_stakes: delegator_stakes2 + } }; let pbo_delegator_configs = vector[pbo_delegator_config1, pbo_delegator_config2]; create_pbo_delegation_pools(pbo_delegator_configs, delegation_percentage); @@ -1085,14 +1231,15 @@ module supra_framework::genesis { assert!(pbo_delegation_pool::delegation_pool_exists(pool_address2), 1); } - #[test (supra_framework= @0x1, owner1= @0x1234, owner2= @0x2345, owner3= @0x3456)] + #[test( + supra_framework = @0x1, owner1 = @0x1234, owner2 = @0x2345, owner3 = @0x3456 + )] fun test_create_multisig_account_with_balance( supra_framework: &signer, owner1: address, owner2: address, owner3: address - ) - { + ) { setup(); initialize_supra_coin(supra_framework); let additional_owners = vector[owner2, owner3]; @@ -1104,8 +1251,17 @@ module supra_framework::genesis { create_account(supra_framework, owner1, 0); create_account(supra_framework, owner2, 0); create_account(supra_framework, owner3, 0); - let addr = create_multisig_account_with_balance(supra_framework, owner1, additional_owners, - num_signatures_required, metadata_keys, metadata_values, timeout_duration, balance); + let addr = + create_multisig_account_with_balance( + supra_framework, + owner1, + additional_owners, + num_signatures_required, + metadata_keys, + metadata_values, + timeout_duration, + balance + ); //Ensure it is indeed on-chain multisig account with required threshold assert!(multisig_account::num_signatures_required(addr) == 2, 1); //Ensure the account is seeded with supplied balance @@ -1116,14 +1272,15 @@ module supra_framework::genesis { assert!(coin::balance(owner1) == balance, 3); } - #[test (supra_framework= @0x1, owner1= @0x1234, owner2= @0x2345, owner3= @0x3456)] + #[test( + supra_framework = @0x1, owner1 = @0x1234, owner2 = @0x2345, owner3 = @0x3456 + )] fun test_create_multisig_account_with_schema( supra_framework: &signer, owner1: address, owner2: address, owner3: address - ) - { + ) { setup(); initialize_supra_coin(supra_framework); let additional_owners = vector[owner2, owner3]; @@ -1136,18 +1293,42 @@ module supra_framework::genesis { create_account(supra_framework, owner1, 0); create_account(supra_framework, owner2, 0); create_account(supra_framework, owner3, 0); - let vec_addr = create_multiple_multisig_accounts_with_schema(supra_framework, owner1, - additional_owners, num_signatures_required, metadata_keys, metadata_values, - timeout_duration, balance, num_accounts); + let vec_addr = + create_multiple_multisig_accounts_with_schema( + supra_framework, + owner1, + additional_owners, + num_signatures_required, + metadata_keys, + metadata_values, + timeout_duration, + balance, + num_accounts + ); //Ensure they are indeed on-chain multisig account with required threshold - assert!(vector::all(&vec_addr, |elem| { multisig_account::num_signatures_required(*elem) == 2 }), 1); + assert!( + vector::all( + &vec_addr, + |elem| { multisig_account::num_signatures_required(*elem) == 2 } + ), + 1 + ); //Ensure the accounts are seeded with supplied balance - assert!(vector::all(&vec_addr, |elem| { coin::balance(*elem) == balance }), 2); + assert!( + vector::all( + &vec_addr, + |elem| { + coin::balance(*elem) == balance + } + ), + 2 + ); } - #[test(supra_framework = @0x1)] - fun test_create_vesting_without_staking_pools(supra_framework: &signer) { + fun test_create_vesting_without_staking_pools( + supra_framework: &signer + ) { // use supra_framework::supra_account::create_account; setup(); initialize_supra_coin(supra_framework); @@ -1161,12 +1342,15 @@ module supra_framework::genesis { let shareholders = vector[@0x121343, @0x121344]; create_account(supra_framework, admin_address, 0); create_account(supra_framework, withdrawal_address, 0); - vector::for_each_ref(&shareholders, |addr| { - let addr: address = *addr; - if (!account::exists_at(addr)) { - create_account(supra_framework, addr, 100 * ONE_SUPRA); - }; - }); + vector::for_each_ref( + &shareholders, + |addr| { + let addr: address = *addr; + if (!account::exists_at(addr)) { + create_account(supra_framework, addr, 100 * ONE_SUPRA); + }; + } + ); let cliff_period_in_seconds = 100; let period_duration_in_seconds = 200; let pool_config = VestingPoolsMap { @@ -1177,7 +1361,7 @@ module supra_framework::genesis { withdrawal_address: withdrawal_address, shareholders: shareholders, cliff_period_in_seconds: cliff_period_in_seconds, - period_duration_in_seconds: period_duration_in_seconds, + period_duration_in_seconds: period_duration_in_seconds }; let vesting_pool_map = vector[pool_config]; create_vesting_without_staking_pools(vesting_pool_map); diff --git a/aptos-move/framework/supra-framework/sources/leader_ban_registry.move b/aptos-move/framework/supra-framework/sources/leader_ban_registry.move index a04dcb4a46a..0a913126b15 100644 --- a/aptos-move/framework/supra-framework/sources/leader_ban_registry.move +++ b/aptos-move/framework/supra-framework/sources/leader_ban_registry.move @@ -173,8 +173,11 @@ module supra_framework::leader_ban_registry { #[view] /// Returns the number of consensus rounds remaining in the ban for the validator with the given /// pool address. Returns 0 if the validator is not banned (including if it is on probation). - public fun get_remaining_ban_duration(pool_address: address): u64 acquires BanRegistry, LatestView { - if (!exists(@supra_framework) || !exists(@supra_framework)) { + public fun get_remaining_ban_duration( + pool_address: address + ): u64 acquires BanRegistry, LatestView { + if (!exists(@supra_framework) + || !exists(@supra_framework)) { return 0 }; let ban_registry = borrow_global(@supra_framework); @@ -187,17 +190,20 @@ module supra_framework::leader_ban_registry { } ); if (found) { - remaining_ban_duration(vector::borrow(&ban_registry.bans, index), latest_view) - } else { - 0 - } + remaining_ban_duration( + vector::borrow(&ban_registry.bans, index), latest_view + ) + } else { 0 } } #[view] /// Returns the number of consensus rounds remaining in the probation period for the validator /// with the given pool address. Returns 0 if the validator is not on probation. - public fun get_remaining_probation_duration(pool_address: address): u64 acquires BanRegistry, LatestView { - if (!exists(@supra_framework) || !exists(@supra_framework)) { + public fun get_remaining_probation_duration( + pool_address: address + ): u64 acquires BanRegistry, LatestView { + if (!exists(@supra_framework) + || !exists(@supra_framework)) { return 0 }; let ban_registry = borrow_global(@supra_framework); @@ -211,10 +217,12 @@ module supra_framework::leader_ban_registry { ); if (found) { let probation_dur = get_probation_duration(); - remaining_probation_duration(vector::borrow(&ban_registry.bans, index), latest_view, probation_dur) - } else { - 0 - } + remaining_probation_duration( + vector::borrow(&ban_registry.bans, index), + latest_view, + probation_dur + ) + } else { 0 } } /// Add or update the ban registry as per block metadata @@ -228,94 +236,127 @@ module supra_framework::leader_ban_registry { if (!exists(@supra_framework)) { return }; let ban_registry = borrow_global_mut(@supra_framework); let latest_view = borrow_global_mut(@supra_framework); + + // Save the previous view before updating. Each failed proposer failed at a + // distinct round between the previous commit and the current commit, so we + // need this to reconstruct the actual round at which each ban was earned. + let previous_epoch = latest_view.epoch; + let previous_round = latest_view.round; + + // we expect that current_epoch == latest_view.epoch || current_epoch == latest_view.epoch + 1, + // but we don't assert this to be true here because it should be ensured by the consensus. + if (current_epoch < latest_view.epoch) { return }; + latest_view.epoch = current_epoch; latest_view.round = current_round; // ban the failed proposers - ban_failed_proposers(latest_view, failed_proposer_indices, ban_registry); + ban_failed_proposers( + current_epoch, previous_epoch, previous_round, + failed_proposer_indices, ban_registry + ); // remove expired bans reinstate_expired_bans(latest_view, ban_registry); } - /// Adds failed proposer indices to ban registry + /// Adds failed proposer indices to ban registry. Each failed proposer failed at a + /// consecutive round between the previous commit and the current commit. The actual + /// failed round is reconstructed from the previous view: + /// - Same epoch: failed rounds start at `previous_round + 1` + /// - Epoch boundary: failed rounds start at `0` (new epoch resets round to 0) fun ban_failed_proposers( - latest_view: &LatestView, + current_epoch: u64, + previous_epoch: u64, + previous_round: u64, failed_proposer_indices: vector, ban_registry: &mut BanRegistry ) { let initial_ban_duration = get_initial_ban_duration(); if (initial_ban_duration == 0) { return }; - vector::for_each( - failed_proposer_indices, - |failed_validator_index| { - let validator_pool_address_opt = - stake::get_pool_address_from_index(failed_validator_index); + // Compute the first failed round based on whether the epoch changed. + let first_failed_round = if (previous_epoch == current_epoch) { + previous_round + 1 + } else { + // Epoch boundary: the last block of the previous epoch was committed + // successfully, so failures start from round 0 of the new epoch. + 0 + }; - if (option::is_some(&validator_pool_address_opt)) { - let validator_pool_address = - option::extract(&mut validator_pool_address_opt); - let (is_banned, index) = vector::find( - &ban_registry.bans, - |v| { - let v: &ValidatorBans = v; - validator_pool_address == v.pool_address - } - ); - if (is_banned) { - // Validator is already in registry (either banned or on probation). - // Re-banning resets the ban period and increases consecutive count. - // If the consensus code is implemented correctly then the validator should - // not be re-banned whilst serving a ban as it should not be eligible for election - // when banned (i.e. this branch should only be taken when a validator is on probation). - let bans = vector::borrow_mut(&mut ban_registry.bans, index); - bans.consecutive_bans = bans.consecutive_bans + 1; - bans.active.round_earned = latest_view.round; - bans.active.epoch_earned = latest_view.epoch; - bans.active.rounds_served_in_previous_epochs = 0; - bans.active.on_probation = false; // Reset to banned state + let i = 0; + let len = vector::length(&failed_proposer_indices); + while (i < len) { + let failed_validator_index = *vector::borrow(&failed_proposer_indices, i); + let failed_round = first_failed_round + i; + + let validator_pool_address_opt = + stake::get_pool_address_from_index(failed_validator_index); + + if (option::is_some(&validator_pool_address_opt)) { + let validator_pool_address = + option::extract(&mut validator_pool_address_opt); + let (is_banned, index) = vector::find( + &ban_registry.bans, + |v| { + let v: &ValidatorBans = v; + validator_pool_address == v.pool_address + } + ); + if (is_banned) { + // Validator is already in registry (either banned or on probation). + // Re-banning resets the ban period and increases consecutive count. + // If the consensus code is implemented correctly then the validator should + // not be re-banned whilst serving a ban as it should not be eligible for election + // when banned (i.e. this branch should only be taken when a validator is on probation). + let bans = vector::borrow_mut(&mut ban_registry.bans, index); + bans.consecutive_bans = bans.consecutive_bans + 1; + bans.active.round_earned = failed_round; + bans.active.epoch_earned = current_epoch; + bans.active.rounds_served_in_previous_epochs = 0; + bans.active.on_probation = false; // Reset to banned state + + if (features::module_event_enabled()) { + event::emit( + Banned { + pool_address: validator_pool_address, + epoch: current_epoch, + round: failed_round, + consecutive_bans: bans.consecutive_bans + } + ); + } + } else { + let ban_registry_len = vector::length(&ban_registry.bans); + if (can_be_banned(ban_registry_len)) { + let ban_with_address = ValidatorBans { + active: ActiveBan { + epoch_earned: current_epoch, + round_earned: failed_round, + rounds_served_in_previous_epochs: 0, + on_probation: false + }, + consecutive_bans: 0, + pool_address: validator_pool_address + }; + vector::push_back(&mut ban_registry.bans, ban_with_address); if (features::module_event_enabled()) { event::emit( Banned { - pool_address: validator_pool_address, - epoch: latest_view.epoch, - round: latest_view.round, - consecutive_bans: bans.consecutive_bans + pool_address: ban_with_address.pool_address, + epoch: ban_with_address.active.epoch_earned, + round: ban_with_address.active.round_earned, + consecutive_bans: ban_with_address.consecutive_bans } ); } - } else { - let ban_registry_len = vector::length(&ban_registry.bans); - if (can_be_banned(ban_registry_len)) { - let ban_with_address = ValidatorBans { - active: ActiveBan { - epoch_earned: latest_view.epoch, - round_earned: latest_view.round, - rounds_served_in_previous_epochs: 0, - on_probation: false - }, - consecutive_bans: 0, - pool_address: validator_pool_address - }; - vector::push_back(&mut ban_registry.bans, ban_with_address); - - if (features::module_event_enabled()) { - event::emit( - Banned { - pool_address: ban_with_address.pool_address, - epoch: ban_with_address.active.epoch_earned, - round: ban_with_address.active.round_earned, - consecutive_bans: ban_with_address.consecutive_bans - } - ); - } - } - }; + } }; - } - ); + }; + + i = i + 1; + }; } /// Handles ban and probation expiry: @@ -337,7 +378,8 @@ module supra_framework::leader_ban_registry { |v| { let v: &ValidatorBans = v; if (v.active.on_probation - && remaining_probation_duration(v, latest_view, probation_duration) == 0) { + && remaining_probation_duration(v, latest_view, probation_duration) + == 0) { vector::push_back( &mut pool_addresses_for_full_reinstatement, v.pool_address ); @@ -377,8 +419,11 @@ module supra_framework::leader_ban_registry { &ban_registry.bans, |v| { let v: &ValidatorBans = v; - if (!v.active.on_probation && remaining_ban_duration(v, latest_view) == 0) { - vector::push_back(&mut pool_addresses_with_expired_bans, v.pool_address); + if (!v.active.on_probation + && remaining_ban_duration(v, latest_view) == 0) { + vector::push_back( + &mut pool_addresses_with_expired_bans, v.pool_address + ); } } ); @@ -445,7 +490,7 @@ module supra_framework::leader_ban_registry { }; } - /// Increments the total number of consensus rounds served by each banned validator and removes + /// Increments the total number of consensus rounds served by each banned validator and removes /// registry entries for validators that have left the validator set. /// /// The number of rounds in each epoch may vary due to network asynchrony, so we must record the @@ -467,10 +512,13 @@ module supra_framework::leader_ban_registry { let v: &mut ValidatorBans = v; if (vector::contains(&new_committee_pool_addresses, &v.pool_address)) { if (latest_view.epoch > v.active.epoch_earned) { - v.active.rounds_served_in_previous_epochs = v.active.rounds_served_in_previous_epochs - + latest_view.round; - } else if (latest_view.epoch == v.active.epoch_earned && latest_view.round > v.active.round_earned) { - v.active.rounds_served_in_previous_epochs = latest_view.round - v.active.round_earned; + v.active.rounds_served_in_previous_epochs = + v.active.rounds_served_in_previous_epochs + + latest_view.round; + } else if (latest_view.epoch == v.active.epoch_earned + && latest_view.round > v.active.round_earned) { + v.active.rounds_served_in_previous_epochs = + latest_view.round - v.active.round_earned; }; // else: The ban hasn't started yet. } else { @@ -512,12 +560,24 @@ module supra_framework::leader_ban_registry { ): u64 { let initial_ban_duration = get_initial_ban_duration(); let max_ban_duration = get_max_ban_duration(); - let duration = initial_ban_duration * pow(2, (ban.consecutive_bans as u64)); - let duration = min(duration, max_ban_duration); + // Guard against overflow: pow(2, n) overflows u64 when n >= 64, and the + // subsequent multiplication can overflow for smaller exponents. In both cases + // the uncapped result would exceed max_ban_duration, so we short-circuit. + let duration = if ((ban.consecutive_bans as u64) >= 64) { + max_ban_duration + } else { + let scale = pow(2, (ban.consecutive_bans as u64)); + if (initial_ban_duration > 0 && scale > max_ban_duration / initial_ban_duration) { + max_ban_duration + } else { + min(initial_ban_duration * scale, max_ban_duration) + } + }; let rounds_served = if (latest_view.epoch > ban.active.epoch_earned) { ban.active.rounds_served_in_previous_epochs + latest_view.round - } else if (latest_view.epoch == ban.active.epoch_earned && latest_view.round > ban.active.round_earned) { + } else if (latest_view.epoch == ban.active.epoch_earned + && latest_view.round > ban.active.round_earned) { latest_view.round - ban.active.round_earned } else { // The ban hasn't started yet. @@ -536,7 +596,8 @@ module supra_framework::leader_ban_registry { let rounds_served = if (latest_view.epoch > ban.active.epoch_earned) { ban.active.rounds_served_in_previous_epochs + latest_view.round - } else if (latest_view.epoch == ban.active.epoch_earned && latest_view.round > ban.active.round_earned) { + } else if (latest_view.epoch == ban.active.epoch_earned + && latest_view.round > ban.active.round_earned) { latest_view.round - ban.active.round_earned } else { // The ban hasn't started yet. diff --git a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move index 452f1e1292f..a692ee37b85 100644 --- a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move +++ b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move @@ -2901,7 +2901,7 @@ module supra_framework::pbo_delegation_pool { use supra_framework::timestamp::fast_forward_seconds; #[test_only] - const CONSENSUS_KEY_1: vector = x"c1bd3bcb387e4ee9a909f6304a1c9902661b0ecfb1e148c7892b210c7f353dfd"; + const CONSENSUS_KEY_1: vector = x"20ed28c35dc60a6c9629a7eb0a8dfa815c85c6cf2cedc9e43314cc26f02d741dc430b40c7239278dae17d68d06950d51ce61c2c16c032ceea62c9715611be7f577f48525ad610432bb5d13fa5826fc07c6650000000000000080090192000000000000007bb0b330cbdcec145d2671ef2532bb7a856a5155c66d7ad89ef2cb65e854fc08a5d43cd159a7abc77adfee05e764ec9abdfc133db8e8621398dcbe53db1069de56405f02a1347d5399502fe849b44cfa673ad95bdbf33b417f3f8e4fa854b87b4a60eff6426b277d6036ffc0cfcdd25c971d53c2b612ed1df66f33eff839c0064ac16d7e04650d13984b08b2f9e7bb240fe3ff920000000000000014a973f3c74f41cecc3c596a125835264d72803ba1ef9c9270fa2228e8f8442889f20ddfffc60bc073758c3fd13a29219ad4532c512d2a97c3a8421dedfa41e4d8d9ffaa3581049a65a64f57ea533ab831c88527bb3d7ce46b6eebd6fef6d3303cf7716455381c74da2bcbfc3e02de2e5fadb014ed4f7ecf6b62a4ce6c0db90b91f084512a18be5cb8892b1615a7bb7ef35d0192000000000000008c49908494889c8d07e0b6f0cb6871aaf7e97506476d0a63530ce06b58928225a4292dff8ffaccd4f217fd65c2afbac848ac5d5957d15aa83fb8d2f261d85ddf4f16feee49d07f274dd421f84862bd73634925c41d2b470066d751732cc4f9630e886df15e63f962959c8f765b48434b6124fe051c2a02ba91bd94a7d8fc3cf7240ffba508ff73d8bb95a8ba661fa59ed9c9b8030000000000000192000000000000007bb0b330cbdcec145d2671ef2532bb7a856a5155c66d7ad89ef2cb65e854fc08a5d43cd159a7abc77adfee05e764ec9abdfc133db8e8621398dcbe53db1069de56405f02a1347d5399502fe849b44cfa673ad95bdbf33b417f3f8e4fa854b87b4a60eff6426b277d6036ffc0cfcdd25c971d53c2b612ed1df66f33eff839c0064ac16d7e04650d13984b08b2f9e7bb240fe3ff920000000000000014a973f3c74f41cecc3c596a125835264d72803ba1ef9c9270fa2228e8f8442889f20ddfffc60bc073758c3fd13a29219ad4532c512d2a97c3a8421dedfa41e4d8d9ffaa3581049a65a64f57ea533ab831c88527bb3d7ce46b6eebd6fef6d3303cf7716455381c74da2bcbfc3e02de2e5fadb014ed4f7ecf6b62a4ce6c0db90b91f084512a18be5cb8892b1615a7bb7ef35d0192000000000000008c49908494889c8d07e0b6f0cb6871aaf7e97506476d0a63530ce06b58928225a4292dff8ffaccd4f217fd65c2afbac848ac5d5957d15aa83fb8d2f261d85ddf4f16feee49d07f274dd421f84862bd73634925c41d2b470066d751732cc4f9630e886df15e63f962959c8f765b48434b6124fe051c2a02ba91bd94a7d8fc3cf7240ffba508ff73d8bb95a8ba661fa59ed9c9b8030000000000000120000000000000000da685763a376d42546959f3e2d96ff46256cd3e539dd458b800c9d0daf4d981019c00000000000000a529edcfd13d9f5014b4e2fab134f833d266876a0a0fbcf3577ef87ced2656924e235d4a6f48169d0c6b1fd4d77b27f36b0eda1e78fb1691894e077333e7f278444a3e6de72685de03564bcf61466567e34c79279fcdccc42c2354e4c0a836e785f909656badb5950ebcf77a1ef9a3680818abe674760bc09888a446b96d9765779222970aaeb804abaa939c4225c474c2bc925be1d24648c6298d69208e695ae5888320393ef041be5f42d0f2eaac6036daffb8373eb80ad275fcc2b9"; #[test_only] const CONSENSUS_POP_1: vector = x"a9d6c1f1270f2d1454c89a83a4099f813a56dc7db55591d46aa4e6ccae7898b234029ba7052f18755e6fa5e6b73e235f14efc4e2eb402ca2b8f56bad69f965fc11b7b25eb1c95a06f83ddfd023eac4559b6582696cfea97b227f4ce5bdfdfed0"; diff --git a/aptos-move/framework/supra-framework/sources/randomness.move b/aptos-move/framework/supra-framework/sources/randomness.move index 4aa26724473..6cfa6e01e73 100644 --- a/aptos-move/framework/supra-framework/sources/randomness.move +++ b/aptos-move/framework/supra-framework/sources/randomness.move @@ -26,42 +26,46 @@ module supra_framework::randomness { /// `#[randomness]` annotation. Otherwise, malicious users can bias randomness result. const E_API_USE_IS_BIASIBLE: u64 = 1; - const MAX_U256: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + const MAX_U256: u256 = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; /// 32-byte randomness seed unique to every block. /// This resource is updated in every block prologue. struct PerBlockRandomness has drop, key { epoch: u64, round: u64, - seed: Option>, + seed: Option> } #[event] /// Event emitted every time a public randomness API in this module is called. - struct RandomnessGeneratedEvent has store, drop { - } + struct RandomnessGeneratedEvent has store, drop {} /// Called in genesis.move. /// Must be called in tests to initialize the `PerBlockRandomness` resource. public fun initialize(framework: &signer) { system_addresses::assert_supra_framework(framework); if (!exists(@supra_framework)) { - move_to(framework, PerBlockRandomness { - epoch: 0, - round: 0, - seed: option::none(), - }); + move_to( + framework, + PerBlockRandomness { epoch: 0, round: 0, seed: option::none() } + ); } } #[test_only] - public fun initialize_for_testing(framework: &signer) acquires PerBlockRandomness { + public fun initialize_for_testing(framework: &signer) acquires PerBlockRandomness { initialize(framework); set_seed(x"0000000000000000000000000000000000000000000000000000000000000000"); } /// Invoked in block prologues to update the block-level randomness seed. - public(friend) fun on_new_block(vm: &signer, epoch: u64, round: u64, seed_for_new_block: Option>) acquires PerBlockRandomness { + public(friend) fun on_new_block( + vm: &signer, + epoch: u64, + round: u64, + seed_for_new_block: Option> + ) acquires PerBlockRandomness { system_addresses::assert_vm(vm); if (exists(@supra_framework)) { let randomness = borrow_global_mut(@supra_framework); @@ -303,7 +307,7 @@ module supra_framework::randomness { let values = vector[]; - if(n == 0) { + if (n == 0) { return vector[] }; @@ -354,17 +358,26 @@ module supra_framework::randomness { let a_clone = a; let neg_b = m - b; let a_less = a < neg_b; - take_first(if (a_less) { a + b } else { a_clone - neg_b }, if (!a_less) { a_clone - neg_b } else { a + b }) + take_first( + if (a_less) { a + b } + else { + a_clone - neg_b + }, + if (!a_less) { + a_clone - neg_b + } else { a + b } + ) } - fun take_first(x: u256, _y: u256 ): u256 { x } + fun take_first(x: u256, _y: u256): u256 { + x + } #[verify_only] fun safe_add_mod_for_verification(a: u256, b: u256, m: u256): u256 { let neg_b = m - b; - if (a < neg_b) { - a + b - } else { + if (a < neg_b) { a + b } + else { a - neg_b } } @@ -385,13 +398,69 @@ module supra_framework::randomness { assert!(2 == safe_add_mod(4, 3, 5), 1); assert!(7 == safe_add_mod(3, 4, 9), 1); assert!(7 == safe_add_mod(4, 3, 9), 1); - assert!(0xfffffffffffffffffffffffffffffffffffffffffffffffe == safe_add_mod(0xfffffffffffffffffffffffffffffffffffffffffffffffd, 0x000000000000000000000000000000000000000000000001, 0xffffffffffffffffffffffffffffffffffffffffffffffff), 1); - assert!(0xfffffffffffffffffffffffffffffffffffffffffffffffe == safe_add_mod(0x000000000000000000000000000000000000000000000001, 0xfffffffffffffffffffffffffffffffffffffffffffffffd, 0xffffffffffffffffffffffffffffffffffffffffffffffff), 1); - assert!(0x000000000000000000000000000000000000000000000000 == safe_add_mod(0xfffffffffffffffffffffffffffffffffffffffffffffffd, 0x000000000000000000000000000000000000000000000002, 0xffffffffffffffffffffffffffffffffffffffffffffffff), 1); - assert!(0x000000000000000000000000000000000000000000000000 == safe_add_mod(0x000000000000000000000000000000000000000000000002, 0xfffffffffffffffffffffffffffffffffffffffffffffffd, 0xffffffffffffffffffffffffffffffffffffffffffffffff), 1); - assert!(0x000000000000000000000000000000000000000000000001 == safe_add_mod(0xfffffffffffffffffffffffffffffffffffffffffffffffd, 0x000000000000000000000000000000000000000000000003, 0xffffffffffffffffffffffffffffffffffffffffffffffff), 1); - assert!(0x000000000000000000000000000000000000000000000001 == safe_add_mod(0x000000000000000000000000000000000000000000000003, 0xfffffffffffffffffffffffffffffffffffffffffffffffd, 0xffffffffffffffffffffffffffffffffffffffffffffffff), 1); - assert!(0xfffffffffffffffffffffffffffffffffffffffffffffffd == safe_add_mod(0xfffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffff), 1); + assert!( + 0xfffffffffffffffffffffffffffffffffffffffffffffffe + == safe_add_mod( + 0xfffffffffffffffffffffffffffffffffffffffffffffffd, + 0x000000000000000000000000000000000000000000000001, + 0xffffffffffffffffffffffffffffffffffffffffffffffff + ), + 1 + ); + assert!( + 0xfffffffffffffffffffffffffffffffffffffffffffffffe + == safe_add_mod( + 0x000000000000000000000000000000000000000000000001, + 0xfffffffffffffffffffffffffffffffffffffffffffffffd, + 0xffffffffffffffffffffffffffffffffffffffffffffffff + ), + 1 + ); + assert!( + 0x000000000000000000000000000000000000000000000000 + == safe_add_mod( + 0xfffffffffffffffffffffffffffffffffffffffffffffffd, + 0x000000000000000000000000000000000000000000000002, + 0xffffffffffffffffffffffffffffffffffffffffffffffff + ), + 1 + ); + assert!( + 0x000000000000000000000000000000000000000000000000 + == safe_add_mod( + 0x000000000000000000000000000000000000000000000002, + 0xfffffffffffffffffffffffffffffffffffffffffffffffd, + 0xffffffffffffffffffffffffffffffffffffffffffffffff + ), + 1 + ); + assert!( + 0x000000000000000000000000000000000000000000000001 + == safe_add_mod( + 0xfffffffffffffffffffffffffffffffffffffffffffffffd, + 0x000000000000000000000000000000000000000000000003, + 0xffffffffffffffffffffffffffffffffffffffffffffffff + ), + 1 + ); + assert!( + 0x000000000000000000000000000000000000000000000001 + == safe_add_mod( + 0x000000000000000000000000000000000000000000000003, + 0xfffffffffffffffffffffffffffffffffffffffffffffffd, + 0xffffffffffffffffffffffffffffffffffffffffffffffff + ), + 1 + ); + assert!( + 0xfffffffffffffffffffffffffffffffffffffffffffffffd + == safe_add_mod( + 0xfffffffffffffffffffffffffffffffffffffffffffffffe, + 0xfffffffffffffffffffffffffffffffffffffffffffffffe, + 0xffffffffffffffffffffffffffffffffffffffffffffffff + ), + 1 + ); } #[test(fx = @supra_framework)] @@ -524,7 +593,7 @@ module supra_framework::randomness { for (i in 0..n) { let bit = vector::borrow(&present, i); - if(*bit == false) { + if (*bit == false) { return false }; }; @@ -559,12 +628,12 @@ module supra_framework::randomness { let permutations = table_with_length::new, bool>(); // This loop will not exit until all permutations are created - while(table_with_length::length(&permutations) < num_permutations) { + while (table_with_length::length(&permutations) < num_permutations) { let v = permutation(size); assert!(vector::length(&v) == size, 0); assert!(is_permutation(&v), 0); - if(table_with_length::contains(&permutations, v) == false) { + if (table_with_length::contains(&permutations, v) == false) { table_with_length::add(&mut permutations, v, true); } }; diff --git a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move index 8386cf18dd9..00db1a4cf5d 100644 --- a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move +++ b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move @@ -1,10 +1,17 @@ /// Reconfiguration with DKG helper functions. module supra_framework::reconfiguration_with_dkg { + use std::dkg_committee::{ + new_dkg_committee_from_validator_consensus_info, + new_receiver_committee + }; use std::features; use std::option; + use std::vector; use supra_framework::automation_registry; + use supra_framework::randomness; use supra_framework::consensus_config; use supra_framework::dkg; + use supra_framework::dkg_config; use supra_framework::execution_config; use supra_framework::gas_schedule; use supra_framework::jwk_consensus_config; @@ -36,14 +43,48 @@ module supra_framework::reconfiguration_with_dkg { }; reconfiguration_state::on_reconfig_start(); let cur_epoch = reconfiguration::current_epoch(); + let randomness_seed = randomness::bytes(32); + + // Get DKG configuration (dealer threshold type and receiver committee configs) + let config = dkg_config::current(); + let receiver_configs = dkg_config::get_receiver_committee_configs(&config); + + // Build receiver committees from config + let receiver_committees = vector[]; + let i = 0; + let len = vector::length(&receiver_configs); + while (i < len) { + let rc = vector::borrow(&receiver_configs, i); + vector::push_back( + &mut receiver_committees, + new_receiver_committee( + dkg_config::get_is_resharing(rc), + dkg_config::get_dkg_threshold_type(rc), + new_dkg_committee_from_validator_consensus_info( + stake::next_epoch_validator_consensus_infos_for_dkg(), + dkg_config::get_committee_threshold_type(rc) + ) + ) + ); + i = i + 1; + }; + + // DKG for configured receiver committees dkg::start( cur_epoch, - randomness_config::current(), - stake::cur_validator_consensus_infos(), - stake::next_validator_consensus_infos() + randomness_seed, + new_dkg_committee_from_validator_consensus_info( + stake::cur_validator_consensus_infos(), + dkg_config::get_dealer_committee_threshold_type(&config) + ), + receiver_committees ); } + fun set_dkg_meta(dkg_meta: vector) { + dkg::set_dkg_meta(dkg_meta); + } + /// Clear incomplete DKG session, if it exists. /// Apply buffered on-chain configs (except for ValidatorSet, which is done inside `reconfiguration::reconfigure()`). /// Re-enable validator set changes. @@ -66,6 +107,7 @@ module supra_framework::reconfiguration_with_dkg { randomness_config::on_new_epoch(framework); randomness_api_v0_config::on_new_epoch(framework); evm_genesis_config::on_new_epoch(framework); + dkg_config::on_new_epoch(framework); reconfiguration::reconfigure(); } diff --git a/aptos-move/framework/supra-framework/sources/stake.move b/aptos-move/framework/supra-framework/sources/stake.move index 5717ce4b270..68d342c61b9 100644 --- a/aptos-move/framework/supra-framework/sources/stake.move +++ b/aptos-move/framework/supra-framework/sources/stake.move @@ -26,6 +26,7 @@ module supra_framework::stake { use aptos_std::ed25519; use aptos_std::math64::min; use aptos_std::table::{Self, Table}; + use supra_std::validator_public_keys; use supra_framework::supra_coin::SupraCoin; use supra_framework::account; use supra_framework::coin::{Self, Coin, MintCapability}; @@ -34,12 +35,14 @@ module supra_framework::stake { use supra_framework::system_addresses; use supra_framework::staking_config::{Self, StakingConfig, StakingRewardsConfig}; use supra_framework::chain_status; + use std::dkg_committee; friend supra_framework::block; friend supra_framework::genesis; friend supra_framework::reconfiguration; friend supra_framework::reconfiguration_with_dkg; friend supra_framework::transaction_fee; + friend supra_framework::dkg; friend supra_framework::leader_ban_registry; #[test_only] @@ -85,6 +88,8 @@ module supra_framework::stake { const EFEES_TABLE_ALREADY_EXISTS: u64 = 19; /// Validator set change temporarily disabled because of in-progress reconfiguration. const ERECONFIGURATION_IN_PROGRESS: u64 = 20; + /// Invalid DKG public key shares. + const EDKG_INVALID_PK_SHARES: u64 = 21; /// Validator status enum. We can switch to proper enum later once Move supports it. const VALIDATOR_STATUS_PENDING_ACTIVE: u64 = 1; @@ -105,7 +110,7 @@ module supra_framework::stake { /// Having this be separate from the signer for the account that the validator resources are hosted at allows /// modules to have control over a validator. struct OwnerCapability has key, store { - pool_address: address, + pool_address: address } /// Each validator has a separate StakePool resource and can provide a stake. @@ -145,13 +150,14 @@ module supra_framework::stake { add_stake_events: EventHandle, reactivate_stake_events: EventHandle, rotate_consensus_key_events: EventHandle, - update_network_and_fullnode_addresses_events: EventHandle, + update_network_and_fullnode_addresses_events: EventHandle< + UpdateNetworkAndFullnodeAddressesEvent>, increase_lockup_events: EventHandle, join_validator_set_events: EventHandle, distribute_rewards_events: EventHandle, unlock_stake_events: EventHandle, withdraw_stake_events: EventHandle, - leave_validator_set_events: EventHandle, + leave_validator_set_events: EventHandle } /// Validator info stored in validator address. @@ -161,14 +167,14 @@ module supra_framework::stake { // to make it compatible with previous definition, remove later fullnode_addresses: vector, // Index in the active set if the validator corresponding to this stake pool is active. - validator_index: u64, + validator_index: u64 } /// Consensus information per validator, stored in ValidatorSet. struct ValidatorInfo has copy, store, drop { addr: address, voting_power: u64, - config: ValidatorConfig, + config: ValidatorConfig } /// Full ValidatorSet, stored in @supra_framework. @@ -186,79 +192,79 @@ module supra_framework::stake { // Current total voting power. total_voting_power: u128, // Total voting power waiting to join in the next epoch. - total_joining_power: u128, + total_joining_power: u128 } /// SupraCoin capabilities, set during genesis and stored in @CoreResource account. /// This allows the Stake module to mint rewards to stakers. struct SupraCoinCapabilities has key { - mint_cap: MintCapability, + mint_cap: MintCapability } struct IndividualValidatorPerformance has store, drop { successful_proposals: u64, - failed_proposals: u64, + failed_proposals: u64 } struct ValidatorPerformance has key { - validators: vector, + validators: vector } struct RegisterValidatorCandidateEvent has drop, store { - pool_address: address, + pool_address: address } #[event] struct RegisterValidatorCandidate has drop, store { - pool_address: address, + pool_address: address } struct SetOperatorEvent has drop, store { pool_address: address, old_operator: address, - new_operator: address, + new_operator: address } #[event] struct SetOperator has drop, store { pool_address: address, old_operator: address, - new_operator: address, + new_operator: address } struct AddStakeEvent has drop, store { pool_address: address, - amount_added: u64, + amount_added: u64 } #[event] struct AddStake has drop, store { pool_address: address, - amount_added: u64, + amount_added: u64 } struct ReactivateStakeEvent has drop, store { pool_address: address, - amount: u64, + amount: u64 } #[event] struct ReactivateStake has drop, store { pool_address: address, - amount: u64, + amount: u64 } struct RotateConsensusKeyEvent has drop, store { pool_address: address, old_consensus_pubkey: vector, - new_consensus_pubkey: vector, + new_consensus_pubkey: vector } #[event] struct RotateConsensusKey has drop, store { pool_address: address, old_consensus_pubkey: vector, - new_consensus_pubkey: vector, + new_consensus_pubkey: vector } struct UpdateNetworkAndFullnodeAddressesEvent has drop, store { @@ -266,7 +272,7 @@ module supra_framework::stake { old_network_addresses: vector, new_network_addresses: vector, old_fullnode_addresses: vector, - new_fullnode_addresses: vector, + new_fullnode_addresses: vector } #[event] @@ -275,82 +281,84 @@ module supra_framework::stake { old_network_addresses: vector, new_network_addresses: vector, old_fullnode_addresses: vector, - new_fullnode_addresses: vector, + new_fullnode_addresses: vector } struct IncreaseLockupEvent has drop, store { pool_address: address, old_locked_until_secs: u64, - new_locked_until_secs: u64, + new_locked_until_secs: u64 } #[event] struct IncreaseLockup has drop, store { pool_address: address, old_locked_until_secs: u64, - new_locked_until_secs: u64, + new_locked_until_secs: u64 } struct JoinValidatorSetEvent has drop, store { - pool_address: address, + pool_address: address } #[event] struct JoinValidatorSet has drop, store { - pool_address: address, + pool_address: address } struct DistributeRewardsEvent has drop, store { pool_address: address, - rewards_amount: u64, + rewards_amount: u64 } #[event] struct DistributeRewards has drop, store { pool_address: address, - rewards_amount: u64, + rewards_amount: u64 } struct UnlockStakeEvent has drop, store { pool_address: address, - amount_unlocked: u64, + amount_unlocked: u64 } #[event] struct UnlockStake has drop, store { pool_address: address, - amount_unlocked: u64, + amount_unlocked: u64 } struct WithdrawStakeEvent has drop, store { pool_address: address, - amount_withdrawn: u64, + amount_withdrawn: u64 } #[event] struct WithdrawStake has drop, store { pool_address: address, - amount_withdrawn: u64, + amount_withdrawn: u64 } struct LeaveValidatorSetEvent has drop, store { - pool_address: address, + pool_address: address } #[event] struct LeaveValidatorSet has drop, store { - pool_address: address, + pool_address: address } /// Stores transaction fees assigned to validators. All fees are distributed to validators /// at the end of the epoch. struct ValidatorFees has key { - fees_table: Table>, + fees_table: Table> } /// Initializes the resource storing information about collected transaction fees per validator. /// Used by `transaction_fee.move` to initialize fee collection and distribution. - public(friend) fun initialize_validator_fees(supra_framework: &signer) { + public(friend) fun initialize_validator_fees( + supra_framework: &signer + ) { system_addresses::assert_supra_framework(supra_framework); assert!( !exists(@supra_framework), @@ -360,8 +368,11 @@ module supra_framework::stake { } /// Stores the transaction fee collected to the specified validator address. - public(friend) fun add_transaction_fee(validator_addr: address, fee: Coin) acquires ValidatorFees { - let fees_table = &mut borrow_global_mut(@supra_framework).fees_table; + public(friend) fun add_transaction_fee( + validator_addr: address, fee: Coin + ) acquires ValidatorFees { + let fees_table = + &mut borrow_global_mut(@supra_framework).fees_table; if (table::contains(fees_table, validator_addr)) { let collected_fee = table::borrow_mut(fees_table, validator_addr); coin::merge(collected_fee, fee); @@ -384,9 +395,8 @@ module supra_framework::stake { public fun get_remaining_lockup_secs(pool_address: address): u64 acquires StakePool { assert_stake_pool_exists(pool_address); let lockup_time = borrow_global(pool_address).locked_until_secs; - if (lockup_time <= timestamp::now_seconds()) { - 0 - } else { + if (lockup_time <= timestamp::now_seconds()) { 0 } + else { lockup_time - timestamp::now_seconds() } } @@ -401,7 +411,7 @@ module supra_framework::stake { coin::value(&stake_pool.active), coin::value(&stake_pool.inactive), coin::value(&stake_pool.pending_active), - coin::value(&stake_pool.pending_inactive), + coin::value(&stake_pool.pending_inactive) ) } @@ -409,11 +419,17 @@ module supra_framework::stake { /// Returns the validator's state. public fun get_validator_state(pool_address: address): u64 acquires ValidatorSet { let validator_set = borrow_global(@supra_framework); - if (option::is_some(&find_validator(&validator_set.pending_active, pool_address))) { + if (option::is_some( + &find_validator(&validator_set.pending_active, pool_address) + )) { VALIDATOR_STATUS_PENDING_ACTIVE - } else if (option::is_some(&find_validator(&validator_set.active_validators, pool_address))) { + } else if (option::is_some( + &find_validator(&validator_set.active_validators, pool_address) + )) { VALIDATOR_STATUS_ACTIVE - } else if (option::is_some(&find_validator(&validator_set.pending_inactive, pool_address))) { + } else if (option::is_some( + &find_validator(&validator_set.pending_inactive, pool_address) + )) { VALIDATOR_STATUS_PENDING_INACTIVE } else { VALIDATOR_STATUS_INACTIVE @@ -423,17 +439,20 @@ module supra_framework::stake { #[view] /// Return the voting power of the validator in the current epoch. /// This is the same as the validator's total active and pending_inactive stake. - public fun get_current_epoch_voting_power(pool_address: address): u64 acquires StakePool, ValidatorSet { + public fun get_current_epoch_voting_power( + pool_address: address + ): u64 acquires StakePool, ValidatorSet { assert_stake_pool_exists(pool_address); let validator_state = get_validator_state(pool_address); // Both active and pending inactive validators can still vote in the current epoch. - if (validator_state == VALIDATOR_STATUS_ACTIVE || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE) { - let active_stake = coin::value(&borrow_global(pool_address).active); - let pending_inactive_stake = coin::value(&borrow_global(pool_address).pending_inactive); + if (validator_state == VALIDATOR_STATUS_ACTIVE + || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE) { + let active_stake = + coin::value(&borrow_global(pool_address).active); + let pending_inactive_stake = + coin::value(&borrow_global(pool_address).pending_inactive); active_stake + pending_inactive_stake - } else { - 0 - } + } else { 0 } } #[view] @@ -464,10 +483,18 @@ module supra_framework::stake { #[view] /// Return the number of successful and failed proposals for the proposal at the given validator index. - public fun get_current_epoch_proposal_counts(validator_index: u64): (u64, u64) acquires ValidatorPerformance { - let validator_performances = &borrow_global(@supra_framework).validators; - let validator_performance = vector::borrow(validator_performances, validator_index); - (validator_performance.successful_proposals, validator_performance.failed_proposals) + public fun get_current_epoch_proposal_counts( + validator_index: u64 + ): (u64, u64) acquires ValidatorPerformance { + let validator_performances = + &borrow_global(@supra_framework).validators; + let validator_performance = vector::borrow( + validator_performances, validator_index + ); + ( + validator_performance.successful_proposals, + validator_performance.failed_proposals + ) } #[view] @@ -477,7 +504,11 @@ module supra_framework::stake { ): (vector, vector, vector) acquires ValidatorConfig { assert_stake_pool_exists(pool_address); let validator_config = borrow_global(pool_address); - (validator_config.consensus_pubkey, validator_config.network_addresses, validator_config.fullnode_addresses) + ( + validator_config.consensus_pubkey, + validator_config.network_addresses, + validator_config.fullnode_addresses + ) } #[view] @@ -489,48 +520,57 @@ module supra_framework::stake { public(friend) fun initialize(supra_framework: &signer) { system_addresses::assert_supra_framework(supra_framework); - move_to(supra_framework, ValidatorSet { - consensus_scheme: 0, - active_validators: vector::empty(), - pending_active: vector::empty(), - pending_inactive: vector::empty(), - total_voting_power: 0, - total_joining_power: 0, - }); + move_to( + supra_framework, + ValidatorSet { + consensus_scheme: 0, + active_validators: vector::empty(), + pending_active: vector::empty(), + pending_inactive: vector::empty(), + total_voting_power: 0, + total_joining_power: 0 + } + ); - move_to(supra_framework, ValidatorPerformance { - validators: vector::empty(), - }); + move_to(supra_framework, ValidatorPerformance { validators: vector::empty() }); } /// This is only called during Genesis, which is where MintCapability can be created. /// Beyond genesis, no one can create SupraCoin mint/burn capabilities. - public(friend) fun store_supra_coin_mint_cap(supra_framework: &signer, mint_cap: MintCapability) { + public(friend) fun store_supra_coin_mint_cap( + supra_framework: &signer, mint_cap: MintCapability + ) { system_addresses::assert_supra_framework(supra_framework); move_to(supra_framework, SupraCoinCapabilities { mint_cap }) } /// To get validator pool address from validator index - public(friend) fun get_pool_address_from_index(index: u64) : Option
- acquires ValidatorSet - { + public(friend) fun get_pool_address_from_index( + index: u64 + ): Option
acquires ValidatorSet { if (exists(@supra_framework)) { let validator_set = borrow_global(@supra_framework); // it can happen that some validator may added a leave request in between // this can change the order of indexes in active validator // so need to iterate through all until find pool address in active and pending_active - let (is_index_exist, i) = vector::find(&validator_set.active_validators, |v| { - let v: &ValidatorInfo = v; - v.config.validator_index == index - }); + let (is_index_exist, i) = vector::find( + &validator_set.active_validators, + |v| { + let v: &ValidatorInfo = v; + v.config.validator_index == index + } + ); if (is_index_exist) { let v_info = vector::borrow(&validator_set.active_validators, i); return option::some(v_info.addr) }; - let (is_index_exist, i) = vector::find(&validator_set.pending_inactive, |v| { - let v: &ValidatorInfo = v; - v.config.validator_index == index - }); + let (is_index_exist, i) = vector::find( + &validator_set.pending_inactive, + |v| { + let v: &ValidatorInfo = v; + v.config.validator_index == index + } + ); if (is_index_exist) { let v_info = vector::borrow(&validator_set.pending_inactive, i); return option::some(v_info.addr) @@ -540,40 +580,42 @@ module supra_framework::stake { } /// Returns committee size - public(friend) fun get_committee_size() : u64 - acquires ValidatorSet - { - let commitee_size= 0; + public(friend) fun get_committee_size(): u64 acquires ValidatorSet { + let commitee_size = 0; if (exists(@supra_framework)) { let validator_set = borrow_global(@supra_framework); - commitee_size = vector::length(&validator_set.active_validators) + vector::length(&validator_set.pending_inactive); + commitee_size = vector::length(&validator_set.active_validators) + + vector::length(&validator_set.pending_inactive); }; commitee_size } /// Returns pool addresses of current committee including pending inactive - public(friend) fun get_committee_pool_addresses() : vector
- acquires ValidatorSet - { - let pool_addresses= vector::empty(); + public(friend) fun get_committee_pool_addresses(): vector
acquires ValidatorSet { + let pool_addresses = vector::empty(); if (exists(@supra_framework)) { let validator_set = borrow_global(@supra_framework); - vector::for_each_ref(&validator_set.active_validators, |validator_info| { - let validator_info: &ValidatorInfo = validator_info; - vector::push_back(&mut pool_addresses, validator_info.addr); - }); - vector::for_each_ref(&validator_set.pending_inactive, |validator_info| { - let validator_info: &ValidatorInfo = validator_info; - vector::push_back(&mut pool_addresses, validator_info.addr); - }); + vector::for_each_ref( + &validator_set.active_validators, + |validator_info| { + let validator_info: &ValidatorInfo = validator_info; + vector::push_back(&mut pool_addresses, validator_info.addr); + } + ); + vector::for_each_ref( + &validator_set.pending_inactive, + |validator_info| { + let validator_info: &ValidatorInfo = validator_info; + vector::push_back(&mut pool_addresses, validator_info.addr); + } + ); }; pool_addresses } /// Allow on chain governance to remove validators from the validator set. public fun remove_validators( - supra_framework: &signer, - validators: &vector
, + supra_framework: &signer, validators: &vector
) acquires ValidatorSet { assert_reconfig_not_in_progress(); system_addresses::assert_supra_framework(supra_framework); @@ -594,14 +636,17 @@ module supra_framework::stake { invariant spec_validator_indices_are_valid(active_validators); invariant spec_validators_are_initialized(pending_inactive); invariant spec_validator_indices_are_valid(pending_inactive); - invariant ghost_active_num + ghost_pending_inactive_num == len(active_validators) + len(pending_inactive); + invariant ghost_active_num + ghost_pending_inactive_num + == len(active_validators) + len(pending_inactive); }; i < len_validators }) { let validator = *vector::borrow(validators, i); let validator_index = find_validator(active_validators, validator); if (option::is_some(&validator_index)) { - let validator_info = vector::swap_remove(active_validators, *option::borrow(&validator_index)); + let validator_info = vector::swap_remove( + active_validators, *option::borrow(&validator_index) + ); vector::push_back(pending_inactive, validator_info); spec { update ghost_active_num = ghost_active_num - 1; @@ -620,15 +665,18 @@ module supra_framework::stake { owner: &signer, initial_stake_amount: u64, operator: address, - voter: address, + voter: address ) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet { initialize_owner(owner); - move_to(owner, ValidatorConfig { - consensus_pubkey: vector::empty(), - network_addresses: vector::empty(), - fullnode_addresses: vector::empty(), - validator_index: 0, - }); + move_to( + owner, + ValidatorConfig { + consensus_pubkey: vector::empty(), + network_addresses: vector::empty(), + fullnode_addresses: vector::empty(), + validator_index: 0 + } + ); if (initial_stake_amount != 0) { add_stake(owner, initial_stake_amount); @@ -648,50 +696,79 @@ module supra_framework::stake { account: &signer, consensus_pubkey: vector, network_addresses: vector, - fullnode_addresses: vector, + fullnode_addresses: vector ) acquires AllowedValidators { + // Checks the public key is valid to prevent rogue-key attacks. - let valid_public_key = ed25519::new_validated_public_key_from_bytes(consensus_pubkey); - assert!(option::is_some(&valid_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY)); + if (std::features::supra_validator_identity_v2_enabled()) { + let _valid_public_key = + validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey); + } else { + let valid_public_key = + ed25519::new_validated_public_key_from_bytes(consensus_pubkey); + assert!( + option::is_some(&valid_public_key), + error::invalid_argument(EINVALID_PUBLIC_KEY) + ); + }; initialize_owner(account); - move_to(account, ValidatorConfig { - consensus_pubkey, - network_addresses, - fullnode_addresses, - validator_index: 0, - }); + move_to( + account, + ValidatorConfig { + consensus_pubkey, + network_addresses, + fullnode_addresses, + validator_index: 0 + } + ); } fun initialize_owner(owner: &signer) acquires AllowedValidators { let owner_address = signer::address_of(owner); assert!(is_allowed(owner_address), error::not_found(EINELIGIBLE_VALIDATOR)); - assert!(!stake_pool_exists(owner_address), error::already_exists(EALREADY_REGISTERED)); - - move_to(owner, StakePool { - active: coin::zero(), - pending_active: coin::zero(), - pending_inactive: coin::zero(), - inactive: coin::zero(), - locked_until_secs: 0, - operator_address: owner_address, - delegated_voter: owner_address, - // Events. - initialize_validator_events: account::new_event_handle(owner), - set_operator_events: account::new_event_handle(owner), - add_stake_events: account::new_event_handle(owner), - reactivate_stake_events: account::new_event_handle(owner), - rotate_consensus_key_events: account::new_event_handle(owner), - update_network_and_fullnode_addresses_events: account::new_event_handle( - owner - ), - increase_lockup_events: account::new_event_handle(owner), - join_validator_set_events: account::new_event_handle(owner), - distribute_rewards_events: account::new_event_handle(owner), - unlock_stake_events: account::new_event_handle(owner), - withdraw_stake_events: account::new_event_handle(owner), - leave_validator_set_events: account::new_event_handle(owner), - }); + assert!( + !stake_pool_exists(owner_address), + error::already_exists(EALREADY_REGISTERED) + ); + + move_to( + owner, + StakePool { + active: coin::zero(), + pending_active: coin::zero(), + pending_inactive: coin::zero(), + inactive: coin::zero(), + locked_until_secs: 0, + operator_address: owner_address, + delegated_voter: owner_address, + // Events. + initialize_validator_events: account::new_event_handle< + RegisterValidatorCandidateEvent>(owner), + set_operator_events: account::new_event_handle(owner), + add_stake_events: account::new_event_handle(owner), + reactivate_stake_events: account::new_event_handle( + owner + ), + rotate_consensus_key_events: account::new_event_handle< + RotateConsensusKeyEvent>(owner), + update_network_and_fullnode_addresses_events: account::new_event_handle< + UpdateNetworkAndFullnodeAddressesEvent>(owner), + increase_lockup_events: account::new_event_handle( + owner + ), + join_validator_set_events: account::new_event_handle( + owner + ), + distribute_rewards_events: account::new_event_handle( + owner + ), + unlock_stake_events: account::new_event_handle(owner), + withdraw_stake_events: account::new_event_handle(owner), + leave_validator_set_events: account::new_event_handle< + LeaveValidatorSetEvent>(owner) + } + ); move_to(owner, OwnerCapability { pool_address: owner_address }); } @@ -705,8 +782,13 @@ module supra_framework::stake { /// Deposit `owner_cap` into `account`. This requires `account` to not already have ownership of another /// staking pool. - public fun deposit_owner_cap(owner: &signer, owner_cap: OwnerCapability) { - assert!(!exists(signer::address_of(owner)), error::not_found(EOWNER_CAP_ALREADY_EXISTS)); + public fun deposit_owner_cap( + owner: &signer, owner_cap: OwnerCapability + ) { + assert!( + !exists(signer::address_of(owner)), + error::not_found(EOWNER_CAP_ALREADY_EXISTS) + ); move_to(owner, owner_cap); } @@ -716,7 +798,9 @@ module supra_framework::stake { } /// Allows an owner to change the operator of the stake pool. - public entry fun set_operator(owner: &signer, new_operator: address) acquires OwnerCapability, StakePool { + public entry fun set_operator( + owner: &signer, new_operator: address + ) acquires OwnerCapability, StakePool { let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -724,7 +808,9 @@ module supra_framework::stake { } /// Allows an account with ownership capability to change the operator of the stake pool. - public fun set_operator_with_cap(owner_cap: &OwnerCapability, new_operator: address) acquires StakePool { + public fun set_operator_with_cap( + owner_cap: &OwnerCapability, new_operator: address + ) acquires StakePool { let pool_address = owner_cap.pool_address; assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut(pool_address); @@ -732,27 +818,19 @@ module supra_framework::stake { stake_pool.operator_address = new_operator; if (std::features::module_event_migration_enabled()) { - event::emit( - SetOperator { - pool_address, - old_operator, - new_operator, - }, - ); + event::emit(SetOperator { pool_address, old_operator, new_operator }); }; event::emit_event( &mut stake_pool.set_operator_events, - SetOperatorEvent { - pool_address, - old_operator, - new_operator, - }, + SetOperatorEvent { pool_address, old_operator, new_operator } ); } /// Allows an owner to change the delegated voter of the stake pool. - public entry fun set_delegated_voter(owner: &signer, new_voter: address) acquires OwnerCapability, StakePool { + public entry fun set_delegated_voter( + owner: &signer, new_voter: address + ) acquires OwnerCapability, StakePool { let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -760,7 +838,9 @@ module supra_framework::stake { } /// Allows an owner to change the delegated voter of the stake pool. - public fun set_delegated_voter_with_cap(owner_cap: &OwnerCapability, new_voter: address) acquires StakePool { + public fun set_delegated_voter_with_cap( + owner_cap: &OwnerCapability, new_voter: address + ) acquires StakePool { let pool_address = owner_cap.pool_address; assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut(pool_address); @@ -768,7 +848,9 @@ module supra_framework::stake { } /// Add `amount` of coins from the `account` owning the StakePool. - public entry fun add_stake(owner: &signer, amount: u64) acquires OwnerCapability, StakePool, ValidatorSet { + public entry fun add_stake( + owner: &signer, amount: u64 + ) acquires OwnerCapability, StakePool, ValidatorSet { let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); let ownership_cap = borrow_global(owner_address); @@ -776,7 +858,9 @@ module supra_framework::stake { } /// Add `coins` into `pool_address`. this requires the corresponding `owner_cap` to be passed in. - public fun add_stake_with_cap(owner_cap: &OwnerCapability, coins: Coin) acquires StakePool, ValidatorSet { + public fun add_stake_with_cap( + owner_cap: &OwnerCapability, coins: Coin + ) acquires StakePool, ValidatorSet { assert_reconfig_not_in_progress(); let pool_address = owner_cap.pool_address; assert_stake_pool_exists(pool_address); @@ -792,8 +876,11 @@ module supra_framework::stake { // Inactive validator's total stake will be tracked when they join the validator set. let validator_set = borrow_global_mut(@supra_framework); // Search directly rather using get_validator_state to save on unnecessary loops. - if (option::is_some(&find_validator(&validator_set.active_validators, pool_address)) || - option::is_some(&find_validator(&validator_set.pending_active, pool_address))) { + if (option::is_some( + &find_validator(&validator_set.active_validators, pool_address) + ) || option::is_some( + &find_validator(&validator_set.pending_active, pool_address) + )) { update_voting_power_increase(amount); }; @@ -806,24 +893,19 @@ module supra_framework::stake { coin::merge(&mut stake_pool.active, coins); }; - let (_, maximum_stake) = staking_config::get_required_stake(&staking_config::get()); + let (_, maximum_stake) = + staking_config::get_required_stake(&staking_config::get()); let voting_power = get_next_epoch_voting_power(stake_pool); - assert!(voting_power <= maximum_stake, error::invalid_argument(ESTAKE_EXCEEDS_MAX)); + assert!( + voting_power <= maximum_stake, error::invalid_argument(ESTAKE_EXCEEDS_MAX) + ); if (std::features::module_event_migration_enabled()) { - event::emit( - AddStake { - pool_address, - amount_added: amount, - }, - ); + event::emit(AddStake { pool_address, amount_added: amount }); }; event::emit_event( &mut stake_pool.add_stake_events, - AddStakeEvent { - pool_address, - amount_added: amount, - }, + AddStakeEvent { pool_address, amount_added: amount } ); } @@ -836,7 +918,9 @@ module supra_framework::stake { reactivate_stake_with_cap(ownership_cap, amount); } - public fun reactivate_stake_with_cap(owner_cap: &OwnerCapability, amount: u64) acquires StakePool { + public fun reactivate_stake_with_cap( + owner_cap: &OwnerCapability, amount: u64 + ) acquires StakePool { assert_reconfig_not_in_progress(); let pool_address = owner_cap.pool_address; assert_stake_pool_exists(pool_address); @@ -853,19 +937,11 @@ module supra_framework::stake { coin::merge(&mut stake_pool.active, reactivated_coins); if (std::features::module_event_migration_enabled()) { - event::emit( - ReactivateStake { - pool_address, - amount, - }, - ); + event::emit(ReactivateStake { pool_address, amount }); }; event::emit_event( &mut stake_pool.reactivate_stake_events, - ReactivateStakeEvent { - pool_address, - amount, - }, + ReactivateStakeEvent { pool_address, amount } ); } @@ -873,24 +949,52 @@ module supra_framework::stake { operator: &signer, pool_address: address, new_consensus_pubkey: vector, - genesis: bool, + genesis: bool ) acquires StakePool, ValidatorConfig { assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut(pool_address); - assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR)); + assert!( + signer::address_of(operator) == stake_pool.operator_address, + error::unauthenticated(ENOT_OPERATOR) + ); - assert!(exists(pool_address), error::not_found(EVALIDATOR_CONFIG)); + assert!( + exists(pool_address), + error::not_found(EVALIDATOR_CONFIG) + ); let validator_info = borrow_global_mut(pool_address); let old_consensus_pubkey = validator_info.consensus_pubkey; // Checks the public key is valid to prevent rogue-key attacks. if (!genesis) { - let validated_public_key = ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); - assert!(option::is_some(&validated_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY)); + if (std::features::supra_validator_identity_v2_enabled()) { + let _valid_public_key = + validator_public_keys::validator_public_keys_from_bytes( + new_consensus_pubkey + ); + } else { + let valid_public_key = + ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); + assert!( + option::is_some(&valid_public_key), + error::invalid_argument(EINVALID_PUBLIC_KEY) + ); + }; } else { - let validated_public_key = ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); - assert!(option::is_some(&validated_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY)); + if (std::features::supra_validator_identity_v2_enabled()) { + let _valid_public_key = + validator_public_keys::validator_public_keys_from_bytes( + new_consensus_pubkey + ); + } else { + let valid_public_key = + ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); + assert!( + option::is_some(&valid_public_key), + error::invalid_argument(EINVALID_PUBLIC_KEY) + ); + }; }; validator_info.consensus_pubkey = new_consensus_pubkey; @@ -899,8 +1003,8 @@ module supra_framework::stake { RotateConsensusKey { pool_address, old_consensus_pubkey, - new_consensus_pubkey, - }, + new_consensus_pubkey + } ); }; event::emit_event( @@ -908,29 +1012,127 @@ module supra_framework::stake { RotateConsensusKeyEvent { pool_address, old_consensus_pubkey, - new_consensus_pubkey, - }, + new_consensus_pubkey + } ); } + /// Set DKG output keys for all provided threshold types. + /// Each DkgCommitteeOutput contains a threshold_type and corresponding keys for all validators. + public(friend) fun set_dkg_output_keys( + committee_outputs: vector + ) acquires ValidatorConfig, ValidatorFees, ValidatorPerformance, ValidatorSet, StakePool { + if (vector::is_empty(&committee_outputs)) { return }; + + let next_validator_infos = next_validator_consensus_infos(); + let num_validators = vector::length(&next_validator_infos); + + // Validate all committee outputs have correct number of keys + let num_outputs = vector::length(&committee_outputs); + let j = 0; + while (j < num_outputs) { + let output = vector::borrow(&committee_outputs, j); + assert!( + num_validators + == vector::length( + &dkg_committee::get_dkg_committee_output_keys(output) + ), + error::invalid_argument(EDKG_INVALID_PK_SHARES) + ); + j = j + 1; + }; + + // Iterate over each validator + let i = 0; + while (i < num_validators) { + let val_info = vector::borrow(&next_validator_infos, i); + let addr = validator_consensus_info::get_addr(val_info); + let validator_config = borrow_global_mut(addr); + let old_consensus_pubkey = validator_config.consensus_pubkey; + + // Load current public keys + let pub_keys = + validator_public_keys::validator_public_keys_from_bytes( + old_consensus_pubkey + ); + + // Apply all threshold key updates for this validator + let k = 0; + while (k < num_outputs) { + let output = vector::borrow(&committee_outputs, k); + let output_keys = dkg_committee::get_dkg_committee_output_keys(output); + let key_bytes = vector::borrow(&output_keys, i); + + // Deserialize the key + let key_opt = aptos_std::bls12381::public_key_from_bytes(*key_bytes); + assert!( + option::is_some(&key_opt), + error::invalid_argument(EINVALID_PUBLIC_KEY) + ); + let new_key = option::extract(&mut key_opt); + + // Rotate the key based on threshold type + validator_public_keys::rotate_supra_bls_threshold_key_by_type( + &mut pub_keys, + dkg_committee::get_dkg_committee_output_threshold_type(output), + new_key + ); + k = k + 1; + }; + + // Serialize and save updated keys + let new_consensus_pubkey = + validator_public_keys::public_key_to_bytes(pub_keys); + validator_config.consensus_pubkey = new_consensus_pubkey; + + // Emit events + let stake_pool = borrow_global_mut(addr); + if (std::features::module_event_migration_enabled()) { + event::emit( + RotateConsensusKey { + pool_address: addr, + old_consensus_pubkey, + new_consensus_pubkey + } + ); + }; + event::emit_event( + &mut stake_pool.rotate_consensus_key_events, + RotateConsensusKeyEvent { + pool_address: addr, + old_consensus_pubkey, + new_consensus_pubkey + } + ); + + i = i + 1; + }; + } + /// Rotate the consensus key of the validator /// does not verify proof of possession /// only for genesis public(friend) fun rotate_consensus_key_genesis( - operator: &signer, - pool_address: address, - new_consensus_pubkey: vector, + operator: &signer, pool_address: address, new_consensus_pubkey: vector ) acquires StakePool, ValidatorConfig { - rotate_consensus_key_internal(operator, pool_address, new_consensus_pubkey, true); + rotate_consensus_key_internal( + operator, + pool_address, + new_consensus_pubkey, + true + ); } /// Rotate the consensus key of the validator, it'll take effect in next epoch. public entry fun rotate_consensus_key( - operator: &signer, - pool_address: address, - new_consensus_pubkey: vector, + operator: &signer, pool_address: address, new_consensus_pubkey: vector ) acquires StakePool, ValidatorConfig { - rotate_consensus_key_internal(operator, pool_address, new_consensus_pubkey, false); + rotate_consensus_key_internal( + operator, + pool_address, + new_consensus_pubkey, + false + ); } /// Update the network and full node addresses of the validator. This only takes effect in the next epoch. @@ -938,13 +1140,19 @@ module supra_framework::stake { operator: &signer, pool_address: address, new_network_addresses: vector, - new_fullnode_addresses: vector, + new_fullnode_addresses: vector ) acquires StakePool, ValidatorConfig { assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut(pool_address); - assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR)); - assert!(exists(pool_address), error::not_found(EVALIDATOR_CONFIG)); + assert!( + signer::address_of(operator) == stake_pool.operator_address, + error::unauthenticated(ENOT_OPERATOR) + ); + assert!( + exists(pool_address), + error::not_found(EVALIDATOR_CONFIG) + ); let validator_info = borrow_global_mut(pool_address); let old_network_addresses = validator_info.network_addresses; validator_info.network_addresses = new_network_addresses; @@ -958,8 +1166,8 @@ module supra_framework::stake { old_network_addresses, new_network_addresses, old_fullnode_addresses, - new_fullnode_addresses, - }, + new_fullnode_addresses + } ); }; event::emit_event( @@ -969,8 +1177,8 @@ module supra_framework::stake { old_network_addresses, new_network_addresses, old_fullnode_addresses, - new_fullnode_addresses, - }, + new_fullnode_addresses + } ); } @@ -992,8 +1200,13 @@ module supra_framework::stake { let stake_pool = borrow_global_mut(pool_address); let old_locked_until_secs = stake_pool.locked_until_secs; - let new_locked_until_secs = timestamp::now_seconds() + staking_config::get_recurring_lockup_duration(&config); - assert!(old_locked_until_secs < new_locked_until_secs, error::invalid_argument(EINVALID_LOCKUP)); + let new_locked_until_secs = + timestamp::now_seconds() + + staking_config::get_recurring_lockup_duration(&config); + assert!( + old_locked_until_secs < new_locked_until_secs, + error::invalid_argument(EINVALID_LOCKUP) + ); stake_pool.locked_until_secs = new_locked_until_secs; if (std::features::module_event_migration_enabled()) { @@ -1001,8 +1214,8 @@ module supra_framework::stake { IncreaseLockup { pool_address, old_locked_until_secs, - new_locked_until_secs, - }, + new_locked_until_secs + } ); }; event::emit_event( @@ -1010,19 +1223,18 @@ module supra_framework::stake { IncreaseLockupEvent { pool_address, old_locked_until_secs, - new_locked_until_secs, - }, + new_locked_until_secs + } ); } /// This can only called by the operator of the validator/staking pool. public entry fun join_validator_set( - operator: &signer, - pool_address: address + operator: &signer, pool_address: address ) acquires StakePool, ValidatorConfig, ValidatorSet { assert!( staking_config::get_allow_validator_set_change(&staking_config::get()), - error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED), + error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED) ); join_validator_set_internal(operator, pool_address); @@ -1035,16 +1247,18 @@ module supra_framework::stake { /// /// This internal version can only be called by the Genesis module during Genesis. public(friend) fun join_validator_set_internal( - operator: &signer, - pool_address: address + operator: &signer, pool_address: address ) acquires StakePool, ValidatorConfig, ValidatorSet { assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut(pool_address); - assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR)); + assert!( + signer::address_of(operator) == stake_pool.operator_address, + error::unauthenticated(ENOT_OPERATOR) + ); assert!( get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE, - error::invalid_state(EALREADY_ACTIVE_VALIDATOR), + error::invalid_state(EALREADY_ACTIVE_VALIDATOR) ); let config = staking_config::get(); @@ -1058,7 +1272,10 @@ module supra_framework::stake { // Add validator to pending_active, to be activated in the next epoch. let validator_config = borrow_global_mut(pool_address); - assert!(!vector::is_empty(&validator_config.consensus_pubkey), error::invalid_argument(EINVALID_PUBLIC_KEY)); + assert!( + !vector::is_empty(&validator_config.consensus_pubkey), + error::invalid_argument(EINVALID_PUBLIC_KEY) + ); // Validate the current validator set size has not exceeded the limit. let validator_set = borrow_global_mut(@supra_framework); @@ -1066,17 +1283,19 @@ module supra_framework::stake { &mut validator_set.pending_active, generate_validator_info(pool_address, stake_pool, *validator_config) ); - let validator_set_size = vector::length(&validator_set.active_validators) + vector::length( - &validator_set.pending_active + let validator_set_size = vector::length(&validator_set.active_validators) + + vector::length(&validator_set.pending_active); + assert!( + validator_set_size <= MAX_VALIDATOR_SET_SIZE, + error::invalid_argument(EVALIDATOR_SET_TOO_LARGE) ); - assert!(validator_set_size <= MAX_VALIDATOR_SET_SIZE, error::invalid_argument(EVALIDATOR_SET_TOO_LARGE)); if (std::features::module_event_migration_enabled()) { event::emit(JoinValidatorSet { pool_address }); }; event::emit_event( &mut stake_pool.join_validator_set_events, - JoinValidatorSetEvent { pool_address }, + JoinValidatorSetEvent { pool_address } ); } @@ -1093,9 +1312,7 @@ module supra_framework::stake { public fun unlock_with_cap(amount: u64, owner_cap: &OwnerCapability) acquires StakePool { assert_reconfig_not_in_progress(); // Short-circuit if amount to unlock is 0 so we don't emit events. - if (amount == 0) { - return - }; + if (amount == 0) { return }; // Unlocked coins are moved to pending_inactive. When the current lockup cycle expires, they will be moved into // inactive in the earliest possible epoch transition. @@ -1108,26 +1325,17 @@ module supra_framework::stake { coin::merge(&mut stake_pool.pending_inactive, unlocked_stake); if (std::features::module_event_migration_enabled()) { - event::emit( - UnlockStake { - pool_address, - amount_unlocked: amount, - }, - ); + event::emit(UnlockStake { pool_address, amount_unlocked: amount }); }; event::emit_event( &mut stake_pool.unlock_stake_events, - UnlockStakeEvent { - pool_address, - amount_unlocked: amount, - }, + UnlockStakeEvent { pool_address, amount_unlocked: amount } ); } /// Withdraw from `account`'s inactive stake. public entry fun withdraw( - owner: &signer, - withdraw_amount: u64 + owner: &signer, withdraw_amount: u64 ) acquires OwnerCapability, StakePool, ValidatorSet { let owner_address = signer::address_of(owner); assert_owner_cap_exists(owner_address); @@ -1138,8 +1346,7 @@ module supra_framework::stake { /// Withdraw from `pool_address`'s inactive stake with the corresponding `owner_cap`. public fun withdraw_with_cap( - owner_cap: &OwnerCapability, - withdraw_amount: u64 + owner_cap: &OwnerCapability, withdraw_amount: u64 ): Coin acquires StakePool, ValidatorSet { assert_reconfig_not_in_progress(); let pool_address = owner_cap.pool_address; @@ -1148,9 +1355,10 @@ module supra_framework::stake { // There's an edge case where a validator unlocks their stake and leaves the validator set before // the stake is fully unlocked (the current lockup cycle has not expired yet). // This can leave their stake stuck in pending_inactive even after the current lockup cycle expires. - if (get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE && - timestamp::now_seconds() >= stake_pool.locked_until_secs) { - let pending_inactive_stake = coin::extract_all(&mut stake_pool.pending_inactive); + if (get_validator_state(pool_address) == VALIDATOR_STATUS_INACTIVE + && timestamp::now_seconds() >= stake_pool.locked_until_secs) { + let pending_inactive_stake = + coin::extract_all(&mut stake_pool.pending_inactive); coin::merge(&mut stake_pool.inactive, pending_inactive_stake); }; @@ -1159,19 +1367,11 @@ module supra_framework::stake { if (withdraw_amount == 0) return coin::zero(); if (std::features::module_event_migration_enabled()) { - event::emit( - WithdrawStake { - pool_address, - amount_withdrawn: withdraw_amount, - }, - ); + event::emit(WithdrawStake { pool_address, amount_withdrawn: withdraw_amount }); }; event::emit_event( &mut stake_pool.withdraw_stake_events, - WithdrawStakeEvent { - pool_address, - amount_withdrawn: withdraw_amount, - }, + WithdrawStakeEvent { pool_address, amount_withdrawn: withdraw_amount } ); coin::extract(&mut stake_pool.inactive, withdraw_amount) @@ -1184,27 +1384,32 @@ module supra_framework::stake { /// /// Can only be called by the operator of the validator/staking pool. public entry fun leave_validator_set( - operator: &signer, - pool_address: address + operator: &signer, pool_address: address ) acquires StakePool, ValidatorSet { assert_reconfig_not_in_progress(); let config = staking_config::get(); assert!( staking_config::get_allow_validator_set_change(&config), - error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED), + error::invalid_argument(ENO_POST_GENESIS_VALIDATOR_SET_CHANGE_ALLOWED) ); assert_stake_pool_exists(pool_address); let stake_pool = borrow_global_mut(pool_address); // Account has to be the operator. - assert!(signer::address_of(operator) == stake_pool.operator_address, error::unauthenticated(ENOT_OPERATOR)); + assert!( + signer::address_of(operator) == stake_pool.operator_address, + error::unauthenticated(ENOT_OPERATOR) + ); let validator_set = borrow_global_mut(@supra_framework); // If the validator is still pending_active, directly kick the validator out. - let maybe_pending_active_index = find_validator(&validator_set.pending_active, pool_address); + let maybe_pending_active_index = + find_validator(&validator_set.pending_active, pool_address); if (option::is_some(&maybe_pending_active_index)) { vector::swap_remove( - &mut validator_set.pending_active, option::extract(&mut maybe_pending_active_index)); + &mut validator_set.pending_active, + option::extract(&mut maybe_pending_active_index) + ); // Decrease the voting power increase as the pending validator's voting power was added when they requested // to join. Now that they changed their mind, their voting power should not affect the joining limit of this @@ -1214,17 +1419,27 @@ module supra_framework::stake { // rounding error somewhere that can lead to an underflow, we still want to allow this transaction to // succeed. if (validator_set.total_joining_power > validator_stake) { - validator_set.total_joining_power = validator_set.total_joining_power - validator_stake; + validator_set.total_joining_power = + validator_set.total_joining_power - validator_stake; } else { validator_set.total_joining_power = 0; }; } else { // Validate that the validator is already part of the validator set. - let maybe_active_index = find_validator(&validator_set.active_validators, pool_address); - assert!(option::is_some(&maybe_active_index), error::invalid_state(ENOT_VALIDATOR)); + let maybe_active_index = + find_validator(&validator_set.active_validators, pool_address); + assert!( + option::is_some(&maybe_active_index), + error::invalid_state(ENOT_VALIDATOR) + ); let validator_info = vector::swap_remove( - &mut validator_set.active_validators, option::extract(&mut maybe_active_index)); - assert!(vector::length(&validator_set.active_validators) != 0, error::invalid_state(ELAST_VALIDATOR)); + &mut validator_set.active_validators, + option::extract(&mut maybe_active_index) + ); + assert!( + vector::length(&validator_set.active_validators) != 0, + error::invalid_state(ELAST_VALIDATOR) + ); vector::push_back(&mut validator_set.pending_inactive, validator_info); if (std::features::module_event_migration_enabled()) { @@ -1232,9 +1447,7 @@ module supra_framework::stake { }; event::emit_event( &mut stake_pool.leave_validator_set_events, - LeaveValidatorSetEvent { - pool_address, - }, + LeaveValidatorSetEvent { pool_address } ); }; } @@ -1245,14 +1458,14 @@ module supra_framework::stake { public fun is_current_epoch_validator(pool_address: address): bool acquires ValidatorSet { assert_stake_pool_exists(pool_address); let validator_state = get_validator_state(pool_address); - validator_state == VALIDATOR_STATUS_ACTIVE || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE + validator_state == VALIDATOR_STATUS_ACTIVE + || validator_state == VALIDATOR_STATUS_PENDING_INACTIVE } /// Update the validator performance (proposal statistics). This is only called by block::prologue(). /// This function cannot abort. public(friend) fun update_performance_statistics( - proposer_index: Option, - failed_proposer_indices: vector + proposer_index: Option, failed_proposer_indices: vector ) acquires ValidatorPerformance { // Validator set cannot change until the end of the epoch, so the validator index in arguments should // match with those of the validators in ValidatorPerformance resource. @@ -1269,7 +1482,9 @@ module supra_framework::stake { // Here, and in all other vector::borrow, skip any validator indices that are out of bounds, // this ensures that this function doesn't abort if there are out of bounds errors. if (cur_proposer_index < validator_len) { - let validator = vector::borrow_mut(&mut validator_perf.validators, cur_proposer_index); + let validator = vector::borrow_mut( + &mut validator_perf.validators, cur_proposer_index + ); spec { assume validator.successful_proposals + 1 <= MAX_U64; }; @@ -1282,17 +1497,25 @@ module supra_framework::stake { while ({ spec { invariant len(validator_perf.validators) == validator_len; - invariant (option::spec_is_some(ghost_proposer_idx) && option::spec_borrow( - ghost_proposer_idx - ) < validator_len) ==> - (validator_perf.validators[option::spec_borrow(ghost_proposer_idx)].successful_proposals == - ghost_valid_perf.validators[option::spec_borrow(ghost_proposer_idx)].successful_proposals + 1); + invariant ( + option::spec_is_some(ghost_proposer_idx) + && option::spec_borrow(ghost_proposer_idx) < validator_len + ) ==> + ( + validator_perf.validators[option::spec_borrow(ghost_proposer_idx)] + .successful_proposals + == ghost_valid_perf.validators[option::spec_borrow( + ghost_proposer_idx + )].successful_proposals + 1 + ); }; f < f_len }) { let validator_index = *vector::borrow(&failed_proposer_indices, f); if (validator_index < validator_len) { - let validator = vector::borrow_mut(&mut validator_perf.validators, validator_index); + let validator = vector::borrow_mut( + &mut validator_perf.validators, validator_index + ); spec { assume validator.failed_proposals + 1 <= MAX_U64; }; @@ -1312,24 +1535,29 @@ module supra_framework::stake { /// pending inactive validators so they no longer can vote. /// 4. The validator's voting power in the validator set is updated to be the corresponding staking pool's voting /// power. - public(friend) fun on_new_epoch( - ) acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + public(friend) fun on_new_epoch() acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { let validator_set = borrow_global_mut(@supra_framework); let config = staking_config::get(); let validator_perf = borrow_global_mut(@supra_framework); // Process pending stake and distribute transaction fees and rewards for each currently active validator. - vector::for_each_ref(&validator_set.active_validators, |validator| { - let validator: &ValidatorInfo = validator; - update_stake_pool(validator_perf, validator.addr, &config); - }); + vector::for_each_ref( + &validator_set.active_validators, + |validator| { + let validator: &ValidatorInfo = validator; + update_stake_pool(validator_perf, validator.addr, &config); + } + ); // Process pending stake and distribute transaction fees and rewards for each currently pending_inactive validator // (requested to leave but not removed yet). - vector::for_each_ref(&validator_set.pending_inactive, |validator| { - let validator: &ValidatorInfo = validator; - update_stake_pool(validator_perf, validator.addr, &config); - }); + vector::for_each_ref( + &validator_set.pending_inactive, + |validator| { + let validator: &ValidatorInfo = validator; + update_stake_pool(validator_perf, validator.addr, &config); + } + ); // Activate currently pending_active validators. append(&mut validator_set.active_validators, &mut validator_set.pending_active); @@ -1352,18 +1580,23 @@ module supra_framework::stake { }; i < vlen }) { - let old_validator_info = vector::borrow_mut(&mut validator_set.active_validators, i); + let old_validator_info = vector::borrow_mut( + &mut validator_set.active_validators, i + ); let pool_address = old_validator_info.addr; let validator_config = borrow_global_mut(pool_address); let stake_pool = borrow_global_mut(pool_address); - let new_validator_info = generate_validator_info(pool_address, stake_pool, *validator_config); + let new_validator_info = + generate_validator_info(pool_address, stake_pool, *validator_config); // A validator needs at least the min stake required to join the validator set. if (new_validator_info.voting_power >= minimum_stake) { spec { - assume total_voting_power + new_validator_info.voting_power <= MAX_U128; + assume total_voting_power + new_validator_info.voting_power + <= MAX_U128; }; - total_voting_power = total_voting_power + (new_validator_info.voting_power as u128); + total_voting_power = + total_voting_power + (new_validator_info.voting_power as u128); vector::push_back(&mut next_epoch_validators, new_validator_info); }; i = i + 1; @@ -1375,7 +1608,8 @@ module supra_framework::stake { // Update validator indices, reset performance scores, and renew lockups. validator_perf.validators = vector::empty(); - let recurring_lockup_duration_secs = staking_config::get_recurring_lockup_duration(&config); + let recurring_lockup_duration_secs = + staking_config::get_recurring_lockup_duration(&config); let vlen = vector::length(&validator_set.active_validators); let validator_index = 0; while ({ @@ -1386,37 +1620,47 @@ module supra_framework::stake { invariant 0 <= validator_index && validator_index <= vlen; invariant vlen == len(validator_set.active_validators); invariant forall i in 0..validator_index: - global(validator_set.active_validators[i].addr).validator_index < validator_index; + global(validator_set.active_validators[i].addr).validator_index + < validator_index; invariant forall i in 0..validator_index: - validator_set.active_validators[i].config.validator_index < validator_index; + validator_set.active_validators[i].config.validator_index + < validator_index; invariant len(validator_perf.validators) == validator_index; }; validator_index < vlen }) { - let validator_info = vector::borrow_mut(&mut validator_set.active_validators, validator_index); + let validator_info = vector::borrow_mut( + &mut validator_set.active_validators, validator_index + ); validator_info.config.validator_index = validator_index; - let validator_config = borrow_global_mut(validator_info.addr); + let validator_config = + borrow_global_mut(validator_info.addr); validator_config.validator_index = validator_index; - vector::push_back(&mut validator_perf.validators, IndividualValidatorPerformance { - successful_proposals: 0, - failed_proposals: 0, - }); + vector::push_back( + &mut validator_perf.validators, + IndividualValidatorPerformance { + successful_proposals: 0, + failed_proposals: 0 + } + ); // Automatically renew a validator's lockup for validators that will still be in the validator set in the // next epoch. let stake_pool = borrow_global_mut(validator_info.addr); let now_secs = timestamp::now_seconds(); - let reconfig_start_secs = if (chain_status::is_operating()) { - get_reconfig_start_time_secs() - } else { - now_secs - }; + let reconfig_start_secs = + if (chain_status::is_operating()) { + get_reconfig_start_time_secs() + } else { + now_secs + }; if (stake_pool.locked_until_secs <= reconfig_start_secs) { spec { assume now_secs + recurring_lockup_duration_secs <= MAX_U64; }; - stake_pool.locked_until_secs = now_secs + recurring_lockup_duration_secs; + stake_pool.locked_until_secs = now_secs + + recurring_lockup_duration_secs; }; validator_index = validator_index + 1; @@ -1434,14 +1678,41 @@ module supra_framework::stake { validator_consensus_infos_from_validator_set(validator_set) } - public fun next_validator_consensus_infos(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig { + let new_validator_set = compute_next_validator_set_internal(false); + validator_consensus_infos_from_validator_set(&new_validator_set) + } + + /// Same as `next_validator_consensus_infos` but uses the current-epoch config data for + /// validators that are already active. This is used when starting DKG: the committee + /// membership (active + pending_active) must reflect the next epoch, but node config + /// should reflect current-epoch for the active validators to ensure that validators that update + /// their configuration do not need to run two copies of themselves to participate in DKG. + public fun next_epoch_validator_consensus_infos_for_dkg(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig { + // Use the current-epoch config snapshot for active validators so mid-epoch config changes + // do not take effect during DKG (use_current_config_for_actives=true). + let new_validator_set = compute_next_validator_set_internal(true); + validator_consensus_infos_from_validator_set(&new_validator_set) + } + + /// Computes the validator set for the next epoch. + /// + /// `use_current_config_for_actives`: when `true`, currently-active validators retain their + /// current-epoch `ValidatorConfig` snapshot instead of reading the latest on-chain value. + /// New joiners (`pending_active`) always read from `ValidatorConfig` regardless of this flag. + /// + /// `pending_active` is iterated in reverse to match the order produced by `on_new_epoch` + /// (which appends via `pop_back`). + fun compute_next_validator_set_internal( + use_current_config_for_actives: bool, + ): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig { // Init. let cur_validator_set = borrow_global(@supra_framework); let staking_config = staking_config::get(); let validator_perf = borrow_global(@supra_framework); let (minimum_stake, _) = staking_config::get_required_stake(&staking_config); - let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate(&staking_config); + let (rewards_rate, rewards_rate_denominator) = + staking_config::get_reward_rate(&staking_config); // Compute new validator set. let new_active_validators = vector[]; @@ -1467,56 +1738,60 @@ module supra_framework::stake { candidate_idx < num_candidates }) { let candidate_in_current_validator_set = candidate_idx < num_cur_actives; - let candidate = if (candidate_idx < num_cur_actives) { - vector::borrow(&cur_validator_set.active_validators, candidate_idx) - } else { - vector::borrow(&cur_validator_set.pending_active, candidate_idx - num_cur_actives) - }; + let candidate = + if (candidate_idx < num_cur_actives) { + vector::borrow(&cur_validator_set.active_validators, candidate_idx) + } else { + let pending_idx = + num_cur_pending_actives - 1 - (candidate_idx - num_cur_actives); + vector::borrow(&cur_validator_set.pending_active, pending_idx) + }; let stake_pool = borrow_global(candidate.addr); let cur_active = coin::value(&stake_pool.active); let cur_pending_active = coin::value(&stake_pool.pending_active); let cur_pending_inactive = coin::value(&stake_pool.pending_inactive); - let cur_reward = if (candidate_in_current_validator_set && cur_active != 0) { - spec { - assert candidate.config.validator_index < len(validator_perf.validators); - }; - let cur_perf = vector::borrow(&validator_perf.validators, candidate.config.validator_index); - spec { - assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64; - }; - calculate_rewards_amount(cur_active, cur_perf.successful_proposals, cur_perf.successful_proposals + cur_perf.failed_proposals, rewards_rate, rewards_rate_denominator) - } else { - 0 - }; + let cur_reward = calculate_candidate_reward( + candidate, + candidate_in_current_validator_set, + cur_active, + validator_perf, + rewards_rate, + rewards_rate_denominator + ); - let cur_fee = 0; - if (features::collect_and_distribute_gas_fees()) { - let fees_table = &borrow_global(@supra_framework).fees_table; - if (table::contains(fees_table, candidate.addr)) { - let fee_coin = table::borrow(fees_table, candidate.addr); - cur_fee = coin::value(fee_coin); - } - }; + let cur_fee = collect_candidate_fee(candidate.addr); - let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs; + let lockup_expired = + get_reconfig_start_time_secs() >= stake_pool.locked_until_secs; spec { - assume cur_active + cur_pending_active + cur_reward + cur_fee <= MAX_U64; - assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward + cur_fee <= MAX_U64; + assume cur_active + cur_pending_active + cur_reward + cur_fee + <= MAX_U64; + assume cur_active + cur_pending_inactive + cur_pending_active + + cur_reward + cur_fee <= MAX_U64; }; let new_voting_power = cur_active - + if (lockup_expired) { 0 } else { cur_pending_inactive } - + cur_pending_active - + cur_reward + cur_fee; + + if (lockup_expired) { 0 } + else { + cur_pending_inactive + } + cur_pending_active + cur_reward + cur_fee; if (new_voting_power >= minimum_stake) { - let config = *borrow_global(candidate.addr); + let config = + if (use_current_config_for_actives && candidate_in_current_validator_set) { + // Use the current-epoch config snapshot so that any mid-epoch changes + // (consensus key, network addresses, etc.) only take effect after the + // epoch transition, not during DKG. + candidate.config + } else { + *borrow_global(candidate.addr) + }; config.validator_index = num_new_actives; let new_validator_info = ValidatorInfo { addr: candidate.addr, voting_power: new_voting_power, - config, + config }; // Update ValidatorSet. @@ -1526,24 +1801,65 @@ module supra_framework::stake { new_total_power = new_total_power + (new_voting_power as u128); vector::push_back(&mut new_active_validators, new_validator_info); num_new_actives = num_new_actives + 1; - }; candidate_idx = candidate_idx + 1; }; - let new_validator_set = ValidatorSet { + ValidatorSet { consensus_scheme: cur_validator_set.consensus_scheme, active_validators: new_active_validators, pending_inactive: vector[], pending_active: vector[], total_voting_power: new_total_power, - total_joining_power: 0, - }; + total_joining_power: 0 + } + } - validator_consensus_infos_from_validator_set(&new_validator_set) + /// Computes the reward earned by a candidate validator for the current epoch. + /// Returns 0 for pending-active validators (not yet in the active set) or validators + /// with no active stake. + fun calculate_candidate_reward( + candidate: &ValidatorInfo, + candidate_in_current_validator_set: bool, + cur_active: u64, + validator_perf: &ValidatorPerformance, + rewards_rate: u64, + rewards_rate_denominator: u64, + ): u64 { + if (candidate_in_current_validator_set && cur_active != 0) { + spec { + assert candidate.config.validator_index < len(validator_perf.validators); + }; + let cur_perf = vector::borrow( + &validator_perf.validators, candidate.config.validator_index + ); + spec { + assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64; + }; + calculate_rewards_amount( + cur_active, + cur_perf.successful_proposals, + cur_perf.successful_proposals + cur_perf.failed_proposals, + rewards_rate, + rewards_rate_denominator + ) + } else { 0 } + } + + /// Returns the accumulated gas fees assigned to `candidate_addr`, or 0 if fee collection + /// is disabled or no fees have been recorded for this validator. + fun collect_candidate_fee(candidate_addr: address): u64 acquires ValidatorFees { + if (features::collect_and_distribute_gas_fees()) { + let fees_table = &borrow_global(@supra_framework).fees_table; + if (table::contains(fees_table, candidate_addr)) { + coin::value(table::borrow(fees_table, candidate_addr)) + } else { 0 } + } else { 0 } } - fun validator_consensus_infos_from_validator_set(validator_set: &ValidatorSet): vector { + fun validator_consensus_infos_from_validator_set( + validator_set: &ValidatorSet + ): vector { let validator_consensus_infos = vector[]; let num_active = vector::length(&validator_set.active_validators); @@ -1557,63 +1873,95 @@ module supra_framework::stake { let idx = 0; while ({ spec { - invariant idx <= len(validator_set.active_validators) + len(validator_set.pending_inactive); + invariant idx + <= len(validator_set.active_validators) + + len(validator_set.pending_inactive); invariant len(validator_consensus_infos) == idx; - invariant len(validator_consensus_infos) <= len(validator_set.active_validators) + len(validator_set.pending_inactive); + invariant len(validator_consensus_infos) + <= len(validator_set.active_validators) + + len(validator_set.pending_inactive); }; idx < total }) { - vector::push_back(&mut validator_consensus_infos, validator_consensus_info::default()); + vector::push_back( + &mut validator_consensus_infos, validator_consensus_info::default() + ); idx = idx + 1; }; spec { - assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive); - assert spec_validator_indices_are_valid_config(validator_set.active_validators, - len(validator_set.active_validators) + len(validator_set.pending_inactive)); + assert len(validator_consensus_infos) + == len(validator_set.active_validators) + + len(validator_set.pending_inactive); + assert spec_validator_indices_are_valid_config( + validator_set.active_validators, + len(validator_set.active_validators) + + len(validator_set.pending_inactive) + ); }; - vector::for_each_ref(&validator_set.active_validators, |obj| { - let vi: &ValidatorInfo = obj; - spec { - assume len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive); - assert vi.config.validator_index < len(validator_consensus_infos); - }; - let vci = vector::borrow_mut(&mut validator_consensus_infos, vi.config.validator_index); - *vci = validator_consensus_info::new( - vi.addr, - vi.config.consensus_pubkey, - vi.voting_power - ); - spec { - assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive); - }; - }); + vector::for_each_ref( + &validator_set.active_validators, + |obj| { + let vi: &ValidatorInfo = obj; + spec { + assume len(validator_consensus_infos) + == len(validator_set.active_validators) + + len(validator_set.pending_inactive); + assert vi.config.validator_index < len(validator_consensus_infos); + }; + let vci = vector::borrow_mut( + &mut validator_consensus_infos, vi.config.validator_index + ); + *vci = validator_consensus_info::new( + vi.addr, + vi.config.consensus_pubkey, + vi.voting_power + ); + spec { + assert len(validator_consensus_infos) + == len(validator_set.active_validators) + + len(validator_set.pending_inactive); + }; + } + ); - vector::for_each_ref(&validator_set.pending_inactive, |obj| { - let vi: &ValidatorInfo = obj; - spec { - assume len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive); - assert vi.config.validator_index < len(validator_consensus_infos); - }; - let vci = vector::borrow_mut(&mut validator_consensus_infos, vi.config.validator_index); - *vci = validator_consensus_info::new( - vi.addr, - vi.config.consensus_pubkey, - vi.voting_power - ); - spec { - assert len(validator_consensus_infos) == len(validator_set.active_validators) + len(validator_set.pending_inactive); - }; - }); + vector::for_each_ref( + &validator_set.pending_inactive, + |obj| { + let vi: &ValidatorInfo = obj; + spec { + assume len(validator_consensus_infos) + == len(validator_set.active_validators) + + len(validator_set.pending_inactive); + assert vi.config.validator_index < len(validator_consensus_infos); + }; + let vci = vector::borrow_mut( + &mut validator_consensus_infos, vi.config.validator_index + ); + *vci = validator_consensus_info::new( + vi.addr, + vi.config.consensus_pubkey, + vi.voting_power + ); + spec { + assert len(validator_consensus_infos) + == len(validator_set.active_validators) + + len(validator_set.pending_inactive); + }; + } + ); validator_consensus_infos } fun addresses_from_validator_infos(infos: &vector): vector
{ - vector::map_ref(infos, |obj| { - let info: &ValidatorInfo = obj; - info.addr - }) + vector::map_ref( + infos, + |obj| { + let info: &ValidatorInfo = obj; + info.addr + } + ) } /// Calculate the stake amount of a stake pool for the next epoch. @@ -1626,43 +1974,54 @@ module supra_framework::stake { fun update_stake_pool( validator_perf: &ValidatorPerformance, pool_address: address, - staking_config: &StakingConfig, + staking_config: &StakingConfig ) acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorFees { let stake_pool = borrow_global_mut(pool_address); let validator_config = borrow_global(pool_address); - let cur_validator_perf = vector::borrow(&validator_perf.validators, validator_config.validator_index); + let cur_validator_perf = vector::borrow( + &validator_perf.validators, validator_config.validator_index + ); let num_successful_proposals = cur_validator_perf.successful_proposals; spec { // The following addition should not overflow because `num_total_proposals` cannot be larger than 86400, // the maximum number of proposals in a day (1 proposal per second). - assume cur_validator_perf.successful_proposals + cur_validator_perf.failed_proposals <= MAX_U64; + assume cur_validator_perf.successful_proposals + + cur_validator_perf.failed_proposals <= MAX_U64; }; - let num_total_proposals = cur_validator_perf.successful_proposals + cur_validator_perf.failed_proposals; - let (rewards_rate, rewards_rate_denominator) = staking_config::get_reward_rate(staking_config); - let rewards_active = distribute_rewards( - &mut stake_pool.active, - num_successful_proposals, - num_total_proposals, - rewards_rate, - rewards_rate_denominator - ); - let rewards_pending_inactive = distribute_rewards( - &mut stake_pool.pending_inactive, - num_successful_proposals, - num_total_proposals, - rewards_rate, - rewards_rate_denominator - ); + let num_total_proposals = + cur_validator_perf.successful_proposals + + cur_validator_perf.failed_proposals; + let (rewards_rate, rewards_rate_denominator) = + staking_config::get_reward_rate(staking_config); + let rewards_active = + distribute_rewards( + &mut stake_pool.active, + num_successful_proposals, + num_total_proposals, + rewards_rate, + rewards_rate_denominator + ); + let rewards_pending_inactive = + distribute_rewards( + &mut stake_pool.pending_inactive, + num_successful_proposals, + num_total_proposals, + rewards_rate, + rewards_rate_denominator + ); spec { assume rewards_active + rewards_pending_inactive <= MAX_U64; }; let rewards_amount = rewards_active + rewards_pending_inactive; // Pending active stake can now be active. - coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active)); + coin::merge( + &mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active) + ); // Additionally, distribute transaction fees. if (features::collect_and_distribute_gas_fees()) { - let fees_table = &mut borrow_global_mut(@supra_framework).fees_table; + let fees_table = + &mut borrow_global_mut(@supra_framework).fees_table; if (table::contains(fees_table, pool_address)) { let coin = table::remove(fees_table, pool_address); coin::merge(&mut stake_pool.active, coin); @@ -1674,7 +2033,7 @@ module supra_framework::stake { if (get_reconfig_start_time_secs() >= current_lockup_expiration) { coin::merge( &mut stake_pool.inactive, - coin::extract_all(&mut stake_pool.pending_inactive), + coin::extract_all(&mut stake_pool.pending_inactive) ); }; @@ -1683,10 +2042,7 @@ module supra_framework::stake { }; event::emit_event( &mut stake_pool.distribute_rewards_events, - DistributeRewardsEvent { - pool_address, - rewards_amount, - }, + DistributeRewardsEvent { pool_address, rewards_amount } ); } @@ -1705,7 +2061,7 @@ module supra_framework::stake { num_successful_proposals: u64, num_total_proposals: u64, rewards_rate: u64, - rewards_rate_denominator: u64, + rewards_rate_denominator: u64 ): u64 { spec { // The following condition must hold because @@ -1716,13 +2072,14 @@ module supra_framework::stake { }; // The rewards amount is equal to (stake amount * rewards rate * performance multiplier). // We do multiplication in u128 before division to avoid the overflow and minimize the rounding error. - let rewards_numerator = (stake_amount as u128) * (rewards_rate as u128) * (num_successful_proposals as u128); - let rewards_denominator = (rewards_rate_denominator as u128) * (num_total_proposals as u128); + let rewards_numerator = + (stake_amount as u128) * (rewards_rate as u128) + * (num_successful_proposals as u128); + let rewards_denominator = + (rewards_rate_denominator as u128) * (num_total_proposals as u128); if (rewards_denominator != 0) { ((rewards_numerator / rewards_denominator) as u64) - } else { - 0 - } + } else { 0 } } /// Mint rewards corresponding to current epoch's `stake` and `num_successful_votes`. @@ -1731,22 +2088,22 @@ module supra_framework::stake { num_successful_proposals: u64, num_total_proposals: u64, rewards_rate: u64, - rewards_rate_denominator: u64, + rewards_rate_denominator: u64 ): u64 acquires SupraCoinCapabilities { let stake_amount = coin::value(stake); - let rewards_amount = if (stake_amount != 0) { - calculate_rewards_amount( - stake_amount, - num_successful_proposals, - num_total_proposals, - rewards_rate, - rewards_rate_denominator - ) - } else { - 0 - }; + let rewards_amount = + if (stake_amount != 0) { + calculate_rewards_amount( + stake_amount, + num_successful_proposals, + num_total_proposals, + rewards_rate, + rewards_rate_denominator + ) + } else { 0 }; if (rewards_amount != 0) { - let mint_cap = &borrow_global(@supra_framework).mint_cap; + let mint_cap = + &borrow_global(@supra_framework).mint_cap; let rewards = coin::mint(rewards_amount, mint_cap); coin::merge(stake, rewards); }; @@ -1776,13 +2133,11 @@ module supra_framework::stake { option::none() } - fun generate_validator_info(addr: address, stake_pool: &StakePool, config: ValidatorConfig): ValidatorInfo { + fun generate_validator_info( + addr: address, stake_pool: &StakePool, config: ValidatorConfig + ): ValidatorInfo { let voting_power = get_next_epoch_voting_power(stake_pool); - ValidatorInfo { - addr, - voting_power, - config, - } + ValidatorInfo { addr, voting_power, config } } /// Returns validator's next epoch voting power, including pending_active, active, and pending_inactive stake. @@ -1791,7 +2146,8 @@ module supra_framework::stake { let value_active = coin::value(&stake_pool.active); let value_pending_inactive = coin::value(&stake_pool.pending_inactive); spec { - assume value_pending_active + value_active + value_pending_inactive <= MAX_U64; + assume value_pending_active + value_active + value_pending_inactive + <= MAX_U64; }; value_pending_active + value_active + value_pending_inactive } @@ -1799,32 +2155,39 @@ module supra_framework::stake { fun update_voting_power_increase(increase_amount: u64) acquires ValidatorSet { let validator_set = borrow_global_mut(@supra_framework); let voting_power_increase_limit = - (staking_config::get_voting_power_increase_limit(&staking_config::get()) as u128); - validator_set.total_joining_power = validator_set.total_joining_power + (increase_amount as u128); + ( + staking_config::get_voting_power_increase_limit(&staking_config::get()) as u128 + ); + validator_set.total_joining_power = + validator_set.total_joining_power + (increase_amount as u128); // Only validator voting power increase if the current validator set's voting power > 0. if (validator_set.total_voting_power != 0) { assert!( - validator_set.total_joining_power <= validator_set.total_voting_power * voting_power_increase_limit / 100, - error::invalid_argument(EVOTING_POWER_INCREASE_EXCEEDS_LIMIT), + validator_set.total_joining_power + <= validator_set.total_voting_power * voting_power_increase_limit + / 100, + error::invalid_argument(EVOTING_POWER_INCREASE_EXCEEDS_LIMIT) ); } } fun assert_stake_pool_exists(pool_address: address) { - assert!(stake_pool_exists(pool_address), error::invalid_argument(ESTAKE_POOL_DOES_NOT_EXIST)); + assert!( + stake_pool_exists(pool_address), + error::invalid_argument(ESTAKE_POOL_DOES_NOT_EXIST) + ); } /// This provides an ACL for Testnet purposes. In testnet, everyone is a whale, a whale can be a validator. /// This allows a testnet to bring additional entities into the validator set without compromising the /// security of the testnet. This will NOT be enabled in Mainnet. struct AllowedValidators has key { - accounts: vector
, + accounts: vector
} public fun configure_allowed_validators( - supra_framework: &signer, - accounts: vector
+ supra_framework: &signer, accounts: vector
) acquires AllowedValidators { let supra_framework_address = signer::address_of(supra_framework); system_addresses::assert_supra_framework(supra_framework); @@ -1837,20 +2200,25 @@ module supra_framework::stake { } fun is_allowed(account: address): bool acquires AllowedValidators { - if (!exists(@supra_framework)) { - true - } else { + if (!exists(@supra_framework)) { true } + else { let allowed = borrow_global(@supra_framework); vector::contains(&allowed.accounts, &account) } } fun assert_owner_cap_exists(owner: address) { - assert!(exists(owner), error::not_found(EOWNER_CAP_NOT_FOUND)); + assert!( + exists(owner), + error::not_found(EOWNER_CAP_NOT_FOUND) + ); } fun assert_reconfig_not_in_progress() { - assert!(!reconfiguration_state::is_in_progress(), error::invalid_state(ERECONFIGURATION_IN_PROGRESS)); + assert!( + !reconfiguration_state::is_in_progress(), + error::invalid_state(ERECONFIGURATION_IN_PROGRESS) + ); } #[test_only] @@ -1870,17 +2238,26 @@ module supra_framework::stake { #[test_only] public fun initialize_for_test(supra_framework: &signer) { reconfiguration_state::initialize(supra_framework); - initialize_for_test_custom(supra_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 1000000); + initialize_for_test_custom( + supra_framework, + 100, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 100, + 1000000 + ); } #[test_only] public fun join_validator_set_for_test( - pk: &ed25519::UnvalidatedPublicKey, + pk: &validator_public_keys::ValidatorPublicKeys, operator: &signer, pool_address: address, - should_end_epoch: bool, + should_end_epoch: bool ) acquires SupraCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { - let pk_bytes = ed25519::unvalidated_public_key_to_bytes(pk); + let pk_bytes = validator_public_keys::public_key_to_bytes(*pk); rotate_consensus_key(operator, pool_address, pk_bytes); join_validator_set(operator, pool_address); if (should_end_epoch) { @@ -1889,8 +2266,9 @@ module supra_framework::stake { } #[test_only] - public fun fast_forward_to_unlock(pool_address: address) - acquires SupraCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + public fun fast_forward_to_unlock( + pool_address: address + ) acquires SupraCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { let expiration_time = get_lockup_secs(pool_address); timestamp::update_global_time_for_test_secs(expiration_time); end_epoch(); @@ -1906,7 +2284,7 @@ module supra_framework::stake { allow_validator_set_change: bool, rewards_rate_numerator: u64, rewards_rate_denominator: u64, - voting_power_increase_limit: u64, + voting_power_increase_limit: u64 ) { timestamp::set_time_has_started_for_testing(supra_framework); reconfiguration_state::initialize(supra_framework); @@ -1921,7 +2299,7 @@ module supra_framework::stake { allow_validator_set_change, rewards_rate_numerator, rewards_rate_denominator, - voting_power_increase_limit, + voting_power_increase_limit ); if (!exists(@supra_framework)) { @@ -1946,26 +2324,32 @@ module supra_framework::stake { #[test_only] public fun mint_and_add_stake( - account: &signer, amount: u64) acquires SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorSet { + account: &signer, amount: u64 + ) acquires SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorSet { mint(account, amount); add_stake(account, amount); } #[test_only] public fun initialize_test_validator( - public_key: &ed25519::UnvalidatedPublicKey, + public_key: &validator_public_keys::ValidatorPublicKeys, validator: &signer, amount: u64, should_join_validator_set: bool, - should_end_epoch: bool, + should_end_epoch: bool ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { let validator_address = signer::address_of(validator); if (!account::exists_at(signer::address_of(validator))) { account::create_account_for_test(validator_address); }; - let pk_bytes = ed25519::unvalidated_public_key_to_bytes(public_key); - initialize_validator(validator, pk_bytes, vector::empty(), vector::empty()); + let pk_bytes = validator_public_keys::public_key_to_bytes(*public_key); + initialize_validator( + validator, + pk_bytes, + vector::empty(), + vector::empty() + ); if (amount > 0) { mint_and_add_stake(validator, amount); @@ -1983,37 +2367,43 @@ module supra_framework::stake { public fun create_validator_set( supra_framework: &signer, active_validator_addresses: vector
, - public_keys: vector, + public_keys: vector ) { let active_validators = vector::empty(); let i = 0; while (i < vector::length(&active_validator_addresses)) { let validator_address = vector::borrow(&active_validator_addresses, i); let pk = vector::borrow(&public_keys, i); - vector::push_back(&mut active_validators, ValidatorInfo { - addr: *validator_address, - voting_power: 0, - config: ValidatorConfig { - consensus_pubkey: ed25519::unvalidated_public_key_to_bytes(pk), - network_addresses: b"", - fullnode_addresses: b"", - validator_index: 0, + vector::push_back( + &mut active_validators, + ValidatorInfo { + addr: *validator_address, + voting_power: 0, + config: ValidatorConfig { + consensus_pubkey: validator_public_keys::public_key_to_bytes(*pk), + network_addresses: b"", + fullnode_addresses: b"", + validator_index: 0 + } } - }); + ); i = i + 1; }; - move_to(supra_framework, ValidatorSet { - consensus_scheme: 0, - // active validators for the current epoch - active_validators, - // pending validators to leave in next epoch (still active) - pending_inactive: vector::empty(), - // pending validators to join in next epoch - pending_active: vector::empty(), - total_voting_power: 0, - total_joining_power: 0, - }); + move_to( + supra_framework, + ValidatorSet { + consensus_scheme: 0, + // active validators for the current epoch + active_validators, + // pending validators to leave in next epoch (still active) + pending_inactive: vector::empty(), + // pending validators to join in next epoch + pending_active: vector::empty(), + total_voting_power: 0, + total_joining_power: 0 + } + ); } #[test_only] @@ -2021,7 +2411,7 @@ module supra_framework::stake { account: &signer, active: Coin, pending_inactive: Coin, - locked_until_secs: u64, + locked_until_secs: u64 ) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet { let account_address = signer::address_of(account); initialize_stake_owner(account, 0, account_address, account_address); @@ -2034,24 +2424,23 @@ module supra_framework::stake { // Allows unit tests to set custom validator performances. #[test_only] public fun update_validator_performances_for_test( - proposer_index: Option, - failed_proposer_indices: vector, + proposer_index: Option, failed_proposer_indices: vector ) acquires ValidatorPerformance { update_performance_statistics(proposer_index, failed_proposer_indices); } #[test_only] - public fun generate_identity(): (ed25519::SecretKey, ed25519::UnvalidatedPublicKey) { - let (sk, validated_pub_key) = ed25519::generate_keys(); - let unvalidated_pk = ed25519::public_key_to_unvalidated(&validated_pub_key); - (sk, unvalidated_pk) + public fun generate_identity(): ( + validator_public_keys::ValidatorSecretKeys, + validator_public_keys::ValidatorPublicKeys + ) { + validator_public_keys::generate_keys() } #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x10007, location = Self)] public entry fun test_inactive_validator_can_add_stake_if_exceeding_max_allowed( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2064,11 +2453,18 @@ module supra_framework::stake { #[test(supra_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234)] #[expected_failure(abort_code = 0x10007, location = Self)] public entry fun test_pending_active_validator_cannot_add_stake_if_exceeding_max_allowed( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100000); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 100000 + ); // Have one validator join the set to ensure the validator set is not empty when main validator joins. let (_sk_1, pk_1) = generate_identity(); initialize_test_validator(&pk_1, validator_1, 100, true, true); @@ -2084,8 +2480,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x10007, location = Self)] public entry fun test_active_validator_cannot_add_stake_if_exceeding_max_allowed( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); // Validator joins validator set and waits for epoch end so it's in the validator set. @@ -2099,8 +2494,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x10007, location = Self)] public entry fun test_active_validator_with_pending_inactive_stake_cannot_add_stake_if_exceeding_max_allowed( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); // Validator joins validator set and waits for epoch end so it's in the validator set. @@ -2118,9 +2512,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] #[expected_failure(abort_code = 0x10007, location = Self)] public entry fun test_pending_inactive_cannot_add_stake_if_exceeding_max_allowed( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk_1, pk_1) = generate_identity(); @@ -2137,8 +2529,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_end_to_end( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2194,8 +2585,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_inactive_validator_with_existing_lockup_join_validator_set( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2205,7 +2595,10 @@ module supra_framework::stake { increase_lockup(validator); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS / 2); let validator_address = signer::address_of(validator); - assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS / 2, 1); + assert!( + get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS / 2, + 1 + ); // Join the validator set with an existing lockup join_validator_set(validator, validator_address); @@ -2213,15 +2606,18 @@ module supra_framework::stake { // Validator is added to the set but lockup time shouldn't have changed. end_epoch(); assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_ACTIVE, 2); - assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS / 2 - EPOCH_DURATION, 3); + assert!( + get_remaining_lockup_secs(validator_address) + == LOCKUP_CYCLE_SECONDS / 2 - EPOCH_DURATION, + 3 + ); assert_validator_state(validator_address, 100, 0, 0, 0, 0); } #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x10012, location = Self)] public entry fun test_cannot_reduce_lockup( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2238,12 +2634,19 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] #[expected_failure(abort_code = 0x1000D, location = Self)] public entry fun test_inactive_validator_cannot_join_if_exceed_increase_limit( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // Only 50% voting power increase is allowed in each epoch. - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 50 + ); let (_sk_1, pk_1) = generate_identity(); let (_sk_2, pk_2) = generate_identity(); initialize_test_validator(&pk_1, validator_1, 100, false, false); @@ -2260,11 +2663,18 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] public entry fun test_pending_active_validator_can_add_more_stake( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 10000); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 10000 + ); // Need 1 validator to be in the active validator set so joining limit works. let (_sk_1, pk_1) = generate_identity(); let (_sk_2, pk_2) = generate_identity(); @@ -2274,7 +2684,10 @@ module supra_framework::stake { // Add more stake while still pending_active. let validator_2_address = signer::address_of(validator_2); join_validator_set(validator_2, validator_2_address); - assert!(get_validator_state(validator_2_address) == VALIDATOR_STATUS_PENDING_ACTIVE, 0); + assert!( + get_validator_state(validator_2_address) == VALIDATOR_STATUS_PENDING_ACTIVE, + 0 + ); mint_and_add_stake(validator_2, 100); assert_validator_state(validator_2_address, 200, 0, 0, 0, 0); } @@ -2282,12 +2695,19 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] #[expected_failure(abort_code = 0x1000D, location = Self)] public entry fun test_pending_active_validator_cannot_add_more_stake_than_limit( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // 100% voting power increase is allowed in each epoch. - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 100 + ); // Need 1 validator to be in the active validator set so joining limit works. let (_sk_1, pk_1) = generate_identity(); initialize_test_validator(&pk_1, validator_1, 100, true, true); @@ -2303,35 +2723,49 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_pending_active_validator_leaves_validator_set( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); // Validator joins but epoch hasn't ended, so the validator is still pending_active. let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 100, true, false); let validator_address = signer::address_of(validator); - assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_PENDING_ACTIVE, 0); + assert!( + get_validator_state(validator_address) == VALIDATOR_STATUS_PENDING_ACTIVE, + 0 + ); // Check that voting power increase is tracked. - assert!(borrow_global(@supra_framework).total_joining_power == 100, 0); + assert!( + borrow_global(@supra_framework).total_joining_power == 100, 0 + ); // Leave the validator set immediately. leave_validator_set(validator, validator_address); assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_INACTIVE, 1); // Check that voting power increase has been decreased when the pending active validator leaves. - assert!(borrow_global(@supra_framework).total_joining_power == 0, 1); + assert!( + borrow_global(@supra_framework).total_joining_power == 0, 1 + ); } #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x1000D, location = Self)] public entry fun test_active_validator_cannot_add_more_stake_than_limit_in_multiple_epochs( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // Only 50% voting power increase is allowed in each epoch. - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 50 + ); // Add initial stake and join the validator set. let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 100, true, true); @@ -2349,11 +2783,19 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x1000D, location = Self)] public entry fun test_active_validator_cannot_add_more_stake_than_limit( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // Only 50% voting power increase is allowed in each epoch. - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 50 + ); let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 100, true, true); @@ -2363,11 +2805,19 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_active_validator_unlock_partial_stake( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // Reward rate = 10%. - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 100); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 100 + ); let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 100, true, true); @@ -2389,8 +2839,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_active_validator_can_withdraw_all_stake_and_rewards_at_once( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2404,7 +2853,11 @@ module supra_framework::stake { assert_validator_state(validator_address, 101, 0, 0, 0, 0); // Unlock all coins while still having a lockup. - assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, 2); + assert!( + get_remaining_lockup_secs(validator_address) + == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, + 2 + ); unlock(validator, 101); assert_validator_state(validator_address, 0, 0, 0, 101, 0); @@ -2426,8 +2879,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_active_validator_unlocking_more_than_available_stake_should_cap( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2440,8 +2892,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_active_validator_withdraw_should_cap_by_inactive_stake( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); // Initial balance = 900 (idle) + 100 (staked) = 1000. @@ -2465,8 +2916,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_active_validator_can_reactivate_pending_inactive_stake( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2484,8 +2934,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_active_validator_reactivate_more_than_available_pending_inactive_stake_should_cap( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2501,8 +2950,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_active_validator_having_insufficient_remaining_stake_after_withdrawal_gets_kicked( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2528,9 +2976,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123, validator_2 = @0x234)] public entry fun test_active_validator_leaves_staking_but_still_has_a_lockup( - supra_framework: &signer, - validator: &signer, - validator_2: &signer, + supra_framework: &signer, validator: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk_1, pk_1) = generate_identity(); @@ -2544,7 +2990,10 @@ module supra_framework::stake { assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS, 0); leave_validator_set(validator, validator_address); // Validator is in pending_inactive state but is technically still part of the validator set. - assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_PENDING_INACTIVE, 2); + assert!( + get_validator_state(validator_address) == VALIDATOR_STATUS_PENDING_INACTIVE, + 2 + ); assert_validator_state(validator_address, 100, 0, 0, 0, 1); end_epoch(); @@ -2552,7 +3001,11 @@ module supra_framework::stake { assert!(get_validator_state(validator_address) == VALIDATOR_STATUS_INACTIVE, 3); // However, their stake, including rewards, should still subject to the existing lockup. assert_validator_state(validator_address, 101, 0, 0, 0, 1); - assert!(get_remaining_lockup_secs(validator_address) == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, 4); + assert!( + get_remaining_lockup_secs(validator_address) + == LOCKUP_CYCLE_SECONDS - EPOCH_DURATION, + 4 + ); // If they try to unlock, their stake is moved to pending_inactive and would only be withdrawable after the // lockup has expired. @@ -2572,9 +3025,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123, validator_2 = @0x234)] public entry fun test_active_validator_leaves_staking_and_rejoins_with_expired_lockup_should_be_renewed( - supra_framework: &signer, - validator: &signer, - validator_2: &signer, + supra_framework: &signer, validator: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk_1, pk_1) = generate_identity(); @@ -2603,12 +3054,19 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] public entry fun test_pending_inactive_validator_does_not_count_in_increase_limit( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // Only 50% voting power increase is allowed in each epoch. - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 10, 50); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 10, + 50 + ); let (_sk_1, pk_1) = generate_identity(); let (_sk_2, pk_2) = generate_identity(); initialize_test_validator(&pk_1, validator_1, 100, true, false); @@ -2621,7 +3079,14 @@ module supra_framework::stake { mint_and_add_stake(validator_1, 51); } - #[test(supra_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234, validator_3 = @0x345)] + #[ + test( + supra_framework = @0x1, + validator_1 = @0x123, + validator_2 = @0x234, + validator_3 = @0x345 + ) + ] public entry fun test_multiple_validators_join_and_leave( supra_framework: &signer, validator_1: &signer, @@ -2632,9 +3097,18 @@ module supra_framework::stake { let validator_2_address = signer::address_of(validator_2); let validator_3_address = signer::address_of(validator_3); - initialize_for_test_custom(supra_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100); + initialize_for_test_custom( + supra_framework, + 100, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 100, + 100 + ); let (_sk_1, pk_1) = generate_identity(); - let pk_1_bytes = ed25519::unvalidated_public_key_to_bytes(&pk_1); + let pk_1_bytes = validator_public_keys::public_key_to_bytes(pk_1); let (_sk_2, pk_2) = generate_identity(); let (_sk_3, pk_3) = generate_identity(); initialize_test_validator(&pk_1, validator_1, 100, false, false); @@ -2661,12 +3135,16 @@ module supra_framework::stake { // Validator 1 rotates consensus key. Validator 2 leaves. Validator 3 joins. let (_sk_1b, pk_1b) = generate_identity(); - let pk_1b_bytes = ed25519::unvalidated_public_key_to_bytes(&pk_1b); + let pk_1b_bytes = validator_public_keys::public_key_to_bytes(pk_1b); rotate_consensus_key(validator_1, validator_1_address, pk_1b_bytes); leave_validator_set(validator_2, validator_2_address); join_validator_set(validator_3, validator_3_address); // Validator 2 is not effectively removed until next epoch. - assert!(get_validator_state(validator_2_address) == VALIDATOR_STATUS_PENDING_INACTIVE, 6); + assert!( + get_validator_state(validator_2_address) + == VALIDATOR_STATUS_PENDING_INACTIVE, + 6 + ); assert!( vector::borrow( &borrow_global(@supra_framework).pending_inactive, @@ -2675,7 +3153,10 @@ module supra_framework::stake { 0 ); // Validator 3 is not effectively added until next epoch. - assert!(get_validator_state(validator_3_address) == VALIDATOR_STATUS_PENDING_ACTIVE, 7); + assert!( + get_validator_state(validator_3_address) == VALIDATOR_STATUS_PENDING_ACTIVE, + 7 + ); assert!( vector::borrow( &borrow_global(@supra_framework).pending_active, @@ -2713,15 +3194,25 @@ module supra_framework::stake { unlock(validator_1, 50); timestamp::fast_forward_seconds(LOCKUP_CYCLE_SECONDS); end_epoch(); - assert!(get_validator_state(validator_1_address) == VALIDATOR_STATUS_INACTIVE, 11); + assert!( + get_validator_state(validator_1_address) == VALIDATOR_STATUS_INACTIVE, 11 + ); } #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_delegated_staking_with_owner_cap( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { - initialize_for_test_custom(supra_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100); + initialize_for_test_custom( + supra_framework, + 100, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 100, + 100 + ); let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 0, false, false); let owner_cap = extract_owner_cap(validator); @@ -2750,7 +3241,7 @@ module supra_framework::stake { // Operator can separately rotate consensus key. let (_sk_new, pk_new) = generate_identity(); - let pk_new_bytes = ed25519::unvalidated_public_key_to_bytes(&pk_new); + let pk_new_bytes = validator_public_keys::public_key_to_bytes(pk_new); rotate_consensus_key(validator, pool_address, pk_new_bytes); let validator_config = borrow_global(pool_address); assert!(validator_config.consensus_pubkey == pk_new_bytes, 2); @@ -2770,10 +3261,18 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x1000A, location = Self)] public entry fun test_validator_cannot_join_post_genesis( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { - initialize_for_test_custom(supra_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100); + initialize_for_test_custom( + supra_framework, + 100, + 10000, + LOCKUP_CYCLE_SECONDS, + false, + 1, + 100, + 100 + ); // Joining the validator set should fail as post genesis validator set change is not allowed. let (_sk, pk) = generate_identity(); @@ -2783,8 +3282,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x1000E, location = Self)] public entry fun test_invalid_pool_address( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); @@ -2795,10 +3293,18 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x1000A, location = Self)] public entry fun test_validator_cannot_leave_post_genesis( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { - initialize_for_test_custom(supra_framework, 100, 10000, LOCKUP_CYCLE_SECONDS, false, 1, 100, 100); + initialize_for_test_custom( + supra_framework, + 100, + 10000, + LOCKUP_CYCLE_SECONDS, + false, + 1, + 100, + 100 + ); let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 100, false, false); @@ -2811,21 +3317,23 @@ module supra_framework::stake { leave_validator_set(validator, validator_address); } - #[test( - supra_framework = @supra_framework, - validator_1 = @supra_framework, - validator_2 = @0x2, - validator_3 = @0x3, - validator_4 = @0x4, - validator_5 = @0x5 - )] + #[ + test( + supra_framework = @supra_framework, + validator_1 = @supra_framework, + validator_2 = @0x2, + validator_3 = @0x3, + validator_4 = @0x4, + validator_5 = @0x5 + ) + ] fun test_validator_consensus_infos_from_validator_set( supra_framework: &signer, validator_1: &signer, validator_2: &signer, validator_3: &signer, validator_4: &signer, - validator_5: &signer, + validator_5: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { let v1_addr = signer::address_of(validator_1); let v2_addr = signer::address_of(validator_2); @@ -2854,47 +3362,73 @@ module supra_framework::stake { join_validator_set(validator_1, v1_addr); join_validator_set(validator_5, v5_addr); end_epoch(); - let vci_vec_0 = validator_consensus_infos_from_validator_set(borrow_global(@supra_framework)); - let vci_addrs = vector::map_ref(&vci_vec_0, |obj|{ - let vci: &ValidatorConsensusInfo = obj; - validator_consensus_info::get_addr(vci) - }); - let vci_voting_powers = vector::map_ref(&vci_vec_0, |obj|{ - let vci: &ValidatorConsensusInfo = obj; - validator_consensus_info::get_voting_power(vci) - }); - assert!(vector[@0x5, @supra_framework, @0x3] == vci_addrs, 1); + let vci_vec_0 = + validator_consensus_infos_from_validator_set( + borrow_global(@supra_framework) + ); + let vci_addrs = vector::map_ref( + &vci_vec_0, + |obj| { + let vci: &ValidatorConsensusInfo = obj; + validator_consensus_info::get_addr(vci) + } + ); + let vci_voting_powers = vector::map_ref( + &vci_vec_0, + |obj| { + let vci: &ValidatorConsensusInfo = obj; + validator_consensus_info::get_voting_power(vci) + } + ); + assert!( + vector[@0x5, @supra_framework, @0x3] == vci_addrs, + 1 + ); // assert!(vector[pk_5_bytes, pk_1_bytes, pk_3_bytes] == vci_pks, 2); assert!(vector[105, 101, 103] == vci_voting_powers, 3); leave_validator_set(validator_3, v3_addr); - let vci_vec_1 = validator_consensus_infos_from_validator_set(borrow_global(@supra_framework)); + let vci_vec_1 = + validator_consensus_infos_from_validator_set( + borrow_global(@supra_framework) + ); assert!(vci_vec_0 == vci_vec_1, 11); join_validator_set(validator_2, v2_addr); - let vci_vec_2 = validator_consensus_infos_from_validator_set(borrow_global(@supra_framework)); + let vci_vec_2 = + validator_consensus_infos_from_validator_set( + borrow_global(@supra_framework) + ); assert!(vci_vec_0 == vci_vec_2, 12); leave_validator_set(validator_1, v1_addr); - let vci_vec_3 = validator_consensus_infos_from_validator_set(borrow_global(@supra_framework)); + let vci_vec_3 = + validator_consensus_infos_from_validator_set( + borrow_global(@supra_framework) + ); assert!(vci_vec_0 == vci_vec_3, 13); join_validator_set(validator_4, v4_addr); - let vci_vec_4 = validator_consensus_infos_from_validator_set(borrow_global(@supra_framework)); + let vci_vec_4 = + validator_consensus_infos_from_validator_set( + borrow_global(@supra_framework) + ); assert!(vci_vec_0 == vci_vec_4, 14); } - #[test( - supra_framework = @supra_framework, - validator_1 = @supra_framework, - validator_2 = @0x2, - validator_3 = @0x3, - validator_4 = @0x4, - validator_5 = @0x5 - )] + #[ + test( + supra_framework = @supra_framework, + validator_1 = @supra_framework, + validator_2 = @0x2, + validator_3 = @0x3, + validator_4 = @0x4, + validator_5 = @0x5 + ) + ] public entry fun test_staking_validator_index( supra_framework: &signer, validator_1: &signer, validator_2: &signer, validator_3: &signer, validator_4: &signer, - validator_5: &signer, + validator_5: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { let v1_addr = signer::address_of(validator_1); let v2_addr = signer::address_of(validator_2); @@ -2955,9 +3489,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] public entry fun test_validator_rewards_are_performance_based( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); @@ -2972,8 +3504,10 @@ module supra_framework::stake { // Validator 2 failed proposal. let failed_proposer_indices = vector::empty(); - let validator_1_index = borrow_global(validator_1_address).validator_index; - let validator_2_index = borrow_global(validator_2_address).validator_index; + let validator_1_index = + borrow_global(validator_1_address).validator_index; + let validator_2_index = + borrow_global(validator_2_address).validator_index; vector::push_back(&mut failed_proposer_indices, validator_2_index); let proposer_indices = option::some(validator_1_index); update_performance_statistics(proposer_indices, failed_proposer_indices); @@ -2987,8 +3521,10 @@ module supra_framework::stake { unlock(validator_2, 100); leave_validator_set(validator_2, validator_2_address); let failed_proposer_indices = vector::empty(); - let validator_1_index = borrow_global(validator_1_address).validator_index; - let validator_2_index = borrow_global(validator_2_address).validator_index; + let validator_1_index = + borrow_global(validator_1_address).validator_index; + let validator_2_index = + borrow_global(validator_2_address).validator_index; vector::push_back(&mut failed_proposer_indices, validator_1_index); vector::push_back(&mut failed_proposer_indices, validator_2_index); update_performance_statistics(option::none(), failed_proposer_indices); @@ -3003,9 +3539,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] public entry fun test_validator_rewards_rate_decrease_over_time( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); @@ -3033,9 +3567,13 @@ module supra_framework::stake { fixed_point64::create_from_rational(3, 1000), one_year_in_secs, genesis_time_in_secs, - fixed_point64::create_from_rational(50, 100), + fixed_point64::create_from_rational(50, 100) + ); + features::change_feature_flags_for_testing( + supra_framework, + vector[features::get_periodical_reward_rate_decrease_feature()], + vector[] ); - features::change_feature_flags_for_testing(supra_framework, vector[features::get_periodical_reward_rate_decrease_feature()], vector[]); // For some reason, this epoch is very long. It has been 1 year since genesis when the epoch ends. timestamp::fast_forward_seconds(one_year_in_secs - EPOCH_DURATION * 3); @@ -3060,8 +3598,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_update_performance_statistics_should_not_fail_due_to_out_of_bounds( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); @@ -3069,7 +3606,8 @@ module supra_framework::stake { let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 100, true, true); - let valid_validator_index = borrow_global(validator_address).validator_index; + let valid_validator_index = + borrow_global(validator_address).validator_index; let out_of_bounds_index = valid_validator_index + 100; // Invalid validator index in the failed proposers vector should not lead to abort. @@ -3091,15 +3629,28 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] #[expected_failure(abort_code = 0x1000B, location = Self)] public entry fun test_invalid_config( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet { - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 100, + 100 + ); // Call initialize_stake_owner, which only initializes the stake pool but not validator config. let validator_address = signer::address_of(validator); account::create_account_for_test(validator_address); - initialize_stake_owner(validator, 0, validator_address, validator_address); + initialize_stake_owner( + validator, + 0, + validator_address, + validator_address + ); mint_and_add_stake(validator, 100); // Join the validator set with enough stake. This should fail because the validator didn't initialize validator @@ -3109,21 +3660,34 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_valid_config( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet { - initialize_for_test_custom(supra_framework, 50, 10000, LOCKUP_CYCLE_SECONDS, true, 1, 100, 100); + initialize_for_test_custom( + supra_framework, + 50, + 10000, + LOCKUP_CYCLE_SECONDS, + true, + 1, + 100, + 100 + ); // Call initialize_stake_owner, which only initializes the stake pool but not validator config. let validator_address = signer::address_of(validator); account::create_account_for_test(validator_address); - initialize_stake_owner(validator, 0, validator_address, validator_address); + initialize_stake_owner( + validator, + 0, + validator_address, + validator_address + ); mint_and_add_stake(validator, 100); // Initialize validator config. let validator_address = signer::address_of(validator); let (_sk_new, pk_new) = generate_identity(); - let pk_new_bytes = ed25519::unvalidated_public_key_to_bytes(&pk_new); + let pk_new_bytes = validator_public_keys::public_key_to_bytes(pk_new); rotate_consensus_key(validator, validator_address, pk_new_bytes); // Join the validator set with enough stake. This now wouldn't fail since the validator config already exists. @@ -3137,13 +3701,14 @@ module supra_framework::stake { let num_total_proposals = 200; let rewards_rate = 700; let rewards_rate_denominator = 777; - let rewards_amount = calculate_rewards_amount( - stake_amount, - num_successful_proposals, - num_total_proposals, - rewards_rate, - rewards_rate_denominator - ); + let rewards_amount = + calculate_rewards_amount( + stake_amount, + num_successful_proposals, + num_total_proposals, + rewards_rate, + rewards_rate_denominator + ); // Consider `amount_imprecise` and `amount_precise` defined as follows: // amount_imprecise = (stake_amount * rewards_rate / rewards_rate_denominator) * num_successful_proposals / num_total_proposals // amount_precise = stake_amount * rewards_rate * num_successful_proposals / (rewards_rate_denominator * num_total_proposals) @@ -3158,50 +3723,65 @@ module supra_framework::stake { let rewards_rate = 3141592; let rewards_rate_denominator = 10000000; // This should not abort due to an arithmetic overflow. - let rewards_amount = calculate_rewards_amount( - stake_amount, - num_successful_proposals, - num_total_proposals, - rewards_rate, - rewards_rate_denominator - ); + let rewards_amount = + calculate_rewards_amount( + stake_amount, + num_successful_proposals, + num_total_proposals, + rewards_rate, + rewards_rate_denominator + ); assert!(rewards_amount == 31412778408000000, 0); } #[test_only] public fun set_validator_perf_at_least_one_block() acquires ValidatorPerformance { let validator_perf = borrow_global_mut(@supra_framework); - vector::for_each_mut(&mut validator_perf.validators, |validator|{ - let validator: &mut IndividualValidatorPerformance = validator; - if (validator.successful_proposals + validator.failed_proposals < 1) { - validator.successful_proposals = 1; - }; - }); + vector::for_each_mut( + &mut validator_perf.validators, + |validator| { + let validator: &mut IndividualValidatorPerformance = validator; + if (validator.successful_proposals + validator.failed_proposals < 1) { + validator.successful_proposals = 1; + }; + } + ); } #[test(supra_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234)] public entry fun test_removing_validator_from_active_set( - supra_framework: &signer, - validator_1: &signer, - validator_2: &signer, + supra_framework: &signer, validator_1: &signer, validator_2: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { initialize_for_test(supra_framework); let (_sk_1, pk_1) = generate_identity(); let (_sk_2, pk_2) = generate_identity(); initialize_test_validator(&pk_1, validator_1, 100, true, false); initialize_test_validator(&pk_2, validator_2, 100, true, true); - assert!(vector::length(&borrow_global(@supra_framework).active_validators) == 2, 0); + assert!( + vector::length( + &borrow_global(@supra_framework).active_validators + ) == 2, + 0 + ); // Remove validator 1 from the active validator set. Only validator 2 remains. let validator_to_remove = signer::address_of(validator_1); remove_validators(supra_framework, &vector[validator_to_remove]); - assert!(vector::length(&borrow_global(@supra_framework).active_validators) == 1, 0); - assert!(get_validator_state(validator_to_remove) == VALIDATOR_STATUS_PENDING_INACTIVE, 1); + assert!( + vector::length( + &borrow_global(@supra_framework).active_validators + ) == 1, + 0 + ); + assert!( + get_validator_state(validator_to_remove) + == VALIDATOR_STATUS_PENDING_INACTIVE, + 1 + ); } #[test_only] - public fun end_epoch( - ) acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + public fun end_epoch() acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // Set the number of blocks to 1, to give out rewards to non-failing validators. set_validator_perf_at_least_one_block(); timestamp::fast_forward_seconds(EPOCH_DURATION); @@ -3216,7 +3796,7 @@ module supra_framework::stake { active_stake: u64, inactive_stake: u64, pending_active_stake: u64, - pending_inactive_stake: u64, + pending_inactive_stake: u64 ) acquires StakePool { let stake_pool = borrow_global(pool_address); let actual_active_stake = coin::value(&stake_pool.active); @@ -3224,9 +3804,15 @@ module supra_framework::stake { let actual_inactive_stake = coin::value(&stake_pool.inactive); assert!(actual_inactive_stake == inactive_stake, actual_inactive_stake); let actual_pending_active_stake = coin::value(&stake_pool.pending_active); - assert!(actual_pending_active_stake == pending_active_stake, actual_pending_active_stake); + assert!( + actual_pending_active_stake == pending_active_stake, + actual_pending_active_stake + ); let actual_pending_inactive_stake = coin::value(&stake_pool.pending_inactive); - assert!(actual_pending_inactive_stake == pending_inactive_stake, actual_pending_inactive_stake); + assert!( + actual_pending_inactive_stake == pending_inactive_stake, + actual_pending_inactive_stake + ); } #[test_only] @@ -3236,17 +3822,25 @@ module supra_framework::stake { inactive_stake: u64, pending_active_stake: u64, pending_inactive_stake: u64, - validator_index: u64, + validator_index: u64 ) acquires StakePool, ValidatorConfig { - assert_stake_pool(pool_address, active_stake, inactive_stake, pending_active_stake, pending_inactive_stake); + assert_stake_pool( + pool_address, + active_stake, + inactive_stake, + pending_active_stake, + pending_inactive_stake + ); let validator_config = borrow_global(pool_address); - assert!(validator_config.validator_index == validator_index, validator_config.validator_index); + assert!( + validator_config.validator_index == validator_index, + validator_config.validator_index + ); } #[test(supra_framework = @0x1, validator = @0x123)] public entry fun test_allowed_validators( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet { let addr = signer::address_of(validator); let (burn, mint) = supra_coin::initialize_for_test(supra_framework); @@ -3262,8 +3856,7 @@ module supra_framework::stake { #[test(supra_framework = @0x1, validator = @0x123)] #[expected_failure(abort_code = 0x60011, location = Self)] public entry fun test_not_allowed_validators( - supra_framework: &signer, - validator: &signer, + supra_framework: &signer, validator: &signer ) acquires AllowedValidators, OwnerCapability, StakePool, ValidatorSet { configure_allowed_validators(supra_framework, vector[]); let (burn, mint) = supra_coin::initialize_for_test(supra_framework); @@ -3278,7 +3871,8 @@ module supra_framework::stake { #[test_only] public fun with_rewards(amount: u64): u64 { - let (numerator, denominator) = staking_config::get_reward_rate(&staking_config::get()); + let (numerator, denominator) = + staking_config::get_reward_rate(&staking_config::get()); amount + amount * numerator / denominator } @@ -3298,15 +3892,24 @@ module supra_framework::stake { #[test_only] const COLLECT_AND_DISTRIBUTE_GAS_FEES: u64 = 6; - #[test(supra_framework = @0x1, validator_1 = @0x123, validator_2 = @0x234, validator_3 = @0x345)] + #[ + test( + supra_framework = @0x1, + validator_1 = @0x123, + validator_2 = @0x234, + validator_3 = @0x345 + ) + ] fun test_distribute_validator_fees( supra_framework: &signer, validator_1: &signer, validator_2: &signer, - validator_3: &signer, + validator_3: &signer ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { // Make sure that fees collection and distribution is enabled. - features::change_feature_flags_for_testing(supra_framework, vector[COLLECT_AND_DISTRIBUTE_GAS_FEES], vector[]); + features::change_feature_flags_for_testing( + supra_framework, vector[COLLECT_AND_DISTRIBUTE_GAS_FEES], vector[] + ); assert!(features::collect_and_distribute_gas_fees(), 0); // Initialize staking and validator fees table. diff --git a/aptos-move/framework/supra-framework/sources/stake.spec.move b/aptos-move/framework/supra-framework/sources/stake.spec.move index 3885edda470..c619f126fde 100644 --- a/aptos-move/framework/supra-framework/sources/stake.spec.move +++ b/aptos-move/framework/supra-framework/sources/stake.spec.move @@ -131,10 +131,11 @@ spec supra_framework::stake { network_addresses: vector, fullnode_addresses: vector, ){ - let is_public_key_validated = ed25519::spec_public_key_validate_internal( + //todo: fix this validation + /*let is_public_key_validated = consensus_key::spec_cg_pk_valid( consensus_pubkey, ); - aborts_if !is_public_key_validated; + aborts_if !is_public_key_validated;*/ let addr = signer::address_of(account); let post_addr = signer::address_of(account); let allowed = global(@supra_framework); @@ -407,10 +408,12 @@ spec supra_framework::stake { aborts_if !exists(pool_address); aborts_if signer::address_of(operator) != pre_stake_pool.operator_address; aborts_if !exists(pool_address); - let is_public_key_validated = ed25519::spec_public_key_validate_internal( + + //todo: fix this check + /*let is_public_key_validated = ed25519::spec_public_key_validate_internal( new_consensus_pubkey, ); - aborts_if !is_public_key_validated; + aborts_if !is_public_key_validated;*/ modifies global(pool_address); include StakedValueNochange; diff --git a/aptos-move/framework/supra-framework/sources/supra_governance.move b/aptos-move/framework/supra-framework/sources/supra_governance.move index 6f49a9b4378..e5128fb0b6b 100644 --- a/aptos-move/framework/supra-framework/sources/supra_governance.move +++ b/aptos-move/framework/supra-framework/sources/supra_governance.move @@ -57,13 +57,13 @@ module supra_framework::supra_governance { /// Store the SignerCapabilities of accounts under the on-chain governance's control. struct GovernanceResponsbility has key { - signer_caps: SimpleMap, + signer_caps: SimpleMap } /// Used to track which execution script hashes have been approved by governance. /// This is required to bypass cases where the execution scripts exceed the size limit imposed by mempool. struct ApprovedExecutionHashes has key { - hashes: SimpleMap>, + hashes: SimpleMap> } /// Configurations of the SupraGovernance, set during Genesis and can be updated by the same process offered @@ -71,14 +71,14 @@ module supra_framework::supra_governance { struct SupraGovernanceConfig has key { voting_duration_secs: u64, min_voting_threshold: u64, - voters: vector
, + voters: vector
} /// Events generated by interactions with the SupraGovernance module. struct SupraGovernanceEvents has key { create_proposal_events: EventHandle, update_config_events: EventHandle, - vote_events: EventHandle, + vote_events: EventHandle } /// Event emitted when a proposal is created. @@ -86,21 +86,21 @@ module supra_framework::supra_governance { proposer: address, proposal_id: u64, execution_hash: vector, - proposal_metadata: SimpleMap>, + proposal_metadata: SimpleMap> } /// Event emitted when the governance configs are updated. struct SupraUpdateConfigEvent has drop, store { voting_duration_secs: u64, min_voting_threshold: u64, - voters: vector
, + voters: vector
} /// Event emitted when there's a vote on a proposa; struct SupraVoteEvent has drop, store { proposal_id: u64, voter: address, - should_pass: bool, + should_pass: bool } #[event] @@ -109,7 +109,7 @@ module supra_framework::supra_governance { proposer: address, proposal_id: u64, execution_hash: vector, - proposal_metadata: SimpleMap>, + proposal_metadata: SimpleMap> } #[event] @@ -117,7 +117,7 @@ module supra_framework::supra_governance { struct SupraVote has drop, store { proposal_id: u64, voter: address, - should_pass: bool, + should_pass: bool } #[event] @@ -125,15 +125,13 @@ module supra_framework::supra_governance { struct SupraUpdateConfig has drop, store { voting_duration_secs: u64, min_voting_threshold: u64, - voters: vector
, + voters: vector
} /// Can be called during genesis or by the governance itself. /// Stores the signer capability for a given address. public fun store_signer_cap( - supra_framework: &signer, - signer_address: address, - signer_cap: SignerCapability, + supra_framework: &signer, signer_address: address, signer_cap: SignerCapability ) acquires GovernanceResponsbility { system_addresses::assert_supra_framework(supra_framework); system_addresses::assert_framework_reserved(signer_address); @@ -141,11 +139,14 @@ module supra_framework::supra_governance { if (!exists(@supra_framework)) { move_to( supra_framework, - GovernanceResponsbility { signer_caps: simple_map::create() } + GovernanceResponsbility { + signer_caps: simple_map::create() + } ); }; - let signer_caps = &mut borrow_global_mut(@supra_framework).signer_caps; + let signer_caps = + &mut borrow_global_mut(@supra_framework).signer_caps; simple_map::add(signer_caps, signer_address, signer_cap); } @@ -156,26 +157,42 @@ module supra_framework::supra_governance { supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, - voters: vector
, + voters: vector
) { multisig_voting::register(supra_framework); - assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS)); - assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE)); + assert!( + vector::length(&voters) >= min_voting_threshold + && min_voting_threshold > vector::length(&voters) / 2, + error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS) + ); + assert!( + min_voting_threshold > 1, + error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE) + ); - move_to(supra_framework, SupraGovernanceConfig { - voting_duration_secs, - min_voting_threshold, - voters, - }); - move_to(supra_framework, SupraGovernanceEvents { - create_proposal_events: account::new_event_handle(supra_framework), - update_config_events: account::new_event_handle(supra_framework), - vote_events: account::new_event_handle(supra_framework), - }); - move_to(supra_framework, ApprovedExecutionHashes { - hashes: simple_map::create>(), - }) + move_to( + supra_framework, + SupraGovernanceConfig { voting_duration_secs, min_voting_threshold, voters } + ); + move_to( + supra_framework, + SupraGovernanceEvents { + create_proposal_events: account::new_event_handle( + supra_framework + ), + update_config_events: account::new_event_handle( + supra_framework + ), + vote_events: account::new_event_handle(supra_framework) + } + ); + move_to( + supra_framework, + ApprovedExecutionHashes { + hashes: simple_map::create>() + } + ) } /// Update the governance configurations. This can only be called as part of resolving a proposal in this same @@ -184,35 +201,35 @@ module supra_framework::supra_governance { supra_framework: &signer, voting_duration_secs: u64, min_voting_threshold: u64, - voters: vector
, + voters: vector
) acquires SupraGovernanceConfig, SupraGovernanceEvents { system_addresses::assert_supra_framework(supra_framework); - assert!(vector::length(&voters) >= min_voting_threshold && min_voting_threshold > vector::length(&voters) / 2, error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS)); - assert!(min_voting_threshold > 1, error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE)); + assert!( + vector::length(&voters) >= min_voting_threshold + && min_voting_threshold > vector::length(&voters) / 2, + error::invalid_argument(ETHRESHOLD_EXCEEDS_VOTERS) + ); + assert!( + min_voting_threshold > 1, + error::invalid_argument(ETHRESHOLD_MUST_BE_GREATER_THAN_ONE) + ); - let supra_governance_config = borrow_global_mut(@supra_framework); + let supra_governance_config = + borrow_global_mut(@supra_framework); supra_governance_config.voting_duration_secs = voting_duration_secs; supra_governance_config.min_voting_threshold = min_voting_threshold; supra_governance_config.voters = voters; if (std::features::module_event_migration_enabled()) { event::emit( - SupraUpdateConfig { - min_voting_threshold, - voting_duration_secs, - voters, - }, + SupraUpdateConfig { min_voting_threshold, voting_duration_secs, voters } ) }; let events = borrow_global_mut(@supra_framework); event::emit_event( &mut events.update_config_events, - SupraUpdateConfigEvent { - min_voting_threshold, - voting_duration_secs, - voters, - }, + SupraUpdateConfigEvent { min_voting_threshold, voting_duration_secs, voters } ); } @@ -238,9 +255,15 @@ module supra_framework::supra_governance { proposer: &signer, execution_hash: vector, metadata_location: vector, - metadata_hash: vector, + metadata_hash: vector ) acquires SupraGovernanceConfig, SupraGovernanceEvents { - supra_create_proposal_v2(proposer, execution_hash, metadata_location, metadata_hash, false); + supra_create_proposal_v2( + proposer, + execution_hash, + metadata_location, + metadata_hash, + false + ); } /// Create a single-step or multi-step proposal with the backing `stake_pool`. @@ -251,7 +274,7 @@ module supra_framework::supra_governance { execution_hash: vector, metadata_location: vector, metadata_hash: vector, - is_multi_step_proposal: bool, + is_multi_step_proposal: bool ) acquires SupraGovernanceConfig, SupraGovernanceEvents { supra_create_proposal_v2_impl( proposer, @@ -271,38 +294,46 @@ module supra_framework::supra_governance { execution_hash: vector, metadata_location: vector, metadata_hash: vector, - is_multi_step_proposal: bool, + is_multi_step_proposal: bool ): u64 acquires SupraGovernanceConfig, SupraGovernanceEvents { let proposer_address = signer::address_of(proposer); - let supra_governance_config = borrow_global(@supra_framework); + let supra_governance_config = + borrow_global(@supra_framework); - assert!(vector::contains(&supra_governance_config.voters, &proposer_address), error::permission_denied(EACCOUNT_NOT_AUTHORIZED)); + assert!( + vector::contains(&supra_governance_config.voters, &proposer_address), + error::permission_denied(EACCOUNT_NOT_AUTHORIZED) + ); - let proposal_expiration = timestamp::now_seconds() + supra_governance_config.voting_duration_secs; + let proposal_expiration = + timestamp::now_seconds() + supra_governance_config.voting_duration_secs; // Create and validate proposal metadata. - let proposal_metadata = create_proposal_metadata(metadata_location, metadata_hash); - - let proposal_id = multisig_voting::create_proposal_v2( - proposer_address, - @supra_framework, - governance_proposal::create_proposal(), - execution_hash, - supra_governance_config.min_voting_threshold, - supra_governance_config.voters, - proposal_expiration, - proposal_metadata, - is_multi_step_proposal, + let proposal_metadata = create_proposal_metadata( + metadata_location, metadata_hash ); + let proposal_id = + multisig_voting::create_proposal_v2( + proposer_address, + @supra_framework, + governance_proposal::create_proposal(), + execution_hash, + supra_governance_config.min_voting_threshold, + supra_governance_config.voters, + proposal_expiration, + proposal_metadata, + is_multi_step_proposal + ); + if (std::features::module_event_migration_enabled()) { event::emit( SupraCreateProposal { proposal_id, proposer: proposer_address, execution_hash, - proposal_metadata, - }, + proposal_metadata + } ); }; let events = borrow_global_mut(@supra_framework); @@ -312,17 +343,15 @@ module supra_framework::supra_governance { proposal_id, proposer: proposer_address, execution_hash, - proposal_metadata, - }, + proposal_metadata + } ); proposal_id } /// Vote on proposal with `proposal_id` and all voting power from `stake_pool`. public entry fun supra_vote( - voter: &signer, - proposal_id: u64, - should_pass: bool, + voter: &signer, proposal_id: u64, should_pass: bool ) acquires ApprovedExecutionHashes, SupraGovernanceEvents, SupraGovernanceConfig { supra_vote_internal(voter, proposal_id, should_pass); } @@ -332,56 +361,58 @@ module supra_framework::supra_governance { /// If a stake pool has already voted on a proposal before partial governance voting is enabled, the stake pool /// cannot vote on the proposal even after partial governance voting is enabled. fun supra_vote_internal( - voter: &signer, - proposal_id: u64, - should_pass: bool, + voter: &signer, proposal_id: u64, should_pass: bool ) acquires ApprovedExecutionHashes, SupraGovernanceEvents, SupraGovernanceConfig { let voter_address = signer::address_of(voter); - let supra_governance_config = borrow_global(@supra_framework); - assert!(vector::contains(&supra_governance_config.voters, &signer::address_of(voter)), error::permission_denied(EACCOUNT_NOT_AUTHORIZED)); + let supra_governance_config = + borrow_global(@supra_framework); + assert!( + vector::contains( + &supra_governance_config.voters, &signer::address_of(voter) + ), + error::permission_denied(EACCOUNT_NOT_AUTHORIZED) + ); // The voter's stake needs to be locked up at least as long as the proposal's expiration. - let proposal_expiration = multisig_voting::get_proposal_expiration_secs( - @supra_framework, - proposal_id + let proposal_expiration = + multisig_voting::get_proposal_expiration_secs( + @supra_framework, proposal_id + ); + assert!( + timestamp::now_seconds() <= proposal_expiration, + error::invalid_argument(EPROPOSAL_IS_EXPIRE) ); - assert!(timestamp::now_seconds() <= proposal_expiration, error::invalid_argument(EPROPOSAL_IS_EXPIRE)); multisig_voting::vote( voter, &governance_proposal::create_empty_proposal(), @supra_framework, proposal_id, - should_pass, + should_pass ); if (std::features::module_event_migration_enabled()) { - event::emit( - SupraVote { - proposal_id, - voter: voter_address, - should_pass, - }, - ); + event::emit(SupraVote { proposal_id, voter: voter_address, should_pass }); }; let events = borrow_global_mut(@supra_framework); event::emit_event( &mut events.vote_events, - SupraVoteEvent { - proposal_id, - voter: voter_address, - should_pass, - }, + SupraVoteEvent { proposal_id, voter: voter_address, should_pass } ); - let proposal_state = multisig_voting::get_proposal_state(@supra_framework, proposal_id); + let proposal_state = + multisig_voting::get_proposal_state( + @supra_framework, proposal_id + ); if (proposal_state == PROPOSAL_STATE_SUCCEEDED) { add_supra_approved_script_hash(proposal_id); } } - public entry fun add_supra_approved_script_hash_script(proposal_id: u64) acquires ApprovedExecutionHashes { + public entry fun add_supra_approved_script_hash_script( + proposal_id: u64 + ) acquires ApprovedExecutionHashes { add_supra_approved_script_hash(proposal_id) } @@ -389,18 +420,29 @@ module supra_framework::supra_governance { /// This is needed to bypass the mempool transaction size limit for approved governance proposal transactions that /// are too large (e.g. module upgrades). public fun add_supra_approved_script_hash(proposal_id: u64) acquires ApprovedExecutionHashes { - let approved_hashes = borrow_global_mut(@supra_framework); + let approved_hashes = + borrow_global_mut(@supra_framework); // Ensure the proposal can be resolved. - let proposal_state = multisig_voting::get_proposal_state(@supra_framework, proposal_id); - assert!(proposal_state == PROPOSAL_STATE_SUCCEEDED, error::invalid_argument(EPROPOSAL_NOT_RESOLVABLE_YET)); + let proposal_state = + multisig_voting::get_proposal_state( + @supra_framework, proposal_id + ); + assert!( + proposal_state == PROPOSAL_STATE_SUCCEEDED, + error::invalid_argument(EPROPOSAL_NOT_RESOLVABLE_YET) + ); - let execution_hash = multisig_voting::get_execution_hash(@supra_framework, proposal_id); + let execution_hash = + multisig_voting::get_execution_hash( + @supra_framework, proposal_id + ); // If this is a multi-step proposal, the proposal id will already exist in the ApprovedExecutionHashes map. // We will update execution hash in ApprovedExecutionHashes to be the next_execution_hash. if (simple_map::contains_key(&approved_hashes.hashes, &proposal_id)) { - let current_execution_hash = simple_map::borrow_mut(&mut approved_hashes.hashes, &proposal_id); + let current_execution_hash = + simple_map::borrow_mut(&mut approved_hashes.hashes, &proposal_id); *current_execution_hash = execution_hash; } else { simple_map::add(&mut approved_hashes.hashes, proposal_id, execution_hash); @@ -410,8 +452,7 @@ module supra_framework::supra_governance { /// Resolve a successful single-step proposal. This would fail if the proposal is not successful (not enough votes or more no /// than yes). public fun supra_resolve( - proposal_id: u64, - signer_address: address + proposal_id: u64, signer_address: address ): signer acquires ApprovedExecutionHashes, GovernanceResponsbility { multisig_voting::resolve(@supra_framework, proposal_id); remove_supra_approved_hash(proposal_id); @@ -420,11 +461,11 @@ module supra_framework::supra_governance { /// Resolve a successful multi-step proposal. This would fail if the proposal is not successful. public fun resolve_supra_multi_step_proposal( - proposal_id: u64, - signer_address: address, - next_execution_hash: vector + proposal_id: u64, signer_address: address, next_execution_hash: vector ): signer acquires GovernanceResponsbility, ApprovedExecutionHashes { - multisig_voting::resolve_proposal_v2(@supra_framework, proposal_id, next_execution_hash); + multisig_voting::resolve_proposal_v2( + @supra_framework, proposal_id, next_execution_hash + ); // If the current step is the last step of this multi-step proposal, // we will remove the execution hash from the ApprovedExecutionHashes map. if (vector::length(&next_execution_hash) == 0) { @@ -441,11 +482,14 @@ module supra_framework::supra_governance { /// Remove an approved proposal's execution script hash. public fun remove_supra_approved_hash(proposal_id: u64) acquires ApprovedExecutionHashes { assert!( - multisig_voting::is_resolved(@supra_framework, proposal_id), - error::invalid_argument(EPROPOSAL_NOT_RESOLVED_YET), + multisig_voting::is_resolved( + @supra_framework, proposal_id + ), + error::invalid_argument(EPROPOSAL_NOT_RESOLVED_YET) ); - let approved_hashes = &mut borrow_global_mut(@supra_framework).hashes; + let approved_hashes = + &mut borrow_global_mut(@supra_framework).hashes; if (simple_map::contains_key(approved_hashes, &proposal_id)) { simple_map::remove(approved_hashes, &proposal_id); }; @@ -454,15 +498,19 @@ module supra_framework::supra_governance { /// Manually reconfigure. Called at the end of a governance txn that alters on-chain configs. /// /// WARNING: this function always ensures a reconfiguration starts, but when the reconfiguration finishes depends. - /// - If feature `RECONFIGURE_WITH_DKG` is disabled, it finishes immediately. + /// - If feature `SUPRA_DKG` is disabled, it finishes immediately. /// - At the end of the calling transaction, we will be in a new epoch. - /// - If feature `RECONFIGURE_WITH_DKG` is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes. + /// - If feature `SUPRA_DKG` is enabled, it starts DKG, and the new epoch will start in a block prologue after DKG finishes. /// /// This behavior affects when an update of an on-chain config (e.g. `ConsensusConfig`, `Features`) takes effect, - /// since such updates are applied whenever we enter an new epoch. + /// since such updates are applied whenever we enter a new epoch. public entry fun reconfigure(supra_framework: &signer) { system_addresses::assert_supra_framework(supra_framework); - if (consensus_config::validator_txn_enabled() && randomness_config::enabled()) { + + // The block executor should seed the randomness config with the digest of the last + // block of the first epoch in which the DKG is enabled, so the second conjunct should + // always be true once the first is true. We keep it for safety in case of regression. + if (features::supra_dkg_enabled() && randomness_config::enabled()) { reconfiguration_with_dkg::try_start(); } else { reconfiguration_with_dkg::finish(supra_framework); @@ -470,7 +518,7 @@ module supra_framework::supra_governance { } /// Change epoch immediately. - /// If `RECONFIGURE_WITH_DKG` is enabled and we are in the middle of a DKG, + /// If `SUPRA_DKG` is enabled and we are in the middle of a DKG, /// stop waiting for DKG and enter the new epoch without randomness. /// /// WARNING: currently only used by tests. In most cases you should use `reconfigure()` instead. @@ -482,14 +530,18 @@ module supra_framework::supra_governance { /// `force_end_epoch()` equivalent but only called in testnet, /// where the core resources account exists and has been granted power to mint Supra coins. - public entry fun force_end_epoch_test_only(supra_framework: &signer) acquires GovernanceResponsbility { + public entry fun force_end_epoch_test_only( + supra_framework: &signer + ) acquires GovernanceResponsbility { let core_signer = get_signer_testnet_only(supra_framework, @0x1); system_addresses::assert_supra_framework(&core_signer); reconfiguration_with_dkg::finish(&core_signer); } /// Update feature flags and also trigger reconfiguration. - public fun toggle_features(supra_framework: &signer, enable: vector, disable: vector) { + public fun toggle_features( + supra_framework: &signer, enable: vector, disable: vector + ) { system_addresses::assert_supra_framework(supra_framework); features::change_feature_flags_for_next_epoch(supra_framework, enable, disable); reconfigure(supra_framework); @@ -497,26 +549,37 @@ module supra_framework::supra_governance { /// Only called in testnet where the core resources account exists and has been granted power to mint Supra coins. public fun get_signer_testnet_only( - core_resources: &signer, signer_address: address): signer acquires GovernanceResponsbility { + core_resources: &signer, signer_address: address + ): signer acquires GovernanceResponsbility { system_addresses::assert_core_resource(core_resources); // Core resources account only has mint capability in tests/testnets. - assert!(supra_coin::has_mint_capability(core_resources), error::unauthenticated(EUNAUTHORIZED)); + assert!( + supra_coin::has_mint_capability(core_resources), + error::unauthenticated(EUNAUTHORIZED) + ); get_signer(signer_address) } /// Return a signer for making changes to 0x1 as part of on-chain governance proposal process. fun get_signer(signer_address: address): signer acquires GovernanceResponsbility { - let governance_responsibility = borrow_global(@supra_framework); - let signer_cap = simple_map::borrow(&governance_responsibility.signer_caps, &signer_address); + let governance_responsibility = + borrow_global(@supra_framework); + let signer_cap = + simple_map::borrow(&governance_responsibility.signer_caps, &signer_address); create_signer_with_capability(signer_cap) } fun create_proposal_metadata( - metadata_location: vector, - metadata_hash: vector + metadata_location: vector, metadata_hash: vector ): SimpleMap> { - assert!(string::length(&utf8(metadata_location)) <= 256, error::invalid_argument(EMETADATA_LOCATION_TOO_LONG)); - assert!(string::length(&utf8(metadata_hash)) <= 256, error::invalid_argument(EMETADATA_HASH_TOO_LONG)); + assert!( + string::length(&utf8(metadata_location)) <= 256, + error::invalid_argument(EMETADATA_LOCATION_TOO_LONG) + ); + assert!( + string::length(&utf8(metadata_hash)) <= 256, + error::invalid_argument(EMETADATA_HASH_TOO_LONG) + ); let metadata = simple_map::create>(); simple_map::add(&mut metadata, utf8(METADATA_LOCATION_KEY), metadata_location); @@ -526,26 +589,14 @@ module supra_framework::supra_governance { #[test_only] public entry fun supra_create_proposal_for_test( - proposer: &signer, - multi_step: bool, + proposer: &signer, multi_step: bool ) acquires SupraGovernanceConfig, SupraGovernanceEvents { let execution_hash = vector::empty(); vector::push_back(&mut execution_hash, 1); if (multi_step) { - supra_create_proposal_v2( - proposer, - execution_hash, - b"", - b"", - true, - ); + supra_create_proposal_v2(proposer, execution_hash, b"", b"", true); } else { - supra_create_proposal( - proposer, - execution_hash, - b"", - b"", - ); + supra_create_proposal(proposer, execution_hash, b"", b""); }; } @@ -561,9 +612,13 @@ module supra_framework::supra_governance { vector::push_back(&mut execution_hash, 1); if (finish_multi_step_execution) { - resolve_supra_multi_step_proposal(proposal_id, signer_address, vector::empty()) + resolve_supra_multi_step_proposal( + proposal_id, signer_address, vector::empty() + ) } else { - resolve_supra_multi_step_proposal(proposal_id, signer_address, execution_hash) + resolve_supra_multi_step_proposal( + proposal_id, signer_address, execution_hash + ) } } else { supra_resolve(proposal_id, signer_address) @@ -572,7 +627,9 @@ module supra_framework::supra_governance { #[test_only] /// Force reconfigure. To be called at the end of a proposal that alters on-chain configs. - public fun toggle_features_for_test(enable: vector, disable: vector) { + public fun toggle_features_for_test( + enable: vector, disable: vector + ) { toggle_features(&account::create_signer_for_test(@0x1), enable, disable); } @@ -583,9 +640,13 @@ module supra_framework::supra_governance { yes_voter: &signer, no_voter: &signer, multi_step: bool, - use_generic_resolve_function: bool, + use_generic_resolve_function: bool ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { - let voters = vector[signer::address_of(proposer), signer::address_of(yes_voter), signer::address_of(no_voter)]; + let voters = vector[ + signer::address_of(proposer), + signer::address_of(yes_voter), + signer::address_of(no_voter) + ]; supra_setup_voting(supra_framework, voters); let execution_hash = vector::empty(); @@ -597,73 +658,144 @@ module supra_framework::supra_governance { supra_vote(yes_voter, 0, true); supra_vote(no_voter, 0, false); - supra_test_resolving_proposal_generic(supra_framework, use_generic_resolve_function, execution_hash); + supra_test_resolving_proposal_generic( + supra_framework, use_generic_resolve_function, execution_hash + ); } #[test_only] public entry fun supra_test_resolving_proposal_generic( supra_framework: &signer, use_generic_resolve_function: bool, - execution_hash: vector, + execution_hash: vector ) acquires ApprovedExecutionHashes, GovernanceResponsbility { // Once expiration time has passed, the proposal should be considered resolve now as there are more yes votes // than no. timestamp::update_global_time_for_test(100001000000); - let proposal_state = multisig_voting::get_proposal_state(signer::address_of(supra_framework), 0); + let proposal_state = + multisig_voting::get_proposal_state( + signer::address_of(supra_framework), 0 + ); assert!(proposal_state == PROPOSAL_STATE_SUCCEEDED, proposal_state); // Add approved script hash. add_supra_approved_script_hash(0); - let approved_hashes = borrow_global(@supra_framework).hashes; + let approved_hashes = + borrow_global(@supra_framework).hashes; assert!(*simple_map::borrow(&approved_hashes, &0) == execution_hash, 0); // Resolve the proposal. - let account = supra_resolve_proposal_for_test(0, @supra_framework, use_generic_resolve_function, true); + let account = + supra_resolve_proposal_for_test( + 0, + @supra_framework, + use_generic_resolve_function, + true + ); assert!(signer::address_of(&account) == @supra_framework, 1); - assert!(multisig_voting::is_resolved(@supra_framework, 0), 2); - let approved_hashes = borrow_global(@supra_framework).hashes; + assert!( + multisig_voting::is_resolved(@supra_framework, 0), 2 + ); + let approved_hashes = + borrow_global(@supra_framework).hashes; assert!(!simple_map::contains_key(&approved_hashes, &0), 3); } - #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + yes_voter = @0x234, + no_voter = @345 + ) + ] public entry fun test_voting( supra_framework: &signer, proposer: &signer, yes_voter: &signer, - no_voter: &signer, + no_voter: &signer ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { - test_voting_generic(supra_framework, proposer, yes_voter, no_voter, false, false); + test_voting_generic( + supra_framework, + proposer, + yes_voter, + no_voter, + false, + false + ); } - #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + yes_voter = @0x234, + no_voter = @345 + ) + ] public entry fun test_voting_multi_step( supra_framework: &signer, proposer: &signer, yes_voter: &signer, - no_voter: &signer, + no_voter: &signer ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { - test_voting_generic(supra_framework, proposer, yes_voter, no_voter, true, true); + test_voting_generic( + supra_framework, + proposer, + yes_voter, + no_voter, + true, + true + ); } - #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + yes_voter = @0x234, + no_voter = @345 + ) + ] #[expected_failure(abort_code = 0x5000a, location = supra_framework::multisig_voting)] public entry fun test_voting_multi_step_cannot_use_single_step_resolve( supra_framework: &signer, proposer: &signer, yes_voter: &signer, - no_voter: &signer, + no_voter: &signer ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { - test_voting_generic(supra_framework, proposer, yes_voter, no_voter, true, false); + test_voting_generic( + supra_framework, + proposer, + yes_voter, + no_voter, + true, + false + ); } - #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + yes_voter = @0x234, + no_voter = @345 + ) + ] public entry fun test_voting_single_step_can_use_generic_resolve_function( supra_framework: &signer, proposer: &signer, yes_voter: &signer, - no_voter: &signer, + no_voter: &signer ) acquires ApprovedExecutionHashes, SupraGovernanceConfig, GovernanceResponsbility, SupraGovernanceEvents { - test_voting_generic(supra_framework, proposer, yes_voter, no_voter, false, true); + test_voting_generic( + supra_framework, + proposer, + yes_voter, + no_voter, + false, + true + ); } #[test_only] @@ -672,9 +804,13 @@ module supra_framework::supra_governance { proposer: &signer, yes_voter: &signer, no_voter: &signer, - multi_step: bool, + multi_step: bool ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceEvents, SupraGovernanceConfig { - let voters = vector[signer::address_of(proposer), signer::address_of(yes_voter), signer::address_of(no_voter)]; + let voters = vector[ + signer::address_of(proposer), + signer::address_of(yes_voter), + signer::address_of(no_voter) + ]; supra_setup_voting(supra_framework, voters); supra_create_proposal_for_test(proposer, multi_step); @@ -691,8 +827,13 @@ module supra_framework::supra_governance { let execution_hash = vector::empty(); let next_execution_hash = vector::empty(); vector::push_back(&mut execution_hash, 1); - multisig_voting::resolve_proposal_v2(@supra_framework, 0, next_execution_hash); - assert!(multisig_voting::is_resolved(@supra_framework, 0), 0); + multisig_voting::resolve_proposal_v2( + @supra_framework, 0, next_execution_hash + ); + assert!( + multisig_voting::is_resolved(@supra_framework, 0), + 0 + ); if (vector::length(&next_execution_hash) == 0) { remove_supra_approved_hash(0); } else { @@ -700,19 +841,30 @@ module supra_framework::supra_governance { }; } else { multisig_voting::resolve(@supra_framework, 0); - assert!(multisig_voting::is_resolved(@supra_framework, 0), 0); + assert!( + multisig_voting::is_resolved(@supra_framework, 0), + 0 + ); remove_supra_approved_hash(0); }; - let approved_hashes = borrow_global(@supra_framework).hashes; + let approved_hashes = + borrow_global(@supra_framework).hashes; assert!(!simple_map::contains_key(&approved_hashes, &0), 1); } - #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + yes_voter = @0x234, + no_voter = @345 + ) + ] public entry fun test_can_remove_approved_hash_if_executed_directly_via_voting( supra_framework: &signer, proposer: &signer, yes_voter: &signer, - no_voter: &signer, + no_voter: &signer ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceEvents, SupraGovernanceConfig { test_can_remove_approved_hash_if_executed_directly_via_voting_generic( supra_framework, @@ -723,12 +875,19 @@ module supra_framework::supra_governance { ); } - #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + yes_voter = @0x234, + no_voter = @345 + ) + ] public entry fun test_can_remove_approved_hash_if_executed_directly_via_voting_multi_step( supra_framework: &signer, proposer: &signer, yes_voter: &signer, - no_voter: &signer, + no_voter: &signer ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceEvents, SupraGovernanceConfig { test_can_remove_approved_hash_if_executed_directly_via_voting_generic( supra_framework, @@ -739,23 +898,29 @@ module supra_framework::supra_governance { ); } - #[test(supra_framework = @supra_framework, proposer = @0x123, voter_1 = @0x234, voter_2 = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + voter_1 = @0x234, + voter_2 = @345 + ) + ] #[expected_failure(abort_code = 0x8000d, location = supra_framework::multisig_voting)] public entry fun test_cannot_double_vote( supra_framework: &signer, proposer: &signer, voter_1: &signer, - voter_2: &signer, + voter_2: &signer ) acquires ApprovedExecutionHashes, GovernanceResponsbility, SupraGovernanceConfig, SupraGovernanceEvents { - let voters = vector[signer::address_of(proposer), signer::address_of(voter_1), signer::address_of(voter_2)]; + let voters = vector[ + signer::address_of(proposer), + signer::address_of(voter_1), + signer::address_of(voter_2) + ]; supra_setup_voting(supra_framework, voters); - supra_create_proposal( - proposer, - b"random-test", - b"", - b"", - ); + supra_create_proposal(proposer, b"random-test", b"", b""); // Double voting should throw an error. supra_vote(voter_1, 0, true); @@ -764,8 +929,7 @@ module supra_framework::supra_governance { #[test_only] public fun supra_setup_voting( - supra_framework: &signer, - voters: vector
, + supra_framework: &signer, voters: vector
) acquires GovernanceResponsbility { use supra_framework::account; @@ -777,13 +941,13 @@ module supra_framework::supra_governance { store_signer_cap( supra_framework, @supra_framework, - account::create_test_signer_cap(@supra_framework), + account::create_test_signer_cap(@supra_framework) ); } #[test(supra_framework = @supra_framework)] public entry fun test_update_governance_config( - supra_framework: signer, + supra_framework: signer ) acquires SupraGovernanceEvents, SupraGovernanceConfig { account::create_account_for_test(signer::address_of(&supra_framework)); let voters = vector[@0xa1, @0xa2, @0xa3]; @@ -799,8 +963,9 @@ module supra_framework::supra_governance { #[test(account = @0x123)] #[expected_failure(abort_code = 0x50003, location = supra_framework::system_addresses)] - public entry fun test_update_governance_config_unauthorized_should_fail(account: signer) - acquires SupraGovernanceConfig, SupraGovernanceEvents { + public entry fun test_update_governance_config_unauthorized_should_fail( + account: signer + ) acquires SupraGovernanceConfig, SupraGovernanceEvents { account::create_account_for_test(signer::address_of(&account)); let voters = vector[@0xa1, @0xa2, @0xa3]; @@ -808,14 +973,25 @@ module supra_framework::supra_governance { update_supra_governance_config(&account, 1500, 2, voters); } - #[test(supra_framework = @supra_framework, proposer = @0x123, yes_voter = @0x234, no_voter = @345)] + #[ + test( + supra_framework = @supra_framework, + proposer = @0x123, + yes_voter = @0x234, + no_voter = @345 + ) + ] public entry fun test_replace_execution_hash( supra_framework: &signer, proposer: &signer, yes_voter: &signer, - no_voter: &signer, + no_voter: &signer ) acquires GovernanceResponsbility, ApprovedExecutionHashes, SupraGovernanceConfig, SupraGovernanceEvents { - let voters = vector[signer::address_of(proposer), signer::address_of(yes_voter), signer::address_of(no_voter)]; + let voters = vector[ + signer::address_of(proposer), + signer::address_of(yes_voter), + signer::address_of(no_voter) + ]; supra_setup_voting(supra_framework, voters); supra_create_proposal_for_test(proposer, true); @@ -833,7 +1009,9 @@ module supra_framework::supra_governance { vector::push_back(&mut execution_hash, 1); vector::push_back(&mut next_execution_hash, 10); - multisig_voting::resolve_proposal_v2(@supra_framework, 0, next_execution_hash); + multisig_voting::resolve_proposal_v2( + @supra_framework, 0, next_execution_hash + ); if (vector::length(&next_execution_hash) == 0) { remove_supra_approved_hash(0); @@ -841,8 +1019,12 @@ module supra_framework::supra_governance { add_supra_approved_script_hash(0) }; - let approved_hashes = borrow_global(@supra_framework).hashes; - assert!(*simple_map::borrow(&approved_hashes, &0) == vector[10u8, ], 1); + let approved_hashes = + borrow_global(@supra_framework).hashes; + assert!( + *simple_map::borrow(&approved_hashes, &0) == vector[10u8], + 1 + ); } #[verify_only] @@ -850,8 +1032,13 @@ module supra_framework::supra_governance { supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, - voters: vector
, + voters: vector
) { - initialize(supra_framework, voting_duration_secs, supra_min_voting_threshold, voters); + initialize( + supra_framework, + voting_duration_secs, + supra_min_voting_threshold, + voters + ); } } diff --git a/aptos-move/framework/supra-framework/sources/validator_public_keys.move b/aptos-move/framework/supra-framework/sources/validator_public_keys.move new file mode 100644 index 00000000000..30e389ba0f9 --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/validator_public_keys.move @@ -0,0 +1,259 @@ +// Copyright (c) 2024 Supra. +module supra_framework::validator_public_keys { + + use std::bcs; + use std::error; + use std::option; + use aptos_std::any; + use aptos_std::bls12381; + use aptos_std::ed25519; + use aptos_std::type_info; + use supra_std::class_groups; + #[test_only] + use aptos_std::bls12381::public_key_with_pop_to_normal; + #[test_only] + use supra_framework::validator_public_keys; + + /// The integer should match the Rust enum value representation in `CertificateThresholdType`. + /// f+1, given there are f Byzantine nodes in the [Committee]. + const CERTIFICATE_THRESHOLD_TYPE_VALIDITY: u8 = 0; + /// The integer should match the Rust enum value representation in `CertificateThresholdType`. + /// 2f+1, given there are f Byzantine nodes in the [Committee] and n >= 3f + 1 nodes in total. + const CERTIFICATE_THRESHOLD_TYPE_QUORUM: u8 = 1; + /// The integer should match the Rust enum value representation in `CertificateThresholdType`. + /// n, where n is the total number of nodes in the [Committee]. + const CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS: u8 = 2; + /// The integer should match the Rust enum value representation in `CertificateThresholdType`. + /// f+1, given there are f Byzantine nodes and c crash-only nodes in the [Committee] with n >= 3f + 2c + 1 nodes. + const CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY: u8 = 3; + /// The integer should match the Rust enum value representation in `CertificateThresholdType` + /// 2f + c + 1, given there are f Byzantine nodes and c crash-only nodes in the [Committee] with n >= 3f + 2c + 1 nodes. + const CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM: u8 = 4; + /// The integer should match the Rust enum value representation in `CertificateThresholdType`. + /// n - f - c, given there are f Byzantine nodes and c crash-only nodes in the [Committee] with n >= 3f + 2c + 1 nodes. + const CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE: u8 = 5; + /// The integer should match the Rust enum value representation in `CertificateThresholdType`. + /// f+1, given there are f Byzantine nodes in the [Committee] with n >= 2f + 1 nodes. + const CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY: u8 = 6; + + /// Error: Unknown certificate threshold type. + const EUNKNOWN_THRESHOLD_TYPE: u64 = 1; + + /// Internal tag wrapper + struct CertificateThresholdType has copy, drop, store { tag: u8 } + + public fun validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_VALIDITY } } + public fun quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_QUORUM } } + public fun unanimous_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS } } + public fun bcft_validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY } } + public fun bcft_quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM } } + public fun bcft_fallback_view_change_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE } } + public fun clan_majority_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY } } + + public fun is_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_VALIDITY } + public fun is_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_QUORUM } + public fun is_unanimous_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS } + public fun is_bcft_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY } + public fun is_bcft_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM } + public fun is_bcft_fallback_view_change_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE } + public fun is_clan_majority_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY } + + /// The size of a serialized ed25519 public key, in bytes. + const ED25519_PUBLIC_KEY_NUM_BYTES: u64 = 32; + /// The size of a serialized bls12381 G1 public key, in bytes. + const BLS12381_G1_PUBLIC_KEY_NUM_BYTES: u64 = 48; + + /// InternalPublicKeys consists of: + /// 1. bls multisig key + /// 2. bls threshold key shares for various certificate types + /// 3. classgroup key + /// 4. ed25519 key + struct InternalPublicKeys has copy, drop, store { + bls_multisig_key: bls12381::PublicKey, + bls_threshold_validity_certificate_key: option::Option, + bls_threshold_quorum_certificate_key: option::Option, + bls_threshold_unanimous_certificate_key: option::Option, + bls_threshold_bcft_validity_certificate_key: option::Option, + bls_threshold_bcft_quorum_certificate_key: option::Option, + bls_threshold_bcft_fallback_view_change_certificate_key: option::Option, + bls_threshold_clan_majority_certificate_key: option::Option, + class_group_key: class_groups::CGPublicKey, + ed25519_key: ed25519::ValidatedPublicKey, + } + + /// ValidatorPublicKeys consists of: + /// 1. network key + /// 2. supra's internal keys + struct ValidatorPublicKeys has copy, drop, store { + network_key: ed25519::ValidatedPublicKey, + supra_keys: InternalPublicKeys, + } + + #[test_only] + /// This struct holds calidator secret key that can be used during testing. + struct ValidatorSecretKeys has drop { + network_key: ed25519::SecretKey, + supra_bls_multi_sig_bls_key: bls12381::SecretKey, + supra_bls_threshold_validity_key: option::Option, + supra_bls_threshold_quorum_key: option::Option, + supra_bls_threshold_unanimous_key: option::Option, + supra_bls_threshold_bcft_validity_key: option::Option, + supra_bls_threshold_bcft_quorum_key: option::Option, + supra_bls_threshold_bcft_fallback_view_change_key: option::Option, + supra_bls_threshold_clan_majority_key: option::Option, + cg_key: class_groups::SecretKey, + supra_ed_key: ed25519::SecretKey, + } + + public fun validator_public_keys_from_bytes(bytes: vector): ValidatorPublicKeys{ + + // bcs deserialization + let bytes_serialized = any::new(type_info::type_name(), bytes); + let validator_public_keys = any::unpack(bytes_serialized); + validator_public_keys + } + + public fun public_key_to_bytes(pk: ValidatorPublicKeys): vector{ + // bcs deserialization + bcs::to_bytes(&pk) + } + + public fun get_network_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{ + pk.network_key + } + + public fun get_supra_bls_multi_sig_pub_key(pk: &ValidatorPublicKeys): bls12381::PublicKey{ + pk.supra_keys.bls_multisig_key + } + + public fun get_supra_cg_key(pk: &ValidatorPublicKeys): class_groups::CGPublicKey{ + pk.supra_keys.class_group_key + } + + public fun get_supra_ed_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{ + pk.supra_keys.ed25519_key + } + + public fun rotate_supra_bls_threshold_validity_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_validity_key: bls12381::PublicKey) { + pk.supra_keys.bls_threshold_validity_certificate_key = option::some(new_bls_threshold_validity_key); + } + + public fun rotate_supra_bls_threshold_quorum_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_quorum_key: bls12381::PublicKey) { + pk.supra_keys.bls_threshold_quorum_certificate_key = option::some(new_bls_threshold_quorum_key); + } + + public fun rotate_supra_bls_threshold_unanimous_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) { + pk.supra_keys.bls_threshold_unanimous_certificate_key = option::some(new_key); + } + + public fun rotate_supra_bls_threshold_bcft_validity_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) { + pk.supra_keys.bls_threshold_bcft_validity_certificate_key = option::some(new_key); + } + + public fun rotate_supra_bls_threshold_bcft_quorum_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) { + pk.supra_keys.bls_threshold_bcft_quorum_certificate_key = option::some(new_key); + } + + public fun rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) { + pk.supra_keys.bls_threshold_bcft_fallback_view_change_certificate_key = option::some(new_key); + } + + public fun rotate_supra_bls_threshold_clan_majority_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) { + pk.supra_keys.bls_threshold_clan_majority_certificate_key = option::some(new_key); + } + + /// Rotate a threshold key based on the threshold type tag. + /// threshold_type: 0=validity, 1=quorum, 2=unanimous, 3=bcft_validity, 4=bcft_quorum, 5=bcft_fallback_view_change, 6=clan_majority + public fun rotate_supra_bls_threshold_key_by_type(pk: &mut ValidatorPublicKeys, threshold_type: u8, new_key: bls12381::PublicKey) { + if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_VALIDITY) { + rotate_supra_bls_threshold_validity_key(pk, new_key); + } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_QUORUM) { + rotate_supra_bls_threshold_quorum_key(pk, new_key); + } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS) { + rotate_supra_bls_threshold_unanimous_key(pk, new_key); + } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY) { + rotate_supra_bls_threshold_bcft_validity_key(pk, new_key); + } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM) { + rotate_supra_bls_threshold_bcft_quorum_key(pk, new_key); + } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE) { + rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk, new_key); + } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY) { + rotate_supra_bls_threshold_clan_majority_key(pk, new_key); + } else { + abort error::invalid_argument(EUNKNOWN_THRESHOLD_TYPE) + }; + } + + #[test_only] + /// Generates validator key pair for testing. + public fun generate_keys(): (ValidatorSecretKeys, ValidatorPublicKeys) { + let (network_key_sk, network_key_pk) = ed25519::generate_keys(); + let (supra_bls12381_multi_sig_sk, supra_bls12381_multi_sig_pk) = bls12381::generate_keys(); + let (supra_cg_sk, supra_cg_pk) = class_groups::generate_keys(); + let (supra_ed_key_sk, supra_ed_key_pk) = ed25519::generate_keys(); + + let sk = ValidatorSecretKeys{ + network_key: network_key_sk, + supra_bls_multi_sig_bls_key: supra_bls12381_multi_sig_sk, + supra_bls_threshold_validity_key: option::none(), + supra_bls_threshold_quorum_key: option::none(), + supra_bls_threshold_unanimous_key: option::none(), + supra_bls_threshold_bcft_validity_key: option::none(), + supra_bls_threshold_bcft_quorum_key: option::none(), + supra_bls_threshold_bcft_fallback_view_change_key: option::none(), + supra_bls_threshold_clan_majority_key: option::none(), + cg_key: supra_cg_sk, + supra_ed_key: supra_ed_key_sk, + }; + + let pk = ValidatorPublicKeys { + network_key: network_key_pk, + supra_keys: InternalPublicKeys{ + bls_multisig_key: public_key_with_pop_to_normal(&supra_bls12381_multi_sig_pk), + bls_threshold_validity_certificate_key: option::none(), + bls_threshold_quorum_certificate_key: option::none(), + bls_threshold_unanimous_certificate_key: option::none(), + bls_threshold_bcft_validity_certificate_key: option::none(), + bls_threshold_bcft_quorum_certificate_key: option::none(), + bls_threshold_bcft_fallback_view_change_certificate_key: option::none(), + bls_threshold_clan_majority_certificate_key: option::none(), + class_group_key: supra_cg_pk, + ed25519_key: supra_ed_key_pk, + }, + }; + + (sk, pk) + } + + #[test] + fun test_serde_roundtrip() { + // Generate full keypair + let (_sk, pk) = validator_public_keys::generate_keys(); + + // Serialize + let bytes = validator_public_keys::public_key_to_bytes(pk); + + // Parse + let parsed = validator_public_keys::validator_public_keys_from_bytes(bytes); + + // Compare network key + let ed0 = get_network_key(&pk); + let ed1 = get_network_key(&parsed); + assert!(ed0 == ed1, 1001); + + // BLS multi sig equal + let b0 = get_supra_bls_multi_sig_pub_key(&pk); + let b1 = get_supra_bls_multi_sig_pub_key(&parsed); + assert!(b0 == b1, 1002); + + // CG key equal + let c0 = get_supra_cg_key(&pk); + let c1 = get_supra_cg_key(&parsed); + assert!(c0 == c1, 1003); + + // Compare ED bytes + let ed0 = get_supra_ed_key(&pk); + let ed1 = get_supra_ed_key(&parsed); + assert!(ed0 == ed1, 1004); + } +} diff --git a/aptos-move/framework/supra-framework/sources/vesting_without_staking.move b/aptos-move/framework/supra-framework/sources/vesting_without_staking.move index 226a49acb93..f5f121e8ddb 100644 --- a/aptos-move/framework/supra-framework/sources/vesting_without_staking.move +++ b/aptos-move/framework/supra-framework/sources/vesting_without_staking.move @@ -325,7 +325,7 @@ module supra_framework::vesting_without_staking { // last vesting fraction must be non zero to ensure that no amount remains unvested forever. assert!( fixed_point32::get_raw_value(*vector::borrow(&schedule, schedule_len - 1)) != - 0, + 0, error::invalid_argument(EEMPTY_VESTING_SCHEDULE), ); assert!( @@ -1278,7 +1278,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -1408,7 +1408,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -1539,7 +1539,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -1667,7 +1667,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -1796,7 +1796,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2065,7 +2065,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2301,7 +2301,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2559,7 +2559,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2623,7 +2623,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2682,7 +2682,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2733,7 +2733,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2766,7 +2766,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 2, + * 2, ); vest_individual(contract_address, shareholder_1_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 2, 10); @@ -2793,7 +2793,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 3, + * 3, ); vest_individual(contract_address, shareholder_1_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 1, 10); @@ -2852,7 +2852,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2861,7 +2861,7 @@ module supra_framework::vesting_without_staking { // Time is now at the start time, vest will unlock the first period, which is 2/10. timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 50, + * 50, ); vest_individual(contract_address, shareholder_1_address); vested_amount_1 = vested_amount_1 + GRANT_AMOUNT / 4; @@ -2938,7 +2938,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount_1 = 0; @@ -2961,7 +2961,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 2, + * 2, ); vest(contract_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 2, 10); @@ -2971,7 +2971,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 3, + * 3, ); vest(contract_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 1, 10); @@ -2981,7 +2981,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 4, + * 4, ); vest(contract_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 1, 10); @@ -2991,7 +2991,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 5, + * 5, ); vest(contract_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 1, 10); @@ -3001,7 +3001,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 6, + * 6, ); vest(contract_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 1, 10); @@ -3011,7 +3011,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 7, + * 7, ); vest(contract_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 1, 10); @@ -3021,7 +3021,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 8, + * 8, ); vest(contract_address); vested_amount_1 = vested_amount_1 + fraction(shareholder_1_share, 1, 10); @@ -3031,7 +3031,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 9, + * 9, ); vest(contract_address); vested_amount_1 = shareholder_1_share; @@ -3516,7 +3516,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount = 0; @@ -3535,7 +3535,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 9, + * 9, ); vest(contract_address); vested_amount = shareholder_share; @@ -3566,7 +3566,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount = 0; @@ -3585,7 +3585,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 9, + * 9, ); vest(contract_address); vested_amount = shareholder_share; @@ -3616,7 +3616,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount = 0; @@ -3639,7 +3639,7 @@ module supra_framework::vesting_without_staking { timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 9, + * 9, ); vest(contract_address); vested_amount = shareholder_share; @@ -3675,7 +3675,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount = 0; @@ -3686,7 +3686,7 @@ module supra_framework::vesting_without_staking { // Time is now at the start time, vest will unlock the first period, which is 2/10. timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 2, + * 2, ); vest(contract_address); vested_amount = vested_amount + fraction(shareholder_share, 5, 10); @@ -3723,7 +3723,7 @@ module supra_framework::vesting_without_staking { ); assert!( vector::length(&borrow_global(admin_address).vesting_contracts) == - 1, + 1, 0, ); let vested_amount = 0; @@ -3736,7 +3736,7 @@ module supra_framework::vesting_without_staking { // Time is now at the start time, vest will unlock the first period, which is 2/10. timestamp::update_global_time_for_test_secs( vesting_start_secs(contract_address) + period_duration_secs(contract_address) - * 4, + * 4, ); vest(contract_address); vested_amount = vested_amount + fraction(shareholder_share, 7, 10); @@ -3821,4 +3821,4 @@ module supra_framework::vesting_without_staking { assert!(balance_1 == shareholder_1_share, balance_1); assert!(balance_2 == shareholder_2_share, balance_2); } -} +} \ No newline at end of file diff --git a/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move b/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move index a8aba0c4a58..23f5954a72d 100644 --- a/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move +++ b/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move @@ -37,7 +37,7 @@ module supra_framework::delegation_pool_integration_tests { const MODULE_EVENT: u64 = 26; #[test_only] - const CONSENSUS_KEY_1: vector = x"c1bd3bcb387e4ee9a909f6304a1c9902661b0ecfb1e148c7892b210c7f353dfd"; + const CONSENSUS_KEY_1: vector = x"20ed28c35dc60a6c9629a7eb0a8dfa815c85c6cf2cedc9e43314cc26f02d741dc430b40c7239278dae17d68d06950d51ce61c2c16c032ceea62c9715611be7f577f48525ad610432bb5d13fa5826fc07c6650000000000000080090192000000000000007bb0b330cbdcec145d2671ef2532bb7a856a5155c66d7ad89ef2cb65e854fc08a5d43cd159a7abc77adfee05e764ec9abdfc133db8e8621398dcbe53db1069de56405f02a1347d5399502fe849b44cfa673ad95bdbf33b417f3f8e4fa854b87b4a60eff6426b277d6036ffc0cfcdd25c971d53c2b612ed1df66f33eff839c0064ac16d7e04650d13984b08b2f9e7bb240fe3ff920000000000000014a973f3c74f41cecc3c596a125835264d72803ba1ef9c9270fa2228e8f8442889f20ddfffc60bc073758c3fd13a29219ad4532c512d2a97c3a8421dedfa41e4d8d9ffaa3581049a65a64f57ea533ab831c88527bb3d7ce46b6eebd6fef6d3303cf7716455381c74da2bcbfc3e02de2e5fadb014ed4f7ecf6b62a4ce6c0db90b91f084512a18be5cb8892b1615a7bb7ef35d0192000000000000008c49908494889c8d07e0b6f0cb6871aaf7e97506476d0a63530ce06b58928225a4292dff8ffaccd4f217fd65c2afbac848ac5d5957d15aa83fb8d2f261d85ddf4f16feee49d07f274dd421f84862bd73634925c41d2b470066d751732cc4f9630e886df15e63f962959c8f765b48434b6124fe051c2a02ba91bd94a7d8fc3cf7240ffba508ff73d8bb95a8ba661fa59ed9c9b8030000000000000192000000000000007bb0b330cbdcec145d2671ef2532bb7a856a5155c66d7ad89ef2cb65e854fc08a5d43cd159a7abc77adfee05e764ec9abdfc133db8e8621398dcbe53db1069de56405f02a1347d5399502fe849b44cfa673ad95bdbf33b417f3f8e4fa854b87b4a60eff6426b277d6036ffc0cfcdd25c971d53c2b612ed1df66f33eff839c0064ac16d7e04650d13984b08b2f9e7bb240fe3ff920000000000000014a973f3c74f41cecc3c596a125835264d72803ba1ef9c9270fa2228e8f8442889f20ddfffc60bc073758c3fd13a29219ad4532c512d2a97c3a8421dedfa41e4d8d9ffaa3581049a65a64f57ea533ab831c88527bb3d7ce46b6eebd6fef6d3303cf7716455381c74da2bcbfc3e02de2e5fadb014ed4f7ecf6b62a4ce6c0db90b91f084512a18be5cb8892b1615a7bb7ef35d0192000000000000008c49908494889c8d07e0b6f0cb6871aaf7e97506476d0a63530ce06b58928225a4292dff8ffaccd4f217fd65c2afbac848ac5d5957d15aa83fb8d2f261d85ddf4f16feee49d07f274dd421f84862bd73634925c41d2b470066d751732cc4f9630e886df15e63f962959c8f765b48434b6124fe051c2a02ba91bd94a7d8fc3cf7240ffba508ff73d8bb95a8ba661fa59ed9c9b8030000000000000120000000000000000da685763a376d42546959f3e2d96ff46256cd3e539dd458b800c9d0daf4d981019c00000000000000a529edcfd13d9f5014b4e2fab134f833d266876a0a0fbcf3577ef87ced2656924e235d4a6f48169d0c6b1fd4d77b27f36b0eda1e78fb1691894e077333e7f278444a3e6de72685de03564bcf61466567e34c79279fcdccc42c2354e4c0a836e785f909656badb5950ebcf77a1ef9a3680818abe674760bc09888a446b96d9765779222970aaeb804abaa939c4225c474c2bc925be1d24648c6298d69208e695ae5888320393ef041be5f42d0f2eaac6036daffb8373eb80ad275fcc2b9"; #[test_only] public fun initialize_for_test(supra_framework: &signer) { diff --git a/aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move b/aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move index 122871d34aa..f7458704dd5 100644 --- a/aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move +++ b/aptos-move/framework/supra-framework/tests/test_leader_ban_registry.move @@ -4,6 +4,7 @@ module std::test_leader_ban_registry { use std::option; use std::vector; use aptos_std::ed25519; + use supra_framework::validator_public_keys; use supra_framework::supra_coin; use supra_framework::coin; use supra_framework::supra_coin::SupraCoin; @@ -21,10 +22,10 @@ module std::test_leader_ban_registry { validator_4: &signer ) { // initialise stake module - let (_v_1_s_key, v_1_p_key) = ed25519::generate_keys(); - let (_v_2_s_key, v_2_p_key) = ed25519::generate_keys(); - let (_v_3_s_key, v_3_p_key) = ed25519::generate_keys(); - let (_v_4_s_key, v_4_p_key) = ed25519::generate_keys(); + let (_v_1_s_key, v_1_p_key) = validator_public_keys::generate_keys(); + let (_v_2_s_key, v_2_p_key) = validator_public_keys::generate_keys(); + let (_v_3_s_key, v_3_p_key) = validator_public_keys::generate_keys(); + let (_v_4_s_key, v_4_p_key) = validator_public_keys::generate_keys(); stake::initialize_for_test(sender); account::create_account_for_test(signer::address_of(validator_1)); @@ -80,25 +81,25 @@ module std::test_leader_ban_registry { ); stake::join_validator_set_for_test( - &ed25519::public_key_to_unvalidated(&v_4_p_key), + &v_4_p_key, validator_4, signer::address_of(validator_4), false ); stake::join_validator_set_for_test( - &ed25519::public_key_to_unvalidated(&v_3_p_key), + &v_3_p_key, validator_3, signer::address_of(validator_3), false ); stake::join_validator_set_for_test( - &ed25519::public_key_to_unvalidated(&v_2_p_key), + &v_2_p_key, validator_2, signer::address_of(validator_2), false ); stake::join_validator_set_for_test( - &ed25519::public_key_to_unvalidated(&v_1_p_key), + &v_1_p_key, validator_1, signer::address_of(validator_1), true @@ -293,64 +294,66 @@ module std::test_leader_ban_registry { // ===== Part 5: Cross-epoch ban management ===== // Now test ban expiry across epoch change WITHOUT re-banning - // Ban was set at round 98 with duration 16 + // Bans were set at rounds 95/96 (consecutive=2, duration=16) // First trigger epoch change leader_ban_registry::on_new_epoch(); // In epoch 1, advance rounds without re-banning to let the ban expire naturally - // For validators banned at epoch 0 round 98: - // After on_new_epoch: rounds_served_in_previous_epochs = 0 - // (since epoch_earned == latest_view.epoch and round_earned == latest_view.round) + // For validators banned at epoch 0 rounds 95/96: + // After on_new_epoch: rounds_served_in_previous_epochs = 3/2 + // (latest_view.round 98 - round_earned 95/96) - // At epoch 1 round 0, ban should still be active (rounds_served = 0 + 0 = 0, need 16) + // At epoch 1 round 0, ban should still be active (rounds_served = 3/2 + 0, need 16) leader_ban_registry::update_ban_registry(1, 0, option::some(2), vector::empty()); let ban_registry = leader_ban_registry::get_ban_registry(); assert!(vector::length(&ban_registry) == 2, 22); let vp = vector::borrow(&ban_registry, 0); assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 113); - // At epoch 1 round 15, ban should still be active (rounds_served = 0 + 15 = 15, need 16) - leader_ban_registry::update_ban_registry(1, 15, option::some(2), vector::empty()); + // At epoch 1 round 12, ban should still be active (rounds_served = 3+12=15/2+12=14, need 16) + leader_ban_registry::update_ban_registry(1, 12, option::some(2), vector::empty()); let ban_registry = leader_ban_registry::get_ban_registry(); assert!(vector::length(&ban_registry) == 2, 23); - // At epoch 1 round 16, ban expires and validators transition to probation - leader_ban_registry::update_ban_registry(1, 16, option::some(2), vector::empty()); + // At epoch 1 round 14, ban expires and validators transition to probation + // (rounds_served = 3+14=17/2+14=16 >= 16) + leader_ban_registry::update_ban_registry(1, 14, option::some(2), vector::empty()); let ban_registry = leader_ban_registry::get_ban_registry(); assert!(vector::length(&ban_registry) == 2, 24); // Still in registry (on probation) let vp = vector::borrow(&ban_registry, 0); assert!(leader_ban_registry::is_on_probation_from_vp(vp), 114); - // At epoch 1 round 19, probation still active (1 round remaining) - leader_ban_registry::update_ban_registry(1, 19, option::some(2), vector::empty()); + // At epoch 1 round 17, probation still active (17-14=3 < 4, 1 round remaining) + leader_ban_registry::update_ban_registry(1, 17, option::some(2), vector::empty()); let ban_registry = leader_ban_registry::get_ban_registry(); assert!(vector::length(&ban_registry) == 2, 25); - // At epoch 1 round 20, probation expires and validators are fully reinstated - leader_ban_registry::update_ban_registry(1, 20, option::some(2), vector::empty()); + // At epoch 1 round 18, probation expires and validators are fully reinstated + // (18-14=4 >= 4) + leader_ban_registry::update_ban_registry(1, 18, option::some(2), vector::empty()); let ban_registry = leader_ban_registry::get_ban_registry(); assert!(vector::length(&ban_registry) == 0, 26); // ===== Part 6: Re-ban during probation ===== // Test: Re-banning during probation should increase consecutive count - // Ban validator 1 fresh - leader_ban_registry::update_ban_registry(1, 25, option::some(2), vector[0]); + // Ban validator 1 fresh (prev_round=18, so failed_round=19=current_round) + leader_ban_registry::update_ban_registry(1, 19, option::some(2), vector[0]); let ban_registry = leader_ban_registry::get_ban_registry(); assert!(vector::length(&ban_registry) == 1, 27); let vp = vector::borrow(&ban_registry, 0); assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 0, 115); assert!(!leader_ban_registry::is_on_probation_from_vp(vp), 116); - // Ban duration = 4 rounds, so ban expires at round 25 + 4 = 29 - // Transition to probation at round 29 - leader_ban_registry::update_ban_registry(1, 29, option::some(2), vector::empty()); + // Ban duration = 4 rounds, ban earned at round 19, so ban expires at round 23 + // Transition to probation at round 23 + leader_ban_registry::update_ban_registry(1, 23, option::some(2), vector::empty()); let ban_registry = leader_ban_registry::get_ban_registry(); let vp = vector::borrow(&ban_registry, 0); assert!(leader_ban_registry::is_on_probation_from_vp(vp), 117); assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 0, 118); // Re-ban during probation should increase consecutive count and reset to banned state - leader_ban_registry::update_ban_registry(1, 30, option::some(2), vector[0]); + leader_ban_registry::update_ban_registry(1, 24, option::some(2), vector[0]); let ban_registry = leader_ban_registry::get_ban_registry(); let vp = vector::borrow(&ban_registry, 0); assert!(leader_ban_registry::get_consecutive_count_from_vp(vp) == 1, 119); // Consecutive count increased diff --git a/aptos-move/framework/supra-stdlib/doc/class_groups.md b/aptos-move/framework/supra-stdlib/doc/class_groups.md new file mode 100644 index 00000000000..fb1f8c1c884 --- /dev/null +++ b/aptos-move/framework/supra-stdlib/doc/class_groups.md @@ -0,0 +1,125 @@ + + + +# Module `0x1::class_groups` + + + +- [Struct `CGPublicKey`](#0x1_class_groups_CGPublicKey) +- [Function `public_key_from_bytes`](#0x1_class_groups_public_key_from_bytes) +- [Function `public_key_to_bytes`](#0x1_class_groups_public_key_to_bytes) +- [Function `validate_pubkey_internal`](#0x1_class_groups_validate_pubkey_internal) + + +
use 0x1::option;
+
+ + + + + +## Struct `CGPublicKey` + + + +
struct CGPublicKey has copy, drop, store
+
+ + + +
+Fields + + +
+
+bytes: vector<u8> +
+
+ +
+
+ + +
+ + + +## Function `public_key_from_bytes` + +Creates a new public key from a sequence of bytes. + + +
public fun public_key_from_bytes(bytes: vector<u8>): option::Option<class_groups::CGPublicKey>
+
+ + + +
+Implementation + + +
public fun public_key_from_bytes(bytes: vector<u8>): Option<CGPublicKey> {
+    if (validate_pubkey_internal(bytes)) {
+        option::some(CGPublicKey {
+            bytes
+        })
+    } else {
+        option::none<CGPublicKey>()
+    }
+}
+
+ + + +
+ + + +## Function `public_key_to_bytes` + +Serializes a public key to a sequence of bytes. + + +
public fun public_key_to_bytes(pk: &class_groups::CGPublicKey): vector<u8>
+
+ + + +
+Implementation + + +
public fun public_key_to_bytes(pk: &CGPublicKey): vector<u8> {
+    pk.bytes
+}
+
+ + + +
+ + + +## Function `validate_pubkey_internal` + + + +
fun validate_pubkey_internal(public_key: vector<u8>): bool
+
+ + + +
+Implementation + + +
native fun validate_pubkey_internal(public_key: vector<u8>): bool;
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-stdlib/doc/consensus_key.md b/aptos-move/framework/supra-stdlib/doc/consensus_key.md new file mode 100644 index 00000000000..1476c49c921 --- /dev/null +++ b/aptos-move/framework/supra-stdlib/doc/consensus_key.md @@ -0,0 +1,285 @@ + + + +# Module `0x1::consensus_key` + + + +- [Struct `ConsensusPublicKey`](#0x1_consensus_key_ConsensusPublicKey) +- [Constants](#@Constants_0) +- [Function `consensus_public_key_from_bytes`](#0x1_consensus_key_consensus_public_key_from_bytes) +- [Function `public_key_to_bytes`](#0x1_consensus_key_public_key_to_bytes) +- [Function `get_bls_pub_key`](#0x1_consensus_key_get_bls_pub_key) +- [Function `get_ed_key`](#0x1_consensus_key_get_ed_key) +- [Function `get_cg_key`](#0x1_consensus_key_get_cg_key) + + +
use 0x1::bls12381;
+use 0x1::class_groups;
+use 0x1::ed25519;
+use 0x1::error;
+use 0x1::option;
+use 0x1::vector;
+
+ + + + + +## Struct `ConsensusPublicKey` + +Consensus public key consists of: +1. Ed25519 key +2. Bls12381 G1 key +3. Class group encryption key + + +
struct ConsensusPublicKey has copy, drop, store
+
+ + + +
+Fields + + +
+
+ed_key: ed25519::ValidatedPublicKey +
+
+ +
+
+bls_key: option::Option<bls12381::PublicKey> +
+
+ +
+
+cg_key: option::Option<class_groups::CGPublicKey> +
+
+ +
+
+ + +
+ + + +## Constants + + + + +Wrong number of bytes were given as input when deserializing an consensus public key. + + +
const E_WRONG_PUBKEY_SIZE: u64 = 1;
+
+ + + + + +The size of a serialized bls12381 G1 public key, in bytes. + + +
const BLS12381_G1_PUBLIC_KEY_NUM_BYTES: u64 = 48;
+
+ + + + + +The size of a serialized ed25519 public key, in bytes. + + +
const ED25519_PUBLIC_KEY_NUM_BYTES: u64 = 32;
+
+ + + + + +Invalid consensus public key + + +
const EINVALID_PUBLIC_KEY: u64 = 2;
+
+ + + + + +## Function `consensus_public_key_from_bytes` + + + +
public fun consensus_public_key_from_bytes(bytes: vector<u8>): option::Option<consensus_key::ConsensusPublicKey>
+
+ + + +
+Implementation + + +
public fun consensus_public_key_from_bytes(bytes: vector<u8>): Option<ConsensusPublicKey>{
+    //todo: pop for ed and bls
+    if (vector::length(&bytes) == ED25519_PUBLIC_KEY_NUM_BYTES){
+        let ed_key_bytes = vector::slice(&bytes, 0, ED25519_PUBLIC_KEY_NUM_BYTES);
+        let valid_ed_public_key = ed25519::new_validated_public_key_from_bytes(ed_key_bytes);
+        assert!(option::is_some(&valid_ed_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY));
+        option::some(ConsensusPublicKey {
+            ed_key: option::extract(&mut valid_ed_public_key),
+            bls_key: option::none<bls12381::PublicKey>(),
+            cg_key: option::none<class_groups::CGPublicKey>()
+        })
+    }
+    else if (vector::length(&bytes) > ED25519_PUBLIC_KEY_NUM_BYTES + BLS12381_G1_PUBLIC_KEY_NUM_BYTES){
+
+        let ed_key_bytes = vector::slice(&bytes, 0, ED25519_PUBLIC_KEY_NUM_BYTES);
+        let bls_key_bytes = vector::slice(&bytes, ED25519_PUBLIC_KEY_NUM_BYTES, ED25519_PUBLIC_KEY_NUM_BYTES + BLS12381_G1_PUBLIC_KEY_NUM_BYTES);
+        let cg_key_bytes = vector::slice(&bytes, ED25519_PUBLIC_KEY_NUM_BYTES + BLS12381_G1_PUBLIC_KEY_NUM_BYTES, vector::length(&bytes));
+
+        let valid_ed_public_key = ed25519::new_validated_public_key_from_bytes(ed_key_bytes);
+        assert!(option::is_some(&valid_ed_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY));
+
+        let valid_bls_public_key = bls12381::public_key_from_bytes(bls_key_bytes);
+        assert!(option::is_some(&valid_bls_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY));
+
+        let valid_cg_public_key = class_groups::public_key_from_bytes(cg_key_bytes);
+        assert!(option::is_some(&valid_cg_public_key), error::invalid_argument(EINVALID_PUBLIC_KEY));
+
+        option::some(ConsensusPublicKey {
+            ed_key: option::extract(&mut valid_ed_public_key),
+            bls_key: valid_bls_public_key,
+            cg_key: valid_cg_public_key
+        })
+
+    }
+    else {
+        option::none<ConsensusPublicKey>()
+    }
+}
+
+ + + +
+ + + +## Function `public_key_to_bytes` + + + +
public fun public_key_to_bytes(pk: consensus_key::ConsensusPublicKey): vector<u8>
+
+ + + +
+Implementation + + +
public fun public_key_to_bytes(pk: ConsensusPublicKey): vector<u8>{
+
+    let out = vector::empty<u8>();
+    let ed_bytes  = ed25519::validated_public_key_to_bytes(&pk.ed_key);
+    vector::append(&mut out, ed_bytes);
+
+    if(option::is_some(&pk.bls_key) && option::is_some(&pk.cg_key)){
+        let bls_key = option::extract(&mut pk.bls_key);
+        let bls_bytes = bls12381::public_key_to_bytes(&bls_key);
+        vector::append(&mut out, bls_bytes);
+
+        let cg_key = option::extract(&mut pk.cg_key);
+        let cg_bytes  = class_groups::public_key_to_bytes(&cg_key);
+        vector::append(&mut out, cg_bytes);
+    };
+    out
+}
+
+ + + +
+ + + +## Function `get_bls_pub_key` + + + +
public fun get_bls_pub_key(pk: &consensus_key::ConsensusPublicKey): option::Option<bls12381::PublicKey>
+
+ + + +
+Implementation + + +
public fun get_bls_pub_key(pk: &ConsensusPublicKey): option::Option<bls12381::PublicKey>{
+    pk.bls_key
+}
+
+ + + +
+ + + +## Function `get_ed_key` + + + +
public fun get_ed_key(pk: &consensus_key::ConsensusPublicKey): ed25519::ValidatedPublicKey
+
+ + + +
+Implementation + + +
public fun get_ed_key(pk: &ConsensusPublicKey): ed25519::ValidatedPublicKey{
+    pk.ed_key
+}
+
+ + + +
+ + + +## Function `get_cg_key` + + + +
public fun get_cg_key(pk: &consensus_key::ConsensusPublicKey): option::Option<class_groups::CGPublicKey>
+
+ + + +
+Implementation + + +
public fun get_cg_key(pk: &ConsensusPublicKey): option::Option<class_groups::CGPublicKey>{
+    pk.cg_key
+}
+
+ + + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-stdlib/doc/overview.md b/aptos-move/framework/supra-stdlib/doc/overview.md index e880ae5616a..a8230be46ba 100644 --- a/aptos-move/framework/supra-stdlib/doc/overview.md +++ b/aptos-move/framework/supra-stdlib/doc/overview.md @@ -15,6 +15,7 @@ This is the reference documentation of the Supra standard library extension. - [`0x1::bls12381_bulletproofs`](bls12381_bulletproofs.md#0x1_bls12381_bulletproofs) - [`0x1::bls12381_pedersen`](bls12381_pedersen.md#0x1_bls12381_pedersen) - [`0x1::bls12381_scalar`](bls12381_scalar.md#0x1_bls12381_scalar) +- [`0x1::class_groups`](class_groups.md#0x1_class_groups) - [`0x1::decode_bcs`](decode_bcs.md#0x1_decode_bcs) - [`0x1::enumerable_map`](enumerable_map.md#0x1_enumerable_map) - [`0x1::eth_trie`](eth_trie.md#0x1_eth_trie) diff --git a/aptos-move/framework/supra-stdlib/sources/class_groups.move b/aptos-move/framework/supra-stdlib/sources/class_groups.move new file mode 100644 index 00000000000..d508fb531ca --- /dev/null +++ b/aptos-move/framework/supra-stdlib/sources/class_groups.move @@ -0,0 +1,48 @@ +// Copyright (c) 2025 Supra. +module supra_std::class_groups { + + use std::option; + use std::option::Option; + + struct CGPublicKey has copy, drop, store { + bytes: vector + } + + #[test_only] + struct SecretKey has copy, drop { + bytes: vector, + } + + /// Creates a new public key from a sequence of bytes. + public fun public_key_from_bytes(bytes: vector): Option { + if (validate_pubkey_internal(bytes)) { + option::some(CGPublicKey { + bytes + }) + } else { + option::none() + } + } + + /// Serializes a public key to a sequence of bytes. + public fun public_key_to_bytes(pk: &CGPublicKey): vector { + pk.bytes + } + + #[test_only] + /// Generates a class group key-pair: a secret key with its corresponding public key. + public fun generate_keys(): (SecretKey, CGPublicKey) { + let (sk_bytes, pk_bytes) = generate_keys_internal(); + let sk = SecretKey { + bytes: sk_bytes + }; + let pk = CGPublicKey { + bytes: pk_bytes + }; + (sk, pk) + } + + native fun validate_pubkey_internal(public_key: vector): bool; + #[test_only] + native fun generate_keys_internal(): (vector, vector); +} diff --git a/aptos-move/framework/tests/move_unit_test.rs b/aptos-move/framework/tests/move_unit_test.rs index c4e704137f1..3b1c12ce344 100644 --- a/aptos-move/framework/tests/move_unit_test.rs +++ b/aptos-move/framework/tests/move_unit_test.rs @@ -71,8 +71,8 @@ pub fn aptos_test_natives() -> NativeFunctionTable { natives::configure_for_unit_test(); extended_checks::configure_extended_checks_for_unit_test(); // move_stdlib has the testing feature enabled to include debug native functions - let mut f = Features::default(); - f.enable(aptos_types::on_chain_config::FeatureFlag::DELEGATION_POOLS); + let mut f = Features::default(); + f.enable(aptos_types::on_chain_config::FeatureFlag::DELEGATION_POOLS); natives::aptos_natives( LATEST_GAS_FEATURE_VERSION, NativeGasParameters::zeros(), diff --git a/aptos-move/move-examples/Cargo.toml b/aptos-move/move-examples/Cargo.toml index 7380a8bccfc..3b380bea69b 100644 --- a/aptos-move/move-examples/Cargo.toml +++ b/aptos-move/move-examples/Cargo.toml @@ -16,7 +16,7 @@ rust-version = { workspace = true } aptos-framework = { workspace = true } aptos-gas-schedule = { workspace = true } aptos-types = { workspace = true } -aptos-vm ={ workspace = true, features = ["testing"] } +aptos-vm = { workspace = true, features = ["testing"] } clap = { workspace = true } move-cli = { workspace = true } move-package = { workspace = true } diff --git a/aptos-move/move-examples/cli_args/Move.toml b/aptos-move/move-examples/cli_args/Move.toml index 5549eba33d9..5cd9bd5b839 100644 --- a/aptos-move/move-examples/cli_args/Move.toml +++ b/aptos-move/move-examples/cli_args/Move.toml @@ -7,4 +7,4 @@ upgrade_policy = "compatible" test_account = "_" [dependencies.SupraFramework] -local = "../../framework/supra-framework" \ No newline at end of file +local = "../../framework/supra-framework" diff --git a/aptos-move/move-examples/event/Move.toml b/aptos-move/move-examples/event/Move.toml index 7b0a08a0b3d..80e703ddd18 100644 --- a/aptos-move/move-examples/event/Move.toml +++ b/aptos-move/move-examples/event/Move.toml @@ -9,4 +9,3 @@ event = "_" [dependencies] SupraFramework = { local = "../../framework/supra-framework" } - diff --git a/aptos-move/move-examples/fungible_asset/stablecoin/Move.toml b/aptos-move/move-examples/fungible_asset/stablecoin/Move.toml index 336dfe51799..3fd9f67ffd9 100644 --- a/aptos-move/move-examples/fungible_asset/stablecoin/Move.toml +++ b/aptos-move/move-examples/fungible_asset/stablecoin/Move.toml @@ -6,7 +6,7 @@ version = "0.0.0" [addresses] stablecoin = "_" master_minter = "_" -minter = "_" +minter = "_" pauser = "_" denylister = "_" @@ -18,4 +18,4 @@ pauser = "0xdafe" denylister = "0xcade" [dependencies] -AptosFramework = { local = "../../../framework/aptos-framework" } \ No newline at end of file +AptosFramework = { local = "../../../framework/aptos-framework" } diff --git a/aptos-move/move-examples/hello_prover/Move.toml b/aptos-move/move-examples/hello_prover/Move.toml index 65b64e77840..792250c76b6 100644 --- a/aptos-move/move-examples/hello_prover/Move.toml +++ b/aptos-move/move-examples/hello_prover/Move.toml @@ -6,5 +6,3 @@ version = "0.0.0" SupraFramework = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/supra-framework/", rev = "main" } [addresses] - - diff --git a/aptos-move/move-examples/mint_nft/3-Adding-Admin/Move.toml b/aptos-move/move-examples/mint_nft/3-Adding-Admin/Move.toml index a732c6cc2df..e4519774dbf 100644 --- a/aptos-move/move-examples/mint_nft/3-Adding-Admin/Move.toml +++ b/aptos-move/move-examples/mint_nft/3-Adding-Admin/Move.toml @@ -9,4 +9,4 @@ AptosToken = { local = "../../../framework/aptos-token" } [addresses] aptos_framework = "0x1" # replace the admin_addr with the actual admin address we created using CLI -admin_addr = "0xbeef" \ No newline at end of file +admin_addr = "0xbeef" diff --git a/aptos-move/move-examples/mint_nft/4-Getting-Production-Ready/Move.toml b/aptos-move/move-examples/mint_nft/4-Getting-Production-Ready/Move.toml index a732c6cc2df..e4519774dbf 100644 --- a/aptos-move/move-examples/mint_nft/4-Getting-Production-Ready/Move.toml +++ b/aptos-move/move-examples/mint_nft/4-Getting-Production-Ready/Move.toml @@ -9,4 +9,4 @@ AptosToken = { local = "../../../framework/aptos-token" } [addresses] aptos_framework = "0x1" # replace the admin_addr with the actual admin address we created using CLI -admin_addr = "0xbeef" \ No newline at end of file +admin_addr = "0xbeef" diff --git a/aptos-move/move-examples/my_first_dapp/move/Move.toml b/aptos-move/move-examples/my_first_dapp/move/Move.toml index cc7be052b9f..c1110dd80e9 100644 --- a/aptos-move/move-examples/my_first_dapp/move/Move.toml +++ b/aptos-move/move-examples/my_first_dapp/move/Move.toml @@ -6,4 +6,4 @@ git = 'https://github.com/aptos-labs/aptos-core.git' rev = 'main' subdir = 'aptos-move/framework/supra-framework' [addresses] -todolist_addr='_' \ No newline at end of file +todolist_addr = '_' diff --git a/aptos-move/move-examples/raffle/Move.toml b/aptos-move/move-examples/raffle/Move.toml index ff8b380fcfa..e74c531be77 100644 --- a/aptos-move/move-examples/raffle/Move.toml +++ b/aptos-move/move-examples/raffle/Move.toml @@ -7,4 +7,4 @@ AptosFramework = { local = "../../framework/aptos-framework" } AptosStdlib = { local = "../../framework/aptos-stdlib" } [addresses] -raffle = "_" \ No newline at end of file +raffle = "_" diff --git a/aptos-move/move-examples/tic-tac-toe/Move.toml b/aptos-move/move-examples/tic-tac-toe/Move.toml index 8944127a473..69ae7976390 100644 --- a/aptos-move/move-examples/tic-tac-toe/Move.toml +++ b/aptos-move/move-examples/tic-tac-toe/Move.toml @@ -7,4 +7,3 @@ tic_tac_toe = "_" [dependencies] SupraFramework = { local = "../../framework/supra-framework" } - diff --git a/aptos-move/move-examples/upgrade_and_govern/genesis/Move.toml b/aptos-move/move-examples/upgrade_and_govern/genesis/Move.toml index 512d1c185ac..d0e538ac168 100644 --- a/aptos-move/move-examples/upgrade_and_govern/genesis/Move.toml +++ b/aptos-move/move-examples/upgrade_and_govern/genesis/Move.toml @@ -7,4 +7,4 @@ version = '1.0.0' upgrade_and_govern = '_' [dependencies.SupraFramework] -local = '../../../framework/supra-framework' # <:!:manifest \ No newline at end of file +local = '../../../framework/supra-framework' # <:!:manifest diff --git a/aptos-move/move-examples/upgrade_and_govern/upgrade/Move.toml b/aptos-move/move-examples/upgrade_and_govern/upgrade/Move.toml index 22fc1fd2eef..af213eebc93 100644 --- a/aptos-move/move-examples/upgrade_and_govern/upgrade/Move.toml +++ b/aptos-move/move-examples/upgrade_and_govern/upgrade/Move.toml @@ -7,4 +7,4 @@ version = '1.1.0' upgrade_and_govern = '_' [dependencies.SupraFramework] -local = '../../../framework/supra-framework' # <:!:manifest \ No newline at end of file +local = '../../../framework/supra-framework' # <:!:manifest diff --git a/aptos-move/vm-genesis/Cargo.toml b/aptos-move/vm-genesis/Cargo.toml index 59927cdd791..5dfcd5d6800 100644 --- a/aptos-move/vm-genesis/Cargo.toml +++ b/aptos-move/vm-genesis/Cargo.toml @@ -13,10 +13,11 @@ repository = { workspace = true } rust-version = { workspace = true } [dependencies] -aptos-cached-packages = { workspace = true } +aptos-cached-packages = { workspace = true } aptos-crypto = { workspace = true } -aptos-framework = { workspace = true } -aptos-gas-schedule = { workspace = true } +crypto = { workspace = true } +aptos-framework = { workspace = true } +aptos-gas-schedule = { workspace = true } aptos-types = { workspace = true } aptos-vm = { workspace = true } bcs = { workspace = true } @@ -36,4 +37,8 @@ proptest-derive = { workspace = true } [features] default = [] -fuzzing = ["aptos-types/fuzzing", "move-core-types/fuzzing", "move-vm-types/fuzzing"] +fuzzing = [ + "aptos-types/fuzzing", + "move-core-types/fuzzing", + "move-vm-types/fuzzing", +] diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index a8aeddc99ee..7ffdf0afac8 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -8,6 +8,7 @@ mod genesis_context; use crate::genesis_context::GenesisStateView; use aptos_crypto::{ + bls12381, ed25519, ed25519::{Ed25519PrivateKey, Ed25519PublicKey}, HashValue, PrivateKey, Uniform, @@ -18,7 +19,7 @@ use aptos_gas_schedule::{ }; use aptos_types::{ account_address::{create_resource_address, create_seed_for_pbo_module}, - account_config::{self, aptos_test_root_address, events::NewEpochEvent, CORE_CODE_ADDRESS}, + account_config::{self, CORE_CODE_ADDRESS, aptos_test_root_address, events::NewEpochEvent}, chain_id::ChainId, contract_event::{ContractEvent, ContractEventV1}, jwks::{ @@ -26,17 +27,14 @@ use aptos_types::{ secure_test_rsa_jwk, }, keyless::{ - self, test_utils::get_sample_iss, Groth16VerificationKey, DEVNET_VERIFICATION_KEY, - KEYLESS_ACCOUNT_MODULE_NAME, + self, DEVNET_VERIFICATION_KEY, Groth16VerificationKey, KEYLESS_ACCOUNT_MODULE_NAME, test_utils::get_sample_iss }, move_utils::as_move_value::AsMoveValue, on_chain_config::{ - randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit}, - AutomationRegistryConfig, FeatureFlag, Features, GasScheduleV2, OnChainConsensusConfig, - OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, - OnChainRandomnessConfig, RandomnessConfigMoveStruct, APTOS_MAX_KNOWN_VERSION, + APTOS_MAX_KNOWN_VERSION, AutomationRegistryConfig, BanRegistryParameters, BanRegistryParametersV0, FeatureFlag, Features, GasScheduleV2, OnChainConsensusConfig, OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit} }, transaction::{authenticator::AuthenticationKey, ChangeSet, Transaction, WriteSetPayload}, + validator_public_keys::ValidatorPublicKeys, write_set::TransactionWrite, }; use aptos_vm::{ @@ -108,6 +106,7 @@ pub struct GenesisConfiguration { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub automation_registry_config: Option, + pub leader_ban_registry_config: Option, } pub static GENESIS_KEYPAIR: Lazy<(Ed25519PrivateKey, Ed25519PublicKey)> = Lazy::new(|| { @@ -338,6 +337,7 @@ pub fn encode_genesis_change_set_for_testnet( initialize_randomness_config(&mut session, randomness_config); initialize_randomness_resources(&mut session); initialize_on_chain_governance(&mut session, genesis_config); + initialize_leader_ban_config(&mut session, genesis_config); if let Some(evm_genesis_config) = evm_genesis_config { initialize_evm_genesis_config(&mut session, &evm_genesis_config); @@ -584,6 +584,22 @@ fn initialize_supra_native_automation( ); } +fn initialize_leader_ban_config( + session: &mut SessionExt, + genesis_config: &GenesisConfiguration, +) { + let Some(config) = &genesis_config.leader_ban_registry_config else { + return; + }; + exec_function( + session, + GENESIS_MODULE_NAME, + "initialize_leader_ban_registry_config", + vec![], + config.serialize_into_move_values_with_signer(CORE_CODE_ADDRESS), + ); +} + fn initialize_evm_genesis_config( session: &mut SessionExt, evm_genesis_config: &OnChainEvmGenesisConfig, @@ -1021,19 +1037,13 @@ fn publish_package(session: &mut SessionExt, pack: &ReleasePackage) { }); // Call the initialize function with the metadata. - exec_function( - session, - CODE_MODULE_NAME, - "initialize", - vec![], - vec![ - MoveValue::Signer(CORE_CODE_ADDRESS) - .simple_serialize() - .unwrap(), - MoveValue::Signer(addr).simple_serialize().unwrap(), - bcs::to_bytes(pack.package_metadata()).unwrap(), - ], - ); + exec_function(session, CODE_MODULE_NAME, "initialize", vec![], vec![ + MoveValue::Signer(CORE_CODE_ADDRESS) + .simple_serialize() + .unwrap(), + MoveValue::Signer(addr).simple_serialize().unwrap(), + bcs::to_bytes(pack.package_metadata()).unwrap(), + ]); } /// Trigger a reconfiguration. This emits an event that will be passed along to the storage layer. @@ -1171,7 +1181,35 @@ impl TestValidator { let auth_key = AuthenticationKey::ed25519(&key.public_key()); let owner_address = auth_key.account_address(); let consensus_key = ed25519::PrivateKey::generate(rng); - let consensus_pubkey = consensus_key.public_key().to_bytes().to_vec(); + let network_pubkey_bytes = consensus_key.public_key().to_bytes().to_vec(); + let bls_key = bls12381::PrivateKey::generate(rng); + let bls_pubkey_bytes = bls12381::PublicKey::from(&bls_key).to_bytes().to_vec(); + let cg_pubkey_bytes = { + let mut cg_rng = crypto::bls12381::cl_utils::rng(); + crypto::bls12381::cg_encryption::keygen(&mut cg_rng, &[]) + .expect("CG keygen must succeed") + .1 + .to_vec() + }; + let supra_ed_key = ed25519::PrivateKey::generate(rng); + let supra_ed_pubkey_bytes = supra_ed_key.public_key().to_bytes().to_vec(); + // When SUPRA_BLS_KEYS feature is enabled (default), the genesis validator key must be + // BCS-encoded ValidatorPublicKeys, not a plain ed25519 key. + let validator_public_keys = ValidatorPublicKeys::new( + network_pubkey_bytes, + bls_pubkey_bytes, + None, + None, + None, + None, + None, + None, + None, + cg_pubkey_bytes, + supra_ed_pubkey_bytes, + ); + let consensus_pubkey = + bcs::to_bytes(&validator_public_keys).expect("ValidatorPublicKeys must serialize"); let network_address = [0u8; 0].to_vec(); let full_node_network_address = [0u8; 0].to_vec(); @@ -1242,6 +1280,7 @@ pub fn generate_test_genesis( randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), + leader_ban_registry_config: Some(BanRegistryParameters::default()), }, &OnChainConsensusConfig::default_for_genesis(), &OnChainExecutionConfig::default_for_genesis(), @@ -1310,6 +1349,7 @@ fn mainnet_genesis_config() -> GenesisConfiguration { randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), + leader_ban_registry_config: Some(BanRegistryParameters::default()), } } diff --git a/aptos-node/Cargo.toml b/aptos-node/Cargo.toml index 5281650c795..be242768c5a 100644 --- a/aptos-node/Cargo.toml +++ b/aptos-node/Cargo.toml @@ -87,11 +87,24 @@ jemallocator = { workspace = true } rstack-self = { workspace = true } [features] -assert-private-keys-not-cloneable = ["aptos-crypto/assert-private-keys-not-cloneable"] +assert-private-keys-not-cloneable = [ + "aptos-crypto/assert-private-keys-not-cloneable", +] check-vm-features = [] -consensus-only-perf-test = ["aptos-executor/consensus-only-perf-test", "aptos-mempool/consensus-only-perf-test", "aptos-db/consensus-only-perf-test"] +consensus-only-perf-test = [ + "aptos-executor/consensus-only-perf-test", + "aptos-mempool/consensus-only-perf-test", + "aptos-db/consensus-only-perf-test", +] default = [] -failpoints = ["fail/failpoints", "aptos-consensus/failpoints", "aptos-executor/failpoints", "aptos-mempool/failpoints", "aptos-api/failpoints", "aptos-config/failpoints"] +failpoints = [ + "fail/failpoints", + "aptos-consensus/failpoints", + "aptos-executor/failpoints", + "aptos-mempool/failpoints", + "aptos-api/failpoints", + "aptos-config/failpoints", +] indexer = ["aptos-indexer"] tokio-console = ["aptos-logger/tokio-console", "aptos-config/tokio-console"] smoke-test = ["aptos-jwk-consensus/smoke-test", "aptos-dkg-runtime/smoke-test"] diff --git a/config/global-constants/src/lib.rs b/config/global-constants/src/lib.rs index ef88fd7d768..04f26559d7c 100644 --- a/config/global-constants/src/lib.rs +++ b/config/global-constants/src/lib.rs @@ -23,6 +23,8 @@ pub const GENESIS_WAYPOINT: &str = "genesis-waypoint"; #[cfg(any(test, feature = "testing"))] pub const GAS_UNIT_PRICE: u64 = 0; + +/// Increased from 100 to 100_000 in accordance with the outcome of https://vote.supra.com/proposal/3. #[cfg(not(any(test, feature = "testing")))] pub const GAS_UNIT_PRICE: u64 = 100_000; diff --git a/config/src/config/identity_config.rs b/config/src/config/identity_config.rs index 82f3ded0cc1..096be32cfc2 100644 --- a/config/src/config/identity_config.rs +++ b/config/src/config/identity_config.rs @@ -11,7 +11,7 @@ use aptos_crypto::{ }; use aptos_types::{ account_address::{from_identity_public_key, AccountAddress, AccountAddress as PeerId}, - dkg::{real_dkg::maybe_dk_from_bls_sk, DKGTrait, DefaultDKG}, + aptos_dkg::{real_dkg::maybe_dk_from_bls_sk, DKGTrait, DefaultDKG}, }; use serde::{Deserialize, Serialize}; use std::{ diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 4d6f00ed821..80b45a23ee5 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -105,12 +105,12 @@ tempfile = { workspace = true } [features] default = [] fuzzing = [ - "aptos-consensus-types/fuzzing", - "aptos-config/fuzzing", - "aptos-crypto/fuzzing", - "aptos-mempool/fuzzing", - "aptos-types/fuzzing", - "aptos-safety-rules/testing", + "aptos-consensus-types/fuzzing", + "aptos-config/fuzzing", + "aptos-crypto/fuzzing", + "aptos-mempool/fuzzing", + "aptos-types/fuzzing", + "aptos-safety-rules/testing", ] failpoints = ["fail/failpoints"] diff --git a/consensus/src/epoch_manager.rs b/consensus/src/epoch_manager.rs index f7f43442038..39587b7c0af 100644 --- a/consensus/src/epoch_manager.rs +++ b/consensus/src/epoch_manager.rs @@ -81,7 +81,7 @@ use aptos_safety_rules::SafetyRulesManager; use aptos_secure_storage::{KVStorage, Storage}; use aptos_types::{ account_address::AccountAddress, - dkg::{real_dkg::maybe_dk_from_bls_sk, DKGState, DKGTrait, DefaultDKG}, + aptos_dkg::{real_dkg::maybe_dk_from_bls_sk, DKGState, DKGTrait, DefaultDKG}, epoch_change::EpochChangeProof, epoch_state::EpochState, jwks::SupportedOIDCProviders, diff --git a/consensus/src/payload_client/mixed.rs b/consensus/src/payload_client/mixed.rs index 63cc7f00a62..79b98b59ed4 100644 --- a/consensus/src/payload_client/mixed.rs +++ b/consensus/src/payload_client/mixed.rs @@ -47,15 +47,15 @@ impl MixedPayloadClient { /// When enabled in smoke tests, generate 2 random validator transactions, 1 valid, 1 invalid. fn extra_test_only_vtxns(&self) -> Vec { fail_point!("mixed_payload_client::extra_test_only_vtxns", |_| { - use aptos_types::dkg::{DKGTranscript, DKGTranscriptMetadata}; + use aptos_types::dkg::{DKGTransactionData, DKGTransactionMetadata}; use move_core_types::account_address::AccountAddress; - vec![ValidatorTransaction::DKGResult(DKGTranscript { - metadata: DKGTranscriptMetadata { + vec![ValidatorTransaction::DKG(DKGTransactionData { + metadata: DKGTransactionMetadata { epoch: 999, author: AccountAddress::ZERO, }, - transcript_bytes: vec![], + data_bytes: vec![], })] }); vec![] diff --git a/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun.rs b/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun.rs index 45e1dce9624..778ec7c6bb7 100644 --- a/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun.rs +++ b/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun.rs @@ -4,8 +4,10 @@ use crate::transaction_shuffler::fairness::conflict_key::ConflictKey; use aptos_types::transaction::{SignedTransaction, TransactionPayload}; -use move_core_types::{identifier::Identifier, language_storage::ModuleId}; -use move_core_types::identifier::IdentStr; +use move_core_types::{ + identifier::{IdentStr, Identifier}, + language_storage::ModuleId, +}; #[derive(Eq, Hash, PartialEq)] pub enum EntryFunKey { @@ -36,7 +38,7 @@ impl ConflictKey for EntryFunKey { match txn.payload() { TransactionPayload::AutomationRegistration(auto_payload) => { EntryFunKey::from((auto_payload.module_id(), auto_payload.function())) - } + }, TransactionPayload::EntryFunction(entry_fun) => { EntryFunKey::from((entry_fun.module(), entry_fun.function())) }, diff --git a/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun_module.rs b/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun_module.rs index c142cb193a2..5f5c14ec258 100644 --- a/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun_module.rs +++ b/consensus/src/transaction_shuffler/fairness/conflict_key/entry_fun_module.rs @@ -26,7 +26,9 @@ impl From<&ModuleId> for EntryFunModuleKey { impl ConflictKey for EntryFunModuleKey { fn extract_from(txn: &SignedTransaction) -> Self { match txn.payload() { - TransactionPayload::AutomationRegistration(auto_payload) => Self::from(auto_payload.module_id()), + TransactionPayload::AutomationRegistration(auto_payload) => { + Self::from(auto_payload.module_id()) + }, TransactionPayload::EntryFunction(entry_fun) => Self::from(entry_fun.module()), TransactionPayload::Multisig(..) | TransactionPayload::Script(_) diff --git a/consensus/src/util/mod.rs b/consensus/src/util/mod.rs index a469f121916..37b38074068 100644 --- a/consensus/src/util/mod.rs +++ b/consensus/src/util/mod.rs @@ -18,6 +18,7 @@ pub fn is_vtxn_expected( vtxn: &ValidatorTransaction, ) -> bool { match vtxn { + ValidatorTransaction::DKG(_) => randomness_config.randomness_enabled(), ValidatorTransaction::DKGResult(_) => randomness_config.randomness_enabled(), ValidatorTransaction::ObservedJWKUpdate(_) => jwk_consensus_config.jwk_consensus_enabled(), } diff --git a/crates/aptos-collections/Cargo.toml b/crates/aptos-collections/Cargo.toml index 69c953a35c6..ee1d4db9107 100644 --- a/crates/aptos-collections/Cargo.toml +++ b/crates/aptos-collections/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aptos-collections" -description = "Aptos Collections Library" +description = "Aptos Collections Library" version = "0.1.0" # Workspace inherited keys diff --git a/crates/aptos-crypto/Cargo.toml b/crates/aptos-crypto/Cargo.toml index eacada812fa..f454e10ed6d 100644 --- a/crates/aptos-crypto/Cargo.toml +++ b/crates/aptos-crypto/Cargo.toml @@ -58,6 +58,11 @@ static_assertions = { workspace = true } thiserror = { workspace = true } tiny-keccak = { workspace = true } typenum = { workspace = true } +utoipa = { features = [ + "non_strict_integers", + "preserve_order", + "uuid", +], optional = true, workspace = true } x25519-dalek = { workspace = true } [dev-dependencies] @@ -80,6 +85,7 @@ default = [] assert-private-keys-not-cloneable = [] cloneable-private-keys = [] fuzzing = ["proptest", "proptest-derive", "cloneable-private-keys"] +rest_api_schema = ["utoipa"] testing = [] [[bench]] diff --git a/crates/aptos-crypto/src/hash.rs b/crates/aptos-crypto/src/hash.rs index 4707a0a5eb1..cbfb0340deb 100644 --- a/crates/aptos-crypto/src/hash.rs +++ b/crates/aptos-crypto/src/hash.rs @@ -113,7 +113,7 @@ use std::{ fmt, str::FromStr, }; -use tiny_keccak::{Hasher, Sha3, Keccak}; +use tiny_keccak::{Hasher, Keccak, Sha3}; /// A prefix used to begin the salt of every hashable structure. The salt /// consists in this global prefix, concatenated with the specified @@ -123,6 +123,8 @@ pub(crate) const HASH_PREFIX: &[u8] = b"SUPRA::"; /// Output value of our hash function. Intentionally opaque for safety and modularity. #[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] #[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] +#[cfg_attr(feature = "rest_api_schema", derive(utoipa::ToSchema))] +#[cfg_attr(feature = "rest_api_schema",schema(as = String))] pub struct HashValue { hash: [u8; HashValue::LENGTH], } @@ -192,6 +194,7 @@ impl HashValue { } #[cfg(test)] + #[allow(missing_docs)] pub fn from_iter_sha3<'a, I>(buffers: I) -> Self where I: IntoIterator, diff --git a/crates/aptos-dkg/Cargo.toml b/crates/aptos-dkg/Cargo.toml index 67f8660a49e..d862b569cfd 100644 --- a/crates/aptos-dkg/Cargo.toml +++ b/crates/aptos-dkg/Cargo.toml @@ -9,7 +9,7 @@ anyhow = { workspace = true } aptos-crypto = { workspace = true } aptos-crypto-derive = { workspace = true } aptos-runtimes = { workspace = true } -bcs = { workspace = true } +bcs = { workspace = true } blst = { workspace = true } blstrs = { workspace = true } criterion = { workspace = true } diff --git a/crates/aptos-faucet/cli/Cargo.toml b/crates/aptos-faucet/cli/Cargo.toml index f68cf9a2984..630ebae285c 100644 --- a/crates/aptos-faucet/cli/Cargo.toml +++ b/crates/aptos-faucet/cli/Cargo.toml @@ -19,4 +19,3 @@ aptos-logger = { workspace = true } aptos-sdk = { workspace = true } clap = { workspace = true } tokio = { workspace = true } - diff --git a/crates/aptos-faucet/core/Cargo.toml b/crates/aptos-faucet/core/Cargo.toml index 0653a1eacc5..61b6826b4f2 100644 --- a/crates/aptos-faucet/core/Cargo.toml +++ b/crates/aptos-faucet/core/Cargo.toml @@ -17,12 +17,14 @@ anyhow = { workspace = true } aptos-config = { workspace = true } aptos-faucet-metrics-server = { workspace = true } aptos-logger = { workspace = true } -aptos-metrics-core = { workspace = true } +aptos-metrics-core = { workspace = true } aptos-sdk = { workspace = true } async-trait = { workspace = true } captcha = { version = "0.0.9" } clap = { workspace = true } -deadpool-redis = { version = "0.11.1", features = ["rt_tokio_1"], default-features = false } +deadpool-redis = { version = "0.11.1", features = [ + "rt_tokio_1", +], default-features = false } enum_dispatch = { workspace = true } futures = { workspace = true } hex = { workspace = true } @@ -33,7 +35,11 @@ once_cell = { workspace = true } poem = { workspace = true } poem-openapi = { workspace = true } rand = { workspace = true } -redis = { workspace = true, features = ["aio", "tokio-comp", "connection-manager"] } +redis = { workspace = true, features = [ + "aio", + "tokio-comp", + "connection-manager", +] } reqwest = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/aptos-faucet/core/src/checkers/redis_ratelimit.rs b/crates/aptos-faucet/core/src/checkers/redis_ratelimit.rs index 16f7fb7b68a..32a5659ab47 100644 --- a/crates/aptos-faucet/core/src/checkers/redis_ratelimit.rs +++ b/crates/aptos-faucet/core/src/checkers/redis_ratelimit.rs @@ -252,7 +252,7 @@ impl CheckerTrait for RedisRatelimitChecker { // Generate a key corresponding to this IP address and the current day. let (key, _) = self.get_key_and_secs_until_next_day(&data.checker_data.source_ip); - conn.decr(&key, 1).await.map_err(|e| { + conn.decr::<_, _, ()>(&key, 1).await.map_err(|e| { AptosTapError::new_with_error_code( format!("Failed to decrement value for redis key {}: {}", key, e), AptosTapErrorCode::StorageError, diff --git a/crates/aptos-faucet/metrics-server/Cargo.toml b/crates/aptos-faucet/metrics-server/Cargo.toml index 3b779539d43..f427e211160 100644 --- a/crates/aptos-faucet/metrics-server/Cargo.toml +++ b/crates/aptos-faucet/metrics-server/Cargo.toml @@ -15,7 +15,7 @@ rust-version = { workspace = true } [dependencies] anyhow = { workspace = true } aptos-logger = { workspace = true } -aptos-metrics-core = { workspace = true } +aptos-metrics-core = { workspace = true } once_cell = { workspace = true } poem = { workspace = true } prometheus = { workspace = true } diff --git a/crates/aptos-genesis/src/builder.rs b/crates/aptos-genesis/src/builder.rs index bdb84a172d6..e0374b0b2df 100644 --- a/crates/aptos-genesis/src/builder.rs +++ b/crates/aptos-genesis/src/builder.rs @@ -28,8 +28,7 @@ use aptos_types::{ account_address::AccountAddress, chain_id::ChainId, on_chain_config::{ - Features, GasScheduleV2, OnChainConsensusConfig, OnChainExecutionConfig, - OnChainJWKConsensusConfig, OnChainRandomnessConfig, + AutomationRegistryConfig, BanRegistryParameters, Features, GasScheduleV2, OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig }, transaction::Transaction, waypoint::Waypoint, @@ -45,7 +44,6 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use aptos_types::on_chain_config::AutomationRegistryConfig; const VALIDATOR_IDENTITY: &str = "validator-identity.yaml"; const VFN_IDENTITY: &str = "vfn-identity.yaml"; @@ -438,6 +436,7 @@ pub struct GenesisConfiguration { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub automation_registry_config: Option, + pub leader_ban_registry_config: Option, } pub type InitConfigFn = Arc; @@ -662,6 +661,7 @@ impl Builder { randomness_config_override: None, jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), + leader_ban_registry_config: Some(BanRegistryParameters::default()), }; if let Some(init_genesis_config) = &self.init_genesis_config { (init_genesis_config)(&mut genesis_config); diff --git a/crates/aptos-genesis/src/config.rs b/crates/aptos-genesis/src/config.rs index 5449c46382a..3b31e7421b0 100644 --- a/crates/aptos-genesis/src/config.rs +++ b/crates/aptos-genesis/src/config.rs @@ -7,7 +7,9 @@ use aptos_types::{ account_address::{AccountAddress, AccountAddressWithChecks}, chain_id::ChainId, network_address::{DnsName, NetworkAddress, Protocol}, - on_chain_config::{OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig}, + on_chain_config::{ + AutomationRegistryConfig, BanRegistryParameters, OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig + }, transaction::authenticator::AuthenticationKey, }; use aptos_vm_genesis::{AccountBalance, EmployeePool, Validator, ValidatorWithCommissionRate}; @@ -21,7 +23,6 @@ use std::{ path::Path, str::FromStr, }; -use aptos_types::on_chain_config::AutomationRegistryConfig; /// Template for setting up Github for Genesis /// @@ -83,6 +84,8 @@ pub struct Layout { pub jwk_consensus_config_override: Option, /// An optional supra native automation config. pub automation_registry_config: Option, + /// An optional supra leader ban config. + pub leader_ban_registry_config: Option, } impl Layout { @@ -126,6 +129,7 @@ impl Default for Layout { on_chain_execution_config: OnChainExecutionConfig::default_for_genesis(), jwk_consensus_config_override: None, automation_registry_config: Some(AutomationRegistryConfig::default()), + leader_ban_registry_config: Some(BanRegistryParameters::default()), } } } diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs index 1c5b9fd858d..d53bf924acc 100644 --- a/crates/aptos-genesis/src/lib.rs +++ b/crates/aptos-genesis/src/lib.rs @@ -25,7 +25,9 @@ use aptos_types::{ account_address::AccountAddress, chain_id::ChainId, on_chain_config::{ - Features, GasScheduleV2, OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig + AutomationRegistryConfig, Features, GasScheduleV2, OnChainConsensusConfig, + OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig, + BanRegistryParameters, }, transaction::Transaction, waypoint::Waypoint, @@ -33,7 +35,6 @@ use aptos_types::{ use aptos_vm::AptosVM; use aptos_vm_genesis::Validator; use std::convert::TryInto; -use aptos_types::on_chain_config::AutomationRegistryConfig; /// Holder object for all pieces needed to generate a genesis transaction #[derive(Clone)] @@ -82,6 +83,7 @@ pub struct GenesisInfo { pub randomness_config_override: Option, pub jwk_consensus_config_override: Option, pub automation_registry_config: Option, + pub leader_ban_registry_config: Option } impl GenesisInfo { @@ -124,6 +126,7 @@ impl GenesisInfo { randomness_config_override: genesis_config.randomness_config_override.clone(), jwk_consensus_config_override: genesis_config.jwk_consensus_config_override.clone(), automation_registry_config: genesis_config.automation_registry_config.clone(), + leader_ban_registry_config: genesis_config.leader_ban_registry_config.clone(), }) } @@ -167,6 +170,7 @@ impl GenesisInfo { jwk_consensus_config_override: self.jwk_consensus_config_override.clone(), genesis_timestamp_in_microseconds: self.genesis_timestamp_in_microseconds, automation_registry_config: self.automation_registry_config.clone(), + leader_ban_registry_config: self.leader_ban_registry_config.clone(), }, &self.consensus_config, &self.execution_config, diff --git a/crates/aptos-genesis/src/mainnet.rs b/crates/aptos-genesis/src/mainnet.rs index 1478112f58c..99f0b775f7b 100644 --- a/crates/aptos-genesis/src/mainnet.rs +++ b/crates/aptos-genesis/src/mainnet.rs @@ -13,11 +13,12 @@ use aptos_temppath::TempPath; use aptos_types::{ account_address::AccountAddress, chain_id::ChainId, - on_chain_config::{Features, OnChainJWKConsensusConfig, OnChainRandomnessConfig}, + on_chain_config::{ + AutomationRegistryConfig, BanRegistryParameters, Features, OnChainJWKConsensusConfig, OnChainRandomnessConfig + }, transaction::Transaction, waypoint::Waypoint, }; -use aptos_types::on_chain_config::AutomationRegistryConfig; use aptos_vm::AptosVM; use aptos_vm_genesis::{AccountBalance, EmployeePool, ValidatorWithCommissionRate}; @@ -72,6 +73,8 @@ pub struct MainnetGenesisInfo { jwk_consensus_config_override: Option, /// Supra native automation feature configuration parameters automation_registry_config: Option, + /// Supra native consensus leader ban registry configuration parameters + leader_ban_registry_config: Option, } impl MainnetGenesisInfo { @@ -117,6 +120,7 @@ impl MainnetGenesisInfo { randomness_config_override: genesis_config.randomness_config_override.clone(), jwk_consensus_config_override: genesis_config.jwk_consensus_config_override.clone(), automation_registry_config: genesis_config.automation_registry_config.clone(), + leader_ban_registry_config: genesis_config.leader_ban_registry_config.clone(), }) } @@ -161,6 +165,7 @@ impl MainnetGenesisInfo { randomness_config_override: self.randomness_config_override.clone(), jwk_consensus_config_override: self.jwk_consensus_config_override.clone(), automation_registry_config: self.automation_registry_config.clone(), + leader_ban_registry_config: self.leader_ban_registry_config.clone(), }, b"test".to_vec(), ) diff --git a/crates/aptos-id-generator/Cargo.toml b/crates/aptos-id-generator/Cargo.toml index 89eb2315b9e..332cbb108c7 100644 --- a/crates/aptos-id-generator/Cargo.toml +++ b/crates/aptos-id-generator/Cargo.toml @@ -13,4 +13,3 @@ repository = { workspace = true } rust-version = { workspace = true } [dependencies] - diff --git a/crates/aptos-infallible/Cargo.toml b/crates/aptos-infallible/Cargo.toml index 822c9b1c376..ea7cc093ce8 100644 --- a/crates/aptos-infallible/Cargo.toml +++ b/crates/aptos-infallible/Cargo.toml @@ -13,4 +13,3 @@ repository = { workspace = true } rust-version = { workspace = true } [dependencies] - diff --git a/crates/aptos-keygen/Cargo.toml b/crates/aptos-keygen/Cargo.toml index f58044df02a..abea0439347 100644 --- a/crates/aptos-keygen/Cargo.toml +++ b/crates/aptos-keygen/Cargo.toml @@ -16,4 +16,3 @@ rust-version = { workspace = true } aptos-crypto = { workspace = true } aptos-types = { workspace = true } rand = { workspace = true } - diff --git a/crates/aptos-log-derive/Cargo.toml b/crates/aptos-log-derive/Cargo.toml index 65ba47e3e65..4ada1edf6a8 100644 --- a/crates/aptos-log-derive/Cargo.toml +++ b/crates/aptos-log-derive/Cargo.toml @@ -19,5 +19,3 @@ proc-macro = true proc-macro2 = { workspace = true } quote = { workspace = true } syn = { workspace = true } - - diff --git a/crates/aptos-network-checker/Cargo.toml b/crates/aptos-network-checker/Cargo.toml index b8941edb57c..361eae8246b 100644 --- a/crates/aptos-network-checker/Cargo.toml +++ b/crates/aptos-network-checker/Cargo.toml @@ -23,4 +23,3 @@ clap = { workspace = true } futures = { workspace = true } serde = { workspace = true } tokio = { workspace = true } - diff --git a/crates/aptos-profiler/Cargo.toml b/crates/aptos-profiler/Cargo.toml index e13c1ceec35..a379e835ea1 100644 --- a/crates/aptos-profiler/Cargo.toml +++ b/crates/aptos-profiler/Cargo.toml @@ -20,4 +20,3 @@ pprof = { workspace = true } backtrace = { workspace = true } jemallocator = { workspace = true } jemalloc-sys = { workspace = true } - diff --git a/crates/aptos-proptest-helpers/Cargo.toml b/crates/aptos-proptest-helpers/Cargo.toml index 4e1bc94c076..584d9c3bbca 100644 --- a/crates/aptos-proptest-helpers/Cargo.toml +++ b/crates/aptos-proptest-helpers/Cargo.toml @@ -16,5 +16,3 @@ rust-version = { workspace = true } crossbeam = { workspace = true } proptest = { workspace = true } proptest-derive = { workspace = true } - - diff --git a/crates/aptos-rate-limiter/Cargo.toml b/crates/aptos-rate-limiter/Cargo.toml index 3de9cdfca4f..c277d90e4c7 100644 --- a/crates/aptos-rate-limiter/Cargo.toml +++ b/crates/aptos-rate-limiter/Cargo.toml @@ -20,4 +20,3 @@ futures = { workspace = true } pin-project = { workspace = true } tokio = { workspace = true } tokio-util = { workspace = true } - diff --git a/crates/aptos-retrier/Cargo.toml b/crates/aptos-retrier/Cargo.toml index 8eccb8ac672..a7c809a2e03 100644 --- a/crates/aptos-retrier/Cargo.toml +++ b/crates/aptos-retrier/Cargo.toml @@ -15,4 +15,3 @@ rust-version = { workspace = true } [dependencies] aptos-logger = { workspace = true } tokio = { workspace = true } - diff --git a/crates/aptos-rosetta-cli/Cargo.toml b/crates/aptos-rosetta-cli/Cargo.toml index ff37ec922ae..e9bf998b7b3 100644 --- a/crates/aptos-rosetta-cli/Cargo.toml +++ b/crates/aptos-rosetta-cli/Cargo.toml @@ -23,4 +23,3 @@ serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true } url = { workspace = true } - diff --git a/crates/aptos-rosetta/src/types/objects.rs b/crates/aptos-rosetta/src/types/objects.rs index b9bbde086a4..ed650d3e440 100644 --- a/crates/aptos-rosetta/src/types/objects.rs +++ b/crates/aptos-rosetta/src/types/objects.rs @@ -921,8 +921,7 @@ impl Transaction { (TransactionType::Validator, None, None, txn.info, txn.events) }, BlockEpilogue(_) => (TransactionType::BlockEpilogue, None, None, txn.info, vec![]), - AutomatedTransaction(automated_txn) - | SystemAutomatedTransaction(automated_txn)=> ( + AutomatedTransaction(automated_txn) | SystemAutomatedTransaction(automated_txn) => ( TransactionType::Automated, None, Some(automated_txn), @@ -935,7 +934,7 @@ impl Transaction { None, txn.info, txn.events, - ) + ), }; // Operations must be sequential and operation index must always be in the same order diff --git a/crates/aptos-temppath/Cargo.toml b/crates/aptos-temppath/Cargo.toml index 39341318abf..20aa81dcbc6 100644 --- a/crates/aptos-temppath/Cargo.toml +++ b/crates/aptos-temppath/Cargo.toml @@ -15,5 +15,3 @@ rust-version = { workspace = true } [dependencies] hex = { workspace = true } rand = { workspace = true } - - diff --git a/crates/aptos/Cargo.toml b/crates/aptos/Cargo.toml index bb2d65e0dfa..2dd782a60f3 100644 --- a/crates/aptos/Cargo.toml +++ b/crates/aptos/Cargo.toml @@ -56,9 +56,7 @@ chrono = { workspace = true } clap = { workspace = true, features = ["env", "unstable-styles"] } clap_complete = { workspace = true } dashmap = { workspace = true } -diesel = { workspace = true, features = [ - "postgres_backend", -] } +diesel = { workspace = true, features = ["postgres_backend"] } diesel-async = { workspace = true } dirs = { workspace = true } futures = { workspace = true } @@ -87,7 +85,10 @@ poem = { workspace = true } rand = { workspace = true } regex = { workspace = true } reqwest = { workspace = true } -self_update = { git = "https://github.com/banool/self_update.git", rev = "8306158ad0fd5b9d4766a3c6bf967e7ef0ea5c4b", features = ["archive-zip", "compression-zip-deflate"] } +self_update = { git = "https://github.com/banool/self_update.git", rev = "8306158ad0fd5b9d4766a3c6bf967e7ef0ea5c4b", features = [ + "archive-zip", + "compression-zip-deflate", +] } serde = { workspace = true } serde_json = { workspace = true } serde_yaml = { workspace = true } diff --git a/crates/aptos/src/account/multisig_account.rs b/crates/aptos/src/account/multisig_account.rs index cd30f4e68d4..00383722305 100644 --- a/crates/aptos/src/account/multisig_account.rs +++ b/crates/aptos/src/account/multisig_account.rs @@ -16,10 +16,11 @@ use aptos_rest_client::{ aptos_api_types::{HexEncodedBytes, WriteResource, WriteSetChange}, Transaction, }; -use aptos_types::transaction::automation::RegistrationParams; use aptos_types::{ account_address::AccountAddress, - transaction::{Multisig, MultisigTransactionPayload, TransactionPayload}, + transaction::{ + automation::RegistrationParams, Multisig, MultisigTransactionPayload, TransactionPayload, + }, }; use async_trait::async_trait; use bcs::to_bytes; @@ -170,7 +171,7 @@ impl TryFrom for MultisigTransactionPayload { match value { MultisigPayloadVariants::EntryFunction(e) => e.try_into(), MultisigPayloadVariants::GaslessAutomationTask(r) => r.try_into(), - MultisigPayloadVariants::AutomationTask(r) => r.try_into() + MultisigPayloadVariants::AutomationTask(r) => r.try_into(), } } } @@ -234,7 +235,7 @@ impl TryFrom for MultisigTransactionPayload type Error = CliError; fn try_from( - value: AutomationTaskRegistrationArguments + value: AutomationTaskRegistrationArguments, ) -> Result { let automation_function = value.automation_function.try_into()?; let registration_params = RegistrationParams::new_user_automation_task_v2( @@ -252,7 +253,6 @@ impl TryFrom for MultisigTransactionPayload } } - /// Propose a new multisig transaction. /// /// As one of the owners of the multisig, propose a new transaction. This also implicitly approves @@ -271,7 +271,6 @@ pub struct CreateTransaction { pub(crate) store_hash_only: bool, } - #[async_trait] impl CliCommand for CreateTransaction { fn command_name(&self) -> &'static str { @@ -325,8 +324,6 @@ impl SupraCommand for CreateTransaction { } } - - /// Verify entry function matches on-chain transaction proposal. #[derive(Debug, Parser)] pub struct VerifyProposal { diff --git a/crates/aptos/src/common/types.rs b/crates/aptos/src/common/types.rs index 84e057d8fbc..38027746bd1 100644 --- a/crates/aptos/src/common/types.rs +++ b/crates/aptos/src/common/types.rs @@ -24,6 +24,7 @@ use aptos_api_types::ViewFunction; use aptos_crypto::{ ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature}, encoding_type::{EncodingError, EncodingType}, + hash::HashValueParseError, x25519, PrivateKey, ValidCryptoMaterialStringExt, }; use aptos_global_constants::adjust_gas_headroom; @@ -67,9 +68,8 @@ use std::{ str::FromStr, time::{Duration, Instant, SystemTime, UNIX_EPOCH}, }; -use thiserror::Error; -use aptos_crypto::hash::HashValueParseError; use supra_aptos::ApiVersion; +use thiserror::Error; pub const USER_AGENT: &str = concat!("aptos-cli/", env!("CARGO_PKG_VERSION")); const US_IN_SECS: u64 = 1_000_000; diff --git a/crates/aptos/src/genesis/mod.rs b/crates/aptos/src/genesis/mod.rs index f893ca4b88f..a7c8dc3490b 100644 --- a/crates/aptos/src/genesis/mod.rs +++ b/crates/aptos/src/genesis/mod.rs @@ -260,6 +260,7 @@ pub fn fetch_mainnet_genesis_info(git_options: GitOptions) -> CliTypedResult CliTypedResult> for SubmitVote { summaries.push( self.args .txn_options - .submit_transaction(aptos_stdlib::supra_governance_supra_vote( - proposal_id, - vote, - )) + .submit_transaction(aptos_stdlib::supra_governance_supra_vote(proposal_id, vote)) .await .map(TransactionSummary::from)?, ); @@ -745,14 +745,13 @@ impl SupraCommand for SubmitVote { let vote = self.args.yes; let proposal_id = self.args.proposal_id; - let payload = aptos_stdlib::supra_governance_supra_vote( - proposal_id, - vote, - ); + let payload = aptos_stdlib::supra_governance_supra_vote(proposal_id, vote); Ok(SupraCommandArguments { payload, sender_account: self.args.txn_options.sender_account, - profile_options: supra_aptos::ProfileOptions::from(self.args.txn_options.profile_options), + profile_options: supra_aptos::ProfileOptions::from( + self.args.txn_options.profile_options, + ), rest_options: supra_aptos::RestOptions::from(self.args.txn_options.rest_options), gas_options: supra_aptos::GasOptions::from(self.args.txn_options.gas_options), }) @@ -781,7 +780,9 @@ impl CliCommand for ApproveExecutionHash { Ok(self .txn_options .submit_transaction( - aptos_stdlib::supra_governance_add_supra_approved_script_hash_script(self.proposal_id), + aptos_stdlib::supra_governance_add_supra_approved_script_hash_script( + self.proposal_id, + ), ) .await .map(TransactionSummary::from)?) @@ -791,8 +792,9 @@ impl CliCommand for ApproveExecutionHash { #[async_trait] impl SupraCommand for ApproveExecutionHash { async fn supra_command_arguments(self) -> anyhow::Result { - let payload = aptos_stdlib::supra_governance_add_supra_approved_script_hash_script(self.proposal_id); - Ok(SupraCommandArguments{ + let payload = + aptos_stdlib::supra_governance_add_supra_approved_script_hash_script(self.proposal_id); + Ok(SupraCommandArguments { payload, sender_account: self.txn_options.sender_account, profile_options: supra_aptos::ProfileOptions::from(self.txn_options.profile_options), @@ -946,7 +948,7 @@ impl SupraCommand for ExecuteProposal { let args = vec![TransactionArgument::U64(self.proposal_id)]; let payload = TransactionPayload::Script(Script::new(bytecode, vec![], args)); - Ok(SupraCommandArguments{ + Ok(SupraCommandArguments { payload, sender_account: self.txn_options.sender_account, profile_options: supra_aptos::ProfileOptions::from(self.txn_options.profile_options), @@ -1092,7 +1094,7 @@ impl CliCommand<()> for GenerateUpgradeProposal { testnet, next_execution_hash, proposal_type, - function_name + function_name, } = self; let package_path = move_options.get_package_path()?; let options = included_artifacts.build_options( @@ -1120,8 +1122,10 @@ impl CliCommand<()> for GenerateUpgradeProposal { // If we're generating a multi-step proposal } else { let next_execution_hash = if !next_execution_hash.is_empty() { - Some(HashValue::from_str(&next_execution_hash) - .map_err(|e| CliError::HashError(e, next_execution_hash))?) + Some( + HashValue::from_str(&next_execution_hash) + .map_err(|e| CliError::HashError(e, next_execution_hash))?, + ) } else { None }; @@ -1130,7 +1134,7 @@ impl CliCommand<()> for GenerateUpgradeProposal { account, output, next_execution_hash, - function_name + function_name, )?; } Ok(()) diff --git a/crates/aptos/src/lib.rs b/crates/aptos/src/lib.rs index 1566b44bd00..a30c4bd4db3 100644 --- a/crates/aptos/src/lib.rs +++ b/crates/aptos/src/lib.rs @@ -13,10 +13,10 @@ pub mod move_tool; pub mod node; pub mod op; pub mod stake; +pub mod supra_specific; #[cfg(any(test, feature = "fuzzing"))] pub mod test; pub mod update; -pub mod supra_specific; use crate::common::{ types::{CliCommand, CliResult, CliTypedResult}, diff --git a/crates/aptos/src/move_tool/mod.rs b/crates/aptos/src/move_tool/mod.rs index 57e581d1641..d7527ddddcf 100644 --- a/crates/aptos/src/move_tool/mod.rs +++ b/crates/aptos/src/move_tool/mod.rs @@ -66,8 +66,8 @@ use std::{ str::FromStr, }; pub use stored_package::*; -use tokio::task; use supra_aptos::{SupraCommand, SupraCommandArguments}; +use tokio::task; use url::Url; mod aptos_debug_natives; @@ -181,7 +181,8 @@ impl FrameworkPackageArgs { prompt_options: PromptOptions, ) -> CliTypedResult<()> { const SUPRA_FRAMEWORK: &str = "SupraFramework"; - const SUPRA_FRAMEWORK_GIT_PATH: &str = "https://github.com/Entropy-Foundation/aptos-core.git"; + const SUPRA_FRAMEWORK_GIT_PATH: &str = + "https://github.com/Entropy-Foundation/aptos-core.git"; const SUBDIR_PATH: &str = "aptos-move/framework/supra-framework"; const DEFAULT_BRANCH: &str = "dev"; diff --git a/crates/aptos/src/move_tool/stored_package.rs b/crates/aptos/src/move_tool/stored_package.rs index 29751f5533a..cd4eedb1f61 100644 --- a/crates/aptos/src/move_tool/stored_package.rs +++ b/crates/aptos/src/move_tool/stored_package.rs @@ -40,10 +40,7 @@ impl fmt::Display for CachedPackageMetadata<'_> { impl CachedPackageRegistry { pub fn new(inner: PackageRegistry, bytecode: BTreeMap>) -> Self { - Self { - inner, - bytecode, - } + Self { inner, bytecode } } /// Creates a new registry. diff --git a/crates/aptos/src/node/mod.rs b/crates/aptos/src/node/mod.rs index ab0404eaabb..1aaa6916a00 100644 --- a/crates/aptos/src/node/mod.rs +++ b/crates/aptos/src/node/mod.rs @@ -902,7 +902,7 @@ impl TryFrom<&ValidatorInfo> for ValidatorInfoSummary { fn try_from(info: &ValidatorInfo) -> Result { let config = info.config(); let config = ValidatorConfig { - consensus_public_key: config.consensus_public_key.to_bytes().to_vec(), + consensus_public_key: config.consensus_public_key().to_bytes().to_vec(), validator_network_addresses: config.validator_network_addresses.clone(), fullnode_network_addresses: config.fullnode_network_addresses.clone(), validator_index: config.validator_index, diff --git a/crates/aptos/src/supra_specific.rs b/crates/aptos/src/supra_specific.rs index 023bca4ff9d..327209fdf9b 100644 --- a/crates/aptos/src/supra_specific.rs +++ b/crates/aptos/src/supra_specific.rs @@ -1,10 +1,15 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright © Entropy Foundation use crate::common::types::{GasOptions, ProfileOptions, RestOptions}; impl From for supra_aptos::ProfileOptions { fn from(value: ProfileOptions) -> Self { - Self { profile: value.profile } + Self { + profile: value.profile, + } } } diff --git a/crates/fallible/Cargo.toml b/crates/fallible/Cargo.toml index 6563764a437..7d5b2a7525e 100644 --- a/crates/fallible/Cargo.toml +++ b/crates/fallible/Cargo.toml @@ -14,5 +14,3 @@ rust-version = { workspace = true } [dependencies] thiserror = { workspace = true } - - diff --git a/crates/indexer/Cargo.toml b/crates/indexer/Cargo.toml index 77799b37096..ee12ca227e6 100644 --- a/crates/indexer/Cargo.toml +++ b/crates/indexer/Cargo.toml @@ -29,11 +29,11 @@ bcs = { workspace = true } bigdecimal = { workspace = true } chrono = { workspace = true } diesel = { workspace = true, features = [ - "chrono", - "postgres", - "r2d2", - "numeric", - "serde_json", + "chrono", + "postgres", + "r2d2", + "numeric", + "serde_json", ] } diesel_migrations = { workspace = true } field_count = { workspace = true } diff --git a/crates/indexer/src/indexer/fetcher.rs b/crates/indexer/src/indexer/fetcher.rs index 26418d1e207..4f34674cfc9 100644 --- a/crates/indexer/src/indexer/fetcher.rs +++ b/crates/indexer/src/indexer/fetcher.rs @@ -296,6 +296,9 @@ async fn fetch_nexts( info.block_height = Some(block_height_bcs); info.epoch = Some(epoch_bcs); }, + Transaction::AutomatedTransaction(_) => { + unimplemented!() + }, }; txn }); diff --git a/crates/indexer/src/models/coin_models/account_transactions.rs b/crates/indexer/src/models/coin_models/account_transactions.rs index cea220f9263..a400881bc39 100644 --- a/crates/indexer/src/models/coin_models/account_transactions.rs +++ b/crates/indexer/src/models/coin_models/account_transactions.rs @@ -12,7 +12,7 @@ use crate::{ schema::account_transactions, util::standardize_address, }; -use aptos_api_types::{DeleteResource, Event, Transaction, WriteResource, WriteSetChange}; +use aptos_api_types::{DeleteResource, EventV1, Transaction, WriteResource, WriteSetChange}; use field_count::FieldCount; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -87,7 +87,7 @@ impl AccountTransaction { /// Base case, record event account address. We don't really have to worry about /// objects here because it'll be taken care of in the resource section - fn from_event(event: &Event, txn_version: i64) -> HashMap { + fn from_event(event: &EventV1, txn_version: i64) -> HashMap { let account_address = standardize_address(&event.guid.account_address.to_string()); HashMap::from([((account_address.clone(), txn_version), Self { transaction_version: txn_version, diff --git a/crates/indexer/src/models/coin_models/coin_activities.rs b/crates/indexer/src/models/coin_models/coin_activities.rs index de4df068a2a..c8227db1bd2 100644 --- a/crates/indexer/src/models/coin_models/coin_activities.rs +++ b/crates/indexer/src/models/coin_models/coin_activities.rs @@ -16,7 +16,7 @@ use crate::{ util::{parse_timestamp, standardize_address, truncate_str}, }; use aptos_api_types::{ - Event as APIEvent, Transaction as APITransaction, TransactionInfo as APITransactionInfo, + EventV1 as APIEvent, Transaction as APITransaction, TransactionInfo as APITransactionInfo, TransactionPayload, UserTransactionRequest, WriteSetChange as APIWriteSetChange, }; use aptos_types::SUPRA_COIN_TYPE; diff --git a/crates/indexer/src/models/events.rs b/crates/indexer/src/models/events.rs index 6c58e5ba78d..f7fce13875f 100644 --- a/crates/indexer/src/models/events.rs +++ b/crates/indexer/src/models/events.rs @@ -3,7 +3,7 @@ #![allow(clippy::extra_unused_lifetimes)] use super::transactions::TransactionQuery; use crate::{models::transactions::Transaction, schema::events, util::standardize_address}; -use aptos_api_types::Event as APIEvent; +use aptos_api_types::EventV1 as APIEvent; use field_count::FieldCount; use serde::{Deserialize, Serialize}; diff --git a/crates/indexer/src/models/token_models/token_activities.rs b/crates/indexer/src/models/token_models/token_activities.rs index 21da21e3861..297aac61721 100644 --- a/crates/indexer/src/models/token_models/token_activities.rs +++ b/crates/indexer/src/models/token_models/token_activities.rs @@ -10,7 +10,7 @@ use crate::{ schema::token_activities, util::{parse_timestamp, standardize_address}, }; -use aptos_api_types::{Event as APIEvent, Transaction as APITransaction}; +use aptos_api_types::{EventV1 as APIEvent, Transaction as APITransaction}; use bigdecimal::{BigDecimal, Zero}; use field_count::FieldCount; use serde::{Deserialize, Serialize}; diff --git a/crates/indexer/src/models/token_models/v2_token_activities.rs b/crates/indexer/src/models/token_models/v2_token_activities.rs index 7554f0651e1..a4af8c8a8b5 100644 --- a/crates/indexer/src/models/token_models/v2_token_activities.rs +++ b/crates/indexer/src/models/token_models/v2_token_activities.rs @@ -14,7 +14,7 @@ use crate::{ database::PgPoolConnection, models::coin_models::v2_fungible_asset_utils::FungibleAssetEvent, schema::token_activities_v2, util::standardize_address, }; -use aptos_api_types::Event as APIEvent; +use aptos_api_types::EventV1 as APIEvent; use bigdecimal::{BigDecimal, One, Zero}; use field_count::FieldCount; use serde::{Deserialize, Serialize}; diff --git a/crates/indexer/src/models/token_models/v2_token_utils.rs b/crates/indexer/src/models/token_models/v2_token_utils.rs index aa525d20a5b..bf890765162 100644 --- a/crates/indexer/src/models/token_models/v2_token_utils.rs +++ b/crates/indexer/src/models/token_models/v2_token_utils.rs @@ -18,7 +18,7 @@ use crate::{ }, }; use anyhow::{Context, Result}; -use aptos_api_types::{deserialize_from_string, Event, WriteResource}; +use aptos_api_types::{deserialize_from_string, EventV1, WriteResource}; use bigdecimal::BigDecimal; use serde::{Deserialize, Serialize}; use std::{ @@ -352,7 +352,7 @@ pub struct BurnEvent { } impl BurnEvent { - pub fn from_event(event: &Event, txn_version: i64) -> anyhow::Result> { + pub fn from_event(event: &EventV1, txn_version: i64) -> anyhow::Result> { let event_type = event.typ.to_string(); if let Some(V2TokenEvent::BurnEvent(inner)) = V2TokenEvent::from_event(event_type.as_str(), &event.data, txn_version).unwrap() @@ -376,7 +376,7 @@ pub struct TransferEvent { } impl TransferEvent { - pub fn from_event(event: &Event, txn_version: i64) -> anyhow::Result> { + pub fn from_event(event: &EventV1, txn_version: i64) -> anyhow::Result> { let event_type = event.typ.to_string(); if let Some(V2TokenEvent::TransferEvent(inner)) = V2TokenEvent::from_event(event_type.as_str(), &event.data, txn_version).unwrap() diff --git a/crates/indexer/src/models/transactions.rs b/crates/indexer/src/models/transactions.rs index a4db22b704a..a8476104367 100644 --- a/crates/indexer/src/models/transactions.rs +++ b/crates/indexer/src/models/transactions.rs @@ -247,6 +247,7 @@ impl Transaction { vec![], vec![], ), + APITransaction::AutomatedTransaction(_) => (unimplemented!()), } } diff --git a/crates/proxy/Cargo.toml b/crates/proxy/Cargo.toml index bd1266c3491..330c5adf0b6 100644 --- a/crates/proxy/Cargo.toml +++ b/crates/proxy/Cargo.toml @@ -14,5 +14,3 @@ rust-version = { workspace = true } [dependencies] ipnet = { workspace = true } - - diff --git a/crates/supra/src/lib.rs b/crates/supra/src/lib.rs index a735476b1bc..28d297b74e1 100644 --- a/crates/supra/src/lib.rs +++ b/crates/supra/src/lib.rs @@ -1,8 +1,10 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright © Entropy Foundation use anyhow::Result; -use aptos_types::account_address::AccountAddress; -use aptos_types::transaction::TransactionPayload; +use aptos_types::{account_address::AccountAddress, transaction::TransactionPayload}; use async_trait::async_trait; use clap::ValueEnum; use std::fmt::{Display, Formatter}; diff --git a/crates/validator-transaction-pool/src/tests.rs b/crates/validator-transaction-pool/src/tests.rs index 62a7bbca11b..b837794ebc9 100644 --- a/crates/validator-transaction-pool/src/tests.rs +++ b/crates/validator-transaction-pool/src/tests.rs @@ -5,7 +5,7 @@ use crate::{TransactionFilter, VTxnPoolState}; use aptos_channels::{aptos_channel, message_queues::QueueStyle}; use aptos_crypto::hash::CryptoHash; use aptos_types::{ - dkg::DKGTranscript, + dkg::DKGTransactionData, jwks::{dummy_issuer, QuorumCertifiedUpdate}, validator_txn::{Topic, ValidatorTransaction}, }; @@ -21,9 +21,9 @@ use tokio::time::timeout; #[test] fn txn_pull_order_should_be_fifo_except_in_topic_overwriting() { let pool = VTxnPoolState::default(); - let txn_0 = ValidatorTransaction::DKGResult(DKGTranscript::dummy()); + let txn_0 = ValidatorTransaction::DKG(DKGTransactionData::dummy()); let txn_1 = ValidatorTransaction::ObservedJWKUpdate(QuorumCertifiedUpdate::dummy()); - let txn_2 = ValidatorTransaction::DKGResult(DKGTranscript::dummy()); + let txn_2 = ValidatorTransaction::DKG(DKGTransactionData::dummy()); let _guard_0 = pool.put( Topic::JWK_CONSENSUS(dummy_issuer()), Arc::new(txn_0.clone()), @@ -48,7 +48,7 @@ fn txn_pull_order_should_be_fifo_except_in_topic_overwriting() { fn delete_by_seq_num() { let pool = VTxnPoolState::default(); let txn_0 = ValidatorTransaction::ObservedJWKUpdate(QuorumCertifiedUpdate::dummy()); - let txn_1 = ValidatorTransaction::DKGResult(DKGTranscript::dummy()); + let txn_1 = ValidatorTransaction::DKG(DKGTransactionData::dummy()); let guard_0 = pool.put( Topic::JWK_CONSENSUS(dummy_issuer()), Arc::new(txn_0.clone()), @@ -69,7 +69,7 @@ fn delete_by_seq_num() { fn txn_should_be_dropped_if_guard_is_dropped() { let pool = VTxnPoolState::default(); let txn_0 = ValidatorTransaction::ObservedJWKUpdate(QuorumCertifiedUpdate::dummy()); - let txn_1 = ValidatorTransaction::DKGResult(DKGTranscript::dummy()); + let txn_1 = ValidatorTransaction::DKG(DKGTransactionData::dummy()); let guard_0 = pool.put( Topic::JWK_CONSENSUS(dummy_issuer()), Arc::new(txn_0.clone()), @@ -91,7 +91,7 @@ fn txn_should_be_dropped_if_guard_is_dropped() { async fn per_txn_pull_notification() { let pool = VTxnPoolState::default(); let txn_0 = ValidatorTransaction::ObservedJWKUpdate(QuorumCertifiedUpdate::dummy()); - let txn_1 = ValidatorTransaction::DKGResult(DKGTranscript::dummy()); + let txn_1 = ValidatorTransaction::DKG(DKGTransactionData::dummy()); let (tx, mut rx) = aptos_channel::new(QueueStyle::KLAST, 1, None); let _guard_0 = pool.put( Topic::JWK_CONSENSUS(dummy_issuer()), @@ -116,7 +116,7 @@ async fn per_txn_pull_notification() { fn pull_item_limit_should_be_respected() { let pool = VTxnPoolState::default(); let txn_0 = ValidatorTransaction::ObservedJWKUpdate(QuorumCertifiedUpdate::dummy()); - let txn_1 = ValidatorTransaction::DKGResult(DKGTranscript::dummy()); + let txn_1 = ValidatorTransaction::DKG(DKGTransactionData::dummy()); let guard_0 = pool.put( Topic::JWK_CONSENSUS(dummy_issuer()), Arc::new(txn_0.clone()), diff --git a/dkg/src/agg_trx_producer.rs b/dkg/src/agg_trx_producer.rs index bbe537cea5b..4d760e5a85f 100644 --- a/dkg/src/agg_trx_producer.rs +++ b/dkg/src/agg_trx_producer.rs @@ -7,7 +7,7 @@ use crate::{ use aptos_channels::aptos_channel::Sender; use aptos_logger::info; use aptos_reliable_broadcast::ReliableBroadcast; -use aptos_types::{dkg::DKGTrait, epoch_state::EpochState}; +use aptos_types::{aptos_dkg::DKGTrait, epoch_state::EpochState}; use futures::future::AbortHandle; use futures_util::future::Abortable; use move_core_types::account_address::AccountAddress; diff --git a/dkg/src/counters.rs b/dkg/src/counters.rs index a62e5bd67d8..7e1d904fae3 100644 --- a/dkg/src/counters.rs +++ b/dkg/src/counters.rs @@ -7,7 +7,7 @@ use once_cell::sync::Lazy; /// Count of the pending messages sent to itself in the channel pub static PENDING_SELF_MESSAGES: Lazy = Lazy::new(|| { register_int_gauge!( - "aptos_dkg_pending_self_messages", + "dkg_pending_self_messages", "Count of the pending messages sent to itself in the channel" ) .unwrap() @@ -15,7 +15,7 @@ pub static PENDING_SELF_MESSAGES: Lazy = Lazy::new(|| { pub static DKG_STAGE_SECONDS: Lazy = Lazy::new(|| { register_histogram_vec!( - "aptos_dkg_session_stage_seconds", + "dkg_session_stage_seconds", "How long it takes to reach different DKG stages", &["dealer", "stage"] ) @@ -24,7 +24,7 @@ pub static DKG_STAGE_SECONDS: Lazy = Lazy::new(|| { pub static ROUNDING_SECONDS: Lazy = Lazy::new(|| { register_histogram_vec!( - "aptos_dkg_rounding_seconds", + "dkg_rounding_seconds", "Rounding seconds and counts by method", &["method"] ) diff --git a/dkg/src/dkg_manager/mod.rs b/dkg/src/dkg_manager/mod.rs index 5427e41a196..87970058d4b 100644 --- a/dkg/src/dkg_manager/mod.rs +++ b/dkg/src/dkg_manager/mod.rs @@ -13,7 +13,7 @@ use aptos_crypto::Uniform; use aptos_infallible::duration_since_epoch; use aptos_logger::{debug, error, info, warn}; use aptos_types::{ - dkg::{ + aptos_dkg::{ DKGSessionMetadata, DKGSessionState, DKGStartEvent, DKGTrait, DKGTranscript, DKGTranscriptMetadata, MayHaveRoundingSummary, }, diff --git a/dkg/src/dkg_manager/tests.rs b/dkg/src/dkg_manager/tests.rs index c102836e2f5..258436a54d7 100644 --- a/dkg/src/dkg_manager/tests.rs +++ b/dkg/src/dkg_manager/tests.rs @@ -14,7 +14,7 @@ use aptos_crypto::{ }; use aptos_infallible::RwLock; use aptos_types::{ - dkg::{ + aptos_dkg::{ dummy_dkg::DummyDKG, DKGSessionMetadata, DKGStartEvent, DKGTrait, DKGTranscript, DKGTranscriptMetadata, }, diff --git a/dkg/src/epoch_manager.rs b/dkg/src/epoch_manager.rs index 464b9a98d47..25a4127264a 100644 --- a/dkg/src/epoch_manager.rs +++ b/dkg/src/epoch_manager.rs @@ -21,7 +21,7 @@ use aptos_network::{application::interface::NetworkClient, protocols::network::E use aptos_reliable_broadcast::ReliableBroadcast; use aptos_types::{ account_address::AccountAddress, - dkg::{DKGStartEvent, DKGState, DKGTrait, DefaultDKG}, + aptos_dkg::{DKGStartEvent, DKGState, DKGTrait, DefaultDKG}, epoch_state::EpochState, on_chain_config::{ OnChainConfigPayload, OnChainConfigProvider, OnChainConsensusConfig, diff --git a/dkg/src/lib.rs b/dkg/src/lib.rs index 819e69bf7a8..aa319df672e 100644 --- a/dkg/src/lib.rs +++ b/dkg/src/lib.rs @@ -18,7 +18,7 @@ use aptos_event_notifications::{ DbBackedOnChainConfig, EventNotificationListener, ReconfigNotificationListener, }; use aptos_network::application::interface::{NetworkClient, NetworkServiceEvents}; -use aptos_types::dkg::{DKGTrait, DefaultDKG}; +use aptos_types::aptos_dkg::{DKGTrait, DefaultDKG}; use aptos_validator_transaction_pool::VTxnPoolState; use move_core_types::account_address::AccountAddress; use tokio::runtime::Runtime; diff --git a/dkg/src/transcript_aggregation/mod.rs b/dkg/src/transcript_aggregation/mod.rs index ec43bde5ad9..cf261cd12ae 100644 --- a/dkg/src/transcript_aggregation/mod.rs +++ b/dkg/src/transcript_aggregation/mod.rs @@ -8,7 +8,7 @@ use aptos_infallible::{duration_since_epoch, Mutex}; use aptos_logger::info; use aptos_reliable_broadcast::BroadcastStatus; use aptos_types::{ - dkg::{DKGTrait, DKGTranscript}, + aptos_dkg::{DKGTrait, DKGTranscript}, epoch_state::EpochState, validator_verifier::VerifyError, }; diff --git a/dkg/src/transcript_aggregation/tests.rs b/dkg/src/transcript_aggregation/tests.rs index 6b3c3d8b42f..d722f92504f 100644 --- a/dkg/src/transcript_aggregation/tests.rs +++ b/dkg/src/transcript_aggregation/tests.rs @@ -6,7 +6,7 @@ use aptos_crypto::{ed25519, Uniform}; use aptos_infallible::duration_since_epoch; use aptos_reliable_broadcast::BroadcastStatus; use aptos_types::{ - dkg::{ + aptos_dkg::{ dummy_dkg::{DummyDKG, DummyDKGTranscript}, DKGSessionMetadata, DKGTrait, DKGTranscript, DKGTranscriptMetadata, }, diff --git a/dkg/src/types.rs b/dkg/src/types.rs index 928b6590272..22a9c8820c7 100644 --- a/dkg/src/types.rs +++ b/dkg/src/types.rs @@ -4,7 +4,7 @@ use aptos_crypto_derive::CryptoHasher; use aptos_enum_conversion_derive::EnumConversion; use aptos_reliable_broadcast::RBMessage; -pub use aptos_types::dkg::DKGTranscript; +pub use aptos_types::aptos_dkg::DKGTranscript; use serde::{Deserialize, Serialize}; /// Once DKG starts, a validator should send this message to peers in order to collect DKG transcripts from peers. diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs index 07fc100121b..d030bc343ac 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs @@ -2,27 +2,30 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use aptos_api_types::transaction::{AutomationRegistrationParams, AutomationTaskType}; use aptos_api_types::{ - transaction::ValidatorTransaction as ApiValidatorTransactionEnum, AccountSignature, - DeleteModule, DeleteResource, Ed25519Signature, EntryFunctionId, EntryFunctionPayload, Event, - GenesisPayload, MoveAbility, MoveFunction, MoveFunctionGenericTypeParam, - MoveFunctionVisibility, MoveModule, MoveModuleBytecode, MoveModuleId, MoveScriptBytecode, - MoveStruct, MoveStructField, MoveStructTag, MoveType, MultiEd25519Signature, MultiKeySignature, - MultisigPayload, MultisigTransactionPayload, PublicKey, ScriptPayload, Signature, - SingleKeySignature, Transaction, TransactionInfo, TransactionPayload, TransactionSignature, - WriteSet, WriteSetChange, + transaction::{ + AutomationRegistrationParams, AutomationTaskType, + ValidatorTransaction as ApiValidatorTransactionEnum, + }, + AccountSignature, DeleteModule, DeleteResource, Ed25519Signature, EntryFunctionId, + EntryFunctionPayload, EventV1, GenesisPayload, MoveAbility, MoveFunction, + MoveFunctionGenericTypeParam, MoveFunctionVisibility, MoveModule, MoveModuleBytecode, + MoveModuleId, MoveScriptBytecode, MoveStruct, MoveStructField, MoveStructTag, MoveType, + MultiEd25519Signature, MultiKeySignature, MultisigPayload, MultisigTransactionPayload, + PublicKey, ScriptPayload, Signature, SingleKeySignature, Transaction, TransactionInfo, + TransactionPayload, TransactionSignature, WriteSet, WriteSetChange, }; use aptos_bitvec::BitVec; use aptos_logger::warn; use aptos_protos::{ transaction::v1::{ - self as transaction, any_signature, validator_transaction, + self as transaction, any_signature, automation_payload_extensions, validator_transaction, validator_transaction::observed_jwk_update::exported_provider_jw_ks::{ jwk::{JwkType, Rsa, UnsupportedJwk}, Jwk as ProtoJwk, }, - Ed25519, Keyless, Secp256k1Ecdsa, TransactionSizeInfo, WebAuthn, + AutomationPayloadExtensions, Ed25519, Keyless, Secp256k1Ecdsa, TransactionSizeInfo, + WebAuthn, }, util::timestamp, }; @@ -30,8 +33,6 @@ use aptos_types::jwks::jwk::JWK; use hex; use move_binary_format::file_format::Ability; use std::time::Duration; -use aptos_protos::transaction::v1::automation_payload_extensions; -use aptos_protos::transaction::v1::AutomationPayloadExtensions; pub fn convert_move_module_id(move_module_id: &MoveModuleId) -> transaction::MoveModuleId { transaction::MoveModuleId { @@ -197,7 +198,7 @@ pub fn convert_transaction_payload( } #[inline] -pub fn convert_events(events: &[Event]) -> Vec { +pub fn convert_events(events: &[EventV1]) -> Vec { events.iter().map(convert_event).collect() } @@ -506,7 +507,7 @@ pub fn convert_multisig_payload( ), ), } - } + }, }); transaction::MultisigPayload { multisig_address: multisig_payload.multisig_address.to_string(), @@ -514,11 +515,12 @@ pub fn convert_multisig_payload( } } -pub fn convert_automation_task_type(automation_task_type: &AutomationTaskType) -> transaction::AutomationTaskType { +pub fn convert_automation_task_type( + automation_task_type: &AutomationTaskType, +) -> transaction::AutomationTaskType { match automation_task_type { AutomationTaskType::User => transaction::AutomationTaskType::User, - AutomationTaskType::System => transaction::AutomationTaskType::System - + AutomationTaskType::System => transaction::AutomationTaskType::System, } } @@ -528,7 +530,9 @@ pub fn convert_automation_payload( match auto_payload { AutomationRegistrationParams::V1(params_v1) => { let v1 = transaction::AutomationPayload { - automated_function: Some(convert_entry_function_payload(¶ms_v1.automated_function)), + automated_function: Some(convert_entry_function_payload( + ¶ms_v1.automated_function, + )), expiration_timestamp_secs: params_v1.expiration_timestamp_secs, max_gas_amount: params_v1.max_gas_amount, gas_price_cap: params_v1.gas_price_cap, @@ -536,12 +540,14 @@ pub fn convert_automation_payload( aux_data: params_v1.aux_data.clone(), }; AutomationPayloadExtensions { - variant: Some(automation_payload_extensions::Variant::V1(v1)) + variant: Some(automation_payload_extensions::Variant::V1(v1)), } - } + }, AutomationRegistrationParams::V2(params_v2) => { let v2 = transaction::AutomationPayloadV2 { - automated_function: Some(convert_entry_function_payload(¶ms_v2.automated_function)), + automated_function: Some(convert_entry_function_payload( + ¶ms_v2.automated_function, + )), expiration_timestamp_secs: params_v2.expiration_timestamp_secs, max_gas_amount: params_v2.max_gas_amount, gas_price_cap: params_v2.gas_price_cap, @@ -551,14 +557,13 @@ pub fn convert_automation_payload( priority: params_v2.task_priority.clone(), }; AutomationPayloadExtensions { - variant: Some(automation_payload_extensions::Variant::V2(v2)) + variant: Some(automation_payload_extensions::Variant::V2(v2)), } - - } + }, } } -pub fn convert_event(event: &Event) -> transaction::Event { +pub fn convert_event(event: &EventV1) -> transaction::Event { let event_key: aptos_types::event::EventKey = event.guid.into(); transaction::Event { key: Some(transaction::EventKey { @@ -957,19 +962,35 @@ fn convert_validator_transaction( ) -> transaction::transaction::TxnData { transaction::transaction::TxnData::Validator(transaction::ValidatorTransaction { validator_transaction_type: match api_validator_txn { - ApiValidatorTransactionEnum::DkgResult(dgk_result) => { + ApiValidatorTransactionEnum::Dkg(dkg_transaction) => { + Some( + validator_transaction::ValidatorTransactionType::Dkg( + validator_transaction::DkgTransactionData { + dkg_data: Some(validator_transaction::dkg_data::DkgTransactionData{ + epoch: dkg_transaction.dkg_transaction_data.epoch.0, + author: dkg_transaction.dkg_transaction_data.author.to_string(), + bls_aggregate_signature: dkg_transaction.dkg_transaction_data.bls_aggregate_signature.clone(), + signer_indices_clan_committee: dkg_transaction.dkg_transaction_data.signer_indices_clan_committee.clone(), + transaction_type: dkg_transaction.dkg_transaction_data.transaction_type as u32, + payload: dkg_transaction.dkg_transaction_data.payload.0.clone(), + }), + }, + ) + ) + } + ApiValidatorTransactionEnum::DkgResult(dkg_result) => { Some( validator_transaction::ValidatorTransactionType::DkgUpdate( validator_transaction::DkgUpdate { dkg_transcript: Some(validator_transaction::dkg_update::DkgTranscript { - author: dgk_result.dkg_transcript.author.to_string(), - epoch: dgk_result.dkg_transcript.epoch.0, - payload: dgk_result.dkg_transcript.payload.0.clone(), + author: dkg_result.dkg_transcript.author.to_string(), + epoch: dkg_result.dkg_transcript.epoch.0, + payload: dkg_result.dkg_transcript.payload.0.clone(), }), }, ) ) - }, + } ApiValidatorTransactionEnum::ObservedJwkUpdate(observed_jwk_update) => { Some( validator_transaction::ValidatorTransactionType::ObservedJwkUpdate( diff --git a/ecosystem/indexer-grpc/indexer-grpc-table-info/Cargo.toml b/ecosystem/indexer-grpc/indexer-grpc-table-info/Cargo.toml index 1f3dc6676cb..40b199b98d6 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-table-info/Cargo.toml +++ b/ecosystem/indexer-grpc/indexer-grpc-table-info/Cargo.toml @@ -16,7 +16,7 @@ anyhow = { workspace = true } aptos-api = { workspace = true } aptos-api-types = { workspace = true } aptos-config = { workspace = true } -aptos-db-indexer = { workspace = true } +aptos-db-indexer = { workspace = true } aptos-indexer-grpc-fullnode = { workspace = true } aptos-indexer-grpc-utils = { workspace = true } aptos-logger = { workspace = true } diff --git a/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs b/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs index 7aad300d573..fafe98113db 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs @@ -131,7 +131,7 @@ impl CacheOperator { pub async fn set_chain_id(&mut self, chain_id: u64) -> anyhow::Result<()> { self.conn - .set(CACHE_KEY_CHAIN_ID, chain_id) + .set::<_, _, ()>(CACHE_KEY_CHAIN_ID, chain_id) .await .context("Redis chain id update failed.")?; Ok(()) @@ -182,7 +182,7 @@ impl CacheOperator { latest_version: u64, ) -> anyhow::Result<()> { self.conn - .set(FILE_STORE_LATEST_VERSION, latest_version) + .set::<_, _, ()>(FILE_STORE_LATEST_VERSION, latest_version) .await?; Ok(()) } diff --git a/ecosystem/indexer-grpc/transaction-filter/src/boolean_transaction_filter.rs b/ecosystem/indexer-grpc/transaction-filter/src/boolean_transaction_filter.rs index 5eb6727faf0..f4935e0bf90 100644 --- a/ecosystem/indexer-grpc/transaction-filter/src/boolean_transaction_filter.rs +++ b/ecosystem/indexer-grpc/transaction-filter/src/boolean_transaction_filter.rs @@ -273,6 +273,7 @@ impl Filterable for APIFilter { TxnData::User(u) => &u.events, TxnData::Validator(_) => return false, TxnData::BlockEpilogue(_) => return false, + TxnData::Automated(automated_transaction) => &automated_transaction.events, }; events_filter.is_allowed_vec(events) } else { diff --git a/ecosystem/nft-metadata-crawler-parser/Cargo.toml b/ecosystem/nft-metadata-crawler-parser/Cargo.toml index e04313d4c92..5fcc733ba18 100644 --- a/ecosystem/nft-metadata-crawler-parser/Cargo.toml +++ b/ecosystem/nft-metadata-crawler-parser/Cargo.toml @@ -22,11 +22,11 @@ bytes = { workspace = true } chrono = { workspace = true } clap = { workspace = true } diesel = { workspace = true, features = [ - "chrono", - "postgres", - "r2d2", - "numeric", - "serde_json", + "chrono", + "postgres", + "r2d2", + "numeric", + "serde_json", ] } diesel_migrations = { workspace = true } field_count = { workspace = true } diff --git a/execution/block-partitioner/Cargo.toml b/execution/block-partitioner/Cargo.toml index e4ba06cbfcd..ff7ffcb389f 100644 --- a/execution/block-partitioner/Cargo.toml +++ b/execution/block-partitioner/Cargo.toml @@ -40,4 +40,3 @@ default = [] [[bench]] name = "v2" harness = false - diff --git a/execution/executor-benchmark/Cargo.toml b/execution/executor-benchmark/Cargo.toml index 61371bde602..d78a2be0613 100644 --- a/execution/executor-benchmark/Cargo.toml +++ b/execution/executor-benchmark/Cargo.toml @@ -29,7 +29,7 @@ aptos-jellyfish-merkle = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-node-resource-metrics = { workspace = true } -aptos-push-metrics = { workspace = true } +aptos-push-metrics = { workspace = true } aptos-sdk = { workspace = true } aptos-storage-interface = { workspace = true } aptos-transaction-generator-lib = { workspace = true } @@ -61,4 +61,8 @@ aptos-temppath = { workspace = true } [features] default = [] -fuzzing = ["aptos-config/fuzzing", "aptos-crypto/fuzzing", "aptos-types/fuzzing"] +fuzzing = [ + "aptos-config/fuzzing", + "aptos-crypto/fuzzing", + "aptos-types/fuzzing", +] diff --git a/execution/executor-service/Cargo.toml b/execution/executor-service/Cargo.toml index f5421858af1..e07d41c32d8 100644 --- a/execution/executor-service/Cargo.toml +++ b/execution/executor-service/Cargo.toml @@ -19,7 +19,7 @@ aptos-infallible = { workspace = true } aptos-logger = { workspace = true } aptos-metrics-core = { workspace = true } aptos-node-resource-metrics = { workspace = true } -aptos-push-metrics = { workspace = true } +aptos-push-metrics = { workspace = true } aptos-secure-net = { workspace = true } aptos-storage-interface = { workspace = true } aptos-types = { workspace = true } diff --git a/execution/executor-types/src/lib.rs b/execution/executor-types/src/lib.rs index 5f87e40dc14..9339e56aeff 100644 --- a/execution/executor-types/src/lib.rs +++ b/execution/executor-types/src/lib.rs @@ -12,9 +12,9 @@ use aptos_crypto::{ use aptos_scratchpad::{ProofRead, SparseMerkleTree}; use aptos_types::{ account_config::NEW_EPOCH_EVENT_MOVE_TYPE_TAG, + aptos_dkg::DKG_START_EVENT_MOVE_TYPE_TAG, block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, contract_event::ContractEvent, - dkg::DKG_START_EVENT_MOVE_TYPE_TAG, epoch_state::EpochState, jwks::OBSERVED_JWK_UPDATED_MOVE_TYPE_TAG, ledger_info::LedgerInfoWithSignatures, diff --git a/execution/executor/Cargo.toml b/execution/executor/Cargo.toml index da2d69e3cc5..7738d478657 100644 --- a/execution/executor/Cargo.toml +++ b/execution/executor/Cargo.toml @@ -56,6 +56,11 @@ rand = { workspace = true } [features] default = [] -fuzzing = ["aptos-consensus-types/fuzzing", "aptos-crypto/fuzzing", "aptos-types/fuzzing", "aptos-storage-interface/fuzzing"] +fuzzing = [ + "aptos-consensus-types/fuzzing", + "aptos-crypto/fuzzing", + "aptos-types/fuzzing", + "aptos-storage-interface/fuzzing", +] failpoints = ["fail/failpoints", "aptos-vm/failpoints"] consensus-only-perf-test = [] diff --git a/execution/executor/src/components/chunk_output.rs b/execution/executor/src/components/chunk_output.rs index b00e8ea7ad8..01b03d74f40 100644 --- a/execution/executor/src/components/chunk_output.rs +++ b/execution/executor/src/components/chunk_output.rs @@ -336,7 +336,9 @@ pub fn update_counters_for_processed_chunk( Some(Transaction::BlockEpilogue(_)) => "block_epilogue", Some(Transaction::ValidatorTransaction(_)) => "validator_transaction", Some(Transaction::AutomatedTransaction(_)) => "automated_transaction", - Some(Transaction::AutomationRegistryTransaction(_)) => "automation_registry_transaction", + Some(Transaction::AutomationRegistryTransaction(_)) => { + "automation_registry_transaction" + }, Some(Transaction::SystemAutomatedTransaction(_)) => "system_automated_transaction", None => "unknown", }; @@ -410,11 +412,13 @@ pub fn update_counters_for_processed_chunk( .with_label_values(&[process_type, "script", state]) .inc(); }, - aptos_types::transaction::TransactionPayload::AutomationRegistration(_auto_payload) => { + aptos_types::transaction::TransactionPayload::AutomationRegistration( + _auto_payload, + ) => { metrics::APTOS_PROCESSED_USER_TRANSACTIONS_PAYLOAD_TYPE .with_label_values(&[process_type, "automation", state]) .inc(); - } + }, aptos_types::transaction::TransactionPayload::EntryFunction(function) => { metrics::APTOS_PROCESSED_USER_TRANSACTIONS_PAYLOAD_TYPE .with_label_values(&[process_type, "function", state]) diff --git a/keyless/circuit/Cargo.toml b/keyless/circuit/Cargo.toml index 662d69d6fee..c025d96e51e 100644 --- a/keyless/circuit/Cargo.toml +++ b/keyless/circuit/Cargo.toml @@ -30,7 +30,12 @@ tempfile = { workspace = true } [dev-dependencies] hex = { workspace = true } num-bigint = { workspace = true } -num-modular = { version = "0.6.1", features = ["num-bigint", "num-integer", "num-traits", "std"] } +num-modular = { version = "0.6.1", features = [ + "num-bigint", + "num-integer", + "num-traits", + "std", +] } rand_chacha = "0.3.1" rsa = { version = "0.9.6", features = ["sha2"] } tokio = { workspace = true } diff --git a/mempool/Cargo.toml b/mempool/Cargo.toml index dede31a8319..3da6a345126 100644 --- a/mempool/Cargo.toml +++ b/mempool/Cargo.toml @@ -61,5 +61,10 @@ proptest = { workspace = true } [features] default = [] failpoints = ["fail/failpoints", "aptos-vm-validator/failpoints"] -fuzzing = ["proptest", "aptos-types/fuzzing", "aptos-storage-interface/fuzzing", "aptos-config/fuzzing"] +fuzzing = [ + "proptest", + "aptos-types/fuzzing", + "aptos-storage-interface/fuzzing", + "aptos-config/fuzzing", +] consensus-only-perf-test = [] diff --git a/network/framework/Cargo.toml b/network/framework/Cargo.toml index fc9ede7291c..b4ba67bdd4a 100644 --- a/network/framework/Cargo.toml +++ b/network/framework/Cargo.toml @@ -73,8 +73,25 @@ rand_core = { workspace = true } [features] default = [] -fuzzing = ["aptos-bitvec/fuzzing", "aptos-config/fuzzing", "aptos-crypto/fuzzing", "aptos-types/fuzzing", "aptos-proptest-helpers", "aptos-time-service/testing", "aptos-types/fuzzing", "aptos-memsocket/testing", "aptos-netcore/fuzzing", "proptest", "proptest-derive"] -testing = ["aptos-config/testing", "aptos-time-service/testing", "aptos-memsocket/testing", "aptos-netcore/testing"] +fuzzing = [ + "aptos-bitvec/fuzzing", + "aptos-config/fuzzing", + "aptos-crypto/fuzzing", + "aptos-types/fuzzing", + "aptos-proptest-helpers", + "aptos-time-service/testing", + "aptos-types/fuzzing", + "aptos-memsocket/testing", + "aptos-netcore/fuzzing", + "proptest", + "proptest-derive", +] +testing = [ + "aptos-config/testing", + "aptos-time-service/testing", + "aptos-memsocket/testing", + "aptos-netcore/testing", +] [package.metadata.cargo-machete] ignored = ["serde_bytes"] diff --git a/protos/python/pyproject.toml b/protos/python/pyproject.toml index 2faea9a7c7b..ead7782045d 100644 --- a/protos/python/pyproject.toml +++ b/protos/python/pyproject.toml @@ -8,7 +8,7 @@ readme = "README.md" repository = "https://github.com/aptos-labs/aptos-core" homepage = "https://github.com/aptos-labs/aptos-core/tree/main/protos/python" keywords = ["web3", "aptos", "blockchain", "indexer"] -packages = [{include = "aptos_protos"}] +packages = [{ include = "aptos_protos" }] [tool.poe.tasks] generate = "./generate.sh" diff --git a/protos/rust/src/pb/aptos.transaction.v1.rs b/protos/rust/src/pb/aptos.transaction.v1.rs index 0cbbd0e632e..0386c0702b9 100644 --- a/protos/rust/src/pb/aptos.transaction.v1.rs +++ b/protos/rust/src/pb/aptos.transaction.v1.rs @@ -102,7 +102,7 @@ pub mod transaction { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum TxnData { #[prost(message, tag="7")] BlockMetadata(super::BlockMetadataTransaction), @@ -162,7 +162,7 @@ pub struct ValidatorTransaction { /// Nested message and enum types in `ValidatorTransaction`. pub mod validator_transaction { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct ObservedJwkUpdate { #[prost(message, optional, tag="1")] pub quorum_certified_update: ::core::option::Option, @@ -170,7 +170,7 @@ pub mod validator_transaction { /// Nested message and enum types in `ObservedJwkUpdate`. pub mod observed_jwk_update { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct ExportedProviderJwKs { #[prost(string, tag="1")] pub issuer: ::prost::alloc::string::String, @@ -182,7 +182,7 @@ pub mod validator_transaction { /// Nested message and enum types in `ExportedProviderJWKs`. pub mod exported_provider_jw_ks { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct Jwk { #[prost(oneof="jwk::JwkType", tags="1, 2")] pub jwk_type: ::core::option::Option, @@ -190,7 +190,7 @@ pub mod validator_transaction { /// Nested message and enum types in `JWK`. pub mod jwk { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct Rsa { #[prost(string, tag="1")] pub kid: ::prost::alloc::string::String, @@ -204,7 +204,7 @@ pub mod validator_transaction { pub n: ::prost::alloc::string::String, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct UnsupportedJwk { #[prost(bytes="vec", tag="1")] pub id: ::prost::alloc::vec::Vec, @@ -212,7 +212,7 @@ pub mod validator_transaction { pub payload: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum JwkType { #[prost(message, tag="1")] UnsupportedJwk(UnsupportedJwk), @@ -222,7 +222,7 @@ pub mod validator_transaction { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct ExportedAggregateSignature { #[prost(uint64, repeated, tag="1")] pub signer_indices: ::prost::alloc::vec::Vec, @@ -231,7 +231,7 @@ pub mod validator_transaction { pub sig: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct QuorumCertifiedUpdate { #[prost(message, optional, tag="1")] pub update: ::core::option::Option, @@ -240,7 +240,7 @@ pub mod validator_transaction { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct DkgUpdate { #[prost(message, optional, tag="1")] pub dkg_transcript: ::core::option::Option, @@ -248,7 +248,7 @@ pub mod validator_transaction { /// Nested message and enum types in `DkgUpdate`. pub mod dkg_update { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct DkgTranscript { #[prost(uint64, tag="1")] pub epoch: u64, @@ -258,13 +258,43 @@ pub mod validator_transaction { pub payload: ::prost::alloc::vec::Vec, } } + #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DkgTransactionData { + #[prost(message, optional, tag="1")] + pub dkg_data: ::core::option::Option, + } + + /// Nested message and enum types in `DkgTransactionData`. + pub mod dkg_data { + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DkgTransactionData { + #[prost(uint64, tag="1")] + pub epoch: u64, + #[prost(string, tag="2")] + pub author: ::prost::alloc::string::String, + #[prost(bytes="vec", tag="3")] + pub bls_aggregate_signature: ::prost::alloc::vec::Vec, + #[prost(uint32, repeated, tag="4")] + pub signer_indices_clan_committee: ::prost::alloc::vec::Vec, + #[prost(uint32, tag="5")] + pub transaction_type: u32, + #[prost(bytes="vec", tag="6")] + pub payload: ::prost::alloc::vec::Vec, + } + } + + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum ValidatorTransactionType { #[prost(message, tag="1")] ObservedJwkUpdate(ObservedJwkUpdate), #[prost(message, tag="2")] DkgUpdate(DkgUpdate), + #[prost(message, tag="3")] + Dkg(DkgTransactionData), } } #[allow(clippy::derive_partial_eq_without_eq)] @@ -421,7 +451,7 @@ pub mod write_set { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum WriteSet { #[prost(message, tag="2")] ScriptWriteSet(super::ScriptWriteSet), @@ -497,7 +527,7 @@ pub mod write_set_change { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Change { #[prost(message, tag="2")] DeleteModule(super::DeleteModule), @@ -655,7 +685,7 @@ pub mod transaction_payload { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Payload { #[prost(message, tag="2")] EntryFunctionPayload(super::EntryFunctionPayload), @@ -749,7 +779,7 @@ pub mod multisig_transaction_payload { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Payload { #[prost(message, tag="2")] EntryFunctionPayload(super::EntryFunctionPayload), @@ -930,7 +960,7 @@ pub struct MoveType { /// Nested message and enum types in `MoveType`. pub mod move_type { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Message)] + #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReferenceType { #[prost(bool, tag="1")] pub mutable: bool, @@ -938,7 +968,7 @@ pub mod move_type { pub to: ::core::option::Option<::prost::alloc::boxed::Box>, } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Content { #[prost(message, tag="3")] Vector(::prost::alloc::boxed::Box), @@ -1035,7 +1065,7 @@ pub mod signature { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Signature { #[prost(message, tag="2")] Ed25519(super::Ed25519Signature), @@ -1193,7 +1223,7 @@ pub mod any_signature { } /// Support: >= 1.10. #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum SignatureVariant { #[prost(message, tag="3")] Ed25519(super::Ed25519), @@ -1307,7 +1337,7 @@ pub mod account_signature { } } #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Signature { #[prost(message, tag="2")] Ed25519(super::Ed25519Signature), @@ -4244,4 +4274,4 @@ pub const FILE_DESCRIPTOR_SET: &[u8] = &[ 0x03, 0x12, 0x04, 0xa3, 0x05, 0x17, 0x18, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("aptos.transaction.v1.serde.rs"); -// @@protoc_insertion_point(module) +// @@protoc_insertion_point(module) \ No newline at end of file diff --git a/protos/rust/src/pb/aptos.transaction.v1.serde.rs b/protos/rust/src/pb/aptos.transaction.v1.serde.rs index 92cce90cda4..438666ba8b9 100644 --- a/protos/rust/src/pb/aptos.transaction.v1.serde.rs +++ b/protos/rust/src/pb/aptos.transaction.v1.serde.rs @@ -107,8 +107,8 @@ impl<'de> serde::Deserialize<'de> for AccountSignature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut signature__ = None; @@ -125,28 +125,28 @@ impl<'de> serde::Deserialize<'de> for AccountSignature { return Err(serde::de::Error::duplicate_field("ed25519")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(account_signature::Signature::Ed25519) -; + ; } GeneratedField::MultiEd25519 => { if signature__.is_some() { return Err(serde::de::Error::duplicate_field("multiEd25519")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(account_signature::Signature::MultiEd25519) -; + ; } GeneratedField::SingleKeySignature => { if signature__.is_some() { return Err(serde::de::Error::duplicate_field("singleKeySignature")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(account_signature::Signature::SingleKeySignature) -; + ; } GeneratedField::MultiKeySignature => { if signature__.is_some() { return Err(serde::de::Error::duplicate_field("multiKeySignature")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(account_signature::Signature::MultiKeySignature) -; + ; } } } @@ -322,8 +322,8 @@ impl<'de> serde::Deserialize<'de> for AnyPublicKey { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut public_key__ = None; @@ -548,8 +548,8 @@ impl<'de> serde::Deserialize<'de> for AnySignature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut signature__ = None; @@ -575,28 +575,28 @@ impl<'de> serde::Deserialize<'de> for AnySignature { return Err(serde::de::Error::duplicate_field("ed25519")); } signature_variant__ = map.next_value::<::std::option::Option<_>>()?.map(any_signature::SignatureVariant::Ed25519) -; + ; } GeneratedField::Secp256k1Ecdsa => { if signature_variant__.is_some() { return Err(serde::de::Error::duplicate_field("secp256k1Ecdsa")); } signature_variant__ = map.next_value::<::std::option::Option<_>>()?.map(any_signature::SignatureVariant::Secp256k1Ecdsa) -; + ; } GeneratedField::Webauthn => { if signature_variant__.is_some() { return Err(serde::de::Error::duplicate_field("webauthn")); } signature_variant__ = map.next_value::<::std::option::Option<_>>()?.map(any_signature::SignatureVariant::Webauthn) -; + ; } GeneratedField::Keyless => { if signature_variant__.is_some() { return Err(serde::de::Error::duplicate_field("keyless")); } signature_variant__ = map.next_value::<::std::option::Option<_>>()?.map(any_signature::SignatureVariant::Keyless) -; + ; } } } @@ -819,8 +819,8 @@ impl<'de> serde::Deserialize<'de> for AutomatedTaskMeta { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut sender__ = None; let mut index__ = None; @@ -975,8 +975,8 @@ impl<'de> serde::Deserialize<'de> for AutomatedTransaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut meta__ = None; let mut events__ = None; @@ -1125,8 +1125,8 @@ impl<'de> serde::Deserialize<'de> for AutomationPayload { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut automated_function__ = None; let mut expiration_timestamp_secs__ = None; @@ -1709,8 +1709,8 @@ impl<'de> serde::Deserialize<'de> for Block { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut timestamp__ = None; let mut height__ = None; @@ -1859,8 +1859,8 @@ impl<'de> serde::Deserialize<'de> for BlockEndInfo { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut block_gas_limit_reached__ = None; let mut block_output_limit_reached__ = None; @@ -1979,8 +1979,8 @@ impl<'de> serde::Deserialize<'de> for BlockEpilogueTransaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut block_end_info__ = None; while let Some(k) = map.next_key()? { @@ -2117,8 +2117,8 @@ impl<'de> serde::Deserialize<'de> for BlockMetadataTransaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut id__ = None; let mut round__ = None; @@ -2274,8 +2274,8 @@ impl<'de> serde::Deserialize<'de> for DeleteModule { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut address__ = None; let mut state_key_hash__ = None; @@ -2412,8 +2412,8 @@ impl<'de> serde::Deserialize<'de> for DeleteResource { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut address__ = None; let mut state_key_hash__ = None; @@ -2539,8 +2539,8 @@ impl<'de> serde::Deserialize<'de> for DeleteTableData { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut key__ = None; let mut key_type__ = None; @@ -2666,8 +2666,8 @@ impl<'de> serde::Deserialize<'de> for DeleteTableItem { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut state_key_hash__ = None; let mut handle__ = None; @@ -2793,8 +2793,8 @@ impl<'de> serde::Deserialize<'de> for DirectWriteSet { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut write_set_change__ = None; let mut events__ = None; @@ -2892,8 +2892,8 @@ impl<'de> serde::Deserialize<'de> for Ed25519 { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut signature__ = None; while let Some(k) = map.next_key()? { @@ -2995,8 +2995,8 @@ impl<'de> serde::Deserialize<'de> for Ed25519Signature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut public_key__ = None; let mut signature__ = None; @@ -3107,8 +3107,8 @@ impl<'de> serde::Deserialize<'de> for EntryFunctionId { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut module__ = None; let mut name__ = None; @@ -3235,8 +3235,8 @@ impl<'de> serde::Deserialize<'de> for EntryFunctionPayload { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut function__ = None; let mut type_arguments__ = None; @@ -3388,8 +3388,8 @@ impl<'de> serde::Deserialize<'de> for Event { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut key__ = None; let mut sequence_number__ = None; @@ -3524,8 +3524,8 @@ impl<'de> serde::Deserialize<'de> for EventKey { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut creation_number__ = None; let mut account_address__ = None; @@ -3636,8 +3636,8 @@ impl<'de> serde::Deserialize<'de> for EventSizeInfo { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut type_tag_bytes__ = None; let mut total_bytes__ = None; @@ -3779,8 +3779,8 @@ impl<'de> serde::Deserialize<'de> for FeePayerSignature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut sender__ = None; let mut secondary_signer_addresses__ = None; @@ -3911,8 +3911,8 @@ impl<'de> serde::Deserialize<'de> for GenesisTransaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut payload__ = None; let mut events__ = None; @@ -4019,8 +4019,8 @@ impl<'de> serde::Deserialize<'de> for IndexedSignature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut index__ = None; let mut signature__ = None; @@ -4120,8 +4120,8 @@ impl<'de> serde::Deserialize<'de> for Keyless { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut signature__ = None; while let Some(k) = map.next_key()? { @@ -4344,8 +4344,8 @@ impl<'de> serde::Deserialize<'de> for MoveFunction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut name__ = None; let mut visibility__ = None; @@ -4501,7 +4501,7 @@ impl serde::Serialize for MoveFunctionGenericTypeParam { let v = self.constraints.iter().cloned().map(|v| { MoveAbility::from_i32(v) .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", v))) - }).collect::, _>>()?; + }).collect::, _>>()?; struct_ser.serialize_field("constraints", &v)?; } struct_ser.end() @@ -4558,8 +4558,8 @@ impl<'de> serde::Deserialize<'de> for MoveFunctionGenericTypeParam { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut constraints__ = None; while let Some(k) = map.next_key()? { @@ -4686,8 +4686,8 @@ impl<'de> serde::Deserialize<'de> for MoveModule { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut address__ = None; let mut name__ = None; @@ -4818,8 +4818,8 @@ impl<'de> serde::Deserialize<'de> for MoveModuleBytecode { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut bytecode__ = None; let mut abi__ = None; @@ -4928,8 +4928,8 @@ impl<'de> serde::Deserialize<'de> for MoveModuleId { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut address__ = None; let mut name__ = None; @@ -5036,8 +5036,8 @@ impl<'de> serde::Deserialize<'de> for MoveScriptBytecode { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut bytecode__ = None; let mut abi__ = None; @@ -5102,7 +5102,7 @@ impl serde::Serialize for MoveStruct { let v = self.abilities.iter().cloned().map(|v| { MoveAbility::from_i32(v) .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", v))) - }).collect::, _>>()?; + }).collect::, _>>()?; struct_ser.serialize_field("abilities", &v)?; } if !self.generic_type_params.is_empty() { @@ -5179,8 +5179,8 @@ impl<'de> serde::Deserialize<'de> for MoveStruct { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut name__ = None; let mut is_native__ = None; @@ -5311,8 +5311,8 @@ impl<'de> serde::Deserialize<'de> for MoveStructField { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut name__ = None; let mut r#type__ = None; @@ -5360,7 +5360,7 @@ impl serde::Serialize for MoveStructGenericTypeParam { let v = self.constraints.iter().cloned().map(|v| { MoveAbility::from_i32(v) .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", v))) - }).collect::, _>>()?; + }).collect::, _>>()?; struct_ser.serialize_field("constraints", &v)?; } if self.is_phantom { @@ -5424,8 +5424,8 @@ impl<'de> serde::Deserialize<'de> for MoveStructGenericTypeParam { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut constraints__ = None; let mut is_phantom__ = None; @@ -5551,8 +5551,8 @@ impl<'de> serde::Deserialize<'de> for MoveStructTag { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut address__ = None; let mut module__ = None; @@ -5706,8 +5706,8 @@ impl<'de> serde::Deserialize<'de> for MoveType { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut content__ = None; @@ -5724,14 +5724,14 @@ impl<'de> serde::Deserialize<'de> for MoveType { return Err(serde::de::Error::duplicate_field("vector")); } content__ = map.next_value::<::std::option::Option<_>>()?.map(move_type::Content::Vector) -; + ; } GeneratedField::Struct => { if content__.is_some() { return Err(serde::de::Error::duplicate_field("struct")); } content__ = map.next_value::<::std::option::Option<_>>()?.map(move_type::Content::Struct) -; + ; } GeneratedField::GenericTypeParamIndex => { if content__.is_some() { @@ -5744,7 +5744,7 @@ impl<'de> serde::Deserialize<'de> for MoveType { return Err(serde::de::Error::duplicate_field("reference")); } content__ = map.next_value::<::std::option::Option<_>>()?.map(move_type::Content::Reference) -; + ; } GeneratedField::Unparsable => { if content__.is_some() { @@ -5841,8 +5841,8 @@ impl<'de> serde::Deserialize<'de> for move_type::ReferenceType { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut mutable__ = None; let mut to__ = None; @@ -6072,8 +6072,8 @@ impl<'de> serde::Deserialize<'de> for MultiAgentSignature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut sender__ = None; let mut secondary_signer_addresses__ = None; @@ -6208,8 +6208,8 @@ impl<'de> serde::Deserialize<'de> for MultiEd25519Signature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut public_keys__ = None; let mut signatures__ = None; @@ -6354,8 +6354,8 @@ impl<'de> serde::Deserialize<'de> for MultiKeySignature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut public_keys__ = None; let mut signatures__ = None; @@ -6474,8 +6474,8 @@ impl<'de> serde::Deserialize<'de> for MultisigPayload { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut multisig_address__ = None; let mut transaction_payload__ = None; @@ -6596,8 +6596,8 @@ impl<'de> serde::Deserialize<'de> for MultisigTransactionPayload { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut payload__ = None; @@ -6614,7 +6614,7 @@ impl<'de> serde::Deserialize<'de> for MultisigTransactionPayload { return Err(serde::de::Error::duplicate_field("entryFunctionPayload")); } payload__ = map.next_value::<::std::option::Option<_>>()?.map(multisig_transaction_payload::Payload::EntryFunctionPayload) -; + ; } GeneratedField::AutomationPayload => { if payload__.is_some() { @@ -6798,8 +6798,8 @@ impl<'de> serde::Deserialize<'de> for ScriptPayload { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut code__ = None; let mut type_arguments__ = None; @@ -6915,8 +6915,8 @@ impl<'de> serde::Deserialize<'de> for ScriptWriteSet { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut execute_as__ = None; let mut script__ = None; @@ -7014,8 +7014,8 @@ impl<'de> serde::Deserialize<'de> for Secp256k1Ecdsa { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut signature__ = None; while let Some(k) = map.next_key()? { @@ -7150,8 +7150,8 @@ impl<'de> serde::Deserialize<'de> for Signature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut signature__ = None; @@ -7168,35 +7168,35 @@ impl<'de> serde::Deserialize<'de> for Signature { return Err(serde::de::Error::duplicate_field("ed25519")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(signature::Signature::Ed25519) -; + ; } GeneratedField::MultiEd25519 => { if signature__.is_some() { return Err(serde::de::Error::duplicate_field("multiEd25519")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(signature::Signature::MultiEd25519) -; + ; } GeneratedField::MultiAgent => { if signature__.is_some() { return Err(serde::de::Error::duplicate_field("multiAgent")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(signature::Signature::MultiAgent) -; + ; } GeneratedField::FeePayer => { if signature__.is_some() { return Err(serde::de::Error::duplicate_field("feePayer")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(signature::Signature::FeePayer) -; + ; } GeneratedField::SingleSender => { if signature__.is_some() { return Err(serde::de::Error::duplicate_field("singleSender")); } signature__ = map.next_value::<::std::option::Option<_>>()?.map(signature::Signature::SingleSender) -; + ; } } } @@ -7373,8 +7373,8 @@ impl<'de> serde::Deserialize<'de> for SingleKeySignature { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut public_key__ = None; let mut signature__ = None; @@ -7472,8 +7472,8 @@ impl<'de> serde::Deserialize<'de> for SingleSender { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut sender__ = None; while let Some(k) = map.next_key()? { @@ -7537,7 +7537,7 @@ impl<'de> serde::Deserialize<'de> for StateCheckpointTransaction { where E: serde::de::Error, { - Err(serde::de::Error::unknown_field(value, FIELDS)) + Err(serde::de::Error::unknown_field(value, FIELDS)) } } deserializer.deserialize_identifier(GeneratedVisitor) @@ -7552,8 +7552,8 @@ impl<'de> serde::Deserialize<'de> for StateCheckpointTransaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { while map.next_key::()?.is_some() { let _ = map.next_value::()?; @@ -7744,8 +7744,8 @@ impl<'de> serde::Deserialize<'de> for Transaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut timestamp__ = None; let mut version__ = None; @@ -7810,49 +7810,49 @@ impl<'de> serde::Deserialize<'de> for Transaction { return Err(serde::de::Error::duplicate_field("blockMetadata")); } txn_data__ = map.next_value::<::std::option::Option<_>>()?.map(transaction::TxnData::BlockMetadata) -; + ; } GeneratedField::Genesis => { if txn_data__.is_some() { return Err(serde::de::Error::duplicate_field("genesis")); } txn_data__ = map.next_value::<::std::option::Option<_>>()?.map(transaction::TxnData::Genesis) -; + ; } GeneratedField::StateCheckpoint => { if txn_data__.is_some() { return Err(serde::de::Error::duplicate_field("stateCheckpoint")); } txn_data__ = map.next_value::<::std::option::Option<_>>()?.map(transaction::TxnData::StateCheckpoint) -; + ; } GeneratedField::User => { if txn_data__.is_some() { return Err(serde::de::Error::duplicate_field("user")); } txn_data__ = map.next_value::<::std::option::Option<_>>()?.map(transaction::TxnData::User) -; + ; } GeneratedField::Validator => { if txn_data__.is_some() { return Err(serde::de::Error::duplicate_field("validator")); } txn_data__ = map.next_value::<::std::option::Option<_>>()?.map(transaction::TxnData::Validator) -; + ; } GeneratedField::BlockEpilogue => { if txn_data__.is_some() { return Err(serde::de::Error::duplicate_field("blockEpilogue")); } txn_data__ = map.next_value::<::std::option::Option<_>>()?.map(transaction::TxnData::BlockEpilogue) -; + ; } GeneratedField::Automated => { if txn_data__.is_some() { return Err(serde::de::Error::duplicate_field("automated")); } txn_data__ = map.next_value::<::std::option::Option<_>>()?.map(transaction::TxnData::Automated) -; + ; } } } @@ -8109,8 +8109,8 @@ impl<'de> serde::Deserialize<'de> for TransactionInfo { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut hash__ = None; let mut state_change_hash__ = None; @@ -8327,8 +8327,8 @@ impl<'de> serde::Deserialize<'de> for TransactionPayload { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut payload__ = None; @@ -8345,35 +8345,35 @@ impl<'de> serde::Deserialize<'de> for TransactionPayload { return Err(serde::de::Error::duplicate_field("entryFunctionPayload")); } payload__ = map.next_value::<::std::option::Option<_>>()?.map(transaction_payload::Payload::EntryFunctionPayload) -; + ; } GeneratedField::ScriptPayload => { if payload__.is_some() { return Err(serde::de::Error::duplicate_field("scriptPayload")); } payload__ = map.next_value::<::std::option::Option<_>>()?.map(transaction_payload::Payload::ScriptPayload) -; + ; } GeneratedField::WriteSetPayload => { if payload__.is_some() { return Err(serde::de::Error::duplicate_field("writeSetPayload")); } payload__ = map.next_value::<::std::option::Option<_>>()?.map(transaction_payload::Payload::WriteSetPayload) -; + ; } GeneratedField::MultisigPayload => { if payload__.is_some() { return Err(serde::de::Error::duplicate_field("multisigPayload")); } payload__ = map.next_value::<::std::option::Option<_>>()?.map(transaction_payload::Payload::MultisigPayload) -; + ; } GeneratedField::AutomationPayload => { if payload__.is_some() { return Err(serde::de::Error::duplicate_field("automationPayload")); } payload__ = map.next_value::<::std::option::Option<_>>()?.map(transaction_payload::Payload::AutomationPayload) -; + ; } GeneratedField::AutomationPayloads => { if payload__.is_some() { @@ -8571,8 +8571,8 @@ impl<'de> serde::Deserialize<'de> for TransactionSizeInfo { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut transaction_bytes__ = None; let mut event_size_info__ = None; @@ -8689,8 +8689,8 @@ impl<'de> serde::Deserialize<'de> for UserTransaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut request__ = None; let mut events__ = None; @@ -8846,8 +8846,8 @@ impl<'de> serde::Deserialize<'de> for UserTransactionRequest { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut sender__ = None; let mut sequence_number__ = None; @@ -8948,6 +8948,9 @@ impl serde::Serialize for ValidatorTransaction { validator_transaction::ValidatorTransactionType::DkgUpdate(v) => { struct_ser.serialize_field("dkgUpdate", v)?; } + validator_transaction::ValidatorTransactionType::Dkg(v) => { + struct_ser.serialize_field("dkg", v)?; + } } } struct_ser.end() @@ -9012,8 +9015,8 @@ impl<'de> serde::Deserialize<'de> for ValidatorTransaction { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut events__ = None; let mut validator_transaction_type__ = None; @@ -9030,14 +9033,14 @@ impl<'de> serde::Deserialize<'de> for ValidatorTransaction { return Err(serde::de::Error::duplicate_field("observedJwkUpdate")); } validator_transaction_type__ = map.next_value::<::std::option::Option<_>>()?.map(validator_transaction::ValidatorTransactionType::ObservedJwkUpdate) -; + ; } GeneratedField::DkgUpdate => { if validator_transaction_type__.is_some() { return Err(serde::de::Error::duplicate_field("dkgUpdate")); } validator_transaction_type__ = map.next_value::<::std::option::Option<_>>()?.map(validator_transaction::ValidatorTransactionType::DkgUpdate) -; + ; } } } @@ -9120,8 +9123,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::DkgUpdate { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut dkg_transcript__ = None; while let Some(k) = map.next_key()? { @@ -9229,8 +9232,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::dkg_update::DkgTran } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut epoch__ = None; let mut author__ = None; @@ -9271,7 +9274,7 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::dkg_update::DkgTran deserializer.deserialize_struct("aptos.transaction.v1.ValidatorTransaction.DkgUpdate.DkgTranscript", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for validator_transaction::ObservedJwkUpdate { +impl serde::Serialize for validator_transaction::DkgTransactionData { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -9279,30 +9282,30 @@ impl serde::Serialize for validator_transaction::ObservedJwkUpdate { { use serde::ser::SerializeStruct; let mut len = 0; - if self.quorum_certified_update.is_some() { + if self.dkg_data.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate", len)?; - if let Some(v) = self.quorum_certified_update.as_ref() { - struct_ser.serialize_field("quorumCertifiedUpdate", v)?; + let mut struct_ser = serializer.serialize_struct("aptos.transaction.v1.ValidatorTransaction.DkgTransactionData", len)?; + if let Some(v) = self.dkg_data.as_ref() { + struct_ser.serialize_field("dkgData", v)?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for validator_transaction::ObservedJwkUpdate { +impl<'de> serde::Deserialize<'de> for validator_transaction::DkgTransactionData { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "quorum_certified_update", - "quorumCertifiedUpdate", + "dkg_data", + "dkgData", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - QuorumCertifiedUpdate, + DkgData, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -9324,7 +9327,7 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::ObservedJwkUpdate { E: serde::de::Error, { match value { - "quorumCertifiedUpdate" | "quorum_certified_update" => Ok(GeneratedField::QuorumCertifiedUpdate), + "dkgData" | "dkg_data" => Ok(GeneratedField::DkgData), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -9334,15 +9337,297 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::ObservedJwkUpdate { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = validator_transaction::ObservedJwkUpdate; + type Value = validator_transaction::DkgTransactionData; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate") + formatter.write_str("struct aptos.transaction.v1.ValidatorTransaction.DkgTransactionData") } - fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut dkg_data__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::DkgData => { + if dkg_data__.is_some() { + return Err(serde::de::Error::duplicate_field("dkgData")); + } + dkg_data__ = map.next_value()?; + } + } + } + Ok(validator_transaction::DkgTransactionData { + dkg_data: dkg_data__, + }) + } + } + deserializer.deserialize_struct("aptos.transaction.v1.ValidatorTransaction.DkgTransactionData", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for validator_transaction::dkg_data::DkgTransactionData { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.epoch != 0 { + len += 1; + } + if !self.author.is_empty() { + len += 1; + } + if !self.bls_aggregate_signature.is_empty() { + len += 1; + } + if !self.signer_indices_clan_committee.is_empty() { + len += 1; + } + if self.transaction_type != 0 { + len += 1; + } + if !self.payload.is_empty() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("aptos.transaction.v1.ValidatorTransaction.DkgTransactionData.DkgTransactionData", len)?; + if self.epoch != 0 { + struct_ser.serialize_field("epoch", ToString::to_string(&self.epoch).as_str())?; + } + if !self.author.is_empty() { + struct_ser.serialize_field("author", &self.author)?; + } + if !self.bls_aggregate_signature.is_empty() { + struct_ser.serialize_field("blsAggregateSignature", pbjson::private::base64::encode(&self.bls_aggregate_signature).as_str())?; + } + if !self.signer_indices_clan_committee.is_empty() { + struct_ser.serialize_field("signerIndicesClanCommittee", &self.signer_indices_clan_committee.iter().map(ToString::to_string).collect::>())?; + } + if self.transaction_type != 0 { + struct_ser.serialize_field("transactionType", ToString::to_string(&self.transaction_type).as_str())?; + } + if !self.payload.is_empty() { + struct_ser.serialize_field("payload", pbjson::private::base64::encode(&self.payload).as_str())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for validator_transaction::dkg_data::DkgTransactionData { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "epoch", + "author", + "bls_aggregate_signature", + "blsAggregateSignature", + "signer_indices_clan_committee", + "signerIndicesClanCommittee", + "transaction_type", + "transactionType", + "payload", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Epoch, + Author, + BlsAggregateSignature, + SignerIndicesClanCommittee, + TransactionType, + Payload, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "epoch" => Ok(GeneratedField::Epoch), + "author" => Ok(GeneratedField::Author), + "blsAggregateSignature" | "bls_aggregate_signature" => Ok(GeneratedField::BlsAggregateSignature), + "signerIndicesClanCommittee" | "signer_indices_clan_committee" => Ok(GeneratedField::SignerIndicesClanCommittee), + "transactionType" | "transaction_type" => Ok(GeneratedField::TransactionType), + "payload" => Ok(GeneratedField::Payload), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = validator_transaction::dkg_data::DkgTransactionData; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct aptos.transaction.v1.ValidatorTransaction.DkgTransactionData.DkgTransactionData") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut epoch__ = None; + let mut author__ = None; + let mut bls_aggregate_signature__ = None; + let mut signer_indices_clan_committee__ = None; + let mut transaction_type__ = None; + let mut payload__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::Epoch => { + if epoch__.is_some() { + return Err(serde::de::Error::duplicate_field("epoch")); + } + epoch__ = + Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Author => { + if author__.is_some() { + return Err(serde::de::Error::duplicate_field("author")); + } + author__ = Some(map.next_value()?); + } + GeneratedField::BlsAggregateSignature => { + if bls_aggregate_signature__.is_some() { + return Err(serde::de::Error::duplicate_field("blsAggregateSignature")); + } + bls_aggregate_signature__ = + Some(map.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + GeneratedField::SignerIndicesClanCommittee => { + if signer_indices_clan_committee__.is_some() { + return Err(serde::de::Error::duplicate_field("signerIndicesClanCommittee")); + } + signer_indices_clan_committee__ = + Some(map.next_value::>>()? + .into_iter().map(|x| x.0).collect()) + ; + } + GeneratedField::TransactionType => { + if transaction_type__.is_some() { + return Err(serde::de::Error::duplicate_field("transactionType")); + } + transaction_type__ = + Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + GeneratedField::Payload => { + if payload__.is_some() { + return Err(serde::de::Error::duplicate_field("payload")); + } + payload__ = + Some(map.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; + } + } + } + Ok(validator_transaction::dkg_data::DkgTransactionData { + epoch: epoch__.unwrap_or_default(), + author: author__.unwrap_or_default(), + bls_aggregate_signature: bls_aggregate_signature__.unwrap_or_default(), + signer_indices_clan_committee: signer_indices_clan_committee__.unwrap_or_default(), + transaction_type: transaction_type__.unwrap_or_default(), + payload: payload__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("aptos.transaction.v1.ValidatorTransaction.DkgTransactionData.DkgTransactionData", FIELDS, GeneratedVisitor) + } +} +impl serde::Serialize for validator_transaction::ObservedJwkUpdate { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.quorum_certified_update.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate", len)?; + if let Some(v) = self.quorum_certified_update.as_ref() { + struct_ser.serialize_field("quorumCertifiedUpdate", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for validator_transaction::ObservedJwkUpdate { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "quorum_certified_update", + "quorumCertifiedUpdate", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + QuorumCertifiedUpdate, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "quorumCertifiedUpdate" | "quorum_certified_update" => Ok(GeneratedField::QuorumCertifiedUpdate), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = validator_transaction::ObservedJwkUpdate; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct aptos.transaction.v1.ValidatorTransaction.ObservedJwkUpdate") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, { let mut quorum_certified_update__ = None; while let Some(k) = map.next_key()? { @@ -9442,8 +9727,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::observed_jwk_update } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut signer_indices__ = None; let mut sig__ = None; @@ -9564,8 +9849,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::observed_jwk_update } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut issuer__ = None; let mut version__ = None; @@ -9684,8 +9969,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::observed_jwk_update } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut jwk_type__ = None; while let Some(k) = map.next_key()? { @@ -9695,14 +9980,14 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::observed_jwk_update return Err(serde::de::Error::duplicate_field("unsupportedJwk")); } jwk_type__ = map.next_value::<::std::option::Option<_>>()?.map(validator_transaction::observed_jwk_update::exported_provider_jw_ks::jwk::JwkType::UnsupportedJwk) -; + ; } GeneratedField::Rsa => { if jwk_type__.is_some() { return Err(serde::de::Error::duplicate_field("rsa")); } jwk_type__ = map.next_value::<::std::option::Option<_>>()?.map(validator_transaction::observed_jwk_update::exported_provider_jw_ks::jwk::JwkType::Rsa) -; + ; } } } @@ -9819,8 +10104,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::observed_jwk_update } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut kid__ = None; let mut kty__ = None; @@ -9951,8 +10236,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::observed_jwk_update } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut id__ = None; let mut payload__ = None; @@ -10064,8 +10349,8 @@ impl<'de> serde::Deserialize<'de> for validator_transaction::observed_jwk_update } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut update__ = None; let mut multi_sig__ = None; @@ -10163,8 +10448,8 @@ impl<'de> serde::Deserialize<'de> for WebAuthn { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut signature__ = None; while let Some(k) = map.next_key()? { @@ -10275,8 +10560,8 @@ impl<'de> serde::Deserialize<'de> for WriteModule { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut address__ = None; let mut state_key_hash__ = None; @@ -10395,8 +10680,8 @@ impl<'de> serde::Deserialize<'de> for WriteOpSizeInfo { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut key_bytes__ = None; let mut value_bytes__ = None; @@ -10536,8 +10821,8 @@ impl<'de> serde::Deserialize<'de> for WriteResource { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut address__ = None; let mut state_key_hash__ = None; @@ -10685,8 +10970,8 @@ impl<'de> serde::Deserialize<'de> for WriteSet { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut write_set_type__ = None; let mut write_set__ = None; @@ -10703,14 +10988,14 @@ impl<'de> serde::Deserialize<'de> for WriteSet { return Err(serde::de::Error::duplicate_field("scriptWriteSet")); } write_set__ = map.next_value::<::std::option::Option<_>>()?.map(write_set::WriteSet::ScriptWriteSet) -; + ; } GeneratedField::DirectWriteSet => { if write_set__.is_some() { return Err(serde::de::Error::duplicate_field("directWriteSet")); } write_set__ = map.next_value::<::std::option::Option<_>>()?.map(write_set::WriteSet::DirectWriteSet) -; + ; } } } @@ -10919,8 +11204,8 @@ impl<'de> serde::Deserialize<'de> for WriteSetChange { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut r#type__ = None; let mut change__ = None; @@ -10937,42 +11222,42 @@ impl<'de> serde::Deserialize<'de> for WriteSetChange { return Err(serde::de::Error::duplicate_field("deleteModule")); } change__ = map.next_value::<::std::option::Option<_>>()?.map(write_set_change::Change::DeleteModule) -; + ; } GeneratedField::DeleteResource => { if change__.is_some() { return Err(serde::de::Error::duplicate_field("deleteResource")); } change__ = map.next_value::<::std::option::Option<_>>()?.map(write_set_change::Change::DeleteResource) -; + ; } GeneratedField::DeleteTableItem => { if change__.is_some() { return Err(serde::de::Error::duplicate_field("deleteTableItem")); } change__ = map.next_value::<::std::option::Option<_>>()?.map(write_set_change::Change::DeleteTableItem) -; + ; } GeneratedField::WriteModule => { if change__.is_some() { return Err(serde::de::Error::duplicate_field("writeModule")); } change__ = map.next_value::<::std::option::Option<_>>()?.map(write_set_change::Change::WriteModule) -; + ; } GeneratedField::WriteResource => { if change__.is_some() { return Err(serde::de::Error::duplicate_field("writeResource")); } change__ = map.next_value::<::std::option::Option<_>>()?.map(write_set_change::Change::WriteResource) -; + ; } GeneratedField::WriteTableItem => { if change__.is_some() { return Err(serde::de::Error::duplicate_field("writeTableItem")); } change__ = map.next_value::<::std::option::Option<_>>()?.map(write_set_change::Change::WriteTableItem) -; + ; } } } @@ -11143,8 +11428,8 @@ impl<'de> serde::Deserialize<'de> for WriteSetPayload { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut write_set__ = None; while let Some(k) = map.next_key()? { @@ -11263,8 +11548,8 @@ impl<'de> serde::Deserialize<'de> for WriteTableData { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut key__ = None; let mut key_type__ = None; @@ -11406,8 +11691,8 @@ impl<'de> serde::Deserialize<'de> for WriteTableItem { } fn visit_map(self, mut map: V) -> std::result::Result - where - V: serde::de::MapAccess<'de>, + where + V: serde::de::MapAccess<'de>, { let mut state_key_hash__ = None; let mut handle__ = None; @@ -11453,4 +11738,4 @@ impl<'de> serde::Deserialize<'de> for WriteTableItem { } deserializer.deserialize_struct("aptos.transaction.v1.WriteTableItem", FIELDS, GeneratedVisitor) } -} +} \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 30329882ad8..68a2a77e5c5 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.78.0" +channel = "1.93.0" # Note: we don't specify cargofmt in our toolchain because we rely on # the nightly version of cargofmt and verify formatting in CI/CD. diff --git a/sdk/src/transaction_builder.rs b/sdk/src/transaction_builder.rs index 7b048adbb34..9cbca9ef926 100644 --- a/sdk/src/transaction_builder.rs +++ b/sdk/src/transaction_builder.rs @@ -174,14 +174,14 @@ impl TransactionFactory { &self, additional_owners: Vec, signatures_required: u64, - timeout_duration: u64, + timeout_duration: u64, ) -> TransactionBuilder { self.payload(aptos_stdlib::multisig_account_create_with_owners( additional_owners, signatures_required, vec![], vec![], - timeout_duration, + timeout_duration, )) } diff --git a/storage/accumulator/src/lib.rs b/storage/accumulator/src/lib.rs index 6fc7180274f..a37f400a292 100644 --- a/storage/accumulator/src/lib.rs +++ b/storage/accumulator/src/lib.rs @@ -160,6 +160,14 @@ where MerkleAccumulatorView::::new(reader, num_leaves).get_proof(leaf_index) } + pub fn get_proof_by_position( + reader: &R, + num_leaves: LeafCount, + position: Position, + ) -> Result> { + MerkleAccumulatorView::::new(reader, num_leaves).get_proof_by_position(position) + } + /// Gets a proof that shows the full accumulator is consistent with a smaller accumulator. /// /// See [`aptos_types::proof::AccumulatorConsistencyProof`] for proof format. @@ -367,6 +375,17 @@ where Ok(AccumulatorProof::new(siblings)) } + fn get_proof_by_position(&self, position: Position) -> Result> { + let root_pos = Position::root_from_leaf_count(self.num_leaves); + let siblings = self.get_hashes( + &position + .iter_ancestor_sibling() + .take(root_pos.level() as usize) + .collect::>(), + )?; + Ok(AccumulatorProof::new(siblings)) + } + /// Implementation for public interface `MerkleAccumulator::get_consistency_proof`. fn get_consistency_proof( &self, diff --git a/storage/aptosdb/Cargo.toml b/storage/aptosdb/Cargo.toml index a3a5c3d4390..19890caff89 100644 --- a/storage/aptosdb/Cargo.toml +++ b/storage/aptosdb/Cargo.toml @@ -72,6 +72,23 @@ rand = { workspace = true } [features] default = [] -fuzzing = ["proptest", "proptest-derive", "aptos-proptest-helpers", "aptos-temppath", "aptos-crypto/fuzzing", "aptos-jellyfish-merkle/fuzzing", "aptos-types/fuzzing", "aptos-executor-types/fuzzing", "aptos-schemadb/fuzzing", "aptos-scratchpad/fuzzing"] +fuzzing = [ + "proptest", + "proptest-derive", + "aptos-proptest-helpers", + "aptos-temppath", + "aptos-crypto/fuzzing", + "aptos-jellyfish-merkle/fuzzing", + "aptos-types/fuzzing", + "aptos-executor-types/fuzzing", + "aptos-schemadb/fuzzing", + "aptos-scratchpad/fuzzing", +] consensus-only-perf-test = [] -db-debugger = ["aptos-temppath", "clap", "crossbeam-channel", "owo-colors", "indicatif"] +db-debugger = [ + "aptos-temppath", + "clap", + "crossbeam-channel", + "owo-colors", + "indicatif", +] diff --git a/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs b/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs index 605a139648d..172e33a5bec 100644 --- a/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs +++ b/storage/backup/backup-cli/src/backup_types/transaction/analysis.rs @@ -114,8 +114,9 @@ impl TransactionAnalysis { match txn { UserTransaction(signed_txn) => signed_txn.raw_txn_bytes_len(), - AutomatedTransaction(automated_txn) - | SystemAutomatedTransaction(automated_txn) => automated_txn.raw_txn_bytes_len(), + AutomatedTransaction(automated_txn) | SystemAutomatedTransaction(automated_txn) => { + automated_txn.raw_txn_bytes_len() + }, GenesisTransaction(_) | BlockMetadata(_) | BlockMetadataExt(_) diff --git a/storage/indexer_schemas/Cargo.toml b/storage/indexer_schemas/Cargo.toml index 1768053160c..639a54c1ebc 100644 --- a/storage/indexer_schemas/Cargo.toml +++ b/storage/indexer_schemas/Cargo.toml @@ -33,4 +33,9 @@ rand = { workspace = true } [features] default = [] -fuzzing = ["proptest", "proptest-derive", "aptos-types/fuzzing", "aptos-schemadb/fuzzing"] +fuzzing = [ + "proptest", + "proptest-derive", + "aptos-types/fuzzing", + "aptos-schemadb/fuzzing", +] diff --git a/storage/jellyfish-merkle/Cargo.toml b/storage/jellyfish-merkle/Cargo.toml index 3894481f9d1..d2438ad608f 100644 --- a/storage/jellyfish-merkle/Cargo.toml +++ b/storage/jellyfish-merkle/Cargo.toml @@ -45,4 +45,9 @@ rand = { workspace = true } [features] default = [] -fuzzing = ["proptest", "proptest-derive", "aptos-crypto/fuzzing", "aptos-types/fuzzing"] +fuzzing = [ + "proptest", + "proptest-derive", + "aptos-crypto/fuzzing", + "aptos-types/fuzzing", +] diff --git a/testsuite/forge/Cargo.toml b/testsuite/forge/Cargo.toml index caa3c1f34ba..7ab69e5b229 100644 --- a/testsuite/forge/Cargo.toml +++ b/testsuite/forge/Cargo.toml @@ -44,9 +44,14 @@ hyper = { workspace = true } itertools = { workspace = true } json-patch = { workspace = true } k8s-openapi = { version = "0.13.1", default-features = false, features = [ - "v1_22", + "v1_22", +] } +kube = { version = "0.65.0", default-features = false, features = [ + "jsonpatch", + "client", + "rustls-tls", + "derive", ] } -kube = { version = "0.65.0", default-features = false, features = ["jsonpatch", "client", "rustls-tls", "derive"] } num_cpus = { workspace = true } once_cell = { workspace = true } prometheus-http-query = { workspace = true } diff --git a/testsuite/fuzzer/.cargo/config.toml b/testsuite/fuzzer/.cargo/config.toml index 94b9a7ade26..3e4d65a48d0 100644 --- a/testsuite/fuzzer/.cargo/config.toml +++ b/testsuite/fuzzer/.cargo/config.toml @@ -1,7 +1,25 @@ target-applies-to-host = false [host.aarch64-apple-darwin] -rustflags = ["--cfg", "tokio_unstable", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes"] +rustflags = [ + "--cfg", + "tokio_unstable", + "-C", + "force-frame-pointers=yes", + "-C", + "force-unwind-tables=yes", +] [host.x86_64-unknown-linux-gnu] -rustflags = ["--cfg", "tokio_unstable", "-C", "link-arg=-fuse-ld=lld", "-C", "force-frame-pointers=yes", "-C", "force-unwind-tables=yes", "-C", "target-feature=+sse4.2"] +rustflags = [ + "--cfg", + "tokio_unstable", + "-C", + "link-arg=-fuse-ld=lld", + "-C", + "force-frame-pointers=yes", + "-C", + "force-unwind-tables=yes", + "-C", + "target-feature=+sse4.2", +] diff --git a/testsuite/pyproject.toml b/testsuite/pyproject.toml index 3eb002623c0..fad50f770ae 100644 --- a/testsuite/pyproject.toml +++ b/testsuite/pyproject.toml @@ -27,4 +27,4 @@ build-backend = "poetry.core.masonry.api" [tool.pyright] reportUndefinedVariable = "none" -typeCheckingMode = "basic" # TODO(rustielin): eventually make this strict +typeCheckingMode = "basic" # TODO(rustielin): eventually make this strict diff --git a/testsuite/smoke-test/Cargo.toml b/testsuite/smoke-test/Cargo.toml index 31d1d233970..547438b3ac7 100644 --- a/testsuite/smoke-test/Cargo.toml +++ b/testsuite/smoke-test/Cargo.toml @@ -46,11 +46,11 @@ aptos-types = { workspace = true } aptos-vm = { workspace = true } bcs = { workspace = true } diesel = { workspace = true, features = [ - "chrono", - "postgres", - "r2d2", - "numeric", - "serde_json", + "chrono", + "postgres", + "r2d2", + "numeric", + "serde_json", ] } digest = { workspace = true } hex = { workspace = true } @@ -80,4 +80,3 @@ regex = { workspace = true } reqwest = { workspace = true } serde_yaml = { workspace = true } tempfile = { workspace = true } - diff --git a/third_party/move/evm/hardhat-examples/package-lock.json b/third_party/move/evm/hardhat-examples/package-lock.json index c10b7f6cd70..d0cf82e998f 100644 --- a/third_party/move/evm/hardhat-examples/package-lock.json +++ b/third_party/move/evm/hardhat-examples/package-lock.json @@ -26,6 +26,23 @@ "web3": "^1.7.1" } }, + "../hardhat-move": { + "version": "0.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^9.1.0", + "neverthrow": "^4.3.1", + "typescript": "^4.6.3" + }, + "devDependencies": { + "hardhat": "^2.9.3", + "mocha": "^7.1.2" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, "node_modules/@babel/runtime": { "version": "7.17.8", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz", @@ -358,23 +375,118 @@ } }, "node_modules/@ethereumjs/common": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.3.tgz", - "integrity": "sha512-mQwPucDL7FDYIg9XQ8DL31CnIYZwGhU5hyOO5E+BMmT71G0+RHvIT5rIkLBirJEKxV6+Rcf9aEIY0kXInxUWpQ==", + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", "dev": true, + "license": "MIT", "dependencies": { "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.4" + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" } }, "node_modules/@ethereumjs/tx": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.1.tgz", - "integrity": "sha512-xzDrTiu4sqZXUcaBxJ4n4W5FrppwxLxZB4ZDGVLtxSQR4lVuOnFR6RcUHdg1mpUhAPVrmnzLJpxaeXnPxIyhWA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, + "license": "MIT", "dependencies": { - "@ethereumjs/common": "^2.6.3", - "ethereumjs-util": "^7.1.4" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, "node_modules/@ethersproject/abi": { @@ -1116,6 +1228,32 @@ "rlp": "^2.2.3" } }, + "node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@noble/hashes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz", @@ -4304,14 +4442,28 @@ } }, "node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/chai": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", @@ -4336,6 +4488,23 @@ "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4351,12 +4520,6 @@ "@types/node": "*" } }, - "node_modules/@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", - "dev": true - }, "node_modules/@types/node": { "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", @@ -4403,6 +4566,16 @@ "@types/node": "*" } }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/secp256k1": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", @@ -4471,6 +4644,13 @@ "node": ">=6.5" } }, + "node_modules/abortcontroller-polyfill": { + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.8.tgz", + "integrity": "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ==", + "dev": true, + "license": "MIT" + }, "node_modules/abstract-level": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz", @@ -5327,6 +5507,16 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", + "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", @@ -6016,6 +6206,16 @@ "sha.js": "^2.4.8" } }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, "node_modules/cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -6537,6 +6737,13 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true, + "license": "MIT" + }, "node_modules/es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", @@ -7357,10 +7564,11 @@ } }, "node_modules/ethereumjs-util": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", - "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", "dev": true, + "license": "MPL-2.0", "dependencies": { "@types/bn.js": "^5.1.0", "bn.js": "^5.1.2", @@ -7829,6 +8037,13 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", + "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", + "dev": true, + "license": "MIT" + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -18320,18 +18535,8 @@ } }, "node_modules/hardhat-move": { - "version": "0.0.1", - "resolved": "file:../hardhat-move", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mocha": "^9.1.0", - "neverthrow": "^4.3.1", - "typescript": "^4.6.3" - }, - "peerDependencies": { - "hardhat": "^2.0.0" - } + "resolved": "../hardhat-move", + "link": true }, "node_modules/hardhat/node_modules/@noble/hashes": { "version": "1.2.0", @@ -18736,6 +18941,20 @@ "npm": ">=1.3.7" } }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -19828,6 +20047,13 @@ "node": ">= 0.6" } }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -20290,12 +20516,6 @@ "node": ">= 0.6" } }, - "node_modules/neverthrow": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/neverthrow/-/neverthrow-4.4.2.tgz", - "integrity": "sha512-QVY0ylzBF71pUdLshRrqtweMgqKnE3R37/T82Z5bhO/z8P9z96PC/5pEl2FmiZSy0p+3lsjKerh6jmTWM5fv2g==", - "dev": true - }, "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", @@ -20343,10 +20563,11 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -21144,6 +21365,19 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -21429,6 +21663,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, "node_modules/resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", @@ -22668,6 +22909,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -22826,16 +23068,16 @@ "dev": true }, "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", "which-typed-array": "^1.1.2" } }, @@ -22903,356 +23145,308 @@ } }, "node_modules/web3": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.7.1.tgz", - "integrity": "sha512-RKVdyZ5FuVEykj62C1o2tc0teJciSOh61jpVB9yb344dBHO3ZV4XPPP24s/PPqIMXmVFN00g2GD9M/v1SoHO/A==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.4.tgz", + "integrity": "sha512-kgJvQZjkmjOEKimx/tJQsqWfRDPTTcBfYPa9XletxuHLpHcXdx67w8EFn5AW3eVxCutE9dTVHgGa9VYe8vgsEA==", "dev": true, "hasInstallScript": true, + "license": "LGPL-3.0", "dependencies": { - "web3-bzz": "1.7.1", - "web3-core": "1.7.1", - "web3-eth": "1.7.1", - "web3-eth-personal": "1.7.1", - "web3-net": "1.7.1", - "web3-shh": "1.7.1", - "web3-utils": "1.7.1" + "web3-bzz": "1.10.4", + "web3-core": "1.10.4", + "web3-eth": "1.10.4", + "web3-eth-personal": "1.10.4", + "web3-net": "1.10.4", + "web3-shh": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-bzz": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.7.1.tgz", - "integrity": "sha512-sVeUSINx4a4pfdnT+3ahdRdpDPvZDf4ZT/eBF5XtqGWq1mhGTl8XaQAk15zafKVm6Onq28vN8abgB/l+TrG8kA==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.10.4.tgz", + "integrity": "sha512-ZZ/X4sJ0Uh2teU9lAGNS8EjveEppoHNQiKlOXAjedsrdWuaMErBPdLQjXfcrYvN6WM6Su9PMsAxf3FXXZ+HwQw==", "dev": true, "hasInstallScript": true, + "license": "LGPL-3.0", "dependencies": { "@types/node": "^12.12.6", - "got": "9.6.0", + "got": "12.1.0", "swarm-js": "^0.1.40" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-bzz/node_modules/@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", - "dev": true - }, - "node_modules/web3-core": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.7.1.tgz", - "integrity": "sha512-HOyDPj+4cNyeNPwgSeUkhtS0F+Pxc2obcm4oRYPW5ku6jnTO34pjaij0us+zoY3QEusR8FfAKVK1kFPZnS7Dzw==", + "node_modules/web3-bzz/node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "@types/node": "^12.12.6", - "bignumber.js": "^9.0.0", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-requestmanager": "1.7.1", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/web3-core-helpers": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", - "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", + "node_modules/web3-bzz/node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.5.3", - "web3-utils": "1.5.3" + "defer-to-connect": "^2.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=14.16" } }, - "node_modules/web3-core-helpers/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", "dev": true, - "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } + "license": "MIT" }, - "node_modules/web3-core-helpers/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "node_modules/web3-bzz/node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core-method": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.7.1.tgz", - "integrity": "sha512-383wu5FMcEphBFl5jCjk502JnEg3ugHj7MQrsX7DY76pg5N5/dEzxeEMIJFCN6kr5Iq32NINOG3VuJIyjxpsEg==", + "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "license": "MIT", "dependencies": { - "@ethersproject/transactions": "^5.0.0-beta.135", - "web3-core-helpers": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-utils": "1.7.1" + "pump": "^3.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-method/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-core-method/node_modules/web3-core-promievent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", - "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "node_modules/web3-bzz/node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, + "license": "MIT", "dependencies": { - "eventemitter3": "4.0.4" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-core-method/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "node": ">=10" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-promievent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", - "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", + "node_modules/web3-bzz/node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "dev": true, - "dependencies": { - "eventemitter3": "4.0.4" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" } }, - "node_modules/web3-core-requestmanager": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.7.1.tgz", - "integrity": "sha512-/EHVTiMShpZKiq0Jka0Vgguxi3vxq1DAHKxg42miqHdUsz4/cDWay2wGALDR2x3ofDB9kqp7pb66HsvQImQeag==", + "node_modules/web3-bzz/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "util": "^0.12.0", - "web3-core-helpers": "1.7.1", - "web3-providers-http": "1.7.1", - "web3-providers-ipc": "1.7.1", - "web3-providers-ws": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-requestmanager/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/got": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", + "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", "dev": true, + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "@sindresorhus/is": "^4.6.0", + "@szmarczak/http-timer": "^5.0.1", + "@types/cacheable-request": "^6.0.2", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^6.0.4", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "form-data-encoder": "1.7.1", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^2.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/web3-core-requestmanager/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-bzz/node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" - } + "license": "MIT" }, - "node_modules/web3-core-subscriptions": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.7.1.tgz", - "integrity": "sha512-NZBsvSe4J+Wt16xCf4KEtBbxA9TOwSVr8KWfUQ0tC2KMdDYdzNswl0Q9P58xaVuNlJ3/BH+uDFZJJ5E61BSA1Q==", + "node_modules/web3-bzz/node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { - "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "json-buffer": "3.0.1" } }, - "node_modules/web3-core-subscriptions/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core-subscriptions/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-bzz/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "node_modules/web3-bzz/node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true, - "dependencies": { - "@types/node": "*" + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core/node_modules/@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", - "dev": true - }, - "node_modules/web3-core/node_modules/bignumber.js": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", - "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "node_modules/web3-bzz/node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12.20" } }, - "node_modules/web3-core/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-bzz/node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "lowercase-keys": "^2.0.0" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/web3-core/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-bzz/node_modules/responselike/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/web3-eth": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.7.1.tgz", - "integrity": "sha512-Uz3gO4CjTJ+hMyJZAd2eiv2Ur1uurpN7sTMATWKXYR/SgG+SZgncnk/9d8t23hyu4lyi2GiVL1AqVqptpRElxg==", + "node_modules/web3-core": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.10.4.tgz", + "integrity": "sha512-B6elffYm81MYZDTrat7aEhnhdtVE3lDBUZft16Z8awYMZYJDbnykEbJVS+l3mnA7AQTnSDr/1MjWofGDLBJPww==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-eth-accounts": "1.7.1", - "web3-eth-contract": "1.7.1", - "web3-eth-ens": "1.7.1", - "web3-eth-iban": "1.7.1", - "web3-eth-personal": "1.7.1", - "web3-net": "1.7.1", - "web3-utils": "1.7.1" + "@types/bn.js": "^5.1.1", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-requestmanager": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-abi": { + "node_modules/web3-core-helpers": { "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", - "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.5.3.tgz", + "integrity": "sha512-Ip1IjB3S8vN7Kf1PPjK41U5gskmMk6IJQlxIVuS8/1U7n/o0jC8krqtpRwiMfAgYyw3TXwBFtxSRTvJtnLyXZw==", "dev": true, "dependencies": { - "@ethersproject/abi": "5.0.7", + "web3-eth-iban": "1.5.3", "web3-utils": "1.5.3" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "node_modules/web3-eth-abi/node_modules/eth-lib": { + "node_modules/web3-core-helpers/node_modules/eth-lib": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", @@ -23263,7 +23457,7 @@ "xhr-request-promise": "^0.1.2" } }, - "node_modules/web3-eth-abi/node_modules/web3-utils": { + "node_modules/web3-core-helpers/node_modules/web3-utils": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", @@ -23281,191 +23475,515 @@ "node": ">=8.0.0" } }, - "node_modules/web3-eth-accounts": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.7.1.tgz", - "integrity": "sha512-3xGQ2bkTQc7LFoqGWxp5cQDrKndlX05s7m0rAFVoyZZODMqrdSGjMPMqmWqHzJRUswNEMc+oelqSnGBubqhguQ==", + "node_modules/web3-core-method": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.10.4.tgz", + "integrity": "sha512-uZTb7flr+Xl6LaDsyTeE2L1TylokCJwTDrIVfIfnrGmnwLc6bmTWCCrm71sSrQ0hqs6vp/MKbQYIYqUN0J8WyA==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethereumjs/common": "^2.5.0", - "@ethereumjs/tx": "^3.3.2", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.8", - "ethereumjs-util": "^7.0.10", - "scrypt-js": "^3.0.1", - "uuid": "3.3.2", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-utils": "1.7.1" + "@ethersproject/transactions": "^5.6.2", + "web3-core-helpers": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-accounts/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "node_modules/web3-core-method/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" } }, - "node_modules/web3-eth-accounts/node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "node_modules/web3-core-method/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", "dev": true, - "bin": { - "uuid": "bin/uuid" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" } }, - "node_modules/web3-eth-accounts/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-core-method/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-accounts/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-core-method/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/bignumber": "^5.8.0" } }, - "node_modules/web3-eth-contract": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.7.1.tgz", - "integrity": "sha512-HpnbkPYkVK3lOyos2SaUjCleKfbF0SP3yjw7l551rAAi5sIz/vwlEzdPWd0IHL7ouxXbO0tDn7jzWBRcD3sTbA==", + "node_modules/web3-core-method/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.5", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-utils": "1.7.1" + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-core-method/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/web3-core-method/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/web3-core-method/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-method/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/web3-core-method/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-method/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "node_modules/web3-core-method/node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "node_modules/web3-core-method/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@types/node": "*" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-core-promievent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.5.3.tgz", + "integrity": "sha512-CFfgqvk3Vk6PIAxtLLuX+pOMozxkKCY+/GdGr7weMh033mDXEPvwyVjoSRO1PqIKj668/hMGQsVoIgbyxkJ9Mg==", "dev": true, "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "eventemitter3": "4.0.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-core-promievent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", - "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "node_modules/web3-core-requestmanager": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.10.4.tgz", + "integrity": "sha512-vqP6pKH8RrhT/2MoaU+DY/OsYK9h7HmEBNCdoMj+4ZwujQtw/Mq2JifjwsJ7gits7Q+HWJwx8q6WmQoVZAWugg==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "eventemitter3": "4.0.4" + "util": "^0.12.5", + "web3-core-helpers": "1.10.4", + "web3-providers-http": "1.10.4", + "web3-providers-ipc": "1.10.4", + "web3-providers-ws": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-eth-abi": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", - "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "node_modules/web3-core-requestmanager/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-requestmanager/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-contract/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-core-requestmanager/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-ens": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.7.1.tgz", - "integrity": "sha512-DVCF76i9wM93DrPQwLrYiCw/UzxFuofBsuxTVugrnbm0SzucajLLNftp3ITK0c4/lV3x9oo5ER/wD6RRMHQnvw==", + "node_modules/web3-core-subscriptions": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.10.4.tgz", + "integrity": "sha512-o0lSQo/N/f7/L76C0HV63+S54loXiE9fUPfHFcTtpJRQNDBVsSDdWRdePbWwR206XlsBqD5VHApck1//jEafTw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "content-hash": "^2.5.2", - "eth-ens-namehash": "2.0.8", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-promievent": "1.7.1", - "web3-eth-abi": "1.7.1", - "web3-eth-contract": "1.7.1", - "web3-utils": "1.7.1" + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-ens/node_modules/@ethersproject/abi": { + "node_modules/web3-core-subscriptions/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core-subscriptions/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core/node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/web3-core/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-core/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.10.4.tgz", + "integrity": "sha512-Sql2kYKmgt+T/cgvg7b9ce24uLS7xbFrxE4kuuor1zSCGrjhTJ5rRNG8gTJUkAJGKJc7KgnWmgW+cOfMBPUDSA==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-eth-accounts": "1.10.4", + "web3-eth-contract": "1.10.4", + "web3-eth-ens": "1.10.4", + "web3-eth-iban": "1.10.4", + "web3-eth-personal": "1.10.4", + "web3-net": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.5.3.tgz", + "integrity": "sha512-i/qhuFsoNrnV130CSRYX/z4SlCfSQ4mHntti5yTmmQpt70xZKYZ57BsU0R29ueSQ9/P+aQrL2t2rqkQkAloUxg==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", @@ -23482,361 +24000,1925 @@ "@ethersproject/strings": "^5.0.4" } }, - "node_modules/web3-eth-ens/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", - "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "node_modules/web3-eth-abi/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-abi/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.10.4.tgz", + "integrity": "sha512-ysy5sVTg9snYS7tJjxVoQAH6DTOTkRGR8emEVCWNGLGiB9txj+qDvSeT0izjurS/g7D5xlMAgrEHLK1Vi6I3yg==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/common": "2.6.5", + "@ethereumjs/tx": "3.5.2", + "@ethereumjs/util": "^8.1.0", + "eth-lib": "0.2.8", + "scrypt-js": "^3.0.1", + "uuid": "^9.0.0", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/web3-eth-iban/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-contract": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.10.4.tgz", + "integrity": "sha512-Q8PfolOJ4eV9TvnTj1TGdZ4RarpSLmHnUnzVxZ/6/NiTfe4maJz99R0ISgwZkntLhLRtw0C7LRJuklzGYCNN3A==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/bn.js": "^5.1.1", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-contract/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-contract/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/web3-eth-contract/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-contract/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-eth-abi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-contract/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.10.4.tgz", + "integrity": "sha512-LLrvxuFeVooRVZ9e5T6OWKVflHPFgrVjJ/jtisRWcmI7KN/b64+D/wJzXqgmp6CNsMQcE7rpmf4CQmJCrTdsgg==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-eth-contract": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth-ens/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-ens/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/web3-eth-ens/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-ens/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-eth-abi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, - "node_modules/web3-eth-ens/node_modules/web3-core-promievent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.7.1.tgz", - "integrity": "sha512-Vd+CVnpPejrnevIdxhCkzMEywqgVbhHk/AmXXceYpmwA6sX41c5a65TqXv1i3FWRJAz/dW7oKz9NAzRIBAO/kA==", + "node_modules/web3-eth-iban": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", + "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "web3-utils": "1.5.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-iban/node_modules/web3-utils": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", + "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "eth-lib": "0.2.8", + "ethereum-bloom-filters": "^1.0.6", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.10.4.tgz", + "integrity": "sha512-BRa/hs6jU1hKHz+AC/YkM71RP3f0Yci1dPk4paOic53R4ZZG4MgwKRkJhgt3/GPuPliwS46f/i5A7fEGBT4F9w==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-net": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-personal/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-eth-personal/node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/web3-eth/node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/web3-eth/node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "eventemitter3": "4.0.4" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-ens/node_modules/web3-eth-abi": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", - "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "node_modules/web3-eth/node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-ens/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-eth/node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-iban": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.5.3.tgz", - "integrity": "sha512-vMzmGqolYZvRHwP9P4Nf6G8uYM5aTLlQu2a34vz78p0KlDC+eV1th3+90Qeaupa28EG7OO0IT1F0BejiIauOPw==", + "node_modules/web3-eth/node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.5.3" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" } }, - "node_modules/web3-eth-iban/node_modules/eth-lib": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", - "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "node_modules/web3-eth/node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, - "node_modules/web3-eth-iban/node_modules/web3-utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.5.3.tgz", - "integrity": "sha512-56nRgA+Ad9SEyCv39g36rTcr5fpsd4L9LgV3FK0aB66nAMazLAA6Qz4lH5XrUKPDyBIPGJIR+kJsyRtwcu2q1Q==", + "node_modules/web3-eth/node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "eth-lib": "0.2.8", - "ethereum-bloom-filters": "^1.0.6", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" } }, - "node_modules/web3-eth-personal": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.7.1.tgz", - "integrity": "sha512-02H6nFBNfNmFjMGZL6xcDi0r7tUhxrUP91FTFdoLyR94eIJDadPp4rpXfG7MVES873i1PReh4ep5pSCHbc3+Pg==", + "node_modules/web3-eth/node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", "dependencies": { - "@types/node": "^12.12.6", - "web3-core": "1.7.1", - "web3-core-helpers": "1.7.1", - "web3-core-method": "1.7.1", - "web3-net": "1.7.1", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, - "node_modules/web3-eth-personal/node_modules/@types/node": { - "version": "12.20.47", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.47.tgz", - "integrity": "sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg==", - "dev": true - }, - "node_modules/web3-eth-personal/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "node_modules/web3-eth/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", "dev": true, - "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" - } + "license": "MIT" }, - "node_modules/web3-eth-personal/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "node_modules/web3-eth/node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", "dev": true, + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", - "web3-utils": "1.7.1" - }, - "engines": { - "node": ">=8.0.0" + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/web3-eth/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "node_modules/web3-eth/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", "dev": true, - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } + "license": "MIT" }, "node_modules/web3-eth/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-eth/node_modules/web3-eth-abi": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", - "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.7.1" + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-eth/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-net": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.7.1.tgz", - "integrity": "sha512-8yPNp2gvjInWnU7DCoj4pIPNhxzUjrxKlODsyyXF8j0q3Z2VZuQp+c63gL++r2Prg4fS8t141/HcJw4aMu5sVA==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.10.4.tgz", + "integrity": "sha512-mKINnhOOnZ4koA+yV2OT5s5ztVjIx7IY9a03w6s+yao/BUn+Luuty0/keNemZxTr1E8Ehvtn28vbOtW7Ids+Ow==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core": "1.7.1", - "web3-core-method": "1.7.1", - "web3-utils": "1.7.1" + "web3-core": "1.10.4", + "web3-core-method": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-http": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.7.1.tgz", - "integrity": "sha512-dmiO6G4dgAa3yv+2VD5TduKNckgfR97VI9YKXVleWdcpBoKXe2jofhdvtafd42fpIoaKiYsErxQNcOC5gI/7Vg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.10.4.tgz", + "integrity": "sha512-m2P5Idc8hdiO0l60O6DSCPw0kw64Zgi0pMjbEFRmxKIck2Py57RQMu4bxvkxJwkF06SlGaEQF8rFZBmuX7aagQ==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core-helpers": "1.7.1", - "xhr2-cookies": "1.1.0" + "abortcontroller-polyfill": "^1.7.5", + "cross-fetch": "^4.0.0", + "es6-promise": "^4.2.8", + "web3-core-helpers": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, + "node_modules/web3-providers-http/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, "node_modules/web3-providers-http/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-http/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ipc": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.7.1.tgz", - "integrity": "sha512-uNgLIFynwnd5M9ZC0lBvRQU5iLtU75hgaPpc7ZYYR+kjSk2jr2BkEAQhFVJ8dlqisrVmmqoAPXOEU0flYZZgNQ==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.10.4.tgz", + "integrity": "sha512-YRF/bpQk9z3WwjT+A6FI/GmWRCASgd+gC0si7f9zbBWLXjwzYAKG73bQBaFRAHex1hl4CVcM5WUMaQXf3Opeuw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { "oboe": "2.1.5", - "web3-core-helpers": "1.7.1" + "web3-core-helpers": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, + "node_modules/web3-providers-ipc/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, "node_modules/web3-providers-ipc/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ipc/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ws": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.7.1.tgz", - "integrity": "sha512-Uj0n5hdrh0ESkMnTQBsEUS2u6Unqdc7Pe4Zl+iZFb7Yn9cIGsPJBl7/YOP4137EtD5ueXAv+MKwzcelpVhFiFg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.10.4.tgz", + "integrity": "sha512-j3FBMifyuFFmUIPVQR4pj+t5ILhAexAui0opgcpu9R5LxQrLRUZxHSnU+YO25UycSOa/NAX8A+qkqZNpcFAlxA==", "dev": true, + "license": "LGPL-3.0", "dependencies": { "eventemitter3": "4.0.4", - "web3-core-helpers": "1.7.1", + "web3-core-helpers": "1.10.4", "websocket": "^1.0.32" }, "engines": { "node": ">=8.0.0" } }, + "node_modules/web3-providers-ws/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, "node_modules/web3-providers-ws/node_modules/web3-core-helpers": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.7.1.tgz", - "integrity": "sha512-xn7Sx+s4CyukOJdlW8bBBDnUCWndr+OCJAlUe/dN2wXiyaGRiCWRhuQZrFjbxLeBt1fYFH7uWyYHhYU6muOHgw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "web3-eth-iban": "1.7.1", - "web3-utils": "1.7.1" + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-providers-ws/node_modules/web3-eth-iban": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.7.1.tgz", - "integrity": "sha512-XG4I3QXuKB/udRwZdNEhdYdGKjkhfb/uH477oFVMLBqNimU/Cw8yXUI5qwFKvBHM+hMQWfzPDuSDEDKC2uuiMg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", - "web3-utils": "1.7.1" + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-shh": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.7.1.tgz", - "integrity": "sha512-NO+jpEjo8kYX6c7GiaAm57Sx93PLYkWYUCWlZmUOW7URdUcux8VVluvTWklGPvdM9H1WfDrol91DjuSW+ykyqg==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.10.4.tgz", + "integrity": "sha512-cOH6iFFM71lCNwSQrC3niqDXagMqrdfFW85hC9PFUrAr3PUrIem8TNstTc3xna2bwZeWG6OBy99xSIhBvyIACw==", "dev": true, "hasInstallScript": true, + "license": "LGPL-3.0", "dependencies": { - "web3-core": "1.7.1", - "web3-core-method": "1.7.1", - "web3-core-subscriptions": "1.7.1", - "web3-net": "1.7.1" + "web3-core": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-net": "1.10.4" }, "engines": { "node": ">=8.0.0" } }, "node_modules/web3-utils": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.1.tgz", - "integrity": "sha512-fef0EsqMGJUgiHPdX+KN9okVWshbIumyJPmR+btnD1HgvoXijKEkuKBv0OmUqjbeqmLKP2/N9EiXKJel5+E1Dw==", + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", "dev": true, + "license": "LGPL-3.0", "dependencies": { - "bn.js": "^4.11.9", + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", + "ethereum-cryptography": "^2.1.2", "ethjs-unit": "0.1.6", "number-to-bn": "1.7.0", "randombytes": "^2.1.0", @@ -23846,6 +25928,78 @@ "node": ">=8.0.0" } }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/third_party/move/extensions/async/move-async-vm/Cargo.toml b/third_party/move/extensions/async/move-async-vm/Cargo.toml index e26411780b9..4546557fa27 100644 --- a/third_party/move/extensions/async/move-async-vm/Cargo.toml +++ b/third_party/move/extensions/async/move-async-vm/Cargo.toml @@ -17,7 +17,9 @@ move-binary-format = { path = "../../../move-binary-format" } move-command-line-common = { path = "../../../move-command-line-common" } move-compiler = { path = "../../../move-compiler" } move-core-types = { path = "../../../move-core/types" } -move-vm-runtime = { path = "../../../move-vm/runtime", features = ["debugging"] } +move-vm-runtime = { path = "../../../move-vm/runtime", features = [ + "debugging", +] } move-vm-test-utils = { path = "../../../move-vm/test-utils" } move-vm-types = { path = "../../../move-vm/types" } sha3 = { workspace = true } diff --git a/third_party/move/extensions/move-table-extension/Cargo.toml b/third_party/move/extensions/move-table-extension/Cargo.toml index 1dee926a611..7dbaa3a4cd7 100644 --- a/third_party/move/extensions/move-table-extension/Cargo.toml +++ b/third_party/move/extensions/move-table-extension/Cargo.toml @@ -22,5 +22,7 @@ smallvec = { workspace = true } move-cli = { path = "../../tools/move-cli" } move-package = { path = "../../tools/move-package" } move-stdlib = { path = "../../move-stdlib", features = ["testing"] } -move-unit-test = { path = "../../tools/move-unit-test", features = ["table-extension"] } +move-unit-test = { path = "../../tools/move-unit-test", features = [ + "table-extension", +] } tempfile = { workspace = true } diff --git a/third_party/move/move-binary-format/Cargo.toml b/third_party/move/move-binary-format/Cargo.toml index eac71298e66..4cce56ee747 100644 --- a/third_party/move/move-binary-format/Cargo.toml +++ b/third_party/move/move-binary-format/Cargo.toml @@ -30,5 +30,10 @@ serde_json = { workspace = true } [features] default = [] -fuzzing = ["proptest", "proptest-derive", "arbitrary", "move-core-types/fuzzing"] +fuzzing = [ + "proptest", + "proptest-derive", + "arbitrary", + "move-core-types/fuzzing", +] testing = [] diff --git a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml index 4e5c437cddf..edce5afabff 100644 --- a/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml +++ b/third_party/move/move-bytecode-verifier/bytecode-verifier-tests/Cargo.toml @@ -13,7 +13,9 @@ edition = "2021" fail = { workspace = true, features = ['failpoints'] } hex = { workspace = true } invalid-mutations = { path = "../invalid-mutations" } -move-binary-format = { path = "../../move-binary-format", features = ["fuzzing"] } +move-binary-format = { path = "../../move-binary-format", features = [ + "fuzzing", +] } move-bytecode-verifier = { path = "../" } move-core-types = { path = "../../move-core/types" } petgraph = { workspace = true } diff --git a/third_party/move/move-bytecode-verifier/fuzz/Cargo.toml b/third_party/move/move-bytecode-verifier/fuzz/Cargo.toml index c89658cc77f..5eb1bdb8259 100644 --- a/third_party/move/move-bytecode-verifier/fuzz/Cargo.toml +++ b/third_party/move/move-bytecode-verifier/fuzz/Cargo.toml @@ -12,7 +12,9 @@ cargo-fuzz = true [dependencies] arbitrary = { workspace = true } libfuzzer-sys = { workspace = true } -move-binary-format = { path = "../../move-binary-format", features = ["fuzzing"] } +move-binary-format = { path = "../../move-binary-format", features = [ + "fuzzing", +] } move-bytecode-verifier = { path = "../" } move-core-types = { path = "../../move-core/types", features = ["fuzzing"] } # Prevent this from interfering with workspaces diff --git a/third_party/move/move-core/types/Cargo.toml b/third_party/move/move-core/types/Cargo.toml index 591721a9079..3efc4a5a98c 100644 --- a/third_party/move/move-core/types/Cargo.toml +++ b/third_party/move/move-core/types/Cargo.toml @@ -11,7 +11,9 @@ edition = "2021" [dependencies] anyhow = { workspace = true } -arbitrary = { workspace = true, features = ["derive_arbitrary"], optional = true } +arbitrary = { workspace = true, features = [ + "derive_arbitrary", +], optional = true } bcs = { workspace = true } bytes = { workspace = true } ethnum = { workspace = true } diff --git a/third_party/move/move-core/types/src/vm_status.rs b/third_party/move/move-core/types/src/vm_status.rs index e02d1d675da..77afbb355f3 100644 --- a/third_party/move/move-core/types/src/vm_status.rs +++ b/third_party/move/move-core/types/src/vm_status.rs @@ -609,7 +609,26 @@ pub enum StatusCode { // Gas unit price capacity submitted for the automation-task is above the maximum // gas price set in the VM. AUTOMATION_TASK_GAS_PRICE_CAP_ABOVE_MAX_BOUND = 50, - + // DKG session is currently not in progress + DKG_SESSION_NOT_IN_PROGRESS = 51, + // DKG transaction has a future epoch number + DKG_TRANSACTION_FUTURE_EPOCH_NUM = 52, + // DKG transaction has a past epoch number + DKG_TRANSACTION_PAST_EPOCH_NUM = 53, + // DKG meta has already set so DKGMeta transaction should fail + DKG_META_ALREADY_SET = 54, + // DKG transaction data is invalid + DKG_TRANSACTION_NOT_VALID = 55, + // The sender of the dkg transaction is not a family node + DKG_TRANSACTION_SENDER_NOT_FAMILY_NODE = 56, + // Failed to get the public keys for the signer clan nodes + DKG_FAILED_TO_GET_CLAN_NODE_PUBKEYS = 57, + // Failed to deserialize the aggregated signature + DKG_FAILED_TO_DESER_AGG_SIG = 58, + // Failed to aggregate the public keys for the signer clan nodes + DKG_FAILED_TO_AGGREGATE_PUBLIC_KEYS = 59, + // Failed to verify the clan committee aggregated signature + DKG_AGG_SIG_VERIFICATION_FAILED = 60, // When a code module/script is published it is verified. These are the // possible errors that can arise from the verification process. // Verification Errors: 1000-1999 diff --git a/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml b/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml index 7c07613b50b..07bebc1b124 100644 --- a/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml +++ b/third_party/move/move-examples/diem-framework/crates/crypto/Cargo.toml @@ -10,10 +10,15 @@ license = "Apache-2.0" aes-gcm = { workspace = true } anyhow = { workspace = true } bytes = { workspace = true } -curve25519-dalek = { workspace = true, package = "curve25519-dalek-fiat", features = ["std"] } +curve25519-dalek = { workspace = true, package = "curve25519-dalek-fiat", features = [ + "std", +] } diem-crypto-derive = { path = "../crypto-derive" } digest = { workspace = true } -ed25519-dalek = { workspace = true, package = "ed25519-dalek-fiat", features = ["std", "serde"] } +ed25519-dalek = { workspace = true, package = "ed25519-dalek-fiat", features = [ + "std", + "serde", +] } hex = { workspace = true } hkdf = { workspace = true } mirai-annotations = { workspace = true } @@ -28,7 +33,9 @@ sha2 = { workspace = true } static_assertions = { workspace = true } thiserror = { workspace = true } tiny-keccak = { workspace = true, features = ["sha3"] } -x25519-dalek = { workspace = true, package = "x25519-dalek-fiat", features = ["std"] } +x25519-dalek = { workspace = true, package = "x25519-dalek-fiat", features = [ + "std", +] } bcs = { workspace = true } @@ -49,9 +56,21 @@ default = ["fiat"] assert-private-keys-not-cloneable = [] cloneable-private-keys = [] fuzzing = ["proptest", "proptest-derive", "cloneable-private-keys"] -fiat = ["curve25519-dalek/fiat_u64_backend", "ed25519-dalek/fiat_u64_backend", "x25519-dalek/fiat_u64_backend"] -u64 = ["curve25519-dalek/u64_backend", "ed25519-dalek/u64_backend", "x25519-dalek/u64_backend"] -u32 = ["curve25519-dalek/u32_backend", "ed25519-dalek/u32_backend", "x25519-dalek/u32_backend"] +fiat = [ + "curve25519-dalek/fiat_u64_backend", + "ed25519-dalek/fiat_u64_backend", + "x25519-dalek/fiat_u64_backend", +] +u64 = [ + "curve25519-dalek/u64_backend", + "ed25519-dalek/u64_backend", + "x25519-dalek/u64_backend", +] +u32 = [ + "curve25519-dalek/u32_backend", + "ed25519-dalek/u32_backend", + "x25519-dalek/u32_backend", +] [[bench]] name = "noise" diff --git a/third_party/move/move-prover/lab/Cargo.toml b/third_party/move/move-prover/lab/Cargo.toml index 58d250941eb..95e949f5b62 100644 --- a/third_party/move/move-prover/lab/Cargo.toml +++ b/third_party/move/move-prover/lab/Cargo.toml @@ -25,7 +25,7 @@ codespan-reporting = { workspace = true } itertools = { workspace = true } log = { workspace = true, features = ["serde"] } plotters = { workspace = true, features = [ - "evcxr", - "line_series", - "histogram", + "evcxr", + "line_series", + "histogram", ] } diff --git a/third_party/move/move-prover/lab/data/aptos-framework/prover.toml b/third_party/move/move-prover/lab/data/aptos-framework/prover.toml index a2468e645a5..6537a808ccf 100644 --- a/third_party/move/move-prover/lab/data/aptos-framework/prover.toml +++ b/third_party/move/move-prover/lab/data/aptos-framework/prover.toml @@ -1,14 +1,14 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/diem-framework/prover.toml b/third_party/move/move-prover/lab/data/diem-framework/prover.toml index 5c0fe4c002f..b990557b1d6 100644 --- a/third_party/move/move-prover/lab/data/diem-framework/prover.toml +++ b/third_party/move/move-prover/lab/data/diem-framework/prover.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "DiemFramework=0x1", - "DiemRoot=0xA550C18", - "TreasuryCompliance=0xB1E55ED", - "CurrencyInfo=0xA550C18", - "VMReserved=0x0", + "std=0x1", + "DiemFramework=0x1", + "DiemRoot=0xA550C18", + "TreasuryCompliance=0xB1E55ED", + "CurrencyInfo=0xA550C18", + "VMReserved=0x0", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/mono/mono_backend.toml b/third_party/move/move-prover/lab/data/mono/mono_backend.toml index e69de29bb2d..8b137891791 100644 --- a/third_party/move/move-prover/lab/data/mono/mono_backend.toml +++ b/third_party/move/move-prover/lab/data/mono/mono_backend.toml @@ -0,0 +1 @@ + diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_1.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_1.toml index a2468e645a5..6537a808ccf 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_1.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_1.toml @@ -1,14 +1,14 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_2.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_2.toml index a2468e645a5..6537a808ccf 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_2.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_2.toml @@ -1,14 +1,14 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_3.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_3.toml index a2468e645a5..6537a808ccf 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_3.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/current_boogie_3.toml @@ -1,14 +1,14 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_1.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_1.toml index a2468e645a5..6537a808ccf 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_1.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_1.toml @@ -1,14 +1,14 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_2.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_2.toml index a2468e645a5..6537a808ccf 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_2.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_2.toml @@ -1,14 +1,14 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_3.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_3.toml index a2468e645a5..6537a808ccf 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_3.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-framework/new_boogie_3.toml @@ -1,14 +1,14 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-framework/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-framework/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_1.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_1.toml index beb39012e9e..d215563a2d2 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_1.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_1.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_2.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_2.toml index beb39012e9e..d215563a2d2 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_2.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_2.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_3.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_3.toml index beb39012e9e..d215563a2d2 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_3.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/current_boogie_3.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_1.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_1.toml index beb39012e9e..d215563a2d2 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_1.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_1.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_2.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_2.toml index beb39012e9e..d215563a2d2 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_2.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_2.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_3.toml b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_3.toml index beb39012e9e..d215563a2d2 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_3.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-aptos-stdlib/new_boogie_3.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "aptos_std=0x1", - "aptos_framework=0x1", - "aptos_token=0x3", - "core_resources=0xA550C18", - "vm_reserved=0x0", - "Extensions=0x1", + "std=0x1", + "aptos_std=0x1", + "aptos_framework=0x1", + "aptos_token=0x3", + "core_resources=0xA550C18", + "vm_reserved=0x0", + "Extensions=0x1", ] move_deps = [ - "../../../../../../aptos-move/framework/move-stdlib/sources", - "../../../../../../aptos-move/framework/aptos-stdlib/sources", + "../../../../../../aptos-move/framework/move-stdlib/sources", + "../../../../../../aptos-move/framework/aptos-stdlib/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/current_boogie.toml b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/current_boogie.toml index 394a15e27d7..46c347b222b 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/current_boogie.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/current_boogie.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "DiemFramework=0x1", - "DiemRoot=0xA550C18", - "TreasuryCompliance=0xB1E55ED", - "CurrencyInfo=0xA550C18", - "VMReserved=0x0", + "std=0x1", + "DiemFramework=0x1", + "DiemRoot=0xA550C18", + "TreasuryCompliance=0xB1E55ED", + "CurrencyInfo=0xA550C18", + "VMReserved=0x0", ] move_deps = [ - "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", - "../../../../move-stdlib/sources", - "../../../../move-stdlib/nursery/sources", + "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", + "../../../../move-stdlib/sources", + "../../../../move-stdlib/nursery/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie.toml b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie.toml index 394a15e27d7..46c347b222b 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "DiemFramework=0x1", - "DiemRoot=0xA550C18", - "TreasuryCompliance=0xB1E55ED", - "CurrencyInfo=0xA550C18", - "VMReserved=0x0", + "std=0x1", + "DiemFramework=0x1", + "DiemRoot=0xA550C18", + "TreasuryCompliance=0xB1E55ED", + "CurrencyInfo=0xA550C18", + "VMReserved=0x0", ] move_deps = [ - "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", - "../../../../move-stdlib/sources", - "../../../../move-stdlib/nursery/sources", + "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", + "../../../../move-stdlib/sources", + "../../../../move-stdlib/nursery/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_1.toml b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_1.toml index 394a15e27d7..46c347b222b 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_1.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_1.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "DiemFramework=0x1", - "DiemRoot=0xA550C18", - "TreasuryCompliance=0xB1E55ED", - "CurrencyInfo=0xA550C18", - "VMReserved=0x0", + "std=0x1", + "DiemFramework=0x1", + "DiemRoot=0xA550C18", + "TreasuryCompliance=0xB1E55ED", + "CurrencyInfo=0xA550C18", + "VMReserved=0x0", ] move_deps = [ - "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", - "../../../../move-stdlib/sources", - "../../../../move-stdlib/nursery/sources", + "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", + "../../../../move-stdlib/sources", + "../../../../move-stdlib/nursery/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_2.toml b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_2.toml index 394a15e27d7..46c347b222b 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_2.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_2.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "DiemFramework=0x1", - "DiemRoot=0xA550C18", - "TreasuryCompliance=0xB1E55ED", - "CurrencyInfo=0xA550C18", - "VMReserved=0x0", + "std=0x1", + "DiemFramework=0x1", + "DiemRoot=0xA550C18", + "TreasuryCompliance=0xB1E55ED", + "CurrencyInfo=0xA550C18", + "VMReserved=0x0", ] move_deps = [ - "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", - "../../../../move-stdlib/sources", - "../../../../move-stdlib/nursery/sources", + "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", + "../../../../move-stdlib/sources", + "../../../../move-stdlib/nursery/sources", ] diff --git a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_3.toml b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_3.toml index 394a15e27d7..46c347b222b 100644 --- a/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_3.toml +++ b/third_party/move/move-prover/lab/data/new-boogie-diem-framework/new_boogie_3.toml @@ -1,13 +1,13 @@ move_named_address_values = [ - "std=0x1", - "DiemFramework=0x1", - "DiemRoot=0xA550C18", - "TreasuryCompliance=0xB1E55ED", - "CurrencyInfo=0xA550C18", - "VMReserved=0x0", + "std=0x1", + "DiemFramework=0x1", + "DiemRoot=0xA550C18", + "TreasuryCompliance=0xB1E55ED", + "CurrencyInfo=0xA550C18", + "VMReserved=0x0", ] move_deps = [ - "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", - "../../../../move-stdlib/sources", - "../../../../move-stdlib/nursery/sources", + "../../../../documentation/examples/diem-framework/move-packages/DPN/sources", + "../../../../move-stdlib/sources", + "../../../../move-stdlib/nursery/sources", ] diff --git a/third_party/move/move-prover/lab/data/test/prover_stdlib.toml b/third_party/move/move-prover/lab/data/test/prover_stdlib.toml index 793c70611ff..5177472aa2d 100644 --- a/third_party/move/move-prover/lab/data/test/prover_stdlib.toml +++ b/third_party/move/move-prover/lab/data/test/prover_stdlib.toml @@ -1,5 +1,5 @@ move_named_address_values = ["std=0x1"] move_deps = [ - "../../../../move-stdlib/sources", - "../../../../move-stdlib/nursery/sources", + "../../../../move-stdlib/sources", + "../../../../move-stdlib/nursery/sources", ] diff --git a/third_party/move/move-vm/integration-tests/Cargo.toml b/third_party/move/move-vm/integration-tests/Cargo.toml index 99a7339b945..7065a370cf4 100644 --- a/third_party/move/move-vm/integration-tests/Cargo.toml +++ b/third_party/move/move-vm/integration-tests/Cargo.toml @@ -14,7 +14,9 @@ edition = "2021" anyhow = { workspace = true } bytes = { workspace = true } memory-stats = { workspace = true } -move-binary-format = { path = "../../move-binary-format", features = ["testing"] } +move-binary-format = { path = "../../move-binary-format", features = [ + "testing", +] } move-bytecode-verifier = { path = "../../move-bytecode-verifier" } move-compiler = { path = "../../move-compiler" } smallvec = { workspace = true } @@ -28,6 +30,4 @@ move-vm-types = { path = "../types" } [features] default = [] -table-extension = [ - "move-vm-test-utils/table-extension" -] +table-extension = ["move-vm-test-utils/table-extension"] diff --git a/third_party/move/move-vm/paranoid-tests/Cargo.toml b/third_party/move/move-vm/paranoid-tests/Cargo.toml index bf4e6bb0868..1c9de8dfc09 100644 --- a/third_party/move/move-vm/paranoid-tests/Cargo.toml +++ b/third_party/move/move-vm/paranoid-tests/Cargo.toml @@ -9,7 +9,9 @@ license = "Apache-2.0" [dev-dependencies] datatest-stable = { workspace = true } fail = { workspace = true, features = ['failpoints'] } -move-transactional-test-runner = { path = "../../testing-infra/transactional-test-runner", features = ['failpoints'] } +move-transactional-test-runner = { path = "../../testing-infra/transactional-test-runner", features = [ + 'failpoints', +] } [[test]] name = "tests" diff --git a/third_party/move/move-vm/types/Cargo.toml b/third_party/move/move-vm/types/Cargo.toml index 4952f0cdf0b..af9555b939c 100644 --- a/third_party/move/move-vm/types/Cargo.toml +++ b/third_party/move/move-vm/types/Cargo.toml @@ -25,7 +25,9 @@ move-core-types = { path = "../../move-core/types" } [dev-dependencies] claims = { workspace = true } -move-binary-format = { path = "../../move-binary-format", features = ["fuzzing"] } +move-binary-format = { path = "../../move-binary-format", features = [ + "fuzzing", +] } proptest = { workspace = true } rand = { workspace = true } diff --git a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml index 4c534c46f03..d2a9dd87caf 100644 --- a/third_party/move/testing-infra/transactional-test-runner/Cargo.toml +++ b/third_party/move/testing-infra/transactional-test-runner/Cargo.toml @@ -12,7 +12,9 @@ edition = "2021" [dependencies] anyhow = { workspace = true } clap = { workspace = true, features = ["derive"] } -move-binary-format = { path = "../../move-binary-format", features = ["testing"] } +move-binary-format = { path = "../../move-binary-format", features = [ + "testing", +] } move-bytecode-source-map = { path = "../../move-ir-compiler/move-bytecode-source-map" } move-bytecode-verifier = { path = "../../move-bytecode-verifier" } move-command-line-common = { path = "../../move-command-line-common" } diff --git a/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename/Move.toml b/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename/Move.toml index a13ae9d9e4f..0a037bf8dfd 100644 --- a/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename/Move.toml @@ -6,5 +6,5 @@ version = "0.0.0" A = "0x3" [dependencies] -C = { local = "./deps_only/C", addr_subst = {"CA" = "A" } } -D = { local = "./deps_only/D" , addr_subst = {"DA" = "A" } } +C = { local = "./deps_only/C", addr_subst = { "CA" = "A" } } +D = { local = "./deps_only/D", addr_subst = { "DA" = "A" } } diff --git a/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename_one/Move.toml b/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename_one/Move.toml index 423f3f880f1..70a39f3ee65 100644 --- a/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename_one/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/compilation/multiple_deps_rename_one/Move.toml @@ -9,4 +9,4 @@ A = "0x1" [dependencies] C = { local = "./deps_only/C" } -D = { local = "./deps_only/D" , addr_subst = {"DA" = "A" } } +D = { local = "./deps_only/D", addr_subst = { "DA" = "A" } } diff --git a/third_party/move/tools/move-package/tests/test_sources/model/multiple_deps_rename/Move.toml b/third_party/move/tools/move-package/tests/test_sources/model/multiple_deps_rename/Move.toml index a13ae9d9e4f..0a037bf8dfd 100644 --- a/third_party/move/tools/move-package/tests/test_sources/model/multiple_deps_rename/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/model/multiple_deps_rename/Move.toml @@ -6,5 +6,5 @@ version = "0.0.0" A = "0x3" [dependencies] -C = { local = "./deps_only/C", addr_subst = {"CA" = "A" } } -D = { local = "./deps_only/D" , addr_subst = {"DA" = "A" } } +C = { local = "./deps_only/C", addr_subst = { "CA" = "A" } } +D = { local = "./deps_only/D", addr_subst = { "DA" = "A" } } diff --git a/third_party/move/tools/move-package/tests/test_sources/parsing/no_path_set_for_dependency/Move.toml b/third_party/move/tools/move-package/tests/test_sources/parsing/no_path_set_for_dependency/Move.toml index dbd55273608..ff10e27d5d6 100644 --- a/third_party/move/tools/move-package/tests/test_sources/parsing/no_path_set_for_dependency/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/parsing/no_path_set_for_dependency/Move.toml @@ -3,4 +3,4 @@ name = "name" version = "0.1.2" [dependencies] -A = { } +A = {} diff --git a/third_party/move/tools/move-package/tests/test_sources/parsing/non_identifier_address_name_in_subst/Move.toml b/third_party/move/tools/move-package/tests/test_sources/parsing/non_identifier_address_name_in_subst/Move.toml index 8b78acf0abc..bf549e92df8 100644 --- a/third_party/move/tools/move-package/tests/test_sources/parsing/non_identifier_address_name_in_subst/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/parsing/non_identifier_address_name_in_subst/Move.toml @@ -3,4 +3,4 @@ name = "name" version = "0.1.2" [dependencies] -A = { local = "a", addr_subst = { "©" = "A" } } +A = { local = "a", addr_subst = { "©" = "A" } } diff --git a/third_party/move/tools/move-package/tests/test_sources/resolution/dep_good_digest/Move.toml b/third_party/move/tools/move-package/tests/test_sources/resolution/dep_good_digest/Move.toml index adfaac538f7..1cf7c5aea30 100644 --- a/third_party/move/tools/move-package/tests/test_sources/resolution/dep_good_digest/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/resolution/dep_good_digest/Move.toml @@ -6,4 +6,4 @@ version = "0.0.0" A = "0x1" [dependencies] -OtherDep = { local = "./deps_only/other_dep", addr_subst = { "A" = "B" }, digest = "6A88B7888D6049EB0121900E22B6FA2C0E702F042C8C8D4FD62AD5C990B9F9A8"} +OtherDep = { local = "./deps_only/other_dep", addr_subst = { "A" = "B" }, digest = "6A88B7888D6049EB0121900E22B6FA2C0E702F042C8C8D4FD62AD5C990B9F9A8" } diff --git a/third_party/move/tools/move-package/tests/test_sources/resolution/multiple_deps_rename/Move.toml b/third_party/move/tools/move-package/tests/test_sources/resolution/multiple_deps_rename/Move.toml index 6bac3c7efc8..292d9a37375 100644 --- a/third_party/move/tools/move-package/tests/test_sources/resolution/multiple_deps_rename/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/resolution/multiple_deps_rename/Move.toml @@ -3,5 +3,5 @@ name = "test" version = "0.0.0" [dependencies] -C = { local = "./deps_only/C", addr_subst = {"CA" = "A" } } -D = { local = "./deps_only/D" , addr_subst = {"DA" = "A" } } +C = { local = "./deps_only/C", addr_subst = { "CA" = "A" } } +D = { local = "./deps_only/D", addr_subst = { "DA" = "A" } } diff --git a/third_party/move/tools/move-package/tests/test_sources/resolution/one_dep_bad_digest/Move.toml b/third_party/move/tools/move-package/tests/test_sources/resolution/one_dep_bad_digest/Move.toml index bb8f33a3b75..7048f57b13f 100644 --- a/third_party/move/tools/move-package/tests/test_sources/resolution/one_dep_bad_digest/Move.toml +++ b/third_party/move/tools/move-package/tests/test_sources/resolution/one_dep_bad_digest/Move.toml @@ -6,4 +6,4 @@ version = "0.0.0" A = "0x1" [dependencies] -OtherDep = { local = "./deps_only/other_dep", addr_subst = { "A" = "B" }, digest = "BAD_DIGEST"} +OtherDep = { local = "./deps_only/other_dep", addr_subst = { "A" = "B" }, digest = "BAD_DIGEST" } diff --git a/third_party/move/tools/move-unit-test/Cargo.toml b/third_party/move/tools/move-unit-test/Cargo.toml index 3bd0fbfd08a..e8bee74f5dc 100644 --- a/third_party/move/tools/move-unit-test/Cargo.toml +++ b/third_party/move/tools/move-unit-test/Cargo.toml @@ -54,7 +54,5 @@ harness = false [features] evm-backend = ["move-to-yul", "evm-exec-utils", "evm", "primitive-types"] -table-extension = [ - "move-vm-test-utils/table-extension" -] +table-extension = ["move-vm-test-utils/table-extension"] debugging = ["move-vm-runtime/debugging"] diff --git a/types/Cargo.toml b/types/Cargo.toml index b25532ea0d7..08e1be587d0 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -29,6 +29,7 @@ base64 = { workspace = true } bcs = { workspace = true } bytes = { workspace = true } derive-getters = { workspace = true } +crypto = { workspace = true } fixed = { workspace = true } fxhash = { workspace = true } hashbrown = { workspace = true } @@ -65,6 +66,11 @@ strum = { workspace = true } strum_macros = { workspace = true } thiserror = { workspace = true } derive_more = { workspace = true } +utoipa = { features = [ + "non_strict_integers", + "preserve_order", + "uuid", +], optional = true, workspace = true } [dev-dependencies] ahash = { workspace = true } @@ -90,7 +96,13 @@ url = { workspace = true } [features] default = [] -fuzzing = ["proptest", "proptest-derive", "aptos-crypto/fuzzing", "move-core-types/fuzzing"] +fuzzing = [ + "proptest", + "proptest-derive", + "aptos-crypto/fuzzing", + "move-core-types/fuzzing", +] +rest_api_schema = ["utoipa"] [[bench]] name = "keyless" diff --git a/types/src/account_config/events/coin.rs b/types/src/account_config/events/coin.rs index 46761d1f56b..96d2af6c3e8 100644 --- a/types/src/account_config/events/coin.rs +++ b/types/src/account_config/events/coin.rs @@ -1,9 +1,13 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use derive_getters::Getters; use move_core_types::{ - account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, move_resource::MoveStructType, parser::parse_type_tag + account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, + move_resource::MoveStructType, parser::parse_type_tag, }; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; -use derive_getters::Getters; pub static COIN_WITHDRAW_EVENT_TYPE_TAG: Lazy = Lazy::new(|| TypeTag::Struct(Box::new(CoinWithdraw::struct_tag()))); pub static COIN_DEPOSIT_EVENT_TYPE_TAG: Lazy = @@ -42,4 +46,4 @@ impl MoveStructType for CoinWithdraw { impl MoveStructType for CoinDeposit { const MODULE_NAME: &'static IdentStr = ident_str!("coin"); const STRUCT_NAME: &'static IdentStr = ident_str!("CoinDeposit"); -} \ No newline at end of file +} diff --git a/types/src/account_config/events/fa.rs b/types/src/account_config/events/fa.rs index b34cb7c1ac5..a9e78ce5d84 100644 --- a/types/src/account_config/events/fa.rs +++ b/types/src/account_config/events/fa.rs @@ -1,5 +1,11 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + use derive_getters::Getters; -use move_core_types::{account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, move_resource::MoveStructType}; +use move_core_types::{ + account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, + move_resource::MoveStructType, +}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; diff --git a/types/src/account_config/events/mod.rs b/types/src/account_config/events/mod.rs index 179e5f8a920..83d5fa1fcee 100644 --- a/types/src/account_config/events/mod.rs +++ b/types/src/account_config/events/mod.rs @@ -2,16 +2,16 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 +pub mod coin; pub mod deposit; +pub mod fa; pub mod new_block; pub mod new_epoch; pub mod withdraw; -pub mod coin; -pub mod fa; +pub use coin::*; pub use deposit::*; +pub use fa::*; pub use new_block::*; pub use new_epoch::*; pub use withdraw::*; -pub use coin::*; -pub use fa::*; \ No newline at end of file diff --git a/types/src/dkg/dummy_dkg/mod.rs b/types/src/aptos_dkg/dummy_dkg/mod.rs similarity index 98% rename from types/src/dkg/dummy_dkg/mod.rs rename to types/src/aptos_dkg/dummy_dkg/mod.rs index 56bd781ff91..55989283327 100644 --- a/types/src/dkg/dummy_dkg/mod.rs +++ b/types/src/aptos_dkg/dummy_dkg/mod.rs @@ -1,7 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::dkg::{DKGSessionMetadata, DKGTrait}; +use crate::aptos_dkg::{DKGSessionMetadata, DKGTrait}; use anyhow::{anyhow, ensure}; use aptos_crypto::{ed25519, Uniform}; use rand::{CryptoRng, Rng, RngCore}; diff --git a/types/src/dkg/dummy_dkg/tests.rs b/types/src/aptos_dkg/dummy_dkg/tests.rs similarity index 99% rename from types/src/dkg/dummy_dkg/tests.rs rename to types/src/aptos_dkg/dummy_dkg/tests.rs index b3dcb9137ed..b3902cd08d7 100644 --- a/types/src/dkg/dummy_dkg/tests.rs +++ b/types/src/aptos_dkg/dummy_dkg/tests.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - dkg::{ + aptos_dkg::{ dummy_dkg::{DummyDKG, DummyDKGTranscript, DummySecret}, DKGSessionMetadata, DKGTrait, }, diff --git a/types/src/aptos_dkg/mod.rs b/types/src/aptos_dkg/mod.rs new file mode 100644 index 00000000000..e8ff50d530f --- /dev/null +++ b/types/src/aptos_dkg/mod.rs @@ -0,0 +1,219 @@ +// Copyright © Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + +use self::real_dkg::RealDKG; +use crate::{ + aptos_dkg::real_dkg::rounding::DKGRoundingProfile, + on_chain_config::{OnChainConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct}, + validator_verifier::{ValidatorConsensusInfo, ValidatorConsensusInfoMoveStruct}, +}; +use anyhow::Result; +use aptos_crypto::Uniform; +use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; +use move_core_types::{ + account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, + move_resource::MoveStructType, +}; +use once_cell::sync::Lazy; +use rand::{CryptoRng, RngCore}; +use serde::{Deserialize, Serialize}; +use std::{ + collections::BTreeSet, + fmt::{Debug, Formatter}, + time::Duration, +}; + +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, CryptoHasher, BCSCryptoHash)] +pub struct DKGTranscriptMetadata { + pub epoch: u64, + pub author: AccountAddress, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DKGStartEvent { + pub session_metadata: DKGSessionMetadata, + pub start_time_us: u64, +} + +impl MoveStructType for DKGStartEvent { + const MODULE_NAME: &'static IdentStr = ident_str!("dkg"); + const STRUCT_NAME: &'static IdentStr = ident_str!("DKGStartEvent"); +} + +pub static DKG_START_EVENT_MOVE_TYPE_TAG: Lazy = + Lazy::new(|| TypeTag::Struct(Box::new(DKGStartEvent::struct_tag()))); + +/// DKG transcript and its metadata. +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct DKGTranscript { + pub metadata: DKGTranscriptMetadata, + #[serde(with = "serde_bytes")] + pub transcript_bytes: Vec, +} + +impl Debug for DKGTranscript { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DKGTranscript") + .field("metadata", &self.metadata) + .field("transcript_bytes_len", &self.transcript_bytes.len()) + .finish() + } +} + +impl DKGTranscript { + pub fn new(epoch: u64, author: AccountAddress, transcript_bytes: Vec) -> Self { + Self { + metadata: DKGTranscriptMetadata { epoch, author }, + transcript_bytes, + } + } + + pub fn dummy() -> Self { + Self { + metadata: DKGTranscriptMetadata { + epoch: 0, + author: AccountAddress::ZERO, + }, + transcript_bytes: vec![], + } + } +} + +/// Reflection of `0x1::dkg::DKGSessionMetadata` in rust. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct DKGSessionMetadata { + pub dealer_epoch: u64, + pub randomness_config: RandomnessConfigMoveStruct, + pub dealer_validator_set: Vec, + pub target_validator_set: Vec, +} + +impl DKGSessionMetadata { + pub fn target_validator_consensus_infos_cloned(&self) -> Vec { + self.target_validator_set + .clone() + .into_iter() + .map(|obj| obj.try_into().unwrap()) + .collect() + } + + pub fn dealer_consensus_infos_cloned(&self) -> Vec { + self.dealer_validator_set + .clone() + .into_iter() + .map(|obj| obj.try_into().unwrap()) + .collect() + } + + pub fn randomness_config_derived(&self) -> Option { + OnChainRandomnessConfig::try_from(self.randomness_config.clone()).ok() + } +} + +impl MayHaveRoundingSummary for DKGSessionMetadata { + fn rounding_summary(&self) -> Option<&RoundingSummary> { + None + } +} + +/// Reflection of Move type `0x1::dkg::DKGSessionState`. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct DKGSessionState { + pub metadata: DKGSessionMetadata, + pub start_time_us: u64, + pub transcript: Vec, +} + +impl DKGSessionState { + pub fn target_epoch(&self) -> u64 { + self.metadata.dealer_epoch + 1 + } +} +/// Reflection of Move type `0x1::dkg::DKGState`. +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct DKGState { + pub last_completed: Option, + pub in_progress: Option, +} + +impl DKGState { + pub fn maybe_last_complete(&self, epoch: u64) -> Option<&DKGSessionState> { + match &self.last_completed { + Some(session) if session.target_epoch() == epoch => Some(session), + _ => None, + } + } + + pub fn last_complete(&self) -> &DKGSessionState { + self.last_completed.as_ref().unwrap() + } +} + +impl OnChainConfig for DKGState { + const MODULE_IDENTIFIER: &'static str = "dkg"; + const TYPE_IDENTIFIER: &'static str = "DKGState"; +} + +#[derive(Clone, Debug, Default)] +pub struct RoundingSummary { + pub method: String, + pub output: DKGRoundingProfile, + pub error: Option, + pub exec_time: Duration, +} + +pub trait MayHaveRoundingSummary { + fn rounding_summary(&self) -> Option<&RoundingSummary>; +} + +/// NOTE: this is a subset of the full scheme. Some data items/algorithms are not used in DKG and are omitted. +pub trait DKGTrait: Debug { + type DealerPrivateKey; + type PublicParams: Clone + Debug + Send + Sync + MayHaveRoundingSummary; + type Transcript: Clone + Send + Sync + Serialize + for<'a> Deserialize<'a>; + type InputSecret: Uniform; + type DealtSecret; + type DealtSecretShare; + type DealtPubKeyShare; + type NewValidatorDecryptKey: Uniform; + + fn new_public_params(dkg_session_metadata: &DKGSessionMetadata) -> Self::PublicParams; + fn aggregate_input_secret(secrets: Vec) -> Self::InputSecret; + fn dealt_secret_from_input( + pub_params: &Self::PublicParams, + input: &Self::InputSecret, + ) -> Self::DealtSecret; + fn generate_transcript( + rng: &mut R, + params: &Self::PublicParams, + input_secret: &Self::InputSecret, + my_index: u64, + sk: &Self::DealerPrivateKey, + ) -> Self::Transcript; + + fn verify_transcript(params: &Self::PublicParams, trx: &Self::Transcript) -> Result<()>; + + fn aggregate_transcripts( + params: &Self::PublicParams, + accumulator: &mut Self::Transcript, + element: Self::Transcript, + ); + + fn decrypt_secret_share_from_transcript( + pub_params: &Self::PublicParams, + trx: &Self::Transcript, + player_idx: u64, + dk: &Self::NewValidatorDecryptKey, + ) -> Result<(Self::DealtSecretShare, Self::DealtPubKeyShare)>; + + fn reconstruct_secret_from_shares( + pub_params: &Self::PublicParams, + player_share_pairs: Vec<(u64, Self::DealtSecretShare)>, + ) -> Result; + fn get_dealers(transcript: &Self::Transcript) -> BTreeSet; +} + +pub mod dummy_dkg; +pub mod real_dkg; + +pub type DefaultDKG = RealDKG; diff --git a/types/src/dkg/real_dkg/mod.rs b/types/src/aptos_dkg/real_dkg/mod.rs similarity index 99% rename from types/src/dkg/real_dkg/mod.rs rename to types/src/aptos_dkg/real_dkg/mod.rs index 012261a7973..403f9dbc41e 100644 --- a/types/src/dkg/real_dkg/mod.rs +++ b/types/src/aptos_dkg/real_dkg/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - dkg::{ + aptos_dkg::{ real_dkg::rounding::DKGRounding, DKGSessionMetadata, DKGTrait, MayHaveRoundingSummary, RoundingSummary, }, diff --git a/types/src/dkg/real_dkg/rounding/mod.rs b/types/src/aptos_dkg/real_dkg/rounding/mod.rs similarity index 100% rename from types/src/dkg/real_dkg/rounding/mod.rs rename to types/src/aptos_dkg/real_dkg/rounding/mod.rs diff --git a/types/src/dkg/real_dkg/rounding/tests.rs b/types/src/aptos_dkg/real_dkg/rounding/tests.rs similarity index 99% rename from types/src/dkg/real_dkg/rounding/tests.rs rename to types/src/aptos_dkg/real_dkg/rounding/tests.rs index cdb29db527a..55a85096a8f 100644 --- a/types/src/dkg/real_dkg/rounding/tests.rs +++ b/types/src/aptos_dkg/real_dkg/rounding/tests.rs @@ -1,7 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::dkg::real_dkg::rounding::{ +use crate::aptos_dkg::real_dkg::rounding::{ is_valid_profile, total_weight_lower_bound, total_weight_upper_bound, DKGRounding, DKGRoundingProfile, DEFAULT_FAST_PATH_SECRECY_THRESHOLD, DEFAULT_RECONSTRUCT_THRESHOLD, DEFAULT_SECRECY_THRESHOLD, diff --git a/types/src/contract_event.rs b/types/src/contract_event.rs index 59d9a27fae4..b076afe07a5 100644 --- a/types/src/contract_event.rs +++ b/types/src/contract_event.rs @@ -4,7 +4,7 @@ use crate::{ account_config::{DepositEvent, NewBlockEvent, NewEpochEvent, WithdrawEvent}, - dkg::DKGStartEvent, + dkg::events::{DKGFinishEvent, DKGMetaSetEvent, DKGStartEvent}, event::EventKey, jwks::ObservedJWKsUpdated, on_chain_config::new_epoch_event_key, @@ -165,6 +165,24 @@ impl ContractEvent { pub fn expect_new_block_event(&self) -> Result { NewBlockEvent::try_from_bytes(self.event_data()) } + + pub fn as_bytes_for_hash(&self) -> Vec { + let mut bytes = Vec::new(); + match self { + ContractEvent::V1(event) => { + bytes.extend_from_slice(&event.key().get_creation_number().to_le_bytes()); + bytes.extend_from_slice(event.key().get_creator_address().as_ref()); + bytes.extend_from_slice(&event.sequence_number().to_le_bytes()); + bytes.extend_from_slice(event.type_tag().to_canonical_string().as_bytes()); + bytes.extend_from_slice(event.event_data()); + }, + ContractEvent::V2(event) => { + bytes.extend_from_slice(event.type_tag().to_canonical_string().as_bytes()); + bytes.extend_from_slice(event.event_data()); + }, + } + bytes + } } /// Entry produced via a call to the `emit_event` builtin. @@ -299,6 +317,24 @@ impl From<(u64, NewEpochEvent)> for ContractEvent { } } +impl TryFrom<&ContractEvent> for crate::aptos_dkg::DKGStartEvent { + type Error = Error; + + fn try_from(event: &ContractEvent) -> Result { + match event { + ContractEvent::V1(_) => { + bail!("conversion to dkg start event failed with wrong contract event version"); + }, + ContractEvent::V2(event) => { + if event.type_tag != TypeTag::Struct(Box::new(Self::struct_tag())) { + bail!("conversion to dkg start event failed with wrong type tag") + } + bcs::from_bytes(&event.event_data).map_err(Into::into) + }, + } + } +} + impl TryFrom<&ContractEvent> for DKGStartEvent { type Error = Error; @@ -317,6 +353,69 @@ impl TryFrom<&ContractEvent> for DKGStartEvent { } } +impl From for ContractEvent { + fn from(event: DKGStartEvent) -> Self { + Self::new_v2( + TypeTag::from(DKGStartEvent::struct_tag()), + bcs::to_bytes(&event).unwrap(), + ) + } +} + +impl TryFrom<&ContractEvent> for DKGFinishEvent { + type Error = Error; + + fn try_from(event: &ContractEvent) -> Result { + match event { + ContractEvent::V1(_) => { + bail!("conversion to dkg finish event failed with wrong contract event version"); + }, + ContractEvent::V2(event) => { + if event.type_tag != TypeTag::Struct(Box::new(Self::struct_tag())) { + bail!("conversion to dkg finish event failed with wrong type tag") + } + bcs::from_bytes(&event.event_data).map_err(Into::into) + }, + } + } +} + +impl From for ContractEvent { + fn from(event: DKGFinishEvent) -> Self { + Self::new_v2( + TypeTag::from(DKGFinishEvent::struct_tag()), + bcs::to_bytes(&event).unwrap(), + ) + } +} + +impl TryFrom<&ContractEvent> for DKGMetaSetEvent { + type Error = Error; + + fn try_from(event: &ContractEvent) -> Result { + match event { + ContractEvent::V1(_) => { + bail!("conversion to dkg meta set event failed with wrong contract event version"); + }, + ContractEvent::V2(event) => { + if event.type_tag != TypeTag::Struct(Box::new(Self::struct_tag())) { + bail!("conversion to dkg meta set event failed with wrong type tag") + } + bcs::from_bytes(&event.event_data).map_err(Into::into) + }, + } + } +} + +impl From for ContractEvent { + fn from(event: DKGMetaSetEvent) -> Self { + Self::new_v2( + TypeTag::from(DKGMetaSetEvent::struct_tag()), + bcs::to_bytes(&event).unwrap(), + ) + } +} + impl TryFrom<&ContractEvent> for NewEpochEvent { type Error = Error; diff --git a/types/src/dkg/dkg_committee.rs b/types/src/dkg/dkg_committee.rs new file mode 100644 index 00000000000..c531cd35f82 --- /dev/null +++ b/types/src/dkg/dkg_committee.rs @@ -0,0 +1,55 @@ +use derive_getters::Getters; +use move_core_types::account_address::AccountAddress; +use serde::{Deserialize, Serialize}; + +/// Reflection of `0x1::dkg_committee::DkgNodeConfig` in rust. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Getters)] +pub struct DkgNodeConfig { + pool_address: AccountAddress, + identity: Vec, + dkg_pubkey: Vec, +} + +impl DkgNodeConfig { + pub fn new(pool_address: AccountAddress, identity: Vec, dkg_pubkey: Vec) -> Self { + Self { + pool_address, + identity, + dkg_pubkey, + } + } +} + +/// Reflection of `0x1::dkg_committee::DkgCommittee` in rust. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Getters)] +pub struct DkgCommittee { + committee: Vec, + threshold_type: u8, +} + +impl DkgCommittee { + pub fn new(committee: Vec, threshold_type: u8) -> Self { + Self { + committee, + threshold_type, + } + } +} + +/// Reflection of `0x1::dkg_committee::ReceiverCommittee` in rust. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Getters)] +pub struct ReceiverCommittee { + is_resharing: bool, + dkg_threshold_type: u8, + committee: DkgCommittee, +} + +impl ReceiverCommittee { + pub fn new(is_resharing: bool, dkg_threshold_type: u8, committee: DkgCommittee) -> Self { + Self { + is_resharing, + dkg_threshold_type, + committee, + } + } +} diff --git a/types/src/dkg/events.rs b/types/src/dkg/events.rs new file mode 100644 index 00000000000..bb08f2ebb7e --- /dev/null +++ b/types/src/dkg/events.rs @@ -0,0 +1,46 @@ +use crate::dkg::state::DKGSessionMetadata; +use move_core_types::{ + ident_str, identifier::IdentStr, language_storage::TypeTag, move_resource::MoveStructType, +}; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DKGStartEvent { + pub session_metadata: DKGSessionMetadata, + pub start_time_us: u64, +} + +impl MoveStructType for DKGStartEvent { + const MODULE_NAME: &'static IdentStr = ident_str!("dkg"); + const STRUCT_NAME: &'static IdentStr = ident_str!("DKGStartEvent"); +} + +pub static DKG_START_EVENT_MOVE_TYPE_TAG: Lazy = + Lazy::new(|| TypeTag::Struct(Box::new(DKGStartEvent::struct_tag()))); + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DKGMetaSetEvent { + pub dkg_meta_transcript: Vec, +} + +impl MoveStructType for DKGMetaSetEvent { + const MODULE_NAME: &'static IdentStr = ident_str!("dkg"); + const STRUCT_NAME: &'static IdentStr = ident_str!("DKGMetaSetEvent"); +} + +pub static DKG_META_SET_EVENT_MOVE_TYPE_TAG: Lazy = + Lazy::new(|| TypeTag::Struct(Box::new(DKGMetaSetEvent::struct_tag()))); + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct DKGFinishEvent { + pub target_committees_public_key_shares: Vec, +} + +impl MoveStructType for DKGFinishEvent { + const MODULE_NAME: &'static IdentStr = ident_str!("dkg"); + const STRUCT_NAME: &'static IdentStr = ident_str!("DKGFinishEvent"); +} + +pub static DKG_FINISH_EVENT_MOVE_TYPE_TAG: Lazy = + Lazy::new(|| TypeTag::Struct(Box::new(DKGFinishEvent::struct_tag()))); diff --git a/types/src/dkg/mod.rs b/types/src/dkg/mod.rs index 2e3bde94085..c45d9fe1a91 100644 --- a/types/src/dkg/mod.rs +++ b/types/src/dkg/mod.rs @@ -1,219 +1,58 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use self::real_dkg::RealDKG; -use crate::{ - dkg::real_dkg::rounding::DKGRoundingProfile, - on_chain_config::{OnChainConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct}, - validator_verifier::{ValidatorConsensusInfo, ValidatorConsensusInfoMoveStruct}, -}; -use anyhow::Result; -use aptos_crypto::Uniform; -use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; -use move_core_types::{ - account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, - move_resource::MoveStructType, -}; -use once_cell::sync::Lazy; -use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; -use std::{ - collections::BTreeSet, - fmt::{Debug, Formatter}, - time::Duration, -}; - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, CryptoHasher, BCSCryptoHash)] -pub struct DKGTranscriptMetadata { - pub epoch: u64, - pub author: AccountAddress, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct DKGStartEvent { - pub session_metadata: DKGSessionMetadata, - pub start_time_us: u64, -} - -impl MoveStructType for DKGStartEvent { - const MODULE_NAME: &'static IdentStr = ident_str!("dkg"); - const STRUCT_NAME: &'static IdentStr = ident_str!("DKGStartEvent"); -} - -pub static DKG_START_EVENT_MOVE_TYPE_TAG: Lazy = - Lazy::new(|| TypeTag::Struct(Box::new(DKGStartEvent::struct_tag()))); - -/// DKG transcript and its metadata. -#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct DKGTranscript { - pub metadata: DKGTranscriptMetadata, - #[serde(with = "serde_bytes")] - pub transcript_bytes: Vec, -} - -impl Debug for DKGTranscript { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("DKGTranscript") - .field("metadata", &self.metadata) - .field("transcript_bytes_len", &self.transcript_bytes.len()) - .finish() - } -} - -impl DKGTranscript { - pub fn new(epoch: u64, author: AccountAddress, transcript_bytes: Vec) -> Self { - Self { - metadata: DKGTranscriptMetadata { epoch, author }, - transcript_bytes, +use crate::{dkg::dkg_committee::DkgCommittee, validator_public_keys::ValidatorPublicKeys}; +use anyhow::{anyhow, Result}; +use aptos_crypto::bls12381::PublicKey; +use crypto::utils::get_clan_node_indices; + +pub mod dkg_committee; +pub mod events; +pub mod state; +pub mod transactions; + +/// The threshold required to ensure the presence of honest majority in clan where +/// N = 2f+1 with f byzantine nodes +fn clan_threshold(total: u64) -> u64 { + total / 2 + 1 +} + +pub fn get_clan_nodes_bls_keys_from_indices( + dealer_committee: &DkgCommittee, + signers: &Vec, + random_seed: &Vec, +) -> Result> { + let committee = dealer_committee.committee(); + let dealer_clan_committee_indices = + get_clan_node_indices(committee.len() as u32, random_seed.clone()); + + let mut clan_committee_bls_keys = Vec::new(); + if let Some(clan_committee_indices) = dealer_clan_committee_indices { + let clan_threshold = clan_threshold(clan_committee_indices.len() as u64); + + if signers.len() as u64 != clan_threshold { + return Err(anyhow!("dkg::number of signers must match clan_threshold")); } - } - pub fn dummy() -> Self { - Self { - metadata: DKGTranscriptMetadata { - epoch: 0, - author: AccountAddress::ZERO, - }, - transcript_bytes: vec![], + for signer in signers { + let clan_node_index = clan_committee_indices + .get(*signer as usize) + .ok_or(anyhow!("dkg::node Invalid signer index: {signer}"))?; + let clan_node_key = committee + .get(*clan_node_index) + .ok_or(anyhow!("dkg::node Invalid clan node index: {signer}"))? + .dkg_pubkey(); + let clan_node_pk = ValidatorPublicKeys::try_from(clan_node_key).map_err(|e| { + anyhow!("dkg::node validator public key deserialization failed: {e}") + })?; + let clan_node_bls_pubkey_bytes = clan_node_pk.supra_keys().bls_multisig_key(); + let clan_node_bls_pubkey = + PublicKey::try_from(clan_node_bls_pubkey_bytes.as_slice()) + .map_err(|e| anyhow!("dkg::node bls public key deserialization failed: {e}"))?; + clan_committee_bls_keys.push(clan_node_bls_pubkey); } + Ok(clan_committee_bls_keys) + } else { + Err(anyhow!("dkg::cannot derive clan committee")) } } - -/// Reflection of `0x1::dkg::DKGSessionMetadata` in rust. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct DKGSessionMetadata { - pub dealer_epoch: u64, - pub randomness_config: RandomnessConfigMoveStruct, - pub dealer_validator_set: Vec, - pub target_validator_set: Vec, -} - -impl DKGSessionMetadata { - pub fn target_validator_consensus_infos_cloned(&self) -> Vec { - self.target_validator_set - .clone() - .into_iter() - .map(|obj| obj.try_into().unwrap()) - .collect() - } - - pub fn dealer_consensus_infos_cloned(&self) -> Vec { - self.dealer_validator_set - .clone() - .into_iter() - .map(|obj| obj.try_into().unwrap()) - .collect() - } - - pub fn randomness_config_derived(&self) -> Option { - OnChainRandomnessConfig::try_from(self.randomness_config.clone()).ok() - } -} - -impl MayHaveRoundingSummary for DKGSessionMetadata { - fn rounding_summary(&self) -> Option<&RoundingSummary> { - None - } -} - -/// Reflection of Move type `0x1::dkg::DKGSessionState`. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct DKGSessionState { - pub metadata: DKGSessionMetadata, - pub start_time_us: u64, - pub transcript: Vec, -} - -impl DKGSessionState { - pub fn target_epoch(&self) -> u64 { - self.metadata.dealer_epoch + 1 - } -} -/// Reflection of Move type `0x1::dkg::DKGState`. -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] -pub struct DKGState { - pub last_completed: Option, - pub in_progress: Option, -} - -impl DKGState { - pub fn maybe_last_complete(&self, epoch: u64) -> Option<&DKGSessionState> { - match &self.last_completed { - Some(session) if session.target_epoch() == epoch => Some(session), - _ => None, - } - } - - pub fn last_complete(&self) -> &DKGSessionState { - self.last_completed.as_ref().unwrap() - } -} - -impl OnChainConfig for DKGState { - const MODULE_IDENTIFIER: &'static str = "dkg"; - const TYPE_IDENTIFIER: &'static str = "DKGState"; -} - -#[derive(Clone, Debug, Default)] -pub struct RoundingSummary { - pub method: String, - pub output: DKGRoundingProfile, - pub error: Option, - pub exec_time: Duration, -} - -pub trait MayHaveRoundingSummary { - fn rounding_summary(&self) -> Option<&RoundingSummary>; -} - -/// NOTE: this is a subset of the full scheme. Some data items/algorithms are not used in DKG and are omitted. -pub trait DKGTrait: Debug { - type DealerPrivateKey; - type PublicParams: Clone + Debug + Send + Sync + MayHaveRoundingSummary; - type Transcript: Clone + Send + Sync + Serialize + for<'a> Deserialize<'a>; - type InputSecret: Uniform; - type DealtSecret; - type DealtSecretShare; - type DealtPubKeyShare; - type NewValidatorDecryptKey: Uniform; - - fn new_public_params(dkg_session_metadata: &DKGSessionMetadata) -> Self::PublicParams; - fn aggregate_input_secret(secrets: Vec) -> Self::InputSecret; - fn dealt_secret_from_input( - pub_params: &Self::PublicParams, - input: &Self::InputSecret, - ) -> Self::DealtSecret; - fn generate_transcript( - rng: &mut R, - params: &Self::PublicParams, - input_secret: &Self::InputSecret, - my_index: u64, - sk: &Self::DealerPrivateKey, - ) -> Self::Transcript; - - fn verify_transcript(params: &Self::PublicParams, trx: &Self::Transcript) -> Result<()>; - - fn aggregate_transcripts( - params: &Self::PublicParams, - accumulator: &mut Self::Transcript, - element: Self::Transcript, - ); - - fn decrypt_secret_share_from_transcript( - pub_params: &Self::PublicParams, - trx: &Self::Transcript, - player_idx: u64, - dk: &Self::NewValidatorDecryptKey, - ) -> Result<(Self::DealtSecretShare, Self::DealtPubKeyShare)>; - - fn reconstruct_secret_from_shares( - pub_params: &Self::PublicParams, - player_share_pairs: Vec<(u64, Self::DealtSecretShare)>, - ) -> Result; - fn get_dealers(transcript: &Self::Transcript) -> BTreeSet; -} - -pub mod dummy_dkg; -pub mod real_dkg; - -pub type DefaultDKG = RealDKG; diff --git a/types/src/dkg/state.rs b/types/src/dkg/state.rs new file mode 100644 index 00000000000..18bbf8f1dbc --- /dev/null +++ b/types/src/dkg/state.rs @@ -0,0 +1,70 @@ +use crate::{ + dkg::dkg_committee::{DkgCommittee, ReceiverCommittee}, + on_chain_config::OnChainConfig, +}; +use serde::{Deserialize, Serialize}; + +// Reflection of `0x1::dkg::DKGSessionMetadata` in rust. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct DKGSessionMetadata { + pub dealer_epoch: u64, + pub randomness_seed: Vec, + pub dealer_committee: DkgCommittee, + pub target_committees: Vec, +} + +impl DKGSessionMetadata { + pub fn target_committee_cloned(&self) -> Vec { + self.target_committees.clone() + } + + pub fn dealer_committee_cloned(&self) -> DkgCommittee { + self.dealer_committee.clone() + } +} + +/// Reflection of Move type `0x1::dkg::DKGSessionState`. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct DKGSessionState { + pub metadata: DKGSessionMetadata, + pub start_time_us: u64, + pub dkg_meta_transcript: Vec, + pub target_committees_public_key_shares: Vec, +} + +impl DKGSessionState { + pub fn target_epoch(&self) -> u64 { + self.metadata.dealer_epoch + 1 + } +} +/// Reflection of Move type `0x1::dkg::DKGState`. +#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct DKGState { + pub last_completed: Option, + pub in_progress: Option, +} + +impl DKGState { + pub fn maybe_last_complete(&self, epoch: u64) -> Option<&DKGSessionState> { + match &self.last_completed { + Some(session) if session.target_epoch() == epoch => Some(session), + _ => None, + } + } + + pub fn maybe_in_progress(&self, epoch: u64) -> Option<&DKGSessionState> { + match &self.in_progress { + Some(session) if session.target_epoch() == epoch => Some(session), + _ => None, + } + } + + pub fn last_complete(&self) -> &DKGSessionState { + self.last_completed.as_ref().unwrap() + } +} + +impl OnChainConfig for DKGState { + const MODULE_IDENTIFIER: &'static str = "dkg"; + const TYPE_IDENTIFIER: &'static str = "DKGState"; +} diff --git a/types/src/dkg/transactions.rs b/types/src/dkg/transactions.rs new file mode 100644 index 00000000000..dd1054520f1 --- /dev/null +++ b/types/src/dkg/transactions.rs @@ -0,0 +1,77 @@ +use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; +use derive_getters::Getters; +use move_core_types::account_address::AccountAddress; +use serde::{Deserialize, Serialize}; +use std::fmt::{Debug, Formatter}; + +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] +pub enum DKGTransactionType { + DKGMeta, + PublicKeyShares, +} + +#[derive( + Clone, Serialize, Deserialize, Debug, PartialEq, Eq, CryptoHasher, BCSCryptoHash, Getters, +)] +pub struct DKGTransactionMetadata { + epoch: u64, + author: AccountAddress, + bls_aggregate_signature: Vec, + signer_indices_clan_committee: Vec, + transaction_type: DKGTransactionType, +} + +/// DKG transcript and its metadata. +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Getters)] +pub struct DKGTransactionData { + metadata: DKGTransactionMetadata, + #[serde(with = "serde_bytes")] + data_bytes: Vec, +} + +impl Debug for DKGTransactionData { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DKGTransactionData") + .field("metadata", &self.metadata) + .field("data_bytes_len", &self.data_bytes.len()) + .finish() + } +} + +impl DKGTransactionData { + pub fn new( + epoch: u64, + author: AccountAddress, + transcript_bytes: Vec, + bls_aggregate_signature: Vec, + signer_indices_clan_committee: Vec, + transaction_type: DKGTransactionType, + ) -> Self { + Self { + metadata: DKGTransactionMetadata { + epoch, + author, + bls_aggregate_signature, + signer_indices_clan_committee, + transaction_type, + }, + data_bytes: transcript_bytes, + } + } +} + +#[cfg(test)] +impl DKGTransactionData { + pub fn dummy() -> Self { + Self { + metadata: DKGTransactionMetadata { + epoch: 0, + author: AccountAddress::ZERO, + bls_aggregate_signature: vec![], + signer_indices_clan_committee: vec![], + transaction_type: DKGTransactionType::DKGMeta, + }, + data_bytes: vec![], + } + } +} diff --git a/types/src/lib.rs b/types/src/lib.rs index 9081b6c0f0a..302c948787a 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -7,6 +7,7 @@ pub mod access_path; pub mod account_address; pub mod account_config; +pub mod aptos_dkg; pub mod block_info; pub mod block_metadata; pub mod block_metadata_ext; @@ -48,6 +49,7 @@ pub mod utility_coin; pub mod validator_config; pub mod validator_info; pub mod validator_performances; +pub mod validator_public_keys; pub mod validator_signer; pub mod validator_txn; pub mod validator_verifier; diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index 4f250fac06d..4abc853ca97 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -97,8 +97,16 @@ pub enum FeatureFlag { SUPRA_RLP_ENCODE = 94, SUPRA_DELEGATION_POOL_IDENTITY = 95, SUPRA_AUTOMATION_V2 = 96, + /// This flag should only be enabled after all Validators have updated their keys to the new format, including the BLS keys. + SUPRA_BLS_KEYS = 97, + SUPRA_BCFT_CERTIFICATES = 98, + /// `SUPRA_BLS_KEYS` must be enabled first, as the new validator identity format is a prerequisite for the DKG. + /// The default DKG configuration also requires `SUPRA_BCFT_CERTIFICATES` to be enabled first. + SUPRA_DKG = 99, + SUPRA_TRANSACTIONS_INCLUSION_PROOFS = 100, } +//TODO: add dkg feature impl FeatureFlag { pub fn default_features() -> Vec { vec![ @@ -169,6 +177,10 @@ impl FeatureFlag { FeatureFlag::SUPRA_COUNT_FAILED_PROPOSALS, FeatureFlag::SUPRA_DELEGATION_POOL_IDENTITY, FeatureFlag::SUPRA_AUTOMATION_V2, + FeatureFlag::SUPRA_BLS_KEYS, + FeatureFlag::SUPRA_BCFT_CERTIFICATES, + FeatureFlag::SUPRA_DKG, + FeatureFlag::SUPRA_TRANSACTIONS_INCLUSION_PROOFS, ] } } diff --git a/types/src/on_chain_config/automation_registry.rs b/types/src/on_chain_config/automation_registry.rs index 95779e36300..4f68aa12669 100644 --- a/types/src/on_chain_config/automation_registry.rs +++ b/types/src/on_chain_config/automation_registry.rs @@ -1,12 +1,19 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2025 Supra. // SPDX-License-Identifier: Apache-2.0 use crate::on_chain_config::OnChainConfig; use derive_getters::Getters; use derive_more::Constructor; -use move_core_types::account_address::AccountAddress; -use move_core_types::value::{serialize_values, MoveValue}; -use move_core_types::{ident_str, identifier::IdentStr, move_resource::MoveStructType}; +use move_core_types::{ + account_address::AccountAddress, + ident_str, + identifier::IdentStr, + move_resource::MoveStructType, + value::{serialize_values, MoveValue}, +}; use serde::{Deserialize, Serialize}; const ONE_MONTH_IN_SECS: u64 = 2_626_560; diff --git a/types/src/on_chain_config/evm_genesis_config.rs b/types/src/on_chain_config/evm_genesis_config.rs index 66a157ba7bb..1901bc9bb64 100644 --- a/types/src/on_chain_config/evm_genesis_config.rs +++ b/types/src/on_chain_config/evm_genesis_config.rs @@ -1,15 +1,17 @@ -// Copyright (c) Supra Foundation +// Copyright (c) Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use once_cell::sync::Lazy; +// Copyright (c) Supra Foundation +// SPDX-License-Identifier: Apache-2.0 use super::OnChainConfig; use crate::chain_id::ChainId; use anyhow::{anyhow, Result}; -use serde::{Deserialize, Serialize}; use move_core_types::{ ident_str, identifier::IdentStr, language_storage::TypeTag, move_resource::MoveStructType, }; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; /// The Genesis configuration for EVM that can only be set once at genesis epoch. #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] @@ -45,7 +47,11 @@ pub struct GenesisEvmContract { impl OnChainEvmGenesisConfig { /// Create a new OnChainEvmGenesisConfig with the given parameters. - pub fn new(chain_id: ChainId, eoas: Vec, contracts: Vec) -> Self { + pub fn new( + chain_id: ChainId, + eoas: Vec, + contracts: Vec, + ) -> Self { let chain_id = Self::derive_evm_chain_id_from_move_chain_id(chain_id); Self { @@ -54,7 +60,7 @@ impl OnChainEvmGenesisConfig { contracts, } } - + /// Derive the EVM chain ID from the Move chain ID. fn derive_evm_chain_id_from_move_chain_id(move_chain_id: ChainId) -> u64 { let chain_id = move_chain_id.id() as u64; @@ -86,13 +92,10 @@ impl OnChainConfig for OnChainEvmGenesisConfig { } } - - /// Move event type `0x1::evm_genesis_config::EvmGenesisEvent` in rust. /// See its doc in Move for more details. #[derive(Serialize, Deserialize)] -pub struct EvmGenesisEvent { -} +pub struct EvmGenesisEvent {} impl MoveStructType for EvmGenesisEvent { const MODULE_NAME: &'static IdentStr = ident_str!("evm_genesis_config"); diff --git a/types/src/on_chain_config/leader_ban_registry.rs b/types/src/on_chain_config/leader_ban_registry.rs new file mode 100644 index 00000000000..05943ca61a6 --- /dev/null +++ b/types/src/on_chain_config/leader_ban_registry.rs @@ -0,0 +1,95 @@ +use derive_getters::Getters; +use derive_more::Constructor; +use move_core_types::{ + account_address::AccountAddress, + value::{serialize_values, MoveValue}, +}; +use serde::{Deserialize, Serialize}; +use anyhow::{format_err, Result}; + +use crate::on_chain_config::OnChainConfig; + +/// Configuration for a [`BanRegistry`]. Stored in the Move state and updated via governance. +/// +/// This enum allows for future versions of the configuration to be added without breaking +/// the backwards compatibility constraints enforced by BCS. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +pub enum BanRegistryParameters { + V0(BanRegistryParametersV0), +} + +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] +struct MoveBanRegistryParams { + pub config: Vec, + pub version: u8 +} + +impl Default for BanRegistryParameters { + fn default() -> Self { + BanRegistryParameters::V0(BanRegistryParametersV0::default()) + } +} + +impl OnChainConfig for BanRegistryParameters { + const MODULE_IDENTIFIER: &'static str = "leader_ban_registry_config"; + const TYPE_IDENTIFIER: &'static str = "BanRegistryParameters"; + + fn deserialize_default_impl(bytes: &[u8]) -> Result { + let move_ban_registry = bcs::from_bytes::(bytes) + .map_err(|e| format_err!("[on-chain config] Failed to deserialize into config: {}", e))?; + match move_ban_registry.version { + 0 => { + let params_v0 = bcs::from_bytes::(&move_ban_registry.config) + .map_err(|e| format_err!("[on-chain config] Failed to deserialize into config BanRegistryParametersV0: {}", e))?; + Ok(BanRegistryParameters::V0(params_v0)) + }, + _ => { + Err(format_err!("[on-chain config] Failed to deserialize into config: Invalid Version: {}", move_ban_registry.version)) + } + } + } +} + +impl BanRegistryParameters { + pub fn serialize_into_move_values_with_signer(&self, signer_address: AccountAddress) -> Vec> { + let arguments:Vec = match &self { + BanRegistryParameters::V0(ban_registry_parameters_v0) => { + let params_bytes = bcs::to_bytes(ban_registry_parameters_v0).expect("serialisation of leader ban config failed"); + vec![ + MoveValue::Signer(signer_address), + MoveValue::vector_u8(params_bytes), + ] + }, + }; + serialize_values(&arguments) + } +} + +/// The parameters of the consensus leader [`BanRegistry`]. +/// +/// BCS field order **must** match the Move struct `BanRegistryParametersV0`: +/// `initial_elections_denied, max_elections_denied, minimum_unbanned_proposers, probation_elections`. +/// +/// The [`Default`] values of the parameters disable banning. +#[derive(Clone, Constructor, Debug, Default, Deserialize, Eq, PartialEq, Getters, Serialize)] +pub struct BanRegistryParametersV0 { + /// The (approximate) initial number of election opportunities denied to a validator that + /// fails to propose a committed block when elected as leader. + /// + /// This number is scaled in proportion to the size of the [`Committee`] for the current epoch to + /// derive the total number of consensus rounds for which a validator is banned. This enables the + /// ban duration to remain roughly constant, regardless of the number of validators in the committee. + initial_elections_denied: u8, + /// The (approximate) maximum number of election opportunities denied to a validator that + /// consecutively fails to propose a committed block when elected as leader. + max_elections_denied: u32, + /// The lower bound on the number of validators that must remain eligible to be elected as + /// consensus leader. If banning a validator would cause the number of eligible validators to + /// drop below this number, the ban is not applied. + minimum_unbanned_proposers: u8, + /// The number of elections a validator must serve on probation after their ban expires. + /// During probation, the validator is eligible for election but will be banned for a longer + /// period (with `consecutive_bans` incremented) if it fails again. If the validator completes + /// probation without failing, the ban record is fully removed. + probation_elections: u8, +} diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs index 30fd0b8c795..50a10bd80c6 100644 --- a/types/src/on_chain_config/mod.rs +++ b/types/src/on_chain_config/mod.rs @@ -8,7 +8,7 @@ use crate::{ event::{EventHandle, EventKey}, state_store::{state_key::StateKey, StateView}, }; -use anyhow::{format_err, Result}; +use anyhow::{format_err, Context, Result}; use bytes::Bytes; use move_core_types::{ account_address::AccountAddress, @@ -31,6 +31,7 @@ mod evm_genesis_config; mod execution_config; mod gas_schedule; mod jwk_consensus_config; +mod leader_ban_registry; pub mod randomness_api_v0_config; mod randomness_config; mod timed_features; @@ -46,7 +47,8 @@ pub use self::{ }, automation_registry::{ AutomationCycleDetails, AutomationCycleEvent, AutomationCycleInfo, AutomationCycleState, - AutomationRegistryConfig, AutomationRegistryConfigV1, AutomationRegistryConfigV2, AutomationCycleTransitionState + AutomationCycleTransitionState, AutomationRegistryConfig, AutomationRegistryConfigV1, + AutomationRegistryConfigV2, }, commit_history::CommitHistoryResource, consensus_config::{ @@ -54,6 +56,9 @@ pub use self::{ LeaderReputationType, OnChainConsensusConfig, ProposerAndVoterConfig, ProposerElectionType, ValidatorTxnConfig, }, + evm_genesis_config::{ + GenesisEvmContract, GenesisEvmEOA, OnChainEvmGenesisConfig, EVM_GENESIS_EVENT_MOVE_TYPE_TAG, + }, execution_config::{ BlockGasLimitType, ExecutionConfigV1, ExecutionConfigV2, ExecutionConfigV4, OnChainExecutionConfig, TransactionDeduperType, TransactionShufflerType, @@ -62,6 +67,7 @@ pub use self::{ jwk_consensus_config::{ ConfigV1 as JWKConsensusConfigV1, OIDCProvider, OnChainJWKConsensusConfig, }, + leader_ban_registry::{BanRegistryParameters, BanRegistryParametersV0}, randomness_config::{ OnChainRandomnessConfig, RandomnessConfigMoveStruct, RandomnessConfigSeqNum, }, @@ -69,7 +75,6 @@ pub use self::{ timestamp::CurrentTimeMicroseconds, transaction_fee::TransactionFeeBurnCap, validator_set::{ConsensusScheme, ValidatorSet}, - evm_genesis_config::{OnChainEvmGenesisConfig, GenesisEvmContract, GenesisEvmEOA, EVM_GENESIS_EVENT_MOVE_TYPE_TAG}, }; /// To register an on-chain config in Rust: @@ -185,9 +190,18 @@ pub trait OnChainConfig: Send + Sync + DeserializeOwned { where T: ConfigStorage + ?Sized, { - let state_key = StateKey::on_chain_config::().ok()?; - let bytes = storage.fetch_config_bytes(&state_key)?; - Self::deserialize_into_config(&bytes).ok() + Self::try_fetch_config(storage).ok() + } + + fn try_fetch_config(storage: &T) -> Result + where + T: ConfigStorage + ?Sized, + { + let state_key = StateKey::on_chain_config::()?; + let bytes = storage + .fetch_config_bytes(&state_key) + .context("Could not fetch config bytes from storage")?; + Self::deserialize_into_config(&bytes) } fn address() -> &'static AccountAddress { diff --git a/types/src/proof/definition.rs b/types/src/proof/definition.rs index 15eb25d2adc..143d59bef60 100644 --- a/types/src/proof/definition.rs +++ b/types/src/proof/definition.rs @@ -32,14 +32,36 @@ use std::{any::type_name, marker::PhantomData}; /// example, both `LedgerInfoToTransactionInfoProof` and `TransactionInfoToEventProof` can be /// constructed on top of this structure. #[derive(Clone, Serialize, Deserialize)] +#[cfg_attr( + feature = "rest_api_schema", + derive(utoipa::ToSchema), + schema(bound = "") +)] pub struct AccumulatorProof { /// All siblings in this proof, including the default ones. Siblings are ordered from the bottom /// level to the root level. + #[cfg_attr(feature = "rest_api_schema",schema(value_type = String))] siblings: Vec, - + #[serde(skip)] + #[cfg_attr(feature = "rest_api_schema", schema(ignore))] phantom: PhantomData, } +#[cfg(test)] +mod tests { + #[cfg(feature = "rest_api_schema")] + #[test] + fn feature() { + use crate::proof::{AccumulatorProof, TransactionAccumulatorHasher}; + + #[derive(utoipa::ToSchema)] + pub struct TransactionInclusionProof { + #[schema(value_type = AccumulatorProof)] + pub proof: AccumulatorProof, + } + } +} + /// Because leaves can only take half the space in the tree, any numbering of the tree leaves must /// not take the full width of the total space. Thus, for a 64-bit ordering, our maximumm proof /// depth is limited to 63. diff --git a/types/src/proof/position/mod.rs b/types/src/proof/position/mod.rs index c06beef5072..4cb4e56ef68 100644 --- a/types/src/proof/position/mod.rs +++ b/types/src/proof/position/mod.rs @@ -26,12 +26,13 @@ use crate::proof::definition::{LeafCount, MAX_ACCUMULATOR_LEAVES, MAX_ACCUMULATOR_PROOF_DEPTH}; use anyhow::{ensure, Result}; +use serde::{Deserialize, Serialize}; use std::fmt; #[cfg(test)] mod position_test; -#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize)] pub struct Position(u64); // invariant Position.0 < u64::max_value() - 1 @@ -54,8 +55,7 @@ impl Position { /// What position is the node within the level? i.e. how many nodes /// are to the left of this node at the same level - #[cfg(test)] - fn pos_counting_from_left(self) -> u64 { + pub fn pos_counting_from_left(self) -> u64 { self.0 >> (self.level() + 1) } diff --git a/types/src/proptest_types.rs b/types/src/proptest_types.rs index 906d4ce84ca..d81e8a68f24 100644 --- a/types/src/proptest_types.rs +++ b/types/src/proptest_types.rs @@ -14,7 +14,7 @@ use crate::{ block_metadata_ext::BlockMetadataExt, chain_id::ChainId, contract_event::ContractEvent, - dkg::{DKGTranscript, DKGTranscriptMetadata}, + dkg::transactions::{DKGTransactionData, DKGTransactionType}, epoch_state::EpochState, event::{EventHandle, EventKey}, ledger_info::{generate_ledger_info_with_sig, LedgerInfo, LedgerInfoWithSignatures}, @@ -1287,13 +1287,14 @@ impl Arbitrary for ValidatorTransaction { fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { (any::>()) .prop_map(|payload| { - ValidatorTransaction::DKGResult(DKGTranscript { - metadata: DKGTranscriptMetadata { - epoch: 0, - author: AccountAddress::ZERO, - }, - transcript_bytes: payload, - }) + ValidatorTransaction::DKG(DKGTransactionData::new( + 0, + AccountAddress::ZERO, + payload, + vec![], + vec![], + DKGTransactionType::DKGMeta, + )) }) .boxed() } diff --git a/types/src/stake_pool.rs b/types/src/stake_pool.rs index 8f7d9098d59..d6170ad9c31 100644 --- a/types/src/stake_pool.rs +++ b/types/src/stake_pool.rs @@ -2,10 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{account_address::AccountAddress, event::EventHandle}; +use move_core_types::{ + ident_str, + identifier::IdentStr, + language_storage::TypeTag, + move_resource::{MoveResource, MoveStructType}, +}; +use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; -use move_core_types::ident_str; -use move_core_types::identifier::IdentStr; -use move_core_types::move_resource::{MoveResource, MoveStructType}; #[derive(Debug, Serialize, Deserialize)] pub struct StakePool { @@ -72,14 +76,25 @@ pub struct ReactivateStakeEvent { pub amount: u64, } -#[derive(Debug, Serialize, Deserialize)] +/// Emitted when a validator's consensus key is rotated via `stake::rotate_consensus_key`. +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct RotateConsensusKeyEvent { pub pool_address: AccountAddress, pub old_consensus_pubkey: Vec, pub new_consensus_pubkey: Vec, } -#[derive(Debug, Serialize, Deserialize)] +impl MoveStructType for RotateConsensusKeyEvent { + const MODULE_NAME: &'static IdentStr = ident_str!("stake"); + const STRUCT_NAME: &'static IdentStr = ident_str!("RotateConsensusKey"); +} + +pub static ROTATE_CONSENSUS_KEY_EVENT_TYPE_TAG: Lazy = + Lazy::new(|| TypeTag::Struct(Box::new(RotateConsensusKeyEvent::struct_tag()))); + +/// Emitted when a validator's network and fullnode addresses are updated via +/// `stake::update_network_and_fullnode_addresses`. +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct UpdateNetworkAndFullnodeAddressesEvent { pub pool_address: AccountAddress, pub old_network_addresses: Vec, @@ -88,6 +103,17 @@ pub struct UpdateNetworkAndFullnodeAddressesEvent { pub new_fullnode_addresses: Vec, } +impl MoveStructType for UpdateNetworkAndFullnodeAddressesEvent { + const MODULE_NAME: &'static IdentStr = ident_str!("stake"); + const STRUCT_NAME: &'static IdentStr = ident_str!("UpdateNetworkAndFullnodeAddresses"); +} + +pub static UPDATE_NETWORK_ADDRESSES_EVENT_TYPE_TAG: Lazy = Lazy::new(|| { + TypeTag::Struct(Box::new( + UpdateNetworkAndFullnodeAddressesEvent::struct_tag(), + )) +}); + #[derive(Debug, Serialize, Deserialize)] pub struct IncreaseLockupEvent { pub pool_address: AccountAddress, diff --git a/types/src/transaction/automated_transaction.rs b/types/src/transaction/automated_transaction.rs index 7b1d1cf042c..317547326be 100644 --- a/types/src/transaction/automated_transaction.rs +++ b/types/src/transaction/automated_transaction.rs @@ -1,10 +1,16 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 -use std::cmp::Ordering; -use crate::chain_id::ChainId; -use crate::transaction::automation::{AutomationTaskMetaData, AutomationTaskType, Priority}; -use crate::transaction::{EntryFunction, RawTransaction, Transaction, TransactionPayload}; +use crate::{ + chain_id::ChainId, + transaction::{ + automation::{AutomationTaskMetaData, AutomationTaskType, Priority}, + EntryFunction, RawTransaction, Transaction, TransactionPayload, + }, +}; use anyhow::anyhow; use aptos_crypto::HashValue; use derive_getters::Getters; @@ -12,9 +18,7 @@ use derive_more::Constructor; use move_core_types::account_address::AccountAddress; use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; -use std::fmt; -use std::fmt::Debug; -use std::ops::Deref; +use std::{cmp::Ordering, fmt, fmt::Debug, ops::Deref}; /// A transaction that has been created based on the automation-task in automation registry. /// @@ -172,7 +176,6 @@ impl From for Transaction { } } - impl PartialOrd for AutomatedTransactionDescriptor { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) @@ -182,21 +185,15 @@ impl PartialOrd for AutomatedTransactionDescriptor { impl Ord for AutomatedTransactionDescriptor { fn cmp(&self, other: &Self) -> Ordering { match self.task_type.cmp(&other.task_type) { - Ordering::Less => { - Ordering::Less - } - Ordering::Equal => { - self.priority.cmp(&other.priority) - } - Ordering::Greater => { - Ordering::Greater - } + Ordering::Less => Ordering::Less, + Ordering::Equal => self.priority.cmp(&other.priority), + Ordering::Greater => Ordering::Greater, } } } macro_rules! value_or_missing { - ($value: ident , $message: literal) => { + ($value:ident, $message:literal) => { match $value { Some(v) => v, None => return BuilderResult::missing_value($message), @@ -285,6 +282,7 @@ impl AutomatedTransactionBuilder { pub fn new() -> Self { Self::default() } + pub fn with_gas_price_cap(mut self, cap: u64) -> Self { self.gas_price_cap = cap; self @@ -294,10 +292,12 @@ impl AutomatedTransactionBuilder { self.sender = Some(sender); self } + pub fn with_sequence_number(mut self, seq: u64) -> Self { self.sequence_number = Some(seq); self } + pub fn with_payload(mut self, payload: TransactionPayload) -> Self { self.payload = Some(payload); self @@ -307,26 +307,32 @@ impl AutomatedTransactionBuilder { self.payload = Some(TransactionPayload::EntryFunction(entry_fn)); self } + pub fn with_max_gas_amount(mut self, max_gas_amount: u64) -> Self { self.max_gas_amount = Some(max_gas_amount); self } + pub fn with_gas_unit_price(mut self, gas_unit_price: u64) -> Self { self.gas_unit_price = Some(gas_unit_price); self } + pub fn with_expiration_timestamp_secs(mut self, secs: u64) -> Self { self.expiration_timestamp_secs = Some(secs); self } + pub fn with_chain_id(mut self, chain_id: ChainId) -> Self { self.chain_id = Some(chain_id); self } + pub fn with_authenticator(mut self, authenticator: HashValue) -> Self { self.authenticator = Some(authenticator); self } + pub fn with_block_height(mut self, block_height: u64) -> Self { self.block_height = Some(block_height); self diff --git a/types/src/transaction/automation.rs b/types/src/transaction/automation.rs index bb874ebda39..c374987485d 100644 --- a/types/src/transaction/automation.rs +++ b/types/src/transaction/automation.rs @@ -1,17 +1,23 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2025 Supra. // SPDX-License-Identifier: Apache-2.0 -use crate::on_chain_config::{FeatureFlag, Features}; -use crate::transaction::{EntryFunction, Transaction}; +use crate::{ + on_chain_config::{FeatureFlag, Features}, + transaction::{EntryFunction, Transaction}, +}; use aptos_crypto::HashValue; use derive_getters::Getters; use derive_more::Constructor; -use move_core_types::account_address::AccountAddress; -use move_core_types::identifier::{IdentStr, Identifier}; -use move_core_types::language_storage::{ModuleId, TypeTag, CORE_CODE_ADDRESS}; -use move_core_types::value::{serialize_values, MoveValue}; -use once_cell::sync::Lazy; -use once_cell::unsync::OnceCell; +use move_core_types::{ + account_address::AccountAddress, + identifier::{IdentStr, Identifier}, + language_storage::{ModuleId, TypeTag, CORE_CODE_ADDRESS}, + value::{serialize_values, MoveValue}, +}; +use once_cell::{sync::Lazy, unsync::OnceCell}; #[cfg(any(test, feature = "fuzzing"))] use proptest_derive::Arbitrary; use serde::{Deserialize, Serialize}; @@ -219,6 +225,7 @@ impl RegistrationParams { }, } } + pub fn task_type(&self) -> AutomationTaskType { match self { RegistrationParams::V1(p) => p.task_type(), @@ -262,6 +269,7 @@ impl RegistrationParamsV1 { self.aux_data, ) } + /// Module id containing registration function. pub fn module_id(&self) -> &ModuleId { &AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS.module_id @@ -371,6 +379,7 @@ impl RegistrationParamsV2 { self.priority_value, ) } + /// Module id containing registration function. pub fn module_id(&self) -> &ModuleId { &AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS.module_id @@ -518,7 +527,6 @@ impl TryFrom<&[u8]> for AutomationTaskType { } } - /// Describes the state of the automation task // The order of the entries is important, a new one should be appended at the end. #[derive(Clone, Copy, Debug, Hash, Serialize, Deserialize, PartialEq, Eq)] @@ -535,13 +543,11 @@ impl AutomationTaskState { pub fn is_active(&self) -> bool { match self { AutomationTaskState::Pending => false, - AutomationTaskState::Active | - AutomationTaskState::Cancelled => true + AutomationTaskState::Active | AutomationTaskState::Cancelled => true, } } } - /// Rust representation of the Automation task meta information in Move. #[derive(Clone, Debug, Serialize, Deserialize, Getters, Constructor)] pub struct AutomationTaskMetaData { @@ -578,8 +584,8 @@ pub struct AutomationTaskMetaData { pub(crate) priority: OnceCell>, } impl AutomationTaskMetaData { - const TASK_TYPE_AUX_INDEX: usize = 0; const TASK_PRIORITY_AUX_INDEX: usize = 1; + const TASK_TYPE_AUX_INDEX: usize = 0; #[allow(clippy::too_many_arguments)] pub fn create( @@ -682,35 +688,37 @@ impl AutomationTaskMetaData { /// Consumes the input and returns properties flattened. /// No property is modified. /// To get exact values of the task type and priority corresponding special getter functions should be used. - pub fn flatten(self) -> - (u64, - AccountAddress, - Vec, - u64, - Vec, - u64, - u64, - u64, - Vec>, - u64, - AutomationTaskState, - u64, - ) { - ( - self.id, - self.owner, - self.payload_tx, - self.expiry_time, - self.tx_hash, - self.max_gas_amount, - self.gas_price_cap, - self.automation_fee_cap_for_epoch, - self.aux_data, - self.registration_time, - self.state, - self.locked_fee_for_next_epoch, - ) - } + pub fn flatten( + self, + ) -> ( + u64, + AccountAddress, + Vec, + u64, + Vec, + u64, + u64, + u64, + Vec>, + u64, + AutomationTaskState, + u64, + ) { + ( + self.id, + self.owner, + self.payload_tx, + self.expiry_time, + self.tx_hash, + self.max_gas_amount, + self.gas_price_cap, + self.automation_fee_cap_for_epoch, + self.aux_data, + self.registration_time, + self.state, + self.locked_fee_for_next_epoch, + ) + } } /// Action to be performed on automation registry. diff --git a/types/src/transaction/mod.rs b/types/src/transaction/mod.rs index 4bd736c65b5..5d36872db64 100644 --- a/types/src/transaction/mod.rs +++ b/types/src/transaction/mod.rs @@ -56,24 +56,32 @@ pub mod user_transaction_context; pub mod webauthn; pub use self::block_epilogue::{BlockEndInfo, BlockEpiloguePayload}; -use crate::move_utils::MemberId; -use crate::serde_helper::vec_bytes; #[cfg(any(test, feature = "fuzzing"))] use crate::state_store::create_empty_sharded_state_updates; -use crate::transaction::automated_transaction::AutomatedTransaction; -use crate::transaction::automation::{AutomationRegistryRecord, RegistrationParams}; use crate::{ - block_metadata_ext::BlockMetadataExt, contract_event::TransactionEvent, executable::ModulePath, - fee_statement::FeeStatement, proof::accumulator::InMemoryEventAccumulator, - validator_txn::ValidatorTransaction, write_set::TransactionWrite, + block_metadata_ext::BlockMetadataExt, + contract_event::TransactionEvent, + executable::ModulePath, + fee_statement::FeeStatement, + move_utils::MemberId, + proof::accumulator::InMemoryEventAccumulator, + serde_helper::vec_bytes, + transaction::{ + automated_transaction::AutomatedTransaction, + automation::{AutomationRegistryRecord, RegistrationParams}, + }, + validator_txn::ValidatorTransaction, + write_set::TransactionWrite, }; pub use block_output::BlockOutput; pub use change_set::ChangeSet; pub use module::{Module, ModuleBundle}; -use move_core_types::identifier::{IdentStr, Identifier}; -use move_core_types::language_storage::{ModuleId, TypeTag}; pub use move_core_types::transaction_argument::TransactionArgument; -use move_core_types::vm_status::AbortLocation; +use move_core_types::{ + identifier::{IdentStr, Identifier}, + language_storage::{ModuleId, TypeTag}, + vm_status::AbortLocation, +}; use move_vm_types::delayed_values::delayed_field_id::{ ExtractUniqueIndex, ExtractWidth, TryFromMoveValue, TryIntoMoveValue, }; @@ -2084,7 +2092,7 @@ impl Transaction { Transaction::BlockMetadataExt(_) => "block_metadata_ext", Transaction::AutomatedTransaction(_) => "automated_transaction", Transaction::AutomationRegistryTransaction(_) => "automation_registry_transaction", - Transaction::SystemAutomatedTransaction(_) => "system_automated_transaction" + Transaction::SystemAutomatedTransaction(_) => "system_automated_transaction", } } diff --git a/types/src/transaction/multisig.rs b/types/src/transaction/multisig.rs index 4ee6704f826..129b39c3a56 100644 --- a/types/src/transaction/multisig.rs +++ b/types/src/transaction/multisig.rs @@ -1,10 +1,11 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::transaction::{user_transaction_context::MultisigPayload, EntryFunction}; +use crate::transaction::{ + automation::RegistrationParams, user_transaction_context::MultisigPayload, EntryFunction, +}; use move_core_types::{account_address::AccountAddress, vm_status::VMStatus}; use serde::{Deserialize, Serialize}; -use crate::transaction::automation::RegistrationParams; /// A multisig transaction that allows an owner of a multisig account to execute a pre-approved /// transaction as the multisig account. @@ -21,34 +22,27 @@ pub struct Multisig { #[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)] pub enum MultisigTransactionPayload { EntryFunction(EntryFunction), - AutomationRegistration(RegistrationParams) + AutomationRegistration(RegistrationParams), } impl Multisig { pub fn as_multisig_payload(&self) -> MultisigPayload { match &self.transaction_payload { - None => { - MultisigPayload { - multisig_address: self.multisig_address, - entry_function_payload: None, - is_automation_registration: None, - } - } - Some(MultisigTransactionPayload::AutomationRegistration(_)) => { - MultisigPayload { - multisig_address: self.multisig_address, - entry_function_payload: None, - is_automation_registration: Some(true), - } - } - Some(MultisigTransactionPayload::EntryFunction(entry)) => { - MultisigPayload { - multisig_address: self.multisig_address, - entry_function_payload: - Some(entry.as_entry_function_payload()), - is_automation_registration: Some(false), - } - } + None => MultisigPayload { + multisig_address: self.multisig_address, + entry_function_payload: None, + is_automation_registration: None, + }, + Some(MultisigTransactionPayload::AutomationRegistration(_)) => MultisigPayload { + multisig_address: self.multisig_address, + entry_function_payload: None, + is_automation_registration: Some(true), + }, + Some(MultisigTransactionPayload::EntryFunction(entry)) => MultisigPayload { + multisig_address: self.multisig_address, + entry_function_payload: Some(entry.as_entry_function_payload()), + is_automation_registration: Some(false), + }, } } } diff --git a/types/src/transaction/user_transaction_context.rs b/types/src/transaction/user_transaction_context.rs index 4ca99a07129..4d9e504fce0 100644 --- a/types/src/transaction/user_transaction_context.rs +++ b/types/src/transaction/user_transaction_context.rs @@ -20,7 +20,6 @@ pub enum PayloadTypeReference { AutomationRegistration, } - impl PayloadTypeReference where EFP: Clone + Debug, diff --git a/types/src/unit_tests/automation.rs b/types/src/unit_tests/automation.rs index 46ddc713434..eb361d3845c 100644 --- a/types/src/unit_tests/automation.rs +++ b/types/src/unit_tests/automation.rs @@ -1,12 +1,22 @@ +// Copyright (c) Aptos Foundation +// SPDX-License-Identifier: Apache-2.0 + // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 -use crate::chain_id::ChainId; -use crate::move_utils::MemberId; -use crate::on_chain_config::{FeatureFlag, Features}; -use crate::transaction::automated_transaction::{AutomatedTransactionBuilder, BuilderResult}; -use crate::transaction::automation::{AutomationRegistryAction, AutomationRegistryRecordBuilder, AutomationTaskMetaData, AutomationTaskState, AutomationTaskType, RegistrationParams}; -use crate::transaction::{EntryFunction, TransactionPayload}; +use crate::{ + chain_id::ChainId, + move_utils::MemberId, + on_chain_config::{FeatureFlag, Features}, + transaction::{ + automated_transaction::{AutomatedTransactionBuilder, BuilderResult}, + automation::{ + AutomationRegistryAction, AutomationRegistryRecordBuilder, AutomationTaskMetaData, + AutomationTaskState, AutomationTaskType, RegistrationParams, + }, + EntryFunction, TransactionPayload, + }, +}; use aptos_crypto::HashValue; use move_core_types::account_address::AccountAddress; use std::str::FromStr; @@ -23,7 +33,9 @@ fn test_registration_params_serde() { let automation_fee_cap_for_epoch = 50_000_000; let aux_data = vec![vec![1u8, 1, 2, 3]]; // Includes task type prepended to the user specified one. - let expected_aux_data = vec![vec![AutomationTaskType::User as u8], vec![], vec![1u8, 1, 2, 3]]; + let expected_aux_data = vec![vec![AutomationTaskType::User as u8], vec![], vec![ + 1u8, 1, 2, 3, + ]]; let entry_function = EntryFunction::new(module_id, member_id, vec![], vec![]); let registration_params = RegistrationParams::new_user_automation_task_v1( entry_function.clone(), @@ -157,7 +169,9 @@ fn test_registration_params_v2_user_task_serde() { aux_data.clone(), None, ); - let expected_aux_data = vec![vec![AutomationTaskType::User as u8], vec![], vec![1u8, 1, 2, 3]]; + let expected_aux_data = vec![vec![AutomationTaskType::User as u8], vec![], vec![ + 1u8, 1, 2, 3, + ]]; let serialized = registration_params.serialized_args_with_sender_and_parent_hash( address, parent_hash.to_vec(), @@ -245,7 +259,9 @@ fn test_registration_params_system_task_serde() { aux_data.clone(), None, ); - let expected_aux_data = vec![vec![AutomationTaskType::System as u8], vec![], vec![1u8, 1, 2, 3]]; + let expected_aux_data = vec![vec![AutomationTaskType::System as u8], vec![], vec![ + 1u8, 1, 2, 3, + ]]; let serialized = registration_params.serialized_args_with_sender_and_parent_hash( address, parent_hash.to_vec(), @@ -317,7 +333,10 @@ fn automation_task_metadata_type_priority_expansion() { // Aux data with type info, and valid priority results with specified priority and type let task_meta_with_valid_type_priority = AutomationTaskMetaData { - aux_data: vec![vec![AutomationTaskType::System as u8], bcs::to_bytes(&42u64).unwrap()], + aux_data: vec![ + vec![AutomationTaskType::System as u8], + bcs::to_bytes(&42u64).unwrap(), + ], task_type: Default::default(), priority: Default::default(), ..task_meta.clone() @@ -458,7 +477,10 @@ fn automated_txn_builder_from_task_meta() { // Check builder construction when type is specified and priority is valid data. let task_meta_with_valid_type_and_priority = AutomationTaskMetaData { - aux_data: vec![vec![AutomationTaskType::System as u8], bcs::to_bytes(&45u64).unwrap()], + aux_data: vec![ + vec![AutomationTaskType::System as u8], + bcs::to_bytes(&45u64).unwrap(), + ], ..task_meta_valid.clone() }; let builder = diff --git a/types/src/unit_tests/mod.rs b/types/src/unit_tests/mod.rs index 2185535d8b3..ceae6f8b7b7 100644 --- a/types/src/unit_tests/mod.rs +++ b/types/src/unit_tests/mod.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 mod access_path_test; +mod automation; mod block_metadata_test; mod code_debug_fmt_test; mod contract_event_test; @@ -11,4 +12,3 @@ mod transaction_test; mod trusted_state_test; mod validator_set_test; mod write_set_test; -mod automation; diff --git a/types/src/validator_config.rs b/types/src/validator_config.rs index 3e2354ee998..65baf9ed0ea 100644 --- a/types/src/validator_config.rs +++ b/types/src/validator_config.rs @@ -2,8 +2,8 @@ // Parts of the project are originally copyright © Meta Platforms, Inc. // SPDX-License-Identifier: Apache-2.0 -use crate::network_address::NetworkAddress; -use aptos_crypto::ed25519; +use crate::{network_address::NetworkAddress, validator_public_keys::ValidatorPublicKeys}; +use aptos_crypto::{ed25519, ed25519::PublicKey as Ed25519PublicKey}; use move_core_types::{ ident_str, identifier::IdentStr, @@ -35,7 +35,7 @@ impl MoveResource for ValidatorOperatorConfigResource {} #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] #[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))] pub struct ValidatorConfig { - pub consensus_public_key: ed25519::PublicKey, + consensus_public_key: Vec, /// This is an bcs serialized `Vec` pub validator_network_addresses: Vec, /// This is an bcs serialized `Vec` @@ -51,13 +51,29 @@ impl ValidatorConfig { validator_index: u64, ) -> Self { ValidatorConfig { - consensus_public_key, + consensus_public_key: consensus_public_key.to_bytes().to_vec(), validator_network_addresses, fullnode_network_addresses, validator_index, } } + pub fn consensus_key_raw(&self) -> Vec { + self.consensus_public_key.clone() + } + + pub fn consensus_public_key(&self) -> Ed25519PublicKey { + let keys = bcs::from_bytes::(&self.consensus_public_key); + if let Ok(keys) = keys { + let ed_key = Ed25519PublicKey::try_from(keys.supra_keys().ed25519_key().as_slice()) + .expect("Failed to deserialize consensus public key from on-chain representation"); + return ed_key; + } + + Ed25519PublicKey::try_from(&self.consensus_public_key[..]) + .expect("Failed to deserialize consensus public key from on-chain representation") + } + pub fn fullnode_network_addresses(&self) -> Result, bcs::Error> { bcs::from_bytes(&self.fullnode_network_addresses) } diff --git a/types/src/validator_info.rs b/types/src/validator_info.rs index 01f5c7f3fd0..999ec011df9 100644 --- a/types/src/validator_info.rs +++ b/types/src/validator_info.rs @@ -81,8 +81,13 @@ impl ValidatorInfo { } /// Returns the key for validating signed messages from this validator - pub fn consensus_public_key(&self) -> &ed25519::PublicKey { - &self.config.consensus_public_key + pub fn consensus_public_key(&self) -> ed25519::PublicKey { + self.config.consensus_public_key() + } + + /// Returns the key for validating signed messages from this validator + pub fn consensus_key_bytes(&self) -> ed25519::PublicKey { + self.config.consensus_public_key() } /// Returns the voting power for this validator diff --git a/types/src/validator_public_keys.rs b/types/src/validator_public_keys.rs new file mode 100644 index 00000000000..61b59b9b812 --- /dev/null +++ b/types/src/validator_public_keys.rs @@ -0,0 +1,82 @@ +use derive_getters::Getters; +use serde::{Deserialize, Serialize}; +use std::fmt; + +/// Reflection of supra_framework::validator_public_keys::InternalPublicKeys in Rust +#[derive(Clone, Debug, Serialize, Deserialize, Getters)] +pub struct InternalPublicKeys { + bls_multisig_key: Vec, + bls_threshold_validity_certificate_key: Option>, + bls_threshold_quorum_certificate_key: Option>, + bls_threshold_unanimous_certificate_key: Option>, + bls_threshold_bcft_validity_certificate_key: Option>, + bls_threshold_bcft_quorum_certificate_key: Option>, + bls_threshold_bcft_fallback_view_change_certificate_key: Option>, + bls_threshold_clan_majority_certificate_key: Option>, + class_group_key: Vec, + ed25519_key: Vec, +} + +/// Reflection of supra_framework::validator_public_keys::ValidatorPublicKeys in Rust +#[derive(Clone, Debug, Serialize, Deserialize, Getters)] +pub struct ValidatorPublicKeys { + network_key: Vec, + supra_keys: InternalPublicKeys, +} + +impl ValidatorPublicKeys { + pub fn new( + network_key: Vec, + bls_multisig_key: Vec, + bls_threshold_validity_certificate_key: Option>, + bls_threshold_quorum_certificate_key: Option>, + bls_threshold_unanimous_certificate_key: Option>, + bls_threshold_bcft_validity_certificate_key: Option>, + bls_threshold_bcft_quorum_certificate_key: Option>, + bls_threshold_bcft_fallback_view_change_certificate_key: Option>, + bls_threshold_clan_majority_certificate_key: Option>, + class_group_key: Vec, + ed25519_key: Vec, + ) -> Self { + ValidatorPublicKeys { + network_key, + supra_keys: InternalPublicKeys { + bls_multisig_key, + bls_threshold_validity_certificate_key, + bls_threshold_quorum_certificate_key, + bls_threshold_unanimous_certificate_key, + bls_threshold_bcft_validity_certificate_key, + bls_threshold_bcft_quorum_certificate_key, + bls_threshold_bcft_fallback_view_change_certificate_key, + bls_threshold_clan_majority_certificate_key, + class_group_key, + ed25519_key, + }, + } + } +} + +#[derive(Debug)] +pub enum ValidatorPublicKeysError { + InvalidPublicKey, +} + +impl fmt::Display for ValidatorPublicKeysError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ValidatorPublicKeysError::InvalidPublicKey => write!(f, "Invalid public key format"), + } + } +} + +impl std::error::Error for ValidatorPublicKeysError {} + +impl TryFrom<&Vec> for ValidatorPublicKeys { + type Error = ValidatorPublicKeysError; + + fn try_from(bytes: &Vec) -> Result { + let validator_public_keys: ValidatorPublicKeys = + bcs::from_bytes(bytes).map_err(|_| ValidatorPublicKeysError::InvalidPublicKey)?; + Ok(validator_public_keys) + } +} diff --git a/types/src/validator_txn.rs b/types/src/validator_txn.rs index ad6481b36f5..36fe59ff03a 100644 --- a/types/src/validator_txn.rs +++ b/types/src/validator_txn.rs @@ -1,17 +1,14 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -#[cfg(any(test, feature = "fuzzing"))] -use crate::dkg::DKGTranscriptMetadata; -use crate::{dkg::DKGTranscript, jwks}; +use crate::{aptos_dkg::DKGTranscript, dkg::transactions::DKGTransactionData, jwks}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; -#[cfg(any(test, feature = "fuzzing"))] -use move_core_types::account_address::AccountAddress; use serde::{Deserialize, Serialize}; use std::fmt::Debug; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, CryptoHasher, BCSCryptoHash)] pub enum ValidatorTransaction { + DKG(DKGTransactionData), DKGResult(DKGTranscript), ObservedJWKUpdate(jwks::QuorumCertifiedUpdate), } @@ -19,13 +16,14 @@ pub enum ValidatorTransaction { impl ValidatorTransaction { #[cfg(any(test, feature = "fuzzing"))] pub fn dummy(payload: Vec) -> Self { - Self::DKGResult(DKGTranscript { - metadata: DKGTranscriptMetadata { - epoch: 999, - author: AccountAddress::ZERO, - }, - transcript_bytes: payload, - }) + Self::DKG(DKGTransactionData::new( + 999, + move_core_types::account_address::AccountAddress::ZERO, + payload, + vec![], + vec![], + crate::dkg::transactions::DKGTransactionType::DKGMeta, + )) } pub fn size_in_bytes(&self) -> usize { @@ -34,7 +32,8 @@ impl ValidatorTransaction { pub fn topic(&self) -> Topic { match self { - ValidatorTransaction::DKGResult(_) => Topic::DKG, + ValidatorTransaction::DKG(_) => Topic::DKG, + ValidatorTransaction::DKGResult(_) => Topic::DKG_RESULT, ValidatorTransaction::ObservedJWKUpdate(update) => { Topic::JWK_CONSENSUS(update.update.issuer.clone()) }, @@ -43,6 +42,7 @@ impl ValidatorTransaction { pub fn type_name(&self) -> &'static str { match self { + ValidatorTransaction::DKG(_) => "validator_transaction__dkg", ValidatorTransaction::DKGResult(_) => "validator_transaction__dkg_result", ValidatorTransaction::ObservedJWKUpdate(_) => { "validator_transaction__observed_jwk_update" @@ -55,5 +55,6 @@ impl ValidatorTransaction { #[allow(non_camel_case_types)] pub enum Topic { DKG, + DKG_RESULT, JWK_CONSENSUS(jwks::Issuer), } diff --git a/vm-validator/Cargo.toml b/vm-validator/Cargo.toml index 9372eb2cf18..132f4093ef0 100644 --- a/vm-validator/Cargo.toml +++ b/vm-validator/Cargo.toml @@ -27,7 +27,7 @@ aptos-cached-packages = { workspace = true } aptos-crypto = { workspace = true } aptos-db = { workspace = true } aptos-executor-test-helpers = { workspace = true } -aptos-gas-schedule = { workspace = true, features = ["testing"] } +aptos-gas-schedule = { workspace = true, features = ["testing"] } aptos-temppath = { workspace = true } aptos-types = { workspace = true } aptos-vm-genesis = { workspace = true } diff --git a/vm-validator/src/mocks/mock_vm_validator.rs b/vm-validator/src/mocks/mock_vm_validator.rs index 4e32e3a8bd4..4048644919b 100644 --- a/vm-validator/src/mocks/mock_vm_validator.rs +++ b/vm-validator/src/mocks/mock_vm_validator.rs @@ -6,11 +6,12 @@ use crate::vm_validator::TransactionValidation; use anyhow::Result; use aptos_types::{ account_address::AccountAddress, + dkg::transactions::DKGTransactionData, state_store::StateView, transaction::{SignedTransaction, VMValidatorResult}, vm_status::StatusCode, }; -use aptos_vm::VMValidator; +use aptos_vm::{move_vm_ext::AptosMoveResolver, VMValidator}; pub const ACCOUNT_DNE_TEST_ADD: AccountAddress = AccountAddress::new([0_u8; AccountAddress::LENGTH]); @@ -38,6 +39,14 @@ impl VMValidator for MockVMValidator { ) -> VMValidatorResult { VMValidatorResult::new(None, 0) } + + fn validate_dkg_validator_transaction( + &self, + _transaction: DKGTransactionData, + _state_view: &impl AptosMoveResolver, + ) -> VMValidatorResult { + VMValidatorResult::new(None, 0) + } } impl TransactionValidation for MockVMValidator { From 1e45800ddafb82332551169dbd665e275a1fa820 Mon Sep 17 00:00:00 2001 From: Yogesh <155965081+supra-yoga@users.noreply.github.com> Date: Mon, 13 Apr 2026 19:38:58 +0530 Subject: [PATCH 15/31] Update all related Gas schedule parameters as per SUP#3 proposal (#348) (#349) (#351) --- .github/workflows/aptos-framework-test.yaml | 54 ++++++++++++------- .../src/measurements_helpers.rs | 2 +- .../src/gas_schedule/transaction.rs | 6 +-- .../aptos-release-builder/src/validate.rs | 2 +- aptos-move/aptos-vm-benchmarks/src/helper.rs | 2 +- aptos-move/e2e-benchmark/src/main.rs | 2 +- config/global-constants/src/lib.rs | 4 +- config/src/config/api_config.rs | 2 +- crates/aptos/src/common/types.rs | 2 +- .../test_helpers/transaction_test_helpers.rs | 2 +- 10 files changed, 47 insertions(+), 31 deletions(-) diff --git a/.github/workflows/aptos-framework-test.yaml b/.github/workflows/aptos-framework-test.yaml index 9920b27f362..d3eba885a1a 100644 --- a/.github/workflows/aptos-framework-test.yaml +++ b/.github/workflows/aptos-framework-test.yaml @@ -1,4 +1,5 @@ name: Run aptos framework checks + on: push: branches: [ "dev", "release/**", "feature/**" ] @@ -7,37 +8,52 @@ on: types: [opened, synchronize, ready_for_review] branches: [ "dev", "release/**", "feature/**" ] paths-ignore: [ '**/*.md' ] + concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true + env: CARGO_TERM_COLOR: always CARGO_NET_GIT_FETCH_WITH_CLI: true DOCKER_BUILDKIT: 1 - FORGE_BIN: ~/.foundry/bin/forge - SUI_BIN: ~/.cargo/bin/sui - APTOS_BIN: ~/.local/bin/aptos - SCRYPTO_BIN: ~/.cargo/bin/scrypto - REPO_KEY: ${{ secrets.REPO_KEY }} jobs: build: runs-on: [self-hosted, do-ephemeral] timeout-minutes: 90 + steps: - - name: Install SSH Client - uses: webfactory/ssh-agent@v0.9.0 - with: - ssh-private-key: ${{ secrets.REPO_KEY }} + - name: Checkout code + uses: actions/checkout@v4 - - name: SSH key Scan + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + + - name: Setup SSH access run: | - mkdir -p ~/.ssh - ssh-keyscan github.com >> ~/.ssh/known_hosts - - - uses: dtolnay/rust-toolchain@stable - - uses: actions/checkout@v4 - - run: cargo test --release -p aptos-types --lib unit_tests --no-fail-fast - - run: cargo test --release -p aptos-framework -- --skip prover - - run: RUST_MIN_STACK=104857600 cargo test run -p language-e2e-testsuite --no-fail-fast - - run: RUST_MIN_STACK=104857600 cargo test run -p e2e-move-tests --no-fail-fast + mkdir -p ~/.ssh + + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + + ssh-keyscan github.com >> ~/.ssh/known_hosts + + echo "Host github.com + StrictHostKeyChecking no + " >> ~/.ssh/config + + - name: Test SSH connection + run: ssh -T git@github.com || true + + - name: Run aptos-types tests + run: cargo test --release -p aptos-types --lib unit_tests --no-fail-fast + + - name: Run aptos-framework tests + run: cargo test --release -p aptos-framework -- --skip prover + + - name: Run language e2e tests + run: RUST_MIN_STACK=104857600 cargo test run -p language-e2e-testsuite --no-fail-fast + + - name: Run move e2e tests + run: RUST_MIN_STACK=104857600 cargo test run -p e2e-move-tests --no-fail-fast diff --git a/aptos-move/aptos-gas-calibration/src/measurements_helpers.rs b/aptos-move/aptos-gas-calibration/src/measurements_helpers.rs index 3f242b4457d..c2cca96d6a0 100644 --- a/aptos-move/aptos-gas-calibration/src/measurements_helpers.rs +++ b/aptos-move/aptos-gas-calibration/src/measurements_helpers.rs @@ -59,7 +59,7 @@ pub fn execute_module_txn( let sign_tx = account .transaction() .sequence_number(sequence_number) - .max_gas_amount(2_000_000) + .max_gas_amount(2_000_000_000) .gas_unit_price(200) .payload(payload) .sign(); diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs index f9bee7c0fcf..b7c45f677a1 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/transaction.rs @@ -64,7 +64,7 @@ crate::gas_schedule::macros::define_gas_parameters!( [ max_price_per_gas_unit: FeePerGasUnit, "max_price_per_gas_unit", - 10_000_000_000 + 1_000_000_000 ], [ max_transaction_size_in_bytes: NumBytes, @@ -180,7 +180,7 @@ crate::gas_schedule::macros::define_gas_parameters!( [ storage_fee_per_state_slot: FeePerSlot, { 14.. => "storage_fee_per_state_slot" }, - // 0.8 million SUPRA for 2 billion state slots + // 800 million SUPRA for 2 billion state slots 40_000_000, ], [ @@ -191,7 +191,7 @@ crate::gas_schedule::macros::define_gas_parameters!( [ storage_fee_per_state_byte: FeePerByte, { 14.. => "storage_fee_per_state_byte" }, - // 0.8 million SUPRA for 2 TB state bytes + // 800 million SUPRA for 2 TB state bytes 40_000, ], [ diff --git a/aptos-move/aptos-release-builder/src/validate.rs b/aptos-move/aptos-release-builder/src/validate.rs index a3a51dcd8d3..e6d054e0e40 100644 --- a/aptos-move/aptos-release-builder/src/validate.rs +++ b/aptos-move/aptos-release-builder/src/validate.rs @@ -348,7 +348,7 @@ impl NetworkConfig { self.endpoint.as_str(), // Use the max gas unit for now. The simulate API sometimes cannot get the right gas estimate for proposals. "--max-gas", - "2000000", + "2000000000", ]; let rev = self.framework_git_rev.clone(); diff --git a/aptos-move/aptos-vm-benchmarks/src/helper.rs b/aptos-move/aptos-vm-benchmarks/src/helper.rs index aea964f3e20..76b765190f8 100644 --- a/aptos-move/aptos-vm-benchmarks/src/helper.rs +++ b/aptos-move/aptos-vm-benchmarks/src/helper.rs @@ -41,7 +41,7 @@ pub fn execute_module_txn( let sign_tx = account .transaction() .sequence_number(sequence_number) - .max_gas_amount(2_000_000) + .max_gas_amount(2_000_000_000) .gas_unit_price(200) .payload(payload) .sign(); diff --git a/aptos-move/e2e-benchmark/src/main.rs b/aptos-move/e2e-benchmark/src/main.rs index fc5600133bf..c1358d6d4fb 100644 --- a/aptos-move/e2e-benchmark/src/main.rs +++ b/aptos-move/e2e-benchmark/src/main.rs @@ -26,7 +26,7 @@ pub fn execute_txn( let sign_tx = account .transaction() .sequence_number(sequence_number) - .max_gas_amount(2_000_000) + .max_gas_amount(2_000_000_000) .gas_unit_price(200) .payload(payload) .sign(); diff --git a/config/global-constants/src/lib.rs b/config/global-constants/src/lib.rs index 04f26559d7c..a7fba4f0c73 100644 --- a/config/global-constants/src/lib.rs +++ b/config/global-constants/src/lib.rs @@ -29,9 +29,9 @@ pub const GAS_UNIT_PRICE: u64 = 0; pub const GAS_UNIT_PRICE: u64 = 100_000; #[cfg(any(test, feature = "testing"))] -pub const MAX_GAS_AMOUNT: u64 = 100_000_000; +pub const MAX_GAS_AMOUNT: u64 = 100_000_000_000; #[cfg(not(any(test, feature = "testing")))] -pub const MAX_GAS_AMOUNT: u64 = 2_000_000; +pub const MAX_GAS_AMOUNT: u64 = 2_000_000_000; pub const GAS_HEADROOM_NUMERATOR: u64 = 3; pub const GAS_HEADROOM_DENOMINATOR: u64 = 2; diff --git a/config/src/config/api_config.rs b/config/src/config/api_config.rs index 1758d8c2279..08536daca95 100644 --- a/config/src/config/api_config.rs +++ b/config/src/config/api_config.rs @@ -98,7 +98,7 @@ pub const DEFAULT_MAX_SUBMIT_TRANSACTION_BATCH_SIZE: usize = 10; pub const DEFAULT_MAX_PAGE_SIZE: u16 = 100; const DEFAULT_MAX_ACCOUNT_RESOURCES_PAGE_SIZE: u16 = 9999; const DEFAULT_MAX_ACCOUNT_MODULES_PAGE_SIZE: u16 = 9999; -const DEFAULT_MAX_VIEW_GAS: u64 = 2_000_000; // We keep this value the same as the max number of gas allowed for one single transaction defined in aptos-gas. +const DEFAULT_MAX_VIEW_GAS: u64 = 2_000_000_000; // We keep this value the same as the max number of gas allowed for one single transaction defined in aptos-gas. fn default_enabled() -> bool { true diff --git a/crates/aptos/src/common/types.rs b/crates/aptos/src/common/types.rs index 38027746bd1..3d2fc3caaf9 100644 --- a/crates/aptos/src/common/types.rs +++ b/crates/aptos/src/common/types.rs @@ -1800,7 +1800,7 @@ impl TransactionOptions { // Fetch the chain states required for the simulation // TODO(Gas): get the following from the chain const DEFAULT_GAS_UNIT_PRICE: u64 = 100; - const DEFAULT_MAX_GAS: u64 = 2_000_000; + const DEFAULT_MAX_GAS: u64 = 2_000_000_000; let (sender_key, sender_address) = self.get_key_and_address()?; let gas_unit_price = self diff --git a/types/src/test_helpers/transaction_test_helpers.rs b/types/src/test_helpers/transaction_test_helpers.rs index 65110d5c088..0ac7b57d4fb 100644 --- a/types/src/test_helpers/transaction_test_helpers.rs +++ b/types/src/test_helpers/transaction_test_helpers.rs @@ -17,7 +17,7 @@ use crate::{ }; use aptos_crypto::{ed25519::*, traits::*}; -const MAX_GAS_AMOUNT: u64 = 1_000_000; +const MAX_GAS_AMOUNT: u64 = 1_000_000_000; const TEST_GAS_PRICE: u64 = 100; // The block executor onchain config (gas limit parameters) for executor tests From 747d64cbde944709ae1dc7664996fc7ee068ff17 Mon Sep 17 00:00:00 2001 From: Isaac Doidge <30425649+isaacdoidge@users.noreply.github.com> Date: Sat, 18 Apr 2026 18:00:28 +1000 Subject: [PATCH 16/31] Updated validator public key validation logic (#352) * Updated validator public key validation logic to enable registration of new format keys before the related feature flag is active whilst maintaining backwards compatibility with the old format when the flag is off. * Restored original DKG framework module and move new Supra DKG into new module to restore compatibility with production framework. * Fixed DKG module names in Rust code. Missed in last commit. * Made DKG init function public for use in governance scripts. --- .../framework/supra-framework/doc/dkg.md | 445 ++------- .../doc/leader_ban_registry.md | 176 ++-- .../framework/supra-framework/doc/overview.md | 1 + .../supra-framework/doc/randomness_config.md | 39 +- .../doc/reconfiguration_with_dkg.md | 27 +- .../framework/supra-framework/doc/stake.md | 416 ++------- .../supra-framework/doc/supra_dkg.md | 843 ++++++++++++++++++ .../doc/validator_public_keys.md | 3 +- .../sources/configs/randomness_config.move | 54 +- .../supra-framework/sources/dkg.move | 179 +--- .../supra-framework/sources/dkg.spec.move | 22 +- .../sources/reconfiguration_with_dkg.move | 17 +- .../reconfiguration_with_dkg.spec.move | 12 +- .../supra-framework/sources/stake.move | 108 ++- .../supra-framework/sources/supra_dkg.move | 234 +++++ .../sources/supra_dkg.spec.move | 54 ++ .../sources/validator_public_keys.move | 4 +- aptos-move/vm-genesis/src/lib.rs | 2 +- types/src/dkg/events.rs | 6 +- types/src/dkg/state.rs | 8 +- 20 files changed, 1568 insertions(+), 1082 deletions(-) create mode 100644 aptos-move/framework/supra-framework/doc/supra_dkg.md create mode 100644 aptos-move/framework/supra-framework/sources/supra_dkg.move create mode 100644 aptos-move/framework/supra-framework/sources/supra_dkg.spec.move diff --git a/aptos-move/framework/supra-framework/doc/dkg.md b/aptos-move/framework/supra-framework/doc/dkg.md index 56657d41dd1..3138cd16fb8 100644 --- a/aptos-move/framework/supra-framework/doc/dkg.md +++ b/aptos-move/framework/supra-framework/doc/dkg.md @@ -3,58 +3,50 @@ # Module `0x1::dkg` +Deprecated. Replaced by supra_dkg. Retained because the module has already been deployed to +production. + DKG on-chain states and helper functions. -- [Struct `DKGStartEvent`](#0x1_dkg_DKGStartEvent) -- [Struct `DKGMetaSetEvent`](#0x1_dkg_DKGMetaSetEvent) -- [Struct `DKGFinishEvent`](#0x1_dkg_DKGFinishEvent) - [Struct `DKGSessionMetadata`](#0x1_dkg_DKGSessionMetadata) +- [Struct `DKGStartEvent`](#0x1_dkg_DKGStartEvent) - [Struct `DKGSessionState`](#0x1_dkg_DKGSessionState) - [Resource `DKGState`](#0x1_dkg_DKGState) -- [Struct `OnChainAggregateCommitment`](#0x1_dkg_OnChainAggregateCommitment) -- [Struct `OnChainAggregateCommitmentAllCommittees`](#0x1_dkg_OnChainAggregateCommitmentAllCommittees) - [Constants](#@Constants_0) - [Function `initialize`](#0x1_dkg_initialize) - [Function `start`](#0x1_dkg_start) -- [Function `set_dkg_meta`](#0x1_dkg_set_dkg_meta) - [Function `finish`](#0x1_dkg_finish) - [Function `try_clear_incomplete_session`](#0x1_dkg_try_clear_incomplete_session) - [Function `incomplete_session`](#0x1_dkg_incomplete_session) -- [Function `last_completed_session`](#0x1_dkg_last_completed_session) - [Function `session_dealer_epoch`](#0x1_dkg_session_dealer_epoch) - [Specification](#@Specification_1) - [Function `initialize`](#@Specification_1_initialize) - [Function `start`](#@Specification_1_start) - - [Function `set_dkg_meta`](#@Specification_1_set_dkg_meta) - [Function `finish`](#@Specification_1_finish) - [Function `try_clear_incomplete_session`](#@Specification_1_try_clear_incomplete_session) - [Function `incomplete_session`](#@Specification_1_incomplete_session) -
use 0x1::any;
-use 0x1::dkg_committee;
-use 0x1::error;
+
use 0x1::error;
 use 0x1::event;
 use 0x1::option;
-use 0x1::stake;
-use 0x1::string;
+use 0x1::randomness_config;
 use 0x1::system_addresses;
 use 0x1::timestamp;
-use 0x1::type_info;
-use 0x1::vector;
+use 0x1::validator_consensus_info;
 
- + -## Struct `DKGStartEvent` +## Struct `DKGSessionMetadata` +This can be considered as the public input of DKG. -
#[event]
-struct DKGStartEvent has drop, store
+
struct DKGSessionMetadata has copy, drop, store
 
@@ -65,69 +57,25 @@ DKG on-chain states and helper functions.
-session_metadata: dkg::DKGSessionMetadata +dealer_epoch: u64
-start_time_us: u64 +randomness_config: randomness_config::RandomnessConfig
-
- - -
- - - -## Struct `DKGMetaSetEvent` - - - -
#[event]
-struct DKGMetaSetEvent has drop, store
-
- - - -
-Fields - - -
-dkg_meta_transcript: vector<u8> +dealer_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>
-
- - -
- - - -## Struct `DKGFinishEvent` - - - -
#[event]
-struct DKGFinishEvent has drop, store
-
- - - -
-Fields - - -
-target_committees_public_key_shares: vector<u8> +target_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>
@@ -137,14 +85,14 @@ DKG on-chain states and helper functions.
- + -## Struct `DKGSessionMetadata` +## Struct `DKGStartEvent` -This can be considered as the public input of DKG. -
struct DKGSessionMetadata has copy, drop, store
+
#[event]
+struct DKGStartEvent has drop, store
 
@@ -155,25 +103,13 @@ This can be considered as the public input of DKG.
-dealer_epoch: u64 -
-
- -
-
-randomness_seed: vector<u8> -
-
- -
-
-dealer_committee: dkg_committee::DkgCommittee +session_metadata: dkg::DKGSessionMetadata
-target_committees: vector<dkg_committee::ReceiverCommittee> +start_time_us: u64
@@ -214,13 +150,7 @@ The validator set of epoch x works together for an DKG output for t
-dkg_meta_transcript: vector<u8> -
-
- -
-
-target_committees_public_key_shares: vector<u8> +transcript: vector<u8>
@@ -262,96 +192,6 @@ The completed and in-progress DKG sessions.
- - - - -## Struct `OnChainAggregateCommitment` - - - -
struct OnChainAggregateCommitment has copy, drop
-
- - - -
-Fields - - -
-
-bls12381_commitment_g: vector<u8> -
-
- -
-
-bls12381_commitment_evals: vector<vector<u8>> -
-
- -
-
-dealer_ids: vector<u32> -
-
- -
-
-committee_index: u32 -
-
- -
-
-epoch: u64 -
-
- -
-
-chain_id: u8 -
-
- -
-
-threshold_type: u8 -
-
- -
-
- - -
- - - -## Struct `OnChainAggregateCommitmentAllCommittees` - - - -
struct OnChainAggregateCommitmentAllCommittees has copy, drop
-
- - - -
-Fields - - -
-
-commitments: vector<dkg::OnChainAggregateCommitment> -
-
- -
-
- -
@@ -359,38 +199,20 @@ The completed and in-progress DKG sessions. ## Constants - - - - -
const EDKG_INVALID_PK_SHARES: u64 = 4;
-
- - - - - - - -
const EDKG_META_ALREADY_SET: u64 = 2;
-
- - - - + -
const EDKG_META_NOT_SET: u64 = 3;
+
const EDKG_NOT_IN_PROGRESS: u64 = 2;
 
- + -
const EDKG_NOT_IN_PROGRESS: u64 = 1;
+
const EDKG_IN_PROGRESS: u64 = 1;
 
@@ -402,7 +224,7 @@ The completed and in-progress DKG sessions. Called in genesis to initialize on-chain states. -
public(friend) fun initialize(supra_framework: &signer)
+
public fun initialize(supra_framework: &signer)
 
@@ -411,17 +233,17 @@ Called in genesis to initialize on-chain states. Implementation -
public(friend) fun initialize(supra_framework: &signer) {
+
public fun initialize(supra_framework: &signer) {
     system_addresses::assert_supra_framework(supra_framework);
     if (!exists<DKGState>(@supra_framework)) {
         move_to<DKGState>(
             supra_framework,
             DKGState {
                 last_completed: std::option::none(),
-                in_progress: std::option::none(),
+                in_progress: std::option::none()
             }
         );
-    };
+    }
 }
 
@@ -437,7 +259,7 @@ Mark on-chain DKG state as in-progress. Notify validators to start DKG. Abort if a DKG is already in progress. -
public(friend) fun start(dealer_epoch: u64, randomness_seed: vector<u8>, dealer_committee: dkg_committee::DkgCommittee, target_committees: vector<dkg_committee::ReceiverCommittee>)
+
public(friend) fun start(dealer_epoch: u64, randomness_config: randomness_config::RandomnessConfig, dealer_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>, target_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>)
 
@@ -448,68 +270,27 @@ Abort if a DKG is already in progress.
public(friend) fun start(
     dealer_epoch: u64,
-    randomness_seed: vector<u8>,
-    dealer_committee: DkgCommittee,
-    target_committees: vector<ReceiverCommittee>
+    randomness_config: RandomnessConfig,
+    dealer_validator_set: vector<ValidatorConsensusInfo>,
+    target_validator_set: vector<ValidatorConsensusInfo>
 ) acquires DKGState {
     let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
     let new_session_metadata = DKGSessionMetadata {
         dealer_epoch,
-        randomness_seed,
-        dealer_committee,
-        target_committees,
+        randomness_config,
+        dealer_validator_set,
+        target_validator_set
     };
     let start_time_us = timestamp::now_microseconds();
-    dkg_state.in_progress = std::option::some(DKGSessionState {
-        metadata: new_session_metadata,
-        start_time_us,
-        dkg_meta_transcript: vector[],
-        target_committees_public_key_shares: vector[],
-    });
-
-    emit(DKGStartEvent {
-        start_time_us,
-        session_metadata: new_session_metadata,
-    });
-}
-
- - - - - - - -## Function `set_dkg_meta` - -Family Node sets the DKGMeta for the in-progress DKG session -The dkg transcript is assumed to have been already verified by the aptos VM in process_dkg_result method - - -
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
-
- - - -
-Implementation - - -
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
-acquires DKGState {
-    // ensure dkg is in progress
-    let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
-    assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS));
-
-    // we only add the first DKG Meta proposed and ignore the rest
-    let session = option::extract(&mut dkg_state.in_progress);
-    assert!(vector::length(&session.dkg_meta_transcript) == 0, error::already_exists(EDKG_META_ALREADY_SET));
-    session.dkg_meta_transcript = dkg_meta_all_committees;
-    dkg_state.in_progress = option::some(session);
-
-    emit(DKGMetaSetEvent {
-        dkg_meta_transcript: dkg_meta_all_committees,
-    });
+    dkg_state.in_progress = std::option::some(
+        DKGSessionState {
+            metadata: new_session_metadata,
+            start_time_us,
+            transcript: vector[]
+        }
+    );
+
+    emit(DKGStartEvent { start_time_us, session_metadata: new_session_metadata });
 }
 
@@ -521,12 +302,12 @@ The dkg transcript is assumed to have been already verified by the aptos VM in < ## Function `finish` -Family Node sets the target_committees_public_key_shares for the in-progress DKG session and -marks the incomplete DKG session completed. -The target_committees_public_key_shares is assumed to be verified by the aptos VM before calling this function +Put a transcript into the currently incomplete DKG session, then mark it completed. + +Abort if DKG is not in progress. -
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
+
public(friend) fun finish(transcript: vector<u8>)
 
@@ -535,46 +316,16 @@ The target_committees_public_key_shares is assumed to be verified b Implementation -
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
-acquires DKGState {
-    // ensure dkg is in progress
+
public(friend) fun finish(transcript: vector<u8>) acquires DKGState {
     let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
-    assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS));
-
-    // DKG meta should be already set before `finish` is called
+    assert!(
+        option::is_some(&dkg_state.in_progress),
+        error::invalid_state(EDKG_NOT_IN_PROGRESS)
+    );
     let session = option::extract(&mut dkg_state.in_progress);
-    assert!(vector::length(&session.dkg_meta_transcript) > 0, error::already_exists(EDKG_META_NOT_SET));
-
-    session.target_committees_public_key_shares = target_committees_public_key_shares;
+    session.transcript = transcript;
     dkg_state.last_completed = option::some(session);
     dkg_state.in_progress = option::none();
-
-    // propagate updated keys to stake.move for all threshold types
-    let public_key_shares_all_comms_serialized
-        = any::new(type_info::type_name<OnChainAggregateCommitmentAllCommittees>(), target_committees_public_key_shares);
-    let public_key_shares_all_comms = any::unpack<OnChainAggregateCommitmentAllCommittees>(public_key_shares_all_comms_serialized);
-
-    // Build a vector of DkgCommitteeOutput for all committees
-    let committee_outputs = vector[];
-    let i = 0;
-    let len = vector::length(&public_key_shares_all_comms.commitments);
-    while (i < len) {
-        let commitment = vector::borrow(&public_key_shares_all_comms.commitments, i);
-        // As the first index contains the committee's threshold public key, we can skip that
-        let evals = vector::slice(&commitment.bls12381_commitment_evals, 1, vector::length(&commitment.bls12381_commitment_evals));
-
-        vector::push_back(
-            &mut committee_outputs,
-            new_dkg_committee_output(commitment.threshold_type, evals)
-        );
-        i = i + 1;
-    };
-
-    // Set all keys for all threshold types
-    stake::set_dkg_output_keys(committee_outputs);
-    emit(DKGFinishEvent {
-        target_committees_public_key_shares,
-    });
 }
 
@@ -638,35 +389,6 @@ Return the incomplete DKG session state, if it exists. -
- - - -## Function `last_completed_session` - -Return the last completed DKG session state, if it exists. - - -
public fun last_completed_session(): option::Option<dkg::DKGSessionState>
-
- - - -
-Implementation - - -
public fun last_completed_session(): Option<DKGSessionState> acquires DKGState {
-    if (exists<DKGState>(@supra_framework)) {
-        borrow_global<DKGState>(@supra_framework).last_completed
-    } else {
-        option::none()
-    }
-}
-
- - -
@@ -700,7 +422,21 @@ Return the dealer epoch of a DKGS -
invariant [suspendable] chain_status::is_operating() ==> exists<DKGState>(@supra_framework);
+
invariant [suspendable] chain_status::is_operating() ==>
+    exists<DKGState>(@supra_framework);
+
+ + + + + + + +
fun has_incomplete_session(): bool {
+   if (exists<DKGState>(@supra_framework)) {
+       option::spec_is_some(global<DKGState>(@supra_framework).in_progress)
+   } else { false }
+}
 
@@ -710,7 +446,7 @@ Return the dealer epoch of a DKGS ### Function `initialize` -
public(friend) fun initialize(supra_framework: &signer)
+
public fun initialize(supra_framework: &signer)
 
@@ -727,7 +463,7 @@ Return the dealer epoch of a DKGS ### Function `start` -
public(friend) fun start(dealer_epoch: u64, randomness_seed: vector<u8>, dealer_committee: dkg_committee::DkgCommittee, target_committees: vector<dkg_committee::ReceiverCommittee>)
+
public(friend) fun start(dealer_epoch: u64, randomness_config: randomness_config::RandomnessConfig, dealer_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>, target_validator_set: vector<validator_consensus_info::ValidatorConsensusInfo>)
 
@@ -739,30 +475,12 @@ Return the dealer epoch of a DKGS - - -### Function `set_dkg_meta` - - -
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
-
- - - - -
requires exists<DKGState>(@supra_framework);
-requires option::is_some(global<DKGState>(@supra_framework).in_progress);
-aborts_if false;
-
- - - ### Function `finish` -
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
+
public(friend) fun finish(transcript: vector<u8>)
 
@@ -775,21 +493,6 @@ Return the dealer epoch of a DKGS - - - - -
fun has_incomplete_session(): bool {
-   if (exists<DKGState>(@supra_framework)) {
-       option::spec_is_some(global<DKGState>(@supra_framework).in_progress)
-   } else {
-       false
-   }
-}
-
- - - ### Function `try_clear_incomplete_session` diff --git a/aptos-move/framework/supra-framework/doc/leader_ban_registry.md b/aptos-move/framework/supra-framework/doc/leader_ban_registry.md index 61973eb553f..c01e741007a 100644 --- a/aptos-move/framework/supra-framework/doc/leader_ban_registry.md +++ b/aptos-move/framework/supra-framework/doc/leader_ban_registry.md @@ -672,11 +672,25 @@ Add or update the ban registry as per block metadata if (!exists<LatestView>(@supra_framework)) { return }; let ban_registry = borrow_global_mut<BanRegistry>(@supra_framework); let latest_view = borrow_global_mut<LatestView>(@supra_framework); + + // Save the previous view before updating. Each failed proposer failed at a + // distinct round between the previous commit and the current commit, so we + // need this to reconstruct the actual round at which each ban was earned. + let previous_epoch = latest_view.epoch; + let previous_round = latest_view.round; + + // we expect that current_epoch == latest_view.epoch || current_epoch == latest_view.epoch + 1, + // but we don't assert this to be true here because it should be ensured by the consensus. + if (current_epoch < latest_view.epoch) { return }; + latest_view.epoch = current_epoch; latest_view.round = current_round; // ban the failed proposers - ban_failed_proposers(latest_view, failed_proposer_indices, ban_registry); + ban_failed_proposers( + current_epoch, previous_epoch, previous_round, + failed_proposer_indices, ban_registry + ); // remove expired bans reinstate_expired_bans(latest_view, ban_registry); @@ -691,10 +705,14 @@ Add or update the ban registry as per block metadata ## Function `ban_failed_proposers` -Adds failed proposer indices to ban registry +Adds failed proposer indices to ban registry. Each failed proposer failed at a +consecutive round between the previous commit and the current commit. The actual +failed round is reconstructed from the previous view: +- Same epoch: failed rounds start at previous_round + 1 +- Epoch boundary: failed rounds start at 0 (new epoch resets round to 0) -
fun ban_failed_proposers(latest_view: &leader_ban_registry::LatestView, failed_proposer_indices: vector<u64>, ban_registry: &mut leader_ban_registry::BanRegistry)
+
fun ban_failed_proposers(current_epoch: u64, previous_epoch: u64, previous_round: u64, failed_proposer_indices: vector<u64>, ban_registry: &mut leader_ban_registry::BanRegistry)
 
@@ -704,82 +722,97 @@ Adds failed proposer indices to ban registry
fun ban_failed_proposers(
-    latest_view: &LatestView,
+    current_epoch: u64,
+    previous_epoch: u64,
+    previous_round: u64,
     failed_proposer_indices: vector<u64>,
     ban_registry: &mut BanRegistry
 ) {
     let initial_ban_duration = get_initial_ban_duration();
     if (initial_ban_duration == 0) { return };
 
-    vector::for_each(
-        failed_proposer_indices,
-        |failed_validator_index| {
-            let validator_pool_address_opt =
-                stake::get_pool_address_from_index(failed_validator_index);
+    // Compute the first failed round based on whether the epoch changed.
+    let first_failed_round = if (previous_epoch == current_epoch) {
+        previous_round + 1
+    } else {
+        // Epoch boundary: the last block of the previous epoch was committed
+        // successfully, so failures start from round 0 of the new epoch.
+        0
+    };
 
-            if (option::is_some(&validator_pool_address_opt)) {
-                let validator_pool_address =
-                    option::extract(&mut validator_pool_address_opt);
-                let (is_banned, index) = vector::find(
-                    &ban_registry.bans,
-                    |v| {
-                        let v: &ValidatorBans = v;
-                        validator_pool_address == v.pool_address
-                    }
-                );
-                if (is_banned) {
-                    // Validator is already in registry (either banned or on probation).
-                    // Re-banning resets the ban period and increases consecutive count.
-                    // If the consensus code is implemented correctly then the validator should
-                    // not be re-banned whilst serving a ban as it should not be eligible for election
-                    // when banned (i.e. this branch should only be taken when a validator is on probation).
-                    let bans = vector::borrow_mut(&mut ban_registry.bans, index);
-                    bans.consecutive_bans = bans.consecutive_bans + 1;
-                    bans.active.round_earned = latest_view.round;
-                    bans.active.epoch_earned = latest_view.epoch;
-                    bans.active.rounds_served_in_previous_epochs = 0;
-                    bans.active.on_probation = false; // Reset to banned state
+    let i = 0;
+    let len = vector::length(&failed_proposer_indices);
+    while (i < len) {
+        let failed_validator_index = *vector::borrow(&failed_proposer_indices, i);
+        let failed_round = first_failed_round + i;
+
+        let validator_pool_address_opt =
+            stake::get_pool_address_from_index(failed_validator_index);
+
+        if (option::is_some(&validator_pool_address_opt)) {
+            let validator_pool_address =
+                option::extract(&mut validator_pool_address_opt);
+            let (is_banned, index) = vector::find(
+                &ban_registry.bans,
+                |v| {
+                    let v: &ValidatorBans = v;
+                    validator_pool_address == v.pool_address
+                }
+            );
+            if (is_banned) {
+                // Validator is already in registry (either banned or on probation).
+                // Re-banning resets the ban period and increases consecutive count.
+                // If the consensus code is implemented correctly then the validator should
+                // not be re-banned whilst serving a ban as it should not be eligible for election
+                // when banned (i.e. this branch should only be taken when a validator is on probation).
+                let bans = vector::borrow_mut(&mut ban_registry.bans, index);
+                bans.consecutive_bans = bans.consecutive_bans + 1;
+                bans.active.round_earned = failed_round;
+                bans.active.epoch_earned = current_epoch;
+                bans.active.rounds_served_in_previous_epochs = 0;
+                bans.active.on_probation = false; // Reset to banned state
+
+                if (features::module_event_enabled()) {
+                    event::emit(
+                        Banned {
+                            pool_address: validator_pool_address,
+                            epoch: current_epoch,
+                            round: failed_round,
+                            consecutive_bans: bans.consecutive_bans
+                        }
+                    );
+                }
+            } else {
+                let ban_registry_len = vector::length(&ban_registry.bans);
+                if (can_be_banned(ban_registry_len)) {
+                    let ban_with_address = ValidatorBans {
+                        active: ActiveBan {
+                            epoch_earned: current_epoch,
+                            round_earned: failed_round,
+                            rounds_served_in_previous_epochs: 0,
+                            on_probation: false
+                        },
+                        consecutive_bans: 0,
+                        pool_address: validator_pool_address
+                    };
+                    vector::push_back(&mut ban_registry.bans, ban_with_address);
 
                     if (features::module_event_enabled()) {
                         event::emit(
                             Banned {
-                                pool_address: validator_pool_address,
-                                epoch: latest_view.epoch,
-                                round: latest_view.round,
-                                consecutive_bans: bans.consecutive_bans
+                                pool_address: ban_with_address.pool_address,
+                                epoch: ban_with_address.active.epoch_earned,
+                                round: ban_with_address.active.round_earned,
+                                consecutive_bans: ban_with_address.consecutive_bans
                             }
                         );
                     }
-                } else {
-                    let ban_registry_len = vector::length(&ban_registry.bans);
-                    if (can_be_banned(ban_registry_len)) {
-                        let ban_with_address = ValidatorBans {
-                            active: ActiveBan {
-                                epoch_earned: latest_view.epoch,
-                                round_earned: latest_view.round,
-                                rounds_served_in_previous_epochs: 0,
-                                on_probation: false
-                            },
-                            consecutive_bans: 0,
-                            pool_address: validator_pool_address
-                        };
-                        vector::push_back(&mut ban_registry.bans, ban_with_address);
-
-                        if (features::module_event_enabled()) {
-                            event::emit(
-                                Banned {
-                                    pool_address: ban_with_address.pool_address,
-                                    epoch: ban_with_address.active.epoch_earned,
-                                    round: ban_with_address.active.round_earned,
-                                    consecutive_bans: ban_with_address.consecutive_bans
-                                }
-                            );
-                        }
-                    }
-                };
+                }
             };
-        }
-    );
+        };
+
+        i = i + 1;
+    };
 }
 
@@ -1043,8 +1076,19 @@ Calculate the number of rounds remaining in a given ban (not including probation ): u64 { let initial_ban_duration = get_initial_ban_duration(); let max_ban_duration = get_max_ban_duration(); - let duration = initial_ban_duration * pow(2, (ban.consecutive_bans as u64)); - let duration = min(duration, max_ban_duration); + // Guard against overflow: pow(2, n) overflows u64 when n >= 64, and the + // subsequent multiplication can overflow for smaller exponents. In both cases + // the uncapped result would exceed max_ban_duration, so we short-circuit. + let duration = if ((ban.consecutive_bans as u64) >= 64) { + max_ban_duration + } else { + let scale = pow(2, (ban.consecutive_bans as u64)); + if (initial_ban_duration > 0 && scale > max_ban_duration / initial_ban_duration) { + max_ban_duration + } else { + min(initial_ban_duration * scale, max_ban_duration) + } + }; let rounds_served = if (latest_view.epoch > ban.active.epoch_earned) { ban.active.rounds_served_in_previous_epochs + latest_view.round diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 9c2cd430980..0bf36b9ced1 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -69,6 +69,7 @@ This is the reference documentation of the Supra framework. - [`0x1::supra_account`](supra_account.md#0x1_supra_account) - [`0x1::supra_coin`](supra_coin.md#0x1_supra_coin) - [`0x1::supra_config`](supra_config.md#0x1_supra_config) +- [`0x1::supra_dkg`](supra_dkg.md#0x1_supra_dkg) - [`0x1::supra_governance`](supra_governance.md#0x1_supra_governance) - [`0x1::system_addresses`](system_addresses.md#0x1_system_addresses) - [`0x1::timestamp`](timestamp.md#0x1_timestamp) diff --git a/aptos-move/framework/supra-framework/doc/randomness_config.md b/aptos-move/framework/supra-framework/doc/randomness_config.md index 92ad908b2d3..869a4839cd9 100644 --- a/aptos-move/framework/supra-framework/doc/randomness_config.md +++ b/aptos-move/framework/supra-framework/doc/randomness_config.md @@ -224,7 +224,9 @@ This can be called by on-chain governance to update on-chain consensus configs f Implementation -
public fun set_for_next_epoch(framework: &signer, new_config: RandomnessConfig) {
+
public fun set_for_next_epoch(
+    framework: &signer, new_config: RandomnessConfig
+) {
     system_addresses::assert_supra_framework(framework);
     config_buffer::upsert(new_config);
 }
@@ -274,7 +276,6 @@ Only used in reconfigurations to apply the pending consensus_config::validator_txn_enabled() && randomness_config::enabled().
 
 
 
public fun enabled(): bool
@@ -289,11 +290,10 @@ The feature works if and only if enabled(): bool acquires RandomnessConfig {
     if (exists<RandomnessConfig>(@supra_framework)) {
         let config = borrow_global<RandomnessConfig>(@supra_framework);
-        let variant_type_name = *string::bytes(copyable_any::type_name(&config.variant));
+        let variant_type_name =
+            *string::bytes(copyable_any::type_name(&config.variant));
         variant_type_name != b"0x1::randomness_config::ConfigOff"
-    } else {
-        false
-    }
+    } else { false }
 }
 
@@ -319,7 +319,7 @@ Create a Co
public fun new_off(): RandomnessConfig {
     RandomnessConfig {
-        variant: copyable_any::pack( ConfigOff {} )
+        variant: copyable_any::pack(ConfigOff {})
     }
 }
 
@@ -344,12 +344,13 @@ Create a Con Implementation -
public fun new_v1(secrecy_threshold: FixedPoint64, reconstruction_threshold: FixedPoint64): RandomnessConfig {
+
public fun new_v1(
+    secrecy_threshold: FixedPoint64, reconstruction_threshold: FixedPoint64
+): RandomnessConfig {
     RandomnessConfig {
-        variant: copyable_any::pack( ConfigV1 {
-            secrecy_threshold,
-            reconstruction_threshold
-        } )
+        variant: copyable_any::pack(
+            ConfigV1 { secrecy_threshold, reconstruction_threshold }
+        )
     }
 }
 
@@ -377,14 +378,16 @@ Create a Con
public fun new_v2(
     secrecy_threshold: FixedPoint64,
     reconstruction_threshold: FixedPoint64,
-    fast_path_secrecy_threshold: FixedPoint64,
+    fast_path_secrecy_threshold: FixedPoint64
 ): RandomnessConfig {
     RandomnessConfig {
-        variant: copyable_any::pack( ConfigV2 {
-            secrecy_threshold,
-            reconstruction_threshold,
-            fast_path_secrecy_threshold,
-        } )
+        variant: copyable_any::pack(
+            ConfigV2 {
+                secrecy_threshold,
+                reconstruction_threshold,
+                fast_path_secrecy_threshold
+            }
+        )
     }
 }
 
diff --git a/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md b/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md index 13284f3c4f4..d18866c7486 100644 --- a/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md +++ b/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md @@ -18,7 +18,6 @@ Reconfiguration with DKG helper functions.
use 0x1::automation_registry;
 use 0x1::consensus_config;
-use 0x1::dkg;
 use 0x1::dkg_committee;
 use 0x1::dkg_config;
 use 0x1::evm_genesis_config;
@@ -38,6 +37,7 @@ Reconfiguration with DKG helper functions.
 use 0x1::reconfiguration_state;
 use 0x1::stake;
 use 0x1::supra_config;
+use 0x1::supra_dkg;
 use 0x1::system_addresses;
 use 0x1::validator_consensus_info;
 use 0x1::validator_public_keys;
@@ -64,12 +64,11 @@ Do nothing if one is already in progress.
 
 
 
public(friend) fun try_start() {
-    let incomplete_dkg_session = dkg::incomplete_session();
+    let incomplete_dkg_session = supra_dkg::incomplete_session();
     if (option::is_some(&incomplete_dkg_session)) {
         let session = option::borrow(&incomplete_dkg_session);
-        if (dkg::session_dealer_epoch(session) == reconfiguration::current_epoch()) {
-            return
-        }
+        if (supra_dkg::session_dealer_epoch(session)
+            == reconfiguration::current_epoch()) { return }
     };
     reconfiguration_state::on_reconfig_start();
     let cur_epoch = reconfiguration::current_epoch();
@@ -100,7 +99,7 @@ Do nothing if one is already in progress.
     };
 
     // DKG for configured receiver committees
-    dkg::start(
+    supra_dkg::start(
         cur_epoch,
         randomness_seed,
         new_dkg_committee_from_validator_consensus_info(
@@ -132,7 +131,7 @@ Do nothing if one is already in progress.
 
 
 
fun set_dkg_meta(dkg_meta: vector<u8>) {
-    dkg::set_dkg_meta(dkg_meta);
+    supra_dkg::set_dkg_meta(dkg_meta);
 }
 
@@ -161,7 +160,7 @@ Run the default reconfiguration to enter the new epoch.
public(friend) fun finish(framework: &signer) {
     system_addresses::assert_supra_framework(framework);
-    dkg::try_clear_incomplete_session(framework);
+    supra_dkg::try_clear_incomplete_session(framework);
     consensus_config::on_new_epoch(framework);
     execution_config::on_new_epoch(framework);
     supra_config::on_new_epoch(framework);
@@ -204,7 +203,7 @@ Abort if no DKG is in progress.
 
 
 
fun finish_with_dkg_result(account: &signer, dkg_result: vector<u8>) {
-    dkg::finish(dkg_result);
+    supra_dkg::finish(dkg_result);
     finish(account);
 }
 
@@ -240,8 +239,8 @@ Abort if no DKG is in progress. requires chain_status::is_operating(); include stake::ResourceRequirement; include stake::GetReconfigStartTimeRequirement; -include features::spec_periodical_reward_rate_decrease_enabled( -) ==> staking_config::StakingRewardsConfigEnabledRequirement; +include features::spec_periodical_reward_rate_decrease_enabled() ==> + staking_config::StakingRewardsConfigEnabledRequirement; aborts_if false; pragma verify_duration_estimate = 600;
@@ -309,10 +308,8 @@ Abort if no DKG is in progress.
pragma verify_duration_estimate = 1500;
-include FinishRequirement {
-    framework: account
-};
-requires dkg::has_incomplete_session();
+include FinishRequirement { framework: account };
+requires supra_dkg::has_incomplete_session();
 aborts_if false;
 
diff --git a/aptos-move/framework/supra-framework/doc/stake.md b/aptos-move/framework/supra-framework/doc/stake.md index e6cdc709cc8..5c845627071 100644 --- a/aptos-move/framework/supra-framework/doc/stake.md +++ b/aptos-move/framework/supra-framework/doc/stake.md @@ -85,6 +85,7 @@ or if their stake drops below the min required, they would get removed at the en - [Function `remove_validators`](#0x1_stake_remove_validators) - [Function `initialize_stake_owner`](#0x1_stake_initialize_stake_owner) - [Function `initialize_validator`](#0x1_stake_initialize_validator) +- [Function `validate_consensus_public_key`](#0x1_stake_validate_consensus_public_key) - [Function `initialize_owner`](#0x1_stake_initialize_owner) - [Function `extract_owner_cap`](#0x1_stake_extract_owner_cap) - [Function `deposit_owner_cap`](#0x1_stake_deposit_owner_cap) @@ -2685,20 +2686,7 @@ Initialize the validator account and give ownership to the signing account. network_addresses: vector<u8>, fullnode_addresses: vector<u8> ) acquires AllowedValidators { - - // Checks the public key is valid to prevent rogue-key attacks. - if (std::features::supra_validator_identity_v2_enabled()) { - let _valid_public_key = - validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey); - } else { - let valid_public_key = - ed25519::new_validated_public_key_from_bytes(consensus_pubkey); - assert!( - option::is_some(&valid_public_key), - error::invalid_argument(EINVALID_PUBLIC_KEY) - ); - }; - + validate_consensus_public_key(consensus_pubkey); initialize_owner(account); move_to( account, @@ -2714,6 +2702,49 @@ Initialize the validator account and give ownership to the signing account. + + + + +## Function `validate_consensus_public_key` + + + +
fun validate_consensus_public_key(consensus_pubkey: vector<u8>)
+
+ + + +
+Implementation + + +
fun validate_consensus_public_key(consensus_pubkey: vector<u8>) {
+    if (std::features::supra_validator_identity_v2_enabled()) {
+        // Expect the new format.
+        let _valid_public_key =
+            validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey);
+    } else {
+        // Check the old format.
+        let maybe_valid_public_key =
+            ed25519::new_validated_public_key_from_bytes(consensus_pubkey);
+
+        if (option::is_none(&maybe_valid_public_key)) {
+            // Fall back to the new format. This enables validators to register their keys in
+            // the new format before the v2 feature flag is activated, which is safe because the
+            // new keys are a superset of the old and the consensus has logic for maintaining
+            // backwards compatibility.
+            let _valid_public_key =
+                validator_public_keys::validator_public_keys_from_bytes(
+                    consensus_pubkey
+                );
+        }
+    };
+}
+
+ + +
@@ -3213,36 +3244,8 @@ Move amount of coins from pending_inactive to active. ); let validator_info = borrow_global_mut<ValidatorConfig>(pool_address); let old_consensus_pubkey = validator_info.consensus_pubkey; - // Checks the public key is valid to prevent rogue-key attacks. - if (!genesis) { - if (std::features::supra_validator_identity_v2_enabled()) { - let _valid_public_key = - validator_public_keys::validator_public_keys_from_bytes( - new_consensus_pubkey - ); - } else { - let valid_public_key = - ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); - assert!( - option::is_some(&valid_public_key), - error::invalid_argument(EINVALID_PUBLIC_KEY) - ); - }; - } else { - if (std::features::supra_validator_identity_v2_enabled()) { - let _valid_public_key = - validator_public_keys::validator_public_keys_from_bytes( - new_consensus_pubkey - ); - } else { - let valid_public_key = - ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey); - assert!( - option::is_some(&valid_public_key), - error::invalid_argument(EINVALID_PUBLIC_KEY) - ); - }; - }; + + validate_consensus_public_key(new_consensus_pubkey); validator_info.consensus_pubkey = new_consensus_pubkey; if (std::features::module_event_migration_enabled()) { @@ -4351,7 +4354,7 @@ New joiners (pending_active) always read from compute_next_validator_set_internal( - use_current_config_for_actives: bool, + use_current_config_for_actives: bool ): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig { // Init. let cur_validator_set = borrow_global<ValidatorSet>(@supra_framework); @@ -4398,14 +4401,15 @@ New joiners (pending_active) always read from coin::value(&stake_pool.pending_active); let cur_pending_inactive = coin::value(&stake_pool.pending_inactive); - let cur_reward = calculate_candidate_reward( - candidate, - candidate_in_current_validator_set, - cur_active, - validator_perf, - rewards_rate, - rewards_rate_denominator - ); + let cur_reward = + calculate_candidate_reward( + candidate, + candidate_in_current_validator_set, + cur_active, + validator_perf, + rewards_rate, + rewards_rate_denominator + ); let cur_fee = collect_candidate_fee(candidate.addr); @@ -4426,7 +4430,8 @@ New joiners (pending_active) always read from any mid-epoch changes // (consensus key, network addresses, etc.) only take effect after the // epoch transition, not during DKG. @@ -4491,17 +4496,19 @@ with no active stake. cur_active: u64, validator_perf: &ValidatorPerformance, rewards_rate: u64, - rewards_rate_denominator: u64, + rewards_rate_denominator: u64 ): u64 { if (candidate_in_current_validator_set && cur_active != 0) { spec { - assert candidate.config.validator_index < len(validator_perf.validators); + assert candidate.config.validator_index + < len(validator_perf.validators); }; let cur_perf = vector::borrow( &validator_perf.validators, candidate.config.validator_index ); spec { - assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64; + assume cur_perf.successful_proposals + cur_perf.failed_proposals + <= MAX_U64; }; calculate_rewards_amount( cur_active, @@ -6138,301 +6145,6 @@ Returns validator's next epoch voting power, including pending_active, active, a - - - - -
schema AddStakeWithCapAbortsIfAndEnsures {
-    owner_cap: OwnerCapability;
-    amount: u64;
-    let pool_address = owner_cap.pool_address;
-    aborts_if !exists<StakePool>(pool_address);
-    let config = global<staking_config::StakingConfig>(@supra_framework);
-    let validator_set = global<ValidatorSet>(@supra_framework);
-    let voting_power_increase_limit = config.voting_power_increase_limit;
-    let post post_validator_set = global<ValidatorSet>(@supra_framework);
-    let update_voting_power_increase = amount != 0 && (spec_contains(validator_set.active_validators, pool_address)
-                                                       || spec_contains(validator_set.pending_active, pool_address));
-    aborts_if update_voting_power_increase && validator_set.total_joining_power + amount > MAX_U128;
-    ensures update_voting_power_increase ==> post_validator_set.total_joining_power == validator_set.total_joining_power + amount;
-    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
-            && validator_set.total_voting_power * voting_power_increase_limit > MAX_U128;
-    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
-            && validator_set.total_joining_power + amount > validator_set.total_voting_power * voting_power_increase_limit / 100;
-    let stake_pool = global<StakePool>(pool_address);
-    let post post_stake_pool = global<StakePool>(pool_address);
-    let value_pending_active = stake_pool.pending_active.value;
-    let value_active = stake_pool.active.value;
-    ensures amount != 0 && spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.pending_active.value == value_pending_active + amount;
-    ensures amount != 0 && !spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.active.value == value_active + amount;
-    let maximum_stake = config.maximum_stake;
-    let value_pending_inactive = stake_pool.pending_inactive.value;
-    let next_epoch_voting_power = value_pending_active + value_active + value_pending_inactive;
-    let voting_power = next_epoch_voting_power + amount;
-    aborts_if amount != 0 && voting_power > MAX_U64;
-    aborts_if amount != 0 && voting_power > maximum_stake;
-}
-
- - - - - - - -
schema AddStakeAbortsIfAndEnsures {
-    owner: signer;
-    amount: u64;
-    let owner_address = signer::address_of(owner);
-    aborts_if !exists<OwnerCapability>(owner_address);
-    let owner_cap = global<OwnerCapability>(owner_address);
-    include AddStakeWithCapAbortsIfAndEnsures { owner_cap };
-}
-
- - - - - - - -
fun spec_is_allowed(account: address): bool {
-   if (!exists<AllowedValidators>(@supra_framework)) {
-       true
-   } else {
-       let allowed = global<AllowedValidators>(@supra_framework);
-       contains(allowed.accounts, account)
-   }
-}
-
- - - - - - - -
fun spec_find_validator(v: vector<ValidatorInfo>, addr: address): Option<u64>;
-
- - - - - - - -
fun spec_validators_are_initialized(validators: vector<ValidatorInfo>): bool {
-   forall i in 0..len(validators):
-       spec_has_stake_pool(validators[i].addr) &&
-           spec_has_validator_config(validators[i].addr)
-}
-
- - - - - - - -
fun spec_validators_are_initialized_addrs(addrs: vector<address>): bool {
-   forall i in 0..len(addrs):
-       spec_has_stake_pool(addrs[i]) &&
-           spec_has_validator_config(addrs[i])
-}
-
- - - - - - - -
fun spec_validator_indices_are_valid(validators: vector<ValidatorInfo>): bool {
-   spec_validator_indices_are_valid_addr(validators, spec_validator_index_upper_bound()) &&
-       spec_validator_indices_are_valid_config(validators, spec_validator_index_upper_bound())
-}
-
- - - - - - - -
fun spec_validator_indices_are_valid_addr(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
-   forall i in 0..len(validators):
-       global<ValidatorConfig>(validators[i].addr).validator_index < upper_bound
-}
-
- - - - - - - -
fun spec_validator_indices_are_valid_config(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
-   forall i in 0..len(validators):
-       validators[i].config.validator_index < upper_bound
-}
-
- - - - - - - -
fun spec_validator_indices_active_pending_inactive(validator_set: ValidatorSet): bool {
-   len(validator_set.pending_inactive) + len(validator_set.active_validators) == spec_validator_index_upper_bound()
-}
-
- - - - - - - -
fun spec_validator_index_upper_bound(): u64 {
-   len(global<ValidatorPerformance>(@supra_framework).validators)
-}
-
- - - - - - - -
fun spec_has_stake_pool(a: address): bool {
-   exists<StakePool>(a)
-}
-
- - - - - - - -
fun spec_has_validator_config(a: address): bool {
-   exists<ValidatorConfig>(a)
-}
-
- - - - - - - -
fun spec_rewards_amount(
-   stake_amount: u64,
-   num_successful_proposals: u64,
-   num_total_proposals: u64,
-   rewards_rate: u64,
-   rewards_rate_denominator: u64,
-): u64;
-
- - - - - - - -
fun spec_contains(validators: vector<ValidatorInfo>, addr: address): bool {
-   exists i in 0..len(validators): validators[i].addr == addr
-}
-
- - - - - - - -
fun spec_is_current_epoch_validator(pool_address: address): bool {
-   let validator_set = global<ValidatorSet>(@supra_framework);
-   !spec_contains(validator_set.pending_active, pool_address)
-       && (spec_contains(validator_set.active_validators, pool_address)
-       || spec_contains(validator_set.pending_inactive, pool_address))
-}
-
- - - - - - - -
schema ResourceRequirement {
-    requires exists<SupraCoinCapabilities>(@supra_framework);
-    requires exists<ValidatorPerformance>(@supra_framework);
-    requires exists<ValidatorSet>(@supra_framework);
-    requires exists<StakingConfig>(@supra_framework);
-    requires exists<StakingRewardsConfig>(@supra_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
-    requires exists<timestamp::CurrentTimeMicroseconds>(@supra_framework);
-    requires exists<ValidatorFees>(@supra_framework);
-}
-
- - - - - - - -
fun spec_get_reward_rate_1(config: StakingConfig): num {
-   if (features::spec_periodical_reward_rate_decrease_enabled()) {
-       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
-       if (epoch_rewards_rate.value == 0) {
-           0
-       } else {
-           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
-           let denominator = if (denominator_0 > MAX_U64) {
-               MAX_U64
-           } else {
-               denominator_0
-           };
-           let nominator = aptos_std::fixed_point64::spec_multiply_u128(denominator, epoch_rewards_rate);
-           nominator
-       }
-   } else {
-           config.rewards_rate
-   }
-}
-
- - - - - - - -
fun spec_get_reward_rate_2(config: StakingConfig): num {
-   if (features::spec_periodical_reward_rate_decrease_enabled()) {
-       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
-       if (epoch_rewards_rate.value == 0) {
-           1
-       } else {
-           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
-           let denominator = if (denominator_0 > MAX_U64) {
-               MAX_U64
-           } else {
-               denominator_0
-           };
-           denominator
-       }
-   } else {
-           config.rewards_rate_denominator
-   }
-}
-
- - - ### Function `update_stake_pool` diff --git a/aptos-move/framework/supra-framework/doc/supra_dkg.md b/aptos-move/framework/supra-framework/doc/supra_dkg.md new file mode 100644 index 00000000000..fe1ec290b58 --- /dev/null +++ b/aptos-move/framework/supra-framework/doc/supra_dkg.md @@ -0,0 +1,843 @@ + + + +# Module `0x1::supra_dkg` + +DKG on-chain states and helper functions. + + +- [Struct `DKGStartEvent`](#0x1_supra_dkg_DKGStartEvent) +- [Struct `DKGMetaSetEvent`](#0x1_supra_dkg_DKGMetaSetEvent) +- [Struct `DKGFinishEvent`](#0x1_supra_dkg_DKGFinishEvent) +- [Struct `DKGSessionMetadata`](#0x1_supra_dkg_DKGSessionMetadata) +- [Struct `DKGSessionState`](#0x1_supra_dkg_DKGSessionState) +- [Resource `DKGState`](#0x1_supra_dkg_DKGState) +- [Struct `OnChainAggregateCommitment`](#0x1_supra_dkg_OnChainAggregateCommitment) +- [Struct `OnChainAggregateCommitmentAllCommittees`](#0x1_supra_dkg_OnChainAggregateCommitmentAllCommittees) +- [Constants](#@Constants_0) +- [Function `initialize`](#0x1_supra_dkg_initialize) +- [Function `start`](#0x1_supra_dkg_start) +- [Function `set_dkg_meta`](#0x1_supra_dkg_set_dkg_meta) +- [Function `finish`](#0x1_supra_dkg_finish) +- [Function `try_clear_incomplete_session`](#0x1_supra_dkg_try_clear_incomplete_session) +- [Function `incomplete_session`](#0x1_supra_dkg_incomplete_session) +- [Function `last_completed_session`](#0x1_supra_dkg_last_completed_session) +- [Function `session_dealer_epoch`](#0x1_supra_dkg_session_dealer_epoch) +- [Specification](#@Specification_1) + - [Function `initialize`](#@Specification_1_initialize) + - [Function `start`](#@Specification_1_start) + - [Function `set_dkg_meta`](#@Specification_1_set_dkg_meta) + - [Function `finish`](#@Specification_1_finish) + - [Function `try_clear_incomplete_session`](#@Specification_1_try_clear_incomplete_session) + - [Function `incomplete_session`](#@Specification_1_incomplete_session) + + +
use 0x1::any;
+use 0x1::dkg_committee;
+use 0x1::error;
+use 0x1::event;
+use 0x1::option;
+use 0x1::stake;
+use 0x1::string;
+use 0x1::system_addresses;
+use 0x1::timestamp;
+use 0x1::type_info;
+use 0x1::vector;
+
+ + + + + +## Struct `DKGStartEvent` + + + +
#[event]
+struct DKGStartEvent has drop, store
+
+ + + +
+Fields + + +
+
+session_metadata: supra_dkg::DKGSessionMetadata +
+
+ +
+
+start_time_us: u64 +
+
+ +
+
+ + +
+ + + +## Struct `DKGMetaSetEvent` + + + +
#[event]
+struct DKGMetaSetEvent has drop, store
+
+ + + +
+Fields + + +
+
+dkg_meta_transcript: vector<u8> +
+
+ +
+
+ + +
+ + + +## Struct `DKGFinishEvent` + + + +
#[event]
+struct DKGFinishEvent has drop, store
+
+ + + +
+Fields + + +
+
+target_committees_public_key_shares: vector<u8> +
+
+ +
+
+ + +
+ + + +## Struct `DKGSessionMetadata` + +This can be considered as the public input of DKG. + + +
struct DKGSessionMetadata has copy, drop, store
+
+ + + +
+Fields + + +
+
+dealer_epoch: u64 +
+
+ +
+
+randomness_seed: vector<u8> +
+
+ +
+
+dealer_committee: dkg_committee::DkgCommittee +
+
+ +
+
+target_committees: vector<dkg_committee::ReceiverCommittee> +
+
+ +
+
+ + +
+ + + +## Struct `DKGSessionState` + +The input and output of a DKG session. +The validator set of epoch x works together for an DKG output for the target validator set of epoch x+1. + + +
struct DKGSessionState has copy, drop, store
+
+ + + +
+Fields + + +
+
+metadata: supra_dkg::DKGSessionMetadata +
+
+ +
+
+start_time_us: u64 +
+
+ +
+
+dkg_meta_transcript: vector<u8> +
+
+ +
+
+target_committees_public_key_shares: vector<u8> +
+
+ +
+
+ + +
+ + + +## Resource `DKGState` + +The completed and in-progress DKG sessions. + + +
struct DKGState has key
+
+ + + +
+Fields + + +
+
+last_completed: option::Option<supra_dkg::DKGSessionState> +
+
+ +
+
+in_progress: option::Option<supra_dkg::DKGSessionState> +
+
+ +
+
+ + +
+ + + +## Struct `OnChainAggregateCommitment` + + + +
struct OnChainAggregateCommitment has copy, drop
+
+ + + +
+Fields + + +
+
+bls12381_commitment_g: vector<u8> +
+
+ +
+
+bls12381_commitment_evals: vector<vector<u8>> +
+
+ +
+
+dealer_ids: vector<u32> +
+
+ +
+
+committee_index: u32 +
+
+ +
+
+epoch: u64 +
+
+ +
+
+chain_id: u8 +
+
+ +
+
+threshold_type: u8 +
+
+ +
+
+ + +
+ + + +## Struct `OnChainAggregateCommitmentAllCommittees` + + + +
struct OnChainAggregateCommitmentAllCommittees has copy, drop
+
+ + + +
+Fields + + +
+
+commitments: vector<supra_dkg::OnChainAggregateCommitment> +
+
+ +
+
+ + +
+ + + +## Constants + + + + + + +
const EDKG_INVALID_PK_SHARES: u64 = 4;
+
+ + + + + + + +
const EDKG_META_ALREADY_SET: u64 = 2;
+
+ + + + + + + +
const EDKG_META_NOT_SET: u64 = 3;
+
+ + + + + + + +
const EDKG_NOT_IN_PROGRESS: u64 = 1;
+
+ + + + + +## Function `initialize` + +Called in genesis to initialize on-chain states when DKG is active from genesis, +otherwise, must be called from a governance script before the DKG feature flag +is activated. + + +
public fun initialize(supra_framework: &signer)
+
+ + + +
+Implementation + + +
public fun initialize(supra_framework: &signer) {
+    system_addresses::assert_supra_framework(supra_framework);
+    if (!exists<DKGState>(@supra_framework)) {
+        move_to<DKGState>(
+            supra_framework,
+            DKGState {
+                last_completed: std::option::none(),
+                in_progress: std::option::none()
+            }
+        );
+    };
+}
+
+ + + +
+ + + +## Function `start` + +Mark on-chain DKG state as in-progress. Notify validators to start DKG. +Abort if a DKG is already in progress. + + +
public(friend) fun start(dealer_epoch: u64, randomness_seed: vector<u8>, dealer_committee: dkg_committee::DkgCommittee, target_committees: vector<dkg_committee::ReceiverCommittee>)
+
+ + + +
+Implementation + + +
public(friend) fun start(
+    dealer_epoch: u64,
+    randomness_seed: vector<u8>,
+    dealer_committee: DkgCommittee,
+    target_committees: vector<ReceiverCommittee>
+) acquires DKGState {
+    let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
+    let new_session_metadata = DKGSessionMetadata {
+        dealer_epoch,
+        randomness_seed,
+        dealer_committee,
+        target_committees
+    };
+    let start_time_us = timestamp::now_microseconds();
+    dkg_state.in_progress = std::option::some(
+        DKGSessionState {
+            metadata: new_session_metadata,
+            start_time_us,
+            dkg_meta_transcript: vector[],
+            target_committees_public_key_shares: vector[]
+        }
+    );
+
+    emit(DKGStartEvent { start_time_us, session_metadata: new_session_metadata });
+}
+
+ + + +
+ + + +## Function `set_dkg_meta` + +Family Node sets the DKGMeta for the in-progress DKG session +The dkg transcript is assumed to have been already verified by the aptos VM in process_dkg_result method + + +
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
+
+ + + +
+Implementation + + +
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>) acquires DKGState {
+    // ensure dkg is in progress
+    let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
+    assert!(
+        option::is_some(&dkg_state.in_progress),
+        error::invalid_state(EDKG_NOT_IN_PROGRESS)
+    );
+
+    // we only add the first DKG Meta proposed and ignore the rest
+    let session = option::extract(&mut dkg_state.in_progress);
+    assert!(
+        vector::length(&session.dkg_meta_transcript) == 0,
+        error::already_exists(EDKG_META_ALREADY_SET)
+    );
+    session.dkg_meta_transcript = dkg_meta_all_committees;
+    dkg_state.in_progress = option::some(session);
+
+    emit(DKGMetaSetEvent { dkg_meta_transcript: dkg_meta_all_committees });
+}
+
+ + + +
+ + + +## Function `finish` + +Family Node sets the target_committees_public_key_shares for the in-progress DKG session and +marks the incomplete DKG session completed. +The target_committees_public_key_shares is assumed to be verified by the aptos VM before calling this function + + +
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
+
+ + + +
+Implementation + + +
public(friend) fun finish(
+    target_committees_public_key_shares: vector<u8>
+) acquires DKGState {
+    // ensure dkg is in progress
+    let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
+    assert!(
+        option::is_some(&dkg_state.in_progress),
+        error::invalid_state(EDKG_NOT_IN_PROGRESS)
+    );
+
+    // DKG meta should be already set before `finish` is called
+    let session = option::extract(&mut dkg_state.in_progress);
+    assert!(
+        vector::length(&session.dkg_meta_transcript) > 0,
+        error::already_exists(EDKG_META_NOT_SET)
+    );
+
+    session.target_committees_public_key_shares = target_committees_public_key_shares;
+    dkg_state.last_completed = option::some(session);
+    dkg_state.in_progress = option::none();
+
+    // propagate updated keys to stake.move for all threshold types
+    let public_key_shares_all_comms_serialized =
+        any::new(
+            type_info::type_name<OnChainAggregateCommitmentAllCommittees>(),
+            target_committees_public_key_shares
+        );
+    let public_key_shares_all_comms =
+        any::unpack<OnChainAggregateCommitmentAllCommittees>(
+            public_key_shares_all_comms_serialized
+        );
+
+    // Build a vector of DkgCommitteeOutput for all committees
+    let committee_outputs = vector[];
+    let i = 0;
+    let len = vector::length(&public_key_shares_all_comms.commitments);
+    while (i < len) {
+        let commitment = vector::borrow(&public_key_shares_all_comms.commitments, i);
+        // As the first index contains the committee's threshold public key, we can skip that
+        let evals = vector::slice(
+            &commitment.bls12381_commitment_evals,
+            1,
+            vector::length(&commitment.bls12381_commitment_evals)
+        );
+
+        vector::push_back(
+            &mut committee_outputs,
+            new_dkg_committee_output(commitment.threshold_type, evals)
+        );
+        i = i + 1;
+    };
+
+    // Set all keys for all threshold types
+    stake::set_dkg_output_keys(committee_outputs);
+    emit(DKGFinishEvent { target_committees_public_key_shares });
+}
+
+ + + +
+ + + +## Function `try_clear_incomplete_session` + +Delete the currently incomplete session, if it exists. + + +
public fun try_clear_incomplete_session(fx: &signer)
+
+ + + +
+Implementation + + +
public fun try_clear_incomplete_session(fx: &signer) acquires DKGState {
+    system_addresses::assert_supra_framework(fx);
+    if (exists<DKGState>(@supra_framework)) {
+        let dkg_state = borrow_global_mut<DKGState>(@supra_framework);
+        dkg_state.in_progress = option::none();
+    }
+}
+
+ + + +
+ + + +## Function `incomplete_session` + +Return the incomplete DKG session state, if it exists. + + +
public fun incomplete_session(): option::Option<supra_dkg::DKGSessionState>
+
+ + + +
+Implementation + + +
public fun incomplete_session(): Option<DKGSessionState> acquires DKGState {
+    if (exists<DKGState>(@supra_framework)) {
+        borrow_global<DKGState>(@supra_framework).in_progress
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Function `last_completed_session` + +Return the last completed DKG session state, if it exists. + + +
public fun last_completed_session(): option::Option<supra_dkg::DKGSessionState>
+
+ + + +
+Implementation + + +
public fun last_completed_session(): Option<DKGSessionState> acquires DKGState {
+    if (exists<DKGState>(@supra_framework)) {
+        borrow_global<DKGState>(@supra_framework).last_completed
+    } else {
+        option::none()
+    }
+}
+
+ + + +
+ + + +## Function `session_dealer_epoch` + +Return the dealer epoch of a DKGSessionState. + + +
public fun session_dealer_epoch(session: &supra_dkg::DKGSessionState): u64
+
+ + + +
+Implementation + + +
public fun session_dealer_epoch(session: &DKGSessionState): u64 {
+    session.metadata.dealer_epoch
+}
+
+ + + +
+ + + +## Specification + + + +
invariant [suspendable] chain_status::is_operating() ==>
+    exists<DKGState>(@supra_framework);
+
+ + + + + +### Function `initialize` + + +
public fun initialize(supra_framework: &signer)
+
+ + + + +
let supra_framework_addr = signer::address_of(supra_framework);
+aborts_if supra_framework_addr != @supra_framework;
+
+ + + + + +### Function `start` + + +
public(friend) fun start(dealer_epoch: u64, randomness_seed: vector<u8>, dealer_committee: dkg_committee::DkgCommittee, target_committees: vector<dkg_committee::ReceiverCommittee>)
+
+ + + + +
aborts_if !exists<DKGState>(@supra_framework);
+aborts_if !exists<timestamp::CurrentTimeMicroseconds>(@supra_framework);
+
+ + + + + +### Function `set_dkg_meta` + + +
public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector<u8>)
+
+ + + + +
requires exists<DKGState>(@supra_framework);
+requires option::is_some(global<DKGState>(@supra_framework).in_progress);
+aborts_if false;
+
+ + + + + +### Function `finish` + + +
public(friend) fun finish(target_committees_public_key_shares: vector<u8>)
+
+ + + + +
requires exists<DKGState>(@supra_framework);
+requires option::is_some(global<DKGState>(@supra_framework).in_progress);
+aborts_if false;
+
+ + + + + + + +
fun has_incomplete_session(): bool {
+   if (exists<DKGState>(@supra_framework)) {
+       option::spec_is_some(global<DKGState>(@supra_framework).in_progress)
+   } else { false }
+}
+
+ + + + + +### Function `try_clear_incomplete_session` + + +
public fun try_clear_incomplete_session(fx: &signer)
+
+ + + + +
let addr = signer::address_of(fx);
+aborts_if addr != @supra_framework;
+
+ + + + + +### Function `incomplete_session` + + +
public fun incomplete_session(): option::Option<supra_dkg::DKGSessionState>
+
+ + + + +
aborts_if false;
+
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/validator_public_keys.md b/aptos-move/framework/supra-framework/doc/validator_public_keys.md index e0e357572d0..063d42f0467 100644 --- a/aptos-move/framework/supra-framework/doc/validator_public_keys.md +++ b/aptos-move/framework/supra-framework/doc/validator_public_keys.md @@ -637,8 +637,7 @@ Error: Unknown certificate threshold type. Implementation -
public fun validator_public_keys_from_bytes(bytes: vector<u8>): ValidatorPublicKeys{
-
+
public fun validator_public_keys_from_bytes(bytes: vector<u8>): ValidatorPublicKeys {
     // bcs deserialization
     let bytes_serialized = any::new(type_info::type_name<ValidatorPublicKeys>(), bytes);
     let validator_public_keys = any::unpack<ValidatorPublicKeys>(bytes_serialized);
diff --git a/aptos-move/framework/supra-framework/sources/configs/randomness_config.move b/aptos-move/framework/supra-framework/sources/configs/randomness_config.move
index 98e2e79ca29..cfdfab57eeb 100644
--- a/aptos-move/framework/supra-framework/sources/configs/randomness_config.move
+++ b/aptos-move/framework/supra-framework/sources/configs/randomness_config.move
@@ -17,7 +17,7 @@ module supra_framework::randomness_config {
         /// Currently the variant type is one of the following.
         /// - `ConfigOff`
         /// - `ConfigV1`
-        variant: Any,
+        variant: Any
     }
 
     /// A randomness config variant indicating the feature is disabled.
@@ -28,7 +28,7 @@ module supra_framework::randomness_config {
         /// Any validator subset should not be able to reconstruct randomness if `subset_power / total_power <= secrecy_threshold`,
         secrecy_threshold: FixedPoint64,
         /// Any validator subset should be able to reconstruct randomness if `subset_power / total_power > reconstruction_threshold`.
-        reconstruction_threshold: FixedPoint64,
+        reconstruction_threshold: FixedPoint64
     }
 
     /// A randomness config variant indicating the feature is enabled with fast path.
@@ -38,7 +38,7 @@ module supra_framework::randomness_config {
         /// Any validator subset should be able to reconstruct randomness if `subset_power / total_power > reconstruction_threshold`.
         reconstruction_threshold: FixedPoint64,
         /// Any validator subset should not be able to reconstruct randomness via the fast path if `subset_power / total_power <= fast_path_secrecy_threshold`,
-        fast_path_secrecy_threshold: FixedPoint64,
+        fast_path_secrecy_threshold: FixedPoint64
     }
 
     /// Initialize the configuration. Used in genesis or governance.
@@ -50,7 +50,9 @@ module supra_framework::randomness_config {
     }
 
     /// This can be called by on-chain governance to update on-chain consensus configs for the next epoch.
-    public fun set_for_next_epoch(framework: &signer, new_config: RandomnessConfig) {
+    public fun set_for_next_epoch(
+        framework: &signer, new_config: RandomnessConfig
+    ) {
         system_addresses::assert_supra_framework(framework);
         config_buffer::upsert(new_config);
     }
@@ -71,31 +73,30 @@ module supra_framework::randomness_config {
     /// Check whether on-chain randomness main logic (e.g., `DKGManager`, `RandManager`, `BlockMetadataExt`) is enabled.
     ///
     /// NOTE: this returning true does not mean randomness will run.
-    /// The feature works if and only if `consensus_config::validator_txn_enabled() && randomness_config::enabled()`.
     public fun enabled(): bool acquires RandomnessConfig {
         if (exists(@supra_framework)) {
             let config = borrow_global(@supra_framework);
-            let variant_type_name = *string::bytes(copyable_any::type_name(&config.variant));
+            let variant_type_name =
+                *string::bytes(copyable_any::type_name(&config.variant));
             variant_type_name != b"0x1::randomness_config::ConfigOff"
-        } else {
-            false
-        }
+        } else { false }
     }
 
     /// Create a `ConfigOff` variant.
     public fun new_off(): RandomnessConfig {
         RandomnessConfig {
-            variant: copyable_any::pack( ConfigOff {} )
+            variant: copyable_any::pack(ConfigOff {})
         }
     }
 
     /// Create a `ConfigV1` variant.
-    public fun new_v1(secrecy_threshold: FixedPoint64, reconstruction_threshold: FixedPoint64): RandomnessConfig {
+    public fun new_v1(
+        secrecy_threshold: FixedPoint64, reconstruction_threshold: FixedPoint64
+    ): RandomnessConfig {
         RandomnessConfig {
-            variant: copyable_any::pack( ConfigV1 {
-                secrecy_threshold,
-                reconstruction_threshold
-            } )
+            variant: copyable_any::pack(
+                ConfigV1 { secrecy_threshold, reconstruction_threshold }
+            )
         }
     }
 
@@ -103,14 +104,16 @@ module supra_framework::randomness_config {
     public fun new_v2(
         secrecy_threshold: FixedPoint64,
         reconstruction_threshold: FixedPoint64,
-        fast_path_secrecy_threshold: FixedPoint64,
+        fast_path_secrecy_threshold: FixedPoint64
     ): RandomnessConfig {
         RandomnessConfig {
-            variant: copyable_any::pack( ConfigV2 {
-                secrecy_threshold,
-                reconstruction_threshold,
-                fast_path_secrecy_threshold,
-            } )
+            variant: copyable_any::pack(
+                ConfigV2 {
+                    secrecy_threshold,
+                    reconstruction_threshold,
+                    fast_path_secrecy_threshold
+                }
+            )
         }
     }
 
@@ -137,10 +140,11 @@ module supra_framework::randomness_config {
         initialize_for_testing(&framework);
 
         // Enabling.
-        let config = new_v1(
-            fixed_point64::create_from_rational(1, 2),
-            fixed_point64::create_from_rational(2, 3)
-        );
+        let config =
+            new_v1(
+                fixed_point64::create_from_rational(1, 2),
+                fixed_point64::create_from_rational(2, 3)
+            );
         set_for_next_epoch(&framework, config);
         on_new_epoch(&framework);
         assert!(enabled(), 1);
diff --git a/aptos-move/framework/supra-framework/sources/dkg.move b/aptos-move/framework/supra-framework/sources/dkg.move
index f06ca82fb93..6cb058cbccc 100644
--- a/aptos-move/framework/supra-framework/sources/dkg.move
+++ b/aptos-move/framework/supra-framework/sources/dkg.move
@@ -1,184 +1,104 @@
-// Copyright (c) 2024 Supra.
+/// Deprecated. Replaced by supra_dkg. Retained because the module has already been deployed to
+/// production.
+///
 /// DKG on-chain states and helper functions.
 module supra_framework::dkg {
-    use std::dkg_committee::{DkgCommittee, ReceiverCommittee, new_dkg_committee_output};
     use std::error;
     use std::option;
-    use std::option::{Option};
-    use std::vector;
-    use aptos_std::any;
-    use aptos_std::type_info;
+    use std::option::Option;
     use supra_framework::event::emit;
+    use supra_framework::randomness_config::RandomnessConfig;
     use supra_framework::system_addresses;
     use supra_framework::timestamp;
-    use supra_framework::stake;
-    
+    use supra_framework::validator_consensus_info::ValidatorConsensusInfo;
     friend supra_framework::block;
     friend supra_framework::reconfiguration_with_dkg;
 
-    const EDKG_NOT_IN_PROGRESS: u64 = 1;
-    const EDKG_META_ALREADY_SET: u64 = 2;
-    const EDKG_META_NOT_SET: u64 = 3;
-    const EDKG_INVALID_PK_SHARES: u64 = 4;
+    const EDKG_IN_PROGRESS: u64 = 1;
+    const EDKG_NOT_IN_PROGRESS: u64 = 2;
 
-    #[event]
-    struct DKGStartEvent has drop, store {
-        session_metadata: DKGSessionMetadata,
-        start_time_us: u64,
-    }
-
-    #[event]
-    struct DKGMetaSetEvent has drop, store {
-        dkg_meta_transcript: vector,
+    /// This can be considered as the public input of DKG.
+    struct DKGSessionMetadata has copy, drop, store {
+        dealer_epoch: u64,
+        randomness_config: RandomnessConfig,
+        dealer_validator_set: vector,
+        target_validator_set: vector
     }
 
     #[event]
-    struct DKGFinishEvent has drop, store {
-        target_committees_public_key_shares: vector
+    struct DKGStartEvent has drop, store {
+        session_metadata: DKGSessionMetadata,
+        start_time_us: u64
     }
 
-    /// This can be considered as the public input of DKG.
-    struct DKGSessionMetadata has copy, drop, store {
-        dealer_epoch: u64,
-        randomness_seed: vector,
-        dealer_committee: DkgCommittee,
-        target_committees: vector,
-    }
-    
     /// The input and output of a DKG session.
     /// The validator set of epoch `x` works together for an DKG output for the target validator set of epoch `x+1`.
     struct DKGSessionState has copy, store, drop {
         metadata: DKGSessionMetadata,
         start_time_us: u64,
-        dkg_meta_transcript: vector,
-        target_committees_public_key_shares: vector
+        transcript: vector
     }
 
     /// The completed and in-progress DKG sessions.
     struct DKGState has key {
         last_completed: Option,
-        in_progress: Option,
-    }
-
-    struct OnChainAggregateCommitment has copy, drop{
-        bls12381_commitment_g: vector,
-        bls12381_commitment_evals: vector>,
-        dealer_ids: vector,
-        committee_index: u32,
-        epoch: u64,
-        chain_id: u8,
-        threshold_type: u8,
-    }
-
-    struct OnChainAggregateCommitmentAllCommittees has copy, drop{
-        commitments: vector,
+        in_progress: Option
     }
 
     /// Called in genesis to initialize on-chain states.
-    public(friend) fun initialize(supra_framework: &signer) {
+    public fun initialize(supra_framework: &signer) {
         system_addresses::assert_supra_framework(supra_framework);
         if (!exists(@supra_framework)) {
             move_to(
                 supra_framework,
                 DKGState {
                     last_completed: std::option::none(),
-                    in_progress: std::option::none(),
+                    in_progress: std::option::none()
                 }
             );
-        };
+        }
     }
 
     /// Mark on-chain DKG state as in-progress. Notify validators to start DKG.
     /// Abort if a DKG is already in progress.
     public(friend) fun start(
         dealer_epoch: u64,
-        randomness_seed: vector,
-        dealer_committee: DkgCommittee,
-        target_committees: vector
+        randomness_config: RandomnessConfig,
+        dealer_validator_set: vector,
+        target_validator_set: vector
     ) acquires DKGState {
         let dkg_state = borrow_global_mut(@supra_framework);
         let new_session_metadata = DKGSessionMetadata {
             dealer_epoch,
-            randomness_seed,
-            dealer_committee,
-            target_committees,
+            randomness_config,
+            dealer_validator_set,
+            target_validator_set
         };
         let start_time_us = timestamp::now_microseconds();
-        dkg_state.in_progress = std::option::some(DKGSessionState {
-            metadata: new_session_metadata,
-            start_time_us,
-            dkg_meta_transcript: vector[],
-            target_committees_public_key_shares: vector[],
-        });
-
-        emit(DKGStartEvent {
-            start_time_us,
-            session_metadata: new_session_metadata,
-        });
-    }
-
-    /// Family Node sets the DKGMeta for the in-progress DKG session
-    /// The dkg transcript is assumed to have been already verified by the aptos VM in `process_dkg_result` method
-    public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector)
-    acquires DKGState {
-        // ensure dkg is in progress
-        let dkg_state = borrow_global_mut(@supra_framework);
-        assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS));
-
-        // we only add the first DKG Meta proposed and ignore the rest
-        let session = option::extract(&mut dkg_state.in_progress);
-        assert!(vector::length(&session.dkg_meta_transcript) == 0, error::already_exists(EDKG_META_ALREADY_SET));
-        session.dkg_meta_transcript = dkg_meta_all_committees;
-        dkg_state.in_progress = option::some(session);
+        dkg_state.in_progress = std::option::some(
+            DKGSessionState {
+                metadata: new_session_metadata,
+                start_time_us,
+                transcript: vector[]
+            }
+        );
 
-        emit(DKGMetaSetEvent {
-            dkg_meta_transcript: dkg_meta_all_committees,
-        });
+        emit(DKGStartEvent { start_time_us, session_metadata: new_session_metadata });
     }
 
-    /// Family Node sets the `target_committees_public_key_shares` for the in-progress DKG session and
-    /// marks the incomplete DKG session completed.
-    ///The `target_committees_public_key_shares` is assumed to be verified by the aptos VM before calling this function
-    public(friend) fun finish(target_committees_public_key_shares: vector)
-    acquires DKGState {
-        // ensure dkg is in progress
+    /// Put a transcript into the currently incomplete DKG session, then mark it completed.
+    ///
+    /// Abort if DKG is not in progress.
+    public(friend) fun finish(transcript: vector) acquires DKGState {
         let dkg_state = borrow_global_mut(@supra_framework);
-        assert!(option::is_some(&dkg_state.in_progress), error::invalid_state(EDKG_NOT_IN_PROGRESS));
-
-        // DKG meta should be already set before `finish` is called
+        assert!(
+            option::is_some(&dkg_state.in_progress),
+            error::invalid_state(EDKG_NOT_IN_PROGRESS)
+        );
         let session = option::extract(&mut dkg_state.in_progress);
-        assert!(vector::length(&session.dkg_meta_transcript) > 0, error::already_exists(EDKG_META_NOT_SET));
-
-        session.target_committees_public_key_shares = target_committees_public_key_shares;
+        session.transcript = transcript;
         dkg_state.last_completed = option::some(session);
         dkg_state.in_progress = option::none();
-
-        // propagate updated keys to stake.move for all threshold types
-        let public_key_shares_all_comms_serialized
-            = any::new(type_info::type_name(), target_committees_public_key_shares);
-        let public_key_shares_all_comms = any::unpack(public_key_shares_all_comms_serialized);
-        
-        // Build a vector of DkgCommitteeOutput for all committees
-        let committee_outputs = vector[];
-        let i = 0;
-        let len = vector::length(&public_key_shares_all_comms.commitments);
-        while (i < len) {
-            let commitment = vector::borrow(&public_key_shares_all_comms.commitments, i);
-            // As the first index contains the committee's threshold public key, we can skip that
-            let evals = vector::slice(&commitment.bls12381_commitment_evals, 1, vector::length(&commitment.bls12381_commitment_evals));
-            
-            vector::push_back(
-                &mut committee_outputs,
-                new_dkg_committee_output(commitment.threshold_type, evals)
-            );
-            i = i + 1;
-        };
-        
-        // Set all keys for all threshold types
-        stake::set_dkg_output_keys(committee_outputs);
-        emit(DKGFinishEvent {
-            target_committees_public_key_shares,
-        });
     }
 
     /// Delete the currently incomplete session, if it exists.
@@ -199,15 +119,6 @@ module supra_framework::dkg {
         }
     }
 
-    /// Return the last completed DKG session state, if it exists.
-    public fun last_completed_session(): Option acquires DKGState {
-        if (exists(@supra_framework)) {
-            borrow_global(@supra_framework).last_completed
-        } else {
-            option::none()
-        }
-    }
-
     /// Return the dealer epoch of a `DKGSessionState`.
     public fun session_dealer_epoch(session: &DKGSessionState): u64 {
         session.metadata.dealer_epoch
diff --git a/aptos-move/framework/supra-framework/sources/dkg.spec.move b/aptos-move/framework/supra-framework/sources/dkg.spec.move
index 99ffa012427..d5a5ea90589 100644
--- a/aptos-move/framework/supra-framework/sources/dkg.spec.move
+++ b/aptos-move/framework/supra-framework/sources/dkg.spec.move
@@ -2,7 +2,8 @@ spec supra_framework::dkg {
 
     spec module {
         use supra_framework::chain_status;
-        invariant [suspendable] chain_status::is_operating() ==> exists(@supra_framework);
+        invariant [suspendable] chain_status::is_operating() ==>
+            exists(@supra_framework);
     }
 
     spec initialize(supra_framework: &signer) {
@@ -13,22 +14,15 @@ spec supra_framework::dkg {
 
     spec start(
         dealer_epoch: u64,
-        randomness_seed: vector,
-        dealer_committee: DkgCommittee,
-        target_committees: vector
+        randomness_config: RandomnessConfig,
+        dealer_validator_set: vector,
+        target_validator_set: vector
     ) {
         aborts_if !exists(@supra_framework);
         aborts_if !exists(@supra_framework);
     }
 
-    spec set_dkg_meta(dkg_meta_all_committees: vector) {
-        use std::option;
-        requires exists(@supra_framework);
-        requires option::is_some(global(@supra_framework).in_progress);
-        aborts_if false;
-    }
-
-    spec finish(target_committees_public_key_shares: vector) {
+    spec finish(transcript: vector) {
         use std::option;
         requires exists(@supra_framework);
         requires option::is_some(global(@supra_framework).in_progress);
@@ -38,9 +32,7 @@ spec supra_framework::dkg {
     spec fun has_incomplete_session(): bool {
         if (exists(@supra_framework)) {
             option::spec_is_some(global(@supra_framework).in_progress)
-        } else {
-            false
-        }
+        } else { false }
     }
 
     spec try_clear_incomplete_session(fx: &signer) {
diff --git a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move
index 00db1a4cf5d..c272aaa336c 100644
--- a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move
+++ b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move
@@ -10,7 +10,7 @@ module supra_framework::reconfiguration_with_dkg {
     use supra_framework::automation_registry;
     use supra_framework::randomness;
     use supra_framework::consensus_config;
-    use supra_framework::dkg;
+    use supra_framework::supra_dkg;
     use supra_framework::dkg_config;
     use supra_framework::execution_config;
     use supra_framework::gas_schedule;
@@ -34,12 +34,11 @@ module supra_framework::reconfiguration_with_dkg {
     /// Trigger a reconfiguration with DKG.
     /// Do nothing if one is already in progress.
     public(friend) fun try_start() {
-        let incomplete_dkg_session = dkg::incomplete_session();
+        let incomplete_dkg_session = supra_dkg::incomplete_session();
         if (option::is_some(&incomplete_dkg_session)) {
             let session = option::borrow(&incomplete_dkg_session);
-            if (dkg::session_dealer_epoch(session) == reconfiguration::current_epoch()) {
-                return
-            }
+            if (supra_dkg::session_dealer_epoch(session)
+                == reconfiguration::current_epoch()) { return }
         };
         reconfiguration_state::on_reconfig_start();
         let cur_epoch = reconfiguration::current_epoch();
@@ -70,7 +69,7 @@ module supra_framework::reconfiguration_with_dkg {
         };
 
         // DKG for configured receiver committees
-        dkg::start(
+        supra_dkg::start(
             cur_epoch,
             randomness_seed,
             new_dkg_committee_from_validator_consensus_info(
@@ -82,7 +81,7 @@ module supra_framework::reconfiguration_with_dkg {
     }
 
     fun set_dkg_meta(dkg_meta: vector) {
-        dkg::set_dkg_meta(dkg_meta);
+        supra_dkg::set_dkg_meta(dkg_meta);
     }
 
     /// Clear incomplete DKG session, if it exists.
@@ -91,7 +90,7 @@ module supra_framework::reconfiguration_with_dkg {
     /// Run the default reconfiguration to enter the new epoch.
     public(friend) fun finish(framework: &signer) {
         system_addresses::assert_supra_framework(framework);
-        dkg::try_clear_incomplete_session(framework);
+        supra_dkg::try_clear_incomplete_session(framework);
         consensus_config::on_new_epoch(framework);
         execution_config::on_new_epoch(framework);
         supra_config::on_new_epoch(framework);
@@ -114,7 +113,7 @@ module supra_framework::reconfiguration_with_dkg {
     /// Complete the current reconfiguration with DKG.
     /// Abort if no DKG is in progress.
     fun finish_with_dkg_result(account: &signer, dkg_result: vector) {
-        dkg::finish(dkg_result);
+        supra_dkg::finish(dkg_result);
         finish(account);
     }
 }
diff --git a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.spec.move b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.spec.move
index d1ca7d47e20..06bf7afd304 100644
--- a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.spec.move
+++ b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.spec.move
@@ -12,8 +12,8 @@ spec supra_framework::reconfiguration_with_dkg {
         requires chain_status::is_operating();
         include stake::ResourceRequirement;
         include stake::GetReconfigStartTimeRequirement;
-        include features::spec_periodical_reward_rate_decrease_enabled(
-        ) ==> staking_config::StakingRewardsConfigEnabledRequirement;
+        include features::spec_periodical_reward_rate_decrease_enabled() ==>
+            staking_config::StakingRewardsConfigEnabledRequirement;
         aborts_if false;
         pragma verify_duration_estimate = 600; // TODO: set because of timeout (property proved).
     }
@@ -66,12 +66,10 @@ spec supra_framework::reconfiguration_with_dkg {
     }
 
     spec finish_with_dkg_result(account: &signer, dkg_result: vector) {
-        use supra_framework::dkg;
+        use supra_framework::supra_dkg;
         pragma verify_duration_estimate = 1500;
-        include FinishRequirement {
-            framework: account
-        };
-        requires dkg::has_incomplete_session();
+        include FinishRequirement { framework: account };
+        requires supra_dkg::has_incomplete_session();
         aborts_if false;
     }
 }
diff --git a/aptos-move/framework/supra-framework/sources/stake.move b/aptos-move/framework/supra-framework/sources/stake.move
index 68d342c61b9..7b3f1f8bf37 100644
--- a/aptos-move/framework/supra-framework/sources/stake.move
+++ b/aptos-move/framework/supra-framework/sources/stake.move
@@ -44,6 +44,7 @@ module supra_framework::stake {
     friend supra_framework::transaction_fee;
     friend supra_framework::dkg;
     friend supra_framework::leader_ban_registry;
+    friend supra_framework::supra_dkg;
 
     #[test_only]
     friend supra_framework::test_leader_ban_registry;
@@ -698,20 +699,7 @@ module supra_framework::stake {
         network_addresses: vector,
         fullnode_addresses: vector
     ) acquires AllowedValidators {
-
-        // Checks the public key is valid to prevent rogue-key attacks.
-        if (std::features::supra_validator_identity_v2_enabled()) {
-            let _valid_public_key =
-                validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey);
-        } else {
-            let valid_public_key =
-                ed25519::new_validated_public_key_from_bytes(consensus_pubkey);
-            assert!(
-                option::is_some(&valid_public_key),
-                error::invalid_argument(EINVALID_PUBLIC_KEY)
-            );
-        };
-
+        validate_consensus_public_key(consensus_pubkey);
         initialize_owner(account);
         move_to(
             account,
@@ -724,6 +712,36 @@ module supra_framework::stake {
         );
     }
 
+    // Checks the public key is valid to prevent rogue-key attacks.
+    //
+    // The deserializer for the new format currently doesn't offer a way for us to handle
+    // failure, so we expect the new format when the related feature flag has been active
+    // (the flag should only be activated after all validators have migrated to the new
+    // format) and fall back to the new format when deserialization fails before the flag
+    // has been activated.
+    fun validate_consensus_public_key(consensus_pubkey: vector) {
+        if (std::features::supra_validator_identity_v2_enabled()) {
+            // Expect the new format.
+            let _valid_public_key =
+                validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey);
+        } else {
+            // Check the old format.
+            let maybe_valid_public_key =
+                ed25519::new_validated_public_key_from_bytes(consensus_pubkey);
+
+            if (option::is_none(&maybe_valid_public_key)) {
+                // Fall back to the new format. This enables validators to register their keys in
+                // the new format before the v2 feature flag is activated, which is safe because the
+                // new keys are a superset of the old and the consensus has logic for maintaining
+                // backwards compatibility.
+                let _valid_public_key =
+                    validator_public_keys::validator_public_keys_from_bytes(
+                        consensus_pubkey
+                    );
+            }
+        };
+    }
+
     fun initialize_owner(owner: &signer) acquires AllowedValidators {
         let owner_address = signer::address_of(owner);
         assert!(is_allowed(owner_address), error::not_found(EINELIGIBLE_VALIDATOR));
@@ -966,36 +984,8 @@ module supra_framework::stake {
         );
         let validator_info = borrow_global_mut(pool_address);
         let old_consensus_pubkey = validator_info.consensus_pubkey;
-        // Checks the public key is valid to prevent rogue-key attacks.
-        if (!genesis) {
-            if (std::features::supra_validator_identity_v2_enabled()) {
-                let _valid_public_key =
-                    validator_public_keys::validator_public_keys_from_bytes(
-                        new_consensus_pubkey
-                    );
-            } else {
-                let valid_public_key =
-                    ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey);
-                assert!(
-                    option::is_some(&valid_public_key),
-                    error::invalid_argument(EINVALID_PUBLIC_KEY)
-                );
-            };
-        } else {
-            if (std::features::supra_validator_identity_v2_enabled()) {
-                let _valid_public_key =
-                    validator_public_keys::validator_public_keys_from_bytes(
-                        new_consensus_pubkey
-                    );
-            } else {
-                let valid_public_key =
-                    ed25519::new_validated_public_key_from_bytes(new_consensus_pubkey);
-                assert!(
-                    option::is_some(&valid_public_key),
-                    error::invalid_argument(EINVALID_PUBLIC_KEY)
-                );
-            };
-        };
+
+        validate_consensus_public_key(new_consensus_pubkey);
         validator_info.consensus_pubkey = new_consensus_pubkey;
 
         if (std::features::module_event_migration_enabled()) {
@@ -1704,7 +1694,7 @@ module supra_framework::stake {
     /// `pending_active` is iterated in reverse to match the order produced by `on_new_epoch`
     /// (which appends via `pop_back`).
     fun compute_next_validator_set_internal(
-        use_current_config_for_actives: bool,
+        use_current_config_for_actives: bool
     ): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
         // Init.
         let cur_validator_set = borrow_global(@supra_framework);
@@ -1751,14 +1741,15 @@ module supra_framework::stake {
             let cur_pending_active = coin::value(&stake_pool.pending_active);
             let cur_pending_inactive = coin::value(&stake_pool.pending_inactive);
 
-            let cur_reward = calculate_candidate_reward(
-                candidate,
-                candidate_in_current_validator_set,
-                cur_active,
-                validator_perf,
-                rewards_rate,
-                rewards_rate_denominator
-            );
+            let cur_reward =
+                calculate_candidate_reward(
+                    candidate,
+                    candidate_in_current_validator_set,
+                    cur_active,
+                    validator_perf,
+                    rewards_rate,
+                    rewards_rate_denominator
+                );
 
             let cur_fee = collect_candidate_fee(candidate.addr);
 
@@ -1779,7 +1770,8 @@ module supra_framework::stake {
 
             if (new_voting_power >= minimum_stake) {
                 let config =
-                    if (use_current_config_for_actives && candidate_in_current_validator_set) {
+                    if (use_current_config_for_actives
+                        && candidate_in_current_validator_set) {
                         // Use the current-epoch config snapshot so that any mid-epoch changes
                         // (consensus key, network addresses, etc.) only take effect after the
                         // epoch transition, not during DKG.
@@ -1824,17 +1816,19 @@ module supra_framework::stake {
         cur_active: u64,
         validator_perf: &ValidatorPerformance,
         rewards_rate: u64,
-        rewards_rate_denominator: u64,
+        rewards_rate_denominator: u64
     ): u64 {
         if (candidate_in_current_validator_set && cur_active != 0) {
             spec {
-                assert candidate.config.validator_index < len(validator_perf.validators);
+                assert candidate.config.validator_index
+                    < len(validator_perf.validators);
             };
             let cur_perf = vector::borrow(
                 &validator_perf.validators, candidate.config.validator_index
             );
             spec {
-                assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64;
+                assume cur_perf.successful_proposals + cur_perf.failed_proposals
+                    <= MAX_U64;
             };
             calculate_rewards_amount(
                 cur_active,
diff --git a/aptos-move/framework/supra-framework/sources/supra_dkg.move b/aptos-move/framework/supra-framework/sources/supra_dkg.move
new file mode 100644
index 00000000000..4d2d46b6d74
--- /dev/null
+++ b/aptos-move/framework/supra-framework/sources/supra_dkg.move
@@ -0,0 +1,234 @@
+// Copyright (c) 2024 Supra.
+/// DKG on-chain states and helper functions.
+module supra_framework::supra_dkg {
+    use std::dkg_committee::{DkgCommittee, ReceiverCommittee, new_dkg_committee_output};
+    use std::error;
+    use std::option;
+    use std::option::{Option};
+    use std::vector;
+    use aptos_std::any;
+    use aptos_std::type_info;
+    use supra_framework::event::emit;
+    use supra_framework::system_addresses;
+    use supra_framework::timestamp;
+    use supra_framework::stake;
+
+    friend supra_framework::block;
+    friend supra_framework::reconfiguration_with_dkg;
+
+    const EDKG_NOT_IN_PROGRESS: u64 = 1;
+    const EDKG_META_ALREADY_SET: u64 = 2;
+    const EDKG_META_NOT_SET: u64 = 3;
+    const EDKG_INVALID_PK_SHARES: u64 = 4;
+
+    #[event]
+    struct DKGStartEvent has drop, store {
+        session_metadata: DKGSessionMetadata,
+        start_time_us: u64
+    }
+
+    #[event]
+    struct DKGMetaSetEvent has drop, store {
+        dkg_meta_transcript: vector
+    }
+
+    #[event]
+    struct DKGFinishEvent has drop, store {
+        target_committees_public_key_shares: vector
+    }
+
+    /// This can be considered as the public input of DKG.
+    struct DKGSessionMetadata has copy, drop, store {
+        dealer_epoch: u64,
+        randomness_seed: vector,
+        dealer_committee: DkgCommittee,
+        target_committees: vector
+    }
+
+    /// The input and output of a DKG session.
+    /// The validator set of epoch `x` works together for an DKG output for the target validator set of epoch `x+1`.
+    struct DKGSessionState has copy, store, drop {
+        metadata: DKGSessionMetadata,
+        start_time_us: u64,
+        dkg_meta_transcript: vector,
+        target_committees_public_key_shares: vector
+    }
+
+    /// The completed and in-progress DKG sessions.
+    struct DKGState has key {
+        last_completed: Option,
+        in_progress: Option
+    }
+
+    struct OnChainAggregateCommitment has copy, drop {
+        bls12381_commitment_g: vector,
+        bls12381_commitment_evals: vector>,
+        dealer_ids: vector,
+        committee_index: u32,
+        epoch: u64,
+        chain_id: u8,
+        threshold_type: u8
+    }
+
+    struct OnChainAggregateCommitmentAllCommittees has copy, drop {
+        commitments: vector
+    }
+
+    /// Called in genesis to initialize on-chain states when DKG is active from genesis,
+    /// otherwise, must be called from a governance script before the DKG feature flag
+    /// is activated.
+    public fun initialize(supra_framework: &signer) {
+        system_addresses::assert_supra_framework(supra_framework);
+        if (!exists(@supra_framework)) {
+            move_to(
+                supra_framework,
+                DKGState {
+                    last_completed: std::option::none(),
+                    in_progress: std::option::none()
+                }
+            );
+        };
+    }
+
+    /// Mark on-chain DKG state as in-progress. Notify validators to start DKG.
+    /// Abort if a DKG is already in progress.
+    public(friend) fun start(
+        dealer_epoch: u64,
+        randomness_seed: vector,
+        dealer_committee: DkgCommittee,
+        target_committees: vector
+    ) acquires DKGState {
+        let dkg_state = borrow_global_mut(@supra_framework);
+        let new_session_metadata = DKGSessionMetadata {
+            dealer_epoch,
+            randomness_seed,
+            dealer_committee,
+            target_committees
+        };
+        let start_time_us = timestamp::now_microseconds();
+        dkg_state.in_progress = std::option::some(
+            DKGSessionState {
+                metadata: new_session_metadata,
+                start_time_us,
+                dkg_meta_transcript: vector[],
+                target_committees_public_key_shares: vector[]
+            }
+        );
+
+        emit(DKGStartEvent { start_time_us, session_metadata: new_session_metadata });
+    }
+
+    /// Family Node sets the DKGMeta for the in-progress DKG session
+    /// The dkg transcript is assumed to have been already verified by the aptos VM in `process_dkg_result` method
+    public(friend) fun set_dkg_meta(dkg_meta_all_committees: vector) acquires DKGState {
+        // ensure dkg is in progress
+        let dkg_state = borrow_global_mut(@supra_framework);
+        assert!(
+            option::is_some(&dkg_state.in_progress),
+            error::invalid_state(EDKG_NOT_IN_PROGRESS)
+        );
+
+        // we only add the first DKG Meta proposed and ignore the rest
+        let session = option::extract(&mut dkg_state.in_progress);
+        assert!(
+            vector::length(&session.dkg_meta_transcript) == 0,
+            error::already_exists(EDKG_META_ALREADY_SET)
+        );
+        session.dkg_meta_transcript = dkg_meta_all_committees;
+        dkg_state.in_progress = option::some(session);
+
+        emit(DKGMetaSetEvent { dkg_meta_transcript: dkg_meta_all_committees });
+    }
+
+    /// Family Node sets the `target_committees_public_key_shares` for the in-progress DKG session and
+    /// marks the incomplete DKG session completed.
+    ///The `target_committees_public_key_shares` is assumed to be verified by the aptos VM before calling this function
+    public(friend) fun finish(
+        target_committees_public_key_shares: vector
+    ) acquires DKGState {
+        // ensure dkg is in progress
+        let dkg_state = borrow_global_mut(@supra_framework);
+        assert!(
+            option::is_some(&dkg_state.in_progress),
+            error::invalid_state(EDKG_NOT_IN_PROGRESS)
+        );
+
+        // DKG meta should be already set before `finish` is called
+        let session = option::extract(&mut dkg_state.in_progress);
+        assert!(
+            vector::length(&session.dkg_meta_transcript) > 0,
+            error::already_exists(EDKG_META_NOT_SET)
+        );
+
+        session.target_committees_public_key_shares = target_committees_public_key_shares;
+        dkg_state.last_completed = option::some(session);
+        dkg_state.in_progress = option::none();
+
+        // propagate updated keys to stake.move for all threshold types
+        let public_key_shares_all_comms_serialized =
+            any::new(
+                type_info::type_name(),
+                target_committees_public_key_shares
+            );
+        let public_key_shares_all_comms =
+            any::unpack(
+                public_key_shares_all_comms_serialized
+            );
+
+        // Build a vector of DkgCommitteeOutput for all committees
+        let committee_outputs = vector[];
+        let i = 0;
+        let len = vector::length(&public_key_shares_all_comms.commitments);
+        while (i < len) {
+            let commitment = vector::borrow(&public_key_shares_all_comms.commitments, i);
+            // As the first index contains the committee's threshold public key, we can skip that
+            let evals = vector::slice(
+                &commitment.bls12381_commitment_evals,
+                1,
+                vector::length(&commitment.bls12381_commitment_evals)
+            );
+
+            vector::push_back(
+                &mut committee_outputs,
+                new_dkg_committee_output(commitment.threshold_type, evals)
+            );
+            i = i + 1;
+        };
+
+        // Set all keys for all threshold types
+        stake::set_dkg_output_keys(committee_outputs);
+        emit(DKGFinishEvent { target_committees_public_key_shares });
+    }
+
+    /// Delete the currently incomplete session, if it exists.
+    public fun try_clear_incomplete_session(fx: &signer) acquires DKGState {
+        system_addresses::assert_supra_framework(fx);
+        if (exists(@supra_framework)) {
+            let dkg_state = borrow_global_mut(@supra_framework);
+            dkg_state.in_progress = option::none();
+        }
+    }
+
+    /// Return the incomplete DKG session state, if it exists.
+    public fun incomplete_session(): Option acquires DKGState {
+        if (exists(@supra_framework)) {
+            borrow_global(@supra_framework).in_progress
+        } else {
+            option::none()
+        }
+    }
+
+    /// Return the last completed DKG session state, if it exists.
+    public fun last_completed_session(): Option acquires DKGState {
+        if (exists(@supra_framework)) {
+            borrow_global(@supra_framework).last_completed
+        } else {
+            option::none()
+        }
+    }
+
+    /// Return the dealer epoch of a `DKGSessionState`.
+    public fun session_dealer_epoch(session: &DKGSessionState): u64 {
+        session.metadata.dealer_epoch
+    }
+}
diff --git a/aptos-move/framework/supra-framework/sources/supra_dkg.spec.move b/aptos-move/framework/supra-framework/sources/supra_dkg.spec.move
new file mode 100644
index 00000000000..71bd99ead49
--- /dev/null
+++ b/aptos-move/framework/supra-framework/sources/supra_dkg.spec.move
@@ -0,0 +1,54 @@
+spec supra_framework::supra_dkg {
+
+    spec module {
+        use supra_framework::chain_status;
+        invariant [suspendable] chain_status::is_operating() ==>
+            exists(@supra_framework);
+    }
+
+    spec initialize(supra_framework: &signer) {
+        use std::signer;
+        let supra_framework_addr = signer::address_of(supra_framework);
+        aborts_if supra_framework_addr != @supra_framework;
+    }
+
+    spec start(
+        dealer_epoch: u64,
+        randomness_seed: vector,
+        dealer_committee: DkgCommittee,
+        target_committees: vector
+    ) {
+        aborts_if !exists(@supra_framework);
+        aborts_if !exists(@supra_framework);
+    }
+
+    spec set_dkg_meta(dkg_meta_all_committees: vector) {
+        use std::option;
+        requires exists(@supra_framework);
+        requires option::is_some(global(@supra_framework).in_progress);
+        aborts_if false;
+    }
+
+    spec finish(target_committees_public_key_shares: vector) {
+        use std::option;
+        requires exists(@supra_framework);
+        requires option::is_some(global(@supra_framework).in_progress);
+        aborts_if false;
+    }
+
+    spec fun has_incomplete_session(): bool {
+        if (exists(@supra_framework)) {
+            option::spec_is_some(global(@supra_framework).in_progress)
+        } else { false }
+    }
+
+    spec try_clear_incomplete_session(fx: &signer) {
+        use std::signer;
+        let addr = signer::address_of(fx);
+        aborts_if addr != @supra_framework;
+    }
+
+    spec incomplete_session(): Option {
+        aborts_if false;
+    }
+}
diff --git a/aptos-move/framework/supra-framework/sources/validator_public_keys.move b/aptos-move/framework/supra-framework/sources/validator_public_keys.move
index 30e389ba0f9..f6dba388b6b 100644
--- a/aptos-move/framework/supra-framework/sources/validator_public_keys.move
+++ b/aptos-move/framework/supra-framework/sources/validator_public_keys.move
@@ -1,6 +1,5 @@
 // Copyright (c) 2024 Supra.
 module supra_framework::validator_public_keys {
-
     use std::bcs;
     use std::error;
     use std::option;
@@ -105,8 +104,7 @@ module supra_framework::validator_public_keys {
         supra_ed_key: ed25519::SecretKey,
     }
 
-    public fun validator_public_keys_from_bytes(bytes: vector): ValidatorPublicKeys{
-
+    public fun validator_public_keys_from_bytes(bytes: vector): ValidatorPublicKeys {
         // bcs deserialization
         let bytes_serialized = any::new(type_info::type_name(), bytes);
         let validator_public_keys = any::unpack(bytes_serialized);
diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs
index 7ffdf0afac8..d4132f464ad 100644
--- a/aptos-move/vm-genesis/src/lib.rs
+++ b/aptos-move/vm-genesis/src/lib.rs
@@ -68,7 +68,7 @@ const VERSION_MODULE_NAME: &str = "version";
 const JWK_CONSENSUS_CONFIG_MODULE_NAME: &str = "jwk_consensus_config";
 const JWKS_MODULE_NAME: &str = "jwks";
 const CONFIG_BUFFER_MODULE_NAME: &str = "config_buffer";
-const DKG_MODULE_NAME: &str = "dkg";
+const DKG_MODULE_NAME: &str = "supra_dkg";
 const RANDOMNESS_API_V0_CONFIG_MODULE_NAME: &str = "randomness_api_v0_config";
 const RANDOMNESS_CONFIG_SEQNUM_MODULE_NAME: &str = "randomness_config_seqnum";
 const RANDOMNESS_CONFIG_MODULE_NAME: &str = "randomness_config";
diff --git a/types/src/dkg/events.rs b/types/src/dkg/events.rs
index bb08f2ebb7e..c50cfba1556 100644
--- a/types/src/dkg/events.rs
+++ b/types/src/dkg/events.rs
@@ -12,7 +12,7 @@ pub struct DKGStartEvent {
 }
 
 impl MoveStructType for DKGStartEvent {
-    const MODULE_NAME: &'static IdentStr = ident_str!("dkg");
+    const MODULE_NAME: &'static IdentStr = ident_str!("supra_dkg");
     const STRUCT_NAME: &'static IdentStr = ident_str!("DKGStartEvent");
 }
 
@@ -25,7 +25,7 @@ pub struct DKGMetaSetEvent {
 }
 
 impl MoveStructType for DKGMetaSetEvent {
-    const MODULE_NAME: &'static IdentStr = ident_str!("dkg");
+    const MODULE_NAME: &'static IdentStr = ident_str!("supra_dkg");
     const STRUCT_NAME: &'static IdentStr = ident_str!("DKGMetaSetEvent");
 }
 
@@ -38,7 +38,7 @@ pub struct DKGFinishEvent {
 }
 
 impl MoveStructType for DKGFinishEvent {
-    const MODULE_NAME: &'static IdentStr = ident_str!("dkg");
+    const MODULE_NAME: &'static IdentStr = ident_str!("supra_dkg");
     const STRUCT_NAME: &'static IdentStr = ident_str!("DKGFinishEvent");
 }
 
diff --git a/types/src/dkg/state.rs b/types/src/dkg/state.rs
index 18bbf8f1dbc..73db51eea76 100644
--- a/types/src/dkg/state.rs
+++ b/types/src/dkg/state.rs
@@ -4,7 +4,7 @@ use crate::{
 };
 use serde::{Deserialize, Serialize};
 
-// Reflection of `0x1::dkg::DKGSessionMetadata` in rust.
+// Reflection of `0x1::supra_dkg::DKGSessionMetadata` in rust.
 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
 pub struct DKGSessionMetadata {
     pub dealer_epoch: u64,
@@ -23,7 +23,7 @@ impl DKGSessionMetadata {
     }
 }
 
-/// Reflection of Move type `0x1::dkg::DKGSessionState`.
+/// Reflection of Move type `0x1::supra_dkg::DKGSessionState`.
 #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
 pub struct DKGSessionState {
     pub metadata: DKGSessionMetadata,
@@ -37,7 +37,7 @@ impl DKGSessionState {
         self.metadata.dealer_epoch + 1
     }
 }
-/// Reflection of Move type `0x1::dkg::DKGState`.
+/// Reflection of Move type `0x1::supra_dkg::DKGState`.
 #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
 pub struct DKGState {
     pub last_completed: Option,
@@ -65,6 +65,6 @@ impl DKGState {
 }
 
 impl OnChainConfig for DKGState {
-    const MODULE_IDENTIFIER: &'static str = "dkg";
+    const MODULE_IDENTIFIER: &'static str = "supra_dkg";
     const TYPE_IDENTIFIER: &'static str = "DKGState";
 }

From 306b60776be2ba382e35e327a7812233ae7acb13 Mon Sep 17 00:00:00 2001
From: Isaac Doidge <30425649+isaacdoidge@users.noreply.github.com>
Date: Tue, 21 Apr 2026 14:23:06 +1000
Subject: [PATCH 17/31] Ensured that governance transactions can access
 randomness. (#355)

---
 aptos-move/aptos-vm/src/aptos_vm.rs | 49 ++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs
index ab4ceeb0c14..d09cbdf7c28 100644
--- a/aptos-move/aptos-vm/src/aptos_vm.rs
+++ b/aptos-move/aptos-vm/src/aptos_vm.rs
@@ -738,6 +738,7 @@ impl AptosVM {
         traversal_context: &mut TraversalContext,
         senders: Vec,
         script: &Script,
+        is_approved_gov_script: bool,
     ) -> Result<(), VMStatus> {
         // Note: Feature gating is needed here because the traversal of the dependencies could
         //       result in shallow-loading of the modules and therefore subtle changes in
@@ -767,6 +768,12 @@ impl AptosVM {
             self.features().is_enabled(FeatureFlag::STRUCT_CONSTRUCTORS),
         )?;
 
+        if is_approved_gov_script {
+            // If governance is honest then it will not attempt test-and-abort attacks to abuse
+            // randomness.
+            self.mark_unbiasable(session);
+        }
+
         session.execute_script(
             script.code(),
             script.ty_args().to_vec(),
@@ -839,6 +846,7 @@ impl AptosVM {
         log_context: &AdapterLogSchema,
         new_published_modules_loaded: &mut bool,
         change_set_configs: &ChangeSetConfigs,
+        is_approved_gov_script: bool,
     ) -> Result<(VMStatus, VMOutput), VMStatus> {
         fail_point!("aptos_vm::execute_script_or_entry_function", |_| {
             Err(VMStatus::Error {
@@ -862,6 +870,7 @@ impl AptosVM {
                         traversal_context,
                         txn_data.senders(),
                         script,
+                        is_approved_gov_script,
                     )
                 })?;
             },
@@ -1844,6 +1853,12 @@ impl AptosVM {
             )?;
         }
 
+        if is_approved_gov_script {
+            // If governance is honest then it will not attempt test-and-abort attacks to abuse
+            // randomness.
+            self.mark_unbiasable(session);
+        }
+
         // The prologue MUST be run AFTER any validation. Otherwise you may run prologue and hit
         // SEQUENCE_NUMBER_TOO_NEW if there is more than one transaction from the same sender and
         // end up skipping validation.
@@ -1921,6 +1936,7 @@ impl AptosVM {
             )
         });
         unwrap_or_discard!(exec_result);
+
         let storage_gas_params = unwrap_or_discard!(get_or_vm_startup_failure(
             &self.storage_gas_params,
             log_context
@@ -1966,6 +1982,7 @@ impl AptosVM {
                     log_context,
                     &mut new_published_modules_loaded,
                     change_set_configs,
+                    is_approved_gov_script,
                 ),
             TransactionPayload::Multisig(payload) => self.execute_or_simulate_multisig_transaction(
                 resolver,
@@ -2166,6 +2183,10 @@ impl AptosVM {
                     &mut traversal_context,
                     senders,
                     script,
+                    // This function is currently only used for genesis, so this could be set to
+                    // true, but we don't access randomness during genesis at the moment so there
+                    // is no benefit in doing so.
+                    false,
                 )?;
                 Ok(tmp_session.finish(&change_set_configs)?)
             },
@@ -2306,6 +2327,24 @@ impl AptosVM {
         Ok((VMStatus::Executed, output))
     }
 
+    fn mark_unbiasable(&self, session: &mut SessionExt<'_, '_>) {
+        // During the first epoch in which the feature is activated, threshold keys have not yet
+        // been established (they are produced at the end of that epoch via DKG), so the randomness
+        // seed can be biased to some degree (although with great difficulty) by Byzantine proposers.
+        // However, the randomness usages within the metadata transaction itself (e.g. by the DKG
+        // during epoch change) remain unaffected by test-and-abort attacks, which the bias-ability
+        // check is intended to protect against. Similarly, governance is expected not to attempt to
+        // bias randomness results. This allows us to continue to manually force epoch changes via
+        // governance when necessary, which would otherwise be impossible due to 
+        // reconfiguration_with_dkg::try_start relying on access to randomness,
+        if self.features().is_enabled(FeatureFlag::SUPRA_DKG) {
+            session
+                .get_native_extensions()
+                .get_mut::()
+                .mark_unbiasable();
+        }
+    }
+
     fn process_block_prologue_ext(
         &self,
         resolver: &impl AptosMoveResolver,
@@ -2364,14 +2403,8 @@ impl AptosVM {
 
         let storage = TraversalStorage::new();
 
-        // During the first epoch in which the feature is activated, threshold keys have not yet been established (they
-        // are produced at the end of that epoch via DKG), so randomness remains biasable for that epoch.
-        if self.features().is_enabled(FeatureFlag::SUPRA_DKG){
-            session
-                .get_native_extensions()
-                .get_mut::()
-                .mark_unbiasable();
-        }
+        // The block metadata transaction seeds randomness so is immune to test-and-abort attacks.
+        self.mark_unbiasable(&mut session);
 
         session
             .execute_function_bypass_visibility(

From e28cc05e35265c3129afbafd9beda9c4b5bdfd4a Mon Sep 17 00:00:00 2001
From: Isaac Doidge <30425649+isaacdoidge@users.noreply.github.com>
Date: Thu, 21 May 2026 21:33:36 +1000
Subject: [PATCH 18/31] Ensured that validators cannot register duplicate
 network addresses or consensus keys. (#361)

---
 .../supra-framework/sources/genesis.move      |   4 +-
 .../sources/pbo_delegation_pool.move          |  43 ++-
 .../supra-framework/sources/stake.move        | 292 +++++++++++++++++-
 .../supra-framework/sources/stake.spec.move   |  10 +
 .../delegation_pool_integration_tests.move    |  12 +-
 5 files changed, 343 insertions(+), 18 deletions(-)

diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move
index b202ff61e54..aca82ed292f 100644
--- a/aptos-move/framework/supra-framework/sources/genesis.move
+++ b/aptos-move/framework/supra-framework/sources/genesis.move
@@ -1180,8 +1180,8 @@ module supra_framework::genesis {
                 voter_address: @0x121346,
                 stake_amount: 100 * ONE_SUPRA,
                 consensus_pubkey: _pk_2,
-                network_addresses: x"222222",
-                full_node_network_addresses: x"333333"
+                network_addresses: x"444444",
+                full_node_network_addresses: x"555555"
             },
             commission_percentage: 20,
             join_during_genesis: true
diff --git a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move
index a692ee37b85..f26bea1a75c 100644
--- a/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move
+++ b/aptos-move/framework/supra-framework/sources/pbo_delegation_pool.move
@@ -3037,7 +3037,11 @@ module supra_framework::pbo_delegation_pool {
         );
         let pool_address = get_owned_pool_address(validator_address);
 
-        stake::rotate_consensus_key(validator, pool_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            validator,
+            pool_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
 
         if (amount > 0) {
             stake::mint(validator, amount);
@@ -3295,7 +3299,11 @@ module supra_framework::pbo_delegation_pool {
         );
         let pool_address = get_owned_pool_address(validator_address);
 
-        stake::rotate_consensus_key(validator, pool_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            validator,
+            pool_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
 
         // zero `add_stake` fee as validator is not producing rewards this epoch
         assert!(
@@ -6031,7 +6039,11 @@ module supra_framework::pbo_delegation_pool {
         assert_delegation(validator_address, pool_address, 0, 0, 0);
 
         // activate validator
-        stake::rotate_consensus_key(validator, pool_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            validator,
+            pool_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
         stake::join_validator_set(validator, pool_address);
         end_aptos_epoch();
 
@@ -6318,7 +6330,11 @@ module supra_framework::pbo_delegation_pool {
         unlock(delegator, pool_address, 100 * ONE_SUPRA);
 
         // activate validator
-        stake::rotate_consensus_key(old_operator, pool_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            old_operator,
+            pool_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
         stake::join_validator_set(old_operator, pool_address);
         end_aptos_epoch();
 
@@ -6435,7 +6451,11 @@ module supra_framework::pbo_delegation_pool {
         unlock(delegator, pool_address, 1000000 * ONE_SUPRA);
 
         // activate validator
-        stake::rotate_consensus_key(operator1, pool_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            operator1,
+            pool_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
         stake::join_validator_set(operator1, pool_address);
         end_aptos_epoch();
 
@@ -6552,7 +6572,11 @@ module supra_framework::pbo_delegation_pool {
         unlock(delegator, pool_address, 100 * ONE_SUPRA);
 
         // activate validator
-        stake::rotate_consensus_key(operator, pool_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            operator,
+            pool_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
         stake::join_validator_set(operator, pool_address);
         end_aptos_epoch();
 
@@ -6653,7 +6677,11 @@ module supra_framework::pbo_delegation_pool {
         unlock(delegator, pool_address, 100 * ONE_SUPRA);
 
         // activate validator
-        stake::rotate_consensus_key(operator, pool_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            operator,
+            pool_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
         stake::join_validator_set(operator, pool_address);
         end_aptos_epoch();
 
@@ -10747,3 +10775,4 @@ module supra_framework::pbo_delegation_pool {
         );
     }
 }
+
diff --git a/aptos-move/framework/supra-framework/sources/stake.move b/aptos-move/framework/supra-framework/sources/stake.move
index 7b3f1f8bf37..bc58805b752 100644
--- a/aptos-move/framework/supra-framework/sources/stake.move
+++ b/aptos-move/framework/supra-framework/sources/stake.move
@@ -91,6 +91,10 @@ module supra_framework::stake {
     const ERECONFIGURATION_IN_PROGRESS: u64 = 20;
     /// Invalid DKG public key shares.
     const EDKG_INVALID_PK_SHARES: u64 = 21;
+    /// Another validator in the next validator set already uses this consensus public key.
+    const EDUPLICATE_CONSENSUS_PUBKEY: u64 = 22;
+    /// Another validator in the next validator set already uses these network addresses.
+    const EDUPLICATE_NETWORK_ADDRESSES: u64 = 23;
 
     /// Validator status enum. We can switch to proper enum later once Move supports it.
     const VALIDATOR_STATUS_PENDING_ACTIVE: u64 = 1;
@@ -698,8 +702,15 @@ module supra_framework::stake {
         consensus_pubkey: vector,
         network_addresses: vector,
         fullnode_addresses: vector
-    ) acquires AllowedValidators {
+    ) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
         validate_consensus_public_key(consensus_pubkey);
+        let account_addr = signer::address_of(account);
+        assert_consensus_pubkey_unique_in_next_validator_set(
+            account_addr, &consensus_pubkey
+        );
+        assert_network_addresses_unique_in_next_validator_set(
+            account_addr, &network_addresses
+        );
         initialize_owner(account);
         move_to(
             account,
@@ -742,6 +753,79 @@ module supra_framework::stake {
         };
     }
 
+    /// Aborts if any validator other than `self_addr` in the next validator set
+    /// (the union of `active_validators` and `pending_active`) already uses
+    /// `consensus_pubkey` as its latest on-chain consensus key.
+    fun assert_consensus_pubkey_unique_in_next_validator_set(
+        self_addr: address,
+        consensus_pubkey: &vector
+    ) acquires ValidatorSet, ValidatorConfig {
+        let validator_set = borrow_global(@supra_framework);
+        assert_consensus_pubkey_unique_in_validator_list(
+            self_addr, consensus_pubkey, &validator_set.active_validators
+        );
+        assert_consensus_pubkey_unique_in_validator_list(
+            self_addr, consensus_pubkey, &validator_set.pending_active
+        );
+    }
+
+    fun assert_consensus_pubkey_unique_in_validator_list(
+        self_addr: address,
+        consensus_pubkey: &vector,
+        validators: &vector
+    ) acquires ValidatorConfig {
+        let len = vector::length(validators);
+        let i = 0;
+        while (i < len) {
+            let other = vector::borrow(validators, i);
+            if (other.addr != self_addr && exists(other.addr)) {
+                let other_config = borrow_global(other.addr);
+                assert!(
+                    other_config.consensus_pubkey != *consensus_pubkey,
+                    error::invalid_argument(EDUPLICATE_CONSENSUS_PUBKEY)
+                );
+            };
+            i = i + 1;
+        };
+    }
+
+    /// Aborts if any validator other than `self_addr` in the next validator set
+    /// already uses `network_addresses`. Empty `network_addresses` is treated
+    /// as "unset" and skips the check.
+    fun assert_network_addresses_unique_in_next_validator_set(
+        self_addr: address,
+        network_addresses: &vector
+    ) acquires ValidatorSet, ValidatorConfig {
+        if (vector::is_empty(network_addresses)) { return };
+        let validator_set = borrow_global(@supra_framework);
+        assert_network_addresses_unique_in_validator_list(
+            self_addr, network_addresses, &validator_set.active_validators
+        );
+        assert_network_addresses_unique_in_validator_list(
+            self_addr, network_addresses, &validator_set.pending_active
+        );
+    }
+
+    fun assert_network_addresses_unique_in_validator_list(
+        self_addr: address,
+        network_addresses: &vector,
+        validators: &vector
+    ) acquires ValidatorConfig {
+        let len = vector::length(validators);
+        let i = 0;
+        while (i < len) {
+            let other = vector::borrow(validators, i);
+            if (other.addr != self_addr && exists(other.addr)) {
+                let other_config = borrow_global(other.addr);
+                assert!(
+                    other_config.network_addresses != *network_addresses,
+                    error::invalid_argument(EDUPLICATE_NETWORK_ADDRESSES)
+                );
+            };
+            i = i + 1;
+        };
+    }
+
     fun initialize_owner(owner: &signer) acquires AllowedValidators {
         let owner_address = signer::address_of(owner);
         assert!(is_allowed(owner_address), error::not_found(EINELIGIBLE_VALIDATOR));
@@ -968,7 +1052,7 @@ module supra_framework::stake {
         pool_address: address,
         new_consensus_pubkey: vector,
         genesis: bool
-    ) acquires StakePool, ValidatorConfig {
+    ) acquires StakePool, ValidatorConfig, ValidatorSet {
         assert_reconfig_not_in_progress();
         assert_stake_pool_exists(pool_address);
 
@@ -982,10 +1066,12 @@ module supra_framework::stake {
             exists(pool_address),
             error::not_found(EVALIDATOR_CONFIG)
         );
+        validate_consensus_public_key(new_consensus_pubkey);
+        assert_consensus_pubkey_unique_in_next_validator_set(
+            pool_address, &new_consensus_pubkey
+        );
         let validator_info = borrow_global_mut(pool_address);
         let old_consensus_pubkey = validator_info.consensus_pubkey;
-
-        validate_consensus_public_key(new_consensus_pubkey);
         validator_info.consensus_pubkey = new_consensus_pubkey;
 
         if (std::features::module_event_migration_enabled()) {
@@ -1104,7 +1190,7 @@ module supra_framework::stake {
     /// only for genesis
     public(friend) fun rotate_consensus_key_genesis(
         operator: &signer, pool_address: address, new_consensus_pubkey: vector
-    ) acquires StakePool, ValidatorConfig {
+    ) acquires StakePool, ValidatorConfig, ValidatorSet {
         rotate_consensus_key_internal(
             operator,
             pool_address,
@@ -1116,7 +1202,7 @@ module supra_framework::stake {
     /// Rotate the consensus key of the validator, it'll take effect in next epoch.
     public entry fun rotate_consensus_key(
         operator: &signer, pool_address: address, new_consensus_pubkey: vector
-    ) acquires StakePool, ValidatorConfig {
+    ) acquires StakePool, ValidatorConfig, ValidatorSet {
         rotate_consensus_key_internal(
             operator,
             pool_address,
@@ -1131,7 +1217,7 @@ module supra_framework::stake {
         pool_address: address,
         new_network_addresses: vector,
         new_fullnode_addresses: vector
-    ) acquires StakePool, ValidatorConfig {
+    ) acquires StakePool, ValidatorConfig, ValidatorSet {
         assert_reconfig_not_in_progress();
         assert_stake_pool_exists(pool_address);
         let stake_pool = borrow_global_mut(pool_address);
@@ -1143,6 +1229,9 @@ module supra_framework::stake {
             exists(pool_address),
             error::not_found(EVALIDATOR_CONFIG)
         );
+        assert_network_addresses_unique_in_next_validator_set(
+            pool_address, &new_network_addresses
+        );
         let validator_info = borrow_global_mut(pool_address);
         let old_network_addresses = validator_info.network_addresses;
         validator_info.network_addresses = new_network_addresses;
@@ -2431,6 +2520,195 @@ module supra_framework::stake {
         validator_public_keys::generate_keys()
     }
 
+    /// Returns the serialized bytes of a freshly generated, unique consensus public key.
+    /// Useful for test helpers that previously hardcoded a shared key but now must
+    /// satisfy the on-chain uniqueness requirement enforced by `rotate_consensus_key`.
+    #[test_only]
+    public fun generate_unique_consensus_pubkey_bytes(): vector {
+        let (_sk, pk) = generate_identity();
+        validator_public_keys::public_key_to_bytes(pk)
+    }
+
+    #[test_only]
+    fun register_test_validator_with_addresses(
+        public_key: &validator_public_keys::ValidatorPublicKeys,
+        validator: &signer,
+        network_addresses: vector,
+        fullnode_addresses: vector
+    ) acquires AllowedValidators, ValidatorConfig, ValidatorSet {
+        let validator_address = signer::address_of(validator);
+        if (!account::exists_at(validator_address)) {
+            account::create_account_for_test(validator_address);
+        };
+        let pk_bytes = validator_public_keys::public_key_to_bytes(*public_key);
+        initialize_validator(validator, pk_bytes, network_addresses, fullnode_addresses);
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    #[expected_failure(abort_code = 0x10016, location = Self)]
+    public entry fun test_initialize_validator_rejects_duplicate_consensus_pubkey_active(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        // validator_1 joins and becomes active in the next epoch.
+        initialize_test_validator(&pk, validator_1, 100, true, true);
+        // validator_2 tries to register with the same consensus key - should abort.
+        initialize_test_validator(&pk, validator_2, 100, false, false);
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    #[expected_failure(abort_code = 0x10016, location = Self)]
+    public entry fun test_initialize_validator_rejects_duplicate_consensus_pubkey_pending_active(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        // validator_1 joins pending_active but no epoch transition.
+        initialize_test_validator(&pk, validator_1, 100, true, false);
+        // validator_2 tries to register with the same key against pending_active - should abort.
+        initialize_test_validator(&pk, validator_2, 100, false, false);
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    #[expected_failure(abort_code = 0x10017, location = Self)]
+    public entry fun test_initialize_validator_rejects_duplicate_network_addresses(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet {
+        initialize_for_test(supra_framework);
+        let (_sk_1, pk_1) = generate_identity();
+        let (_sk_2, pk_2) = generate_identity();
+        let validator_1_address = signer::address_of(validator_1);
+        register_test_validator_with_addresses(&pk_1, validator_1, b"net-1", b"fn-1");
+        mint_and_add_stake(validator_1, 100);
+        join_validator_set(validator_1, validator_1_address);
+        // validator_2 tries to reuse the same network address - should abort.
+        register_test_validator_with_addresses(&pk_2, validator_2, b"net-1", b"fn-2");
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    public entry fun test_initialize_validator_allows_unique_credentials(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet {
+        initialize_for_test(supra_framework);
+        let (_sk_1, pk_1) = generate_identity();
+        let (_sk_2, pk_2) = generate_identity();
+        let validator_1_address = signer::address_of(validator_1);
+        register_test_validator_with_addresses(&pk_1, validator_1, b"net-1", b"fn-1");
+        mint_and_add_stake(validator_1, 100);
+        join_validator_set(validator_1, validator_1_address);
+        // Distinct key and address - should succeed.
+        register_test_validator_with_addresses(&pk_2, validator_2, b"net-2", b"fn-2");
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    public entry fun test_initialize_validator_allows_two_empty_network_addresses(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk_1, pk_1) = generate_identity();
+        let (_sk_2, pk_2) = generate_identity();
+        // Both validators register with empty network_addresses via initialize_test_validator.
+        // The empty-skip rule lets this succeed; existing test helpers must keep working.
+        initialize_test_validator(&pk_1, validator_1, 100, true, false);
+        initialize_test_validator(&pk_2, validator_2, 100, false, false);
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    #[expected_failure(abort_code = 0x10016, location = Self)]
+    public entry fun test_rotate_consensus_key_rejects_duplicate(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk_1, pk_1) = generate_identity();
+        let (_sk_2, pk_2) = generate_identity();
+        let pk_1_bytes = validator_public_keys::public_key_to_bytes(pk_1);
+        initialize_test_validator(&pk_1, validator_1, 100, true, true);
+        initialize_test_validator(&pk_2, validator_2, 100, true, true);
+        // validator_2 tries to rotate to validator_1's consensus key - should abort.
+        rotate_consensus_key(validator_2, signer::address_of(validator_2), pk_1_bytes);
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    public entry fun test_rotate_consensus_key_allows_fresh_key(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        initialize_test_validator(&pk, validator, 100, true, true);
+        let (_sk_new, pk_new) = generate_identity();
+        let pk_new_bytes = validator_public_keys::public_key_to_bytes(pk_new);
+        rotate_consensus_key(validator, signer::address_of(validator), pk_new_bytes);
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    public entry fun test_rotate_consensus_key_allows_self_rotation(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        let pk_bytes = validator_public_keys::public_key_to_bytes(pk);
+        initialize_test_validator(&pk, validator, 100, true, true);
+        // Rotating to the same key the validator already holds is a no-op and must not abort.
+        rotate_consensus_key(validator, signer::address_of(validator), pk_bytes);
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    #[expected_failure(abort_code = 0x10017, location = Self)]
+    public entry fun test_update_network_addresses_rejects_duplicate(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk_1, pk_1) = generate_identity();
+        let (_sk_2, pk_2) = generate_identity();
+        let validator_1_address = signer::address_of(validator_1);
+        register_test_validator_with_addresses(&pk_1, validator_1, b"net-1", b"fn-1");
+        mint_and_add_stake(validator_1, 100);
+        join_validator_set(validator_1, validator_1_address);
+        // validator_2 registers with empty addresses then tries to claim validator_1's net address.
+        initialize_test_validator(&pk_2, validator_2, 100, true, true);
+        update_network_and_fullnode_addresses(
+            validator_2, signer::address_of(validator_2), b"net-1", b"fn-2"
+        );
+    }
+
+    #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
+    public entry fun test_update_network_addresses_allows_clear_to_empty(
+        supra_framework: &signer, validator_1: &signer, validator_2: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet {
+        initialize_for_test(supra_framework);
+        let (_sk_1, pk_1) = generate_identity();
+        let (_sk_2, pk_2) = generate_identity();
+        let validator_1_address = signer::address_of(validator_1);
+        let validator_2_address = signer::address_of(validator_2);
+        register_test_validator_with_addresses(&pk_1, validator_1, b"net-1", b"fn-1");
+        mint_and_add_stake(validator_1, 100);
+        join_validator_set(validator_1, validator_1_address);
+        register_test_validator_with_addresses(&pk_2, validator_2, b"net-2", b"fn-2");
+        mint_and_add_stake(validator_2, 100);
+        join_validator_set(validator_2, validator_2_address);
+        // Clearing to empty is always allowed (empty == "unset / non-functional").
+        update_network_and_fullnode_addresses(
+            validator_2, validator_2_address, vector::empty(), vector::empty()
+        );
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    public entry fun test_update_network_addresses_allows_self(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorSet {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        let validator_address = signer::address_of(validator);
+        register_test_validator_with_addresses(&pk, validator, b"net-self", b"fn-self");
+        mint_and_add_stake(validator, 100);
+        join_validator_set(validator, validator_address);
+        // Re-setting the same address on self must be a no-op, not an abort.
+        update_network_and_fullnode_addresses(
+            validator, validator_address, b"net-self", b"fn-self"
+        );
+    }
+
     #[test(supra_framework = @supra_framework, validator = @0x123)]
     #[expected_failure(abort_code = 0x10007, location = Self)]
     public entry fun test_inactive_validator_can_add_stake_if_exceeding_max_allowed(
diff --git a/aptos-move/framework/supra-framework/sources/stake.spec.move b/aptos-move/framework/supra-framework/sources/stake.spec.move
index c619f126fde..c81f102701a 100644
--- a/aptos-move/framework/supra-framework/sources/stake.spec.move
+++ b/aptos-move/framework/supra-framework/sources/stake.spec.move
@@ -131,6 +131,9 @@ spec supra_framework::stake {
         network_addresses: vector,
         fullnode_addresses: vector,
     ){
+        // Partial: the function also aborts when `consensus_pubkey` or `network_addresses`
+        // collide with another validator in the next validator set.
+        pragma aborts_if_is_partial = true;
         //todo: fix this validation
         /*let is_public_key_validated = consensus_key::spec_cg_pk_valid(
             consensus_pubkey,
@@ -357,6 +360,9 @@ spec supra_framework::stake {
         new_network_addresses: vector,
         new_fullnode_addresses: vector,
     ) {
+        // Partial: the function also aborts when `new_network_addresses` collides
+        // with another validator in the next validator set.
+        pragma aborts_if_is_partial = true;
         let pre_stake_pool = global(pool_address);
         let post validator_info = global(pool_address);
         modifies global(pool_address);
@@ -402,6 +408,9 @@ spec supra_framework::stake {
         pool_address: address,
         new_consensus_pubkey: vector,
     ) {
+        // Partial: the function also aborts when `new_consensus_pubkey` collides
+        // with another validator in the next validator set.
+        pragma aborts_if_is_partial = true;
         let pre_stake_pool = global(pool_address);
         let post validator_info = global(pool_address);
         aborts_if reconfiguration_state::spec_is_in_progress();
@@ -973,3 +982,4 @@ spec supra_framework::stake {
         }
     }
 }
+
diff --git a/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move b/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move
index 23f5954a72d..7bc68221d48 100644
--- a/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move
+++ b/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move
@@ -134,7 +134,11 @@ module supra_framework::delegation_pool_integration_tests {
         );
         validator_address = dp::get_owned_pool_address(validator_address);
 
-        stake::rotate_consensus_key(validator, validator_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            validator,
+            validator_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
 
         if (amount > 0) {
             mint_and_add_stake(validator, amount);
@@ -1112,7 +1116,11 @@ module supra_framework::delegation_pool_integration_tests {
 
         // Initialize validator config.
         let (_sk_new, _, _) = generate_identity();
-        stake::rotate_consensus_key(validator, validator_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            validator,
+            validator_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
 
         // Join the validator set with enough stake. This now wouldn't fail since the validator config already exists.
         stake::join_validator_set(validator, validator_address);

From 839bec89e43c3ee9e6919a02fb62d6597899e73f Mon Sep 17 00:00:00 2001
From: Kiran Kumar Roy 
Date: Wed, 10 Jun 2026 13:03:14 +0530
Subject: [PATCH 19/31] clip backtrace dump mentioned in #1171 and make cli
 respect supra-rpc view api (#362)

---
 aptos-move/aptos-vm/src/aptos_vm.rs | 2 +-
 crates/aptos/src/move_tool/mod.rs   | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs
index d09cbdf7c28..d1c72a06fe1 100644
--- a/aptos-move/aptos-vm/src/aptos_vm.rs
+++ b/aptos-move/aptos-vm/src/aptos_vm.rs
@@ -2528,7 +2528,7 @@ impl AptosVM {
                 gas_meter,
                 &mut TraversalContext::new(&storage),
             )
-            .map_err(|err| anyhow!("Failed to execute function: {:?}", err))?
+            .map_err(|err| anyhow!("Failed to execute view function: {}", err))?
             .return_values
             .into_iter()
             .map(|(bytes, _ty)| bytes)
diff --git a/crates/aptos/src/move_tool/mod.rs b/crates/aptos/src/move_tool/mod.rs
index d7527ddddcf..e0b11c8dca2 100644
--- a/crates/aptos/src/move_tool/mod.rs
+++ b/crates/aptos/src/move_tool/mod.rs
@@ -2040,6 +2040,13 @@ impl ArgWithType {
         match self._ty {
             FunctionArgType::Address => self.bcs_value_to_json::(),
             FunctionArgType::Bool => self.bcs_value_to_json::(),
+            // The Supra RPC view endpoint expects a `vector` argument as a hex string, not a JSON array of bytes.
+            FunctionArgType::Hex if self._vector_depth == 0 => {
+                let bytes = bcs::from_bytes::>(&self.arg)
+                    .map_err(|err| CliError::UnexpectedError(err.to_string()))?;
+                serde_json::to_value(HexEncodedBytes(bytes).to_string())
+                    .map_err(|err| CliError::UnexpectedError(err.to_string()))
+            },
             FunctionArgType::Hex => self.bcs_value_to_json::>(),
             FunctionArgType::String => self.bcs_value_to_json::(),
             FunctionArgType::U8 => self.bcs_value_to_json::(),

From 531d2d299ece316bc08fd5c2f88cfff65e75c429 Mon Sep 17 00:00:00 2001
From: Aregnaz Harutyunyan <89187359+aregng@users.noreply.github.com>
Date: Wed, 10 Jun 2026 23:29:16 +0400
Subject: [PATCH 20/31] [EAN-Issue-2530] Added evm-contracts-details move
 module (#342)

* [EAN-Issue-2530] Added emv-contracts-details move module

- The module will hold the evm contract names accosiated with the corresponding addresses
- Supra node runtime will utilize this information to retrieve evm block-metadata and automation-registry contract addresses
- Users can retrieve the 0x1::evm_contracts_details::EvmContractsDetails resource to get info on supra native evm contracts

* Addressed review comments

* Addressed license headers

* Fixed TODO and test failures

* Fixed EvnContractName string values

* Addressed review comments

* add evm_config in Move state (#353)

* add evm_config in Move state

* add config validation for required key and value type match

* add test

* remove double negative assert check

* change to EvmScalarCOnfig with everything u128

* minor

* add evm config to encode testnet

* Fixed test

* Fixed build error

* Enabled serde for OnChainEvmConfig required by to be able to cache on-chain-config

* remove nested if

* validate gas used ratio, add other evm parameters

---------

Co-authored-by: Saurabh Joshi 
Co-authored-by: Aregnaz Harutyunyan <>

* [Issue-2530] Extended GenesisEvmContract to support function calls as well (#354)

Co-authored-by: Aregnaz Harutyunyan <>

* Fixed evm config initializtion function name

* Fixed the evm-address length value in evm_config.move

* ensure nextest is installed (#358)

Co-authored-by: Saurabh Joshi 

* Delete aptos-move/framework/supra-framework/doc/evm_contracts_details.md

* allow smart contract to register automation task (#356)

* allow smart contract to register automation task

* add invalidation method

* tests and invalid task cancellation from runtime

* Report discart output for automated transactions failing validation before execution

- INVALID_AUTOMATION_INNER_PAYLOAD error will be reported in case if entry function validation fails

* Removed redundant function from aptos-vm-viewer

* Addressed review comments

- If automated transasction pre-execution phase fails and SUPRA_AUTOMATION_V2_1 is not enabled, error is reported with kept status
- Generated unit test to cover new flow of automated transaction execution
- Enabled SUPRA_AUTOMATION_V2_1 by default at genesis

* Cosmetic changes

* Addressed review comments

* Added means to register system task from smart contract context

---------

Co-authored-by: Saurabh Joshi 
Co-authored-by: Aregnaz Harutyunyan <>

---------

Co-authored-by: Aregnaz Harutyunyan <>
Co-authored-by: Saurabh Joshi <106232965+sjoshisupra@users.noreply.github.com>
Co-authored-by: Saurabh Joshi 
---
 .github/workflows/aptos-framework-test.yaml   |   7 +-
 .../src/gas_schedule/aptos_framework.rs       |   3 +
 aptos-move/aptos-gas-schedule/src/ver.rs      |   3 +-
 aptos-move/aptos-vm/src/aptos_vm.rs           |  40 +-
 aptos-move/aptos-vm/src/aptos_vm_viewer.rs    |   6 +-
 .../src/automated_transaction_processor.rs    |  58 +-
 ...tomation_registry_transaction_processor.rs |  30 +-
 .../aptos-vm/src/transaction_metadata.rs      |  11 +-
 .../automation_registry.data/pack/Move.toml   |  11 +
 .../sources/automation_contract_test.move     |  32 +
 .../src/tests/automation_registry.rs          | 284 +++++++
 aptos-move/e2e-move-tests/src/tests/mod.rs    |   1 +
 aptos-move/e2e-tests/src/executor.rs          |   7 +-
 .../src/tests/automated_transactions.rs       | 713 +++++++++++++++++-
 .../src/tests/automation_registration.rs      |  91 ++-
 .../e2e-testsuite/src/tests/vm_viewer.rs      |   3 -
 aptos-move/framework/aptos-stdlib/doc/any.md  |  29 +
 .../aptos-stdlib/doc/copyable_any.md          |  63 ++
 .../framework/aptos-stdlib/sources/any.move   |   7 +
 .../aptos-stdlib/sources/copyable_any.move    |  20 +
 .../framework/move-stdlib/doc/features.md     |  65 ++
 .../move-stdlib/sources/configs/features.move |  16 +
 .../natives/automation_registry_callbacks.rs  |   3 -
 .../cryptography/bls12381_bulletproofs.rs     |   3 -
 .../natives/cryptography/bls12381_scalar.rs   |   3 -
 .../src/natives/cryptography/eth_trie.rs      |   3 -
 aptos-move/framework/src/natives/rlp.rs       |   3 -
 .../src/natives/transaction_context.rs        |  33 +
 .../doc/automation_registry.md                | 302 +++++++-
 .../supra-framework/doc/evm_config.md         | 508 +++++++++++--
 .../framework/supra-framework/doc/genesis.md  |  33 +
 .../framework/supra-framework/doc/overview.md |   1 +
 .../doc/reconfiguration_with_dkg.md           |   2 +
 .../doc/transaction_context.md                |  52 ++
 .../sources/automation_registry.move          | 164 +++-
 .../sources/configs/config_buffer.move        |   1 +
 .../sources/configs/evm_config.move           | 484 ++++++++++++
 .../supra-framework/sources/genesis.move      |  12 +
 .../sources/reconfiguration_with_dkg.move     |   2 +
 .../sources/transaction_context.move          |  19 +
 .../tests/automation_registry_tests.move      | 116 +++
 aptos-move/vm-genesis/src/lib.rs              |  40 +
 crates/aptos-genesis/src/lib.rs               |   2 +
 devtools/assets/license_header.txt            |   2 +-
 devtools/assets/license_header_utf8.txt       |   2 +-
 devtools/assets/shared_license_header.txt     |   1 +
 .../assets/shared_license_header_utf8.txt     |   1 +
 types/src/on_chain_config/aptos_features.rs   |   7 +
 .../on_chain_config/automation_registry.rs    |   3 -
 types/src/on_chain_config/evm_config.rs       | 553 ++++++++++++++
 .../src/on_chain_config/evm_genesis_config.rs |  16 +-
 types/src/on_chain_config/mod.rs              |   8 +-
 .../src/transaction/automated_transaction.rs  |   3 -
 types/src/transaction/automation.rs           | 158 +++-
 .../transaction/user_transaction_context.rs   |  10 +
 types/src/unit_tests/automation.rs            |   3 -
 56 files changed, 3834 insertions(+), 219 deletions(-)
 create mode 100644 aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/Move.toml
 create mode 100644 aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/sources/automation_contract_test.move
 create mode 100644 aptos-move/e2e-move-tests/src/tests/automation_registry.rs
 create mode 100644 aptos-move/framework/supra-framework/sources/configs/evm_config.move
 create mode 100644 types/src/on_chain_config/evm_config.rs

diff --git a/.github/workflows/aptos-framework-test.yaml b/.github/workflows/aptos-framework-test.yaml
index d3eba885a1a..aa5881e89a2 100644
--- a/.github/workflows/aptos-framework-test.yaml
+++ b/.github/workflows/aptos-framework-test.yaml
@@ -30,6 +30,9 @@ jobs:
       - name: Setup Rust
         uses: dtolnay/rust-toolchain@stable
 
+      - name: Install cargo-nextest
+        uses: taiki-e/install-action@nextest
+
       - name: Setup SSH access
         run: |
           mkdir -p ~/.ssh
@@ -53,7 +56,7 @@ jobs:
         run: cargo test --release -p aptos-framework -- --skip prover
 
       - name: Run language e2e tests
-        run: RUST_MIN_STACK=104857600 cargo test run -p language-e2e-testsuite --no-fail-fast
+        run: RUST_MIN_STACK=104857600 cargo nextest run -p language-e2e-testsuite --no-fail-fast
 
       - name: Run move e2e tests
-        run: RUST_MIN_STACK=104857600 cargo test run -p e2e-move-tests --no-fail-fast
+        run: RUST_MIN_STACK=104857600 cargo nextest run -p e2e-move-tests --no-fail-fast
diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
index 80de653e89d..e94840d420f 100644
--- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
+++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
@@ -9,6 +9,7 @@ use crate::{
     gas_schedule::NativeGasParameters,
     ver::gas_feature_versions::{
         RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_16_SUPRA_V1_6_0, RELEASE_V1_16_SUPRA_V1_7_14,
+        RELEASE_V1_16_SUPRA_V1_9_0,
     },
 };
 use aptos_gas_algebra::{
@@ -294,6 +295,8 @@ crate::gas_schedule::macros::define_gas_parameters!(
         [transaction_context_entry_function_payload_per_byte_in_str: InternalGasPerByte, {RELEASE_V1_12.. => "transaction_context.entry_function_payload.per_abstract_memory_unit"}, 18],
         [transaction_context_multisig_payload_base: InternalGas, {RELEASE_V1_12.. => "transaction_context.multisig_payload.base"}, 735],
         [transaction_context_multisig_payload_per_byte_in_str: InternalGasPerByte, {RELEASE_V1_12.. => "transaction_context.multisig_payload.per_abstract_memory_unit"}, 18],
+        // Cost matches other fixed-size hash-return natives (get_txn_hash, sender, fee_payer, etc.)
+        [transaction_context_get_txn_consensus_hash_base: InternalGas, {RELEASE_V1_16_SUPRA_V1_9_0 .. => "transaction_context.get_transaction_consensus_hash.base"}, 735],
 
         [code_request_publish_base: InternalGas, "code.request_publish.base", 1838],
         [code_request_publish_per_byte: InternalGasPerByte, "code.request_publish.per_byte", 7],
diff --git a/aptos-move/aptos-gas-schedule/src/ver.rs b/aptos-move/aptos-gas-schedule/src/ver.rs
index 0aad7bc6e02..7d69af865b4 100644
--- a/aptos-move/aptos-gas-schedule/src/ver.rs
+++ b/aptos-move/aptos-gas-schedule/src/ver.rs
@@ -73,7 +73,7 @@
 ///       global operations.
 /// - V1
 ///   - TBA
-pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_16_SUPRA_V1_8_0;
+pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_16_SUPRA_V1_9_0;
 
 pub mod gas_feature_versions {
     pub const RELEASE_V1_8: u64 = 11;
@@ -90,4 +90,5 @@ pub mod gas_feature_versions {
     pub const RELEASE_V1_16_SUPRA_V1_6_0: u64 = 23;
     pub const RELEASE_V1_16_SUPRA_V1_7_14: u64 = 24;
     pub const RELEASE_V1_16_SUPRA_V1_8_0: u64 = 25;
+    pub const RELEASE_V1_16_SUPRA_V1_9_0: u64 = 26;
 }
diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs
index d1c72a06fe1..ef381d28ee5 100644
--- a/aptos-move/aptos-vm/src/aptos_vm.rs
+++ b/aptos-move/aptos-vm/src/aptos_vm.rs
@@ -108,6 +108,7 @@ use move_core_types::{
 use move_vm_runtime::{
     logging::expect_no_verification_errors,
     module_traversal::{TraversalContext, TraversalStorage},
+    LoadedFunction,
 };
 use move_vm_types::gas::{GasMeter, UnmeteredGasMeter};
 use num_cpus;
@@ -784,7 +785,12 @@ impl AptosVM {
         Ok(())
     }
 
-    pub(crate) fn validate_and_execute_entry_function(
+    // Loads the entry function from the module store and validates its arguments,
+    // returning the resolved function handle and the serialized validated args.
+    // Separated from execution so callers can apply different error handling to
+    // pre-execution failures (e.g. the automation path tags them distinctly from
+    // transient execution failures).
+    pub(crate) fn load_and_validate_entry_function(
         &self,
         resolver: &impl AptosMoveResolver,
         session: &mut SessionExt,
@@ -793,7 +799,7 @@ impl AptosVM {
         senders: Vec,
         entry_fn: &EntryFunction,
         _txn_data: &TransactionMetadata,
-    ) -> Result<(), VMStatus> {
+    ) -> Result<(LoadedFunction, Vec>), VMStatus> {
         // Note: Feature gating is needed here because the traversal of the dependencies could
         //       result in shallow-loading of the modules and therefore subtle changes in
         //       the error semantics.
@@ -831,6 +837,29 @@ impl AptosVM {
             &function,
             struct_constructors_enabled,
         )?;
+
+        Ok((function, args))
+    }
+
+    pub(crate) fn validate_and_execute_entry_function(
+        &self,
+        resolver: &impl AptosMoveResolver,
+        session: &mut SessionExt,
+        gas_meter: &mut impl AptosGasMeter,
+        traversal_context: &mut TraversalContext,
+        senders: Vec,
+        entry_fn: &EntryFunction,
+        txn_data: &TransactionMetadata,
+    ) -> Result<(), VMStatus> {
+        let (function, args) = self.load_and_validate_entry_function(
+            resolver,
+            session,
+            gas_meter,
+            traversal_context,
+            senders,
+            entry_fn,
+            txn_data,
+        )?;
         session.execute_entry_function(function, args, gas_meter, traversal_context)?;
         Ok(())
     }
@@ -1034,7 +1063,7 @@ impl AptosVM {
         }
         let args = registration_params.serialized_args_with_sender_and_parent_hash(
             sender,
-            txn_metadata.txn_app_hash.clone(),
+            txn_metadata.txn_consensus_hash.clone(),
             self.features(),
         );
 
@@ -1050,7 +1079,10 @@ impl AptosVM {
     }
 
     /// Checks inner payload/entry function of automation registration transaction to be valid.
-    fn validate_automated_function(
+    ///
+    /// Exposed as `pub(crate)` so that `AptosVMViewer` can call it for pre-flight validation of
+    /// automation tasks that were registered without type-checking (e.g. `register_without_validation`).
+    pub(crate) fn validate_automated_function(
         &self,
         session: &mut SessionExt,
         gas_meter: &mut impl AptosGasMeter,
diff --git a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs
index a5ce78285ef..be2c96ea29b 100644
--- a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs
+++ b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs
@@ -1,6 +1,3 @@
-// Copyright (c) Aptos Foundation
-// SPDX-License-Identifier: Apache-2.0
-
 // Copyright (c) 2024 Supra.
 // SPDX-License-Identifier: Apache-2.0
 
@@ -12,8 +9,9 @@ use crate::{
 };
 use aptos_types::{
     state_store::StateView,
-    transaction::{ViewFunction, ViewFunctionOutput},
+    transaction::{EntryFunction, ViewFunction, ViewFunctionOutput},
 };
+use move_core_types::account_address::AccountAddress;
 use aptos_vm_logging::log_schema::AdapterLogSchema;
 
 /// Move VM with only view function API.
diff --git a/aptos-move/aptos-vm/src/automated_transaction_processor.rs b/aptos-move/aptos-vm/src/automated_transaction_processor.rs
index 84d3eb76430..121307f8a6e 100644
--- a/aptos-move/aptos-vm/src/automated_transaction_processor.rs
+++ b/aptos-move/aptos-vm/src/automated_transaction_processor.rs
@@ -1,6 +1,3 @@
-// Copyright (c) Aptos Foundation
-// SPDX-License-Identifier: Apache-2.0
-
 // Copyright (c) 2024 Supra.
 // SPDX-License-Identifier: Apache-2.0
 
@@ -38,7 +35,10 @@ use aptos_vm_types::{
 use fail::fail_point;
 use move_binary_format::errors::Location;
 use move_core_types::vm_status::{StatusCode, VMStatus};
-use move_vm_runtime::module_traversal::{TraversalContext, TraversalStorage};
+use move_vm_runtime::{
+    module_traversal::{TraversalContext, TraversalStorage},
+    LoadedFunction,
+};
 use std::ops::Deref;
 
 pub struct AutomatedTransactionProcessor<'m> {
@@ -178,8 +178,15 @@ impl<'m> AutomatedTransactionProcessor<'m> {
         );
 
         gas_meter.charge_intrinsic_gas_for_transaction(txn_data.transaction_size())?;
-        session.execute(|session| {
-            self.validate_and_execute_entry_function(
+
+        // Phase 1: load the function and validate arguments.
+        // Failures here mean the registered payload became permanently invalid after
+        // registration (e.g., module removed, function renamed, or signature changed
+        // by an upgrade). Tagged as INVALID_AUTOMATION_INNER_PAYLOAD so that
+        // execute_transaction_impl can distinguish pre-execution failures from transient
+        // execution failures and discard without charging any gas.
+        let (function, args) = session.execute(|session| {
+            self.load_and_validate_entry_function(
                 resolver,
                 session,
                 gas_meter,
@@ -188,6 +195,24 @@ impl<'m> AutomatedTransactionProcessor<'m> {
                 entry_function,
                 txn_data,
             )
+            .map_err(|e| {
+                VMStatus::error(
+                    StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD,
+                    Some(format!(
+                        "Automated task inner payload became invalid at execution time: {e:?}"
+                    )),
+                )
+            })
+        })?;
+
+        // Phase 2: execute the entry function body.
+        // Failures here (ABORTED, OUT_OF_GAS, etc.) are transient execution errors
+        // and flow through the normal failure-epilogue path with gas charged.
+        session.execute(|session| {
+            session
+                .execute_entry_function(function, args, gas_meter, traversal_context)
+                .map(|_| ())
+                .map_err(|e| e.into_vm_status())
         })?;
 
         session.execute(|session| {
@@ -321,6 +346,27 @@ impl<'m> AutomatedTransactionProcessor<'m> {
         TXN_GAS_USAGE.observe(u64::from(gas_usage) as f64);
 
         result.unwrap_or_else(|err| {
+            // True only [FeatureFlag::SUPRA_AUTOMATION_V2_1] is enabled: which enables task registration without validation
+            // Pre-execution failure: the task's registered payload is permanently invalid
+            // (function signature is invalid, function is missing or arguments do not match expected ones).
+            // The entry function body never ran so no execution gas was consumed. Skip the failure epilogue
+            // entirely — discarded_output produces FeeStatement::zero() and an empty
+            // change set so no fees are charged and no state is committed.
+            //
+            // Note: Before [FeatureFlag::SUPRA_AUTOMATION_V2_1] during task registration inner payload is always verified
+            // and in case of failure task will never be actually registered.
+            // So potentially this error should never be registered for a task which is registered with validation flow.
+            // And if for some reason it is registered, then user will be charged with whatever gas was used so far.
+            if err.status_code() == StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD
+                && self
+                    .features()
+                    .is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2_1)
+            {
+                return (
+                    err,
+                    discarded_output(StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD),
+                );
+            }
             self.on_transaction_execution_failure(
                 prologue_change_set,
                 err,
diff --git a/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs b/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs
index 71125163f6d..d6ab20f151b 100644
--- a/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs
+++ b/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs
@@ -1,6 +1,3 @@
-// Copyright (c) Aptos Foundation
-// SPDX-License-Identifier: Apache-2.0
-
 // Copyright (c) 2025 Supra.
 // SPDX-License-Identifier: Apache-2.0
 
@@ -16,7 +13,11 @@ use aptos_types::{
     account_config,
     fee_statement::FeeStatement,
     on_chain_config::FeatureFlag,
-    transaction::{automation::AutomationRegistryRecord, ExecutionStatus, TransactionStatus},
+    transaction::{
+        automation::{AutomationRegistryAction, AutomationRegistryRecord},
+        ExecutionStatus,
+        TransactionStatus,
+    },
 };
 use aptos_vm_logging::log_schema::AdapterLogSchema;
 use aptos_vm_types::{output::VMOutput, storage::change_set_configs::ChangeSetConfigs};
@@ -62,6 +63,27 @@ impl<'m> AutomationRegistryTransactionProcessor<'m> {
                 discarded_output(StatusCode::FEATURE_UNDER_GATING),
             ));
         }
+        // CancelInvalidTask is part of SUPRA_AUTOMATION_V2_1: ensure the feature is live
+        // before executing cancellations generated by the consensus layer.
+        if matches!(
+            action_record.action(),
+            AutomationRegistryAction::CancelInvalidTask { .. }
+        ) && !self
+            .features()
+            .is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2_1)
+        {
+            return Ok((
+                VMStatus::Error {
+                    status_code: StatusCode::FEATURE_UNDER_GATING,
+                    sub_status: None,
+                    message: Some(
+                        "SUPRA_AUTOMATION_V2_1 is not enabled; CancelInvalidTask is unavailable."
+                            .to_string(),
+                    ),
+                },
+                discarded_output(StatusCode::FEATURE_UNDER_GATING),
+            ));
+        }
         let gas_params = get_or_vm_startup_failure(&self.gas_params_internal(), log_context)?
             .vm
             .clone();
diff --git a/aptos-move/aptos-vm/src/transaction_metadata.rs b/aptos-move/aptos-vm/src/transaction_metadata.rs
index 5c5575aff26..9412af58a2c 100644
--- a/aptos-move/aptos-vm/src/transaction_metadata.rs
+++ b/aptos-move/aptos-vm/src/transaction_metadata.rs
@@ -35,7 +35,7 @@ pub struct TransactionMetadata {
     pub script_size: NumBytes,
     pub is_keyless: bool,
     pub payload_type_reference: PayloadTypeReferenceMeta,
-    pub txn_app_hash: Vec,
+    pub txn_consensus_hash: Vec,
 }
 
 impl TransactionMetadata {
@@ -91,7 +91,7 @@ impl TransactionMetadata {
                 .map(|res| !res.is_empty())
                 .unwrap_or(false),
             payload_type_reference,
-            txn_app_hash: HashValue::keccak_256_of(
+            txn_consensus_hash: HashValue::keccak_256_of(
                 &bcs::to_bytes(&txn).expect("Unable to serialize SignedTransaction"),
             )
             .to_vec(),
@@ -177,6 +177,10 @@ impl TransactionMetadata {
                 PayloadTypeReferenceContext::AutomationRegistration
             },
         };
+        // Safe: txn_consensus_hash is always populated from HashValue::keccak_256_of or txn.hash(),
+        // both of which produce exactly 32 bytes.
+        let txn_consensus_hash: [u8; 32] = self.txn_consensus_hash.as_slice().try_into()
+            .expect("txn_consensus_hash is always a 32-byte Keccak-256 hash");
         UserTransactionContext::new(
             self.sender,
             self.secondary_signers.clone(),
@@ -185,6 +189,7 @@ impl TransactionMetadata {
             self.gas_unit_price.into(),
             self.chain_id.id(),
             payload_type_reference,
+            txn_consensus_hash,
         )
     }
 }
@@ -210,7 +215,7 @@ impl From<&AutomatedTransaction> for TransactionMetadata {
             payload_type_reference: PayloadTypeReferenceMeta::UserEntryFunction(
                 txn.payload().clone().into_entry_function(),
             ),
-            txn_app_hash: txn.hash().to_vec(),
+            txn_consensus_hash: txn.hash().to_vec(),
         }
     }
 }
diff --git a/aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/Move.toml b/aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/Move.toml
new file mode 100644
index 00000000000..91967340636
--- /dev/null
+++ b/aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/Move.toml
@@ -0,0 +1,11 @@
+[package]
+name = "automation_registry_test"
+version = "0.0.0"
+
+[addresses]
+# A fixed address for the test contract simulating a third-party DeFi protocol.
+automation_test = "0xDEADBEEF"
+
+[dependencies]
+SupraFramework = { local = "../../../../../framework/supra-framework" }
+AptosStdlib = { local = "../../../../../framework/aptos-stdlib" }
diff --git a/aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/sources/automation_contract_test.move b/aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/sources/automation_contract_test.move
new file mode 100644
index 00000000000..2e4427d4f76
--- /dev/null
+++ b/aptos-move/e2e-move-tests/src/tests/automation_registry.data/pack/sources/automation_contract_test.move
@@ -0,0 +1,32 @@
+/// Simulates a third-party smart contract (e.g. a DeFi protocol) that registers
+/// automation tasks by calling the public `register_without_validation` API.
+///
+/// In production a DeFi contract would call `automation_registry::register_without_validation`
+/// from inside its own module logic.  This module exposes a thin entry-function wrapper so
+/// that the Rust e2e test harness can invoke it as a regular signed transaction.
+module automation_test::automation_contract_test {
+    use supra_framework::automation_registry;
+
+    /// Entry-function wrapper that delegates to `register_without_validation`.
+    /// All arguments are forwarded verbatim; the tx_hash is captured automatically
+    /// from the native transaction context inside the callee.
+    public entry fun register_via_contract(
+        owner: &signer,
+        payload_tx: vector,
+        expiry_time: u64,
+        max_gas_amount: u64,
+        gas_price_cap: u64,
+        automation_fee_cap_for_epoch: u64,
+        aux_data: vector>,
+    ) {
+        automation_registry::register_without_validation(
+            owner,
+            payload_tx,
+            expiry_time,
+            max_gas_amount,
+            gas_price_cap,
+            automation_fee_cap_for_epoch,
+            aux_data,
+        )
+    }
+}
diff --git a/aptos-move/e2e-move-tests/src/tests/automation_registry.rs b/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
new file mode 100644
index 00000000000..d04ba33c242
--- /dev/null
+++ b/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
@@ -0,0 +1,284 @@
+// Copyright (c) Supra.
+// SPDX-License-Identifier: Apache-2.0
+
+//! E2E tests for the `register_without_validation` / `get_transaction_consensus_hash` feature
+//! (SUPRA_AUTOMATION_V2_1).
+//!
+//! These tests exercise the full call chain:
+//!   signed transaction → VM → native `get_transaction_consensus_hash_internal` → Move registry storage
+//!
+//! and verify that the hash stored in the registry is the Keccak-256 of the BCS-serialised
+//! `SignedTransaction` that triggered the registration.
+
+use crate::{assert_abort, assert_success, tests::common, MoveHarness};
+use aptos_crypto::HashValue;
+use aptos_language_e2e_tests::account::Account;
+use aptos_types::{
+    move_utils::MemberId,
+    on_chain_config::FeatureFlag,
+    transaction::{automation::AutomationTaskMetaData, SignedTransaction},
+};
+use move_core_types::account_address::AccountAddress;
+
+// -----------------------------------------------------------------------
+// Stack-size helper
+// -----------------------------------------------------------------------
+
+/// Runs `f` on a thread with a 64 MB stack.
+///
+/// Publishing the supra-framework package triggers deep recursive Move type-checking that
+/// overflows the OS default stack (~8 MB).  This wrapper ensures the compilation succeeds
+/// regardless of the default stack size configured by the test runner.
+fn run_on_large_stack(f: F) {
+    std::thread::Builder::new()
+        .stack_size(64 * 1024 * 1024)
+        .spawn(f)
+        .expect("spawning large-stack thread must not fail")
+        .join()
+        .expect("large-stack thread must not panic");
+}
+
+// -----------------------------------------------------------------------
+// Module-level abort code constant (mirrors Move's EDISABLED_AUTOMATION_FEATURE = 15)
+// -----------------------------------------------------------------------
+
+/// Raw abort code emitted by `automation_registry` when a required feature is disabled.
+/// This is NOT wrapped with error::invalid_state — it is the plain u64 constant 15.
+const EDISABLED_AUTOMATION_FEATURE: u64 = 15;
+
+// -----------------------------------------------------------------------
+// Helpers
+// -----------------------------------------------------------------------
+
+/// Builds a harness with SUPRA_NATIVE_AUTOMATION and SUPRA_AUTOMATION_V2_1 enabled,
+/// then transitions the automation cycle from CYCLE_READY to CYCLE_STARTED.
+///
+/// At head-genesis SUPRA_NATIVE_AUTOMATION is absent from the default feature set, so the
+/// registry is initialised in CYCLE_READY state.  Calling `on_new_epoch` after enabling the
+/// flag transitions the cycle to CYCLE_STARTED, which is required for registration to succeed.
+fn setup_harness_with_v2_1() -> MoveHarness {
+    let mut h = MoveHarness::new_with_features(
+        vec![
+            FeatureFlag::SUPRA_NATIVE_AUTOMATION,
+            FeatureFlag::SUPRA_AUTOMATION_V2_1,
+        ],
+        vec![],
+    );
+    // Transition CYCLE_READY -> CYCLE_STARTED now that SUPRA_NATIVE_AUTOMATION is enabled.
+    h.executor
+        .exec("automation_registry", "on_new_epoch", vec![], vec![]);
+    h
+}
+
+/// Same setup but deliberately *without* SUPRA_AUTOMATION_V2_1, to test the disabled path.
+fn setup_harness_without_v2_1() -> MoveHarness {
+    let mut h = MoveHarness::new_with_features(
+        vec![FeatureFlag::SUPRA_NATIVE_AUTOMATION],
+        vec![FeatureFlag::SUPRA_AUTOMATION_V2_1],
+    );
+    h.executor
+        .exec("automation_registry", "on_new_epoch", vec![], vec![]);
+    h
+}
+
+/// Deploys the third-party wrapper contract and returns the deployer account.
+///
+/// The contract lives at `0xDEADBEEF` and exposes a `public entry fun register_via_contract`
+/// that delegates to `automation_registry::register_without_validation`.  This mimics the
+/// real-world scenario where a DeFi protocol registers automation tasks through its own module.
+fn deploy_wrapper(h: &mut MoveHarness) -> Account {
+    let addr = AccountAddress::from_hex_literal("0xDEADBEEF").unwrap();
+    let account = h.new_account_with_balance_at(addr, 1_000_000_000_000_000);
+    assert_success!(h.publish_package_cache_building(
+        &account,
+        &common::test_dir_path("automation_registry.data/pack"),
+    ));
+    account
+}
+
+/// Returns a new user account with enough balance to cover gas and registration/deposit fees.
+fn new_funded_user(h: &mut MoveHarness) -> Account {
+    h.new_account_with_key_pair()
+}
+
+/// A 64-byte dummy payload.  `register_without_validation` does not validate the payload
+/// bytes, so any non-empty vector is valid for unit-test purposes.
+fn dummy_payload_bytes() -> Vec {
+    (0u8..64u8).collect()
+}
+
+/// AUX data required by the registry for a user-submitted task (type byte = 0x01, empty priority).
+fn user_aux_data() -> Vec> {
+    vec![vec![1u8], vec![]]
+}
+
+/// Calls the `get_task_details(task_index)` view function and BCS-decodes the result.
+fn get_task_details(h: &mut MoveHarness, task_index: u64) -> AutomationTaskMetaData {
+    let output = h.execute_view_function(
+        str::parse("0x1::automation_registry::get_task_details").unwrap(),
+        vec![],
+        vec![bcs::to_bytes(&task_index).unwrap()],
+    );
+    let values = output
+        .values
+        .expect("get_task_details view call must succeed");
+    bcs::from_bytes(&values[0]).expect("AutomationTaskMetaData must BCS-decode cleanly")
+}
+
+/// Builds (but does not submit) the `register_via_contract` signed transaction.
+///
+/// Returning the `SignedTransaction` before submission allows the caller to compute its
+/// Keccak-256 hash and then verify that the same bytes end up stored in the registry.
+fn build_register_txn(
+    h: &mut MoveHarness,
+    user: &Account,
+    expiry_time: u64,
+) -> SignedTransaction {
+    h.create_entry_function(
+        user,
+        str::parse("0xDEADBEEF::automation_contract_test::register_via_contract").unwrap(),
+        vec![],
+        vec![
+            bcs::to_bytes(&dummy_payload_bytes()).unwrap(),
+            bcs::to_bytes(&expiry_time).unwrap(),
+            bcs::to_bytes(&10_000u64).unwrap(), // max_gas_amount
+            bcs::to_bytes(&100u64).unwrap(),    // gas_price_cap
+            bcs::to_bytes(&1_000u64).unwrap(),  // automation_fee_cap_for_epoch
+            bcs::to_bytes(&user_aux_data()).unwrap(),
+        ],
+    )
+}
+
+// -----------------------------------------------------------------------
+// E2E Tests
+// -----------------------------------------------------------------------
+
+/// Verifies that `tx_hash` stored in the registry is exactly the Keccak-256 hash of the
+/// BCS-serialised `SignedTransaction` that called `register_via_contract`.
+///
+/// This is the primary correctness test for the entire feature:
+/// 1. `get_transaction_consensus_hash_internal` (native) reads `txn_consensus_hash` from the
+///    `UserTransactionContext` populated by `TransactionMetadata::new()`.
+/// 2. `register_without_validation` forwards this hash to the private `register()` call.
+/// 3. `register()` stores it in `AutomationTaskMetaData.tx_hash`.
+/// 4. We verify the stored value equals what we compute independently of the same bytes
+///    before submission.
+#[test]
+fn test_register_without_validation_hash_matches_txn() {
+    run_on_large_stack(|| {
+        let mut h = setup_harness_with_v2_1();
+        deploy_wrapper(&mut h);
+        let user = new_funded_user(&mut h);
+
+        // Expiry must exceed current time (genesis = 0 s) plus at least one cycle (7 200 s).
+        let expiry_time = 7_200u64 + 86_400;
+
+        // Build the transaction *without* submitting it so we can hash it before the VM sees it.
+        let signed_txn: SignedTransaction = build_register_txn(&mut h, &user, expiry_time);
+
+        // Compute the expected hash: mirrors TransactionMetadata::new() in transaction_metadata.rs
+        let expected_hash = HashValue::keccak_256_of(
+            &bcs::to_bytes(&signed_txn)
+                .expect("SignedTransaction must always BCS-serialize successfully"),
+        );
+
+        // Submit the transaction and assert it succeeds.
+        let output = h.run_raw(signed_txn);
+        assert_success!(output.status().to_owned());
+
+        // Read the task that was just registered (first task ever → task index 0).
+        let task = get_task_details(&mut h, 0);
+
+        assert_eq!(
+            task.tx_hash().as_slice(),
+            expected_hash.as_ref(),
+            "tx_hash in registry must equal the Keccak-256 of the registering SignedTransaction"
+        );
+    });
+}
+
+/// Happy-path test: a third-party smart contract calls `register_without_validation` and the
+/// task is written to the registry with the correct owner and a 32-byte tx_hash.
+///
+/// This exercises the public API surface that DeFi protocols are intended to use.
+#[test]
+fn test_register_without_validation_from_smart_contract() {
+    run_on_large_stack(|| {
+        let mut h = setup_harness_with_v2_1();
+        deploy_wrapper(&mut h);
+        let user = new_funded_user(&mut h);
+
+        let expiry_time = 7_200u64 + 86_400;
+        let status = h.run_entry_function(
+            &user,
+            str::parse("0xDEADBEEF::automation_contract_test::register_via_contract").unwrap(),
+            vec![],
+            vec![
+                bcs::to_bytes(&dummy_payload_bytes()).unwrap(),
+                bcs::to_bytes(&expiry_time).unwrap(),
+                bcs::to_bytes(&10_000u64).unwrap(),
+                bcs::to_bytes(&100u64).unwrap(),
+                bcs::to_bytes(&1_000u64).unwrap(),
+                bcs::to_bytes(&user_aux_data()).unwrap(),
+            ],
+        );
+        assert_success!(status);
+
+        // Verify task owner.
+        let task = get_task_details(&mut h, 0);
+        assert_eq!(
+            task.owner(),
+            user.address(),
+            "task owner must be the account that submitted the transaction"
+        );
+
+        // Verify the tx_hash field is a 32-byte Keccak-256 digest.
+        assert_eq!(
+            task.tx_hash().len(),
+            32,
+            "tx_hash must be a 32-byte Keccak-256 digest"
+        );
+
+        // Verify exactly one task was registered (next index = 1).
+        let idx_output = h.execute_view_function(
+            str::parse("0x1::automation_registry::get_next_task_index").unwrap(),
+            vec![],
+            vec![],
+        );
+        let values = idx_output
+            .values
+            .expect("get_next_task_index view call must succeed");
+        let next_index: u64 = bcs::from_bytes(&values[0]).expect("decode task index");
+        assert_eq!(next_index, 1, "exactly one task should be registered");
+    });
+}
+
+/// Verifies that calling `register_via_contract` when SUPRA_AUTOMATION_V2_1 is disabled
+/// aborts with EDISABLED_AUTOMATION_FEATURE = 15.
+///
+/// This ensures the feature gate in `register_without_validation` is enforced and that
+/// the function cannot be used before the binary upgrade is rolled out to all nodes.
+#[test]
+fn test_register_without_validation_feature_disabled_aborts() {
+    run_on_large_stack(|| {
+        let mut h = setup_harness_without_v2_1();
+        deploy_wrapper(&mut h);
+        let user = new_funded_user(&mut h);
+
+        let expiry_time = 7_200u64 + 86_400;
+        let status = h.run_entry_function(
+            &user,
+            str::parse("0xDEADBEEF::automation_contract_test::register_via_contract").unwrap(),
+            vec![],
+            vec![
+                bcs::to_bytes(&dummy_payload_bytes()).unwrap(),
+                bcs::to_bytes(&expiry_time).unwrap(),
+                bcs::to_bytes(&10_000u64).unwrap(),
+                bcs::to_bytes(&100u64).unwrap(),
+                bcs::to_bytes(&1_000u64).unwrap(),
+                bcs::to_bytes(&user_aux_data()).unwrap(),
+            ],
+        );
+        assert_abort!(status, EDISABLED_AUTOMATION_FEATURE);
+    });
+}
diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs
index c407d74e82e..126ece674dd 100644
--- a/aptos-move/e2e-move-tests/src/tests/mod.rs
+++ b/aptos-move/e2e-move-tests/src/tests/mod.rs
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: Apache-2.0
 
 mod access_path_test;
+mod automation_registry;
 mod account;
 mod aggregator;
 mod aggregator_v2;
diff --git a/aptos-move/e2e-tests/src/executor.rs b/aptos-move/e2e-tests/src/executor.rs
index 87da2dbbac4..b483f2c9dbb 100644
--- a/aptos-move/e2e-tests/src/executor.rs
+++ b/aptos-move/e2e-tests/src/executor.rs
@@ -502,8 +502,9 @@ impl FakeExecutor {
     /// Executes the transaction as a singleton block and applies the resulting write set to the
     /// data store. Panics if execution fails
     pub fn execute_and_apply_transaction(&mut self, transaction: Transaction) -> TransactionOutput {
-        let mut outputs = self.execute_transaction_block(vec![transaction]).unwrap();
+        let mut outputs = self.execute_transaction_block(vec![transaction.clone()]).unwrap();
         assert_eq!(outputs.len(), 1, "transaction outputs size mismatch");
+        println!("transaction execution output: {:#?} : {:#?}", outputs, transaction);
         let output = outputs.pop().unwrap();
         match output.status() {
             TransactionStatus::Keep(status) => {
@@ -522,8 +523,8 @@ impl FakeExecutor {
                 assert_eq!(
                     status,
                     &ExecutionStatus::Success,
-                    "transaction failed with {:?}",
-                    status
+                    "transaction failed with {:?}, {:?}",
+                    status,  transaction
                 );
                 output
             },
diff --git a/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs b/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs
index 931f7b3611a..913b80e40e3 100644
--- a/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs
+++ b/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs
@@ -1,6 +1,3 @@
-// Copyright (c) Aptos Foundation
-// SPDX-License-Identifier: Apache-2.0
-
 // Copyright (c) 2024 Supra.
 // SPDX-License-Identifier: Apache-2.0
 
@@ -9,13 +6,159 @@ use aptos_cached_packages::aptos_framework_sdk_builder;
 use aptos_crypto::HashValue;
 use aptos_types::{
     chain_id::ChainId,
-    on_chain_config::AutomationCycleState,
+    on_chain_config::{AutomationCycleState, FeatureFlag},
     transaction::{
-        automated_transaction::{AutomatedTransaction, AutomatedTransactionBuilder, BuilderResult},
-        ExecutionStatus, Transaction, TransactionStatus,
+        automated_transaction::{
+            AutomatedTransaction, AutomatedTransactionBuilder, AutomatedTransactionDescriptor,
+            BuilderResult,
+        },
+        automation::AutomationTaskType,
+        EntryFunction, ExecutionStatus, Transaction, TransactionStatus,
     },
 };
-use move_core_types::vm_status::StatusCode;
+use move_core_types::{
+    account_address::AccountAddress,
+    identifier::Identifier,
+    language_storage::ModuleId,
+    vm_status::StatusCode,
+};
+
+// ─────────────────────────────────────────────────────────────────────────────
+// Shared test constants
+// ─────────────────────────────────────────────────────────────────────────────
+
+/// Number of seconds by which a test must advance the chain clock to trigger a
+/// cycle transition (CYCLE_STARTED → CYCLE_FINISHED).
+const CYCLE_ADVANCE_SECS: u64 = 1200;
+
+/// Automation-fee cap (in quants) used when registering test tasks.
+/// Large enough to satisfy the estimated-fee assertion inside `register`.
+const AUTOMATION_FEE_CAP: u64 = 100_000;
+
+/// Max-gas amount and gas-price cap used for test tasks.  Small enough that
+/// `gas_price_cap × max_gas_amount` (10 000) is well within the test sender's
+/// initial balance of 100 billion tokens, so the gas-balance prologue check
+/// passes even after deducting registration fees.
+const TASK_MAX_GAS_AMOUNT: u64 = 1_000;
+const TASK_GAS_PRICE_CAP: u64 = 100;
+
+/// A canonical 32-byte dummy transaction hash used as the `tx_hash` field
+/// when registering tasks via the bypass helper.  The prologue does not check
+/// this field, so any 32-byte value is valid.
+const DUMMY_TX_HASH: [u8; 32] = [42u8; 32];
+
+/// Auxiliary data for a User-Submitted Task (UST) with no explicit priority.
+/// Format required by `check_and_validate_aux_data` in `automation_registry.move`:
+///   - element 0: `[1u8]`  → task type byte (1 = UST)
+///   - element 1: `[]`      → empty priority → registry auto-assigns task_index
+fn ust_aux_data() -> Vec> {
+    // UST type byte = 1 (mirrors `const UST: u8 = 1` in automation_registry.move)
+    vec![vec![1u8], vec![]]
+}
+
+// ─────────────────────────────────────────────────────────────────────────────
+// Helper: build an EntryFunction that references a module which does NOT exist
+// in the framework.
+//
+// The resulting BCS bytes are well-formed (`bcs::from_bytes::`
+// succeeds) but when the automated-transaction processor calls
+// `load_and_validate_entry_function` the VM cannot find the module and returns
+// `StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD`.
+// ─────────────────────────────────────────────────────────────────────────────
+fn make_nonexistent_entry_function() -> EntryFunction {
+    EntryFunction::new(
+        ModuleId::new(
+            // 0x0 never has user modules deployed; "phantom_automation_mod" is
+            // deliberately absent from the genesis framework.
+            AccountAddress::ZERO,
+            Identifier::new("phantom_automation_mod")
+                .expect("identifier must be valid"),
+        ),
+        Identifier::new("phantom_fn").expect("identifier must be valid"),
+        vec![],  // no type arguments
+        vec![],  // no runtime arguments (function signature is irrelevant — it doesn't exist)
+    )
+}
+
+// ─────────────────────────────────────────────────────────────────────────────
+// Helper: activate the first registered task (task index 0).
+//
+// Steps:
+//   1. Advance the chain clock by CYCLE_ADVANCE_SECS to move the cycle into
+//      CYCLE_FINISHED state.
+//   2. Submit the registry-action transaction that transitions the cycle back
+//      to CYCLE_STARTED and marks task 0 as ACTIVE.
+// ─────────────────────────────────────────────────────────────────────────────
+fn activate_first_task(ctx: &mut AutomationRegistrationTestContext) {
+    ctx.advance_chain_time_in_secs(CYCLE_ADVANCE_SECS);
+
+    let cycle_info = ctx.get_cycle_info();
+    assert_eq!(
+        cycle_info.state,
+        AutomationCycleState::FINISHED,
+        "cycle must be FINISHED before it can be restarted"
+    );
+
+    let registry_action =
+        ctx.create_automation_registry_transaction(0, cycle_info.index + 1, 1, vec![0]);
+    ctx.execute_and_apply_transaction(Transaction::AutomationRegistryTransaction(registry_action));
+
+    let cycle_info = ctx.get_cycle_info();
+    assert_eq!(
+        cycle_info.state,
+        AutomationCycleState::STARTED,
+        "cycle must be STARTED after the registry action"
+    );
+}
+
+// ─────────────────────────────────────────────────────────────────────────────
+// Helper: build an AutomatedTransactionDescriptor for task 0 using the given
+// entry function and gas-unit price.
+//
+// The `entry_fn` parameter is decoupled from the registry's `payload_tx` bytes
+// intentionally: this lets tests inject an invalid entry function into the
+// automated transaction even when the stored bytes might differ, or use the
+// canonical entry function fetched from the registry for positive-path tests.
+// ─────────────────────────────────────────────────────────────────────────────
+fn build_automated_txn(
+    ctx: &mut AutomationRegistrationTestContext,
+    task_index: u64,
+    entry_fn: EntryFunction,
+    gas_unit_price: u64,
+    expiry_time: u64,
+) -> AutomatedTransactionDescriptor {
+    // The authenticator is the stored tx_hash from the registry task.  It is
+    // used only to populate TransactionMetadata.authentication_key; the prologue
+    // does not validate it, so using the same DUMMY_TX_HASH works here.
+    let authenticator = HashValue::new(DUMMY_TX_HASH);
+    let sender_address = ctx.sender_account_address();
+
+    let result = AutomatedTransactionBuilder::default()
+        .with_sender(sender_address)
+        .with_sequence_number(task_index)
+        .with_entry_function(entry_fn)
+        .with_max_gas_amount(TASK_MAX_GAS_AMOUNT)
+        .with_gas_price_cap(TASK_GAS_PRICE_CAP)
+        .with_expiration_timestamp_secs(expiry_time)
+        .with_authenticator(authenticator)
+        // Priority must match the auto-assigned value (= task_index) so that
+        // the AutomatedTransactionDescriptor is valid.
+        .with_task_priority(task_index)
+        .with_task_type(AutomationTaskType::User)
+        .with_chain_id(ChainId::test())
+        .with_block_height(1)
+        .with_gas_unit_price(gas_unit_price)
+        .build();
+
+    match result {
+        BuilderResult::Success(txn) => txn,
+        other => panic!("Expected successful automated-transaction build, got: {other:?}"),
+    }
+}
+
+// ─────────────────────────────────────────────────────────────────────────────
+// Existing tests (unchanged)
+// ─────────────────────────────────────────────────────────────────────────────
 
 #[test]
 fn check_unregistered_automated_transaction() {
@@ -105,20 +248,18 @@ fn check_automated_transaction_successful_execution() {
     let dest_account = test_context.new_account_data(1_000_000, 0);
     let payload =
         aptos_framework_sdk_builder::supra_account_transfer(dest_account.address().clone(), 100);
-    let gas_price = 100;
-    let max_gas_amount = 100;
-    let automation_fee_cap = 100_000;
 
-    // Register automation task
+    // Register automation task using the module-level shared constants so that
+    // the gas parameters here stay in sync with the new bypass-registration tests.
     let inner_entry_function = payload.clone().into_entry_function();
-    let expiration_time = test_context.chain_time_now() + 8000;
+    let expiration_time = test_context.chain_time_now() + 8_000;
     let automation_txn = test_context.create_automation_txn(
         0,
         inner_entry_function.clone(),
         expiration_time,
-        gas_price,
-        max_gas_amount,
-        automation_fee_cap,
+        TASK_GAS_PRICE_CAP,   // gas_price_cap = 100
+        TASK_MAX_GAS_AMOUNT,  // max_gas_amount = 1 000
+        AUTOMATION_FEE_CAP,   // automation_fee_cap_for_epoch = 100 000
     );
 
     let output = test_context.execute_and_apply(automation_txn);
@@ -136,32 +277,26 @@ fn check_automated_transaction_successful_execution() {
         .clone()
         .with_chain_id(ChainId::test())
         .with_block_height(1)
-        .with_gas_unit_price(gas_price)
+        .with_gas_unit_price(TASK_GAS_PRICE_CAP)
         .build();
     let BuilderResult::Success(automated_txn) = maybe_automated_txn else {
         panic!("Automated transaction should successfully build: {maybe_automated_txn:?}")
     };
 
+    // The task is PENDING — execution must be rejected before the first cycle starts.
     let result = test_context.execute_tagged_transaction(automated_txn.clone().into());
     AutomationRegistrationTestContext::check_discarded_output(
         result,
         StatusCode::NO_ACTIVE_AUTOMATED_TASK,
     );
 
-    // Moving to the next cycle
-    test_context.advance_chain_time_in_secs(1200);
+    // Advance the chain clock and run the registry action to transition the task
+    // from PENDING → ACTIVE and the cycle from FINISHED → STARTED.
+    // `activate_first_task` encapsulates the advance + registry-action + state
+    // assertions that are identical to the setup in the bypass-registration tests.
+    activate_first_task(&mut test_context);
 
-    // Execute registry action to charge and activate the task
-    let cycle_info = test_context.get_cycle_info();
-    assert_eq!(cycle_info.state, AutomationCycleState::FINISHED);
-    let registry_action =
-        test_context.create_automation_registry_transaction(0, cycle_info.index + 1, 1, vec![0]);
-    test_context
-        .execute_and_apply_transaction(Transaction::AutomationRegistryTransaction(registry_action));
-    let cycle_info = test_context.get_cycle_info();
-    assert_eq!(cycle_info.state, AutomationCycleState::STARTED);
-
-    // Execute automated transaction one more time which should be success, as task is already become active after epoch change
+    // Execute automated transaction; task is now ACTIVE so it should succeed.
     let sender_address = test_context.sender_account_address();
     let sender_seq_num = test_context.account_sequence_number(sender_address);
     let output = test_context.execute_and_apply_transaction(automated_txn.clone().into());
@@ -172,18 +307,20 @@ fn check_automated_transaction_successful_execution() {
     );
     let dest_account_balance = test_context.account_balance(dest_account.address().clone());
     assert_eq!(dest_account_balance, 1_000_100);
-    // check that sequence number is not updated.
+    // Automated transactions must NOT increment the owner's sequence number.
     assert_eq!(
         sender_seq_num,
         test_context.account_sequence_number(sender_address)
     );
 
-    // try to submit automated transaction with incorrect sender
+    // Submitting the same automated transaction with the wrong sender must fail:
+    // the prologue's `has_sender_active_task_with_id_and_type` check uses the
+    // sender address as part of the task-lookup key.
     let maybe_automated_txn = automated_txn_builder
         .with_sender(*dest_account.address())
         .with_chain_id(ChainId::test())
         .with_block_height(1)
-        .with_gas_unit_price(gas_price)
+        .with_gas_unit_price(TASK_GAS_PRICE_CAP)
         .build();
     let BuilderResult::Success(automated_txn) = maybe_automated_txn else {
         panic!("Automated transaction should successfully build")
@@ -194,3 +331,515 @@ fn check_automated_transaction_successful_execution() {
         StatusCode::NO_ACTIVE_AUTOMATED_TASK,
     );
 }
+
+// ─────────────────────────────────────────────────────────────────────────────
+// Tests for tasks registered *without* payload validation
+// (simulates the `register_without_validation` / SUPRA_AUTOMATION_V2_1 path)
+// ─────────────────────────────────────────────────────────────────────────────
+
+/// **Positive case — V2_1 enabled, valid payload, registered without validation.**
+///
+/// A task whose `payload_tx` bytes encode a *valid* EntryFunction (one that
+/// exists in the framework and whose arguments match) is registered through the
+/// bypass helper (simulating `register_without_validation`).  Because the entry
+/// function is valid, the automated-transaction processor's Phase-1 load succeeds
+/// and the function body runs normally, producing a `Keep(Success)` output.
+///
+/// This establishes the baseline: `SUPRA_AUTOMATION_V2_1` being enabled does not
+/// break execution of valid tasks, it only changes the behaviour for *invalid*
+/// ones (see the negative cases below).
+#[test]
+fn check_valid_payload_task_registered_without_validation_executes_successfully() {
+    let mut test_context = AutomationRegistrationTestContext::new();
+
+    // SUPRA_AUTOMATION_V2_1 is in the default feature set (see aptos_features.rs).
+    // Enable SUPRA_NATIVE_AUTOMATION to transition the registry from CYCLE_READY
+    // to CYCLE_STARTED (required for task registration and activation).
+    test_context.set_supra_native_automation(true);
+
+    let dest_account = test_context.new_account_data(0, 0);
+    let inner_fn = aptos_framework_sdk_builder::supra_account_transfer(
+        dest_account.address().clone(),
+        100,
+    )
+    .into_entry_function();
+
+    // BCS-encode the valid EntryFunction — this is what the registry stores as
+    // `payload_tx` in both the validated and the non-validated registration paths.
+    let valid_payload_bytes = bcs::to_bytes(&inner_fn)
+        .expect("EntryFunction must BCS-serialize successfully");
+
+    let expiry_time = test_context.chain_time_now() + 8_000;
+    let sender_address = test_context.sender_account_address();
+
+    // Register via exec bypass (skips native-layer BCS/type-check validation).
+    // The Move `register` function still runs and charges the registration fee.
+    test_context.register_task_bypassing_native_validation(
+        sender_address,
+        valid_payload_bytes,
+        expiry_time,
+        TASK_MAX_GAS_AMOUNT,
+        TASK_GAS_PRICE_CAP,
+        AUTOMATION_FEE_CAP,
+        DUMMY_TX_HASH.to_vec(),
+        ust_aux_data(),
+    );
+
+    assert_eq!(
+        test_context.get_next_task_index_from_registry(),
+        1,
+        "exactly one task should now be in the registry"
+    );
+
+    // Advance the cycle and make the task ACTIVE.
+    activate_first_task(&mut test_context);
+
+    let automated_txn = build_automated_txn(
+        &mut test_context,
+        0,          // task_index
+        inner_fn,   // the same valid entry function
+        1,          // gas_unit_price (≤ TASK_GAS_PRICE_CAP)
+        expiry_time,
+    );
+
+    // The entry function exists and its arguments match — execution must succeed.
+    let output =
+        test_context.execute_and_apply_transaction(automated_txn.into());
+    assert_eq!(
+        output.status(),
+        &TransactionStatus::Keep(ExecutionStatus::Success),
+        "valid payload registered without validation must execute successfully: {output:?}"
+    );
+
+    // Verify the transfer actually happened.
+    let dest_balance = test_context.account_balance(*dest_account.address());
+    assert_eq!(
+        dest_balance,
+        100,
+        "100 tokens should have been transferred to dest_account"
+    );
+}
+
+/// **Negative case — V2_1 enabled, invalid inner payload, registered without validation.**
+///
+/// When `SUPRA_AUTOMATION_V2_1` is enabled, a task whose `payload_tx` bytes
+/// point to a non-existent module is *discarded* at execution time without
+/// charging any gas.  The special path in `execute_transaction_impl` catches
+/// `INVALID_AUTOMATION_INNER_PAYLOAD` and returns `discarded_output(...)` instead
+/// of running the failure epilogue.
+///
+/// # Rationale
+/// Tasks registered through `register_without_validation` skip the BCS/entry-
+/// function check performed by the normal registration flow.  A malformed payload
+/// that was never verified at registration time should not drain the task owner's
+/// account with repeated gas charges if it turns out to be permanently invalid.
+/// The `SUPRA_AUTOMATION_V2_1` discard path is the mechanism that prevents this.
+#[test]
+fn check_invalid_inner_payload_is_discarded_when_v2_1_enabled() {
+    let mut test_context = AutomationRegistrationTestContext::new();
+
+    // SUPRA_AUTOMATION_V2_1 is enabled by default via default_features().
+    // No explicit toggle needed.  SUPRA_NATIVE_AUTOMATION must be enabled
+    // separately to start the registry cycle.
+    test_context.set_supra_native_automation(true);
+
+    // Build an EntryFunction that BCS-serialises successfully (so the payload
+    // bytes are syntactically valid) but references a module that does not exist
+    // at runtime.  `load_and_validate_entry_function` will fail with
+    // INVALID_AUTOMATION_INNER_PAYLOAD when the processor tries to load it.
+    let nonexistent_fn = make_nonexistent_entry_function();
+    let invalid_payload_bytes = bcs::to_bytes(&nonexistent_fn)
+        .expect("EntryFunction must BCS-serialize even if the module is absent at runtime");
+
+    let expiry_time = test_context.chain_time_now() + 8_000;
+    let sender_address = test_context.sender_account_address();
+
+    // Register via exec bypass — the native validator is NOT called, so the
+    // syntactically-valid-but-semantically-invalid payload is accepted.
+    test_context.register_task_bypassing_native_validation(
+        sender_address,
+        invalid_payload_bytes,
+        expiry_time,
+        TASK_MAX_GAS_AMOUNT,
+        TASK_GAS_PRICE_CAP,
+        AUTOMATION_FEE_CAP,
+        DUMMY_TX_HASH.to_vec(),
+        ust_aux_data(),
+    );
+
+    assert_eq!(
+        test_context.get_next_task_index_from_registry(),
+        1,
+        "exactly one task should be registered"
+    );
+
+    // Activate the task so the prologue's `has_sender_active_task_with_id_and_type`
+    // check will pass.
+    activate_first_task(&mut test_context);
+
+    // Record the balance AFTER registration (coins were transferred for the fee)
+    // but BEFORE executing the automated transaction.  We will compare against
+    // this to verify that the discard path charges nothing extra.
+    let balance_before_exec = test_context.account_balance(sender_address);
+
+    // Build the automated transaction carrying the non-existent entry function.
+    // The builder itself succeeds because it only BCS-decodes the stored bytes
+    // (which are valid) — it does not query the VM for module existence.
+    let automated_txn = build_automated_txn(
+        &mut test_context,
+        0,
+        nonexistent_fn,
+        1,
+        expiry_time,
+    );
+
+    // Execute without applying state changes.  We use execute_tagged_transaction
+    // because the output is DISCARDED (no write set to apply) and
+    // execute_and_apply_transaction panics on discarded outputs.
+    let output = test_context
+        .execute_tagged_transaction(automated_txn.into());
+
+    // With SUPRA_AUTOMATION_V2_1 enabled the processor's special path triggers:
+    // the output is discarded and no failure epilogue runs.
+    AutomationRegistrationTestContext::check_discarded_output(
+        output.clone(),
+        StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD,
+    );
+
+    // Discarded outputs carry FeeStatement::zero(), so gas_used must be 0.
+    assert_eq!(
+        output.gas_used(),
+        0,
+        "a discarded output must not charge any gas (FeeStatement::zero())"
+    );
+
+    // The sender's balance must be unchanged since the discard path commits
+    // no write set.  (execute_tagged_transaction does not apply state.)
+    let balance_after_exec = test_context.account_balance(sender_address);
+    assert_eq!(
+        balance_before_exec,
+        balance_after_exec,
+        "balance must not change when the automated transaction is discarded"
+    );
+}
+
+/// **Negative case — V2_1 *disabled*, invalid inner payload registered without validation.**
+///
+/// When `SUPRA_AUTOMATION_V2_1` is disabled, the special discard path in
+/// `execute_transaction_impl` does NOT trigger.  Instead the
+/// `INVALID_AUTOMATION_INNER_PAYLOAD` error flows through
+/// `on_transaction_execution_failure` → `failed_transaction_cleanup`, which runs
+/// the failure epilogue and charges the sender for gas consumed up to that point
+/// (at minimum the intrinsic-gas charge).
+///
+/// The resulting output is `Keep(MiscellaneousError(INVALID_AUTOMATION_INNER_PAYLOAD))`
+/// (status code 1132 is in the Verification range, so `keep_or_discard()` returns
+/// `Ok(KeptVMStatus::MiscellaneousError)`).  Gas *is* charged even though the
+/// entry function body never ran, because `charge_intrinsic_gas_for_transaction`
+/// was called before the failed load attempt.
+///
+/// # Key difference from the enabled case
+/// Without V2_1 the protocol has no way to know that the payload was registered
+/// without validation, so it applies the same fee-charging logic as for any other
+/// kind of execution failure.
+#[test]
+fn check_invalid_inner_payload_charges_fee_when_v2_1_disabled() {
+    let mut test_context = AutomationRegistrationTestContext::new();
+
+    // Enable the base automation feature so the cycle starts and registration
+    // is accepted.  Then explicitly disable SUPRA_AUTOMATION_V2_1 so the
+    // special discard path in the processor is inactive.
+    test_context.set_supra_native_automation(true);
+    // SUPRA_AUTOMATION_V2_1 is in default_features() so we must turn it off.
+    // set_feature_flag updates the on-chain feature bitset directly; no
+    // on_new_epoch call is needed because V2_1 does not affect the registry
+    // state machine (only the VM's error-handling path).
+    test_context.set_feature_flag(FeatureFlag::SUPRA_AUTOMATION_V2_1, false);
+
+    let nonexistent_fn = make_nonexistent_entry_function();
+    let invalid_payload_bytes = bcs::to_bytes(&nonexistent_fn)
+        .expect("EntryFunction must BCS-serialize successfully");
+
+    let expiry_time = test_context.chain_time_now() + 8_000;
+    let sender_address = test_context.sender_account_address();
+
+    // Register the task with the invalid payload.  SUPRA_NATIVE_AUTOMATION is
+    // enabled (so the Move `register` function accepts the call) and the Move
+    // function itself does not check SUPRA_AUTOMATION_V2_1, so registration
+    // succeeds regardless of the V2_1 flag.
+    test_context.register_task_bypassing_native_validation(
+        sender_address,
+        invalid_payload_bytes,
+        expiry_time,
+        TASK_MAX_GAS_AMOUNT,
+        TASK_GAS_PRICE_CAP,
+        AUTOMATION_FEE_CAP,
+        DUMMY_TX_HASH.to_vec(),
+        ust_aux_data(),
+    );
+
+    assert_eq!(
+        test_context.get_next_task_index_from_registry(),
+        1,
+        "exactly one task should be registered"
+    );
+
+    activate_first_task(&mut test_context);
+
+    let balance_before_exec = test_context.account_balance(sender_address);
+
+    let automated_txn = build_automated_txn(
+        &mut test_context,
+        0,
+        nonexistent_fn,
+        1,
+        expiry_time,
+    );
+
+    // Execute via execute_tagged_transaction so we can inspect the output before
+    // deciding whether to apply it.  The output is Keep(MiscellaneousError),
+    // so the write set contains gas-deduction entries.
+    let output = test_context
+        .execute_tagged_transaction(automated_txn.into());
+
+    // Without V2_1 the special discard path is bypassed; the failure epilogue
+    // runs and the output is Keep(MiscellaneousError).
+    AutomationRegistrationTestContext::check_miscellaneous_output(
+        output.clone(),
+        StatusCode::INVALID_AUTOMATION_INNER_PAYLOAD,
+    );
+
+    // The failure epilogue charges at least intrinsic gas.
+    assert!(
+        output.gas_used() > 0,
+        "gas must be charged by the failure epilogue when V2_1 is disabled \
+         (gas_used = {})",
+        output.gas_used()
+    );
+
+    // Apply the write set manually so the balance change is reflected in the
+    // fake data store, then assert the balance decreased.
+    test_context.apply_write_set(output.write_set());
+    let balance_after_exec = test_context.account_balance(sender_address);
+
+    assert!(
+        balance_after_exec < balance_before_exec,
+        "sender balance must decrease when the failure epilogue charges gas \
+         (before = {balance_before_exec}, after = {balance_after_exec})"
+    );
+}
+
+/// **Transient execution failure — failure epilogue runs regardless of V2_1.**
+///
+/// A task whose `payload_tx` points to an existing function is registered
+/// normally (with full validation).  At execution time, the Phase-1 load
+/// succeeds (the function exists and its argument types are correct), but the
+/// function body *aborts* because the transfer amount far exceeds the sender's
+/// balance.
+///
+/// This produces a `VMStatus::MoveAbort`, which does **not** match the special
+/// `INVALID_AUTOMATION_INNER_PAYLOAD` condition in `execute_transaction_impl`.
+/// Therefore the failure epilogue always runs — the sender is charged for gas
+/// regardless of whether `SUPRA_AUTOMATION_V2_1` is enabled.
+///
+/// # What this test verifies
+/// * The V2_1 discard path is narrowly scoped to `INVALID_AUTOMATION_INNER_PAYLOAD`
+///   (Phase-1 load failure); it does NOT affect ordinary runtime aborts.
+/// * The failure epilogue correctly charges gas for a task whose body aborted.
+/// * The output status is `Keep(MoveAbort)` — the write set contains gas fees.
+#[test]
+fn check_transient_execution_failure_charges_fee_regardless_of_v2_1() {
+    let mut test_context = AutomationRegistrationTestContext::new();
+
+    // SUPRA_AUTOMATION_V2_1 is enabled by default.  We leave it enabled to
+    // confirm that V2_1 does NOT suppress transient (runtime) failures.
+    test_context.set_supra_native_automation(true);
+
+    // Use a destination that can receive coins (create it with 0 initial balance).
+    let dest_account = test_context.new_account_data(0, 0);
+
+    // Transfer amount is astronomically larger than the sender's balance (~100
+    // billion quants after registration fees).  The prologue only checks that
+    // `gas_price × max_gas_amount` fits within the balance, NOT the transfer
+    // amount itself — so the prologue passes.  The transfer then aborts inside
+    // `supra_account_transfer` when it tries to withdraw more than available.
+    let oversized_transfer_amount = 500_000_000_000_000u64; // 500 trillion >> sender's ~100 billion
+
+    let inner_fn = aptos_framework_sdk_builder::supra_account_transfer(
+        dest_account.address().clone(),
+        oversized_transfer_amount,
+    )
+    .into_entry_function();
+
+    // Register with the validated path to prove the inner function is valid at
+    // registration time.  Only the runtime execution will fail.
+    let expiry_time = test_context.chain_time_now() + 8_000;
+    let automation_txn = test_context.create_automation_txn(
+        0,
+        inner_fn.clone(),
+        expiry_time,
+        TASK_MAX_GAS_AMOUNT,
+        TASK_GAS_PRICE_CAP,
+        AUTOMATION_FEE_CAP,
+    );
+
+    let reg_output = test_context.execute_and_apply(automation_txn);
+    assert_eq!(
+        reg_output.status(),
+        &TransactionStatus::Keep(ExecutionStatus::Success),
+        "registration must succeed: {reg_output:?}"
+    );
+
+    assert_eq!(
+        test_context.get_next_task_index_from_registry(),
+        1,
+        "exactly one task should be registered"
+    );
+
+    activate_first_task(&mut test_context);
+
+    let sender_address = test_context.sender_account_address();
+    let balance_before_exec = test_context.account_balance(sender_address);
+
+    // Build the automated transaction using the same entry function that was
+    // registered (which the builder obtains via try_from(task_details)).
+    let task_details = test_context.get_task_details(0);
+    let builder = AutomatedTransactionBuilder::try_from(task_details)
+        .expect("builder construction from registered task must succeed");
+
+    let result = builder
+        .with_chain_id(ChainId::test())
+        .with_block_height(1)
+        .with_gas_unit_price(1)
+        .build();
+
+    let BuilderResult::Success(automated_txn) = result else {
+        panic!("automated transaction builder must succeed for a validly registered task");
+    };
+
+    // Execute without applying so we can inspect the output first.
+    let output = test_context.execute_tagged_transaction(automated_txn.into());
+
+    // Phase-1 (load) succeeded.  Phase-2 (execution body) aborted.
+    // This is a transient failure → `on_transaction_execution_failure` runs.
+    // keep_or_discard() for MoveAbort returns Ok(KeptVMStatus::MoveAbort), so
+    // the output is Keep(MoveAbort { ... }).
+    match output.status() {
+        TransactionStatus::Keep(ExecutionStatus::MoveAbort { .. }) => {
+            // Expected: the execution body aborted at runtime.
+        },
+        other => panic!(
+            "expected Keep(MoveAbort) for runtime abort, got: {other:?}"
+        ),
+    }
+
+    // Gas must have been charged by the failure epilogue.
+    assert!(
+        output.gas_used() > 0,
+        "gas must be charged for a runtime abort (failure epilogue ran)"
+    );
+
+    // Apply the write set and verify balance decreased.
+    test_context.apply_write_set(output.write_set());
+    let balance_after_exec = test_context.account_balance(sender_address);
+
+    assert!(
+        balance_after_exec < balance_before_exec,
+        "sender balance must decrease after a runtime abort \
+         (before = {balance_before_exec}, after = {balance_after_exec})"
+    );
+
+    // The destination should NOT have received any coins because the transfer
+    // was rolled back as part of the abort.
+    let dest_balance = test_context.account_balance(*dest_account.address());
+    assert_eq!(
+        dest_balance,
+        0,
+        "destination must not receive tokens when the transfer aborts"
+    );
+}
+
+/// **Symmetry check — transient failure with V2_1 explicitly disabled.**
+///
+/// Mirrors `check_transient_execution_failure_charges_fee_regardless_of_v2_1`
+/// but with `SUPRA_AUTOMATION_V2_1` turned off.  The result must be identical
+/// (`Keep(MoveAbort)`, gas charged) because the V2_1 flag only influences the
+/// `INVALID_AUTOMATION_INNER_PAYLOAD` path, not ordinary runtime aborts.
+///
+/// Together with the test above this provides full cross-flag coverage for the
+/// transient-failure branch of `execute_transaction_impl`.
+#[test]
+fn check_transient_execution_failure_charges_fee_when_v2_1_disabled() {
+    let mut test_context = AutomationRegistrationTestContext::new();
+
+    test_context.set_supra_native_automation(true);
+    // Disable V2_1 to confirm it has no effect on runtime aborts.
+    test_context.set_feature_flag(FeatureFlag::SUPRA_AUTOMATION_V2_1, false);
+
+    let dest_account = test_context.new_account_data(0, 0);
+    let oversized_transfer_amount = 500_000_000_000_000u64;
+
+    let inner_fn = aptos_framework_sdk_builder::supra_account_transfer(
+        dest_account.address().clone(),
+        oversized_transfer_amount,
+    )
+    .into_entry_function();
+
+    let expiry_time = test_context.chain_time_now() + 8_000;
+    let automation_txn = test_context.create_automation_txn(
+        0,
+        inner_fn.clone(),
+        expiry_time,
+        TASK_MAX_GAS_AMOUNT,
+        TASK_GAS_PRICE_CAP,
+        AUTOMATION_FEE_CAP,
+    );
+
+    let reg_output = test_context.execute_and_apply(automation_txn);
+    assert_eq!(
+        reg_output.status(),
+        &TransactionStatus::Keep(ExecutionStatus::Success),
+        "registration must succeed: {reg_output:?}"
+    );
+
+    activate_first_task(&mut test_context);
+
+    let sender_address = test_context.sender_account_address();
+    let balance_before_exec = test_context.account_balance(sender_address);
+
+    let task_details = test_context.get_task_details(0);
+    let builder = AutomatedTransactionBuilder::try_from(task_details)
+        .expect("builder must succeed for a validly registered task");
+
+    let result = builder
+        .with_chain_id(ChainId::test())
+        .with_block_height(1)
+        .with_gas_unit_price(1)
+        .build();
+
+    let BuilderResult::Success(automated_txn) = result else {
+        panic!("automated transaction builder must succeed");
+    };
+
+    let output = test_context.execute_tagged_transaction(automated_txn.into());
+
+    // Result is identical to the V2_1-enabled case: Keep(MoveAbort).
+    match output.status() {
+        TransactionStatus::Keep(ExecutionStatus::MoveAbort { .. }) => {},
+        other => panic!(
+            "expected Keep(MoveAbort) regardless of V2_1 flag for runtime abort, got: {other:?}"
+        ),
+    }
+
+    assert!(
+        output.gas_used() > 0,
+        "gas must be charged by the failure epilogue regardless of V2_1"
+    );
+
+    test_context.apply_write_set(output.write_set());
+    let balance_after_exec = test_context.account_balance(sender_address);
+    assert!(
+        balance_after_exec < balance_before_exec,
+        "sender balance must decrease (before = {balance_before_exec}, after = {balance_after_exec})"
+    );
+}
\ No newline at end of file
diff --git a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
index 73648ec2e11..4302aba4753 100644
--- a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
+++ b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
@@ -1,6 +1,3 @@
-// Copyright (c) Aptos Foundation
-// SPDX-License-Identifier: Apache-2.0
-
 // Copyright (c) 2024 Supra.
 // SPDX-License-Identifier: Apache-2.0
 
@@ -51,6 +48,8 @@ const HAS_SENDER_ACTIVE_TASK_WITH_ID: &str =
     "0x1::automation_registry::has_sender_active_task_with_id";
 const GET_TASK_IDS: &str = "0x1::automation_registry::get_task_ids";
 
+const MAX_GAS_AMOUNT_REGISTRATION: u64 = 500_000_000;
+
 struct MultisigAccountData {
     multisig_address: AccountAddress,
     owners: Vec,
@@ -111,8 +110,8 @@ impl AutomationRegistrationTestContext {
 
     fn create_multisig_account_data(executor: &mut FakeExecutor) -> MultisigAccountData {
         // Prepare multisig_account for system task registration
-        let multisig_owner1 = executor.create_raw_account_data(1_000_000_000, 0);
-        let multisig_owner2 = executor.create_raw_account_data(1_000_000_000, 0);
+        let multisig_owner1 = executor.create_raw_account_data(1_000_000_000_000, 0);
+        let multisig_owner2 = executor.create_raw_account_data(1_000_000_000_000, 0);
         executor.add_account_data(&multisig_owner1);
         executor.add_account_data(&multisig_owner2);
         let multisig_address = create_multisig_account_address(
@@ -129,7 +128,7 @@ impl AutomationRegistrationTestContext {
         let account_create_txn = multisig_owner1
             .account()
             .transaction()
-            .max_gas_amount(1_000_000)
+            .max_gas_amount(5_000_000)
             .gas_unit_price(100)
             .payload(create_multisig_payload)
             .sequence_number(0)
@@ -139,7 +138,7 @@ impl AutomationRegistrationTestContext {
         let transfer_txn = multisig_owner1
             .account()
             .transaction()
-            .max_gas_amount(1000)
+            .max_gas_amount(5_000_000)
             .payload(aptos_stdlib::supra_account_transfer(
                 multisig_address,
                 10_000_000,
@@ -233,6 +232,7 @@ impl AutomationRegistrationTestContext {
             .payload(automation_txn)
             .sequence_number(seq_num)
             .gas_unit_price(1)
+            .max_gas_amount(MAX_GAS_AMOUNT_REGISTRATION)
             .sign()
     }
 
@@ -262,6 +262,7 @@ impl AutomationRegistrationTestContext {
             .payload(automation_txn)
             .sequence_number(seq_num)
             .gas_unit_price(1)
+            .max_gas_amount(MAX_GAS_AMOUNT_REGISTRATION)
             .sign()
     }
 
@@ -286,6 +287,7 @@ impl AutomationRegistrationTestContext {
             .payload(automation_txn)
             .sequence_number(seq_num)
             .gas_unit_price(1)
+            .max_gas_amount(MAX_GAS_AMOUNT_REGISTRATION)
             .sign()
     }
 
@@ -303,6 +305,7 @@ impl AutomationRegistrationTestContext {
             ))
             .sequence_number(seq_num)
             .gas_unit_price(1)
+            .max_gas_amount(MAX_GAS_AMOUNT_REGISTRATION)
             .sign()
     }
 
@@ -496,6 +499,80 @@ impl AutomationRegistrationTestContext {
         bcs::from_bytes::>(&result[0])
             .expect("Successful deserialization of AutomationCycleInfo")
     }
+
+    /// Registers an automation task by directly invoking the private Move `register`
+    /// function through the test executor, bypassing both:
+    ///
+    /// 1. **Visibility**: `register` is a `fun` (package-private in Move). The
+    ///    underlying `execute_function_bypass_visibility` call ignores this, so
+    ///    no access-control error is raised.
+    ///
+    /// 2. **Native-layer payload validation**: In the normal `AutomationRegistration`
+    ///    transaction flow the VM validates that `payload_bytes` is a well-formed,
+    ///    BCS-encoded `EntryFunction` with correct argument types *before* any Move
+    ///    code runs. The `exec` path skips this check entirely, so arbitrary bytes
+    ///    (including those that encode a call to a non-existent function) are stored
+    ///    directly in the registry.
+    ///
+    /// This simulates what happens in production when a smart-contract registers a
+    /// task via `automation_registry::register_without_validation` (the
+    /// `SUPRA_AUTOMATION_V2_1` path), which also skips payload validation and relies
+    /// on the runtime to catch and discard permanently invalid tasks at execution
+    /// time.
+    ///
+    /// # Prerequisites
+    /// * `SUPRA_NATIVE_AUTOMATION` must be enabled and the automation cycle must be
+    ///   in `CYCLE_STARTED` state before calling this method (the Move `register`
+    ///   function asserts this).
+    /// * `tx_hash` must be exactly 32 bytes (`TXN_HASH_LENGTH = 32` in the Move
+    ///   contract).
+    /// * `aux_data` must have exactly 2 elements matching the format validated by
+    ///   `check_and_validate_aux_data`:
+    ///   - index 0: a single byte encoding the task type (`[1u8]` for UST/User)
+    ///   - index 1: BCS-serialised priority `u64`, or empty (`[]`) to let the
+    ///     registry assign the task index as the default priority.
+    /// * The `owner_address` account must have enough SupraCoin balance to cover
+    ///   the flat registration fee plus the epoch-deposit (`automation_fee_cap`).
+    pub(crate) fn register_task_bypassing_native_validation(
+        &mut self,
+        owner_address: AccountAddress,
+        payload_bytes: Vec,
+        expiry_time: u64,
+        max_gas_amount: u64,
+        gas_price_cap: u64,
+        automation_fee_cap: u64,
+        tx_hash: Vec,
+        aux_data: Vec>,
+    ) {
+        // Call the private `register` Move function via execute_function_bypass_visibility.
+        // The signer argument is passed as a BCS-serialised MoveValue::Signer so the Move VM
+        // constructs a valid signer capability for `owner_address` without requiring a
+        // real signed transaction.
+        //
+        // Crucially, none of the native-layer checks (BCS-decode payload, validate
+        // EntryFunction shape) execute here — only the Move code inside `register` runs.
+        // This means `payload_bytes` is stored verbatim, even if it encodes a call to a
+        // non-existent module/function.
+        self.executor.exec("automation_registry", "register", vec![], vec![
+            MoveValue::Signer(owner_address)
+                .simple_serialize()
+                .expect("Signer serialization must not fail"),
+            bcs::to_bytes(&payload_bytes)
+                .expect("payload bytes must be BCS-serialisable"),
+            bcs::to_bytes(&expiry_time)
+                .expect("expiry_time must be BCS-serialisable"),
+            bcs::to_bytes(&max_gas_amount)
+                .expect("max_gas_amount must be BCS-serialisable"),
+            bcs::to_bytes(&gas_price_cap)
+                .expect("gas_price_cap must be BCS-serialisable"),
+            bcs::to_bytes(&automation_fee_cap)
+                .expect("automation_fee_cap must be BCS-serialisable"),
+            bcs::to_bytes(&tx_hash)
+                .expect("tx_hash must be BCS-serialisable"),
+            bcs::to_bytes(&aux_data)
+                .expect("aux_data must be BCS-serialisable"),
+        ]);
+    }
 }
 
 impl Deref for AutomationRegistrationTestContext {
diff --git a/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs b/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs
index 7f5b7ea6a58..10e0b6e33bc 100644
--- a/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs
+++ b/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs
@@ -1,6 +1,3 @@
-// Copyright (c) Aptos Foundation
-// SPDX-License-Identifier: Apache-2.0
-
 // Copyright (c) 2024 Supra.
 // SPDX-License-Identifier: Apache-2.0
 
diff --git a/aptos-move/framework/aptos-stdlib/doc/any.md b/aptos-move/framework/aptos-stdlib/doc/any.md
index d8f08373494..5b930d17a03 100644
--- a/aptos-move/framework/aptos-stdlib/doc/any.md
+++ b/aptos-move/framework/aptos-stdlib/doc/any.md
@@ -11,6 +11,7 @@
 -  [Function `pack`](#0x1_any_pack)
 -  [Function `unpack`](#0x1_any_unpack)
 -  [Function `type_name`](#0x1_any_type_name)
+-  [Function `is_empty`](#0x1_any_is_empty)
 -  [Specification](#@Specification_1)
     -  [Function `pack`](#@Specification_1_pack)
     -  [Function `unpack`](#@Specification_1_unpack)
@@ -22,6 +23,7 @@
 use 0x1::from_bcs;
 use 0x1::string;
 use 0x1::type_info;
+use 0x1::vector;
 
@@ -191,6 +193,33 @@ Returns the type name of this Any + + + + +## Function `is_empty` + +Returns true if the BCS-encoded data payload is empty. +An Any value with an empty data vector cannot be decoded and should +be treated as invalid by callers. + + +
public fun is_empty(x: &any::Any): bool
+
+ + + +
+Implementation + + +
public fun is_empty(x: &Any): bool {
+    std::vector::is_empty(&x.data)
+}
+
+ + +
diff --git a/aptos-move/framework/aptos-stdlib/doc/copyable_any.md b/aptos-move/framework/aptos-stdlib/doc/copyable_any.md index 7ac120437e6..4803bd75f7e 100644 --- a/aptos-move/framework/aptos-stdlib/doc/copyable_any.md +++ b/aptos-move/framework/aptos-stdlib/doc/copyable_any.md @@ -8,8 +8,10 @@ - [Struct `Any`](#0x1_copyable_any_Any) - [Constants](#@Constants_0) - [Function `pack`](#0x1_copyable_any_pack) +- [Function `new`](#0x1_copyable_any_new) - [Function `unpack`](#0x1_copyable_any_unpack) - [Function `type_name`](#0x1_copyable_any_type_name) +- [Function `is_empty`](#0x1_copyable_any_is_empty) - [Specification](#@Specification_1) - [Function `pack`](#@Specification_1_pack) - [Function `unpack`](#@Specification_1_unpack) @@ -21,6 +23,7 @@ use 0x1::from_bcs; use 0x1::string; use 0x1::type_info; +use 0x1::vector;
@@ -101,6 +104,39 @@ also required from T. + + + + +## Function `new` + +Construct an Any directly from a pre-known type-name string and +already-BCS-encoded data bytes. Use this only when the type name is +obtained from a trusted source (e.g. type_info::type_name<T>() or a +constant produced by the same) and the data bytes are the BCS encoding +of a value of that type. Prefer pack<T> whenever the concrete type +is statically known at the call site, as it is safer and self-validating. + +This constructor exists primarily for genesis and governance scripts that +receive pre-serialised values from the Rust layer. + + +
public fun new(type_name: string::String, data: vector<u8>): copyable_any::Any
+
+ + + +
+Implementation + + +
public fun new(type_name: String, data: vector<u8>): Any {
+    Any { type_name, data }
+}
+
+ + +
@@ -152,6 +188,33 @@ Returns the type name of this Any + + + + +## Function `is_empty` + +Returns true if the BCS-encoded data payload is empty. +An Any value with an empty data vector cannot be decoded and should +be treated as invalid by callers. + + +
public fun is_empty(x: &copyable_any::Any): bool
+
+ + + +
+Implementation + + +
public fun is_empty(x: &Any): bool {
+    std::vector::is_empty(&x.data)
+}
+
+ + +
diff --git a/aptos-move/framework/aptos-stdlib/sources/any.move b/aptos-move/framework/aptos-stdlib/sources/any.move index 88b9f4dd780..a275828d4cf 100644 --- a/aptos-move/framework/aptos-stdlib/sources/any.move +++ b/aptos-move/framework/aptos-stdlib/sources/any.move @@ -54,6 +54,13 @@ module aptos_std::any { &x.type_name } + /// Returns true if the BCS-encoded data payload is empty. + /// An Any value with an empty data vector cannot be decoded and should + /// be treated as invalid by callers. + public fun is_empty(x: &Any): bool { + std::vector::is_empty(&x.data) + } + #[test_only] struct S has store, drop { x: u64 } diff --git a/aptos-move/framework/aptos-stdlib/sources/copyable_any.move b/aptos-move/framework/aptos-stdlib/sources/copyable_any.move index b12303a3f92..dc288f0faec 100644 --- a/aptos-move/framework/aptos-stdlib/sources/copyable_any.move +++ b/aptos-move/framework/aptos-stdlib/sources/copyable_any.move @@ -23,6 +23,19 @@ module aptos_std::copyable_any { } } + /// Construct an `Any` directly from a pre-known type-name string and + /// already-BCS-encoded data bytes. Use this only when the type name is + /// obtained from a trusted source (e.g. `type_info::type_name()` or a + /// constant produced by the same) and the data bytes are the BCS encoding + /// of a value of that type. Prefer `pack` whenever the concrete type + /// is statically known at the call site, as it is safer and self-validating. + /// + /// This constructor exists primarily for genesis and governance scripts that + /// receive pre-serialised values from the Rust layer. + public fun new(type_name: String, data: vector): Any { + Any { type_name, data } + } + /// Unpack a value from the `Any` representation. This aborts if the value has not the expected type `T`. public fun unpack(x: Any): T { assert!(type_info::type_name() == x.type_name, error::invalid_argument(ETYPE_MISMATCH)); @@ -34,6 +47,13 @@ module aptos_std::copyable_any { &x.type_name } + /// Returns true if the BCS-encoded data payload is empty. + /// An Any value with an empty data vector cannot be decoded and should + /// be treated as invalid by callers. + public fun is_empty(x: &Any): bool { + std::vector::is_empty(&x.data) + } + #[test_only] struct S has store, drop, copy { x: u64 } diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md index d1044ad9144..d9909651845 100644 --- a/aptos-move/framework/move-stdlib/doc/features.md +++ b/aptos-move/framework/move-stdlib/doc/features.md @@ -155,6 +155,8 @@ return true. - [Function `supra_dkg_enabled`](#0x1_features_supra_dkg_enabled) - [Function `get_supra_transactions_inclusion_proofs_feature`](#0x1_features_get_supra_transactions_inclusion_proofs_feature) - [Function `supra_transactions_inclusion_proofs_enabled`](#0x1_features_supra_transactions_inclusion_proofs_enabled) +- [Function `get_supra_automation_v2_1_feature`](#0x1_features_get_supra_automation_v2_1_feature) +- [Function `supra_automation_v2_1_enabled`](#0x1_features_supra_automation_v2_1_enabled) - [Function `change_feature_flags`](#0x1_features_change_feature_flags) - [Function `change_feature_flags_internal`](#0x1_features_change_feature_flags_internal) - [Function `change_feature_flags_for_next_epoch`](#0x1_features_change_feature_flags_for_next_epoch) @@ -932,6 +934,21 @@ Lifetime: transient + + +Whether smart contracts can register automation tasks via register_without_validation, +using the get_txn_app_hash native to obtain the registering transaction's hash. +Must only be enabled after all nodes have upgraded to the binary that implements +the get_txn_app_hash_internal native function. + +Lifetime: transient + + +
const SUPRA_AUTOMATION_V2_1: u64 = 101;
+
+ + + Whether BCFT certificate thresholds are enabled. @@ -4044,6 +4061,54 @@ Lifetime: transient + + + + +## Function `get_supra_automation_v2_1_feature` + + + +
public fun get_supra_automation_v2_1_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_supra_automation_v2_1_feature(): u64 {
+    SUPRA_AUTOMATION_V2_1
+}
+
+ + + +
+ + + +## Function `supra_automation_v2_1_enabled` + + + +
public fun supra_automation_v2_1_enabled(): bool
+
+ + + +
+Implementation + + +
public fun supra_automation_v2_1_enabled(): bool acquires Features {
+    is_enabled(SUPRA_AUTOMATION_V2_1)
+}
+
+ + +
diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.move b/aptos-move/framework/move-stdlib/sources/configs/features.move index 811e68ec897..5db8b24e07d 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.move @@ -839,6 +839,22 @@ module std::features { is_enabled(SUPRA_TRANSACTIONS_INCLUSION_PROOFS) } + /// Whether smart contracts can register automation tasks via `register_without_validation`, + /// using the `get_txn_app_hash` native to obtain the registering transaction's hash. + /// Must only be enabled after all nodes have upgraded to the binary that implements + /// the `get_txn_app_hash_internal` native function. + /// + /// Lifetime: transient + const SUPRA_AUTOMATION_V2_1: u64 = 101; + + public fun get_supra_automation_v2_1_feature(): u64 { + SUPRA_AUTOMATION_V2_1 + } + + public fun supra_automation_v2_1_enabled(): bool acquires Features { + is_enabled(SUPRA_AUTOMATION_V2_1) + } + // ============================================================================================ // Feature Flag Implementation diff --git a/aptos-move/framework/src/natives/automation_registry_callbacks.rs b/aptos-move/framework/src/natives/automation_registry_callbacks.rs index 462756d9fd1..bc2aeb2a13d 100644 --- a/aptos-move/framework/src/natives/automation_registry_callbacks.rs +++ b/aptos-move/framework/src/natives/automation_registry_callbacks.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2025 Supra. // SPDX-License-Identifier: Apache-2.0 use aptos_native_interface::{SafeNativeBuilder, SafeNativeContext, SafeNativeResult}; diff --git a/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs b/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs index 01530e3accc..7839d844271 100644 --- a/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs +++ b/aptos-move/framework/src/natives/cryptography/bls12381_bulletproofs.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2024 Supra. use crate::natives::cryptography::bulletproofs::abort_codes; diff --git a/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs b/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs index 1a544baa646..831cbedc52e 100644 --- a/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs +++ b/aptos-move/framework/src/natives/cryptography/bls12381_scalar.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2024 Supra. use aptos_gas_schedule::gas_params::natives::aptos_framework::{ diff --git a/aptos-move/framework/src/natives/cryptography/eth_trie.rs b/aptos-move/framework/src/natives/cryptography/eth_trie.rs index 6dc32154c90..bafc3006fb2 100644 --- a/aptos-move/framework/src/natives/cryptography/eth_trie.rs +++ b/aptos-move/framework/src/natives/cryptography/eth_trie.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2024 Supra. use aptos_gas_schedule::gas_params::natives::aptos_framework::{ diff --git a/aptos-move/framework/src/natives/rlp.rs b/aptos-move/framework/src/natives/rlp.rs index 413bb9cf867..9f650350766 100644 --- a/aptos-move/framework/src/natives/rlp.rs +++ b/aptos-move/framework/src/natives/rlp.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2024 Supra. use aptos_gas_schedule::gas_params::natives::aptos_framework::{ diff --git a/aptos-move/framework/src/natives/transaction_context.rs b/aptos-move/framework/src/natives/transaction_context.rs index 9dbc0b189ec..465813c0647 100644 --- a/aptos-move/framework/src/natives/transaction_context.rs +++ b/aptos-move/framework/src/natives/transaction_context.rs @@ -378,6 +378,35 @@ fn get_user_transaction_context_opt_from_context<'a>( .user_transaction_context_opt } +/*************************************************************************************************** + * native fun get_transaction_consensus_hash_internal + * + * gas cost: base_cost + * + * Returns the Keccak-256 hash of the current signed transaction (transaction_consensus_hash). + * Aborts if called outside a user transaction context (e.g. system or view sessions). + * + **************************************************************************************************/ +fn native_get_transaction_consensus_hash_internal( + context: &mut SafeNativeContext, + _ty_args: Vec, + _args: VecDeque, +) -> SafeNativeResult> { + + context.charge(TRANSACTION_CONTEXT_GET_TXN_CONSENSUS_HASH_BASE)?; + + let user_transaction_context_opt = get_user_transaction_context_opt_from_context(context); + if let Some(txn_context) = user_transaction_context_opt { + Ok(smallvec![Value::vector_u8( + txn_context.txn_consensus_hash().to_vec() + )]) + } else { + Err(SafeNativeError::Abort { + abort_code: error::invalid_state(abort_codes::ETRANSACTION_CONTEXT_NOT_AVAILABLE), + }) + } +} + /*************************************************************************************************** * module * @@ -406,6 +435,10 @@ pub fn make_all( "multisig_payload_internal", native_multisig_payload_internal, ), + ( + "get_transaction_consensus_hash_internal", + native_get_transaction_consensus_hash_internal, + ), ]; builder.make_named_natives(natives) diff --git a/aptos-move/framework/supra-framework/doc/automation_registry.md b/aptos-move/framework/supra-framework/doc/automation_registry.md index c69be63dd5f..5114cfff982 100644 --- a/aptos-move/framework/supra-framework/doc/automation_registry.md +++ b/aptos-move/framework/supra-framework/doc/automation_registry.md @@ -42,6 +42,7 @@ This contract is part of the Supra Framework and is designed to manage automated - [Struct `TaskCancelledInsufficentBalanceV2`](#0x1_automation_registry_TaskCancelledInsufficentBalanceV2) - [Struct `TaskCancelledCapacitySurpassed`](#0x1_automation_registry_TaskCancelledCapacitySurpassed) - [Struct `TaskCancelledCapacitySurpassedV2`](#0x1_automation_registry_TaskCancelledCapacitySurpassedV2) +- [Struct `TaskCancelledByRuntime`](#0x1_automation_registry_TaskCancelledByRuntime) - [Struct `RemovedTasks`](#0x1_automation_registry_RemovedTasks) - [Struct `ActiveTasks`](#0x1_automation_registry_ActiveTasks) - [Struct `ErrorTaskDoesNotExist`](#0x1_automation_registry_ErrorTaskDoesNotExist) @@ -107,7 +108,9 @@ This contract is part of the Supra Framework and is designed to manage automated - [Function `grant_authorization`](#0x1_automation_registry_grant_authorization) - [Function `revoke_authorization`](#0x1_automation_registry_revoke_authorization) - [Function `cancel_task`](#0x1_automation_registry_cancel_task) +- [Function `stop_tasks_internal`](#0x1_automation_registry_stop_tasks_internal) - [Function `stop_tasks`](#0x1_automation_registry_stop_tasks) +- [Function `cancel_invalid_task`](#0x1_automation_registry_cancel_invalid_task) - [Function `stop_system_tasks`](#0x1_automation_registry_stop_system_tasks) - [Function `cancel_system_task`](#0x1_automation_registry_cancel_system_task) - [Function `initialize_refund_bookkeeping_resource`](#0x1_automation_registry_initialize_refund_bookkeeping_resource) @@ -116,7 +119,9 @@ This contract is part of the Supra Framework and is designed to manage automated - [Function `monitor_cycle_end`](#0x1_automation_registry_monitor_cycle_end) - [Function `on_new_epoch`](#0x1_automation_registry_on_new_epoch) - [Function `register`](#0x1_automation_registry_register) +- [Function `register_without_validation`](#0x1_automation_registry_register_without_validation) - [Function `register_system_task`](#0x1_automation_registry_register_system_task) +- [Function `register_system_task_without_validation`](#0x1_automation_registry_register_system_task_without_validation) - [Function `process_tasks`](#0x1_automation_registry_process_tasks) - [Function `on_cycle_transition`](#0x1_automation_registry_on_cycle_transition) - [Function `on_cycle_suspend`](#0x1_automation_registry_on_cycle_suspend) @@ -187,6 +192,7 @@ This contract is part of the Supra Framework and is designed to manage automated use 0x1::supra_coin; use 0x1::system_addresses; use 0x1::timestamp; +use 0x1::transaction_context; use 0x1::vector; use 0x1::vector_utils;
@@ -1813,6 +1819,57 @@ Event emitted when an automation task is cancelled due to automation fee capacit + + + + +## Struct `TaskCancelledByRuntime` + +Emitted when the VM/runtime cancels a task that was registered without payload +validation and was later found to be invalid. The diagnostic_message is a +human-readable explanation provided by the runtime (e.g. BCS decode error, unknown +entry function). Consumers should use this event -- rather than TasksStoppedV2 alone -- +to distinguish runtime-driven cancellations from voluntary owner-initiated stops. + + +
#[event]
+struct TaskCancelledByRuntime has drop, store
+
+ + + +
+Fields + + +
+
+task_index: u64 +
+
+ +
+
+owner: address +
+
+ +
+
+registration_hash: vector<u8> +
+
+ +
+
+diagnostic_message: string::String +
+
+ +
+
+ +
@@ -2559,6 +2616,17 @@ Supra native automation feature is not initialized or enabled + + +Supra automation v2.1 feature is not enabled. Distinct from EDISABLED_AUTOMATION_FEATURE +(which covers the base automation feature) so callers can tell the two conditions apart. + + +
const EDISABLED_AUTOMATION_V2_1_FEATURE: u64 = 49;
+
+ + + Task index list is empty. @@ -4685,18 +4753,19 @@ Committed gas-limit is updated by reducing it with the max-gas-amount of the can - + -## Function `stop_tasks` +## Function `stop_tasks_internal` -Immediately stops automation tasks for the specified task_indexes. -Only tasks that exist and are owned by the sender can be stopped. -If any of the specified tasks are not owned by the sender, the transaction will abort. -When a task is stopped, the committed gas for the next epoch is reduced -by the max gas amount of the stopped task. Half of the remaining task fee is refunded. +Core logic for immediately stopping a set of user automation tasks owned by owner. +Extracted from the public entry stop_tasks so the same refund-and-removal path can be +reused by the VM-only cancel_invalid_task without requiring a signer from the owner. +Callers are responsible for ensuring owner is the legitimate task owner before calling; +the per-task ownership assert inside this function provides a defence-in-depth check. -
public entry fun stop_tasks(owner_signer: &signer, task_indexes: vector<u64>)
+
+
fun stop_tasks_internal(owner: address, task_indexes: vector<u64>)
 
@@ -4705,8 +4774,8 @@ by the max gas amount of the stopped task. Half of the remaining task fee is ref Implementation -
public entry fun stop_tasks(
-    owner_signer: &signer,
+
fun stop_tasks_internal(
+    owner: address,
     task_indexes: vector<u64>
 ) acquires AutomationRegistryV2, ActiveAutomationRegistryConfigV2, AutomationCycleDetails, AutomationRefundBookkeeping {
     assert!(features::supra_native_automation_enabled(), EDISABLED_AUTOMATION_FEATURE);
@@ -4715,7 +4784,6 @@ by the max gas amount of the stopped task. Half of the remaining task fee is ref
     // Ensure that task indexes are provided
     assert!(!vector::is_empty(&task_indexes), EEMPTY_TASK_INDEXES);
 
-    let owner = signer::address_of(owner_signer);
     let automation_registry = &mut borrow_global_mut<AutomationRegistryV2>(@supra_framework).main;
     let arc = borrow_global<ActiveAutomationRegistryConfigV2>(@supra_framework).main_config;
     let refund_bookkeeping = borrow_global_mut<AutomationRefundBookkeeping>(@supra_framework);
@@ -4827,6 +4895,110 @@ by the max gas amount of the stopped task. Half of the remaining task fee is ref
 
 
 
+
+
+
+
+## Function `stop_tasks`
+
+Immediately stops automation tasks for the specified task_indexes.
+Only tasks that exist and are owned by the sender can be stopped.
+If any of the specified tasks are not owned by the sender, the transaction will abort.
+When a task is stopped, the committed gas for the next epoch is reduced
+by the max gas amount of the stopped task. Half of the remaining task fee is refunded.
+
+
+
public entry fun stop_tasks(owner_signer: &signer, task_indexes: vector<u64>)
+
+ + + +
+Implementation + + +
public entry fun stop_tasks(
+    owner_signer: &signer,
+    task_indexes: vector<u64>
+) acquires AutomationRegistryV2, ActiveAutomationRegistryConfigV2, AutomationCycleDetails, AutomationRefundBookkeeping {
+    stop_tasks_internal(signer::address_of(owner_signer), task_indexes)
+}
+
+ + + +
+ + + +## Function `cancel_invalid_task` + +Cancels a single automation task that the runtime has determined to be invalid. +May only be called by the VM (enforced via system_addresses::assert_vm). + +This is the runtime-side remedy for tasks registered through +register_without_validation: because that path skips BCS/entry-function checks, +a malformed payload may reach the scheduler and fail repeatedly. The runtime calls +this function to remove the task immediately, refund the owner in full (same policy +as a voluntary stop_tasks call), and emit a diagnostic event so the owner can see +why the task was cancelled. + +Two events are emitted: +- TasksStoppedV2 (fee refund amounts, via stop_tasks_internal) +- TaskCancelledByRuntime (task identity + human-readable diagnostic message) + + +
fun cancel_invalid_task(vm: signer, task_index: u64, diagnostic_message: string::String)
+
+ + + +
+Implementation + + +
fun cancel_invalid_task(
+    vm: signer,
+    task_index: u64,
+    diagnostic_message: std::string::String,
+) acquires AutomationRegistryV2, ActiveAutomationRegistryConfigV2, AutomationCycleDetails, AutomationRefundBookkeeping {
+    // Guard: only the VM may trigger runtime cancellation.
+    system_addresses::assert_vm(&vm);
+
+    // Read owner address and registration hash before the mutable borrow inside
+    // stop_tasks_internal. AutomationTaskMetaData has `copy` ability, so
+    // enumerable_map::get_value returns an owned copy -- no live reference survives
+    // this block, allowing the subsequent mutable borrow to proceed without conflict.
+    let owner;
+    let registration_hash;
+    {
+        let automation_registry = borrow_global<AutomationRegistryV2>(@supra_framework);
+        assert!(
+            enumerable_map::contains(&automation_registry.main.tasks, task_index),
+            EAUTOMATION_TASK_NOT_FOUND
+        );
+        let task = enumerable_map::get_value(&automation_registry.main.tasks, task_index);
+        owner = task.owner;
+        registration_hash = task.tx_hash;
+    };
+
+    // Perform the full refund and removal -- same path as a voluntary stop_tasks call.
+    // Also emits TasksStoppedV2 with the per-task fee detail.
+    stop_tasks_internal(owner, vector[task_index]);
+
+    // Emit the runtime-specific event so indexers/explorers can surface the diagnostic
+    // message to the owner rather than showing only an unexplained stop.
+    event::emit(TaskCancelledByRuntime {
+        task_index,
+        owner,
+        registration_hash,
+        diagnostic_message,
+    });
+}
+
+ + +
@@ -5447,6 +5619,62 @@ Registers a new automation task entry. + + + + +## Function `register_without_validation` + +Registers a new automation task from a smart contract call. + +Unlike the AutomationRegistrationPayload transaction path (which calls the private +register via the VM and performs full payload validation before execution), this +function does NOT validate that payload_tx encodes a well-formed entry function with +correct parameter types. If the payload is malformed, the task will fail silently at +execution time and the caller will have paid registration and deposit fees for nothing. +The caller is responsible for providing a valid BCS-encoded EntryFunction payload. + +The required consenus hash of the transaciton registering the task is obtained from native +layer. + +Requires both supra_native_automation_enabled and supra_automation_v2_1_enabled. + + +
public fun register_without_validation(owner_signer: &signer, payload_tx: vector<u8>, expiry_time: u64, max_gas_amount: u64, gas_price_cap: u64, automation_fee_cap_for_epoch: u64, aux_data: vector<vector<u8>>)
+
+ + + +
+Implementation + + +
public fun register_without_validation(
+    owner_signer: &signer,
+    payload_tx: vector<u8>,
+    expiry_time: u64,
+    max_gas_amount: u64,
+    gas_price_cap: u64,
+    automation_fee_cap_for_epoch: u64,
+    aux_data: vector<vector<u8>>
+) acquires AutomationRegistryV2, AutomationCycleDetails, ActiveAutomationRegistryConfigV2, AutomationRefundBookkeeping {
+    assert!(features::supra_automation_v2_1_enabled(), EDISABLED_AUTOMATION_V2_1_FEATURE);
+    let tx_hash = supra_framework::transaction_context::get_transaction_consensus_hash();
+    register(
+        owner_signer,
+        payload_tx,
+        expiry_time,
+        max_gas_amount,
+        gas_price_cap,
+        automation_fee_cap_for_epoch,
+        tx_hash,
+        aux_data,
+    )
+}
+
+ + +
@@ -5548,6 +5776,58 @@ Note, system tasks are not charged registration and deposit fee. + + + + +## Function `register_system_task_without_validation` + +Registers a new system automation task from a smart contract call. + +Unlike the AutomationRegistrationPayload transaction path (which calls the private +register_system_task via the VM and performs full payload validation before execution), this +function does NOT validate that payload_tx encodes a well-formed entry function with +correct parameter types. If the payload is malformed, the task will fail silently at +execution time and the caller will have paid registration and deposit fees for nothing. +The caller is responsible for providing a valid BCS-encoded EntryFunction payload. + +The required consenus hash of the transaciton registering the task is obtained from native +layer. + +Requires both supra_native_automation_enabled and supra_automation_v2_1_enabled. + + +
public fun register_system_task_without_validation(owner_signer: &signer, payload_tx: vector<u8>, expiry_time: u64, max_gas_amount: u64, aux_data: vector<vector<u8>>)
+
+ + + +
+Implementation + + +
public fun register_system_task_without_validation(
+    owner_signer: &signer,
+    payload_tx: vector<u8>,
+    expiry_time: u64,
+    max_gas_amount: u64,
+    aux_data: vector<vector<u8>>
+) acquires AutomationRegistryV2, AutomationCycleDetails, ActiveAutomationRegistryConfigV2 {
+    assert!(features::supra_automation_v2_1_enabled(), EDISABLED_AUTOMATION_V2_1_FEATURE);
+    let tx_hash = supra_framework::transaction_context::get_transaction_consensus_hash();
+    register_system_task(
+        owner_signer,
+        payload_tx,
+        expiry_time,
+        max_gas_amount,
+        tx_hash,
+        aux_data,
+    )
+}
+
+ + +
diff --git a/aptos-move/framework/supra-framework/doc/evm_config.md b/aptos-move/framework/supra-framework/doc/evm_config.md index 266294bb013..9644b3bb39b 100644 --- a/aptos-move/framework/supra-framework/doc/evm_config.md +++ b/aptos-move/framework/supra-framework/doc/evm_config.md @@ -5,33 +5,41 @@ -- [Resource `EvmConfig`](#0x1_evm_config_EvmConfig) +- [Resource `EvmContractsDetails`](#0x1_evm_config_EvmContractsDetails) +- [Resource `EvmScalarConfig`](#0x1_evm_config_EvmScalarConfig) - [Constants](#@Constants_0) - [Function `initialize`](#0x1_evm_config_initialize) -- [Function `set_for_next_epoch`](#0x1_evm_config_set_for_next_epoch) +- [Function `upsert_evm_contract_details_for_next_epoch`](#0x1_evm_config_upsert_evm_contract_details_for_next_epoch) +- [Function `upsert_config_for_next_epoch`](#0x1_evm_config_upsert_config_for_next_epoch) +- [Function `get_contract_value`](#0x1_evm_config_get_contract_value) +- [Function `get_scalar_config_value`](#0x1_evm_config_get_scalar_config_value) +- [Function `validate_scalar_config`](#0x1_evm_config_validate_scalar_config) +- [Function `is_valid_evm_address`](#0x1_evm_config_is_valid_evm_address) - [Function `on_new_epoch`](#0x1_evm_config_on_new_epoch) -- [Specification](#@Specification_1) - - [Function `initialize`](#@Specification_1_initialize) - - [Function `set_for_next_epoch`](#@Specification_1_set_for_next_epoch) - - [Function `on_new_epoch`](#@Specification_1_on_new_epoch) -
use 0x1::config_buffer;
+
use 0x1::bcs;
+use 0x1::config_buffer;
 use 0x1::error;
+use 0x1::event;
+use 0x1::option;
+use 0x1::signer;
+use 0x1::simple_map;
+use 0x1::string;
 use 0x1::system_addresses;
 use 0x1::vector;
 
- + -## Resource `EvmConfig` +## Resource `EvmContractsDetails` -The struct stores the on-chain EVM configuration. -
struct EvmConfig has drop, store, key
+
#[event]
+struct EvmContractsDetails has copy, drop, store, key
 
@@ -42,7 +50,35 @@ The struct stores the on-chain EVM configuration.
-config: vector<u8> +details: simple_map::SimpleMap<string::String, address> +
+
+ +
+
+ + + + + + +## Resource `EvmScalarConfig` + + + +
#[event]
+struct EvmScalarConfig has copy, drop, store, key
+
+ + + +
+Fields + + +
+
+config: simple_map::SimpleMap<string::String, u128>
@@ -57,12 +93,132 @@ The struct stores the on-chain EVM configuration. ## Constants - + + +Requested key does not exist in the map + + +
const EKEY_NOT_FOUND: u64 = 4;
+
+ + + + + +Supra EVM Gas Estimate Margin + + +
const CONFIG_KEY_EVM_GAS_ESTIMATE_MARGIN: vector<u8> = [101, 118, 109, 95, 103, 97, 115, 95, 101, 115, 116, 105, 109, 97, 116, 101, 95, 109, 97, 114, 103, 105, 110];
+
+ + + + + +Well-known config key for the EVM gas normalisation denominator. +This u64 value is used to scale EVM gas units into Supra gas units. + + +
const CONFIG_KEY_EVM_GAS_NORMALIZATION_DENOM: vector<u8> = [101, 118, 109, 95, 103, 97, 115, 95, 110, 111, 114, 109, 97, 108, 105, 122, 97, 116, 105, 111, 110, 95, 100, 101, 110, 111, 109];
+
+ + + + + +Empty keys/values to update config. + + +
const EEMPTY_DATA: u64 = 1;
+
+ + + + + +gas used ratio cannot exceed decimal precision + + +
const EGAS_USED_RATIO_CANNOT_EXCEED_DECIMAL_PRECISION: u64 = 7;
+
+ + + + + +Invalid EVM address, valid EVM address must fit in 20 bytes + + +
const EINVALID_EVM_ADDRESS: u64 = 3;
+
+ + + + + +Input keys and values should have the same amount of data + + +
const EKEYS_VALUES_MISMATCH: u64 = 2;
+
-The provided on chain config bytes are empty or invalid -
const EINVALID_CONFIG: u64 = 1;
+
+
+Required Key is missing or value type is incorrect for a key
+
+
+
const EMISSING_KEY_OR_INCORRECT_VAL_TYPE: u64 = 5;
+
+ + + + + +Resource already exist at address + + +
const ERESOURCE_ALREADY_EXISTS: u64 = 6;
+
+ + + + + +Evm and Move address length + + +
const EVM_ADDRESS_BYTE_LENGTH: u64 = 20;
+
+ + + + + + + +
const MOVE_ADDRESS_BYTE_LENGTH: u64 = 32;
+
+ + + + + +Supra EVM Gas Used Ratio + + +
const SUPRA_EVM_GAS_USED_RATIO: vector<u8> = [101, 118, 109, 95, 103, 97, 115, 95, 117, 115, 101, 100, 95, 114, 97, 116, 105, 111];
+
+ + + + + +DECIMAL_PRECISION + + +
const SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION: vector<u8> = [101, 118, 109, 95, 103, 97, 115, 95, 117, 115, 101, 100, 95, 114, 97, 116, 105, 111, 95, 100, 101, 99, 105, 109, 97, 108, 95, 112, 114, 101, 99, 105, 115, 105, 111, 110];
 
@@ -71,10 +227,14 @@ The provided on chain config bytes are empty or invalid ## Function `initialize` -Publishes the EvmConfig config. +Publishes both the EVM contract address map and the scalar config map. +contract_keys/contract_values must be the same length and every address +must be a valid 20-byte EVM address (upper 12 bytes of the 32-byte Move +address must be zero). config_keys/config_values must be the same +length and must include all required keys (e.g. evm_gas_normalization_denom). -
public(friend) fun initialize(supra_framework: &signer, config: vector<u8>)
+
public(friend) fun initialize(supra_framework: &signer, contract_keys: vector<string::String>, contract_values: vector<address>, config_keys: vector<string::String>, config_values: vector<u128>)
 
@@ -83,10 +243,45 @@ Publishes the EvmConfig config. Implementation -
public(friend) fun initialize(supra_framework: &signer, config: vector<u8>) {
+
public(friend) fun initialize(
+    supra_framework: &signer,
+    contract_keys: vector<String>,
+    contract_values: vector<address>,
+    config_keys: vector<String>,
+    config_values: vector<u128>
+) {
     system_addresses::assert_supra_framework(supra_framework);
-    assert!(!vector::is_empty(&config), error::invalid_argument(EINVALID_CONFIG));
-    move_to(supra_framework, EvmConfig { config });
+    assert!(!vector::is_empty(&contract_keys), error::invalid_argument(EEMPTY_DATA));
+    assert!(!vector::is_empty(&config_keys), error::invalid_argument(EEMPTY_DATA));
+    let supra_framework_addr = signer::address_of(supra_framework);
+    assert!(!exists<EvmContractsDetails>(supra_framework_addr),error::invalid_state(ERESOURCE_ALREADY_EXISTS));
+    assert!(!exists<EvmScalarConfig>(supra_framework_addr),error::invalid_state(ERESOURCE_ALREADY_EXISTS));
+    assert!(
+        vector::length(&contract_keys) == vector::length(&contract_values),
+        error::invalid_argument(EKEYS_VALUES_MISMATCH)
+    );
+    assert!(
+        vector::length(&config_keys) == vector::length(&config_values),
+        error::invalid_argument(EKEYS_VALUES_MISMATCH)
+    );
+
+    // Check that no contract value is invalid EVM address
+    let all_valid_evm_address = vector::all(&contract_values,
+    |v|{ is_valid_evm_address(v) });
+    assert!(all_valid_evm_address, error::invalid_argument(EINVALID_EVM_ADDRESS));
+
+    let contract_details = EvmContractsDetails {
+        details: simple_map::new_from(contract_keys, contract_values)
+    };
+    move_to(supra_framework, contract_details);
+    event::emit(contract_details);
+
+    let evm_config = EvmScalarConfig {
+        config: simple_map::new_from(config_keys, config_values)
+    };
+    validate_scalar_config(&evm_config);
+    move_to(supra_framework, evm_config);
+    event::emit(evm_config);
 }
 
@@ -94,19 +289,21 @@ Publishes the EvmConfig config.
- + -## Function `set_for_next_epoch` +## Function `upsert_evm_contract_details_for_next_epoch` -This can be called by on-chain governance to update on-chain evm configs for the next epoch. +This can be called by on-chain governance to update on-chain evm contract +details for the next epoch. Example usage: ``` -supra_framework::evm_config::set_for_next_epoch(&framework_signer, some_config_bytes); +supra_framework::evm_config::upsert_evm_contract_details_for_next_epoch( +&framework_signer, vector["contract1_name"], vector[contract1_address]); supra_framework::supra_governance::reconfigure(&framework_signer); ``` -
public fun set_for_next_epoch(account: &signer, config: vector<u8>)
+
public fun upsert_evm_contract_details_for_next_epoch(account: &signer, keys: vector<string::String>, values: vector<address>)
 
@@ -115,10 +312,30 @@ supra_framework::supra_governance::reconfigure(&framework_signer); Implementation -
public fun set_for_next_epoch(account: &signer, config: vector<u8>) {
+
public fun upsert_evm_contract_details_for_next_epoch(
+    account: &signer,
+    keys: vector<String>,
+    values: vector<address>
+) acquires EvmContractsDetails {
     system_addresses::assert_supra_framework(account);
-    assert!(!vector::is_empty(&config), error::invalid_argument(EINVALID_CONFIG));
-    std::config_buffer::upsert<EvmConfig>(EvmConfig {config});
+    assert!(!vector::is_empty(&keys), error::invalid_argument(EEMPTY_DATA));
+    assert!(
+        vector::length(&keys) == vector::length(&values),
+        error::invalid_argument(EKEYS_VALUES_MISMATCH)
+    );
+    let all_valid_evm_address = vector::all(&values, |v| { is_valid_evm_address(v) });
+    assert!(all_valid_evm_address, error::invalid_argument(EINVALID_EVM_ADDRESS));
+    if (!exists<EvmContractsDetails>(@supra_framework)) {
+        std::config_buffer::upsert<EvmContractsDetails>(
+            EvmContractsDetails { details: simple_map::new_from(keys, values) }
+        );
+        return
+    };
+    let updated_config = *borrow_global<EvmContractsDetails>(@supra_framework);
+    vector::zip(keys, values, |key, value| {
+        simple_map::upsert(&mut updated_config.details, key, value);
+    });
+    std::config_buffer::upsert<EvmContractsDetails>(updated_config);
 }
 
@@ -126,16 +343,21 @@ supra_framework::supra_governance::reconfigure(&framework_signer); - + -## Function `on_new_epoch` +## Function `upsert_config_for_next_epoch` -Only used in reconfigurations to apply the pending EvmConfig in buffer, if there is any. -If supra_framework has a EvmConfig, then update the new config to supra_framework. -Otherwise, move the new config to supra_framework. +This can be called by on-chain governance to update on-chain evm config +for the next epoch. Values are plain u128 scalars. +Example usage: +``` +supra_framework::evm_config::upsert_config_for_next_epoch( +&framework_signer, vector["config_key"], vector[new_value]); +supra_framework::supra_governance::reconfigure(&framework_signer); +``` -
public(friend) fun on_new_epoch(framework: &signer)
+
public fun upsert_config_for_next_epoch(account: &signer, keys: vector<string::String>, values: vector<u128>)
 
@@ -144,16 +366,35 @@ Otherwise, move the new config to supra_framework. Implementation -
public(friend) fun on_new_epoch(framework: &signer) acquires EvmConfig {
-    system_addresses::assert_supra_framework(framework);
-    if (config_buffer::does_exist<EvmConfig>()) {
-        let new_config = config_buffer::extract<EvmConfig>();
-        if (exists<EvmConfig>(@supra_framework)) {
-            *borrow_global_mut<EvmConfig>(@supra_framework) = new_config;
-        } else {
-            move_to(framework, new_config);
-        };
-    }
+
public fun upsert_config_for_next_epoch(
+    account: &signer,
+    keys: vector<String>,
+    values: vector<u128>
+) acquires EvmScalarConfig {
+    system_addresses::assert_supra_framework(account);
+    assert!(!vector::is_empty(&keys), error::invalid_argument(EEMPTY_DATA));
+    assert!(
+        vector::length(&keys) == vector::length(&values),
+        error::invalid_argument(EKEYS_VALUES_MISMATCH)
+    );
+    if (!exists<EvmScalarConfig>(@supra_framework)) {
+        let evm_config =
+            EvmScalarConfig { config: simple_map::new_from(keys, values) };
+        // Config did not exist earlier, so validate the config for
+        // presence of required keys and value type match
+        validate_scalar_config(&evm_config);
+        std::config_buffer::upsert<EvmScalarConfig>(evm_config);
+        return;
+    };
+    // Copy existing config
+    let updated_config = *borrow_global<EvmScalarConfig>(@supra_framework);
+    // We are never removing existing keys so by induction if all required
+    // keys are present in config during initialization
+    // they will be there later as well, so no need to validate here
+    vector::zip(keys, values, |key, value| {
+        simple_map::upsert(&mut updated_config.config, key, value);
+    });
+    std::config_buffer::upsert<EvmScalarConfig>(updated_config);
 }
 
@@ -161,53 +402,169 @@ Otherwise, move the new config to supra_framework. - + -## Specification +## Function `get_contract_value` +Returns the contract address stored under key in the EvmContractsDetails map. +Aborts with EKEY_NOT_FOUND if the resource has not been initialised or the key +is not present in the map. -
pragma verify = true;
-pragma aborts_if_is_strict;
+
#[view]
+public fun get_contract_value(key: string::String): address
 
- +
+Implementation + + +
public fun get_contract_value(key: String): address acquires EvmContractsDetails {
+    assert!(exists<EvmContractsDetails>(@supra_framework), error::not_found(EKEY_NOT_FOUND));
+    let details = borrow_global<EvmContractsDetails>(@supra_framework);
+    assert!(
+        simple_map::contains_key(&details.details, &key),
+        error::not_found(EKEY_NOT_FOUND)
+    );
+    *simple_map::borrow(&details.details, &key)
+}
+
+ -### Function `initialize` +
-
public(friend) fun initialize(supra_framework: &signer, config: vector<u8>)
+
+
+## Function `get_scalar_config_value`
+
+Returns the u128 value stored under key in the EvmScalarConfig map.
+Aborts with EKEY_NOT_FOUND if the resource has not been initialised or the key
+is not present in the map.
+
+
+
#[view]
+public fun get_scalar_config_value(key: string::String): u128
 
+
+Implementation -
pragma aborts_if_is_strict = false;
+
+
public fun get_scalar_config_value(key: String): u128 acquires EvmScalarConfig {
+    assert!(exists<EvmScalarConfig>(@supra_framework), error::not_found(EKEY_NOT_FOUND));
+    let config = borrow_global<EvmScalarConfig>(@supra_framework);
+    assert!(
+        simple_map::contains_key(&config.config, &key),
+        error::not_found(EKEY_NOT_FOUND)
+    );
+    *simple_map::borrow(&config.config, &key)
+}
 
- +
+ + + +## Function `validate_scalar_config` -### Function `set_for_next_epoch` -
public fun set_for_next_epoch(account: &signer, config: vector<u8>)
+
fun validate_scalar_config(evm_config: &evm_config::EvmScalarConfig)
 
+
+Implementation + -
include config_buffer::SetForNextEpochAbortsIf;
+
fun validate_scalar_config(evm_config: &EvmScalarConfig) {
+    let required_keys = vector[string::utf8(CONFIG_KEY_EVM_GAS_NORMALIZATION_DENOM),
+                               string::utf8(CONFIG_KEY_EVM_GAS_ESTIMATE_MARGIN),
+                               string::utf8(SUPRA_EVM_GAS_USED_RATIO),
+                               string::utf8(SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION)];
+    // With u128 as the value type, the Move type system prevents type mismatches at
+    // compile time. The only meaningful runtime check is key presence.
+    vector::for_each_reverse(required_keys, |rk| {
+        assert!(simple_map::contains_key(&evm_config.config, &rk),
+            error::invalid_argument(EMISSING_KEY_OR_INCORRECT_VAL_TYPE)
+        );
+        assert!(*simple_map::borrow(&evm_config.config, &rk) > 0u128, error::invalid_argument(EMISSING_KEY_OR_INCORRECT_VAL_TYPE));
+    });
+    let gas_used_ratio = *simple_map::borrow(&evm_config.config, &string::utf8(SUPRA_EVM_GAS_USED_RATIO));
+    let gas_used_ratio_decimal_precision = *simple_map::borrow(&evm_config.config, &string::utf8(SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION));
+    assert!(gas_used_ratio <= gas_used_ratio_decimal_precision, error::invalid_argument(EGAS_USED_RATIO_CANNOT_EXCEED_DECIMAL_PRECISION));
+}
 
- +
+ + + +## Function `is_valid_evm_address` + + + +
fun is_valid_evm_address(addr: &address): bool
+
-### Function `on_new_epoch` + + +
+Implementation + + +
fun is_valid_evm_address(addr: &address): bool {
+    // BCS serialises a Move `address` as a raw fixed-size 32-byte array in
+    // big-endian order (most-significant byte first).  An EVM address is only
+    // 20 bytes wide, so when a 20-byte EVM address is stored in a 32-byte Move
+    // address the EVM bytes occupy the last 20 positions (indices 12-31) and the
+    // leading 12 bytes (indices 0-11) must all be zero.
+    // We iterate only over that prefix and bail immediately on the first non-zero
+    // byte to avoid unnecessary work.
+    let evm_addr_bytes = bcs::to_bytes(addr);
+
+    // Sanity check: BCS encoding of an address is always 32 bytes. If somehow
+    // the length differs, the address cannot be valid.
+    if (vector::length(&evm_addr_bytes) != MOVE_ADDRESS_BYTE_LENGTH) {
+        return false
+    };
+
+    // Check that all 12 high-order prefix bytes are zero.  A non-zero byte here
+    // means the value cannot fit in 20 bytes and is therefore not a valid EVM address.
+    let i = 0u64;
+    let addr_length_diff = MOVE_ADDRESS_BYTE_LENGTH - EVM_ADDRESS_BYTE_LENGTH;
+    while (i < addr_length_diff) {
+        if (*vector::borrow(&evm_addr_bytes, i) != 0u8) {
+            // Non-zero prefix byte found - not a valid 20-byte EVM address.
+            return false
+        };
+        i = i + 1;
+    };
+
+    true
+}
+
+ + + +
+ + + +## Function `on_new_epoch` + +Only used in reconfigurations to apply the pending configs in buffer, if any. +If supra_framework already holds the resource, overwrite it; otherwise move it in.
public(friend) fun on_new_epoch(framework: &signer)
@@ -215,11 +572,40 @@ Otherwise, move the new config to supra_framework.
 
 
 
+
+Implementation -
requires @supra_framework == std::signer::address_of(framework);
-include config_buffer::OnNewEpochRequirement<EvmConfig>;
-aborts_if false;
+
+
public(friend) fun on_new_epoch(framework: &signer) acquires EvmScalarConfig, EvmContractsDetails {
+    system_addresses::assert_supra_framework(framework);
+    if (config_buffer::does_exist<EvmContractsDetails>()) {
+        //TODO: change to extract_v2 when extract_v2 is merged and available
+        let new_config = config_buffer::extract<EvmContractsDetails>();
+        if (!exists<EvmContractsDetails>(@supra_framework)) {
+            move_to(framework, new_config);
+        } else {
+            let old_config = borrow_global_mut<EvmContractsDetails>(@supra_framework);
+            *old_config = new_config;
+        };
+        event::emit(new_config)
+    };
+    if (config_buffer::does_exist<EvmScalarConfig>()) {
+        // change to extract_v2 when it is available
+        let new_config = config_buffer::extract<EvmScalarConfig>();
+        if (!exists<EvmScalarConfig>(@supra_framework)) {
+            move_to(framework, new_config);
+        } else {
+            let old_config = borrow_global_mut<EvmScalarConfig>(@supra_framework);
+            *old_config = new_config;
+        };
+        event::emit(new_config)
+    };
+}
 
+ +
+ + [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/supra-framework/doc/genesis.md b/aptos-move/framework/supra-framework/doc/genesis.md index 68589c74226..a3a7417e932 100644 --- a/aptos-move/framework/supra-framework/doc/genesis.md +++ b/aptos-move/framework/supra-framework/doc/genesis.md @@ -19,6 +19,7 @@ - [Function `initialize_supra_native_automation_v2`](#0x1_genesis_initialize_supra_native_automation_v2) - [Function `initialize_core_resources_and_supra_coin`](#0x1_genesis_initialize_core_resources_and_supra_coin) - [Function `initialize_evm_genesis_config`](#0x1_genesis_initialize_evm_genesis_config) +- [Function `initialize_evm_config`](#0x1_genesis_initialize_evm_config) - [Function `initialize_leader_ban_registry_config`](#0x1_genesis_initialize_leader_ban_registry_config) - [Function `create_accounts`](#0x1_genesis_create_accounts) - [Function `create_account`](#0x1_genesis_create_account) @@ -62,6 +63,7 @@ use 0x1::create_signer; use 0x1::dkg_config; use 0x1::error; +use 0x1::evm_config; use 0x1::evm_genesis_config; use 0x1::execution_config; use 0x1::features; @@ -845,6 +847,37 @@ Initialize the EVM genesis config. + + + + +## Function `initialize_evm_config` + +Initialize the EVM config. + + +
fun initialize_evm_config(supra_framework: &signer, contract_names: vector<string::String>, contract_addresses: vector<address>, config_keys: vector<string::String>, config_values: vector<u128>)
+
+ + + +
+Implementation + + +
fun initialize_evm_config(
+    supra_framework: &signer,
+    contract_names: vector<String>,
+    contract_addresses: vector<address>,
+    config_keys: vector<String>,
+    config_values: vector<u128>
+) {
+    evm_config::initialize(supra_framework, contract_names, contract_addresses, config_keys, config_values);
+}
+
+ + +
diff --git a/aptos-move/framework/supra-framework/doc/overview.md b/aptos-move/framework/supra-framework/doc/overview.md index 0bf36b9ced1..f07a02a84ae 100644 --- a/aptos-move/framework/supra-framework/doc/overview.md +++ b/aptos-move/framework/supra-framework/doc/overview.md @@ -31,6 +31,7 @@ This is the reference documentation of the Supra framework. - [`0x1::dkg_committee`](dkg_committee.md#0x1_dkg_committee) - [`0x1::dkg_config`](dkg_config.md#0x1_dkg_config) - [`0x1::event`](event.md#0x1_event) +- [`0x1::evm_config`](evm_config.md#0x1_evm_config) - [`0x1::evm_genesis_config`](evm_genesis_config.md#0x1_evm_genesis_config) - [`0x1::execution_config`](execution_config.md#0x1_execution_config) - [`0x1::function_info`](function_info.md#0x1_function_info) diff --git a/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md b/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md index d18866c7486..f894b2ba518 100644 --- a/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md +++ b/aptos-move/framework/supra-framework/doc/reconfiguration_with_dkg.md @@ -20,6 +20,7 @@ Reconfiguration with DKG helper functions. use 0x1::consensus_config; use 0x1::dkg_committee; use 0x1::dkg_config; +use 0x1::evm_config; use 0x1::evm_genesis_config; use 0x1::execution_config; use 0x1::features; @@ -177,6 +178,7 @@ Run the default reconfiguration to enter the new epoch. randomness_api_v0_config::on_new_epoch(framework); evm_genesis_config::on_new_epoch(framework); dkg_config::on_new_epoch(framework); + evm_config::on_new_epoch(framework); reconfiguration::reconfigure(); }
diff --git a/aptos-move/framework/supra-framework/doc/transaction_context.md b/aptos-move/framework/supra-framework/doc/transaction_context.md index b930357c81e..f2ea12ba1e3 100644 --- a/aptos-move/framework/supra-framework/doc/transaction_context.md +++ b/aptos-move/framework/supra-framework/doc/transaction_context.md @@ -37,6 +37,8 @@ - [Function `args`](#0x1_transaction_context_args) - [Function `multisig_payload`](#0x1_transaction_context_multisig_payload) - [Function `multisig_payload_internal`](#0x1_transaction_context_multisig_payload_internal) +- [Function `get_transaction_consensus_hash`](#0x1_transaction_context_get_transaction_consensus_hash) +- [Function `get_transaction_consensus_hash_internal`](#0x1_transaction_context_get_transaction_consensus_hash_internal) - [Function `multisig_address`](#0x1_transaction_context_multisig_address) - [Function `inner_entry_function_payload`](#0x1_transaction_context_inner_entry_function_payload) - [Specification](#@Specification_1) @@ -911,6 +913,56 @@ This function aborts if called outside of the transaction prologue, execution, o + + + + +## Function `get_transaction_consensus_hash` + +Returns the Keccak-256 hash of the current signed transaction (the transaction consensus hash). +This is distinct from get_transaction_hash(), which returns the session UUID hash. +Aborts if called outside a user transaction context. + + +
public fun get_transaction_consensus_hash(): vector<u8>
+
+ + + +
+Implementation + + +
public fun get_transaction_consensus_hash(): vector<u8> {
+    assert!(features::transaction_context_extension_enabled(), error::invalid_state(ETRANSACTION_CONTEXT_EXTENSION_NOT_ENABLED));
+    get_transaction_consensus_hash_internal()
+}
+
+ + + +
+ + + +## Function `get_transaction_consensus_hash_internal` + + + +
fun get_transaction_consensus_hash_internal(): vector<u8>
+
+ + + +
+Implementation + + +
native fun get_transaction_consensus_hash_internal(): vector<u8>;
+
+ + +
diff --git a/aptos-move/framework/supra-framework/sources/automation_registry.move b/aptos-move/framework/supra-framework/sources/automation_registry.move index 405e7859420..4bdeedad1ce 100644 --- a/aptos-move/framework/supra-framework/sources/automation_registry.move +++ b/aptos-move/framework/supra-framework/sources/automation_registry.move @@ -137,6 +137,9 @@ module supra_framework::automation_registry { const EUNKNOWN_MULTISIG_ADDRESS: u64 = 47; /// The refund fee for remaining cycle time is greater than total cycle fee for the task. const EINVALID_CYCLE_REFUND_FEE: u64 = 48; + /// Supra automation v2.1 feature is not enabled. Distinct from EDISABLED_AUTOMATION_FEATURE + /// (which covers the base automation feature) so callers can tell the two conditions apart. + const EDISABLED_AUTOMATION_V2_1_FEATURE: u64 = 49; /// The length of the transaction hash. const TXN_HASH_LENGTH: u64 = 32; @@ -639,6 +642,19 @@ module supra_framework::automation_registry { registration_hash: vector } + #[event] + /// Emitted when the VM/runtime cancels a task that was registered without payload + /// validation and was later found to be invalid. The `diagnostic_message` is a + /// human-readable explanation provided by the runtime (e.g. BCS decode error, unknown + /// entry function). Consumers should use this event -- rather than `TasksStoppedV2` alone -- + /// to distinguish runtime-driven cancellations from voluntary owner-initiated stops. + struct TaskCancelledByRuntime has drop, store { + task_index: u64, + owner: address, + registration_hash: vector, + diagnostic_message: std::string::String, + } + #[event] /// Event emitted on epoch transition containing removed task indexes. struct RemovedTasks has drop, store { @@ -1295,13 +1311,14 @@ module supra_framework::automation_registry { event::emit(TaskCancelledV2 { task_index: automation_task_metadata.task_index, owner, registration_hash: automation_task_metadata.tx_hash }); } - /// Immediately stops automation tasks for the specified `task_indexes`. - /// Only tasks that exist and are owned by the sender can be stopped. - /// If any of the specified tasks are not owned by the sender, the transaction will abort. - /// When a task is stopped, the committed gas for the next epoch is reduced - /// by the max gas amount of the stopped task. Half of the remaining task fee is refunded. - public entry fun stop_tasks( - owner_signer: &signer, + /// Core logic for immediately stopping a set of user automation tasks owned by `owner`. + /// + /// Extracted from the public entry `stop_tasks` so the same refund-and-removal path can be + /// reused by the VM-only `cancel_invalid_task` without requiring a signer from the owner. + /// Callers are responsible for ensuring `owner` is the legitimate task owner before calling; + /// the per-task ownership assert inside this function provides a defence-in-depth check. + fun stop_tasks_internal( + owner: address, task_indexes: vector ) acquires AutomationRegistryV2, ActiveAutomationRegistryConfigV2, AutomationCycleDetails, AutomationRefundBookkeeping { assert!(features::supra_native_automation_enabled(), EDISABLED_AUTOMATION_FEATURE); @@ -1310,7 +1327,6 @@ module supra_framework::automation_registry { // Ensure that task indexes are provided assert!(!vector::is_empty(&task_indexes), EEMPTY_TASK_INDEXES); - let owner = signer::address_of(owner_signer); let automation_registry = &mut borrow_global_mut(@supra_framework).main; let arc = borrow_global(@supra_framework).main_config; let refund_bookkeeping = borrow_global_mut(@supra_framework); @@ -1419,6 +1435,70 @@ module supra_framework::automation_registry { }; } + /// Immediately stops automation tasks for the specified `task_indexes`. + /// Only tasks that exist and are owned by the sender can be stopped. + /// If any of the specified tasks are not owned by the sender, the transaction will abort. + /// When a task is stopped, the committed gas for the next epoch is reduced + /// by the max gas amount of the stopped task. Half of the remaining task fee is refunded. + public entry fun stop_tasks( + owner_signer: &signer, + task_indexes: vector + ) acquires AutomationRegistryV2, ActiveAutomationRegistryConfigV2, AutomationCycleDetails, AutomationRefundBookkeeping { + stop_tasks_internal(signer::address_of(owner_signer), task_indexes) + } + + /// Cancels a single automation task that the runtime has determined to be invalid. + /// May only be called by the VM (enforced via `system_addresses::assert_vm`). + /// + /// This is the runtime-side remedy for tasks registered through + /// `register_without_validation`: because that path skips BCS/entry-function checks, + /// a malformed payload may reach the scheduler and fail repeatedly. The runtime calls + /// this function to remove the task immediately, refund the owner in full (same policy + /// as a voluntary `stop_tasks` call), and emit a diagnostic event so the owner can see + /// why the task was cancelled. + /// + /// Two events are emitted: + /// - `TasksStoppedV2` (fee refund amounts, via `stop_tasks_internal`) + /// - `TaskCancelledByRuntime` (task identity + human-readable diagnostic message) + fun cancel_invalid_task( + vm: signer, + task_index: u64, + diagnostic_message: std::string::String, + ) acquires AutomationRegistryV2, ActiveAutomationRegistryConfigV2, AutomationCycleDetails, AutomationRefundBookkeeping { + // Guard: only the VM may trigger runtime cancellation. + system_addresses::assert_vm(&vm); + + // Read owner address and registration hash before the mutable borrow inside + // stop_tasks_internal. AutomationTaskMetaData has `copy` ability, so + // enumerable_map::get_value returns an owned copy -- no live reference survives + // this block, allowing the subsequent mutable borrow to proceed without conflict. + let owner; + let registration_hash; + { + let automation_registry = borrow_global(@supra_framework); + assert!( + enumerable_map::contains(&automation_registry.main.tasks, task_index), + EAUTOMATION_TASK_NOT_FOUND + ); + let task = enumerable_map::get_value(&automation_registry.main.tasks, task_index); + owner = task.owner; + registration_hash = task.tx_hash; + }; + + // Perform the full refund and removal -- same path as a voluntary stop_tasks call. + // Also emits TasksStoppedV2 with the per-task fee detail. + stop_tasks_internal(owner, vector[task_index]); + + // Emit the runtime-specific event so indexers/explorers can surface the diagnostic + // message to the owner rather than showing only an unexplained stop. + event::emit(TaskCancelledByRuntime { + task_index, + owner, + registration_hash, + diagnostic_message, + }); + } + /// Immediately stops system automation tasks for the specified `task_indexes`. /// Only tasks that exist and are owned by the sender can be stopped. /// If any of the specified tasks are not owned by the sender, the transaction will abort. @@ -1886,6 +1966,42 @@ module supra_framework::automation_registry { event::emit(automation_task_metadata); } + /// Registers a new automation task from a smart contract call. + /// + /// Unlike the `AutomationRegistrationPayload` transaction path (which calls the private + /// `register` via the VM and performs full payload validation before execution), this + /// function does NOT validate that `payload_tx` encodes a well-formed entry function with + /// correct parameter types. If the payload is malformed, the task will fail silently at + /// execution time and the caller will have paid registration and deposit fees for nothing. + /// The caller is responsible for providing a valid BCS-encoded `EntryFunction` payload. + /// + /// The required consenus hash of the transaciton registering the task is obtained from native + /// layer. + /// + /// Requires both `supra_native_automation_enabled` and `supra_automation_v2_1_enabled`. + public fun register_without_validation( + owner_signer: &signer, + payload_tx: vector, + expiry_time: u64, + max_gas_amount: u64, + gas_price_cap: u64, + automation_fee_cap_for_epoch: u64, + aux_data: vector> + ) acquires AutomationRegistryV2, AutomationCycleDetails, ActiveAutomationRegistryConfigV2, AutomationRefundBookkeeping { + assert!(features::supra_automation_v2_1_enabled(), EDISABLED_AUTOMATION_V2_1_FEATURE); + let tx_hash = supra_framework::transaction_context::get_transaction_consensus_hash(); + register( + owner_signer, + payload_tx, + expiry_time, + max_gas_amount, + gas_price_cap, + automation_fee_cap_for_epoch, + tx_hash, + aux_data, + ) + } + /// Registers a new system automation task entry. /// Note, system tasks are not charged registration and deposit fee. fun register_system_task( @@ -1967,6 +2083,38 @@ module supra_framework::automation_registry { event::emit(automation_task_metadata); } + /// Registers a new system automation task from a smart contract call. + /// + /// Unlike the `AutomationRegistrationPayload` transaction path (which calls the private + /// `register_system_task` via the VM and performs full payload validation before execution), this + /// function does NOT validate that `payload_tx` encodes a well-formed entry function with + /// correct parameter types. If the payload is malformed, the task will fail silently at + /// execution time and the caller will have paid registration and deposit fees for nothing. + /// The caller is responsible for providing a valid BCS-encoded `EntryFunction` payload. + /// + /// The required consenus hash of the transaciton registering the task is obtained from native + /// layer. + /// + /// Requires both `supra_native_automation_enabled` and `supra_automation_v2_1_enabled`. + public fun register_system_task_without_validation( + owner_signer: &signer, + payload_tx: vector, + expiry_time: u64, + max_gas_amount: u64, + aux_data: vector> + ) acquires AutomationRegistryV2, AutomationCycleDetails, ActiveAutomationRegistryConfigV2 { + assert!(features::supra_automation_v2_1_enabled(), EDISABLED_AUTOMATION_V2_1_FEATURE); + let tx_hash = supra_framework::transaction_context::get_transaction_consensus_hash(); + register_system_task( + owner_signer, + payload_tx, + expiry_time, + max_gas_amount, + tx_hash, + aux_data, + ) + } + /// Called by MoveVm on `AutomationBookkeepingAction::Process` action emitted by native layer ahead of cycle transition fun process_tasks( diff --git a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move index 6e0019d13d0..4b97ec1cabe 100644 --- a/aptos-move/framework/supra-framework/sources/configs/config_buffer.move +++ b/aptos-move/framework/supra-framework/sources/configs/config_buffer.move @@ -19,6 +19,7 @@ module supra_framework::config_buffer { use supra_framework::system_addresses; + friend supra_framework::evm_config; friend supra_framework::evm_genesis_config; friend supra_framework::consensus_config; friend supra_framework::execution_config; diff --git a/aptos-move/framework/supra-framework/sources/configs/evm_config.move b/aptos-move/framework/supra-framework/sources/configs/evm_config.move new file mode 100644 index 00000000000..a17464e9120 --- /dev/null +++ b/aptos-move/framework/supra-framework/sources/configs/evm_config.move @@ -0,0 +1,484 @@ +module supra_framework::evm_config { + + use std::error; + use std::signer; + use std::string::{Self,String}; + use std::vector; + use aptos_std::simple_map; + use aptos_std::simple_map::SimpleMap; + use aptos_std::bcs; + use supra_framework::config_buffer; + use supra_framework::event; + use supra_framework::system_addresses; + + friend supra_framework::genesis; + friend supra_framework::reconfiguration_with_dkg; + + /// Empty keys/values to update config. + const EEMPTY_DATA: u64 = 1; + + /// Input keys and values should have the same amount of data + const EKEYS_VALUES_MISMATCH: u64 = 2; + + /// Invalid EVM address, valid EVM address must fit in 20 bytes + const EINVALID_EVM_ADDRESS: u64 = 3; + + /// Requested key does not exist in the map + const EKEY_NOT_FOUND: u64 = 4; + + /// Required Key is missing or value type is incorrect for a key + const EMISSING_KEY_OR_INCORRECT_VAL_TYPE: u64 = 5; + + /// Resource already exist at address + const ERESOURCE_ALREADY_EXISTS: u64 = 6; + + /// gas used ratio cannot exceed decimal precision + const EGAS_USED_RATIO_CANNOT_EXCEED_DECIMAL_PRECISION: u64 = 7; + + /// Well-known config key for the EVM gas normalisation denominator. + /// This u64 value is used to scale EVM gas units into Supra gas units. + const CONFIG_KEY_EVM_GAS_NORMALIZATION_DENOM: vector = b"evm_gas_normalization_denom"; + + /// Supra EVM Gas Estimate Margin + const CONFIG_KEY_EVM_GAS_ESTIMATE_MARGIN: vector = b"evm_gas_estimate_margin"; + + /// Supra EVM Gas Used Ratio + const SUPRA_EVM_GAS_USED_RATIO : vector = b"evm_gas_used_ratio"; + + /// DECIMAL_PRECISION + const SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION: vector = b"evm_gas_used_ratio_decimal_precision"; + + /// Evm and Move address length + const EVM_ADDRESS_BYTE_LENGTH : u64 = 20; + const MOVE_ADDRESS_BYTE_LENGTH: u64 = 32; + + #[event] + struct EvmContractsDetails has key, copy, store, drop { + details: SimpleMap, + } + + /// key-value map of EVM scalar config parameters. + /// Values are plain u128 integers; the Move type system enforces type safety + /// at compile time, eliminating the need for self-describing Any wrappers. + #[event] + struct EvmScalarConfig has key, copy, store, drop { + config: SimpleMap + } + + /// Publishes both the EVM contract address map and the scalar config map. + /// `contract_keys`/`contract_values` must be the same length and every address + /// must be a valid 20-byte EVM address (upper 12 bytes of the 32-byte Move + /// address must be zero). `config_keys`/`config_values` must be the same + /// length and must include all required keys (e.g. evm_gas_normalization_denom). + public(friend) fun initialize( + supra_framework: &signer, + contract_keys: vector, + contract_values: vector
, + config_keys: vector, + config_values: vector + ) { + system_addresses::assert_supra_framework(supra_framework); + assert!(!vector::is_empty(&contract_keys), error::invalid_argument(EEMPTY_DATA)); + assert!(!vector::is_empty(&config_keys), error::invalid_argument(EEMPTY_DATA)); + let supra_framework_addr = signer::address_of(supra_framework); + assert!(!exists(supra_framework_addr),error::invalid_state(ERESOURCE_ALREADY_EXISTS)); + assert!(!exists(supra_framework_addr),error::invalid_state(ERESOURCE_ALREADY_EXISTS)); + assert!( + vector::length(&contract_keys) == vector::length(&contract_values), + error::invalid_argument(EKEYS_VALUES_MISMATCH) + ); + assert!( + vector::length(&config_keys) == vector::length(&config_values), + error::invalid_argument(EKEYS_VALUES_MISMATCH) + ); + + // Check that no contract value is invalid EVM address + let all_valid_evm_address = vector::all(&contract_values, + |v|{ is_valid_evm_address(v) }); + assert!(all_valid_evm_address, error::invalid_argument(EINVALID_EVM_ADDRESS)); + + let contract_details = EvmContractsDetails { + details: simple_map::new_from(contract_keys, contract_values) + }; + move_to(supra_framework, contract_details); + event::emit(contract_details); + + let evm_config = EvmScalarConfig { + config: simple_map::new_from(config_keys, config_values) + }; + validate_scalar_config(&evm_config); + move_to(supra_framework, evm_config); + event::emit(evm_config); + } + + /// This can be called by on-chain governance to update on-chain evm contract + /// details for the next epoch. + /// Example usage: + /// ``` + /// supra_framework::evm_config::upsert_evm_contract_details_for_next_epoch( + /// &framework_signer, vector["contract1_name"], vector[contract1_address]); + /// supra_framework::supra_governance::reconfigure(&framework_signer); + /// ``` + public fun upsert_evm_contract_details_for_next_epoch( + account: &signer, + keys: vector, + values: vector
+ ) acquires EvmContractsDetails { + system_addresses::assert_supra_framework(account); + assert!(!vector::is_empty(&keys), error::invalid_argument(EEMPTY_DATA)); + assert!( + vector::length(&keys) == vector::length(&values), + error::invalid_argument(EKEYS_VALUES_MISMATCH) + ); + let all_valid_evm_address = vector::all(&values, |v| { is_valid_evm_address(v) }); + assert!(all_valid_evm_address, error::invalid_argument(EINVALID_EVM_ADDRESS)); + if (!exists(@supra_framework)) { + std::config_buffer::upsert( + EvmContractsDetails { details: simple_map::new_from(keys, values) } + ); + return + }; + let updated_config = *borrow_global(@supra_framework); + vector::zip(keys, values, |key, value| { + simple_map::upsert(&mut updated_config.details, key, value); + }); + std::config_buffer::upsert(updated_config); + } + + /// This can be called by on-chain governance to update on-chain evm config + /// for the next epoch. Values are plain u128 scalars. + /// Example usage: + /// ``` + /// supra_framework::evm_config::upsert_config_for_next_epoch( + /// &framework_signer, vector["config_key"], vector[new_value]); + /// supra_framework::supra_governance::reconfigure(&framework_signer); + /// ``` + public fun upsert_config_for_next_epoch( + account: &signer, + keys: vector, + values: vector + ) acquires EvmScalarConfig { + system_addresses::assert_supra_framework(account); + assert!(!vector::is_empty(&keys), error::invalid_argument(EEMPTY_DATA)); + assert!( + vector::length(&keys) == vector::length(&values), + error::invalid_argument(EKEYS_VALUES_MISMATCH) + ); + if (!exists(@supra_framework)) { + let evm_config = + EvmScalarConfig { config: simple_map::new_from(keys, values) }; + // Config did not exist earlier, so validate the config for + // presence of required keys and value type match + validate_scalar_config(&evm_config); + std::config_buffer::upsert(evm_config); + return; + }; + // Copy existing config + let updated_config = *borrow_global(@supra_framework); + // We are never removing existing keys so by induction if all required + // keys are present in config during initialization + // they will be there later as well, so no need to validate here + vector::zip(keys, values, |key, value| { + simple_map::upsert(&mut updated_config.config, key, value); + }); + std::config_buffer::upsert(updated_config); + } + + #[view] + /// Returns the contract address stored under `key` in the EvmContractsDetails map. + /// Aborts with EKEY_NOT_FOUND if the resource has not been initialised or the key + /// is not present in the map. + public fun get_contract_value(key: String): address acquires EvmContractsDetails { + assert!(exists(@supra_framework), error::not_found(EKEY_NOT_FOUND)); + let details = borrow_global(@supra_framework); + assert!( + simple_map::contains_key(&details.details, &key), + error::not_found(EKEY_NOT_FOUND) + ); + *simple_map::borrow(&details.details, &key) + } + + #[view] + /// Returns the u128 value stored under `key` in the EvmScalarConfig map. + /// Aborts with EKEY_NOT_FOUND if the resource has not been initialised or the key + /// is not present in the map. + public fun get_scalar_config_value(key: String): u128 acquires EvmScalarConfig { + assert!(exists(@supra_framework), error::not_found(EKEY_NOT_FOUND)); + let config = borrow_global(@supra_framework); + assert!( + simple_map::contains_key(&config.config, &key), + error::not_found(EKEY_NOT_FOUND) + ); + *simple_map::borrow(&config.config, &key) + } + + fun validate_scalar_config(evm_config: &EvmScalarConfig) { + let required_keys = vector[string::utf8(CONFIG_KEY_EVM_GAS_NORMALIZATION_DENOM), + string::utf8(CONFIG_KEY_EVM_GAS_ESTIMATE_MARGIN), + string::utf8(SUPRA_EVM_GAS_USED_RATIO), + string::utf8(SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION)]; + // With u128 as the value type, the Move type system prevents type mismatches at + // compile time. The only meaningful runtime check is key presence. + vector::for_each_reverse(required_keys, |rk| { + assert!(simple_map::contains_key(&evm_config.config, &rk), + error::invalid_argument(EMISSING_KEY_OR_INCORRECT_VAL_TYPE) + ); + assert!(*simple_map::borrow(&evm_config.config, &rk) > 0u128, error::invalid_argument(EMISSING_KEY_OR_INCORRECT_VAL_TYPE)); + }); + let gas_used_ratio = *simple_map::borrow(&evm_config.config, &string::utf8(SUPRA_EVM_GAS_USED_RATIO)); + let gas_used_ratio_decimal_precision = *simple_map::borrow(&evm_config.config, &string::utf8(SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION)); + assert!(gas_used_ratio <= gas_used_ratio_decimal_precision, error::invalid_argument(EGAS_USED_RATIO_CANNOT_EXCEED_DECIMAL_PRECISION)); + } + + fun is_valid_evm_address(addr: &address): bool { + // BCS serialises a Move `address` as a raw fixed-size 32-byte array in + // big-endian order (most-significant byte first). An EVM address is only + // 20 bytes wide, so when a 20-byte EVM address is stored in a 32-byte Move + // address the EVM bytes occupy the last 20 positions (indices 12-31) and the + // leading 12 bytes (indices 0-11) must all be zero. + // We iterate only over that prefix and bail immediately on the first non-zero + // byte to avoid unnecessary work. + let evm_addr_bytes = bcs::to_bytes(addr); + + // Sanity check: BCS encoding of an address is always 32 bytes. If somehow + // the length differs, the address cannot be valid. + if (vector::length(&evm_addr_bytes) != MOVE_ADDRESS_BYTE_LENGTH) { + return false + }; + + // Check that all 12 high-order prefix bytes are zero. A non-zero byte here + // means the value cannot fit in 20 bytes and is therefore not a valid EVM address. + let i = 0u64; + let addr_length_diff = MOVE_ADDRESS_BYTE_LENGTH - EVM_ADDRESS_BYTE_LENGTH; + while (i < addr_length_diff) { + if (*vector::borrow(&evm_addr_bytes, i) != 0u8) { + // Non-zero prefix byte found - not a valid 20-byte EVM address. + return false + }; + i = i + 1; + }; + + true + } + + /// Only used in reconfigurations to apply the pending configs in buffer, if any. + /// If supra_framework already holds the resource, overwrite it; otherwise move it in. + public(friend) fun on_new_epoch(framework: &signer) acquires EvmScalarConfig, EvmContractsDetails { + system_addresses::assert_supra_framework(framework); + if (config_buffer::does_exist()) { + //TODO: change to extract_v2 when extract_v2 is merged and available + let new_config = config_buffer::extract(); + if (!exists(@supra_framework)) { + move_to(framework, new_config); + } else { + let old_config = borrow_global_mut(@supra_framework); + *old_config = new_config; + }; + event::emit(new_config) + }; + if (config_buffer::does_exist()) { + // change to extract_v2 when it is available + let new_config = config_buffer::extract(); + if (!exists(@supra_framework)) { + move_to(framework, new_config); + } else { + let old_config = borrow_global_mut(@supra_framework); + *old_config = new_config; + }; + event::emit(new_config) + }; + } + + // ------------------------------------------------------------------------- + // Tests + // ------------------------------------------------------------------------- + + #[test] + /// Verifies that a small address value (@0x1) is accepted as a valid EVM address. + /// + /// @0x1 is the 256-bit integer 1. BCS serialises a Move address as a raw + /// big-endian 32-byte array, so the most-significant byte is at index 0 and the + /// least-significant byte (0x01) is at index 31. The 12 leading bytes + /// (indices 0-11) are therefore all zero, and the function must return true. + fun test_valid_evm_address_small_value() { + // BCS big-endian layout for @0x1 (32 bytes): + // index 0 : 0x00 + // ... + // index 30 : 0x00 + // index 31 : 0x01 + // Leading bytes 0-11 are all 0x00 -> valid 20-byte EVM address. + assert!(is_valid_evm_address(&@0x1), 0); + } + + #[test] + /// Verifies that a full 32-byte address is rejected as an invalid EVM address. + /// + /// @0x1000...000 (64 hex digits, most-significant nibble = 1) is the 256-bit + /// value 2^252. BCS serialises it as a big-endian byte array, so the + /// most-significant byte (0x10) lands at index 0 - which falls inside the + /// leading window [0, 11] that must be entirely zero for a valid EVM address. + /// The function must therefore return false. + fun test_invalid_evm_address_full_32_bytes() { + // BCS big-endian layout for @0x1000...000 (32 bytes): + // index 0 : 0x10 <- non-zero prefix byte -> invalid EVM address + // index 1 : 0x00 + // ... + // index 31 : 0x00 + assert!( + is_valid_evm_address( + &@0x0000000000000000000000001000000000000000000000000000000000000001 + ), + 0 + ); + + assert!( + !is_valid_evm_address( + &@0x1000000000000000000000000000000000000000000000000000000000000000 + ), + 0 + ); + assert!( + !is_valid_evm_address( + &@0x0000000000000000000000011000000000000000000000000000000000000001 + ), + 0 + ); + + } + + #[test(supra_framework = @supra_framework)] + /// Happy-path test: both get_contract_value and get_scalar_config_value return the + /// values that were seeded into their respective resources. + fun test_get_contract_and_config_value_success(supra_framework: signer) acquires EvmContractsDetails, EvmScalarConfig { + // Seed EvmContractsDetails with a single entry. + let contract_key = std::string::utf8(b"usdc_contract"); + let contract_addr = @0xA550C18; + move_to(&supra_framework, EvmContractsDetails { + details: simple_map::new_from(vector[contract_key], vector[contract_addr]) + }); + + // Seed EvmScalarConfig with a single entry using a plain u128 value. + let config_key = std::string::utf8(b"evm_gas_normalization_denom"); + let config_value = 42u128; + move_to(&supra_framework, EvmScalarConfig { + config: simple_map::new_from(vector[config_key], vector[config_value]) + }); + + // Both lookups must return the exact values that were inserted above. + assert!(get_contract_value(std::string::utf8(b"usdc_contract")) == contract_addr, 0); + assert!( + get_scalar_config_value(std::string::utf8(b"evm_gas_normalization_denom")) == 42u128, + 0 + ); + } + + #[test(supra_framework = @supra_framework)] + /// Failure test: get_contract_value aborts when the requested key is absent. + /// + /// The expected abort code is error::not_found(EKEY_NOT_FOUND) + /// = (NOT_FOUND_CATEGORY=6 << 16) | EKEY_NOT_FOUND=4 = 0x60004. + #[expected_failure(abort_code = 0x60004, location = supra_framework::evm_config)] + fun test_get_contract_value_key_not_found(supra_framework: signer) acquires EvmContractsDetails { + move_to(&supra_framework, EvmContractsDetails { + details: simple_map::new_from( + vector[std::string::utf8(b"existing_key")], + vector[@0x1] + ) + }); + get_contract_value(std::string::utf8(b"nonexistent_key")); + } + + #[test(supra_framework = @supra_framework)] + /// Failure test: get_scalar_config_value aborts when the requested key is absent. + /// + /// The expected abort code is error::not_found(EKEY_NOT_FOUND) + /// = (NOT_FOUND_CATEGORY=6 << 16) | EKEY_NOT_FOUND=4 = 0x60004. + #[expected_failure(abort_code = 0x60004, location = supra_framework::evm_config)] + fun test_get_config_value_key_not_found(supra_framework: signer) acquires EvmScalarConfig { + move_to(&supra_framework, EvmScalarConfig { + config: simple_map::new_from( + vector[std::string::utf8(b"existing_key")], + vector[1u128] + ) + }); + get_scalar_config_value(std::string::utf8(b"nonexistent_key")); + } + + #[test] + /// Success test: validate_scalar_config must not abort when all required keys are present. + /// + /// evm_gas_normalization_denom is the sole required key. A config seeded with that + /// key and a plain u128 value must pass validation. + fun test_validate_config_success() { + let config_key = std::string::utf8(CONFIG_KEY_EVM_GAS_NORMALIZATION_DENOM); + let estimate_margin_key = std::string::utf8(CONFIG_KEY_EVM_GAS_ESTIMATE_MARGIN); + let gas_used_ratio_key = std::string::utf8(SUPRA_EVM_GAS_USED_RATIO); + let decimal_precision_key = std::string::utf8(SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION); + + + let evm_config = EvmScalarConfig { + config: simple_map::new_from(vector[config_key, estimate_margin_key, gas_used_ratio_key, decimal_precision_key], vector[100u128, 1000u128, 500u128, 1000u128]) + }; + // Must complete without aborting. + validate_scalar_config(&evm_config); + } + + #[test] + /// Failure test: validate_scalar_config aborts when a required key is absent. + /// + /// An empty config is missing evm_gas_normalization_denom, so validation must abort. + /// The expected abort code is error::invalid_argument(EMISSING_KEY_OR_INCORRECT_VAL_TYPE) + /// = (INVALID_ARGUMENT_CATEGORY=1 << 16) | EMISSING_KEY_OR_INCORRECT_VAL_TYPE=5 = 0x10005. + #[expected_failure(abort_code = 0x10005, location = supra_framework::evm_config)] + fun test_validate_config_missing_required_key() { + // An empty config is missing the sole required key -> must abort. + let evm_config = EvmScalarConfig { config: simple_map::new() }; + validate_scalar_config(&evm_config); + } + + #[test(supra_framework = @supra_framework)] + /// Failure test: upsert_evm_contract_details_for_next_epoch aborts when any + /// address in the values vector is not a valid EVM address. + /// + /// The call passes one valid address (@0x1, which fits in 20 bytes with all + /// leading bytes zero) alongside one invalid address whose most-significant + /// byte is non-zero (@0x1000...000). The presence of the invalid address + /// must trigger EINVALID_EVM_ADDRESS regardless of position in the vector. + /// The expected abort code is error::invalid_argument(EINVALID_EVM_ADDRESS) + /// = (INVALID_ARGUMENT_CATEGORY=1 << 16) | EINVALID_EVM_ADDRESS=3 = 0x10003. + #[expected_failure(abort_code = 0x10003, location = supra_framework::evm_config)] + fun test_upsert_evm_contract_details_mixed_invalid_address(supra_framework: signer) acquires EvmContractsDetails { + let keys = vector[ + std::string::utf8(b"valid_contract"), + std::string::utf8(b"invalid_contract") + ]; + let values = vector[ + @0x1, // valid: fits in 20 bytes + @0x1000000000000000000000000000000000000000000000000000000000000000 // invalid: high byte non-zero + ]; + upsert_evm_contract_details_for_next_epoch(&supra_framework, keys, values); + } + + #[test(supra_framework = @supra_framework)] + /// Failure test: validate_scalar_config aborts when gas used ratio exceeds decimal precision. + /// + /// The config includes all required keys, but the value for SUPRA_EVM_GAS_USED_RATIO (500) exceeds the value for SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION (1000), which is not logically valid. Validation must abort with + /// error::invalid_argument(EGAS_USED_RATIO_CANNOT_EXCEED_DECIMAL_PRECISION) + /// = (INVALID_ARGUMENT_CATEGORY=1 << 16) | EGAS_USED_RATIO_CANNOT_EXCEED_DECIMAL_PRECISION=7 = 0x10007. + #[expected_failure(abort_code = 0x10007, location = supra_framework::evm_config)] + fun test_validate_config_gas_used_ratio_exceeds_decimal_precision() { + let config_key = std::string::utf8(CONFIG_KEY_EVM_GAS_NORMALIZATION_DENOM); + let estimate_margin_key = std::string::utf8(CONFIG_KEY_EVM_GAS_ESTIMATE_MARGIN); + let gas_used_ratio_key = std::string::utf8(SUPRA_EVM_GAS_USED_RATIO); + let decimal_precision_key = std::string::utf8(SUPRA_EVM_GAS_USED_RATIO_DECIMAL_PRECISION); + let evm_config = EvmScalarConfig { + config: simple_map::new_from( + vector[config_key, estimate_margin_key, gas_used_ratio_key, decimal_precision_key], + vector[100u128, 1000u128, 1500u128, 1000u128] // gas used ratio exceeds decimal precision -> must abort + ) + }; + validate_scalar_config(&evm_config); + +} + +} diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index aca82ed292f..52a6aa81aca 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -5,6 +5,7 @@ module supra_framework::genesis { use std::string::String; use std::vector; use aptos_std::simple_map; + use supra_framework::evm_config; use supra_framework::account; use supra_framework::aggregator_factory; @@ -300,6 +301,17 @@ module supra_framework::genesis { evm_genesis_config::initialize(supra_framework, evm_genesis_config); } + /// Initialize the EVM config. + fun initialize_evm_config( + supra_framework: &signer, + contract_names: vector, + contract_addresses: vector
, + config_keys: vector, + config_values: vector + ) { + evm_config::initialize(supra_framework, contract_names, contract_addresses, config_keys, config_values); + } + /// Initialize the leader ban config fun initialize_leader_ban_registry_config( supra_framework: &signer, leader_ban_registry_config: vector diff --git a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move index c272aaa336c..598aecdfaf1 100644 --- a/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move +++ b/aptos-move/framework/supra-framework/sources/reconfiguration_with_dkg.move @@ -7,6 +7,7 @@ module supra_framework::reconfiguration_with_dkg { use std::features; use std::option; use std::vector; + use supra_framework::evm_config; use supra_framework::automation_registry; use supra_framework::randomness; use supra_framework::consensus_config; @@ -107,6 +108,7 @@ module supra_framework::reconfiguration_with_dkg { randomness_api_v0_config::on_new_epoch(framework); evm_genesis_config::on_new_epoch(framework); dkg_config::on_new_epoch(framework); + evm_config::on_new_epoch(framework); reconfiguration::reconfigure(); } diff --git a/aptos-move/framework/supra-framework/sources/transaction_context.move b/aptos-move/framework/supra-framework/sources/transaction_context.move index 0b4c163107f..1a64404ab15 100644 --- a/aptos-move/framework/supra-framework/sources/transaction_context.move +++ b/aptos-move/framework/supra-framework/sources/transaction_context.move @@ -170,6 +170,15 @@ module supra_framework::transaction_context { } native fun multisig_payload_internal(): Option; + /// Returns the Keccak-256 hash of the current signed transaction (the `transaction consensus hash`). + /// This is distinct from `get_transaction_hash()`, which returns the session UUID hash. + /// Aborts if called outside a user transaction context. + public fun get_transaction_consensus_hash(): vector { + assert!(features::transaction_context_extension_enabled(), error::invalid_state(ETRANSACTION_CONTEXT_EXTENSION_NOT_ENABLED)); + get_transaction_consensus_hash_internal() + } + native fun get_transaction_consensus_hash_internal(): vector; + /// Returns the multisig account address of the multisig payload. public fun multisig_address(payload: &MultisigPayload): address { assert!(features::transaction_context_extension_enabled(), error::invalid_state(ETRANSACTION_CONTEXT_EXTENSION_NOT_ENABLED)); @@ -259,4 +268,14 @@ module supra_framework::transaction_context { // expected to fail with the error code of `invalid_state(E_TRANSACTION_CONTEXT_NOT_AVAILABLE)` let _multisig = multisig_payload(); } + + /// SUPRA_AUTOMATION_V2_1 is not in the default feature set, so calling `get_transaction_consensus_hash()` + /// aborts at the Move-level assert with error::invalid_state(ETRANSACTION_CONTEXT_NOT_AVAILABLE). + /// Even if the feature were enabled in a test environment, the native would also abort with + /// the same code because there is no real user transaction context in a unit test. + #[test] + #[expected_failure(abort_code=196609, location = Self)] + fun test_call_get_transaction_consensus_hash() { + let _hash = get_transaction_consensus_hash(); + } } diff --git a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move index 5ffd5f4e114..56b1d51b147 100644 --- a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move +++ b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move @@ -114,6 +114,8 @@ module std::automation_registry_tests { const EREGISTRY_SYSTEM_MAX_GAS_CAP_NON_ZERO: u64 = 46; /// The input address is not identified as multisig account. const EUNKNOWN_MULTISIG_ADDRESS: u64 = 47; + /// Supra automation v2.1 feature is not enabled. + const EDISABLED_AUTOMATION_V2_1_FEATURE: u64 = 49; /// Constants describing CYCLE state. /// State transition flow is: @@ -4426,4 +4428,118 @@ module std::automation_registry_tests { assert!(automation_registry::is_authorized_account(multisig_address2), 4); } + // ------------------------------------------------------------------------- + // Tests for register_without_validation (SUPRA_AUTOMATION_V2_1 feature) + // ------------------------------------------------------------------------- + + /// `register_without_validation` must abort with EDISABLED_AUTOMATION_V2_1_FEATURE when + /// SUPRA_AUTOMATION_V2_1 is not enabled. SUPRA_NATIVE_AUTOMATION and SUPRA_AUTOMATION_V2 + /// are both enabled by `initialize_registry_test`, but V2_1 is deliberately omitted. + #[test(supra_framework = @supra_framework, user = @0x1cafe)] + #[expected_failure(abort_code = EDISABLED_AUTOMATION_V2_1_FEATURE, location = automation_registry)] + fun test_register_without_validation_v2_1_feature_disabled( + supra_framework: &signer, + user: &signer, + ) { + initialize_registry_test(supra_framework, user); + // Expiry must be after the current time plus at least one cycle duration. + let expiry_time = EPOCH_INTERVAL_FOR_TEST_IN_SECS + 86400; + automation_registry::register_without_validation( + user, + PAYLOAD, + expiry_time, + 10_000, + 100, + 1_000, + AUX_DATA, + ); + } + + /// When SUPRA_AUTOMATION_V2_1 is enabled, `register_without_validation` calls + /// `get_txn_app_hash()` which requires a real user transaction context. In a Move unit + /// test that context does not exist, so the native function aborts with + /// error::invalid_state(ETRANSACTION_CONTEXT_NOT_AVAILABLE) = 196609. + #[test(supra_framework = @supra_framework, user = @0x1cafe)] + #[expected_failure(abort_code = 196609, location = supra_framework::transaction_context)] + fun test_register_without_validation_aborts_outside_txn_context( + supra_framework: &signer, + user: &signer, + ) { + initialize_registry_test(supra_framework, user); + // Enable V2_1 so the feature guard passes; the native should then abort because + // there is no real user transaction context in a unit test. + toggle_custom_feature_flags( + supra_framework, + vector[features::get_supra_automation_v2_1_feature()], + true, + ); + let expiry_time = EPOCH_INTERVAL_FOR_TEST_IN_SECS + 86400; + automation_registry::register_without_validation( + user, + PAYLOAD, + expiry_time, + 10_000, + 100, + 1_000, + AUX_DATA, + ); + } + + // ------------------------------------------------------------------------- + // Tests for register_system_task_without_validation (SUPRA_AUTOMATION_V2_1 feature) + // ------------------------------------------------------------------------- + + /// `register_system_task_without_validation` must abort with EDISABLED_AUTOMATION_V2_1_FEATURE + /// when SUPRA_AUTOMATION_V2_1 is not enabled. `initialize_registry_test` enables + /// SUPRA_NATIVE_AUTOMATION and SUPRA_AUTOMATION_V2 but deliberately omits V2_1. + /// The V2_1 guard fires before any authorization or registry logic is reached, so + /// the caller does not need to be an authorized multisig account for this test. + #[test(supra_framework = @supra_framework, user = @0x1cafe)] + #[expected_failure(abort_code = EDISABLED_AUTOMATION_V2_1_FEATURE, location = automation_registry)] + fun test_register_system_task_without_validation_v2_1_feature_disabled( + supra_framework: &signer, + user: &signer, + ) { + initialize_registry_test(supra_framework, user); + // V2_1 is not enabled — the function must abort immediately. + let expiry_time = EPOCH_INTERVAL_FOR_TEST_IN_SECS + 86400; + automation_registry::register_system_task_without_validation( + user, + PAYLOAD, + expiry_time, + 10_000, + SYS_AUX_DATA, + ); + } + + /// When SUPRA_AUTOMATION_V2_1 is enabled, `register_system_task_without_validation` calls + /// `transaction_context::get_transaction_consensus_hash()` to obtain the registering + /// transaction's consensus hash. That native requires a real user transaction context which + /// does not exist in a Move unit test, so the call aborts with + /// error::invalid_state(ETRANSACTION_CONTEXT_NOT_AVAILABLE) = 196609. + /// The abort happens before authorization or registry checks, so no multisig setup is needed. + #[test(supra_framework = @supra_framework, user = @0x1cafe)] + #[expected_failure(abort_code = 196609, location = supra_framework::transaction_context)] + fun test_register_system_task_without_validation_aborts_outside_txn_context( + supra_framework: &signer, + user: &signer, + ) { + initialize_registry_test(supra_framework, user); + // Enable V2_1 so the feature guard passes; the native consensus-hash getter then + // aborts because there is no real transaction context available in unit tests. + toggle_custom_feature_flags( + supra_framework, + vector[features::get_supra_automation_v2_1_feature()], + true, + ); + let expiry_time = EPOCH_INTERVAL_FOR_TEST_IN_SECS + 86400; + automation_registry::register_system_task_without_validation( + user, + PAYLOAD, + expiry_time, + 10_000, + SYS_AUX_DATA, + ); + } + } diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index d4132f464ad..0a45efde5e6 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -56,6 +56,7 @@ use std::{ collections::BTreeSet, hash::{Hash, Hasher}, }; +use aptos_types::on_chain_config::{OnChainEvmContractsDetails, OnChainEvmConfig}; // The seed is arbitrarily picked to produce a consistent key. XXX make this more formal? const GENESIS_SEED: [u8; 32] = [42; 32]; @@ -248,6 +249,8 @@ pub fn encode_genesis_transaction_for_testnet( gas_schedule: &GasScheduleV2, supra_config_bytes: Vec, evm_genesis_config: Option, + evm_contracts_details: Option, + evm_scalar_config: Option ) -> Transaction { Transaction::GenesisTransaction(WriteSetPayload::Direct( encode_genesis_change_set_for_testnet( @@ -268,6 +271,8 @@ pub fn encode_genesis_transaction_for_testnet( gas_schedule, supra_config_bytes, evm_genesis_config, + evm_contracts_details, + evm_scalar_config ), )) } @@ -290,6 +295,9 @@ pub fn encode_genesis_change_set_for_testnet( gas_schedule: &GasScheduleV2, supra_config_bytes: Vec, evm_genesis_config: Option, + evm_contracts_details: Option, + evm_scalar_config: Option + ) -> ChangeSet { validate_genesis_config(genesis_config); // Create a Move VM session so we can invoke on-chain genesis initializations. @@ -343,6 +351,10 @@ pub fn encode_genesis_change_set_for_testnet( initialize_evm_genesis_config(&mut session, &evm_genesis_config); } + if let (Some(evm_contracts_details), Some(evm_scalar_config)) = (evm_contracts_details, evm_scalar_config) { + initialize_evm_config(&mut session, evm_contracts_details, evm_scalar_config); + } + create_accounts(&mut session, accounts); if let Some(owner_group) = owner_group { @@ -619,6 +631,30 @@ fn initialize_evm_genesis_config( ); } +fn initialize_evm_config( + session: &mut SessionExt, + evm_contracts_details: OnChainEvmContractsDetails, + evm_scalar_config: OnChainEvmConfig, +) { + + let (contract_names, contract_addresses) = evm_contracts_details.to_move_values(); + let (config_keys, config_values) = evm_scalar_config.to_move_values(); + + exec_function( + session, + GENESIS_MODULE_NAME, + "initialize_evm_config", + vec![], + serialize_values(&vec![ + MoveValue::Signer(CORE_CODE_ADDRESS), + contract_names, + contract_addresses, + config_keys, + config_values + ]), + ); +} + fn initialize_config_buffer(session: &mut SessionExt) { exec_function( session, @@ -1287,6 +1323,8 @@ pub fn generate_test_genesis( &default_gas_schedule(), b"test".to_vec(), None, + None, + None, ); (genesis, test_validators) } @@ -1318,6 +1356,8 @@ pub fn generate_mainnet_genesis( &default_gas_schedule(), b"test".to_vec(), None, + None, + None, ); (genesis, test_validators) } diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs index d53bf924acc..aca84febb4c 100644 --- a/crates/aptos-genesis/src/lib.rs +++ b/crates/aptos-genesis/src/lib.rs @@ -177,6 +177,8 @@ impl GenesisInfo { &self.gas_schedule, b"test".to_vec(), None, + None, + None, ) } diff --git a/devtools/assets/license_header.txt b/devtools/assets/license_header.txt index ebc846ed74b..47bc4ada806 100644 --- a/devtools/assets/license_header.txt +++ b/devtools/assets/license_header.txt @@ -1,2 +1,2 @@ -Copyright (c) Aptos Foundation +Copyright (c) Supra. SPDX-License-Identifier: Apache-2.0 diff --git a/devtools/assets/license_header_utf8.txt b/devtools/assets/license_header_utf8.txt index 5f8d7b55e16..c0cb30e1214 100644 --- a/devtools/assets/license_header_utf8.txt +++ b/devtools/assets/license_header_utf8.txt @@ -1,2 +1,2 @@ -Copyright © Aptos Foundation +Copyright © Supra. SPDX-License-Identifier: Apache-2.0 diff --git a/devtools/assets/shared_license_header.txt b/devtools/assets/shared_license_header.txt index 18a8743e5f4..a279050a3ae 100644 --- a/devtools/assets/shared_license_header.txt +++ b/devtools/assets/shared_license_header.txt @@ -1,3 +1,4 @@ +Copyright © Supra. Copyright (c) Aptos Foundation Parts of the project are originally copyright (c) Meta Platforms, Inc. SPDX-License-Identifier: Apache-2.0 diff --git a/devtools/assets/shared_license_header_utf8.txt b/devtools/assets/shared_license_header_utf8.txt index e5b2ef62fc0..78c2c2b1913 100644 --- a/devtools/assets/shared_license_header_utf8.txt +++ b/devtools/assets/shared_license_header_utf8.txt @@ -1,3 +1,4 @@ +Copyright © Supra. Copyright © Aptos Foundation Parts of the project are originally copyright © Meta Platforms, Inc. SPDX-License-Identifier: Apache-2.0 diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index 4abc853ca97..79dcf0e2ca1 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -104,6 +104,8 @@ pub enum FeatureFlag { /// The default DKG configuration also requires `SUPRA_BCFT_CERTIFICATES` to be enabled first. SUPRA_DKG = 99, SUPRA_TRANSACTIONS_INCLUSION_PROOFS = 100, + /// Enables smart contracts to register automation tasks via `register_without_validation`, + SUPRA_AUTOMATION_V2_1 = 101, } //TODO: add dkg feature @@ -181,6 +183,7 @@ impl FeatureFlag { FeatureFlag::SUPRA_BCFT_CERTIFICATES, FeatureFlag::SUPRA_DKG, FeatureFlag::SUPRA_TRANSACTIONS_INCLUSION_PROOFS, + FeatureFlag::SUPRA_AUTOMATION_V2_1, ] } } @@ -339,6 +342,10 @@ impl Features { file_format_common::VERSION_5 } } + + pub fn is_supra_automation_v2_1_enabled(&self) -> bool { + self.is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2_1) + } } pub fn aptos_test_feature_flags_genesis() -> ChangeSet { diff --git a/types/src/on_chain_config/automation_registry.rs b/types/src/on_chain_config/automation_registry.rs index 4f68aa12669..e910f61baad 100644 --- a/types/src/on_chain_config/automation_registry.rs +++ b/types/src/on_chain_config/automation_registry.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2025 Supra. // SPDX-License-Identifier: Apache-2.0 diff --git a/types/src/on_chain_config/evm_config.rs b/types/src/on_chain_config/evm_config.rs new file mode 100644 index 00000000000..e3644621ba1 --- /dev/null +++ b/types/src/on_chain_config/evm_config.rs @@ -0,0 +1,553 @@ +// Copyright (c) 2026 Supra. +// SPDX-License-Identifier: Apache-2.0 + +use crate::on_chain_config::OnChainConfig; +use move_core_types::account_address::AccountAddress; +use move_core_types::value::MoveValue; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; + +// -- EvmContractName ----------------------------------------------------------- + +/// Evm Contract Names deployed by Supra at genesis or later to be part of Supra EVM main state. +/// Currently only system targeted contracts have dedicated enum variants, the rest will be stored +/// as instance of [Self::Custom] variant. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, Hash, PartialOrd, Ord)] +pub enum EvmContractName { + BlockMetadata, + AutomationRegistry, + Custom(String), +} + +impl FromStr for EvmContractName { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s { + "BlockMetadata" => Ok(EvmContractName::BlockMetadata), + "AutomationRegistry" => Ok(EvmContractName::AutomationRegistry), + n => Ok(EvmContractName::Custom(n.to_string())), + } + } +} + +impl Display for EvmContractName { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + EvmContractName::BlockMetadata => write!(f, "BlockMetadata"), + EvmContractName::AutomationRegistry => write!(f, "AutomationRegistry"), + EvmContractName::Custom(n) => write!(f, "{n}"), + } + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +pub(crate) struct EvmContractsDetails { + details: Vec<(String, AccountAddress)>, +} + +pub const EVM_ADDRESS_LENGTH: usize = 20; +type RawEvmAddress = [u8; EVM_ADDRESS_LENGTH]; + +/// The Genesis configuration for EVM that can only be set once at genesis epoch. +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +pub struct OnChainEvmContractsDetails { + pub name_to_addresses: BTreeMap, +} + +impl OnChainEvmContractsDetails { + /// Converts keys and values to [`MoveValue`] and returns as tuple. + pub fn to_move_values(self) -> (MoveValue, MoveValue) { + let (keys, values): (Vec<_>, Vec<_>) = self + .name_to_addresses + .into_iter() + .map(|(key, value)| { + // A Move `address` is 32 bytes serialised by BCS in big-endian order + // (most-significant byte at index 0). An EVM address is only 20 bytes, + // so we zero-pad the leading 12 bytes and place the EVM bytes at the + // tail (indices 12-31). This matches the invariant enforced by + // `is_valid_evm_address` in evm_config.move, which asserts that + // indices 0-11 are all zero. + let mut padded = [0u8; AccountAddress::LENGTH]; + padded[AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..].copy_from_slice(&value); + ( + MoveValue::vector_u8(key.to_string().into_bytes()), + AccountAddress::from(padded), + ) + }) + .unzip(); + (MoveValue::Vector(keys), MoveValue::vector_address(values)) + } + + pub fn get(&self, contract_name: EvmContractName) -> Option<&RawEvmAddress> { + self.name_to_addresses.get(&contract_name) + } + + pub fn has_all_keys(&self, keys: &[EvmContractName]) -> bool { + keys.into_iter() + .all(|key| self.name_to_addresses.contains_key(key)) + } +} + +impl OnChainConfig for OnChainEvmContractsDetails { + const MODULE_IDENTIFIER: &'static str = "evm_config"; + const TYPE_IDENTIFIER: &'static str = "EvmContractsDetails"; + + fn deserialize_into_config(bytes: &[u8]) -> anyhow::Result { + let raw_details = bcs::from_bytes::(bytes)?; + let details = raw_details + .details + .into_iter() + .filter_map(|(key, value)| { + let name = EvmContractName::from_str(&key).ok()?; + // BCS serialises a Move `address` as a raw 32-byte big-endian + // array. `to_move_values` places the 20-byte EVM address in the + // tail (indices 12-31) with the leading 12 bytes zeroed, so we + // must read from the back to recover the original EVM address. + let evm_address: RawEvmAddress = value.into_bytes() + [AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..] + .try_into() + .ok()?; + Some((name, evm_address)) + }) + .collect::>(); + Ok(Self { + name_to_addresses: details, + }) + } +} + +// -- EvmScalarConfigKey -------------------------------------------------------- + +/// Typed keys for entries stored in the on-chain `EvmScalarConfig` resource. +/// Only keys whose string representation is known at compile time are listed +/// here; unknown keys are silently skipped during deserialization so that an +/// older node binary can still read a config that was extended with new keys. +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, Hash, PartialOrd, Ord)] +pub enum EvmScalarConfigKey { + EvmGasNormalizationDenom, + EvmGasEstimateMargin, + EvmGasUsedRatio, + EvmGasUsedRatioDecimalPrecision, +} + +impl EvmScalarConfigKey { + /// The set of keys that MUST be present in the on-chain config. + /// Deserialization hard-fails if any of these is missing. + pub fn required_keys() -> &'static [EvmScalarConfigKey] { + &[ + EvmScalarConfigKey::EvmGasNormalizationDenom, + EvmScalarConfigKey::EvmGasEstimateMargin, + EvmScalarConfigKey::EvmGasUsedRatio, + EvmScalarConfigKey::EvmGasUsedRatioDecimalPrecision, + ] + } +} + +impl FromStr for EvmScalarConfigKey { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s { + "evm_gas_normalization_denom" => Ok(EvmScalarConfigKey::EvmGasNormalizationDenom), + "evm_gas_estimate_margin" => Ok(EvmScalarConfigKey::EvmGasEstimateMargin), + "evm_gas_used_ratio" => Ok(EvmScalarConfigKey::EvmGasUsedRatio), + "evm_gas_used_ratio_decimal_precision" => { + Ok(EvmScalarConfigKey::EvmGasUsedRatioDecimalPrecision) + }, + _ => Err(anyhow::anyhow!("unknown evm scalar config key: {}", s)), + } + } +} + +impl Display for EvmScalarConfigKey { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + // Mirror FromStr: Display produces the canonical snake_case string that + // operators see in logs and error messages. + match self { + EvmScalarConfigKey::EvmGasNormalizationDenom => { + write!(f, "evm_gas_normalization_denom") + }, + EvmScalarConfigKey::EvmGasEstimateMargin => { + write!(f, "evm_gas_estimate_margin") + }, + EvmScalarConfigKey::EvmGasUsedRatio => { + write!(f, "evm_gas_used_ratio") + }, + EvmScalarConfigKey::EvmGasUsedRatioDecimalPrecision => { + write!(f, "evm_gas_used_ratio_decimal_precision") + }, + } + } +} + +// -- Internal BCS mirror struct ------------------------------------------------ + +/// BCS mirror of the on-chain `EvmScalarConfig` resource. +/// `SimpleMap` serializes as `Vec<(K, V)>` in BCS. +/// All config values are plain u128 scalars; the Move type system enforces +/// type correctness at compile time. +#[derive(Deserialize, Serialize)] +struct RawEvmScalarConfig { + config: Vec<(String, u128)>, +} + +// -- OnChainEvmConfig ---------------------------------------------------------- + +/// The decoded, type-safe representation of the on-chain `EvmScalarConfig` resource. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct OnChainEvmConfig { + pub config: BTreeMap, +} + +impl OnChainEvmConfig { + /// Convenience accessor for the EVM gas normalisation denominator. + pub fn evm_gas_normalization_denom(&self) -> anyhow::Result { + self.config + .get(&EvmScalarConfigKey::EvmGasNormalizationDenom) + .copied() + .ok_or_else(|| { + anyhow::anyhow!("evm_gas_normalization_denom not found in EvmScalarConfig") + }) + } + + pub fn evm_gas_estimate_margin(&self) -> anyhow::Result { + self.config + .get(&EvmScalarConfigKey::EvmGasEstimateMargin) + .copied() + .and_then(|v| v.try_into().ok()) + .ok_or_else(|| anyhow::anyhow!("evm_gas_estimate_margin not found in EvmScalarConfig")) + } + + pub fn evm_gas_used_ratio(&self) -> anyhow::Result { + // Decimal is guaranteed to be non-zero due to validation in evm_config.move, so this division is safe. + let decimal = self.evm_gas_used_ratio_decimal_precision()?; + self.config + .get(&EvmScalarConfigKey::EvmGasUsedRatio) + .copied() + .and_then(|v| { + let ratio = v as f64 / decimal as f64; + if ratio > 0.0 { + Some(ratio) + } else { + None + } + }) + .ok_or_else(|| anyhow::anyhow!("evm_gas_used_ratio not found in EvmScalarConfig")) + } + + pub fn evm_gas_used_ratio_decimal_precision(&self) -> anyhow::Result { + self.config + .get(&EvmScalarConfigKey::EvmGasUsedRatioDecimalPrecision) + .copied() + .and_then(|v| v.try_into().ok()) + .ok_or_else(|| { + anyhow::anyhow!("evm_gas_used_ratio_decimal_precision not found in EvmScalarConfig") + }) + } + + pub fn to_move_values(self) -> (MoveValue, MoveValue) { + let (keys, values): (Vec<_>, Vec<_>) = self + .config + .into_iter() + .map(|(key, value)| { + ( + MoveValue::vector_u8(key.to_string().into_bytes()), + MoveValue::U128(value), + ) + }) + .unzip(); + (MoveValue::Vector(keys), MoveValue::Vector(values)) + } +} + +impl OnChainConfig for OnChainEvmConfig { + const MODULE_IDENTIFIER: &'static str = "evm_config"; + const TYPE_IDENTIFIER: &'static str = "EvmScalarConfig"; + + fn deserialize_into_config(bytes: &[u8]) -> anyhow::Result { + let raw: RawEvmScalarConfig = bcs::from_bytes(bytes) + .map_err(|e| anyhow::anyhow!("failed to BCS-decode RawEvmScalarConfig: {}", e))?; + + let mut config = BTreeMap::new(); + for (key_str, value) in raw.config { + // Skip keys that are not (yet) known to this codebase; this allows + // the on-chain config to grow new entries without breaking older nodes. + let key = match EvmScalarConfigKey::from_str(&key_str) { + Ok(k) => k, + Err(_) => continue, + }; + config.insert(key, value); + } + + // Hard-fail if any required key is absent - the node cannot operate + // correctly without the full set of mandatory config values. + for required_key in EvmScalarConfigKey::required_keys() { + if !config.contains_key(required_key) { + return Err(anyhow::anyhow!( + "required EvmScalarConfig key '{}' is missing from on-chain state", + required_key // Display -> "evm_gas_normalization_denom" + )); + } + } + + Ok(Self { config }) + } +} + +#[cfg(test)] +mod unit_tests { + use super::*; + use crate::on_chain_config::{InMemoryOnChainConfig, OnChainConfig, OnChainConfigProvider}; + use std::collections::HashMap; + + // -- Helpers --------------------------------------------------------------- + + /// Returns a `RawEvmScalarConfig` with all four required keys populated. + /// Use this as the baseline for any test that needs a fully valid config. + fn raw_evm_scalar_config_all_keys( + denom: u128, + margin: u128, + gas_used_ratio: u128, + decimal_precision: u128, + ) -> RawEvmScalarConfig { + RawEvmScalarConfig { + config: vec![ + ("evm_gas_normalization_denom".to_string(), denom), + ("evm_gas_estimate_margin".to_string(), margin), + ("evm_gas_used_ratio".to_string(), gas_used_ratio), + ( + "evm_gas_used_ratio_decimal_precision".to_string(), + decimal_precision, + ), + ], + } + } + + /// Convenience wrapper with fixed margin/ratio/precision for tests that + /// only care about the denom value. + fn raw_evm_scalar_config_with_denom(denom: u128) -> RawEvmScalarConfig { + raw_evm_scalar_config_all_keys(denom, 500, 750, 1000) + } + + // -- OnChainEvmConfig deserialization -------------------------------------- + + #[test] + fn test_deserialize_evm_config_happy_path() { + let bytes = bcs::to_bytes(&raw_evm_scalar_config_with_denom(100)).unwrap(); + let config = OnChainEvmConfig::deserialize_into_config(&bytes).unwrap(); + assert_eq!(config.evm_gas_normalization_denom().unwrap(), 100u128); + // All four required keys must be decoded - no phantom entries. + assert_eq!(config.config.len(), 4); + } + + #[test] + fn test_deserialize_evm_config_missing_required_key() { + // Empty config - all required keys absent; the first one iterated + // (evm_gas_normalization_denom) must appear in the error. + let raw = RawEvmScalarConfig { config: vec![] }; + let bytes = bcs::to_bytes(&raw).unwrap(); + let result = OnChainEvmConfig::deserialize_into_config(&bytes); + assert!(result.is_err(), "expected Err when required key is missing"); + assert!( + result + .unwrap_err() + .to_string() + .contains("evm_gas_normalization_denom"), + "error should identify the missing key" + ); + } + + #[test] + fn test_deserialize_evm_config_each_required_key_missing() { + // Every required key must be individually enforced: removing any single + // one must hard-fail with an error message that names that key. + let required = [ + "evm_gas_normalization_denom", + "evm_gas_estimate_margin", + "evm_gas_used_ratio", + "evm_gas_used_ratio_decimal_precision", + ]; + let full = raw_evm_scalar_config_all_keys(100, 500, 750, 1000); + for missing_key in &required { + let partial = RawEvmScalarConfig { + config: full + .config + .iter() + .filter(|(k, _)| k != missing_key) + .cloned() + .collect(), + }; + let bytes = bcs::to_bytes(&partial).unwrap(); + let result = OnChainEvmConfig::deserialize_into_config(&bytes); + assert!( + result.is_err(), + "expected Err when '{}' is absent", + missing_key + ); + assert!( + result.unwrap_err().to_string().contains(missing_key), + "error must name the missing key '{}'", + missing_key + ); + } + } + + #[test] + fn test_deserialize_evm_config_unknown_key_skipped() { + // Unknown keys must be silently dropped so an older node binary can still + // read a config that was extended with new keys by a newer software version. + let mut raw = raw_evm_scalar_config_all_keys(42, 500, 750, 1000); + raw.config + .push(("completely_unknown_key".to_string(), 7u128)); + let bytes = bcs::to_bytes(&raw).unwrap(); + let config = OnChainEvmConfig::deserialize_into_config(&bytes).unwrap(); + assert_eq!(config.evm_gas_normalization_denom().unwrap(), 42u128); + // Only the four known keys should appear; the unknown one is dropped. + assert_eq!(config.config.len(), 4); + } + + // -- Accessor correctness -------------------------------------------------- + + #[test] + fn test_accessor_evm_gas_estimate_margin() { + let bytes = bcs::to_bytes(&raw_evm_scalar_config_all_keys(100, 1234, 750, 1000)).unwrap(); + let config = OnChainEvmConfig::deserialize_into_config(&bytes).unwrap(); + assert_eq!(config.evm_gas_estimate_margin().unwrap(), 1234u64); + } + + #[test] + fn test_accessor_evm_gas_used_ratio_decimal_precision() { + let bytes = bcs::to_bytes(&raw_evm_scalar_config_all_keys(100, 500, 750, 2000)).unwrap(); + let config = OnChainEvmConfig::deserialize_into_config(&bytes).unwrap(); + assert_eq!( + config.evm_gas_used_ratio_decimal_precision().unwrap(), + 2000u64 + ); + } + + #[test] + fn test_accessor_evm_gas_used_ratio() { + // ratio=750, decimal_precision=1000 -> 750 / 1000 = 0.75 + let bytes = bcs::to_bytes(&raw_evm_scalar_config_all_keys(100, 500, 750, 1000)).unwrap(); + let config = OnChainEvmConfig::deserialize_into_config(&bytes).unwrap(); + let ratio = config.evm_gas_used_ratio().unwrap(); + assert!( + (ratio - 0.75f64).abs() < f64::EPSILON, + "expected 0.75, got {}", + ratio + ); + } + + // -- to_move_values -------------------------------------------------------- + + #[test] + fn test_to_move_values_structure() { + // to_move_values must produce two parallel MoveValue::Vector outputs: + // keys as vector (UTF-8 strings) and values as u128. + let config = OnChainEvmConfig { + config: [ + (EvmScalarConfigKey::EvmGasNormalizationDenom, 42u128), + (EvmScalarConfigKey::EvmGasEstimateMargin, 500u128), + (EvmScalarConfigKey::EvmGasUsedRatio, 750u128), + ( + EvmScalarConfigKey::EvmGasUsedRatioDecimalPrecision, + 1000u128, + ), + ] + .into(), + }; + let (keys_mv, values_mv) = config.to_move_values(); + let MoveValue::Vector(keys) = keys_mv else { + panic!("expected MoveValue::Vector for keys") + }; + let MoveValue::Vector(values) = values_mv else { + panic!("expected MoveValue::Vector for values") + }; + assert_eq!(keys.len(), 4); + assert_eq!(values.len(), 4); + // Keys are encoded as vector (UTF-8 bytes). + assert!(matches!(keys[0], MoveValue::Vector(_))); + // Values are u128. + assert!(matches!(values[0], MoveValue::U128(_))); + } + + // -- OnChainEvmContractsDetails round-trip --------------------------------- + + #[test] + fn test_evm_contracts_details_round_trip() { + // 20-byte EVM address placed in the lower 20 bytes of a 32-byte Move + // address (upper 12 zeroed), matching the to_move_values encoding. + let evm_bytes: RawEvmAddress = [ + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, + 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, + ]; + let original = OnChainEvmContractsDetails { + name_to_addresses: [(EvmContractName::BlockMetadata, evm_bytes)].into(), + }; + let mut padded = [0u8; AccountAddress::LENGTH]; + padded[AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..].copy_from_slice(&evm_bytes); + let raw = EvmContractsDetails { + details: vec![("BlockMetadata".to_string(), AccountAddress::from(padded))], + }; + let bytes = bcs::to_bytes(&raw).unwrap(); + let recovered = OnChainEvmContractsDetails::deserialize_into_config(&bytes).unwrap(); + assert_eq!(recovered, original); + + let (_keys, addresses) = original.to_move_values(); + match addresses { + MoveValue::Vector(addrs) => { + assert_eq!(addrs.len(), 1); + match &addrs[0] { + MoveValue::Address(addr) => { + let recovered_evm_bytes: RawEvmAddress = addr.into_bytes()[AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..] + .try_into() + .expect("slice with correct length"); + assert_eq!(recovered_evm_bytes, evm_bytes); + }, + _ => panic!("expected MoveValue::Address in values vector"), + } + } + _ => panic!("expected MoveValue::Vector"), + } + } + + // -- Tier 2: InMemoryOnChainConfig provider -------------------------------- + + #[test] + fn test_fetch_evm_config_via_provider() { + // Validates the full path: raw BCS bytes -> ConfigID lookup -> + // deserialize_into_config -> typed accessor, without a running VM. + let bytes = bcs::to_bytes(&raw_evm_scalar_config_with_denom(999)).unwrap(); + let mut map = HashMap::new(); + map.insert(OnChainEvmConfig::CONFIG_ID, bytes); + let provider = InMemoryOnChainConfig::new(map); + let config = provider.get::().unwrap(); + assert_eq!(config.evm_gas_normalization_denom().unwrap(), 999u128); + } + + #[test] + fn test_fetch_evm_contracts_details_via_provider() { + // Same end-to-end path for OnChainEvmContractsDetails. + let evm_bytes: RawEvmAddress = [ + 0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + ]; + let mut padded = [0u8; AccountAddress::LENGTH]; + padded[AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..].copy_from_slice(&evm_bytes); + let raw = EvmContractsDetails { + details: vec![("BlockMetadata".to_string(), AccountAddress::from(padded))], + }; + let bytes = bcs::to_bytes(&raw).unwrap(); + let mut map = HashMap::new(); + map.insert(OnChainEvmContractsDetails::CONFIG_ID, bytes); + let provider = InMemoryOnChainConfig::new(map); + let recovered = provider.get::().unwrap(); + assert_eq!( + recovered.get(EvmContractName::BlockMetadata), + Some(&evm_bytes) + ); + } +} diff --git a/types/src/on_chain_config/evm_genesis_config.rs b/types/src/on_chain_config/evm_genesis_config.rs index 1901bc9bb64..ca66bdc826d 100644 --- a/types/src/on_chain_config/evm_genesis_config.rs +++ b/types/src/on_chain_config/evm_genesis_config.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) Supra Foundation // SPDX-License-Identifier: Apache-2.0 @@ -32,6 +29,15 @@ pub struct GenesisEvmEOA { pub amount: u128, } +/// The Creator address and nonce determines the contract' deployment address. +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +pub enum ContractKind { + /// Default contract creation API + Create, + /// EVM address that creates a contract. + Call(String), +} + /// The Creator address and nonce determines the contract' deployment address. #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct GenesisEvmContract { @@ -43,6 +49,10 @@ pub struct GenesisEvmContract { pub amount: u128, /// The bytecode of the contract to deploy. pub bytecode: Vec, + /// Type of the contract + pub kind: ContractKind, + /// Precalculated address of the contract + pub deploy_address: String, } impl OnChainEvmGenesisConfig { diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs index 50a10bd80c6..e3ade280f2c 100644 --- a/types/src/on_chain_config/mod.rs +++ b/types/src/on_chain_config/mod.rs @@ -27,6 +27,7 @@ mod automation_registry; mod chain_id; mod commit_history; mod consensus_config; +mod evm_config; mod evm_genesis_config; mod execution_config; mod gas_schedule; @@ -38,7 +39,6 @@ mod timed_features; mod timestamp; mod transaction_fee; mod validator_set; - pub use self::{ approved_execution_hashes::ApprovedExecutionHashes, aptos_features::*, @@ -56,8 +56,12 @@ pub use self::{ LeaderReputationType, OnChainConsensusConfig, ProposerAndVoterConfig, ProposerElectionType, ValidatorTxnConfig, }, + evm_config::{ + EvmContractName, EvmScalarConfigKey, OnChainEvmConfig, OnChainEvmContractsDetails, + }, evm_genesis_config::{ - GenesisEvmContract, GenesisEvmEOA, OnChainEvmGenesisConfig, EVM_GENESIS_EVENT_MOVE_TYPE_TAG, + ContractKind, GenesisEvmContract, GenesisEvmEOA, OnChainEvmGenesisConfig, + EVM_GENESIS_EVENT_MOVE_TYPE_TAG, }, execution_config::{ BlockGasLimitType, ExecutionConfigV1, ExecutionConfigV2, ExecutionConfigV4, diff --git a/types/src/transaction/automated_transaction.rs b/types/src/transaction/automated_transaction.rs index 317547326be..a7b1009ebcc 100644 --- a/types/src/transaction/automated_transaction.rs +++ b/types/src/transaction/automated_transaction.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 diff --git a/types/src/transaction/automation.rs b/types/src/transaction/automation.rs index c374987485d..29918d49c9b 100644 --- a/types/src/transaction/automation.rs +++ b/types/src/transaction/automation.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2025 Supra. // SPDX-License-Identifier: Apache-2.0 @@ -28,6 +25,9 @@ struct AutomationTransactionEntryRef { register_user_task_function: Identifier, register_system_task_function: Identifier, process_tasks_function: Identifier, + /// Function called to cancel an invalid task that cannot be executed (e.g. bad payload or + /// type mismatch). Corresponds to `automation_registry::cancel_invalid_task` in Move. + cancel_invalid_task_function: Identifier, } static AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS: Lazy = @@ -39,6 +39,7 @@ static AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS: Lazy }, + /// Cancel a single task whose payload is invalid (bad BCS encoding or type-check failure) + /// before it can be executed. The diagnostic message is recorded in the on-chain + /// `TaskCancelledByRuntime` event so that off-chain indexers can surface the root cause. + CancelInvalidTask { + task_index: u64, + diagnostic_message: String, + }, } impl AutomationRegistryAction { @@ -739,22 +748,48 @@ impl AutomationRegistryAction { } } - pub fn as_move_value(&self) -> MoveValue { - let AutomationRegistryAction::Process { task_indexes } = self; - let value_indexes = task_indexes - .iter() - .map(|v| MoveValue::U64(*v)) - .collect::>(); - MoveValue::Vector(value_indexes) + /// Creates a `CancelInvalidTask` action. + /// + /// `diagnostic_message` is stored verbatim in the on-chain event; callers should use + /// descriptive prefixes (e.g. `"BCS_DECODE: "`, `"TYPE_CHECK: "`) to aid indexers. + pub fn cancel_invalid_task(task_index: u64, diagnostic_message: String) -> Self { + AutomationRegistryAction::CancelInvalidTask { + task_index, + diagnostic_message, + } } - /// Returns a tuple of min and max task indexes included in the action. + /// Returns the MoveValue representation of the task-index list for a `Process` action. + /// + /// Returns `None` for `CancelInvalidTask` — that variant uses a different serialization + /// path in `AutomationRegistryRecord::serialize_args_with_sender()`. + pub fn as_move_value(&self) -> Option { + match self { + AutomationRegistryAction::Process { task_indexes } => { + let value_indexes = task_indexes + .iter() + .map(|v| MoveValue::U64(*v)) + .collect::>(); + Some(MoveValue::Vector(value_indexes)) + }, + AutomationRegistryAction::CancelInvalidTask { .. } => None, + } + } + + /// Returns the (min, max) task-index range covered by this action. + /// + /// For `CancelInvalidTask` the range is `(task_index, task_index)` because the action + /// targets exactly one task. pub fn task_range(&self) -> (u64, u64) { - let AutomationRegistryAction::Process { task_indexes } = self; - ( - task_indexes.iter().min().copied().unwrap_or(u64::MAX), - task_indexes.iter().max().copied().unwrap_or(u64::MAX), - ) + match self { + AutomationRegistryAction::Process { task_indexes } => ( + task_indexes.iter().min().copied().unwrap_or(u64::MAX), + task_indexes.iter().max().copied().unwrap_or(u64::MAX), + ), + AutomationRegistryAction::CancelInvalidTask { task_index, .. } => { + (*task_index, *task_index) + }, + } } /// Module id containing automation registry target function. @@ -762,12 +797,19 @@ impl AutomationRegistryAction { &AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS.module_id } - /// Action function name accepting enclosed tasks. + /// Function name in `automation_registry` that handles this action. pub fn function(&self) -> &IdentStr { - &AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS.process_tasks_function + match self { + AutomationRegistryAction::Process { .. } => { + &AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS.process_tasks_function + }, + AutomationRegistryAction::CancelInvalidTask { .. } => { + &AUTOMATION_REGISTRY_PRIVATE_ENTRY_REFS.cancel_invalid_task_function + }, + } } - /// Type arguments required by action function. + /// Type arguments required by action function (none for all variants). pub fn ty_args(&self) -> Vec { vec![] } @@ -819,12 +861,38 @@ impl AutomationRegistryRecord { } pub fn serialize_args_with_sender(&self, sender: AccountAddress) -> Vec> { - let action_as_value = self.action.as_move_value(); - serialize_values(&[ - MoveValue::Address(sender), - MoveValue::U64(self.cycle_id), - action_as_value, - ]) + match &self.action { + AutomationRegistryAction::Process { task_indexes } => { + // process_tasks(vm: signer, cycle_index: u64, task_indexes: vector) + let value_indexes = task_indexes + .iter() + .map(|v| MoveValue::U64(*v)) + .collect::>(); + serialize_values(&[ + MoveValue::Address(sender), + MoveValue::U64(self.cycle_id), + MoveValue::Vector(value_indexes), + ]) + }, + AutomationRegistryAction::CancelInvalidTask { + task_index, + diagnostic_message, + } => { + // cancel_invalid_task(vm: signer, task_index: u64, diagnostic_message: String) + // Move's String is BCS-encoded as vector (length-prefixed UTF-8 bytes). + serialize_values(&[ + MoveValue::Address(sender), + MoveValue::U64(*task_index), + MoveValue::Vector( + diagnostic_message + .as_bytes() + .iter() + .map(|b| MoveValue::U8(*b)) + .collect(), + ), + ]) + }, + } } pub fn hash(&self) -> HashValue { @@ -871,7 +939,7 @@ impl From for Transaction { } } -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Getters)] pub struct AutomationRegistryRecordBuilder { record_index: Option, action: Option, @@ -916,8 +984,9 @@ impl AutomationRegistryRecordBuilder { self } - /// Splits the existing record builder into single task based actions if possible. + /// Splits the existing record builder into single-task based actions if possible. /// If no action is specified the same instance is returned. + /// `CancelInvalidTask` already targets a single task and is returned unchanged. pub fn split(mut self) -> Vec { match self.action.take() { None => vec![self], @@ -931,25 +1000,36 @@ impl AutomationRegistryRecordBuilder { block_height: self.block_height, }) .collect::>(), + // CancelInvalidTask is already a single-task action; nothing to split. + Some(cancel @ AutomationRegistryAction::CancelInvalidTask { .. }) => { + self.action = Some(cancel); + vec![self] + }, } } - /// Consumes the builder and returns task indexes enclosed in the action if any specified + /// Consumes the builder and returns the task index(es) enclosed in the action. + /// + /// For `CancelInvalidTask` the single targeted task index is returned as a one-element vec. pub fn into_task_indexes(self) -> Vec { - let Some(action_data) = self.action else { - return vec![]; - }; - let AutomationRegistryAction::Process { task_indexes } = action_data; - task_indexes + match self.action { + None => vec![], + Some(AutomationRegistryAction::Process { task_indexes }) => task_indexes, + Some(AutomationRegistryAction::CancelInvalidTask { task_index, .. }) => { + vec![task_index] + }, + } } - /// Returns potential number of the tasks to be processed in scope of the record. + /// Returns the number of tasks that will be processed in scope of the record. + /// + /// For `CancelInvalidTask` this is always 1. pub fn task_count(&self) -> usize { - let Some(action_data) = &self.action else { - return 0; - }; - let AutomationRegistryAction::Process { task_indexes } = action_data; - task_indexes.len() + match &self.action { + None => 0, + Some(AutomationRegistryAction::Process { task_indexes }) => task_indexes.len(), + Some(AutomationRegistryAction::CancelInvalidTask { .. }) => 1, + } } /// Constructs [`AutomationRegistryRecord`] diff --git a/types/src/transaction/user_transaction_context.rs b/types/src/transaction/user_transaction_context.rs index 4d9e504fce0..202cb70e353 100644 --- a/types/src/transaction/user_transaction_context.rs +++ b/types/src/transaction/user_transaction_context.rs @@ -55,6 +55,10 @@ pub struct UserTransactionContext { gas_unit_price: u64, chain_id: u8, payload_type_reference: PayloadTypeReferenceContext, + /// Keccak-256 hash of the BCS-serialized `SignedTransaction` (or the automation task hash + /// for automated transactions). Fixed 32 bytes. Used by the `get_transaction_consensus_hash` native to + /// expose the registering transaction's identity to smart contracts registering automation tasks. + txn_consensus_hash: [u8; 32], } impl UserTransactionContext { @@ -66,6 +70,7 @@ impl UserTransactionContext { gas_unit_price: u64, chain_id: u8, payload_type_reference: PayloadTypeReferenceContext, + txn_consensus_hash: [u8; 32], ) -> Self { Self { sender, @@ -75,6 +80,7 @@ impl UserTransactionContext { gas_unit_price, chain_id, payload_type_reference, + txn_consensus_hash, } } @@ -113,6 +119,10 @@ impl UserTransactionContext { pub fn is_automation_registration(&self) -> bool { self.payload_type_reference.is_automation_registration() } + + pub fn txn_consensus_hash(&self) -> &[u8; 32] { + &self.txn_consensus_hash + } } #[derive(Debug, Clone)] diff --git a/types/src/unit_tests/automation.rs b/types/src/unit_tests/automation.rs index eb361d3845c..470b806479d 100644 --- a/types/src/unit_tests/automation.rs +++ b/types/src/unit_tests/automation.rs @@ -1,6 +1,3 @@ -// Copyright (c) Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - // Copyright (c) 2024 Supra. // SPDX-License-Identifier: Apache-2.0 From f89729dfa8760f8be5e6aca9b973b70152032ecc Mon Sep 17 00:00:00 2001 From: Aregnaz Harutyunyan <89187359+aregng@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:48:52 +0400 Subject: [PATCH 21/31] [Issue-2876] Fixed failing tests and updated docs (#363) Co-authored-by: Aregnaz Harutyunyan <> --- .../framework/supra-framework/doc/stake.md | 507 +++++++++++++++++- .../tests/automation_registry_tests.move | 12 +- 2 files changed, 508 insertions(+), 11 deletions(-) diff --git a/aptos-move/framework/supra-framework/doc/stake.md b/aptos-move/framework/supra-framework/doc/stake.md index 5c845627071..5c049239252 100644 --- a/aptos-move/framework/supra-framework/doc/stake.md +++ b/aptos-move/framework/supra-framework/doc/stake.md @@ -86,6 +86,10 @@ or if their stake drops below the min required, they would get removed at the en - [Function `initialize_stake_owner`](#0x1_stake_initialize_stake_owner) - [Function `initialize_validator`](#0x1_stake_initialize_validator) - [Function `validate_consensus_public_key`](#0x1_stake_validate_consensus_public_key) +- [Function `assert_consensus_pubkey_unique_in_next_validator_set`](#0x1_stake_assert_consensus_pubkey_unique_in_next_validator_set) +- [Function `assert_consensus_pubkey_unique_in_validator_list`](#0x1_stake_assert_consensus_pubkey_unique_in_validator_list) +- [Function `assert_network_addresses_unique_in_next_validator_set`](#0x1_stake_assert_network_addresses_unique_in_next_validator_set) +- [Function `assert_network_addresses_unique_in_validator_list`](#0x1_stake_assert_network_addresses_unique_in_validator_list) - [Function `initialize_owner`](#0x1_stake_initialize_owner) - [Function `extract_owner_cap`](#0x1_stake_extract_owner_cap) - [Function `deposit_owner_cap`](#0x1_stake_deposit_owner_cap) @@ -1679,6 +1683,26 @@ Invalid DKG public key shares. + + +Another validator in the next validator set already uses this consensus public key. + + +
const EDUPLICATE_CONSENSUS_PUBKEY: u64 = 22;
+
+ + + + + +Another validator in the next validator set already uses these network addresses. + + +
const EDUPLICATE_NETWORK_ADDRESSES: u64 = 23;
+
+ + + Table to store collected transaction fees for each validator already exists. @@ -2685,8 +2709,15 @@ Initialize the validator account and give ownership to the signing account. consensus_pubkey: vector<u8>, network_addresses: vector<u8>, fullnode_addresses: vector<u8> -) acquires AllowedValidators { +) acquires AllowedValidators, ValidatorSet, ValidatorConfig { validate_consensus_public_key(consensus_pubkey); + let account_addr = signer::address_of(account); + assert_consensus_pubkey_unique_in_next_validator_set( + account_addr, &consensus_pubkey + ); + assert_network_addresses_unique_in_next_validator_set( + account_addr, &network_addresses + ); initialize_owner(account); move_to( account, @@ -2745,6 +2776,159 @@ Initialize the validator account and give ownership to the signing account. + + + + +## Function `assert_consensus_pubkey_unique_in_next_validator_set` + +Aborts if any validator other than self_addr in the next validator set +(the union of active_validators and pending_active) already uses +consensus_pubkey as its latest on-chain consensus key. + + +
fun assert_consensus_pubkey_unique_in_next_validator_set(self_addr: address, consensus_pubkey: &vector<u8>)
+
+ + + +
+Implementation + + +
fun assert_consensus_pubkey_unique_in_next_validator_set(
+    self_addr: address,
+    consensus_pubkey: &vector<u8>
+) acquires ValidatorSet, ValidatorConfig {
+    let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+    assert_consensus_pubkey_unique_in_validator_list(
+        self_addr, consensus_pubkey, &validator_set.active_validators
+    );
+    assert_consensus_pubkey_unique_in_validator_list(
+        self_addr, consensus_pubkey, &validator_set.pending_active
+    );
+}
+
+ + + +
+ + + +## Function `assert_consensus_pubkey_unique_in_validator_list` + + + +
fun assert_consensus_pubkey_unique_in_validator_list(self_addr: address, consensus_pubkey: &vector<u8>, validators: &vector<stake::ValidatorInfo>)
+
+ + + +
+Implementation + + +
fun assert_consensus_pubkey_unique_in_validator_list(
+    self_addr: address,
+    consensus_pubkey: &vector<u8>,
+    validators: &vector<ValidatorInfo>
+) acquires ValidatorConfig {
+    let len = vector::length(validators);
+    let i = 0;
+    while (i < len) {
+        let other = vector::borrow(validators, i);
+        if (other.addr != self_addr && exists<ValidatorConfig>(other.addr)) {
+            let other_config = borrow_global<ValidatorConfig>(other.addr);
+            assert!(
+                other_config.consensus_pubkey != *consensus_pubkey,
+                error::invalid_argument(EDUPLICATE_CONSENSUS_PUBKEY)
+            );
+        };
+        i = i + 1;
+    };
+}
+
+ + + +
+ + + +## Function `assert_network_addresses_unique_in_next_validator_set` + +Aborts if any validator other than self_addr in the next validator set +already uses network_addresses. Empty network_addresses is treated +as "unset" and skips the check. + + +
fun assert_network_addresses_unique_in_next_validator_set(self_addr: address, network_addresses: &vector<u8>)
+
+ + + +
+Implementation + + +
fun assert_network_addresses_unique_in_next_validator_set(
+    self_addr: address,
+    network_addresses: &vector<u8>
+) acquires ValidatorSet, ValidatorConfig {
+    if (vector::is_empty(network_addresses)) { return };
+    let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+    assert_network_addresses_unique_in_validator_list(
+        self_addr, network_addresses, &validator_set.active_validators
+    );
+    assert_network_addresses_unique_in_validator_list(
+        self_addr, network_addresses, &validator_set.pending_active
+    );
+}
+
+ + + +
+ + + +## Function `assert_network_addresses_unique_in_validator_list` + + + +
fun assert_network_addresses_unique_in_validator_list(self_addr: address, network_addresses: &vector<u8>, validators: &vector<stake::ValidatorInfo>)
+
+ + + +
+Implementation + + +
fun assert_network_addresses_unique_in_validator_list(
+    self_addr: address,
+    network_addresses: &vector<u8>,
+    validators: &vector<ValidatorInfo>
+) acquires ValidatorConfig {
+    let len = vector::length(validators);
+    let i = 0;
+    while (i < len) {
+        let other = vector::borrow(validators, i);
+        if (other.addr != self_addr && exists<ValidatorConfig>(other.addr)) {
+            let other_config = borrow_global<ValidatorConfig>(other.addr);
+            assert!(
+                other_config.network_addresses != *network_addresses,
+                error::invalid_argument(EDUPLICATE_NETWORK_ADDRESSES)
+            );
+        };
+        i = i + 1;
+    };
+}
+
+ + +
@@ -3228,7 +3412,7 @@ Move amount of coins from pending_inactive to active. pool_address: address, new_consensus_pubkey: vector<u8>, genesis: bool -) acquires StakePool, ValidatorConfig { +) acquires StakePool, ValidatorConfig, ValidatorSet { assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); @@ -3242,10 +3426,12 @@ Move amount of coins from pending_inactive to active. exists<ValidatorConfig>(pool_address), error::not_found(EVALIDATOR_CONFIG) ); + validate_consensus_public_key(new_consensus_pubkey); + assert_consensus_pubkey_unique_in_next_validator_set( + pool_address, &new_consensus_pubkey + ); let validator_info = borrow_global_mut<ValidatorConfig>(pool_address); let old_consensus_pubkey = validator_info.consensus_pubkey; - - validate_consensus_public_key(new_consensus_pubkey); validator_info.consensus_pubkey = new_consensus_pubkey; if (std::features::module_event_migration_enabled()) { @@ -3404,7 +3590,7 @@ only for genesis
public(friend) fun rotate_consensus_key_genesis(
     operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>
-) acquires StakePool, ValidatorConfig {
+) acquires StakePool, ValidatorConfig, ValidatorSet {
     rotate_consensus_key_internal(
         operator,
         pool_address,
@@ -3436,7 +3622,7 @@ Rotate the consensus key of the validator, it'll take effect in next epoch.
 
 
public entry fun rotate_consensus_key(
     operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>
-) acquires StakePool, ValidatorConfig {
+) acquires StakePool, ValidatorConfig, ValidatorSet {
     rotate_consensus_key_internal(
         operator,
         pool_address,
@@ -3471,7 +3657,7 @@ Update the network and full node addresses of the validator. This only takes eff
     pool_address: address,
     new_network_addresses: vector<u8>,
     new_fullnode_addresses: vector<u8>
-) acquires StakePool, ValidatorConfig {
+) acquires StakePool, ValidatorConfig, ValidatorSet {
     assert_reconfig_not_in_progress();
     assert_stake_pool_exists(pool_address);
     let stake_pool = borrow_global_mut<StakePool>(pool_address);
@@ -3483,6 +3669,9 @@ Update the network and full node addresses of the validator. This only takes eff
         exists<ValidatorConfig>(pool_address),
         error::not_found(EVALIDATOR_CONFIG)
     );
+    assert_network_addresses_unique_in_next_validator_set(
+        pool_address, &new_network_addresses
+    );
     let validator_info = borrow_global_mut<ValidatorConfig>(pool_address);
     let old_network_addresses = validator_info.network_addresses;
     validator_info.network_addresses = new_network_addresses;
@@ -5614,7 +5803,8 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
let addr = signer::address_of(account);
+
pragma aborts_if_is_partial = true;
+let addr = signer::address_of(account);
 let post_addr = signer::address_of(account);
 let allowed = global<AllowedValidators>(@supra_framework);
 aborts_if exists<ValidatorConfig>(addr);
@@ -5808,7 +5998,8 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
let pre_stake_pool = global<StakePool>(pool_address);
+
pragma aborts_if_is_partial = true;
+let pre_stake_pool = global<StakePool>(pool_address);
 let post validator_info = global<ValidatorConfig>(pool_address);
 aborts_if reconfiguration_state::spec_is_in_progress();
 aborts_if !exists<StakePool>(pool_address);
@@ -5832,7 +6023,8 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
let pre_stake_pool = global<StakePool>(pool_address);
+
pragma aborts_if_is_partial = true;
+let pre_stake_pool = global<StakePool>(pool_address);
 let post validator_info = global<ValidatorConfig>(pool_address);
 modifies global<ValidatorConfig>(pool_address);
 include StakedValueNochange;
@@ -6145,6 +6337,301 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
+
+
+
+
+
schema AddStakeWithCapAbortsIfAndEnsures {
+    owner_cap: OwnerCapability;
+    amount: u64;
+    let pool_address = owner_cap.pool_address;
+    aborts_if !exists<StakePool>(pool_address);
+    let config = global<staking_config::StakingConfig>(@supra_framework);
+    let validator_set = global<ValidatorSet>(@supra_framework);
+    let voting_power_increase_limit = config.voting_power_increase_limit;
+    let post post_validator_set = global<ValidatorSet>(@supra_framework);
+    let update_voting_power_increase = amount != 0 && (spec_contains(validator_set.active_validators, pool_address)
+                                                       || spec_contains(validator_set.pending_active, pool_address));
+    aborts_if update_voting_power_increase && validator_set.total_joining_power + amount > MAX_U128;
+    ensures update_voting_power_increase ==> post_validator_set.total_joining_power == validator_set.total_joining_power + amount;
+    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
+            && validator_set.total_voting_power * voting_power_increase_limit > MAX_U128;
+    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
+            && validator_set.total_joining_power + amount > validator_set.total_voting_power * voting_power_increase_limit / 100;
+    let stake_pool = global<StakePool>(pool_address);
+    let post post_stake_pool = global<StakePool>(pool_address);
+    let value_pending_active = stake_pool.pending_active.value;
+    let value_active = stake_pool.active.value;
+    ensures amount != 0 && spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.pending_active.value == value_pending_active + amount;
+    ensures amount != 0 && !spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.active.value == value_active + amount;
+    let maximum_stake = config.maximum_stake;
+    let value_pending_inactive = stake_pool.pending_inactive.value;
+    let next_epoch_voting_power = value_pending_active + value_active + value_pending_inactive;
+    let voting_power = next_epoch_voting_power + amount;
+    aborts_if amount != 0 && voting_power > MAX_U64;
+    aborts_if amount != 0 && voting_power > maximum_stake;
+}
+
+ + + + + + + +
schema AddStakeAbortsIfAndEnsures {
+    owner: signer;
+    amount: u64;
+    let owner_address = signer::address_of(owner);
+    aborts_if !exists<OwnerCapability>(owner_address);
+    let owner_cap = global<OwnerCapability>(owner_address);
+    include AddStakeWithCapAbortsIfAndEnsures { owner_cap };
+}
+
+ + + + + + + +
fun spec_is_allowed(account: address): bool {
+   if (!exists<AllowedValidators>(@supra_framework)) {
+       true
+   } else {
+       let allowed = global<AllowedValidators>(@supra_framework);
+       contains(allowed.accounts, account)
+   }
+}
+
+ + + + + + + +
fun spec_find_validator(v: vector<ValidatorInfo>, addr: address): Option<u64>;
+
+ + + + + + + +
fun spec_validators_are_initialized(validators: vector<ValidatorInfo>): bool {
+   forall i in 0..len(validators):
+       spec_has_stake_pool(validators[i].addr) &&
+           spec_has_validator_config(validators[i].addr)
+}
+
+ + + + + + + +
fun spec_validators_are_initialized_addrs(addrs: vector<address>): bool {
+   forall i in 0..len(addrs):
+       spec_has_stake_pool(addrs[i]) &&
+           spec_has_validator_config(addrs[i])
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid(validators: vector<ValidatorInfo>): bool {
+   spec_validator_indices_are_valid_addr(validators, spec_validator_index_upper_bound()) &&
+       spec_validator_indices_are_valid_config(validators, spec_validator_index_upper_bound())
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid_addr(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
+   forall i in 0..len(validators):
+       global<ValidatorConfig>(validators[i].addr).validator_index < upper_bound
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid_config(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
+   forall i in 0..len(validators):
+       validators[i].config.validator_index < upper_bound
+}
+
+ + + + + + + +
fun spec_validator_indices_active_pending_inactive(validator_set: ValidatorSet): bool {
+   len(validator_set.pending_inactive) + len(validator_set.active_validators) == spec_validator_index_upper_bound()
+}
+
+ + + + + + + +
fun spec_validator_index_upper_bound(): u64 {
+   len(global<ValidatorPerformance>(@supra_framework).validators)
+}
+
+ + + + + + + +
fun spec_has_stake_pool(a: address): bool {
+   exists<StakePool>(a)
+}
+
+ + + + + + + +
fun spec_has_validator_config(a: address): bool {
+   exists<ValidatorConfig>(a)
+}
+
+ + + + + + + +
fun spec_rewards_amount(
+   stake_amount: u64,
+   num_successful_proposals: u64,
+   num_total_proposals: u64,
+   rewards_rate: u64,
+   rewards_rate_denominator: u64,
+): u64;
+
+ + + + + + + +
fun spec_contains(validators: vector<ValidatorInfo>, addr: address): bool {
+   exists i in 0..len(validators): validators[i].addr == addr
+}
+
+ + + + + + + +
fun spec_is_current_epoch_validator(pool_address: address): bool {
+   let validator_set = global<ValidatorSet>(@supra_framework);
+   !spec_contains(validator_set.pending_active, pool_address)
+       && (spec_contains(validator_set.active_validators, pool_address)
+       || spec_contains(validator_set.pending_inactive, pool_address))
+}
+
+ + + + + + + +
schema ResourceRequirement {
+    requires exists<SupraCoinCapabilities>(@supra_framework);
+    requires exists<ValidatorPerformance>(@supra_framework);
+    requires exists<ValidatorSet>(@supra_framework);
+    requires exists<StakingConfig>(@supra_framework);
+    requires exists<StakingRewardsConfig>(@supra_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
+    requires exists<timestamp::CurrentTimeMicroseconds>(@supra_framework);
+    requires exists<ValidatorFees>(@supra_framework);
+}
+
+ + + + + + + +
fun spec_get_reward_rate_1(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           0
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           let nominator = aptos_std::fixed_point64::spec_multiply_u128(denominator, epoch_rewards_rate);
+           nominator
+       }
+   } else {
+           config.rewards_rate
+   }
+}
+
+ + + + + + + +
fun spec_get_reward_rate_2(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           1
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           denominator
+       }
+   } else {
+           config.rewards_rate_denominator
+   }
+}
+
+ + + ### Function `update_stake_pool` diff --git a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move index 56b1d51b147..971e111d9ea 100644 --- a/aptos-move/framework/supra-framework/tests/automation_registry_tests.move +++ b/aptos-move/framework/supra-framework/tests/automation_registry_tests.move @@ -4442,6 +4442,11 @@ module std::automation_registry_tests { user: &signer, ) { initialize_registry_test(supra_framework, user); + toggle_custom_feature_flags( + supra_framework, + vector[features::get_supra_automation_v2_1_feature()], + false, + ); // Expiry must be after the current time plus at least one cycle duration. let expiry_time = EPOCH_INTERVAL_FOR_TEST_IN_SECS + 86400; automation_registry::register_without_validation( @@ -4501,7 +4506,12 @@ module std::automation_registry_tests { user: &signer, ) { initialize_registry_test(supra_framework, user); - // V2_1 is not enabled — the function must abort immediately. + toggle_custom_feature_flags( + supra_framework, + vector[features::get_supra_automation_v2_1_feature()], + false, + ); + // V2_1 is not enabled, the function must abort immediately. let expiry_time = EPOCH_INTERVAL_FOR_TEST_IN_SECS + 86400; automation_registry::register_system_task_without_validation( user, From 931e81559ee774651daacfc76d7e4966a13d2ef0 Mon Sep 17 00:00:00 2001 From: Aregnaz Harutyunyan <89187359+aregng@users.noreply.github.com> Date: Thu, 11 Jun 2026 17:52:05 +0400 Subject: [PATCH 22/31] Fixed missing std::vector for gas-schedule update script (#364) Co-authored-by: Aregnaz Harutyunyan <> --- aptos-move/aptos-gas-schedule-updator/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/aptos-move/aptos-gas-schedule-updator/src/lib.rs b/aptos-move/aptos-gas-schedule-updator/src/lib.rs index 9442d92e140..8d528243368 100644 --- a/aptos-move/aptos-gas-schedule-updator/src/lib.rs +++ b/aptos-move/aptos-gas-schedule-updator/src/lib.rs @@ -65,6 +65,7 @@ fn generate_script(gas_schedule: &GasScheduleV2) -> Result { emitln!(writer, "use supra_framework::supra_governance;"); emitln!(writer, "use supra_framework::gas_schedule;"); + emitln!(writer, "use std::vector;"); emitln!(writer); emitln!(writer, "fun main(proposal_id: u64) {"); From 8bc4b56da346512722fd9992c301419c6b2728a7 Mon Sep 17 00:00:00 2001 From: Aregnaz Harutyunyan <89187359+aregng@users.noreply.github.com> Date: Tue, 16 Jun 2026 11:15:32 +0400 Subject: [PATCH 23/31] [Evm] Exposed convenience APIs for evm-configs (#366) * [Evm] Exposed convenience APIs for evm-configs * Addressed review comment --------- Co-authored-by: Aregnaz Harutyunyan <> --- types/src/on_chain_config/evm_config.rs | 25 ++++++++++------- .../src/on_chain_config/evm_genesis_config.rs | 27 +++++++++++++++++++ types/src/on_chain_config/mod.rs | 4 +-- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/types/src/on_chain_config/evm_config.rs b/types/src/on_chain_config/evm_config.rs index e3644621ba1..003569e460f 100644 --- a/types/src/on_chain_config/evm_config.rs +++ b/types/src/on_chain_config/evm_config.rs @@ -49,7 +49,20 @@ pub(crate) struct EvmContractsDetails { } pub const EVM_ADDRESS_LENGTH: usize = 20; -type RawEvmAddress = [u8; EVM_ADDRESS_LENGTH]; +pub type RawEvmAddress = [u8; EVM_ADDRESS_LENGTH]; + +/// Converts EVM(20bytes) Address to Move Address(32bytes) by left-padding it with 12 zero bytes. +pub fn evm_address_as_account_address(evm_address: &RawEvmAddress) -> AccountAddress { + // A Move `address` is 32 bytes serialised by BCS in big-endian order + // (most-significant byte at index 0). An EVM address is only 20 bytes, + // so we zero-pad the leading 12 bytes and place the EVM bytes at the + // tail (indices 12-31). This matches the invariant enforced by + // `is_valid_evm_address` in evm_config.move, which asserts that + // indices 0-11 are all zero. + let mut padded = [0u8; AccountAddress::LENGTH]; + padded[AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..].copy_from_slice(evm_address); + AccountAddress::from(padded) +} /// The Genesis configuration for EVM that can only be set once at genesis epoch. #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] @@ -64,17 +77,9 @@ impl OnChainEvmContractsDetails { .name_to_addresses .into_iter() .map(|(key, value)| { - // A Move `address` is 32 bytes serialised by BCS in big-endian order - // (most-significant byte at index 0). An EVM address is only 20 bytes, - // so we zero-pad the leading 12 bytes and place the EVM bytes at the - // tail (indices 12-31). This matches the invariant enforced by - // `is_valid_evm_address` in evm_config.move, which asserts that - // indices 0-11 are all zero. - let mut padded = [0u8; AccountAddress::LENGTH]; - padded[AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..].copy_from_slice(&value); ( MoveValue::vector_u8(key.to_string().into_bytes()), - AccountAddress::from(padded), + evm_address_as_account_address(&value) ) }) .unzip(); diff --git a/types/src/on_chain_config/evm_genesis_config.rs b/types/src/on_chain_config/evm_genesis_config.rs index ca66bdc826d..49391060400 100644 --- a/types/src/on_chain_config/evm_genesis_config.rs +++ b/types/src/on_chain_config/evm_genesis_config.rs @@ -1,6 +1,7 @@ // Copyright (c) Supra Foundation // SPDX-License-Identifier: Apache-2.0 +use std::fmt::Display; use super::OnChainConfig; use crate::chain_id::ChainId; use anyhow::{anyhow, Result}; @@ -21,6 +22,17 @@ pub struct OnChainEvmGenesisConfig { pub contracts: Vec, } +impl Display for OnChainEvmGenesisConfig { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "OnChainEvmGenesisConfig {{\n\t chain_id: {},\n\t eoas: {:?}, \n\t contracts: [{}\n\t]\n}}", + self.chain_id, self.eoas, self.contracts.iter().map(|c| format!("\n\t\t{}", c)).collect::>().join(", "), + ) + } + +} + #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct GenesisEvmEOA { /// The address of the EOA to be funded @@ -55,6 +67,21 @@ pub struct GenesisEvmContract { pub deploy_address: String, } +impl Display for GenesisEvmContract { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "GenesisEvmContract {{ creator: {}, nonce: {}, amount: {}, bytecode: {} bytes, kind: {:?}, deploy_address: {} }}", + self.creator, + self.nonce, + self.amount, + hex::encode(&self.bytecode), + self.kind, + self.deploy_address + ) + } +} + impl OnChainEvmGenesisConfig { /// Create a new OnChainEvmGenesisConfig with the given parameters. pub fn new( diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs index e3ade280f2c..fb803e6ad47 100644 --- a/types/src/on_chain_config/mod.rs +++ b/types/src/on_chain_config/mod.rs @@ -57,11 +57,11 @@ pub use self::{ ValidatorTxnConfig, }, evm_config::{ - EvmContractName, EvmScalarConfigKey, OnChainEvmConfig, OnChainEvmContractsDetails, + EvmContractName, EvmScalarConfigKey, OnChainEvmConfig, OnChainEvmContractsDetails, evm_address_as_account_address }, evm_genesis_config::{ ContractKind, GenesisEvmContract, GenesisEvmEOA, OnChainEvmGenesisConfig, - EVM_GENESIS_EVENT_MOVE_TYPE_TAG, + EVM_GENESIS_EVENT_MOVE_TYPE_TAG }, execution_config::{ BlockGasLimitType, ExecutionConfigV1, ExecutionConfigV2, ExecutionConfigV4, From 536e1a37d43597a06476381c7b41ce1e9fcee807 Mon Sep 17 00:00:00 2001 From: Dhaval Purohit Date: Wed, 17 Jun 2026 12:17:08 +0530 Subject: [PATCH 24/31] Fixed building issue and test cases --- .github/workflows/aptos-framework-test.yaml | 4 +- Cargo.lock | 5259 +++++++++++------ Cargo.toml | 8 +- api/types/src/transaction.rs | 38 +- aptos-move/aptos-vm/src/aptos_vm.rs | 18 +- aptos-move/aptos-vm/src/aptos_vm_viewer.rs | 2 +- .../aptos-vm/src/transaction_metadata.rs | 11 +- .../aptos-vm/src/transaction_validation.rs | 2 - aptos-move/aptos-vm/src/validator_txns/dkg.rs | 7 +- aptos-move/e2e-move-tests/src/harness.rs | 1 + aptos-move/e2e-move-tests/src/lib.rs | 2 +- .../src/tests/fungible_asset.rs | 6 +- .../src/tests/keyless_feature_gating.rs | 4 +- aptos-move/e2e-testsuite/src/lib.rs | 6 + .../src/tests/automation_registration.rs | 11 +- .../framework/move-stdlib/doc/features.md | 16 +- .../supra-framework/doc/aggregator_v2.md | 2 +- .../framework/supra-framework/doc/block.md | 6 +- .../supra-framework/doc/dkg_config.md | 2 +- .../supra-framework/doc/fungible_asset.md | 44 +- .../framework/supra-framework/doc/genesis.md | 95 +- .../doc/leader_ban_registry_config.md | 2 +- .../supra-framework/doc/randomness.md | 4 +- .../framework/supra-framework/doc/stake.md | 870 ++- .../supra-framework/doc/supra_governance.md | 35 - .../sources/configs/dkg_config.move | 2 +- .../configs/leader_ban_registry_config.move | 2 +- .../supra-framework/sources/genesis.move | 3 +- .../supra-framework/sources/stake.move | 156 +- .../supra-framework/sources/stake.spec.move | 2 +- aptos-move/vm-genesis/src/lib.rs | 24 +- config/src/config/identity_config.rs | 2 +- execution/executor-types/src/lib.rs | 2 +- types/Cargo.toml | 1 + types/src/aptos_dkg/mod.rs | 219 - types/src/contract_event.rs | 112 +- types/src/{aptos_dkg => dkg}/dummy_dkg/mod.rs | 6 +- .../src/{aptos_dkg => dkg}/dummy_dkg/tests.rs | 2 +- types/src/dkg/mod.rs | 87 +- types/src/{aptos_dkg => dkg}/real_dkg/mod.rs | 2 +- .../real_dkg/rounding/mod.rs | 0 .../real_dkg/rounding/tests.rs | 2 +- types/src/lib.rs | 1 - types/src/transaction/mod.rs | 8 - types/src/unit_tests/automation.rs | 12 +- types/src/validator_txn.rs | 4 +- 46 files changed, 4237 insertions(+), 2867 deletions(-) delete mode 100644 types/src/aptos_dkg/mod.rs rename types/src/{aptos_dkg => dkg}/dummy_dkg/mod.rs (97%) rename types/src/{aptos_dkg => dkg}/dummy_dkg/tests.rs (99%) rename types/src/{aptos_dkg => dkg}/real_dkg/mod.rs (99%) rename types/src/{aptos_dkg => dkg}/real_dkg/rounding/mod.rs (100%) rename types/src/{aptos_dkg => dkg}/real_dkg/rounding/tests.rs (99%) diff --git a/.github/workflows/aptos-framework-test.yaml b/.github/workflows/aptos-framework-test.yaml index d3eba885a1a..d8175cf15dd 100644 --- a/.github/workflows/aptos-framework-test.yaml +++ b/.github/workflows/aptos-framework-test.yaml @@ -53,7 +53,7 @@ jobs: run: cargo test --release -p aptos-framework -- --skip prover - name: Run language e2e tests - run: RUST_MIN_STACK=104857600 cargo test run -p language-e2e-testsuite --no-fail-fast + run: RUST_MIN_STACK=104857600 cargo test -p language-e2e-testsuite --no-fail-fast - name: Run move e2e tests - run: RUST_MIN_STACK=104857600 cargo test run -p e2e-move-tests --no-fail-fast + run: RUST_MIN_STACK=104857600 cargo test -p e2e-move-tests --no-fail-fast diff --git a/Cargo.lock b/Cargo.lock index afe0f79cb2a..cdd91ee8420 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,9 +24,9 @@ dependencies = [ [[package]] name = "addchain" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +checksum = "2e33f6a175ec6a9e0aca777567f9ff7c3deefc255660df887e7fa3585e9801d8" dependencies = [ "num-bigint 0.3.3", "num-integer", @@ -54,7 +54,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array", ] @@ -66,7 +66,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -112,7 +112,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.11", + "const-random", + "getrandom 0.3.4", "once_cell", "serde", "version_check", @@ -151,9 +152,9 @@ dependencies = [ [[package]] name = "allocative" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "082af274fd02beef17b7f0725a49ecafe6c075ef56cac9d6363eb3916a9817ae" +checksum = "d8cf9afc79c83d514444b55df3935d317da54b1ce3b17a133c646889cc260de8" dependencies = [ "allocative_derive", "ctor", @@ -161,26 +162,32 @@ dependencies = [ [[package]] name = "allocative_derive" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe233a377643e0fc1a56421d7c90acdec45c291b30345eb9f08e8d0ddce5a4ab" +checksum = "614043c56c1173b800acb007b81fd0cbc0a0d7d717b71ba705fc2230d0760a23" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] name = "allocator-api2" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] -name = "android-tzdata" -version = "0.1.1" +name = "ambassador" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "e68de4cdc6006162265d0957edb4a860fe4e711b1dc17a5746fd95f952f08285" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "android_system_properties" @@ -198,7 +205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" dependencies = [ "anstyle", - "unicode-width 0.2.0", + "unicode-width 0.2.2", ] [[package]] @@ -218,9 +225,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -233,15 +240,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -257,12 +264,13 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] @@ -273,12 +281,9 @@ checksum = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" -dependencies = [ - "backtrace", -] +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "approx" @@ -333,9 +338,10 @@ dependencies = [ "bcs 0.1.4", "bollard", "chrono", - "clap 4.4.14", + "clap 4.6.1", "clap_complete", - "dashmap", + "colored", + "dashmap 7.0.0-rc2", "diesel", "diesel-async", "dirs 5.0.1", @@ -367,7 +373,7 @@ dependencies = [ "poem", "rand 0.7.3", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "self_update", "serde", "serde_json", @@ -380,7 +386,7 @@ dependencies = [ "tokio", "toml 0.7.8", "tracing", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.23", "url", ] @@ -423,8 +429,9 @@ dependencies = [ "aptos-system-utils 0.1.0", "aptos-types", "bcs 0.1.4", - "http", - "hyper", + "futures-channel", + "http 0.2.12", + "hyper 0.14.32", "sha256", "tokio", "url", @@ -491,7 +498,7 @@ dependencies = [ "proptest", "rand 0.7.3", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tokio", @@ -525,7 +532,7 @@ dependencies = [ "bcs 0.1.4", "bytes", "goldenfile", - "hyper 0.14.28", + "hyper 0.14.32", "rand 0.7.3", "regex", "serde_json", @@ -615,7 +622,7 @@ dependencies = [ "async-trait", "bcs 0.1.4", "bytes", - "clap 4.4.14", + "clap 4.6.1", "csv", "futures", "itertools 0.13.0", @@ -623,11 +630,11 @@ dependencies = [ "move-bytecode-verifier", "num_cpus", "once_cell", - "pin-project 1.1.3", + "pin-project 1.1.13", "proptest", "rand 0.7.3", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "serde_yaml 0.8.26", @@ -654,9 +661,9 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "bytes", - "hyper 0.14.28", + "hyper 0.14.32", "once_cell", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "tokio", "tokio-stream", @@ -710,10 +717,9 @@ dependencies = [ "concurrent-queue", "criterion", "crossbeam", - "dashmap", "derivative", "fail", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "itertools 0.13.0", "move-binary-format", "move-core-types", @@ -739,10 +745,10 @@ dependencies = [ "aptos-metrics-core", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "criterion", - "dashmap", - "itertools 0.12.1", + "dashmap 7.0.0-rc2", + "itertools 0.13.0", "jemallocator", "move-core-types", "once_cell", @@ -789,13 +795,13 @@ dependencies = [ "anyhow", "camino", "chrono", - "clap 4.4.14", + "clap 4.6.1", "clap-verbosity-flag", "determinator", "env_logger 0.10.2", "guppy", "log", - "reqwest 0.11.23", + "reqwest 0.11.27", "url", ] @@ -816,7 +822,7 @@ name = "aptos-cli-common" version = "1.0.0" dependencies = [ "anstyle", - "clap 4.4.14", + "clap 4.6.1", "clap_complete", ] @@ -838,7 +844,7 @@ dependencies = [ "aptos-validator-interface", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "futures", "itertools 0.13.0", "legacy-move-compiler", @@ -895,8 +901,8 @@ dependencies = [ "serde_json", "serde_merge", "serde_yaml 0.8.26", - "strum 0.27.1", - "strum_macros 0.27.1", + "strum 0.27.2", + "strum_macros 0.27.2", "tempfile", "thiserror 1.0.69", "url", @@ -953,8 +959,8 @@ dependencies = [ "bytes", "chrono", "claims", - "clap 4.4.14", - "dashmap", + "clap 4.6.1", + "dashmap 7.0.0-rc2", "enum_dispatch", "fail", "futures", @@ -980,8 +986,8 @@ dependencies = [ "serde_bytes", "serde_json", "sha3 0.9.1", - "strum 0.27.1", - "strum_macros 0.27.1", + "strum 0.27.2", + "strum_macros 0.27.2", "tempfile", "thiserror 1.0.69", "tokio", @@ -1076,7 +1082,7 @@ dependencies = [ "ed25519-dalek 1.0.1", "ff 0.13.1", "hex", - "hkdf 0.10.0", + "hkdf", "libsecp256k1", "merlin", "more-asserts", @@ -1143,13 +1149,13 @@ dependencies = [ "async-trait", "bcs 0.1.4", "claims", - "dashmap", + "dashmap 7.0.0-rc2", "futures", "itertools 0.13.0", "maplit", "mockall 0.11.4", "ordered-float 3.9.2", - "rand 0.8.5", + "rand 0.8.6", "serde", "thiserror 1.0.69", "tokio", @@ -1213,9 +1219,9 @@ dependencies = [ "bcs 0.1.4", "byteorder", "claims", - "clap 4.4.14", + "clap 4.6.1", "crossbeam-channel", - "dashmap", + "dashmap 7.0.0-rc2", "either", "hex", "indicatif 0.15.0", @@ -1252,7 +1258,7 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "bytes", - "dashmap", + "dashmap 7.0.0-rc2", "move-core-types", "once_cell", "rand 0.7.3", @@ -1297,8 +1303,10 @@ dependencies = [ "aptos-types", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", - "itertools 0.12.1", + "clap 4.6.1", + "itertools 0.13.0", + "rayon", + "serde_json", "tokio", ] @@ -1312,7 +1320,7 @@ dependencies = [ "aptos-logger", "aptos-move-debugger", "aptos-push-metrics", - "clap 4.4.14", + "clap 4.6.1", "jemallocator", "tokio", ] @@ -1406,7 +1414,7 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "e2e-move-tests", - "getrandom 0.2.11", + "getrandom 0.2.17", "move-binary-format", "move-bytecode-verifier", "move-core-types", @@ -1451,20 +1459,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "aptos-executable-store" -version = "0.1.0" -dependencies = [ - "aptos-infallible", - "aptos-logger", - "aptos-types", - "claims", - "dashmap", - "proptest", - "proptest-derive", - "rayon", -] - [[package]] name = "aptos-executor" version = "0.1.0" @@ -1496,7 +1490,7 @@ dependencies = [ "arr_macro", "bcs 0.1.4", "bytes", - "dashmap", + "criterion", "fail", "itertools 0.13.0", "move-core-types", @@ -1546,7 +1540,8 @@ dependencies = [ "bcs 0.1.4", "bytes", "chrono", - "clap 4.4.14", + "clap 4.6.1", + "dashmap 7.0.0-rc2", "derivative", "indicatif 0.15.0", "itertools 0.13.0", @@ -1583,11 +1578,11 @@ dependencies = [ "aptos-types", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "crossbeam-channel", "ctrlc", - "dashmap", - "itertools 0.12.1", + "dashmap 7.0.0-rc2", + "itertools 0.13.0", "num_cpus", "once_cell", "rayon", @@ -1632,7 +1627,7 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "criterion", - "derive_more 2.0.1", + "derive_more 2.1.1", "itertools 0.13.0", "once_cell", "ouroboros", @@ -1653,10 +1648,10 @@ dependencies = [ "aptos-transaction-generator-lib", "bcs 0.1.4", "chrono", - "clap 4.5.21", + "clap 4.6.1", "futures", "rand 0.7.3", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tokio", @@ -1683,7 +1678,7 @@ dependencies = [ name = "aptos-experimental-layered-map" version = "0.1.0" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "anyhow", "aptos-crypto", "aptos-drop-helper", @@ -1748,7 +1743,7 @@ dependencies = [ "aptos-faucet-core", "aptos-logger", "aptos-sdk", - "clap 4.4.14", + "clap 4.6.1", "tokio", ] @@ -1764,7 +1759,7 @@ dependencies = [ "aptos-sdk", "async-trait", "captcha", - "clap 4.4.14", + "clap 4.6.1", "deadpool-redis", "enum_dispatch", "firebase-token", @@ -1778,7 +1773,7 @@ dependencies = [ "poem-openapi", "rand 0.7.3", "redis", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "serde_yaml 0.8.26", @@ -1805,7 +1800,7 @@ dependencies = [ "anyhow", "aptos-faucet-core", "aptos-logger", - "clap 4.4.14", + "clap 4.6.1", "tokio", ] @@ -1817,11 +1812,11 @@ dependencies = [ "aptos-logger", "aptos-node-checker", "aptos-sdk", - "clap 4.4.14", - "env_logger", + "clap 4.6.1", + "env_logger 0.10.2", "futures", "gcp-bigquery-client", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tokio", @@ -1855,11 +1850,11 @@ dependencies = [ "aptos-transaction-workloads-lib", "async-trait", "chrono", - "clap 4.4.14", + "clap 4.6.1", "either", "futures", "hex", - "hyper 0.14.28", + "hyper 0.14.32", "itertools 0.13.0", "json-patch", "k8s-openapi", @@ -1871,7 +1866,7 @@ dependencies = [ "quick-junit", "rand 0.7.3", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "serde_merge", @@ -1882,7 +1877,7 @@ dependencies = [ "thiserror 1.0.69", "tokio", "url", - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] @@ -1900,13 +1895,14 @@ dependencies = [ "aptos-testcases", "async-trait", "chrono", - "clap 4.4.14", + "clap 4.6.1", + "env_logger 0.10.2", "futures", "jemallocator", "once_cell", "rand 0.7.3", "random_word", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde_json", "serde_yaml 0.8.26", "sugars", @@ -1945,7 +1941,7 @@ dependencies = [ "bulletproofs 5.0.0", "byteorder", "claims", - "clap 4.4.14", + "clap 4.6.1", "codespan-reporting", "crypto", "curve25519-dalek-ng", @@ -1989,7 +1985,6 @@ dependencies = [ "siphasher 0.3.11", "smallvec", "tempfile", - "thiserror", "tiny-keccak", "toml 0.7.8", ] @@ -2015,7 +2010,7 @@ dependencies = [ "aptos-language-e2e-tests", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "float-cmp", "move-binary-format", "move-core-types", @@ -2080,7 +2075,7 @@ dependencies = [ "aptos-package-builder", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "move-core-types", "move-model", "tempfile", @@ -2174,14 +2169,14 @@ dependencies = [ "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=62beedc881d1b76632318ceb186ee9065236468e)", "aptos-protos 1.3.1", "async-trait", - "clap 4.4.14", + "clap 4.6.1", "futures", "futures-core", "jemallocator", "once_cell", - "prost 0.13.4", + "prost 0.13.5", "redis", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "tempfile", "tokio", @@ -2202,11 +2197,11 @@ dependencies = [ "aptos-protos 1.3.1", "aptos-transaction-filter 0.1.0", "async-trait", - "clap 4.4.14", + "clap 4.6.1", "futures", "jemallocator", "once_cell", - "prost 0.13.4", + "prost 0.13.5", "redis", "rstest", "serde", @@ -2216,7 +2211,7 @@ dependencies = [ "tonic 0.12.3", "tonic-reflection", "tracing", - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] @@ -2231,12 +2226,12 @@ dependencies = [ "aptos-transaction-filter 0.1.0", "async-trait", "build_html", - "clap 4.5.21", + "clap 4.6.1", "dashmap 7.0.0-rc2", "futures", "jemallocator", "once_cell", - "prost 0.13.4", + "prost 0.13.5", "rand 0.7.3", "serde", "tokio", @@ -2245,7 +2240,7 @@ dependencies = [ "tonic 0.12.3", "tonic-reflection", "tracing", - "uuid 1.11.0", + "uuid 1.23.2", "warp", ] @@ -2258,7 +2253,7 @@ dependencies = [ "aptos-indexer-grpc-utils", "aptos-metrics-core", "async-trait", - "clap 4.5.21", + "clap 4.6.1", "cloud-storage", "jemallocator", "once_cell", @@ -2278,7 +2273,7 @@ dependencies = [ "aptos-metrics-core", "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processors.git?rev=62beedc881d1b76632318ceb186ee9065236468e)", "async-trait", - "clap 4.4.14", + "clap 4.6.1", "futures", "jemallocator", "once_cell", @@ -2297,7 +2292,7 @@ dependencies = [ "aptos-indexer-grpc-utils", "aptos-protos 1.3.1", "async-trait", - "clap 4.5.21", + "clap 4.6.1", "futures", "jemallocator", "serde", @@ -2347,7 +2342,7 @@ dependencies = [ "futures", "goldenfile", "hex", - "hyper 0.14.28", + "hyper 0.14.32", "itertools 0.13.0", "move-core-types", "once_cell", @@ -2389,12 +2384,12 @@ dependencies = [ "aptos-protos 1.3.1", "async-trait", "build_html", - "clap 4.5.21", + "clap 4.6.1", "dashmap 7.0.0-rc2", "futures", "jemallocator", "once_cell", - "prost 0.13.4", + "prost 0.13.5", "rand 0.7.3", "serde", "serde_json", @@ -2414,14 +2409,15 @@ dependencies = [ "aptos-system-utils 0.1.0", "async-trait", "backtrace", - "clap 4.4.14", + "clap 4.6.1", + "figment", "prometheus", "serde", "tempfile", "tokio", "toml 0.7.8", "tracing", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.23", "warp", ] @@ -2445,7 +2441,7 @@ dependencies = [ "flate2", "futures", "google-cloud-storage", - "hyper 0.14.28", + "hyper 0.14.32", "itertools 0.13.0", "once_cell", "rocksdb", @@ -2455,8 +2451,7 @@ dependencies = [ "tempfile", "tokio", "tokio-stream", - "tokio-util 0.7.10", - "tonic", + "tokio-util 0.7.18", ] [[package]] @@ -2474,21 +2469,150 @@ dependencies = [ "bytesize", "chrono", "cloud-storage", - "dashmap", + "dashmap 7.0.0-rc2", "futures", "itertools 0.13.0", "lz4", "once_cell", "prometheus", - "prost 0.13.4", + "prost 0.13.5", "redis", "redis-test", "ripemd", "serde", "serde_json", "tokio", - "tokio-util 0.7.10", - "tonic", + "tokio-util 0.7.18", + "tonic 0.12.3", + "tracing", + "url", + "warp", +] + +[[package]] +name = "aptos-indexer-grpc-v2-file-store-backfiller" +version = "1.0.0" +dependencies = [ + "anyhow", + "aptos-indexer-grpc-server-framework", + "aptos-indexer-grpc-utils", + "aptos-protos 1.3.1", + "async-trait", + "clap 4.6.1", + "futures", + "jemallocator", + "serde", + "serde_json", + "tokio", + "tokio-scoped", + "tonic 0.12.3", + "tracing", + "url", +] + +[[package]] +name = "aptos-indexer-processor-sdk" +version = "0.1.0" +source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2#188ba1a37597739a2e503165dec0c3fcc63c89ec" +dependencies = [ + "ahash 0.8.12", + "anyhow", + "aptos-indexer-transaction-stream", + "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686)", + "aptos-system-utils 0.1.0 (git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686)", + "async-trait", + "autometrics", + "axum 0.7.9", + "backtrace", + "bcs 0.1.4", + "bigdecimal", + "chrono", + "clap 4.6.1", + "derive_builder", + "diesel", + "diesel-async", + "diesel_migrations", + "field_count", + "futures", + "futures-util", + "hex", + "indexmap 2.14.0", + "instrumented-channel", + "kanal", + "mockall 0.12.1", + "native-tls", + "num_cpus", + "once_cell", + "petgraph 0.6.5", + "postgres-native-tls", + "prometheus", + "prometheus-client", + "serde", + "serde_json", + "serde_yaml 0.8.26", + "sha2 0.9.9", + "tempfile", + "thiserror 1.0.69", + "tiny-keccak", + "tokio", + "tokio-postgres", + "toml 0.7.8", + "tracing", + "tracing-subscriber 0.3.23", + "url", +] + +[[package]] +name = "aptos-indexer-test-transactions" +version = "1.0.0" +dependencies = [ + "aptos-protos 1.3.1", + "serde_json", +] + +[[package]] +name = "aptos-indexer-transaction-generator" +version = "1.0.0" +dependencies = [ + "anyhow", + "aptos", + "aptos-config", + "aptos-faucet-core", + "aptos-indexer-grpc-utils", + "aptos-protos 1.3.1", + "clap 4.6.1", + "futures", + "itertools 0.13.0", + "rand 0.7.3", + "serde", + "serde_json", + "serde_yaml 0.8.26", + "tempfile", + "tokio", + "tokio-stream", + "toml 0.7.8", + "tonic 0.12.3", + "url", +] + +[[package]] +name = "aptos-indexer-transaction-stream" +version = "0.1.0" +source = "git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2#188ba1a37597739a2e503165dec0c3fcc63c89ec" +dependencies = [ + "anyhow", + "aptos-moving-average 0.1.0 (git+https://github.com/aptos-labs/aptos-indexer-processor-sdk.git?tag=aptos-indexer-processor-sdk-v2.1.2)", + "aptos-protos 1.3.1 (git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686)", + "aptos-transaction-filter 0.1.0 (git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686)", + "chrono", + "futures-util", + "once_cell", + "prometheus", + "prost 0.13.5", + "sample", + "serde", + "tokio", + "tonic 0.12.3", "tracing", "url", ] @@ -2515,10 +2639,10 @@ dependencies = [ "aptos-time-service", "assert_approx_eq", "futures", - "hyper 0.14.28", + "hyper 0.14.32", "once_cell", "prometheus", - "reqwest 0.11.23", + "reqwest 0.11.27", "rusty-fork", "serde_json", "tokio", @@ -2595,9 +2719,9 @@ version = "0.1.0" dependencies = [ "anyhow", "aptos-types", - "http", + "http 0.2.12", "move-core-types", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tokio", @@ -2612,48 +2736,6 @@ dependencies = [ "rand 0.7.3", ] -[[package]] -name = "aptos-keyless-circuit" -version = "0.1.0" -dependencies = [ - "anyhow", - "aptos-crypto", - "aptos-keyless-common", - "aptos-logger", - "ark-bn254", - "ark-ff", - "base64 0.13.1", - "hex", - "itertools 0.12.1", - "num-bigint 0.3.3", - "num-modular", - "num-traits", - "rand 0.7.3", - "rand_chacha 0.3.1", - "rsa 0.9.6", - "serde_json", - "sha2 0.9.9", - "tempfile", - "tokio", -] - -[[package]] -name = "aptos-keyless-common" -version = "0.1.0" -dependencies = [ - "anyhow", - "aptos-types", - "ark-bn254", - "ark-ff", - "base64 0.13.1", - "hex", - "num-bigint 0.3.3", - "serde", - "serde_json", - "tempfile", - "tracing", -] - [[package]] name = "aptos-keyless-pepper-common" version = "0.1.0" @@ -2696,7 +2778,7 @@ dependencies = [ "bcs 0.1.4", "firestore", "hex", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde_json", "tokio", ] @@ -2721,20 +2803,21 @@ dependencies = [ "ark-groth16", "ark-serialize", "bcs 0.1.4", - "dashmap", + "dashmap 7.0.0-rc2", + "firestore", "hex", - "hyper 0.14.28", + "hyper 0.14.32", "jsonwebtoken 8.3.0", "jwt", "once_cell", "rand 0.7.3", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "sha3 0.9.1", "tokio", - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] @@ -2811,7 +2894,7 @@ dependencies = [ "dirs 5.0.1", "futures", "processor", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tokio", @@ -2847,11 +2930,11 @@ dependencies = [ "prometheus", "serde", "serde_json", - "strum 0.27.1", - "strum_macros 0.27.1", + "strum 0.27.2", + "strum_macros 0.27.2", "tokio", "tracing", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.23", ] [[package]] @@ -2960,9 +3043,10 @@ dependencies = [ "aptos-vm-logging", "aptos-vm-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", + "itertools 0.13.0", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "tokio", "url", ] @@ -2976,7 +3060,7 @@ dependencies = [ "aptos-transaction-generator-lib", "aptos-transaction-workloads-lib", "aptos-types", - "clap 4.5.21", + "clap 4.6.1", "rand 0.7.3", "serde_json", ] @@ -2989,7 +3073,7 @@ dependencies = [ "aptos-gas-schedule", "aptos-types", "aptos-vm", - "clap 4.4.14", + "clap 4.6.1", "move-cli", "move-model", "move-package", @@ -3050,8 +3134,9 @@ dependencies = [ "claims", "concurrent-queue", "crossbeam", - "dashmap", - "derivative", + "dashmap 7.0.0-rc2", + "equivalent", + "fail", "move-binary-format", "move-core-types", "move-vm-runtime", @@ -3087,7 +3172,7 @@ dependencies = [ "aptos-types", "bytes", "futures", - "pin-project 1.1.3", + "pin-project 1.1.13", "serde", "tokio", "tokio-util 0.7.18", @@ -3127,11 +3212,11 @@ dependencies = [ "maplit", "once_cell", "ordered-float 3.9.2", - "pin-project 1.1.3", + "pin-project 1.1.13", "proptest", "proptest-derive", "rand 0.7.3", - "rand 0.8.5", + "rand 0.8.6", "rand_core 0.5.1", "serde", "serde_bytes", @@ -3194,7 +3279,7 @@ dependencies = [ "aptos-logger", "aptos-network", "aptos-types", - "clap 4.4.14", + "clap 4.6.1", "futures", "serde", "tokio", @@ -3231,16 +3316,16 @@ dependencies = [ name = "aptos-nft-metadata-crawler" version = "0.1.0" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "anyhow", "aptos-indexer-grpc-server-framework", "aptos-metrics-core", "async-trait", - "axum 0.7.5", + "axum 0.7.9", "backoff", "bytes", "chrono", - "clap 4.4.14", + "clap 4.6.1", "diesel", "diesel_migrations", "enum_dispatch", @@ -3251,7 +3336,7 @@ dependencies = [ "once_cell", "rayon", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "sha256", @@ -3316,7 +3401,7 @@ dependencies = [ "aptos-vm", "aptos-vm-environment", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "either", "fail", "futures", @@ -3349,13 +3434,13 @@ dependencies = [ "aptos-transaction-emitter-lib", "aptos-transaction-workloads-lib", "async-trait", - "clap 4.4.14", + "clap 4.6.1", "futures", "once_cell", "poem", "poem-openapi", "prometheus-parse", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "serde_yaml 0.8.26", @@ -3420,7 +3505,7 @@ dependencies = [ "aptos-mempool", "aptos-storage-interface", "aptos-types", - "clap 4.4.14", + "clap 4.6.1", ] [[package]] @@ -3547,7 +3632,7 @@ version = "1.3.1" dependencies = [ "futures-core", "pbjson", - "prost 0.13.4", + "prost 0.13.5", "serde", "tonic 0.12.3", ] @@ -3558,7 +3643,7 @@ version = "1.3.1" source = "git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686#2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686" dependencies = [ "pbjson", - "prost 0.13.4", + "prost 0.13.5", "serde", "tonic 0.12.3", ] @@ -3589,7 +3674,7 @@ dependencies = [ "aptos-logger", "aptos-metrics-core", "futures", - "pin-project 1.1.3", + "pin-project 1.1.13", "tokio", "tokio-util 0.7.18", ] @@ -3620,7 +3705,7 @@ dependencies = [ "aptos-vm-logging", "aptos-vm-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "futures", "git2 0.16.1", "handlebars", @@ -3632,13 +3717,13 @@ dependencies = [ "move-vm-runtime", "move-vm-types", "once_cell", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "serde_yaml 0.8.26", "sha3 0.9.1", - "strum 0.27.1", - "strum_macros 0.27.1", + "strum 0.27.2", + "strum_macros 0.27.2", "tokio", "url", "walkdir", @@ -3683,10 +3768,10 @@ dependencies = [ "aptos-vm-environment", "bcs 0.1.4", "claims", - "clap 4.5.21", + "clap 4.6.1", "colored", "move-core-types", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "rand 0.7.3", "serde", "tokio", @@ -3719,10 +3804,10 @@ dependencies = [ "aptos-types", "bcs 0.1.4", "bytes", - "clap 4.4.14", + "clap 4.6.1", "hex", "move-core-types", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "thiserror 1.0.69", @@ -3763,13 +3848,13 @@ dependencies = [ "aptos-types", "aptos-warp-webserver", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "futures", "hex", "itertools 0.13.0", "move-core-types", "once_cell", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tokio", @@ -3786,7 +3871,7 @@ dependencies = [ "aptos-logger", "aptos-rosetta", "aptos-types", - "clap 4.4.14", + "clap 4.6.1", "serde", "serde_json", "tokio", @@ -3890,7 +3975,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "rand_core 0.5.1", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tiny-bip39", @@ -3907,7 +3992,7 @@ dependencies = [ "aptos-framework", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "heck 0.4.1", "move-core-types", "once_cell", @@ -4046,8 +4131,10 @@ dependencies = [ "aptos-types", "arr_macro", "bcs 0.1.4", - "crossbeam-channel", - "dashmap", + "dashmap 7.0.0-rc2", + "derive_more 2.1.1", + "itertools 0.13.0", + "lru", "once_cell", "parking_lot 0.12.5", "proptest", @@ -4055,8 +4142,7 @@ dependencies = [ "rand 0.7.3", "rayon", "serde", - "thiserror", - "threadpool", + "thiserror 1.0.69", ] [[package]] @@ -4106,7 +4192,7 @@ dependencies = [ "bcs 0.1.4", "bytes", "claims", - "dashmap", + "dashmap 7.0.0-rc2", "futures", "maplit", "mini-moka", @@ -4143,8 +4229,28 @@ dependencies = [ "anyhow", "aptos-profiler 0.1.0", "async-mutex", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.32", + "lazy_static", + "mime", + "pprof", + "regex", + "rstack-self", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "aptos-system-utils" +version = "0.1.0" +source = "git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686#2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686" +dependencies = [ + "anyhow", + "aptos-profiler 0.1.0 (git+https://github.com/aptos-labs/aptos-core.git?rev=2dd9c73b27fdcbe78c7391fd43c9a5d00b93e686)", + "async-mutex", + "http 0.2.12", + "hyper 0.14.32", "lazy_static", "mime", "pprof", @@ -4199,7 +4305,7 @@ dependencies = [ "prometheus", "rand 0.7.3", "rand_core 0.5.1", - "reqwest 0.11.23", + "reqwest 0.11.27", "reqwest-middleware", "reqwest-retry", "serde", @@ -4208,7 +4314,7 @@ dependencies = [ "tokio", "tokio-stream", "url", - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] @@ -4227,7 +4333,7 @@ dependencies = [ "bcs 0.1.4", "chrono", "claims", - "clap 4.4.14", + "clap 4.6.1", "debug-ignore", "flate2", "futures", @@ -4238,7 +4344,7 @@ dependencies = [ "prometheus", "rand 0.7.3", "rand_core 0.5.1", - "reqwest 0.11.23", + "reqwest 0.11.27", "reqwest-middleware", "reqwest-retry", "serde", @@ -4248,7 +4354,7 @@ dependencies = [ "tokio", "tracing", "url", - "uuid 1.11.0", + "uuid 1.23.2", "warp", ] @@ -4286,7 +4392,7 @@ dependencies = [ "itertools 0.13.0", "log", "rand 0.7.3", - "reqwest 0.11.23", + "reqwest 0.11.27", "tokio", ] @@ -4297,8 +4403,8 @@ dependencies = [ "aptos-infallible", "enum_dispatch", "futures", - "pin-project", - "thiserror", + "pin-project 1.1.13", + "thiserror 1.0.69", "tokio", "tokio-test", ] @@ -4320,7 +4426,7 @@ dependencies = [ "aptos-types", "aptos-vm", "aptos-vm-logging", - "clap 4.4.14", + "clap 4.6.1", "criterion", "criterion-cpu-time", "num_cpus", @@ -4336,7 +4442,8 @@ dependencies = [ "aptos-logger", "aptos-sdk", "aptos-transaction-emitter-lib", - "clap 4.4.14", + "aptos-transaction-workloads-lib", + "clap 4.6.1", "futures", "rand 0.7.3", "tokio", @@ -4358,7 +4465,8 @@ dependencies = [ "aptos-transaction-generator-lib", "aptos-types", "async-trait", - "clap 4.4.14", + "base64 0.13.1", + "clap 4.6.1", "futures", "hex", "itertools 0.13.0", @@ -4366,7 +4474,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "rand_core 0.5.1", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "tokio", @@ -4384,7 +4492,7 @@ dependencies = [ "lz4", "memchr", "once_cell", - "prost 0.13.4", + "prost 0.13.5", "serde", "serde_json", "serde_yaml 0.8.26", @@ -4402,11 +4510,11 @@ dependencies = [ "derive_builder", "memchr", "once_cell", - "prost 0.13.4", + "prost 0.13.5", "serde", "serde_json", "serde_yaml 0.8.26", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4431,16 +4539,53 @@ dependencies = [ "aptos-logger", "aptos-sdk", "async-trait", - "clap 4.4.14", + "clap 4.6.1", + "log", "move-binary-format", + "move-package", "once_cell", "rand 0.7.3", - "rand_core 0.5.1", "serde", ] [[package]] -name = "aptos-transactional-test-harness" +name = "aptos-transaction-simulation" +version = "0.0.1" +dependencies = [ + "anyhow", + "aptos-crypto", + "aptos-keygen", + "aptos-types", + "aptos-vm-genesis", + "bcs 0.1.4", + "bytes", + "move-binary-format", + "move-core-types", + "once_cell", + "parking_lot 0.12.5", + "proptest", + "serde", +] + +[[package]] +name = "aptos-transaction-workloads-lib" +version = "0.0.0" +dependencies = [ + "anyhow", + "aptos-framework", + "aptos-sdk", + "aptos-transaction-generator-lib", + "async-trait", + "clap 4.6.1", + "move-binary-format", + "once_cell", + "rand 0.7.3", + "rand_core 0.5.1", + "serde", +] + +[[package]] +name = "aptos-transactional-test-harness" version = "0.1.0" dependencies = [ "anyhow", @@ -4459,7 +4604,7 @@ dependencies = [ "aptos-vm-genesis", "aptos-vm-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "codespan-reporting", "datatest-stable", "hex", @@ -4503,11 +4648,13 @@ dependencies = [ "bcs 0.1.4", "bytes", "chrono", - "chrono-tz 0.10.1", + "chrono-tz 0.10.4", "ciborium", "claims", "coset", "criterion", + "crypto", + "dashmap 7.0.0-rc2", "derivative", "derive-getters", "derive_more 2.1.1", @@ -4539,7 +4686,7 @@ dependencies = [ "rand 0.7.3", "rayon", "ref-cast", - "reqwest 0.11.23", + "reqwest 0.11.27", "ring 0.16.20", "rsa 0.9.10", "serde", @@ -4548,9 +4695,9 @@ dependencies = [ "serde_json", "serde_with", "serde_yaml 0.8.26", - "strum 0.24.1", - "strum_macros 0.24.3", - "thiserror", + "strum 0.27.2", + "strum_macros 0.27.2", + "thiserror 1.0.69", "tokio", "tracing", "url", @@ -4674,7 +4821,7 @@ dependencies = [ "aptos-language-e2e-tests", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "move-binary-format", "move-core-types", ] @@ -4716,6 +4863,9 @@ dependencies = [ "aptos-vm-types", "bcs 0.1.4", "bytes", + "claims", + "crypto", + "move-binary-format", "move-core-types", "move-vm-runtime", "move-vm-types", @@ -4755,7 +4905,7 @@ dependencies = [ "aptos-types", "aptos-vm", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "glob", "move-binary-format", "move-core-types", @@ -4827,7 +4977,7 @@ dependencies = [ "aptos-config", "aptos-logger", "bcs 0.1.4", - "hyper 0.14.28", + "hyper 0.14.32", "serde", "serde_json", "warp", @@ -4846,7 +4996,7 @@ dependencies = [ "aptos-node", "aptos-types", "bollard", - "clap 4.5.21", + "clap 4.6.1", "diesel", "diesel-async", "futures", @@ -4855,25 +5005,25 @@ dependencies = [ "rand 0.7.3", "tempfile", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "url", - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] [[package]] name = "arc-swap" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ded5f9a03ac8f24d1b8a25101ee812cd32cdc8c50a4c50237de2c4915850e73" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] @@ -4916,7 +5066,8 @@ dependencies = [ "blake2", "derivative", "digest 0.10.7", - "sha2 0.10.8", + "rayon", + "sha2 0.10.9", ] [[package]] @@ -5065,7 +5216,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", "rayon", ] @@ -5168,28 +5319,26 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.11" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5" +checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac" dependencies = [ - "brotli", - "flate2", - "futures-core", - "memchr", + "compression-codecs", + "compression-core", "pin-project-lite", "tokio", ] [[package]] name = "async-executor" -version = "1.13.3" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.3.0", - "futures-lite 2.6.1", + "fastrand", + "futures-lite", "pin-project-lite", "slab", ] @@ -5205,7 +5354,7 @@ dependencies = [ "async-io", "async-lock", "blocking", - "futures-lite 2.6.1", + "futures-lite", "once_cell", ] @@ -5219,10 +5368,10 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "parking", - "polling 3.11.0", - "rustix 1.1.3", + "polling", + "rustix 1.1.4", "slab", "windows-sys 0.61.2", ] @@ -5270,8 +5419,8 @@ dependencies = [ "blocking", "cfg-if", "event-listener 5.4.1", - "futures-lite 2.6.1", - "rustix 1.1.3", + "futures-lite", + "rustix 1.1.4", ] [[package]] @@ -5282,14 +5431,14 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] name = "async-signal" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" dependencies = [ "async-io", "async-lock", @@ -5297,7 +5446,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.3", + "rustix 1.1.4", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -5318,7 +5467,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "gloo-timers", "kv-log-macro", "log", @@ -5349,7 +5498,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -5360,13 +5509,33 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version", +] + +[[package]] +name = "atomic" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" +dependencies = [ + "bytemuck", ] [[package]] @@ -5394,14 +5563,69 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "autometrics" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10eaae539e7319a3813dc8cd53776a7128bdd6d82067275c12586f5a0fce9137" +dependencies = [ + "autometrics-macros", + "cfg_aliases 0.1.1", + "http 1.4.1", + "linkme", + "metrics-exporter-prometheus", + "once_cell", + "opentelemetry-prometheus", + "opentelemetry_sdk", + "prometheus", + "prometheus-client", + "spez", + "thiserror 1.0.69", +] + +[[package]] +name = "autometrics-macros" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf7c9ebfee6425011c65788c746adf80fac99ba38957ba1cdb824b593cfc993" +dependencies = [ + "percent-encoding", + "proc-macro2", + "quote", + "regex", + "syn 2.0.117", +] + +[[package]] +name = "aws-lc-rs" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] [[package]] name = "axum" @@ -5414,9 +5638,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", "itoa", "matchit", "memchr", @@ -5426,24 +5650,26 @@ dependencies = [ "rustversion", "serde", "sync_wrapper 0.1.2", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", ] [[package]] name = "axum" -version = "0.7.5" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", - "axum-core 0.4.3", + "axum-core 0.4.5", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 1.4.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.10.1", + "hyper-util", "itoa", "matchit", "memchr", @@ -5455,9 +5681,9 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", - "tower", + "tower 0.5.3", "tower-layer", "tower-service", "tracing", @@ -5472,8 +5698,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -5482,19 +5708,20 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.4.1", + "http-body 1.0.1", + "http-body-util", "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", @@ -5516,7 +5743,7 @@ dependencies = [ "getrandom 0.2.17", "instant", "pin-project-lite", - "rand 0.8.5", + "rand 0.8.6", "tokio", ] @@ -5535,6 +5762,12 @@ dependencies = [ "windows-link", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base16ct" version = "0.2.0" @@ -5577,8 +5810,8 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67bd8fd42c16bdb08688243dc5f0cc117a3ca9efeeaba3a345a18a6159ad96f7" dependencies = [ - "lalrpop 0.19.12", - "lalrpop-util 0.19.12", + "lalrpop", + "lalrpop-util", "regex", ] @@ -5670,10 +5903,10 @@ source = "git+ssh://git@github.com/Entropy-Foundation/bicycl-rs?rev=e67e3ab#e67e dependencies = [ "gmp-mpfr-sys", "libc", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_bytes", - "sha3 0.10.8", + "sha3 0.10.9", ] [[package]] @@ -5705,7 +5938,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.12.1", "cexpr", "clang-sys", "itertools 0.12.1", @@ -5714,9 +5947,9 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", - "shlex", - "syn 2.0.48", + "rustc-hash 1.1.0", + "shlex 1.3.0", + "syn 2.0.117", ] [[package]] @@ -5763,9 +5996,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" [[package]] name = "bitmaps" @@ -5860,6 +6093,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.2.1" @@ -5884,7 +6126,7 @@ dependencies = [ "async-channel 2.5.0", "async-task", "futures-io", - "futures-lite 2.6.1", + "futures-lite", "piper", ] @@ -5945,7 +6187,7 @@ dependencies = [ "hex", "hex_fmt", "pairing 0.22.0", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "serde", "thiserror 1.0.69", @@ -5965,8 +6207,8 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.32", "hyperlocal", "log", "pin-project-lite", @@ -5995,9 +6237,9 @@ dependencies = [ [[package]] name = "brotli" -version = "6.0.0" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" +checksum = "8119e4516436f5708bbc474a9d395bf12f1b5395e93a92a56e647ac3388c8610" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -6006,21 +6248,27 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "4.0.1" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +checksum = "5962523e1b92ce1b5e793d9169b9943eece10d39f62550bc04bb605d75b94924" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", ] +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + [[package]] name = "bs58" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.8", + "sha2 0.10.9", "tinyvec", ] @@ -6037,9 +6285,9 @@ dependencies = [ [[package]] name = "build_html" -version = "2.5.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225eb82ce9e70dcc0cfa6e404d0f353326b6e163bf500ec4711cec317d11935c" +checksum = "f1829197343f1874c1979c988a5e75c2539c4645792d87494286ce2cb6dc890d" [[package]] name = "bulletproofs" @@ -6052,7 +6300,7 @@ dependencies = [ "curve25519-dalek-ng", "digest 0.9.0", "merlin", - "rand 0.8.5", + "rand 0.8.6", "rand_core 0.6.4", "serde", "serde_derive", @@ -6072,33 +6320,27 @@ dependencies = [ "digest 0.10.7", "group 0.13.0", "merlin", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "rand_core 0.6.4", "serde", "serde_derive", - "sha3 0.10.8", + "sha3 0.10.9", "subtle", "thiserror 1.0.69", ] [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "byte-slice-cast" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "bytecode-verifier-libfuzzer" @@ -6165,19 +6407,9 @@ dependencies = [ [[package]] name = "bytesize" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" - -[[package]] -name = "bzip2" -version = "0.4.4" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" -dependencies = [ - "bzip2-sys", - "libc", -] +checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] name = "bzip2-sys" @@ -6200,7 +6432,7 @@ name = "calc-dep-sizes" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.6.1", "futures", "move-binary-format", "move-core-types", @@ -6227,7 +6459,7 @@ dependencies = [ "regex", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -6240,7 +6472,7 @@ dependencies = [ "hound", "image", "lodepng", - "rand 0.8.5", + "rand 0.8.6", "serde_json", ] @@ -6255,9 +6487,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082" +checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba" dependencies = [ "serde", "serde_core", @@ -6271,9 +6503,23 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform 0.1.9", - "semver 1.0.27", + "semver 1.0.28", + "serde", + "serde_json", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform 0.1.9", + "semver 1.0.28", "serde", "serde_json", + "thiserror 1.0.69", ] [[package]] @@ -6283,8 +6529,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" dependencies = [ "camino", - "cargo-platform 0.3.2", - "semver 1.0.27", + "cargo-platform 0.3.3", + "semver 1.0.28", "serde", "serde_json", "thiserror 2.0.18", @@ -6304,20 +6550,23 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "castaway" -version = "0.1.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", +] [[package]] name = "cc" -version = "1.0.83" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex", + "shlex 2.0.1", ] [[package]] @@ -6331,9 +6580,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.20.6" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cef5b5a1a6827c7322ae2a636368a573006b27cfa76c7ebd53e834daeaab6a" +checksum = "fb693542bcafa528e198be0ebd9d3632ca5b7c93dbe7237460e199910835997c" dependencies = [ "smallvec", "target-lexicon", @@ -6343,20 +6592,43 @@ dependencies = [ name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-link", ] [[package]] @@ -6367,7 +6639,17 @@ checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" dependencies = [ "chrono", "chrono-tz-build", - "phf", + "phf 0.11.3", +] + +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf 0.12.1", ] [[package]] @@ -6377,7 +6659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" dependencies = [ "parse-zoneinfo", - "phf", + "phf 0.11.3", "phf_codegen", ] @@ -6420,7 +6702,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", ] @@ -6478,12 +6760,12 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.14" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", - "clap_derive 4.4.7", + "clap_derive 4.6.1", ] [[package]] @@ -6492,29 +6774,30 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34c77f67047557f62582784fd7482884697731b2932c7d37ced54bce2312e1e2" dependencies = [ - "clap 4.4.14", + "clap 4.6.1", "log", ] [[package]] name = "clap_builder" -version = "4.4.14" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", - "clap_lex 0.6.0", - "strsim 0.10.0", + "clap_lex 1.1.0", + "strsim 0.11.1", + "terminal_size", ] [[package]] name = "clap_complete" -version = "4.5.66" +version = "4.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c757a3b7e39161a4e56f9365141ada2a6c915a8622c408ab6bb4b5d047371031" +checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" dependencies = [ - "clap 4.4.14", + "clap 4.6.1", ] [[package]] @@ -6532,14 +6815,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -6553,9 +6836,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clear_on_drop" @@ -6583,13 +6866,28 @@ dependencies = [ "lazy_static", "pem 0.8.3", "percent-encoding", - "reqwest 0.11.23", + "reqwest 0.11.27", "ring 0.16.20", "serde", "serde_json", "tokio", ] +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "codespan" version = "0.11.1" @@ -6617,14 +6915,14 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" dependencies = [ - "bs58", + "bs58 0.5.1", "coins-core", "digest 0.10.7", "hmac 0.12.1", - "k256", + "k256 0.13.4", "serde", - "sha2 0.10.8", - "thiserror", + "sha2 0.10.9", + "thiserror 1.0.69", ] [[package]] @@ -6638,9 +6936,9 @@ dependencies = [ "hmac 0.12.1", "once_cell", "pbkdf2 0.12.2", - "rand 0.8.5", - "sha2 0.10.8", - "thiserror", + "rand 0.8.6", + "sha2 0.10.9", + "thiserror 1.0.69", ] [[package]] @@ -6651,16 +6949,16 @@ checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" dependencies = [ "base64 0.21.7", "bech32", - "bs58", + "bs58 0.5.1", "digest 0.10.7", "generic-array", "hex", "ripemd", "serde", "serde_derive", - "sha2 0.10.8", - "sha3 0.10.8", - "thiserror", + "sha2 0.10.9", + "sha3 0.10.9", + "thiserror 1.0.69", ] [[package]] @@ -6671,9 +6969,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "colored" @@ -6699,12 +6997,32 @@ dependencies = [ "tokio-util 0.7.18", ] +[[package]] +name = "compression-codecs" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf" +dependencies = [ + "brotli", + "compression-core", + "flate2", + "memchr", + "zstd", + "zstd-safe", +] + +[[package]] +name = "compression-core" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" + [[package]] name = "compute-module-expansion-size" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.6.1", "futures", "move-binary-format", "move-core-types", @@ -6736,13 +7054,12 @@ dependencies = [ [[package]] name = "console" -version = "0.16.2" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" dependencies = [ "encode_unicode", "libc", - "once_cell", "unicode-width 0.2.2", "windows-sys 0.61.2", ] @@ -6754,8 +7071,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a257c22cd7e487dd4a13d413beabc512c5052f0bc048db0da6a84c3d8a6142fd" dependencies = [ "futures-core", - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.6", + "prost-types 0.12.6", "tonic 0.11.0", "tracing-core", ] @@ -6772,8 +7089,8 @@ dependencies = [ "futures-task", "hdrhistogram", "humantime", - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.12.6", + "prost-types 0.12.6", "serde", "serde_json", "thread_local", @@ -6782,20 +7099,19 @@ dependencies = [ "tonic 0.11.0", "tracing", "tracing-core", - "tracing-subscriber 0.3.18", + "tracing-subscriber 0.3.23", ] [[package]] name = "const-hex" -version = "1.14.0" +version = "1.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" +checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558" dependencies = [ "cfg-if", - "cpufeatures", - "hex", + "cpufeatures 0.2.17", "proptest", - "serde", + "serde_core", ] [[package]] @@ -6810,6 +7126,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-random" version = "0.1.18" @@ -6825,24 +7147,25 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.11", + "getrandom 0.2.17", "once_cell", "tiny-keccak", ] [[package]] name = "const_fn" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" +checksum = "413d67b29ef1021b4d60f4aa1e925ca031751e213832b4b1d588fae623c05c60" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" dependencies = [ "const_format_proc_macros", + "konst", ] [[package]] @@ -6870,9 +7193,9 @@ checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "convert_case" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" dependencies = [ "unicode-segmentation", ] @@ -6888,18 +7211,11 @@ dependencies = [ [[package]] name = "cookie" -version = "0.18.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" dependencies = [ - "aes-gcm", - "base64 0.21.6", - "hkdf 0.12.4", - "hmac 0.12.1", "percent-encoding", - "rand 0.8.5", - "sha2 0.10.9", - "subtle", "time", "version_check", ] @@ -6931,6 +7247,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -6995,6 +7321,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -7115,8 +7450,8 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio", - "parking_lot 0.12.1", + "mio 0.8.11", + "parking_lot 0.12.5", "signal-hook", "signal-hook-mio", "winapi 0.3.9", @@ -7131,8 +7466,8 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio", - "parking_lot 0.12.1", + "mio 0.8.11", + "parking_lot 0.12.5", "signal-hook", "signal-hook-mio", "winapi 0.3.9", @@ -7168,12 +7503,12 @@ dependencies = [ "hex", "lazy_static", "miracl_core_bls12381", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.2.2", "rand_core 0.6.4", "rayon", "serde", - "sha3 0.10.8", + "sha3 0.10.9", "statrs", "thiserror 1.0.69", "tiny-keccak", @@ -7190,6 +7525,18 @@ dependencies = [ "subtle", ] +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -7213,6 +7560,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + [[package]] name = "crypto-mac" version = "0.8.0" @@ -7256,12 +7612,12 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.26" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +checksum = "01334b89b69ff726750c5ce5073fc8bd860e99aa9a8fc5ca11b04730e3aee97a" dependencies = [ - "quote", - "syn 1.0.109", + "link-section", + "linktime-proc-macro", ] [[package]] @@ -7275,15 +7631,24 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.5.1" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" +checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" dependencies = [ "dispatch2", - "nix 0.30.1", + "nix 0.31.3", "windows-sys 0.61.2", ] +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "curl" version = "0.4.49" @@ -7292,18 +7657,18 @@ checksum = "79fc3b6dd0b87ba36e565715bf9a2ced221311db47bd18011676f24a6066edbc" dependencies = [ "curl-sys", "libc", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "schannel", - "socket2 0.6.2", + "socket2 0.6.4", "windows-sys 0.59.0", ] [[package]] name = "curl-sys" -version = "0.4.85+curl-8.18.0" +version = "0.4.87+curl-8.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0efa6142b5ecc05f6d3eaa39e6af4888b9d3939273fb592c92b7088a8cf3fdb" +checksum = "61a460380f0ef783703dcbe909107f39c162adeac050d73c850055118b5b6327" dependencies = [ "cc", "libc", @@ -7335,7 +7700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", @@ -7352,7 +7717,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -7381,22 +7746,22 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", + "darling_core 0.20.11", + "darling_macro 0.20.11", ] [[package]] name = "darling" -version = "0.20.9" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "darling_core 0.20.9", - "darling_macro 0.20.9", + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -7415,30 +7780,29 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", - "syn 1.0.109", + "strsim 0.11.1", + "syn 2.0.117", ] [[package]] name = "darling_core" -version = "0.20.9" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -7454,24 +7818,51 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core 0.20.10", + "darling_core 0.20.11", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] name = "darling_macro" -version = "0.20.9" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "darling_core 0.20.9", + "darling_core 0.23.0", "quote", - "syn 2.0.48", + "syn 2.0.117", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.12", +] + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.12", ] [[package]] @@ -7481,17 +7872,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a1e35a65fe0538a60167f0ada6e195ad5d477f6ddae273943596d4a1a5730b" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "crossbeam-utils", + "equivalent", + "hashbrown 0.15.5", "lock_api", - "once_cell", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.12", ] [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] name = "datatest-stable" @@ -7560,7 +7952,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] @@ -7571,7 +7963,7 @@ checksum = "4e018fccbeeb50ff26562ece792ed06659b9c2dae79ece77c4456bb10d9bf79b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -7585,6 +7977,16 @@ dependencies = [ "pem-rfc7468 0.3.1", ] +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid 0.9.6", + "zeroize", +] + [[package]] name = "der" version = "0.7.10" @@ -7598,9 +8000,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", "serde_core", @@ -7631,18 +8033,18 @@ checksum = "74ef43543e701c01ad77d3a5922755c6a1d71b22d942cb8042be4994b380caff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -7660,10 +8062,10 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling 0.20.9", + "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -7673,18 +8075,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] -name = "derive_more" -version = "0.99.17" +name = "derive_dearbitrary" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "afdf9e6fb6c8a925c6b19b78ec3a80152e7a46dc7811be5f1fa64568e7c7b6c0" dependencies = [ "proc-macro2", "quote", - "rustc_version", "syn 1.0.109", ] @@ -7703,7 +8104,7 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ - "derive_more-impl 2.0.1", + "derive_more-impl 2.1.1", ] [[package]] @@ -7714,8 +8115,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", - "unicode-xid", + "syn 2.0.117", ] [[package]] @@ -7727,7 +8127,8 @@ dependencies = [ "convert_case 0.10.0", "proc-macro2", "quote", - "syn 2.0.48", + "rustc_version", + "syn 2.0.117", "unicode-xid", ] @@ -7756,12 +8157,12 @@ checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04" [[package]] name = "diesel" -version = "2.1.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" +checksum = "35b696af9ff4c0d2a507db2c5faafa8aa0205e297e5f11e203a24226d5355e7a" dependencies = [ "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.12.1", "byteorder", "chrono", "diesel_derives", @@ -7772,7 +8173,7 @@ dependencies = [ "pq-sys", "r2d2", "serde_json", - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] @@ -7791,15 +8192,15 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.1.2" +version = "2.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" +checksum = "1b96984c469425cb577bf6f17121ecb3e4fe1e81de5d8f780dd372802858d756" dependencies = [ "diesel_table_macro_syntax", "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -7819,7 +8220,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -7866,10 +8267,22 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "const-oid 0.9.6", - "crypto-common", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "dir-diff" version = "0.3.3" @@ -7943,11 +8356,11 @@ dependencies = [ [[package]] name = "dispatch2" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.12.1", "block2", "libc", "objc2", @@ -7955,13 +8368,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -7988,19 +8401,19 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "139ae9aca7527f85f26dd76483eb38533fd84bd571065da1739656ef71c5ff5b" dependencies = [ - "darling 0.20.10", + "darling 0.20.11", "either", "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] name = "dtoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" [[package]] name = "dunce" @@ -8075,6 +8488,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + [[package]] name = "ecdsa" version = "0.16.9" @@ -8083,8 +8508,8 @@ checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der 0.7.10", "digest 0.10.7", - "elliptic-curve", - "rfc6979", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", "signature 2.2.0", "spki 0.7.3", ] @@ -8154,9 +8579,29 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] [[package]] name = "elliptic-curve" @@ -8164,17 +8609,17 @@ version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct", + "base16ct 0.2.0", "base64ct", "crypto-bigint 0.5.5", "digest 0.10.7", - "ff 0.13.0", - "generic-array 0.14.7", + "ff 0.13.1", + "generic-array", "group 0.13.0", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", "serde_json", "serdect", "subtle", @@ -8207,19 +8652,20 @@ dependencies = [ [[package]] name = "enr" -version = "0.10.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" +checksum = "492a7e5fc2504d5fdce8e124d3e263b244a68b283cac67a69eda0cd43e0aebad" dependencies = [ - "base64 0.21.7", + "base64 0.13.1", + "bs58 0.4.0", "bytes", "hex", - "k256", + "k256 0.11.6", "log", - "rand 0.8.5", + "rand 0.8.6", "rlp", "serde", - "sha3 0.10.8", + "sha3 0.10.9", "zeroize", ] @@ -8232,7 +8678,16 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", +] + +[[package]] +name = "env_filter" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +dependencies = [ + "log", ] [[package]] @@ -8249,10 +8704,14 @@ dependencies = [ ] [[package]] -name = "environmental" -version = "1.1.4" +name = "env_logger" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +dependencies = [ + "env_filter", + "log", +] [[package]] name = "equivalent" @@ -8300,13 +8759,13 @@ dependencies = [ "hex", "hmac 0.12.1", "pbkdf2 0.11.0", - "rand 0.8.5", + "rand 0.8.6", "scrypt", "serde", "serde_json", - "sha2 0.10.8", - "sha3 0.10.8", - "thiserror", + "sha2 0.10.9", + "sha3 0.10.9", + "thiserror 1.0.69", "uuid 0.8.2", ] @@ -8316,8 +8775,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3aeb0284b473041df2419a28e3cdf0c64a78d2b9511af4b6e40bad3964b172" dependencies = [ - "ethereum-types 0.14.1", - "hashbrown 0.14.3", + "ethereum-types", + "hashbrown 0.14.5", "keccak-hash", "log", "parking_lot 0.12.5", @@ -8336,7 +8795,7 @@ dependencies = [ "regex", "serde", "serde_json", - "sha3 0.10.8", + "sha3 0.10.9", "thiserror 1.0.69", "uint", ] @@ -8374,9 +8833,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.14" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" +checksum = "839a392641e746a1ff365ef7c901238410b5c6285d240cf2409ffaaa7df9a78a" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -8385,7 +8844,6 @@ dependencies = [ "ethers-middleware", "ethers-providers", "ethers-signers", - "ethers-solc", ] [[package]] @@ -8410,20 +8868,35 @@ dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", "ethers-core", - "ethers-providers", "futures-util", "once_cell", - "pin-project 1.1.3", + "pin-project 1.1.13", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] -name = "ethnum" -version = "1.5.0" +name = "ethers-contract-abigen" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" +dependencies = [ + "Inflector", + "const-hex", + "dunce", + "ethers-core", + "eyre", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "syn 2.0.117", + "toml 0.8.23", + "walkdir", +] [[package]] name = "ethers-contract-derive" @@ -8438,79 +8911,113 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] -name = "event-listener" -version = "3.1.0" +name = "ethers-core" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", + "arrayvec 0.7.6", + "bytes", + "cargo_metadata 0.18.1", + "chrono", + "const-hex", + "elliptic-curve 0.13.8", + "ethabi", + "generic-array", + "k256 0.13.4", + "num_enum", + "once_cell", + "open-fastrlp", + "rand 0.8.6", + "rlp", + "serde", + "serde_json", + "strum 0.26.3", + "syn 2.0.117", + "tempfile", + "thiserror 1.0.69", + "tiny-keccak", + "unicode-xid", ] [[package]] -name = "event-listener" -version = "4.0.3" +name = "ethers-etherscan" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ "chrono", "ethers-core", - "reqwest 0.11.23", - "semver", + "reqwest 0.11.27", + "semver 1.0.28", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tracing", ] [[package]] -name = "event-listener-strategy" -version = "0.4.0" +name = "ethers-middleware" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "a7dd311b76eab9d15209e4fd16bb419e25543709cbdf33079e8923dfa597517c" dependencies = [ - "event-listener 4.0.3", - "pin-project-lite", + "async-trait", + "auto_impl", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-providers", + "ethers-signers", + "futures-locks", + "futures-util", + "instant", + "reqwest 0.11.27", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tracing", + "tracing-futures", + "url", ] [[package]] name = "ethers-providers" -version = "2.0.14" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" +checksum = "ed7174af93619e81844d3d49887106a3721e5caecdf306e0b824bfb4316db3be" dependencies = [ "async-trait", "auto_impl", "base64 0.21.7", - "bytes", - "const-hex", "enr", "ethers-core", "futures-core", "futures-timer", "futures-util", + "getrandom 0.2.17", "hashers", - "http 0.2.11", - "instant", - "jsonwebtoken 8.3.0", + "hex", + "http 0.2.12", "once_cell", - "pin-project 1.1.3", - "reqwest 0.11.23", + "parking_lot 0.11.2", + "pin-project 1.1.13", + "reqwest 0.11.27", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", - "tokio-tungstenite", "tracing", "tracing-futures", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-timer", "web-sys", "ws_stream_wasm", ] @@ -8525,75 +9032,32 @@ dependencies = [ "coins-bip32", "coins-bip39", "const-hex", - "elliptic-curve", + "elliptic-curve 0.13.8", "eth-keystore", "ethers-core", - "rand 0.8.5", - "sha2 0.10.8", - "thiserror", + "rand 0.8.6", + "sha2 0.10.9", + "thiserror 1.0.69", "tracing", ] [[package]] -name = "ethers-solc" -version = "2.0.14" +name = "ethnum" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40404c3f5f511ec4da6fe866ddf6a717c309fdbb69fbbad7b0f3edab8f2e835f" + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" -dependencies = [ - "cfg-if", - "const-hex", - "dirs 5.0.1", - "dunce", - "ethers-core", - "glob", - "home", - "md-5", - "num_cpus", - "once_cell", - "path-slash", - "rayon", - "regex", - "semver", - "serde", - "serde_json", - "solang-parser", - "svm-rs", - "thiserror", - "tiny-keccak", - "tokio", - "tracing", - "walkdir", - "yansi 0.5.1", -] - -[[package]] -name = "ethnum" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "4.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -8602,11 +9066,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener 4.0.3", + "event-listener 5.4.1", "pin-project-lite", ] @@ -8631,12 +9095,8 @@ version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ - "anyhow", - "atty", - "clap 4.4.14", - "codespan-reporting", - "move-to-yul", - "serde_json", + "indenter", + "once_cell", ] [[package]] @@ -8647,7 +9107,7 @@ checksum = "fe5e43d0f78a42ad591453aedb1d7ae631ce7ee445c7643691055a9ed8d3b01c" dependencies = [ "log", "once_cell", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -8680,18 +9140,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fdeflate" @@ -8775,7 +9226,7 @@ dependencies = [ "atomic", "pear", "serde", - "serde_yaml 0.9.30", + "serde_yaml 0.9.34+deprecated", "uncased", "version_check", ] @@ -8788,13 +9239,12 @@ checksum = "31a7a908b8f32538a2143e59a6e4e2508988832d5d4d6f7c156b3cbc762643a5" [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] @@ -8816,16 +9266,45 @@ dependencies = [ ] [[package]] -name = "finl_unicode" -version = "1.2.0" +name = "firebase-token" +version = "0.3.0" +source = "git+https://github.com/aptos-labs/firebase-token?rev=34ea512d3d1fad6c11df3e7d82ff72beccc05836#34ea512d3d1fad6c11df3e7d82ff72beccc05836" +dependencies = [ + "jsonwebtoken 8.3.0", + "reqwest 0.11.27", + "serde", + "tokio", + "tracing", +] + +[[package]] +name = "firestore" +version = "0.43.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" +checksum = "483bce3ebe3bec625c4a3800a84966e966604e274ea9acbe7e6429477f915445" +dependencies = [ + "async-trait", + "backoff", + "chrono", + "futures", + "gcloud-sdk", + "hex", + "hyper 1.10.1", + "rand 0.8.6", + "rsb_derive", + "rvstruct", + "serde", + "struct-path", + "tokio", + "tokio-stream", + "tracing", +] [[package]] name = "fixed" -version = "1.30.0" +version = "1.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c566da967934c6c7ee0458a9773de9b2a685bd2ce26a3b28ddfc740e640182f5" +checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40" dependencies = [ "az", "bytemuck", @@ -8840,7 +9319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" dependencies = [ "byteorder", - "rand 0.8.5", + "rand 0.8.6", "rustc-hex", "static_assertions", ] @@ -8852,7 +9331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand 0.8.5", + "rand 0.8.6", "rustc-hex", "static_assertions", ] @@ -8923,6 +9402,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -8950,7 +9435,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -8976,9 +9461,18 @@ dependencies = [ [[package]] name = "fragile" -version = "2.0.1" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8878864ba14bb86e818a412bfd6f18f9eabd4ec0f008a28e8f7eb61db532fcf9" +dependencies = [ + "futures-core", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "fst" @@ -9000,9 +9494,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -9015,9 +9509,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -9025,15 +9519,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -9042,24 +9536,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "1.13.0" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-lite" @@ -9067,7 +9546,7 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ - "fastrand 2.3.0", + "fastrand", "futures-core", "futures-io", "parking", @@ -9086,38 +9565,38 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -9127,7 +9606,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -9141,7 +9619,7 @@ dependencies = [ "arbitrary", "base64 0.21.7", "bcs 0.1.4", - "clap 4.5.21", + "clap 4.6.1", "csv", "dearbitrary", "hex", @@ -9201,26 +9679,26 @@ checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" [[package]] name = "gcloud-sdk" -version = "0.25.3" +version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898e349fb0fabc16892de7858e5650b70a8044edeee13469cb2f7649040bf3c2" +checksum = "0775bfa745cdf7287ae9765a685a813b91049b6b6d5ca3de20a3d5d16a80d8b2" dependencies = [ "async-trait", "bytes", "chrono", "futures", - "hyper 1.4.1", - "jsonwebtoken 9.3.0", + "hyper 1.10.1", + "jsonwebtoken 9.3.1", "once_cell", - "prost 0.13.4", - "prost-types 0.13.1", - "reqwest 0.12.5", + "prost 0.13.5", + "prost-types 0.13.5", + "reqwest 0.12.28", "secret-vault-value", "serde", "serde_json", "tokio", "tonic 0.12.3", - "tower", + "tower 0.5.3", "tower-layer", "tower-util", "tracing", @@ -9236,10 +9714,10 @@ dependencies = [ "async-stream", "async-trait", "dyn-clone", - "hyper 0.14.28", + "hyper 0.14.32", "hyper-rustls 0.24.2", "log", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "thiserror 1.0.69", @@ -9263,7 +9741,7 @@ dependencies = [ "aptos-network", "aptos-types", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "move-core-types", "rand 0.7.3", "serde", @@ -9330,13 +9808,41 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 5.3.0", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasip2", + "wasip3", +] + [[package]] name = "ghash" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ - "opaque-debug 0.3.0", + "opaque-debug", "polyval", ] @@ -9379,7 +9885,7 @@ dependencies = [ "libc", "libgit2-sys", "log", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "url", ] @@ -9409,7 +9915,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.12.1", "ignore", "walkdir", ] @@ -9438,9 +9944,9 @@ dependencies = [ [[package]] name = "goldenfile" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce2238f730d493a06ef6746713fe0b56acecc88485892ae65c50d2db9bf977b" +checksum = "206600f27ef687e85a572315eb297c79f66620b2b3eeb3a6cde17f25e049ae5b" dependencies = [ "scopeguard", "similar-asserts", @@ -9461,7 +9967,7 @@ dependencies = [ "google-cloud-token", "home", "jsonwebtoken 8.3.0", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "thiserror 1.0.69", @@ -9478,12 +9984,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8bdaaa4bc036e8318274d1b25f0f2265b3e95418b765fd1ea1c7ef938fd69bd" dependencies = [ "google-cloud-token", - "http 0.2.11", - "thiserror", + "http 0.2.12", + "thiserror 1.0.69", "tokio", "tokio-retry", "tonic 0.9.2", - "tower", + "tower 0.4.13", "tracing", ] @@ -9504,8 +10010,8 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96e4ad0802d3f416f62e7ce01ac1460898ee0efc98f8b45cd4aab7611607012f" dependencies = [ - "reqwest", - "thiserror", + "reqwest 0.11.27", + "thiserror 1.0.69", "tokio", ] @@ -9522,9 +10028,9 @@ dependencies = [ "google-cloud-googleapis", "google-cloud-token", "prost-types 0.11.9", - "thiserror", + "thiserror 1.0.69", "tokio", - "tokio-util 0.7.10", + "tokio-util 0.7.18", "tracing", ] @@ -9545,7 +10051,7 @@ dependencies = [ "once_cell", "percent-encoding", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "ring 0.16.20", "rsa 0.6.1", "serde", @@ -9574,7 +10080,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ "ff 0.12.1", - "rand 0.8.5", + "rand 0.8.6", "rand_core 0.6.4", "rand_xorshift 0.3.0", "subtle", @@ -9587,7 +10093,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff 0.13.1", - "rand 0.8.5", + "rand 0.8.6", "rand_core 0.6.4", "rand_xorshift 0.3.0", "subtle", @@ -9595,9 +10101,9 @@ dependencies = [ [[package]] name = "guppy" -version = "0.17.25" +version = "0.17.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a502977572076a42d585dd12f04bccf9c9cafdd4546e99878c072460b904e115" +checksum = "eb611f63088c20f3f7252d896f0beaa176a9628da8c21cdf258fe9ae179bebda" dependencies = [ "ahash 0.8.12", "camino", @@ -9607,14 +10113,14 @@ dependencies = [ "fixedbitset 0.5.7", "guppy-summaries", "guppy-workspace-hack", - "indexmap 2.2.5", - "itertools 0.12.1", + "indexmap 2.14.0", + "itertools 0.14.0", "nested", "once_cell", - "pathdiff", - "petgraph 0.6.4", + "pathdiff 0.2.3", + "petgraph 0.8.3", "rayon", - "semver 1.0.27", + "semver 1.0.28", "serde", "serde_json", "smallvec", @@ -9633,7 +10139,7 @@ dependencies = [ "cfg-if", "diffus", "guppy-workspace-hack", - "semver 1.0.27", + "semver 1.0.28", "serde", "toml 0.5.11", ] @@ -9655,8 +10161,27 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 2.2.5", + "http 0.2.12", + "indexmap 2.14.0", + "slab", + "tokio", + "tokio-util 0.7.18", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.4.1", + "indexmap 2.14.0", "slab", "tokio", "tokio-util 0.7.18", @@ -9677,6 +10202,8 @@ checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "num-traits", + "zerocopy", ] [[package]] @@ -9721,6 +10248,41 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + [[package]] name = "hdrhistogram" version = "7.5.4" @@ -9742,8 +10304,23 @@ checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ "base64 0.21.7", "bytes", - "headers-core", - "http", + "headers-core 0.2.0", + "http 0.2.12", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" +dependencies = [ + "base64 0.22.1", + "bytes", + "headers-core 0.3.0", + "http 1.4.1", "httpdate", "mime", "sha1", @@ -9755,7 +10332,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http", + "http 0.2.12", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.4.1", ] [[package]] @@ -9792,7 +10378,13 @@ dependencies = [ name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -9837,15 +10429,6 @@ dependencies = [ "hmac 0.10.1", ] -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac 0.12.1", -] - [[package]] name = "hmac" version = "0.8.1" @@ -9875,6 +10458,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", +] + [[package]] name = "hmac-drbg" version = "0.3.0" @@ -9916,7 +10508,7 @@ checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" name = "http" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -9925,9 +10517,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -9940,7 +10532,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.4.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.4.1", + "http-body 1.0.1", "pin-project-lite", ] @@ -9976,7 +10591,7 @@ dependencies = [ "crossbeam-utils", "form_urlencoded", "futures-util", - "hyper 0.14.28", + "hyper 0.14.32", "isahc", "lazy_static", "levenshtein", @@ -10006,7 +10621,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] -name = "hyper" +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" @@ -10015,9 +10639,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -10031,16 +10655,17 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", - "h2 0.4.5", - "http 1.1.0", - "http-body 1.0.0", + "futures-core", + "h2 0.4.14", + "http 1.4.1", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -10056,8 +10681,8 @@ version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.32", "log", "rustls 0.20.9", "rustls-native-certs 0.6.3", @@ -10072,8 +10697,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.32", "log", "rustls 0.21.12", "rustls-native-certs 0.6.3", @@ -10083,19 +10708,17 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "futures-util", - "http 1.1.0", - "hyper 1.4.1", + "http 1.4.1", + "hyper 1.10.1", "hyper-util", - "rustls 0.23.7", - "rustls-native-certs 0.7.0", - "rustls-pki-types", + "rustls 0.23.40", + "rustls-native-certs 0.8.4", "tokio", - "tokio-rustls 0.26.0", + "tokio-rustls 0.26.4", "tower-service", ] @@ -10105,7 +10728,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.28", + "hyper 0.14.32", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -10113,11 +10736,11 @@ dependencies = [ [[package]] name = "hyper-timeout" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.4.1", + "hyper 1.10.1", "hyper-util", "pin-project-lite", "tokio", @@ -10131,7 +10754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.28", + "hyper 0.14.32", "native-tls", "tokio", "tokio-native-tls", @@ -10139,20 +10762,23 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.6" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.4.1", + "http 1.4.1", + "http-body 1.0.1", + "hyper 1.10.1", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2 0.5.5", + "socket2 0.6.4", "tokio", - "tower", "tower-service", "tracing", ] @@ -10165,8 +10791,8 @@ checksum = "0fafdf7b2b2de7c9784f76e02c0935e65a8117ec3b768644379983ab333ac98c" dependencies = [ "futures-util", "hex", - "hyper 0.14.28", - "pin-project 1.1.3", + "hyper 0.14.32", + "pin-project 1.1.13", "tokio", ] @@ -10196,12 +10822,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -10209,9 +10836,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -10222,9 +10849,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -10236,15 +10863,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -10256,15 +10883,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -10320,9 +10947,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -10391,7 +11018,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.9", + "parity-scale-codec 3.7.5", ] [[package]] @@ -10429,7 +11056,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -10458,9 +11085,9 @@ dependencies = [ [[package]] name = "indenter" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" @@ -10475,12 +11102,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -10491,7 +11118,7 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7baab56125e25686df467fe470785512329883aab42696d661247aca2a2896e4" dependencies = [ - "console 0.16.2", + "console 0.16.3", "lazy_static", "number_prefix 0.3.0", "regex", @@ -10522,13 +11149,13 @@ version = "0.11.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "232929e1d75fe899576a3d5c7416ad0d88dbfbb3c3d6aa00873a7408a50ddb88" dependencies = [ - "ahash 0.8.11", - "clap 4.4.14", + "ahash 0.8.12", + "clap 4.6.1", "crossbeam-channel", "crossbeam-utils", - "dashmap", - "env_logger", - "indexmap 2.2.5", + "dashmap 6.2.1", + "env_logger 0.11.10", + "indexmap 2.14.0", "is-terminal", "itoa", "log", @@ -10611,9 +11238,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iprange" @@ -10639,9 +11266,9 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.28", - "windows-sys 0.52.0", + "hermit-abi 0.5.2", + "libc", + "windows-sys 0.61.2", ] [[package]] @@ -10658,27 +11285,32 @@ dependencies = [ name = "is_debug" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" +checksum = "1fe266d2e243c931d8190177f20bf7f24eed45e96f39e87dc49a27b32d12d407" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "isahc" -version = "1.7.2" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "334e04b4d781f436dc315cb1e7515bd96826426345d498149e4bde36b67f8ee9" +checksum = "82d93e1769c5c2b13a8e0d8ca9b6466c60bafade047326f25e3bcb97a947d875" dependencies = [ - "async-channel 1.9.0", + "async-channel 2.5.0", "castaway", "crossbeam-utils", "curl", "curl-sys", "encoding_rs", - "event-listener 2.5.3", - "futures-lite 1.13.0", - "http", + "event-listener 5.4.1", + "futures-lite", + "http 0.2.12", "log", "mime", - "once_cell", - "polling 2.8.0", + "polling", "slab", "sluice", "tracing", @@ -10723,11 +11355,29 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jemalloc-sys" @@ -10751,9 +11401,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.4", "libc", @@ -10770,9 +11420,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -10825,22 +11475,22 @@ dependencies = [ "ring 0.16.20", "serde", "serde_json", - "simple_asn1 0.6.3", + "simple_asn1 0.6.4", ] [[package]] name = "jsonwebtoken" -version = "9.3.0" +version = "9.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "js-sys", - "pem 3.0.4", - "ring 0.17.7", + "pem 3.0.6", + "ring 0.17.14", "serde", "serde_json", - "simple_asn1 0.6.2", + "simple_asn1 0.6.4", ] [[package]] @@ -10850,7 +11500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6204285f77fe7d9784db3fdc449ecce1a0114927a51d5a41c4c7a292011c015f" dependencies = [ "base64 0.13.1", - "crypto-common", + "crypto-common 0.1.7", "digest 0.10.7", "hmac 0.12.1", "serde", @@ -10858,6 +11508,18 @@ dependencies = [ "sha2 0.10.9", ] +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.9", +] + [[package]] name = "k256" version = "0.13.4" @@ -10865,10 +11527,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", - "sha2 0.10.8", + "sha2 0.10.9", "signature 2.2.0", ] @@ -10898,11 +11560,11 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -10925,6 +11587,21 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "kube" version = "0.65.0" @@ -10949,16 +11626,16 @@ dependencies = [ "dirs-next", "either", "futures", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", "hyper-rustls 0.23.2", "hyper-timeout 0.4.1", "jsonpath_lib", "k8s-openapi", "kube-core", "pem 1.1.1", - "pin-project 1.1.3", + "pin-project 1.1.13", "rustls 0.20.9", "rustls-pemfile 0.2.1", "serde", @@ -10967,8 +11644,8 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tokio-util 0.6.10", - "tower", - "tower-http", + "tower 0.4.13", + "tower-http 0.2.5", "tracing", ] @@ -10980,7 +11657,7 @@ checksum = "c52b6ab05d160691083430f6f431707a4e05b64903f2ffa0095ee5efde759117" dependencies = [ "chrono", "form_urlencoded", - "http", + "http 0.2.12", "json-patch", "k8s-openapi", "once_cell", @@ -11011,29 +11688,6 @@ dependencies = [ "log", ] -[[package]] -name = "lalrpop" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" -dependencies = [ - "ascii-canvas", - "bit-set", - "diff", - "ena", - "is-terminal", - "itertools 0.10.5", - "lalrpop-util", - "petgraph 0.6.4", - "regex", - "regex-syntax", - "string_cache", - "term 0.7.0", - "tiny-keccak", - "unicode-xid", - "walkdir", -] - [[package]] name = "lalrpop" version = "0.20.2" @@ -11044,12 +11698,13 @@ dependencies = [ "bit-set 0.5.3", "ena", "itertools 0.11.0", - "lalrpop-util 0.20.2", + "lalrpop-util", "petgraph 0.6.5", + "pico-args", "regex", - "regex-syntax 0.8.2", + "regex-syntax", "string_cache", - "term", + "term 0.7.0", "tiny-keccak", "unicode-xid", "walkdir", @@ -11064,15 +11719,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "lalrpop-util" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" -dependencies = [ - "regex-automata 0.4.6", -] - [[package]] name = "language-e2e-testsuite" version = "0.1.0" @@ -11169,7 +11815,7 @@ version = "0.0.1" dependencies = [ "anyhow", "bcs 0.1.4", - "clap 4.5.21", + "clap 4.6.1", "codespan-reporting", "hex", "move-binary-format", @@ -11193,15 +11839,15 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d" dependencies = [ "arbitrary", "cc", @@ -11239,9 +11885,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libnghttp2-sys" -version = "0.1.11+1.64.0" +version = "0.1.13+1.68.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b6c24e48a7167cffa7119da39d577fa482e66c688a4aac016bee862e1a713c4" +checksum = "492e00167f1418c15648144f42bbfc63099806ecee9bf8d09a6353d6b4856b3c" dependencies = [ "cc", "libc", @@ -11249,13 +11895,14 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.12.1", "libc", - "redox_syscall 0.7.1", + "plain", + "redox_syscall 0.8.1", ] [[package]] @@ -11286,7 +11933,7 @@ dependencies = [ "libsecp256k1-core", "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", - "rand 0.8.5", + "rand 0.8.6", "serde", "sha2 0.9.9", "typenum", @@ -11348,9 +11995,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.13" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f526fdd09d99e19742883e43de41e1aa9e36db0c7ab7f935165d611c5cccc66" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "libc", @@ -11358,6 +12005,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "link-section" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "014e440054ce8170890229eeef5bcda955305e056ec713de40ed366944483f09" + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -11366,24 +12019,30 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linkme" -version = "0.3.32" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22d227772b5999ddc0690e733f734f95ca05387e329c4084fe65678c51198ffe" +checksum = "e83272d46373fb8decca684579ac3e7c8f3d71d4cc3aa693df8759e260ae41cf" dependencies = [ "linkme-impl", ] [[package]] name = "linkme-impl" -version = "0.3.32" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71a98813fa0073a317ed6a8055dcd4722a49d9b862af828ee68449adb799b6be" +checksum = "32d59e20403c7d08fe62b4376edfe5c7fb2ef1e6b1465379686d0f21c8df444b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] +[[package]] +name = "linktime-proc-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7b0a3383c2a1002d11349c92c85a666a5fb679e96c79d782cf0dbe557fd6ee" + [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -11398,33 +12057,30 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] -name = "listener" -version = "0.1.0" -dependencies = [ - "bytes", - "clap 4.4.14", - "tokio", -] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ "scopeguard", ] [[package]] name = "lodepng" -version = "3.12.1" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a32335d22e44238e2bb0b4d726964d18952ce1f1279ec3305305d2c61539eb" +checksum = "fe7982db11054edc023a1b424dddcc65be18f71fa46ec6bde2efcfc1fb6b22da" dependencies = [ "crc32fast", "flate2", @@ -11434,9 +12090,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f" dependencies = [ "serde_core", "value-bag", @@ -11444,13 +12100,19 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.0" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ea4e65087ff52f3862caff188d489f1fab49a0cb09e01b2e3f1a617b10aaed" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" dependencies = [ - "hashbrown 0.15.3", + "hashbrown 0.16.1", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "lz4" version = "1.28.1" @@ -11461,29 +12123,29 @@ dependencies = [ ] [[package]] -name = "lz4" -version = "1.25.0" +name = "lz4-sys" +version = "1.11.1+lz4-1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6eab492fe7f8651add23237ea56dbf11b3c4ff762ab83d40a47f11433421f91" +checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" dependencies = [ + "cc", "libc", - "lz4-sys", ] [[package]] -name = "lz4-sys" -version = "1.9.5" +name = "lz4_flex" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3" +checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a" dependencies = [ - "twox-hash", + "twox-hash 2.1.2", ] [[package]] name = "mach2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] @@ -11509,18 +12171,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "matchit" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" - [[package]] name = "matchit" version = "0.7.3" @@ -11539,19 +12189,19 @@ dependencies = [ [[package]] name = "md-5" -version = "0.10.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" dependencies = [ "cfg-if", - "digest 0.10.7", + "digest 0.11.3", ] [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "memmap2" @@ -11589,7 +12239,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "metrics-macros", "portable-atomic", ] @@ -11605,7 +12255,7 @@ dependencies = [ "metrics", "metrics-util", "quanta", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -11616,7 +12266,7 @@ checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -11636,12 +12286,12 @@ dependencies = [ [[package]] name = "migrations_internals" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" +checksum = "3bda1634d70d5bd53553cf15dca9842a396e8c799982a3ad22998dc44d961f24" dependencies = [ "serde", - "toml 0.8.12", + "toml 0.9.12+spec-1.1.0", ] [[package]] @@ -11714,6 +12364,23 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.61.2", +] + +[[package]] +name = "miracl_core_bls12381" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07cbe42e2a8dd41df582fb8e00fc24d920b5561cc301fcb6d14e2e0434b500f" + [[package]] name = "mirai-annotations" version = "1.12.0" @@ -11746,7 +12413,7 @@ dependencies = [ "fragile", "lazy_static", "mockall_derive 0.12.1", - "predicates 3.1.3", + "predicates 3.1.4", "predicates-tree", ] @@ -11771,7 +12438,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -11779,10 +12446,8 @@ name = "module-publish" version = "0.1.0" dependencies = [ "anyhow", - "aptos-framework", - "bcs 0.1.4", - "clap 4.4.14", - "move-binary-format", + "aptos-transaction-generator-lib", + "clap 4.6.1", ] [[package]] @@ -11818,7 +12483,7 @@ name = "move-asm" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.5.21", + "clap 4.6.1", "codespan", "codespan-reporting", "either", @@ -11851,7 +12516,7 @@ dependencies = [ "arbitrary", "backtrace", "dearbitrary", - "indexmap 2.7.0", + "indexmap 2.14.0", "move-bytecode-spec", "move-core-types", "once_cell", @@ -11930,7 +12595,7 @@ name = "move-bytecode-viewer" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.6.1", "crossterm 0.26.1", "move-binary-format", "move-bytecode-source-map", @@ -11944,7 +12609,7 @@ name = "move-cli" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.6.1", "codespan-reporting", "colored", "datatest-stable", @@ -11986,41 +12651,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "move-compiler" -version = "0.0.1" -dependencies = [ - "anyhow", - "bcs 0.1.4", - "clap 4.4.14", - "codespan-reporting", - "datatest-stable", - "hex", - "move-binary-format", - "move-borrow-graph", - "move-bytecode-source-map", - "move-bytecode-verifier", - "move-command-line-common", - "move-core-types", - "move-ir-to-bytecode", - "move-ir-types", - "move-stdlib", - "move-symbol-pool", - "once_cell", - "petgraph 0.5.1", - "regex", - "sha3 0.9.1", - "tempfile", -] - -[[package]] -name = "move-compiler-transactional-tests" -version = "0.1.0" -dependencies = [ - "datatest-stable", - "move-transactional-test-runner", -] - [[package]] name = "move-compiler-v2" version = "0.1.0" @@ -12028,7 +12658,8 @@ dependencies = [ "abstract-domain-derive", "anyhow", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", + "codespan", "codespan-reporting", "ethnum", "flexi_logger", @@ -12087,7 +12718,7 @@ dependencies = [ "primitive-types 0.10.1", "proptest", "proptest-derive", - "rand 0.8.5", + "rand 0.8.6", "ref-cast", "regex", "serde", @@ -12103,7 +12734,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "codespan", "colored", "move-binary-format", @@ -12121,7 +12752,7 @@ version = "0.1.0" dependencies = [ "anyhow", "bcs 0.1.4", - "clap 4.5.21", + "clap 4.6.1", "codespan", "codespan-reporting", "datatest-stable", @@ -12140,7 +12771,7 @@ name = "move-disassembler" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.6.1", "colored", "legacy-move-compiler", "move-binary-format", @@ -12156,7 +12787,7 @@ name = "move-docgen" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.6.1", "codespan", "codespan-reporting", "datatest-stable", @@ -12195,23 +12826,13 @@ dependencies = [ "move-stdlib", ] -[[package]] -name = "move-explain" -version = "0.1.0" -dependencies = [ - "bcs 0.1.4", - "clap 4.4.14", - "move-command-line-common", - "move-core-types", -] - [[package]] name = "move-ir-compiler" version = "0.1.0" dependencies = [ "anyhow", "bcs 0.1.4", - "clap 4.4.14", + "clap 4.6.1", "move-binary-format", "move-bytecode-source-map", "move-bytecode-verifier", @@ -12281,7 +12902,7 @@ dependencies = [ "move-model", "move-prover-test-utils", "move-stackless-bytecode", - "num 0.4.1", + "num 0.4.3", ] [[package]] @@ -12317,7 +12938,7 @@ name = "move-package" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.4.14", + "clap 4.6.1", "colored", "datatest-stable", "itertools 0.13.0", @@ -12368,7 +12989,7 @@ version = "0.1.0" dependencies = [ "anyhow", "atty", - "clap 4.4.14", + "clap 4.6.1", "codespan-reporting", "itertools 0.13.0", "legacy-move-compiler", @@ -12447,7 +13068,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chrono", - "clap 4.5.21", + "clap 4.6.1", "codespan-reporting", "itertools 0.13.0", "move-model", @@ -12575,43 +13196,14 @@ dependencies = [ ] [[package]] -name = "move-to-yul" +name = "move-transactional-test-runner" version = "0.1.0" dependencies = [ "anyhow", - "atty", - "clap 4.4.14", - "codespan", - "codespan-reporting", - "datatest-stable", - "ethnum", - "evm", - "evm-exec-utils", - "itertools 0.12.1", - "maplit", - "move-command-line-common", - "move-compiler", - "move-core-types", - "move-ethereum-abi", - "move-model", - "move-prover-test-utils", - "move-stackless-bytecode", - "move-stdlib", - "once_cell", - "primitive-types 0.10.1", - "regex", - "serde_json", - "sha3 0.9.1", - "tempfile", - "walkdir", -] - -[[package]] -name = "move-transactional-test-runner" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap 4.4.14", + "aptos-framework", + "arbitrary", + "bcs 0.1.4", + "clap 4.6.1", "datatest-stable", "dearbitrary", "difference", @@ -12646,7 +13238,7 @@ version = "0.1.0" dependencies = [ "anyhow", "better_any", - "clap 4.4.14", + "clap 4.6.1", "codespan-reporting", "colored", "datatest-stable", @@ -12783,12 +13375,12 @@ dependencies = [ "crossbeam", "dashmap 7.0.0-rc2", "derivative", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "itertools 0.13.0", "mockall 0.11.4", "move-binary-format", "move-core-types", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "proptest", "rand 0.7.3", "serde", @@ -12807,7 +13399,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 0.2.12", "httparse", "log", "memchr", @@ -12825,7 +13417,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 1.1.0", + "http 1.4.1", "httparse", "memchr", "mime", @@ -12852,16 +13444,16 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.33.2" +version = "0.33.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +checksum = "9d43ddcacf343185dfd6de2ee786d9e8b1c2301622afab66b6c73baf9882abfd" dependencies = [ "approx", "matrixmultiply", "num-complex 0.4.6", "num-rational 0.4.2", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "rand_distr", "simba 0.9.1", "typenum", @@ -12875,7 +13467,7 @@ checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -12894,17 +13486,17 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ "libc", "log", "openssl", - "openssl-probe", + "openssl-probe 0.2.1", "openssl-sys", "schannel", - "security-framework", + "security-framework 3.7.0", "security-framework-sys", "tempfile", ] @@ -12920,8 +13512,8 @@ dependencies = [ "blake2s_simd", "blstrs 0.7.1", "byteorder", - "ff 0.13.0", - "generic-array 0.14.7", + "ff 0.13.1", + "generic-array", "log", "pasta_curves", "serde", @@ -12938,7 +13530,16 @@ checksum = "ca2b420f638f07fe83056b55ea190bb815f609ec5a35e7017884a10f78839c9e" name = "new_debug_unreachable" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "newtype-uuid" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c012d14ef788ab066a347d19e3dda699916c92293b05b85ba2c76b8c82d2830" +dependencies = [ + "uuid 1.23.2", +] [[package]] name = "nix" @@ -12953,12 +13554,25 @@ dependencies = [ [[package]] name = "nix" -version = "0.27.1" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.12.1", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.12.1", "cfg-if", + "cfg_aliases 0.2.1", "libc", ] @@ -13001,9 +13615,9 @@ dependencies = [ [[package]] name = "ntest" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da8ec6d2b73d45307e926f5af46809768581044384637af6b3f3fe7c3c88f512" +checksum = "54d1aa56874c2152c24681ed0df95ee155cc06c5c61b78e2d1e8c0cae8bc5326" dependencies = [ "ntest_test_cases", "ntest_timeout", @@ -13011,9 +13625,9 @@ dependencies = [ [[package]] name = "ntest_test_cases" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be7d33be719c6f4d09e64e27c1ef4e73485dc4cc1f4d22201f89860a7fe22e22" +checksum = "6913433c6319ef9b2df316bb8e3db864a41724c2bb8f12555e07dc4ec69d3db1" dependencies = [ "proc-macro2", "quote", @@ -13022,11 +13636,11 @@ dependencies = [ [[package]] name = "ntest_timeout" -version = "0.9.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066b468120587a402f0b47d8f80035c921f6a46f8209efd0632a89a16f5188a4" +checksum = "9224be3459a0c1d6e9b0f42ab0e76e98b29aef5aba33c0487dfcf47ea08b5150" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", "syn 1.0.109", @@ -13122,7 +13736,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "zeroize", ] @@ -13145,6 +13759,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + [[package]] name = "num-derive" version = "0.4.2" @@ -13153,7 +13773,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -13186,17 +13806,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-modular" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" -dependencies = [ - "num-bigint 0.4.4", - "num-integer", - "num-traits", -] - [[package]] name = "num-rational" version = "0.3.2" @@ -13236,29 +13845,30 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.5.2", "libc", ] [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -13283,16 +13893,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] -name = "number_range" -version = "0.3.2" +name = "objc2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60080faccd4ca50ad0b801b2be686136376b13f691f6eac84817e40973b2e1bb" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ - "anyhow", - "itertools 0.10.5", - "num 0.4.1", + "objc2-encode", ] +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + [[package]] name = "object" version = "0.37.3" @@ -13304,9 +13918,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -13322,27 +13936,56 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] -name = "opaque-debug" -version = "0.3.0" +name = "open" +version = "5.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" +dependencies = [ + "is-wsl", + "libc", + "pathdiff 0.2.3", +] + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.6", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.12.1", "cfg-if", "foreign-types 0.3.2", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -13355,7 +13998,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -13364,11 +14007,17 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -13384,11 +14033,11 @@ checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" dependencies = [ "futures-core", "futures-sink", - "indexmap 2.7.0", + "indexmap 2.14.0", "js-sys", "once_cell", "pin-project-lite", - "thiserror", + "thiserror 1.0.69", "urlencoding", ] @@ -13419,7 +14068,7 @@ dependencies = [ "once_cell", "opentelemetry", "ordered-float 4.6.0", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -13496,8 +14145,8 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa", - "elliptic-curve", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "primeorder", "sha2 0.10.9", ] @@ -13510,7 +14159,7 @@ dependencies = [ "aptos-framework", "aptos-transaction-workloads-lib", "bcs 0.1.4", - "clap 4.5.21", + "clap 4.6.1", "move-package", ] @@ -13557,16 +14206,17 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" dependencies = [ "arrayvec 0.7.6", "bitvec 1.0.1", "byte-slice-cast", "const_format", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.9", + "parity-scale-codec-derive 3.7.5", + "rustversion", "serde", ] @@ -13584,14 +14234,14 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -13618,7 +14268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.12", ] [[package]] @@ -13637,15 +14287,49 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.48.5", + "windows-link", +] + +[[package]] +name = "parquet" +version = "52.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e977b9066b4d3b03555c22bdc442f3fadebd96a39111249113087d0edb2691cd" +dependencies = [ + "ahash 0.8.12", + "bytes", + "chrono", + "futures", + "half 2.7.1", + "hashbrown 0.14.5", + "lz4_flex", + "num 0.4.3", + "num-bigint 0.4.6", + "paste", + "seq-macro", + "thrift", + "tokio", + "twox-hash 1.6.3", +] + +[[package]] +name = "parquet_derive" +version = "52.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e57262f900bc3e93755be67e0fc4e2fcdae416b563472528e413c6e0a52ee81" +dependencies = [ + "parquet", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -13669,7 +14353,7 @@ dependencies = [ "mockall 0.11.4", "p256", "passkey-types", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -13696,12 +14380,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "499cff8432e71c5f8784d9645aac0f9fca604d67f59b68a606170b5e229c6538" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.12.1", "ciborium", "coset", "data-encoding", - "indexmap 2.2.5", - "rand 0.8.5", + "indexmap 2.14.0", + "rand 0.8.6", "serde", "serde_json", "sha2 0.10.9", @@ -13709,17 +14393,6 @@ dependencies = [ "typeshare", ] -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "pasta_curves" version = "0.5.1" @@ -13731,7 +14404,7 @@ dependencies = [ "group 0.13.0", "hex", "lazy_static", - "rand 0.8.5", + "rand 0.8.6", "serde", "static_assertions", "subtle", @@ -13741,7 +14414,7 @@ dependencies = [ name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" @@ -13794,9 +14467,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ "digest 0.10.7", - "hmac 0.12.1", - "password-hash", - "sha2 0.10.8", ] [[package]] @@ -13817,7 +14487,7 @@ checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" dependencies = [ "inlinable_string", "pear_codegen", - "yansi 1.0.0-rc.1", + "yansi", ] [[package]] @@ -13829,7 +14499,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -13854,12 +14524,12 @@ dependencies = [ [[package]] name = "pem" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ "base64 0.22.1", - "serde", + "serde_core", ] [[package]] @@ -13916,7 +14586,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -13946,7 +14616,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.2.5", + "indexmap 2.14.0", +] + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset 0.5.7", + "hashbrown 0.15.5", + "indexmap 2.14.0", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", ] [[package]] @@ -13955,7 +14646,16 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ - "phf_shared 0.11.2", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared 0.12.1", ] [[package]] @@ -13985,29 +14685,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared 0.11.3", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] -name = "phf_macros" +name = "phf_shared" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "phf_generator", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.87", + "siphasher 1.0.3", ] [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" dependencies = [ - "siphasher", + "siphasher 1.0.3", ] [[package]] @@ -14016,7 +14712,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ - "siphasher", + "siphasher 1.0.3", ] [[package]] @@ -14027,11 +14723,20 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.10" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef0f924a5ee7ea9cbcea77529dba45f8a9ba9f622419fe3386ca581a3ae9d5a" +dependencies = [ + "pin-project-internal 0.4.30", +] + +[[package]] +name = "pin-project" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ - "pin-project-internal 1.1.3", + "pin-project-internal 1.1.13", ] [[package]] @@ -14047,20 +14752,20 @@ dependencies = [ [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -14070,12 +14775,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" dependencies = [ "atomic-waker", - "fastrand 2.3.0", + "fastrand", "futures-io", ] @@ -14112,6 +14817,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -14124,9 +14839,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "plain" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "plotters" @@ -14171,41 +14892,40 @@ dependencies = [ [[package]] name = "poem" -version = "3.1.3" +version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef0e102c6b811e0e01928eed4872b3ff63917f37dc2dab39a93db55f25d314d" +checksum = "9f977080932c87287147dca052951c3e2696f8759863f6b4e4c0c9ffe7a4cc8b" dependencies = [ "anyhow", "async-compression", "bytes", - "chrono", - "cookie 0.17.0", "futures-util", - "headers", - "http", - "hyper", + "headers 0.4.1", + "http 1.4.1", + "http-body-util", + "hyper 1.10.1", + "hyper-util", "mime", - "multer", - "nix 0.27.1", - "parking_lot 0.12.1", + "multer 3.1.0", + "nix 0.30.1", + "parking_lot 0.12.5", "percent-encoding", "pin-project-lite", "poem-derive", "quick-xml 0.36.2", "regex", "rfc7239", - "rustls-pemfile 2.1.1", + "rustls-pemfile 2.2.0", "serde", "serde_json", "serde_urlencoded", - "serde_yaml 0.9.30", + "serde_yaml 0.9.34+deprecated", "smallvec", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tempfile", - "thiserror 1.0.69", - "time", + "thiserror 2.0.18", "tokio", - "tokio-rustls 0.25.0", + "tokio-rustls 0.26.4", "tokio-stream", "tokio-util 0.7.18", "tracing", @@ -14214,27 +14934,28 @@ dependencies = [ [[package]] name = "poem-derive" -version = "3.1.0" +version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdfed15c1102d2a9a51b9f1aba945628c72ccb52fc5d3e4ad4ffbbd222e11821" +checksum = "056e2fea6de1cb240ffe23cfc4fc370b629f8be83b5f27e16b7acd5231a72de4" dependencies = [ - "proc-macro-crate 2.0.1", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] name = "poem-openapi" -version = "5.1.2" +version = "5.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c354a706a81a17657da8441869c6ce3d486ef5e72705919d6035fb038a6f7b5" +checksum = "1ccbcc395bf4dd03df1da32da351b6b6732e4074ce27ddec315650e52a2be44c" dependencies = [ "base64 0.22.1", "bytes", - "derive_more 0.99.17", + "derive_more 2.1.1", "futures-util", - "indexmap 2.7.0", + "indexmap 2.14.0", + "itertools 0.14.0", "mime", "num-traits", "poem", @@ -14245,43 +14966,27 @@ dependencies = [ "serde_json", "serde_urlencoded", "serde_yaml 0.9.34+deprecated", - "thiserror 1.0.69", + "thiserror 2.0.18", "tokio", "url", ] [[package]] name = "poem-openapi-derive" -version = "5.1.1" +version = "5.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e4cd0c926ab1d9a015ecc1077c950d5897577554691ff70efcd9c90ddeb614" +checksum = "41273b691a3d467a8c44d05506afba9f7b6bd56c9cdf80123de13fe52d7ec587" dependencies = [ - "darling 0.14.4", - "http", - "indexmap 1.9.3", + "darling 0.20.11", + "http 1.4.1", + "indexmap 2.14.0", "mime", - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", "regex", - "syn 1.0.109", - "thiserror", -] - -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", + "syn 2.0.117", + "thiserror 2.0.18", ] [[package]] @@ -14294,7 +14999,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.5.2", "pin-project-lite", - "rustix 1.1.3", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -14305,8 +15010,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", - "cpufeatures", - "opaque-debug 0.3.0", + "cpufeatures 0.2.17", + "opaque-debug", "universal-hash", ] @@ -14348,9 +15053,9 @@ dependencies = [ [[package]] name = "postgres-native-tls" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac73153d92e4bde922bd6f1dfba7f1ab8132266c031153b55e20a1521cd36d49" +checksum = "fef4de47bb81477e0c3deaf153a1b10ae176484713ff1640969f4cb96b653ebc" dependencies = [ "native-tls", "tokio", @@ -14360,27 +15065,27 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.6" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" +checksum = "56201207dac53e2f38e848e31b4b91616a6bb6e0c7205b77718994a7f49e70fc" dependencies = [ "base64 0.22.1", "byteorder", "bytes", "fallible-iterator", - "hmac 0.12.1", + "hmac 0.13.0", "md-5", "memchr", - "rand 0.8.5", - "sha2 0.10.8", + "rand 0.10.1", + "sha2 0.11.0", "stringprep", ] [[package]] name = "postgres-types" -version = "0.2.6" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +checksum = "8dc729a129e682e8d24170cd30ae1aa01b336b096cbb56df6d534ffec133d186" dependencies = [ "bytes", "fallible-iterator", @@ -14389,9 +15094,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -14436,9 +15141,9 @@ dependencies = [ [[package]] name = "pq-sys" -version = "0.4.8" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0052426df997c0cbd30789eb44ca097e3541717a7b8fa36b1c464ee7edebd" +checksum = "f6cc05d7ea95200187117196eee9edd0644424911821aeb28a18ce60ea0b8793" dependencies = [ "vcpkg", ] @@ -14465,9 +15170,9 @@ dependencies = [ [[package]] name = "predicates" -version = "3.1.3" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" dependencies = [ "anstyle", "predicates-core", @@ -14522,10 +15227,20 @@ dependencies = [ ] [[package]] -name = "prettytable-rs" -version = "0.10.0" +name = "prettyplease" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + +[[package]] +name = "prettytable-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a" dependencies = [ "csv", "encode_unicode", @@ -14541,7 +15256,7 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve", + "elliptic-curve 0.13.8", ] [[package]] @@ -14582,21 +15297,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" -dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", -] - -[[package]] -name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.23.10+spec-1.0.0", + "toml_edit 0.25.12+spec-1.1.0", ] [[package]] @@ -14637,9 +15342,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -14652,9 +15357,9 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", "version_check", - "yansi 1.0.0-rc.1", + "yansi", ] [[package]] @@ -14662,7 +15367,7 @@ name = "processor" version = "0.1.0" source = "git+https://github.com/aptos-labs/aptos-indexer-processors-v2.git?tag=aptos-indexer-processors-v2.1.5#a1a0cfeff7febc81dbe5a238ed5318f319aaef6c" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.12", "allocative", "allocative_derive", "anyhow", @@ -14670,10 +15375,10 @@ dependencies = [ "async-trait", "bcs 0.1.4", "bigdecimal", - "bitflags 2.9.1", + "bitflags 2.12.1", "canonical_json", "chrono", - "clap 4.5.21", + "clap 4.6.1", "const_format", "diesel", "diesel-async", @@ -14686,7 +15391,7 @@ dependencies = [ "google-cloud-pubsub", "google-cloud-storage", "hex", - "hyper 0.14.28", + "hyper 0.14.32", "itertools 0.12.1", "jemallocator", "lazy_static", @@ -14698,13 +15403,13 @@ dependencies = [ "parquet_derive", "postgres-native-tls", "prometheus", - "prost 0.13.4", + "prost 0.13.5", "rayon", "regex", "serde", "serde_json", - "sha2 0.10.8", - "sha3 0.10.8", + "sha2 0.10.9", + "sha3 0.10.9", "strum 0.24.1", "tiny-keccak", "tokio", @@ -14746,8 +15451,9 @@ dependencies = [ "fnv", "lazy_static", "memchr", - "parking_lot 0.12.1", - "thiserror", + "parking_lot 0.12.5", + "protobuf", + "thiserror 1.0.69", ] [[package]] @@ -14758,7 +15464,7 @@ checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "prometheus-client-derive-encode", ] @@ -14770,7 +15476,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -14779,7 +15485,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ae2f6a3f14ff35c16b51ac796d1dc73c15ad6472c48836c6c467f6d52266648" dependencies = [ - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "time", @@ -14800,19 +15506,18 @@ dependencies = [ [[package]] name = "proptest" -version = "1.4.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bit-set", - "bit-vec", - "bitflags 2.4.1", - "lazy_static", + "bit-set 0.8.0", + "bit-vec 0.8.0", + "bitflags 2.12.1", "num-traits", - "rand 0.8.5", - "rand_chacha 0.3.1", - "rand_xorshift", - "regex-syntax 0.8.2", + "rand 0.9.4", + "rand_chacha 0.9.0", + "rand_xorshift 0.4.0", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -14826,7 +15531,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -14846,17 +15551,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.12.6", ] [[package]] name = "prost" -version = "0.13.4" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive 0.13.5", +] + +[[package]] +name = "prost" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" dependencies = [ "bytes", - "prost-derive 0.13.4", + "prost-derive 0.14.3", ] [[package]] @@ -14882,7 +15597,42 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools 0.14.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost 0.11.9", ] [[package]] @@ -14891,16 +15641,25 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ - "prost 0.12.3", + "prost 0.12.6", ] [[package]] name = "prost-types" -version = "0.13.1" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost 0.13.5", +] + +[[package]] +name = "prost-types" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" dependencies = [ - "prost 0.13.4", + "prost 0.14.3", ] [[package]] @@ -14928,25 +15687,6 @@ dependencies = [ "protobuf-codegen", ] -[[package]] -name = "prover-lab" -version = "0.1.0" -dependencies = [ - "anyhow", - "chrono", - "clap 4.4.14", - "codespan-reporting", - "itertools 0.12.1", - "log", - "move-compiler", - "move-model", - "move-prover", - "move-prover-boogie-backend", - "move-prover-bytecode-pipeline", - "plotters", - "z3tracer", -] - [[package]] name = "psl-types" version = "2.0.11" @@ -14975,7 +15715,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.12.1", "memchr", "unicase", ] @@ -15009,7 +15749,7 @@ dependencies = [ "mach2", "once_cell", "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "web-sys", "winapi 0.3.9", ] @@ -15022,17 +15762,17 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quick-junit" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ffd2f9a162cfae131bed6d9d1ed60adced33be340a94f96952897d7cb0c240" +checksum = "6ee9342d671fae8d66b3ae9fd7a9714dfd089c04d2a8b1ec0436ef77aee15e5f" dependencies = [ "chrono", - "indexmap 2.7.0", + "indexmap 2.14.0", "newtype-uuid", - "quick-xml 0.36.2", + "quick-xml 0.38.4", "strip-ansi-escapes", - "thiserror", - "uuid 1.11.0", + "thiserror 2.0.18", + "uuid 1.23.2", ] [[package]] @@ -15063,6 +15803,15 @@ dependencies = [ "serde", ] +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", +] + [[package]] name = "quick_cache" version = "0.5.2" @@ -15077,59 +15826,80 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.2" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", + "cfg_aliases 0.2.1", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash", - "rustls 0.23.7", - "thiserror", + "rustc-hash 2.1.2", + "rustls 0.23.40", + "socket2 0.6.4", + "thiserror 2.0.18", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.3" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "bytes", - "rand 0.8.5", - "ring 0.17.7", - "rustc-hash", - "rustls 0.23.7", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.4", + "ring 0.17.14", + "rustc-hash 2.1.2", + "rustls 0.23.40", + "rustls-pki-types", "slab", - "thiserror", + "thiserror 2.0.18", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.4" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ + "cfg_aliases 0.2.1", "libc", "once_cell", - "socket2 0.5.5", - "windows-sys 0.52.0", + "socket2 0.6.4", + "tracing", + "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "r2d2" version = "0.8.10" @@ -15169,15 +15939,36 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -15198,6 +15989,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -15225,6 +16026,12 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rand_distr" version = "0.4.3" @@ -15232,16 +16039,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", + "rand 0.8.6", ] [[package]] @@ -15271,6 +16069,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.5", +] + [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -15287,7 +16094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d0f7171155590e912ab907550240a5764c665388ab0a1e46d783a493e816ff3" dependencies = [ "once_cell", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -15307,9 +16114,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -15327,9 +16134,9 @@ dependencies = [ [[package]] name = "redis" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa8455fa3621f6b41c514946de66ea0531f57ca017b2e6c7cc368035ea5b46df" +checksum = "f8d5a2ed627935139b60bf35b4af4747cb2c657b5ac0567954d7a4b8300e3d21" dependencies = [ "arc-swap", "async-trait", @@ -15372,25 +16179,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "redox_syscall" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" -dependencies = [ - "bitflags 2.10.0", + "bitflags 2.12.1", ] [[package]] name = "redox_syscall" -version = "0.5.11" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.12.1", ] [[package]] @@ -15421,7 +16219,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -15449,9 +16247,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" @@ -15466,10 +16264,10 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", "hyper-rustls 0.24.2", "hyper-tls", "ipnet", @@ -15486,7 +16284,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-native-tls", @@ -15496,56 +16294,52 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams 0.3.0", + "wasm-streams", "web-sys", - "webpki-roots 0.25.3", - "winreg 0.50.0", + "webpki-roots 0.25.4", + "winreg", ] [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "async-compression", "base64 0.22.1", "bytes", "futures-core", "futures-util", - "http 1.1.0", - "http-body 1.0.0", + "http 1.4.1", + "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", - "hyper-rustls 0.27.2", + "hyper 1.10.1", + "hyper-rustls 0.27.9", "hyper-util", - "ipnet", "js-sys", "log", - "mime", "mime_guess", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.7", - "rustls-native-certs 0.7.0", - "rustls-pemfile 2.1.1", + "rustls 0.23.40", + "rustls-native-certs 0.8.4", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", - "tokio-rustls 0.26.0", - "tokio-util 0.7.10", + "tokio-rustls 0.26.4", + "tokio-util 0.7.18", + "tower 0.5.3", + "tower-http 0.6.11", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams 0.4.0", + "wasm-streams", "web-sys", - "winreg 0.52.0", ] [[package]] @@ -15556,8 +16350,8 @@ checksum = "5a735987236a8e238bf0296c7e351b999c188ccc11477f311b82b55c93984216" dependencies = [ "anyhow", "async-trait", - "http", - "reqwest", + "http 0.2.12", + "reqwest 0.11.27", "serde", "task-local-extensions", "thiserror 1.0.69", @@ -15573,11 +16367,11 @@ dependencies = [ "async-trait", "chrono", "futures", - "getrandom 0.2.11", - "http", - "hyper", + "getrandom 0.2.17", + "http 0.2.12", + "hyper 0.14.32", "parking_lot 0.11.2", - "reqwest 0.11.23", + "reqwest 0.11.27", "reqwest-middleware", "retry-policies", "task-local-extensions", @@ -15600,7 +16394,18 @@ checksum = "e09bbcb5003282bcb688f0bae741b278e9c7e8f378f561522c9806c58e075d9b" dependencies = [ "anyhow", "chrono", - "rand 0.8.5", + "rand 0.8.6", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac 0.12.1", + "zeroize", ] [[package]] @@ -15624,9 +16429,9 @@ dependencies = [ [[package]] name = "rgb" -version = "0.8.52" +version = "0.8.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" dependencies = [ "bytemuck", ] @@ -15669,6 +16474,49 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "ritual_build" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f86c36bf720176c6d573d0827cd5b2b9f1c6a3450dc237374a35ce0f2268835" +dependencies = [ + "log", + "ritual_common", +] + +[[package]] +name = "ritual_common" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d30de34c9683bedc6f0b1f5a3ef0bb613df7ff7e1833c767eeed45f1a9d2af" +dependencies = [ + "bincode", + "dunce", + "failure", + "itertools 0.8.2", + "lazy_static", + "log", + "num_cpus", + "pathdiff 0.1.0", + "regex", + "semver 0.9.0", + "serde", + "serde_derive", + "serde_json", + "shell-words 0.1.0", + "term-painter", + "toml 0.4.10", +] + +[[package]] +name = "rlimit" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" +dependencies = [ + "libc", +] + [[package]] name = "rlp" version = "0.5.2" @@ -15735,7 +16583,6 @@ dependencies = [ "pkcs1 0.7.5", "pkcs8 0.10.2", "rand_core 0.6.4", - "sha2 0.10.8", "signature 2.2.0", "spki 0.7.3", "subtle", @@ -15818,6 +16665,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -15830,7 +16683,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.27", + "semver 1.0.28", ] [[package]] @@ -15853,7 +16706,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.12.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -15862,14 +16715,14 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.12.1", "errno", "libc", - "linux-raw-sys 0.11.0", + "linux-raw-sys 0.12.1", "windows-sys 0.61.2", ] @@ -15913,15 +16766,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring 0.17.14", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.13", "subtle", "zeroize", ] @@ -15932,23 +16786,22 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ - "openssl-probe", + "openssl-probe 0.1.6", "rustls-pemfile 1.0.4", "schannel", - "security-framework", + "security-framework 2.11.1", ] [[package]] name = "rustls-native-certs" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ - "openssl-probe", - "rustls-pemfile 2.2.0", + "openssl-probe 0.2.1", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.7.0", ] [[package]] @@ -15975,15 +16828,28 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.21.6", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.100.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] [[package]] name = "rustls-webpki" @@ -16008,10 +16874,11 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring 0.17.14", "rustls-pki-types", "untrusted 0.9.0", @@ -16103,8 +16970,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if", - "derive_more 0.99.17", - "parity-scale-codec 2.3.1", + "derive_more 1.0.0", + "parity-scale-codec 3.7.5", "scale-info-derive", ] @@ -16114,17 +16981,17 @@ version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -16192,7 +17059,7 @@ dependencies = [ "hmac 0.12.1", "pbkdf2 0.11.0", "salsa20", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -16213,27 +17080,41 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.7.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der 0.7.8", - "generic-array 0.14.7", - "pkcs8 0.10.2", - "serdect", + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", "subtle", "zeroize", ] [[package]] -name = "secret-vault-value" -version = "0.3.8" +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.10", + "generic-array", + "pkcs8 0.10.2", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "secret-vault-value" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f8cfb86d2019f64a4cfb49e499f401f406fbec946c1ffeea9d0504284347de" +checksum = "662c7f8e99d46c9d3a87561d771a970c29efaccbab4bbdc6ab65d099d2358077" dependencies = [ - "prost 0.12.3", - "prost-types 0.12.3", + "prost 0.14.3", + "prost-types 0.14.3", "serde", "serde_json", "zeroize", @@ -16245,8 +17126,21 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.10.0", - "core-foundation", + "bitflags 2.12.1", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.12.1", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -16254,9 +17148,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -16268,7 +17162,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03ec815b5eab420ab893f63393878d89c90fdd94c0bcc44c07abb8ad95552fb7" dependencies = [ - "fastrand 2.3.0", + "fastrand", "tempfile", "windows-sys 0.52.0", ] @@ -16278,14 +17172,14 @@ name = "self_update" version = "0.39.0" source = "git+https://github.com/banool/self_update.git?rev=8306158ad0fd5b9d4766a3c6bf967e7ef0ea5c4b#8306158ad0fd5b9d4766a3c6bf967e7ef0ea5c4b" dependencies = [ - "hyper 0.14.28", + "hyper 0.14.32", "indicatif 0.17.11", "log", "quick-xml 0.23.1", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "self-replace", - "semver 1.0.27", + "semver 1.0.28", "serde_json", "tempfile", "urlencoding", @@ -16304,9 +17198,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" dependencies = [ "serde", "serde_core", @@ -16319,14 +17213,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] -name = "sender" -version = "0.1.0" -dependencies = [ - "bytes", - "clap 4.4.14", - "event-listener 2.5.3", - "tokio", -] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "seq-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] name = "serde" @@ -16432,16 +17328,16 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.14.0", "itoa", "memchr", "serde", @@ -16466,7 +17362,7 @@ version = "0.9.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e408f29489b5fd500fab51ff1484fc859bb655f32c671f307dcd733b72e8168c" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.14.0", "itoa", "ryu", "serde", @@ -16475,19 +17371,20 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.16" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa", "serde", + "serde_core", ] [[package]] name = "serde_regex" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" +checksum = "bafc8d0c5330cecff10f16b459b479fd9acaa5b4acd7167301414e21b0057012" dependencies = [ "regex", "serde", @@ -16501,7 +17398,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -16515,9 +17412,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ "serde_core", ] @@ -16536,16 +17433,19 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.16.1" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" dependencies = [ - "base64 0.21.6", + "base64 0.22.1", + "bs58 0.5.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.2.5", - "serde", + "indexmap 2.14.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -16553,14 +17453,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.1" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" dependencies = [ - "darling 0.20.9", + "darling 0.23.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -16581,7 +17481,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.14.0", "itoa", "ryu", "serde", @@ -16594,7 +17494,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct", + "base16ct 0.2.0", "serde", ] @@ -16624,7 +17524,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -16642,9 +17542,9 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] @@ -16654,10 +17554,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + [[package]] name = "sha256" version = "1.6.0" @@ -16680,14 +17591,14 @@ dependencies = [ "block-buffer 0.9.0", "digest 0.9.0", "keccak", - "opaque-debug 0.3.0", + "opaque-debug", ] [[package]] name = "sha3" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" dependencies = [ "digest 0.10.7", "keccak", @@ -16733,6 +17644,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signal-hook" version = "0.3.18" @@ -16769,6 +17686,10 @@ name = "signature" version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] [[package]] name = "signature" @@ -16808,9 +17729,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "similar" @@ -16845,9 +17766,9 @@ dependencies = [ [[package]] name = "simple_asn1" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" +checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d" dependencies = [ "num-bigint 0.4.6", "num-traits", @@ -16872,6 +17793,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + [[package]] name = "sized-chunks" version = "0.6.5" @@ -16921,20 +17848,20 @@ dependencies = [ [[package]] name = "sluice" -version = "0.5.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7400c0eff44aa2fcb5e31a5f24ba9716ed90138769e4977a2ba6014ae63eb5" +checksum = "160b744a45e8261307bcfe03c98e2f8274502207d534c9a64b675c4db1b6bd58" dependencies = [ - "async-channel 1.9.0", + "async-channel 2.5.0", "futures-core", "futures-io", ] [[package]] name = "smallbitvec" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d31d263dd118560e1a492922182ab6ca6dc1d03a3bf54e7699993f31a4150e3f" +checksum = "9b0e903ee191d8f7a8fbf0d712c3a1699d19e04ceba5ad1eb673053c7d938a09" [[package]] name = "smallvec" @@ -16998,7 +17925,7 @@ dependencies = [ "ethers", "futures", "hex", - "hyper 0.14.28", + "hyper 0.14.32", "itertools 0.13.0", "move-binary-format", "move-core-types", @@ -17006,7 +17933,7 @@ dependencies = [ "once_cell", "rand 0.7.3", "regex", - "reqwest 0.11.23", + "reqwest 0.11.27", "serde", "serde_json", "serde_yaml 0.8.26", @@ -17062,36 +17989,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "socket2" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "solang-parser" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" -dependencies = [ - "itertools 0.11.0", - "lalrpop 0.20.2", - "lalrpop-util 0.20.2", - "phf 0.11.2", - "thiserror", - "unicode-xid", + "windows-sys 0.61.2", ] [[package]] @@ -17102,7 +18005,7 @@ checksum = "c87e960f4dca2788eeb86bbdde8dd246be8948790b7618d656e68f9b720a86e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] @@ -17127,6 +18030,16 @@ dependencies = [ "der 0.5.1", ] +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + [[package]] name = "spki" version = "0.7.3" @@ -17156,9 +18069,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e" dependencies = [ "approx", - "nalgebra 0.33.2", + "nalgebra 0.33.3", "num-traits", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -17173,9 +18086,9 @@ dependencies = [ [[package]] name = "str_stack" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" +checksum = "7f446288b699d66d0fd2e30d1cfe7869194312524b3b9252594868ed26ef056a" [[package]] name = "string_cache" @@ -17202,9 +18115,9 @@ dependencies = [ [[package]] name = "strip-ansi-escapes" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" dependencies = [ "vte", ] @@ -17229,11 +18142,11 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "struct-path" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899edf28cf7320503eda593b4bbce1bc5e9533501a11d45537e2c5be90128fc7" +checksum = "3bb4afb8a683e3335fa737ad69e4338f1293debed26ec15c0cfab497e75ad3e3" dependencies = [ - "convert_case 0.6.0", + "convert_case 0.8.0", ] [[package]] @@ -17282,7 +18195,16 @@ dependencies = [ name = "strum" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" [[package]] name = "strum_macros" @@ -17307,7 +18229,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -17320,7 +18242,19 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.48", + "syn 2.0.117", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -17348,8 +18282,8 @@ dependencies = [ "anyhow", "aptos-types", "async-trait", - "clap 4.4.14", - "reqwest", + "clap 4.6.1", + "reqwest 0.11.27", ] [[package]] @@ -17361,7 +18295,7 @@ dependencies = [ "debugid", "memmap2", "stable_deref_trait", - "uuid 1.11.0", + "uuid 1.23.2", ] [[package]] @@ -17388,9 +18322,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -17403,6 +18337,38 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "sysinfo" version = "0.28.4" @@ -17425,7 +18391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -17453,9 +18419,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", @@ -17464,15 +18430,15 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "target-spec" -version = "3.5.7" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c173ce474b6257cfb2a107949e48eb1ab9cae21cecbdf13401ae3be4a411a" +checksum = "b00e973676af5497c2a69cc9787e2205c00f3b6f4f70e7d7b0112e28aa84b501" dependencies = [ "cfg-expr", "guppy-workspace-hack", @@ -17497,14 +18463,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.25.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ - "fastrand 2.3.0", - "getrandom 0.4.1", + "fastrand", + "getrandom 0.4.2", "once_cell", - "rustix 1.1.3", + "rustix 1.1.4", "windows-sys 0.61.2", ] @@ -17515,14 +18481,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8004bca281f2d32df3bacd59bc67b312cb4c70cea46cbd79dbe8ac5ed206722" dependencies = [ "chrono", - "chrono-tz 0.8.5", + "chrono-tz 0.9.0", "globwalk", "humansize", "lazy_static", "percent-encoding", "pest", "pest_derive", - "rand 0.8.5", + "rand 0.8.6", "regex", "serde", "serde_json", @@ -17571,12 +18537,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.4.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ - "rustix 0.38.28", - "windows-sys 0.59.0", + "rustix 1.1.4", + "windows-sys 0.61.2", ] [[package]] @@ -17603,7 +18569,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -17614,46 +18580,10 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", "test-case-core", ] -[[package]] -name = "test-generation" -version = "0.1.0" -dependencies = [ - "clap 4.4.14", - "crossbeam-channel", - "getrandom 0.2.11", - "hex", - "itertools 0.12.1", - "module-generation", - "move-binary-format", - "move-bytecode-verifier", - "move-compiler", - "move-core-types", - "move-stdlib", - "move-vm-runtime", - "move-vm-test-utils", - "move-vm-types", - "num_cpus", - "once_cell", - "rand 0.8.5", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "testdiff" -version = "0.1.0" -dependencies = [ - "anyhow", - "clap 4.4.14", - "once_cell", - "regex", - "walkdir", -] - [[package]] name = "textwrap" version = "0.11.0" @@ -17716,7 +18646,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -17761,9 +18702,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -17778,15 +18719,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -17803,7 +18744,7 @@ dependencies = [ "once_cell", "pbkdf2 0.4.0", "rand 0.7.3", - "rustc-hash", + "rustc-hash 1.1.0", "sha2 0.9.9", "thiserror 1.0.69", "unicode-normalization", @@ -17822,9 +18763,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -17842,9 +18783,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -17857,21 +18798,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", - "mio", - "num_cpus", - "parking_lot 0.12.1", + "mio 1.2.1", + "parking_lot 0.12.5", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.2", + "socket2 0.6.4", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -17886,13 +18826,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -17907,9 +18847,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.10" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +checksum = "4dd8df5ef180f6364759a6f00f7aadda4fbbac86cdee37480826a6ff9f3574ce" dependencies = [ "async-trait", "byteorder", @@ -17924,21 +18864,21 @@ dependencies = [ "pin-project-lite", "postgres-protocol", "postgres-types", - "rand 0.8.5", - "socket2 0.5.5", + "rand 0.10.1", + "socket2 0.6.4", "tokio", "tokio-util 0.7.18", - "whoami 2.1.1", + "whoami 2.1.0", ] [[package]] name = "tokio-retry" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +checksum = "40f644c762e9d396831ae2f8935c954b0d758c4532e924bead0f666d0c1c8640" dependencies = [ - "pin-project 1.1.3", - "rand 0.8.5", + "pin-project-lite", + "rand 0.10.1", "tokio", ] @@ -17974,24 +18914,13 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" -dependencies = [ - "rustls 0.22.4", - "rustls-pki-types", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.36", + "rustls 0.23.40", "tokio", ] @@ -18007,9 +18936,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -18035,11 +18964,8 @@ checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", - "rustls 0.21.10", "tokio", - "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots 0.25.3", ] [[package]] @@ -18097,66 +19023,171 @@ checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned 0.6.9", - "toml_datetime 0.6.3", + "toml_datetime 0.6.11", "toml_edit 0.19.15", ] [[package]] -name = "toml_datetime" -version = "0.6.6" +name = "toml" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +name = "toml" +version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ + "indexmap 2.14.0", "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", ] [[package]] -name = "toml_edit" -version = "0.19.15" +name = "toml" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "indexmap 2.2.5", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", + "indexmap 2.14.0", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", ] [[package]] -name = "toml_edit" -version = "0.21.1" +name = "toml_datetime" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ - "indexmap 2.2.5", - "toml_datetime", - "winnow", + "serde", ] [[package]] -name = "toml_parser" -version = "1.0.7+spec-1.1.0" +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "247eaa3197818b831697600aadf81514e577e0cba5eab10f7e064e78ae154df1" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ - "winnow 0.7.14", + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.14.0", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap 2.14.0", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.15", +] + +[[package]] +name = "toml_edit" +version = "0.25.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.3", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-stream", + "async-trait", + "axum 0.6.20", + "base64 0.21.7", + "bytes", + "flate2", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-timeout 0.4.1", + "percent-encoding", + "pin-project 1.1.13", + "prost 0.11.9", + "rustls-pemfile 1.0.4", + "tokio", + "tokio-rustls 0.24.1", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", + "webpki-roots 0.23.1", +] [[package]] name = "tonic" @@ -18169,17 +19200,17 @@ dependencies = [ "axum 0.6.20", "base64 0.21.7", "bytes", - "h2 0.3.26", - "http 0.2.11", + "h2 0.3.27", + "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.28", + "hyper 0.14.32", "hyper-timeout 0.4.1", "percent-encoding", - "pin-project 1.1.3", - "prost 0.12.3", + "pin-project 1.1.13", + "prost 0.12.6", "tokio", "tokio-stream", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -18193,30 +19224,31 @@ checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ "async-stream", "async-trait", - "axum 0.7.5", + "axum 0.7.9", "base64 0.22.1", "bytes", "flate2", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", + "h2 0.4.14", + "http 1.4.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.10.1", + "hyper-timeout 0.5.2", + "hyper-util", "percent-encoding", - "pin-project", - "prost", - "rustls-native-certs 0.7.0", - "rustls-pemfile 2.1.1", - "strum 0.26.2", - "strum_macros 0.26.4", + "pin-project 1.1.13", + "prost 0.13.5", + "rustls-native-certs 0.8.4", + "rustls-pemfile 2.2.0", + "socket2 0.5.10", "tokio", "tokio-rustls 0.26.4", "tokio-stream", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", - "zstd 0.13.0", + "zstd", ] [[package]] @@ -18225,8 +19257,8 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "878d81f52e7fcfd80026b7fdb6a9b578b3c3653ba987f87f0dce4b64043cba27" dependencies = [ - "prost 0.13.4", - "prost-types 0.13.1", + "prost 0.13.5", + "prost-types 0.13.5", "tokio", "tokio-stream", "tonic 0.12.3", @@ -18247,9 +19279,9 @@ dependencies = [ "futures-core", "futures-util", "indexmap 1.9.3", - "pin-project 1.1.3", + "pin-project 1.1.13", "pin-project-lite", - "rand 0.8.5", + "rand 0.8.6", "slab", "tokio", "tokio-util 0.7.18", @@ -18258,6 +19290,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 1.0.2", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-http" version = "0.2.5" @@ -18269,8 +19317,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "pin-project-lite", "tower-layer", @@ -18280,21 +19328,25 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.3.5" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ - "bitflags 1.3.2", + "async-compression", + "bitflags 2.12.1", "bytes", "futures-core", "futures-util", - "http", - "http-body", - "http-range-header", + "http 1.4.1", + "http-body 1.0.1", + "http-body-util", "pin-project-lite", - "tower", + "tokio", + "tokio-util 0.7.18", + "tower 0.5.3", "tower-layer", "tower-service", + "url", ] [[package]] @@ -18307,7 +19359,19 @@ checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" name = "tower-service" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tower-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1093c19826d33807c72511e68f73b4a0469a3f22c2bd5f7d5212178b4b89674" +dependencies = [ + "futures-core", + "futures-util", + "pin-project 0.4.30", + "tower-service", +] [[package]] name = "tracing" @@ -18329,7 +19393,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", ] [[package]] @@ -18348,7 +19412,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.1.3", + "pin-project 1.1.13", "tracing", ] @@ -18384,9 +19448,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term 0.50.3", @@ -18456,14 +19520,14 @@ checksum = "b9c81686f7ab4065ccac3df7a910c4249f8c0f3fb70421d6ddec19b9311f63f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.117", ] [[package]] name = "trybuild" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f614c21bd3a61bad9501d75cbb7686f00386c806d7f456778432c25cf86948a" +checksum = "47c635f0191bd3a2941013e5062667100969f8c4e9cd787c14f977265d73616e" dependencies = [ "glob", "serde", @@ -18471,7 +19535,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.12+spec-1.1.0", + "toml 1.1.2+spec-1.1.0", ] [[package]] @@ -18496,11 +19560,10 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 1.4.1", "httparse", "log", - "rand 0.8.5", - "rustls 0.21.10", + "rand 0.8.6", "sha1", "thiserror 1.0.69", "url", @@ -18517,6 +19580,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "twox-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" + [[package]] name = "typed-arena" version = "2.0.2" @@ -18525,9 +19594,9 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "typeshare" @@ -18548,7 +19617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "621963e302416b389a1ec177397e9e62de849a78bd8205d428608553def75350" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -18574,9 +19643,9 @@ dependencies = [ [[package]] name = "tzdb_data" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310d19de36af75a78ec83fdb325bf4e3a13ab0ab77b7b1a13fabbd059e9b525b" +checksum = "e866b98f6ed570c3ef7bc92f15021a9f9be377b7e6f8b1f0161179fdf84a442c" dependencies = [ "tz-rs", ] @@ -18615,54 +19684,10 @@ dependencies = [ ] [[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" -dependencies = [ - "unic-ucd-segment", -] - -[[package]] -name = "unic-ucd-segment" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" +name = "unescape" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] +checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" [[package]] name = "unicase" @@ -18678,9 +19703,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] name = "unicode-ident" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-linebreak" @@ -18705,9 +19730,9 @@ checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" @@ -18733,7 +19758,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] @@ -18780,9 +19805,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna 1.1.0", @@ -18833,12 +19858,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "uuid" -version = "1.6.1" +name = "utoipa" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "8bde15df68e80b16c7d16b9616e80770ad158988daa56a27dccd1e55558b0160" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.14.0", "serde", "serde_json", "serde_norway", @@ -18847,23 +19872,33 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "5.4.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b" +checksum = "6ba0b99ee52df3028635d93840c797102da61f8a7bb3cf751032455895b52ef8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", - "uuid", + "syn 2.0.117", + "uuid 1.23.2", ] [[package]] name = "uuid" -version = "1.20.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.2.17", + "serde", +] + +[[package]] +name = "uuid" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +dependencies = [ + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", @@ -18877,9 +19912,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "value-bag" -version = "1.5.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd65ff0de3304a013e6dfeb7324e1cd389a8a000e582e3c9c9fae82ced778e26" +checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" [[package]] name = "variant_count" @@ -18889,7 +19924,7 @@ checksum = "a1935e10c6f04d22688d07c0790f2fc0e1b1c5c2c55bc0cc87ed67656e587dd8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -18914,7 +19949,16 @@ checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vte" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" +dependencies = [ + "memchr", +] [[package]] name = "wait-timeout" @@ -18959,16 +20003,16 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "headers", - "http", - "hyper", + "headers 0.3.9", + "http 0.2.12", + "hyper 0.14.32", "log", "mime", "mime_guess", "multer 2.1.0", "percent-encoding", - "pin-project", - "rustls-pemfile 1.0.4", + "pin-project 1.1.13", + "rustls-pemfile 2.2.0", "scoped-tls", "serde", "serde_json", @@ -18987,10 +20031,10 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "948552bbb7a5fb4ba3169fd09b6c1ab53c1b2fdd82603295df550f7a1ec644c0" dependencies = [ - "hyper 0.14.28", + "hyper 0.14.32", "once_cell", - "reqwest", - "thiserror", + "reqwest 0.11.27", + "thiserror 1.0.69", "unicase", "warp", ] @@ -19005,7 +20049,34 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] [[package]] name = "wasite" @@ -19014,38 +20085,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] -name = "wasm-bindgen" -version = "0.2.89" +name = "wasite" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "66fe902b4a6b8028a753d5424909b764ccf79b7a209eac9bf97e59cda9f71a42" dependencies = [ - "cfg-if", - "wasm-bindgen-macro", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.89" +name = "wasm-bindgen" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ - "bumpalo", - "log", + "cfg-if", "once_cell", - "proc-macro2", - "quote", - "syn 2.0.48", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", - "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -19054,9 +20121,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -19064,29 +20131,53 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.48", - "wasm-bindgen-backend", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.14.0", + "wasm-encoder", + "wasmparser", +] [[package]] name = "wasm-streams" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" dependencies = [ "futures-util", "js-sys", @@ -19116,17 +20207,17 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.12.1", "hashbrown 0.15.5", - "indexmap 2.13.0", - "semver 1.0.27", + "indexmap 2.14.0", + "semver 1.0.28", ] [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -19198,13 +20289,11 @@ dependencies = [ [[package]] name = "whoami" -version = "2.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a5b12f9df4f978d2cfdb1bd3bac52433f44393342d7ee9c25f5a1c14c0f45d" +checksum = "8fae98cf96deed1b7572272dfc777713c249ae40aa1cf8862e091e8b745f5361" dependencies = [ - "libc", "libredox", - "objc2-system-configuration", "wasite 1.0.2", "web-sys", ] @@ -19280,7 +20369,33 @@ version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-targets 0.52.0", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -19289,6 +20404,24 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -19313,7 +20446,34 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", ] [[package]] @@ -19563,7 +20723,25 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" name = "winnow" version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7520bbdec7211caa7c4e682eb1fbe07abe20cee6756b6e00f537c82c11816aa" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -19578,6 +20756,125 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.14.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.12.1", + "indexmap 2.14.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.14.0", + "log", + "semver 1.0.28", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "writeable" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" + +[[package]] +name = "ws_stream_wasm" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c173014acad22e83f16403ee360115b38846fe754e735c5d9d3803fe70c6abc" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper", + "thiserror 2.0.18", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wyz" version = "0.2.0" @@ -19610,7 +20907,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", - "rustix 1.1.3", + "rustix 1.1.4", ] [[package]] @@ -19630,9 +20927,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -19641,13 +20938,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "synstructure 0.13.2", ] @@ -19661,8 +20958,8 @@ dependencies = [ "async-trait", "base64 0.21.7", "futures", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.32", "hyper-rustls 0.24.2", "itertools 0.12.1", "log", @@ -19691,22 +20988,43 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", + "synstructure 0.13.2", ] [[package]] @@ -19726,7 +21044,40 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.117", +] + +[[package]] +name = "zerotrie" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -19735,18 +21086,11 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" dependencies = [ - "aes", "byteorder", - "bzip2", - "constant_time_eq 0.1.5", "crc32fast", "crossbeam-utils", "flate2", - "hmac 0.12.1", - "pbkdf2 0.11.0", - "sha1", "time", - "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -19760,22 +21104,24 @@ dependencies = [ ] [[package]] -name = "zstd" -version = "0.13.3" +name = "zlib-rs" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe 7.0.0", -] +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" [[package]] -name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zstd" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ - "libc", - "zstd-sys", + "zstd-safe", ] [[package]] @@ -19805,3 +21151,48 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" dependencies = [ "simd-adler32", ] + +[[patch.unused]] +name = "futures" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-channel" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-core" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-executor" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-io" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-macro" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-sink" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-task" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" + +[[patch.unused]] +name = "futures-util" +version = "0.3.30" +source = "git+https://github.com/aptos-labs/futures-rs?branch=backport#1845d7d36bc4bccbc0b57be68fbc05abd0b8bc68" diff --git a/Cargo.toml b/Cargo.toml index c16ef67fa9b..063d1397f63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -612,10 +612,10 @@ firestore = "0.43.0" fixed = "1.25.1" flate2 = "1.0.24" flexi_logger = "0.27.4" -futures = "0.3.29" -futures-channel = "0.3.29" -futures-core = "0.3.29" -futures-util = "0.3.29" +futures = "0.3.32" +futures-channel = "0.3.32" +futures-core = "0.3.32" +futures-util = "0.3.32" fxhash = "0.2.1" getrandom = "0.2.2" gcp-bigquery-client = "0.16.8" diff --git a/api/types/src/transaction.rs b/api/types/src/transaction.rs index 16cd8151ffa..7460a95cead 100755 --- a/api/types/src/transaction.rs +++ b/api/types/src/transaction.rs @@ -19,7 +19,7 @@ use aptos_crypto::{ use aptos_types::{ account_address::AccountAddress, aggregate_signature::AggregateSignature, - aptos_dkg::{DKGTranscript, DKGTranscriptMetadata}, + dkg::{DKGTranscript, DKGTranscriptMetadata}, block_metadata::BlockMetadata, block_metadata_ext::BlockMetadataExt, contract_event::{ContractEvent, EventWithVersion}, @@ -394,38 +394,6 @@ impl From<(TransactionInfo, WriteSetPayload, Vec)> for Transaction { } } -impl From<(&BlockMetadata, TransactionInfo, Vec)> for Transaction { - fn from((txn, info, events): (&BlockMetadata, TransactionInfo, Vec)) -> Self { - Transaction::BlockMetadataTransaction(BlockMetadataTransaction { - info, - id: txn.id().into(), - epoch: txn.epoch().into(), - round: txn.round().into(), - events, - previous_block_votes_bitvec: txn.previous_block_votes_bitvec().clone(), - proposer: txn.proposer().into(), - failed_proposer_indices: txn.failed_proposer_indices().clone(), - timestamp: txn.timestamp_usecs().into(), - }) - } -} - -impl From<(&BlockMetadataExt, TransactionInfo, Vec)> for Transaction { - fn from((txn, info, events): (&BlockMetadataExt, TransactionInfo, Vec)) -> Self { - Transaction::BlockMetadataTransaction(BlockMetadataTransaction { - info, - id: txn.id().into(), - epoch: txn.epoch().into(), - round: txn.round().into(), - events, - previous_block_votes_bitvec: txn.previous_block_votes_bitvec().clone(), - proposer: txn.proposer().into(), - failed_proposer_indices: txn.failed_proposer_indices().clone(), - timestamp: txn.timestamp_usecs().into(), - }) - } -} - impl From<(&SignedTransaction, TransactionPayload)> for UserTransactionRequest { fn from((txn, payload): (&SignedTransaction, TransactionPayload)) -> Self { Self { @@ -764,7 +732,7 @@ impl BlockMetadataTransaction { pub fn from_internal( internal: BlockMetadata, info: TransactionInfo, - events: Vec, + events: Vec, ) -> Self { Self { info, @@ -783,7 +751,7 @@ impl BlockMetadataTransaction { pub fn from_internal_ext( internal: BlockMetadataExt, info: TransactionInfo, - events: Vec, + events: Vec, ) -> Self { Self { info, diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs index f10367049b4..4d79981156c 100644 --- a/aptos-move/aptos-vm/src/aptos_vm.rs +++ b/aptos-move/aptos-vm/src/aptos_vm.rs @@ -5,11 +5,12 @@ use crate::{ automated_transaction_processor::AutomatedTransactionProcessor, + automation_registry_transaction_processor::AutomationRegistryTransactionProcessor, block_executor::{AptosTransactionOutput, AptosVMBlockExecutorWrapper}, counters::*, data_cache::{AsMoveResolver, StorageAdapter}, errors::{discarded_output, expect_only_successful_execution}, - gas::{check_gas, make_prod_gas_meter, ProdGasMeter}, + gas::{check_automation_task_gas, check_gas, make_prod_gas_meter, ProdGasMeter}, keyless_validation, move_vm_ext::{ session::user_transaction_sessions::{ @@ -41,6 +42,7 @@ use aptos_crypto::{ HashValue, }; use aptos_framework::natives::code::PublishRequest; +use aptos_framework::natives::randomness::RandomnessContext; use aptos_gas_algebra::{Gas, GasQuantity, NumBytes, Quant}; use aptos_gas_meter::{AptosGasMeter, GasAlgebra}; use aptos_gas_schedule::{ @@ -79,9 +81,8 @@ use aptos_types::{ randomness::Randomness, state_store::{state_key::StateKey, StateView, TStateView}, transaction::{ - authenticator::{AbstractionAuthData, AnySignature, + authenticator::{AbstractionAuthData, AnySignature, AuthenticationProof}, automation::{AutomationTaskType, RegistrationParams}, - AuthenticationProof}, block_epilogue::{BlockEpiloguePayload, FeeDistribution}, signature_verified_transaction::SignatureVerifiedTransaction, BlockOutput, EntryFunction, ExecutionError, ExecutionStatus, ModuleBundle, @@ -160,8 +161,6 @@ use std::{ sync::Arc, }; -use crate::gas::check_automation_task_gas; - static EXECUTION_CONCURRENCY_LEVEL: OnceCell = OnceCell::new(); static NUM_EXECUTION_SHARD: OnceCell = OnceCell::new(); static NUM_PROOF_READING_THREADS: OnceCell = OnceCell::new(); @@ -192,10 +191,6 @@ macro_rules! unwrap_or_discard { }; } -use crate::{ - automation_registry_transaction_processor::AutomationRegistryTransactionProcessor, - gas::check_automation_task_gas, -}; pub(crate) use unwrap_or_discard; pub(crate) struct SerializedSigners { @@ -2128,6 +2123,7 @@ impl AptosVM { executable, log_context, change_set_configs, + is_approved_gov_script ) }; drop(payload_timer); @@ -2475,7 +2471,7 @@ impl AptosVM { Ok((VMStatus::Executed, output)) } - fn mark_unbiasable(&self, session: &mut SessionExt<'_, '_>) { + fn mark_unbiasable(&self, session: &mut SessionExt<'_, impl AptosMoveResolver>) { // During the first epoch in which the feature is activated, threshold keys have not yet // been established (they are produced at the end of that epoch via DKG), so the randomness // seed can be biased to some degree (although with great difficulty) by Byzantine proposers. @@ -2487,8 +2483,6 @@ impl AptosVM { // reconfiguration_with_dkg::try_start relying on access to randomness, if self.features().is_enabled(FeatureFlag::SUPRA_DKG) { session - .get_native_extensions() - .get_mut::() .mark_unbiasable(); } } diff --git a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs index 804d427307b..e49a157afc2 100644 --- a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs +++ b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs @@ -17,7 +17,7 @@ use aptos_vm_logging::log_schema::AdapterLogSchema; use aptos_vm_types::module_and_script_storage::AsAptosCodeStorage; use aptos_vm_types::resolver::NoopBlockSynchronizationKillSwitch; use move_vm_runtime::module_traversal::{TraversalContext, TraversalStorage}; -use crate::move_vm_ext::SessionId::Void; +use aptos_vm_environment::environment::AptosEnvironment; /// Move VM with only view function API. /// Convenient to use when more than one view function needs to be executed on the same state-view, diff --git a/aptos-move/aptos-vm/src/transaction_metadata.rs b/aptos-move/aptos-vm/src/transaction_metadata.rs index 504c4cae219..4ed15cb1e99 100644 --- a/aptos-move/aptos-vm/src/transaction_metadata.rs +++ b/aptos-move/aptos-vm/src/transaction_metadata.rs @@ -10,10 +10,13 @@ use aptos_types::{ chain_id::ChainId, transaction::{ automated_transaction::AutomatedTransaction, - authenticator::AuthenticationProof, user_transaction_context::UserTransactionContext, - EntryFunction, Multisig, MultisigTransactionPayload, ReplayProtector, SignedTransaction, - TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig, - TransactionPayload, TransactionPayloadInner, + authenticator::AuthenticationProof, + user_transaction_context::{ + UserTransactionContext, PayloadTypeReference, PayloadTypeReferenceContext + }, + EntryFunction, Multisig, MultisigTransactionPayload, ReplayProtector, SignedTransaction, + TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig, TransactionPayload, + TransactionPayloadInner, }, }; diff --git a/aptos-move/aptos-vm/src/transaction_validation.rs b/aptos-move/aptos-vm/src/transaction_validation.rs index d23ba0af8f3..3487703c3cc 100644 --- a/aptos-move/aptos-vm/src/transaction_validation.rs +++ b/aptos-move/aptos-vm/src/transaction_validation.rs @@ -38,9 +38,7 @@ use move_vm_runtime::{ }; use move_vm_types::gas::UnmeteredGasMeter; use once_cell::sync::Lazy; -use aptos_types::transaction::automation::AutomationTaskType; use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage; -use crate::system_module_names::EMIT_GAS_ASSESSMENT; pub static APTOS_TRANSACTION_VALIDATION: Lazy = Lazy::new(|| TransactionValidation { diff --git a/aptos-move/aptos-vm/src/validator_txns/dkg.rs b/aptos-move/aptos-vm/src/validator_txns/dkg.rs index 523d5dbdfbe..1b4d2b3e19c 100644 --- a/aptos-move/aptos-vm/src/validator_txns/dkg.rs +++ b/aptos-move/aptos-vm/src/validator_txns/dkg.rs @@ -6,6 +6,9 @@ use crate::{ errors::expect_only_successful_execution, move_vm_ext::{AptosMoveResolver, SessionId}, system_module_names::{FINISH_WITH_DKG_RESULT, RECONFIGURATION_WITH_DKG_MODULE, SET_DKG_META}, + validator_txns::dkg::{ + ExecutionFailure::{Expected, Unexpected}, + }, AptosVM, VMValidator, }; use aptos_types::{ @@ -41,12 +44,12 @@ impl AptosVM { session_id: SessionId, dkg_transaction_data: DKGTransactionData, ) -> Result<(VMStatus, VMOutput), VMStatus> { - match self.process_dkg_result_inner( + match self.process_dkg_transaction_inner( resolver, module_storage, log_context, session_id, - dkg_transcript, + dkg_transaction_data, ) { Ok((vm_status, vm_output)) => Ok((vm_status, vm_output)), Err(ExecutionFailure::Expected(status)) => { diff --git a/aptos-move/e2e-move-tests/src/harness.rs b/aptos-move/e2e-move-tests/src/harness.rs index 2d25e03b607..3b79a435a4d 100644 --- a/aptos-move/e2e-move-tests/src/harness.rs +++ b/aptos-move/e2e-move-tests/src/harness.rs @@ -252,6 +252,7 @@ impl MoveHarness { /// Runs a signed transaction. On success, applies the write set. pub fn run_raw(&mut self, txn: SignedTransaction) -> TransactionOutput { let output = self.executor.execute_transaction(txn); + println!("{:?}", output); if matches!(output.status(), TransactionStatus::Keep(_)) { self.executor.apply_write_set(output.write_set()); self.executor.append_events(output.events().to_vec()); diff --git a/aptos-move/e2e-move-tests/src/lib.rs b/aptos-move/e2e-move-tests/src/lib.rs index 875dcf5c764..6037d857471 100644 --- a/aptos-move/e2e-move-tests/src/lib.rs +++ b/aptos-move/e2e-move-tests/src/lib.rs @@ -7,7 +7,7 @@ pub mod harness; pub mod resource_groups; pub mod stake; pub mod supra_governance; -pub mod transaction_fee; +// pub mod transaction_fee; use anyhow::bail; use aptos_framework::UPGRADE_POLICY_CUSTOM_FIELD; diff --git a/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs b/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs index da5315eba5e..1490e5ff513 100644 --- a/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs +++ b/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs @@ -7,17 +7,13 @@ use aptos_language_e2e_tests::{ account::Account, executor::{ExecutorMode, FakeExecutor}, }; -use aptos_cached_packages::aptos_stdlib; -use aptos_language_e2e_tests::account::{Account, TransactionBuilder}; use aptos_types::{ - account_address::{self, AccountAddress}, - account_config::AccountResource, + account_address::{self, AccountAddress}, on_chain_config::FeatureFlag, }; use move_core_types::{ identifier::Identifier, language_storage::{StructTag, TypeTag}, - move_resource::MoveStructType, }; use once_cell::sync::Lazy; use serde::Deserialize; diff --git a/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs b/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs index ffa5d70f50e..27ef2f6049d 100644 --- a/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs +++ b/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs @@ -493,7 +493,7 @@ fn run_jwk_and_config_script(h: &mut MoveHarness) -> Account { TransactionArgument::U64(config.max_exp_horizon_secs), ])) .sequence_number(h.sequence_number(core_resources.address())) - .max_gas_amount(1_000_000) + .max_gas_amount(1_500_000) .gas_unit_price(1) .sign(); @@ -604,7 +604,7 @@ fn run_upgrade_vk_script(h: &mut MoveHarness, core_resources: Account, vk: Groth TransactionArgument::U8Vector(vk.gamma_abc_g1[1].clone()), ])) .sequence_number(h.sequence_number(core_resources.address())) - .max_gas_amount(1_000_000) + .max_gas_amount(2_500_000) .gas_unit_price(1) .sign(); diff --git a/aptos-move/e2e-testsuite/src/lib.rs b/aptos-move/e2e-testsuite/src/lib.rs index 846eaede9b1..8b78ef3e9ed 100644 --- a/aptos-move/e2e-testsuite/src/lib.rs +++ b/aptos-move/e2e-testsuite/src/lib.rs @@ -1,5 +1,11 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 +// The proptest `Arbitrary` strategy for the generated `EntryFunctionCall` enum (see +// `transaction_fuzzer`) builds a `TupleUnionValueTree` whose layout computation recurses once +// per enum variant. After the framework upgrade added more entry functions, the default limit +// of 128 is exceeded ("queries overflow the depth limit!"), so raise it for this crate. +#![recursion_limit = "256"] + #[cfg(test)] mod tests; diff --git a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs index 8a02fba67ba..e49ad225b2f 100644 --- a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs +++ b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs @@ -10,10 +10,7 @@ use aptos_language_e2e_tests::{ account::{Account, AccountData}, executor::FakeExecutor, }; -use aptos_types::account_address::create_multisig_account_address; use aptos_types::state_store::StateView; -use aptos_types::transaction::automation::Priority; -use aptos_types::transaction::{ExecutionError, Multisig, MultisigTransactionPayload}; use aptos_types::{ account_address::create_multisig_account_address, contract_event::ContractEvent, @@ -132,7 +129,10 @@ impl AutomationRegistrationTestContext { let account_create_txn = multisig_owner1 .account() .transaction() - .max_gas_amount(1_000_000) + // The SUP#3 gas-schedule update raised storage fees ~1000x, so creating the + // multisig account (and its new state slots) now costs ~1.7M gas units at this + // gas unit price. Budget enough headroom for it. + .max_gas_amount(2_000_000) .gas_unit_price(100) .payload(create_multisig_payload) .sequence_number(0) @@ -236,6 +236,7 @@ impl AutomationRegistrationTestContext { .payload(automation_txn) .sequence_number(seq_num) .gas_unit_price(1) + .max_gas_amount(55000000) .sign() } @@ -264,6 +265,7 @@ impl AutomationRegistrationTestContext { .transaction() .payload(automation_txn) .sequence_number(seq_num) + .max_gas_amount(55000000) .gas_unit_price(1) .sign() } @@ -306,6 +308,7 @@ impl AutomationRegistrationTestContext { )) .sequence_number(seq_num) .gas_unit_price(1) + .max_gas_amount(55000000) .sign() } diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md index e14bb085abc..d8369a93243 100644 --- a/aptos-move/framework/move-stdlib/doc/features.md +++ b/aptos-move/framework/move-stdlib/doc/features.md @@ -397,7 +397,7 @@ Lifetime: transient Whether to calculate the transaction fee for distribution. -
const CALCULATE_TRANSACTION_FEE_FOR_DISTRIBUTION: u64 = 105;
+
const CALCULATE_TRANSACTION_FEE_FOR_DISTRIBUTION: u64 = 107;
 
@@ -509,7 +509,7 @@ Lifetime: transient Lifetime: transient -
const DEFAULT_ACCOUNT_RESOURCE: u64 = 100;
+
const DEFAULT_ACCOUNT_RESOURCE: u64 = 104;
 
@@ -565,7 +565,7 @@ Whether the account abstraction is enabled. Lifetime: transient -
const DERIVABLE_ACCOUNT_ABSTRACTION: u64 = 97;
+
const DERIVABLE_ACCOUNT_ABSTRACTION: u64 = 101;
 
@@ -587,7 +587,7 @@ Lifetime: transient Whether to distribute transaction fee to validators. -
const DISTRIBUTE_TRANSACTION_FEE: u64 = 106;
+
const DISTRIBUTE_TRANSACTION_FEE: u64 = 108;
 
@@ -649,7 +649,7 @@ Lifetime: transient We do not expect use from Move, so for now only for documentation purposes here -
const ENABLE_FUNCTION_VALUES: u64 = 98;
+
const ENABLE_FUNCTION_VALUES: u64 = 102;
 
@@ -695,7 +695,7 @@ For simplicity, it is represented by type ProviderJWKs (used to rep in JWK Consensus messages, in validator transactions, and in Move. -
const JWK_CONSENSUS_PER_KEY_MODE: u64 = 101;
+
const JWK_CONSENSUS_PER_KEY_MODE: u64 = 105;
 
@@ -828,7 +828,7 @@ Whether new accounts default to the Fungible Asset store. Lifetime: transient -
const NEW_ACCOUNTS_DEFAULT_TO_FA_STORE: u64 = 99;
+
const NEW_ACCOUNTS_DEFAULT_TO_FA_STORE: u64 = 103;
 
@@ -890,7 +890,7 @@ Whether orderless transactions are enabled. Lifetime: transient -
const ORDERLESS_TRANSACTIONS: u64 = 103;
+
const ORDERLESS_TRANSACTIONS: u64 = 106;
 
diff --git a/aptos-move/framework/supra-framework/doc/aggregator_v2.md b/aptos-move/framework/supra-framework/doc/aggregator_v2.md index de7cb1e7cc7..9876000bc0b 100644 --- a/aptos-move/framework/supra-framework/doc/aggregator_v2.md +++ b/aptos-move/framework/supra-framework/doc/aggregator_v2.md @@ -713,7 +713,7 @@ Useful for when object is sometimes created via string_concat(), and sometimes d Concatenates before, snapshot and after into a single string. snapshot passed needs to have integer type - currently supported types are u64 and u128. Raises EUNSUPPORTED_AGGREGATOR_SNAPSHOT_TYPE if called with another type. -If length of prefix and suffix together exceeds 1024 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised. +If length of prefix and suffix together exceed 1024 bytes, ECONCAT_STRING_LENGTH_TOO_LARGE is raised. Parallelism info: This operation enables parallelism. diff --git a/aptos-move/framework/supra-framework/doc/block.md b/aptos-move/framework/supra-framework/doc/block.md index 03fcf45f5cd..5a66c681285 100644 --- a/aptos-move/framework/supra-framework/doc/block.md +++ b/aptos-move/framework/supra-framework/doc/block.md @@ -521,13 +521,11 @@ Can only be called as part of the Supra governance proposal process established block_resource.epoch_interval = new_epoch_interval; if (std::features::module_event_migration_enabled()) { - event::emit( - UpdateEpochInterval { old_epoch_interval, new_epoch_interval }, - ); + event::emit(UpdateEpochInterval { old_epoch_interval, new_epoch_interval }); } else { event::emit_event<UpdateEpochIntervalEvent>( &mut block_resource.update_epoch_interval_events, - UpdateEpochIntervalEvent { old_epoch_interval, new_epoch_interval }, + UpdateEpochIntervalEvent { old_epoch_interval, new_epoch_interval } ); }; } diff --git a/aptos-move/framework/supra-framework/doc/dkg_config.md b/aptos-move/framework/supra-framework/doc/dkg_config.md index e259fd00e0f..3fea15a4d6b 100644 --- a/aptos-move/framework/supra-framework/doc/dkg_config.md +++ b/aptos-move/framework/supra-framework/doc/dkg_config.md @@ -282,7 +282,7 @@ Called from reconfiguration_with_dkg::finish().
public(friend) fun on_new_epoch(framework: &signer) acquires DkgConfig {
     system_addresses::assert_supra_framework(framework);
     if (config_buffer::does_exist<DkgConfig>()) {
-        let new_config = config_buffer::extract<DkgConfig>();
+        let new_config = config_buffer::extract_v2<DkgConfig>();
         if (exists<DkgConfig>(@supra_framework)) {
             *borrow_global_mut<DkgConfig>(@supra_framework) = new_config;
         } else {
diff --git a/aptos-move/framework/supra-framework/doc/fungible_asset.md b/aptos-move/framework/supra-framework/doc/fungible_asset.md
index e7afd03aa3d..5342c37e7d5 100644
--- a/aptos-move/framework/supra-framework/doc/fungible_asset.md
+++ b/aptos-move/framework/supra-framework/doc/fungible_asset.md
@@ -3710,30 +3710,34 @@ Mutate specified fields of the fungible asset's object::object_address(&metadata_ref.metadata);
     let mutable_metadata = borrow_global_mut<Metadata>(metadata_address);
 
-    if (option::is_some(&name)){
-        let name = option::extract(&mut name);
-        assert!(string::length(&name) <= MAX_NAME_LENGTH, error::out_of_range(ENAME_TOO_LONG));
-        mutable_metadata.name = name;
+    if (option::is_some(&name)) {
+        let new_name = option::destroy_some(name);
+        assert!(string::length(&new_name) <= MAX_NAME_LENGTH, error::out_of_range(ENAME_TOO_LONG));
+        mutable_metadata.name = new_name;
     };
-    if (option::is_some(&symbol)){
-        let symbol = option::extract(&mut symbol);
-        assert!(string::length(&symbol) <= MAX_SYMBOL_LENGTH, error::out_of_range(ESYMBOL_TOO_LONG));
-        mutable_metadata.symbol = symbol;
+
+    if (option::is_some(&symbol)) {
+        let new_symbol = option::destroy_some(symbol);
+        assert!(string::length(&new_symbol) <= MAX_SYMBOL_LENGTH, error::out_of_range(ESYMBOL_TOO_LONG));
+        mutable_metadata.symbol = new_symbol;
     };
-    if (option::is_some(&decimals)){
-        let decimals = option::extract(&mut decimals);
-        assert!(decimals <= MAX_DECIMALS, error::out_of_range(EDECIMALS_TOO_LARGE));
-        mutable_metadata.decimals = decimals;
+
+    if (option::is_some(&decimals)) {
+        let new_decimals = option::destroy_some(decimals);
+        assert!(new_decimals <= MAX_DECIMALS, error::out_of_range(EDECIMALS_TOO_LARGE));
+        mutable_metadata.decimals = new_decimals;
     };
-    if (option::is_some(&icon_uri)){
-        let icon_uri = option::extract(&mut icon_uri);
-        assert!(string::length(&icon_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
-        mutable_metadata.icon_uri = icon_uri;
+
+    if (option::is_some(&icon_uri)) {
+        let new_icon_uri = option::destroy_some(icon_uri);
+        assert!(string::length(&new_icon_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
+        mutable_metadata.icon_uri = new_icon_uri;
     };
-    if (option::is_some(&project_uri)){
-        let project_uri = option::extract(&mut project_uri);
-        assert!(string::length(&project_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
-        mutable_metadata.project_uri = project_uri;
+
+    if (option::is_some(&project_uri)) {
+        let new_project_uri = option::destroy_some(project_uri);
+        assert!(string::length(&new_project_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
+        mutable_metadata.project_uri = new_project_uri;
     };
 }
 
diff --git a/aptos-move/framework/supra-framework/doc/genesis.md b/aptos-move/framework/supra-framework/doc/genesis.md index 80aed1bfdff..0398d368056 100644 --- a/aptos-move/framework/supra-framework/doc/genesis.md +++ b/aptos-move/framework/supra-framework/doc/genesis.md @@ -68,7 +68,6 @@ use 0x1::leader_ban_registry; use 0x1::leader_ban_registry_config; use 0x1::multisig_account; -use 0x1::nonce_validation; use 0x1::option; use 0x1::pbo_delegation_pool; use 0x1::reconfiguration; @@ -646,9 +645,6 @@ Genesis step 1: Initialize supra framework account and core modules on chain. reconfiguration::initialize(&supra_framework_account); block::initialize(&supra_framework_account, epoch_interval_microsecs); state_storage::initialize(&supra_framework_account); - timestamp::set_time_has_started( - &supra_framework_account, genesis_timestamp_in_microseconds - ); }
@@ -938,9 +934,7 @@ If it exists, it just returns the signer. Implementation -
fun create_account(
-    supra_framework: &signer, account_address: address, balance: u64
-): signer {
+
fun create_account(supra_framework: &signer, account_address: address, balance: u64): signer {
     let account = if (account::exists_at(account_address)) {
         create_signer(account_address)
     } else {
@@ -1698,93 +1692,6 @@ The last step of genesis.
 
 
 
-
-
-
-
-## Function `initialize_for_verification`
-
-
-
-
#[verify_only]
-fun initialize_for_verification(gas_schedule: vector<u8>, chain_id: u8, initial_version: u64, consensus_config: vector<u8>, execution_config: vector<u8>, supra_config: vector<u8>, evm_genesis_config: vector<u8>, epoch_interval_microsecs: u64, minimum_stake: u64, maximum_stake: u64, recurring_lockup_duration_secs: u64, allow_validator_set_change: bool, rewards_rate: u64, rewards_rate_denominator: u64, voting_power_increase_limit: u64, supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>, accounts: vector<genesis::AccountMap>, employee_vesting_start: u64, employee_vesting_period_duration: u64, employees: vector<genesis::EmployeeAccountMap>, validators: vector<genesis::ValidatorConfigurationWithCommission>)
-
- - - -
-Implementation - - -
fun initialize_for_verification(
-    gas_schedule: vector<u8>,
-    chain_id: u8,
-    initial_version: u64,
-    consensus_config: vector<u8>,
-    execution_config: vector<u8>,
-    supra_config: vector<u8>,
-    evm_genesis_config: vector<u8>,
-    epoch_interval_microsecs: u64,
-    minimum_stake: u64,
-    maximum_stake: u64,
-    recurring_lockup_duration_secs: u64,
-    allow_validator_set_change: bool,
-    rewards_rate: u64,
-    rewards_rate_denominator: u64,
-    voting_power_increase_limit: u64,
-    supra_framework: &signer,
-    // min_voting_threshold: u128,
-    // required_proposer_stake: u64,
-    voting_duration_secs: u64,
-    supra_min_voting_threshold: u64,
-    voters: vector<address>,
-    accounts: vector<AccountMap>,
-    employee_vesting_start: u64,
-    employee_vesting_period_duration: u64,
-    employees: vector<EmployeeAccountMap>,
-    validators: vector<ValidatorConfigurationWithCommission>
-) {
-    initialize(
-        gas_schedule,
-        chain_id,
-        initial_version,
-        consensus_config,
-        execution_config,
-        supra_config,
-        epoch_interval_microsecs,
-        minimum_stake,
-        maximum_stake,
-        recurring_lockup_duration_secs,
-        allow_validator_set_change,
-        rewards_rate,
-        rewards_rate_denominator,
-        voting_power_increase_limit,
-        0
-
-    );
-    features::change_feature_flags_for_verification(
-        supra_framework, vector[1, 2, 11], vector[]
-    );
-    initialize_supra_coin(supra_framework);
-    supra_governance::initialize_for_verification(
-        supra_framework,
-        // min_voting_threshold,
-        // required_proposer_stake,
-        voting_duration_secs,
-        supra_min_voting_threshold,
-        voters
-    );
-    create_accounts(supra_framework, accounts);
-    create_employee_validators(
-        employee_vesting_start, employee_vesting_period_duration, employees
-    );
-    create_initialize_validators_with_commission(supra_framework, true, validators);
-    set_genesis_end(supra_framework);
-}
-
- - -
diff --git a/aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md b/aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md index ec26a067e25..ece30fbf5e8 100644 --- a/aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md +++ b/aptos-move/framework/supra-framework/doc/leader_ban_registry_config.md @@ -263,7 +263,7 @@ Only used in reconfigurations to apply the pending BanRegistryParameters, BanRegistryParametersV0 { system_addresses::assert_supra_framework(framework); if (config_buffer::does_exist<BanRegistryParameters>()) { - let new_config = config_buffer::extract<BanRegistryParameters>(); + let new_config = config_buffer::extract_v2<BanRegistryParameters>(); if (exists<BanRegistryParameters>(@supra_framework)) { *borrow_global_mut<BanRegistryParameters>(@supra_framework) = new_config; } else { diff --git a/aptos-move/framework/supra-framework/doc/randomness.md b/aptos-move/framework/supra-framework/doc/randomness.md index acc412bf781..7cf189e90c5 100644 --- a/aptos-move/framework/supra-framework/doc/randomness.md +++ b/aptos-move/framework/supra-framework/doc/randomness.md @@ -929,7 +929,9 @@ Compute (a + b) % m, assuming m >= 1, 0 <= a < m, 0& Implementation -
fun take_first(x: u256, _y: u256 ): u256 { x }
+
fun take_first(x: u256, _y: u256): u256 {
+    x
+}
 
diff --git a/aptos-move/framework/supra-framework/doc/stake.md b/aptos-move/framework/supra-framework/doc/stake.md index 0fb11bd7d59..3dde8b03f00 100644 --- a/aptos-move/framework/supra-framework/doc/stake.md +++ b/aptos-move/framework/supra-framework/doc/stake.md @@ -92,6 +92,10 @@ or if their stake drops below the min required, they would get removed at the en - [Function `initialize_stake_owner`](#0x1_stake_initialize_stake_owner) - [Function `initialize_validator`](#0x1_stake_initialize_validator) - [Function `validate_consensus_public_key`](#0x1_stake_validate_consensus_public_key) +- [Function `assert_consensus_pubkey_unique_in_next_validator_set`](#0x1_stake_assert_consensus_pubkey_unique_in_next_validator_set) +- [Function `assert_consensus_pubkey_unique_in_validator_list`](#0x1_stake_assert_consensus_pubkey_unique_in_validator_list) +- [Function `assert_network_addresses_unique_in_next_validator_set`](#0x1_stake_assert_network_addresses_unique_in_next_validator_set) +- [Function `assert_network_addresses_unique_in_validator_list`](#0x1_stake_assert_network_addresses_unique_in_validator_list) - [Function `initialize_owner`](#0x1_stake_initialize_owner) - [Function `extract_owner_cap`](#0x1_stake_extract_owner_cap) - [Function `deposit_owner_cap`](#0x1_stake_deposit_owner_cap) @@ -126,7 +130,6 @@ or if their stake drops below the min required, they would get removed at the en - [Function `next_epoch_validator_consensus_infos_for_dkg`](#0x1_stake_next_epoch_validator_consensus_infos_for_dkg) - [Function `compute_next_validator_set_internal`](#0x1_stake_compute_next_validator_set_internal) - [Function `calculate_candidate_reward`](#0x1_stake_calculate_candidate_reward) -- [Function `collect_candidate_fee`](#0x1_stake_collect_candidate_fee) - [Function `validator_consensus_infos_from_validator_set`](#0x1_stake_validator_consensus_infos_from_validator_set) - [Function `addresses_from_validator_infos`](#0x1_stake_addresses_from_validator_infos) - [Function `update_stake_pool`](#0x1_stake_update_stake_pool) @@ -186,9 +189,9 @@ or if their stake drops below the min required, they would get removed at the en
use 0x1::account;
-use 0x1::bls12381;
 use 0x1::aggregator_v2;
 use 0x1::big_ordered_map;
+use 0x1::bls12381;
 use 0x1::chain_status;
 use 0x1::coin;
 use 0x1::dkg_committee;
@@ -1777,6 +1780,26 @@ Invalid DKG public key shares.
 
 
 
+
+
+Another validator in the next validator set already uses this consensus public key.
+
+
+
const EDUPLICATE_CONSENSUS_PUBKEY: u64 = 22;
+
+ + + + + +Another validator in the next validator set already uses these network addresses. + + +
const EDUPLICATE_NETWORK_ADDRESSES: u64 = 23;
+
+ + + Table to store collected transaction fees for each validator already exists. @@ -1862,7 +1885,7 @@ Validators cannot join or leave post genesis on this test network. Signer does not have permission to perform stake logic. -
const ENO_STAKE_PERMISSION: u64 = 28;
+
const ENO_STAKE_PERMISSION: u64 = 24;
 
@@ -1942,7 +1965,7 @@ Not enough stake to join validator set. Transaction fee is not fully distributed at epoch ending. -
const ETRANSACTION_FEE_NOT_FULLY_DISTRIBUTED: u64 = 29;
+
const ETRANSACTION_FEE_NOT_FULLY_DISTRIBUTED: u64 = 25;
 
@@ -2041,9 +2064,7 @@ Permissions Implementation -
inline fun check_stake_permission(
-    s: &signer
-) {
+
inline fun check_stake_permission(s: &signer) {
     assert!(
         permissioned_signer::check_permission_exists(s, StakeManagementPermission {}),
         error::permission_denied(ENO_STAKE_PERMISSION),
@@ -2071,17 +2092,8 @@ Grant permission to mutate staking on behalf of the master signer.
 Implementation
 
 
-
public(friend) fun add_transaction_fee(
-    validator_addr: address, fee: Coin<SupraCoin>
-) acquires ValidatorFees {
-    let fees_table =
-        &mut borrow_global_mut<ValidatorFees>(@supra_framework).fees_table;
-    if (table::contains(fees_table, validator_addr)) {
-        let collected_fee = table::borrow_mut(fees_table, validator_addr);
-        coin::merge(collected_fee, fee);
-    } else {
-        table::add(fees_table, validator_addr, fee);
-    }
+
public fun grant_permission(master: &signer, permissioned_signer: &signer) {
+    permissioned_signer::authorize_unlimited(master, permissioned_signer, StakeManagementPermission {})
 }
 
@@ -2909,8 +2921,16 @@ Initialize the validator account and give ownership to the signing account. consensus_pubkey: vector<u8>, network_addresses: vector<u8>, fullnode_addresses: vector<u8> -) acquires AllowedValidators { +) acquires AllowedValidators, ValidatorSet, ValidatorConfig { + check_stake_permission(account); validate_consensus_public_key(consensus_pubkey); + let account_addr = signer::address_of(account); + assert_consensus_pubkey_unique_in_next_validator_set( + account_addr, &consensus_pubkey + ); + assert_network_addresses_unique_in_next_validator_set( + account_addr, &network_addresses + ); initialize_owner(account); move_to( account, @@ -2969,6 +2989,159 @@ Initialize the validator account and give ownership to the signing account. + + + + +## Function `assert_consensus_pubkey_unique_in_next_validator_set` + +Aborts if any validator other than self_addr in the next validator set +(the union of active_validators and pending_active) already uses +consensus_pubkey as its latest on-chain consensus key. + + +
fun assert_consensus_pubkey_unique_in_next_validator_set(self_addr: address, consensus_pubkey: &vector<u8>)
+
+ + + +
+Implementation + + +
fun assert_consensus_pubkey_unique_in_next_validator_set(
+    self_addr: address,
+    consensus_pubkey: &vector<u8>
+) acquires ValidatorSet, ValidatorConfig {
+    let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+    assert_consensus_pubkey_unique_in_validator_list(
+        self_addr, consensus_pubkey, &validator_set.active_validators
+    );
+    assert_consensus_pubkey_unique_in_validator_list(
+        self_addr, consensus_pubkey, &validator_set.pending_active
+    );
+}
+
+ + + +
+ + + +## Function `assert_consensus_pubkey_unique_in_validator_list` + + + +
fun assert_consensus_pubkey_unique_in_validator_list(self_addr: address, consensus_pubkey: &vector<u8>, validators: &vector<stake::ValidatorInfo>)
+
+ + + +
+Implementation + + +
fun assert_consensus_pubkey_unique_in_validator_list(
+    self_addr: address,
+    consensus_pubkey: &vector<u8>,
+    validators: &vector<ValidatorInfo>
+) acquires ValidatorConfig {
+    let len = vector::length(validators);
+    let i = 0;
+    while (i < len) {
+        let other = vector::borrow(validators, i);
+        if (other.addr != self_addr && exists<ValidatorConfig>(other.addr)) {
+            let other_config = borrow_global<ValidatorConfig>(other.addr);
+            assert!(
+                other_config.consensus_pubkey != *consensus_pubkey,
+                error::invalid_argument(EDUPLICATE_CONSENSUS_PUBKEY)
+            );
+        };
+        i = i + 1;
+    };
+}
+
+ + + +
+ + + +## Function `assert_network_addresses_unique_in_next_validator_set` + +Aborts if any validator other than self_addr in the next validator set +already uses network_addresses. Empty network_addresses is treated +as "unset" and skips the check. + + +
fun assert_network_addresses_unique_in_next_validator_set(self_addr: address, network_addresses: &vector<u8>)
+
+ + + +
+Implementation + + +
fun assert_network_addresses_unique_in_next_validator_set(
+    self_addr: address,
+    network_addresses: &vector<u8>
+) acquires ValidatorSet, ValidatorConfig {
+    if (vector::is_empty(network_addresses)) { return };
+    let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+    assert_network_addresses_unique_in_validator_list(
+        self_addr, network_addresses, &validator_set.active_validators
+    );
+    assert_network_addresses_unique_in_validator_list(
+        self_addr, network_addresses, &validator_set.pending_active
+    );
+}
+
+ + + +
+ + + +## Function `assert_network_addresses_unique_in_validator_list` + + + +
fun assert_network_addresses_unique_in_validator_list(self_addr: address, network_addresses: &vector<u8>, validators: &vector<stake::ValidatorInfo>)
+
+ + + +
+Implementation + + +
fun assert_network_addresses_unique_in_validator_list(
+    self_addr: address,
+    network_addresses: &vector<u8>,
+    validators: &vector<ValidatorInfo>
+) acquires ValidatorConfig {
+    let len = vector::length(validators);
+    let i = 0;
+    while (i < len) {
+        let other = vector::borrow(validators, i);
+        if (other.addr != self_addr && exists<ValidatorConfig>(other.addr)) {
+            let other_config = borrow_global<ValidatorConfig>(other.addr);
+            assert!(
+                other_config.network_addresses != *network_addresses,
+                error::invalid_argument(EDUPLICATE_NETWORK_ADDRESSES)
+            );
+        };
+        i = i + 1;
+    };
+}
+
+ + +
@@ -3089,6 +3262,7 @@ staking pool.
public fun deposit_owner_cap(
     owner: &signer, owner_cap: OwnerCapability
 ) {
+    check_stake_permission(owner);
     assert!(
         !exists<OwnerCapability>(signer::address_of(owner)),
         error::not_found(EOWNER_CAP_ALREADY_EXISTS)
@@ -3145,6 +3319,7 @@ Allows an owner to change the operator of the stake pool.
 
public entry fun set_operator(
     owner: &signer, new_operator: address
 ) acquires OwnerCapability, StakePool {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -3182,13 +3357,23 @@ Allows an account with ownership capability to change the operator of the stake
     stake_pool.operator_address = new_operator;
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(SetOperator { pool_address, old_operator, new_operator });
+        event::emit(
+            SetOperator {
+                pool_address,
+                old_operator,
+                new_operator,
+            },
+        );
+    } else {
+        event::emit_event(
+            &mut stake_pool.set_operator_events,
+            SetOperatorEvent {
+                pool_address,
+                old_operator,
+                new_operator,
+            },
+        );
     };
-
-    event::emit_event(
-        &mut stake_pool.set_operator_events,
-        SetOperatorEvent { pool_address, old_operator, new_operator }
-    );
 }
 
@@ -3215,6 +3400,7 @@ Allows an owner to change the delegated voter of the stake pool.
public entry fun set_delegated_voter(
     owner: &signer, new_voter: address
 ) acquires OwnerCapability, StakePool {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -3275,6 +3461,7 @@ Add amount of coins from the public entry fun add_stake(
     owner: &signer, amount: u64
 ) acquires OwnerCapability, StakePool, ValidatorSet {
+    check_stake_permission(owner);
     let owner_address = signer::address_of(owner);
     assert_owner_cap_exists(owner_address);
     let ownership_cap = borrow_global<OwnerCapability>(owner_address);
@@ -3345,12 +3532,21 @@ Add coins into pool_address. this requires the corresp
     );
 
     if (std::features::module_event_migration_enabled()) {
-        event::emit(AddStake { pool_address, amount_added: amount });
+        event::emit(
+            AddStake {
+                pool_address,
+                amount_added: amount,
+            },
+        );
+    } else {
+        event::emit_event(
+            &mut stake_pool.add_stake_events,
+            AddStakeEvent {
+                pool_address,
+                amount_added: amount,
+            },
+        );
     };
-    event::emit_event(
-        &mut stake_pool.add_stake_events,
-        AddStakeEvent { pool_address, amount_added: amount }
-    );
 }
 
@@ -3422,12 +3618,21 @@ Move amount of coins from pending_inactive to active. coin::merge(&mut stake_pool.active, reactivated_coins); if (std::features::module_event_migration_enabled()) { - event::emit(ReactivateStake { pool_address, amount }); + event::emit( + ReactivateStake { + pool_address, + amount, + }, + ); + } else { + event::emit_event( + &mut stake_pool.reactivate_stake_events, + ReactivateStakeEvent { + pool_address, + amount, + }, + ); }; - event::emit_event( - &mut stake_pool.reactivate_stake_events, - ReactivateStakeEvent { pool_address, amount } - ); }
@@ -3455,7 +3660,7 @@ Move amount of coins from pending_inactive to active. pool_address: address, new_consensus_pubkey: vector<u8>, genesis: bool -) acquires StakePool, ValidatorConfig { +) acquires StakePool, ValidatorConfig, ValidatorSet { check_stake_permission(operator); assert_reconfig_not_in_progress(); assert_stake_pool_exists(pool_address); @@ -3470,10 +3675,12 @@ Move amount of coins from pending_inactive to active. exists<ValidatorConfig>(pool_address), error::not_found(EVALIDATOR_CONFIG) ); + validate_consensus_public_key(new_consensus_pubkey); + assert_consensus_pubkey_unique_in_next_validator_set( + pool_address, &new_consensus_pubkey + ); let validator_info = borrow_global_mut<ValidatorConfig>(pool_address); let old_consensus_pubkey = validator_info.consensus_pubkey; - - validate_consensus_public_key(new_consensus_pubkey); validator_info.consensus_pubkey = new_consensus_pubkey; if (std::features::module_event_migration_enabled()) { @@ -3484,15 +3691,16 @@ Move amount of coins from pending_inactive to active. new_consensus_pubkey } ); - }; - event::emit_event( - &mut stake_pool.rotate_consensus_key_events, - RotateConsensusKeyEvent { - pool_address, - old_consensus_pubkey, - new_consensus_pubkey - } - ); + } else { + event::emit_event( + &mut stake_pool.rotate_consensus_key_events, + RotateConsensusKeyEvent { + pool_address, + old_consensus_pubkey, + new_consensus_pubkey + } + ); + } }
@@ -3519,7 +3727,7 @@ Each DkgCommitteeOutput contains a threshold_type and corresponding keys for all
public(friend) fun set_dkg_output_keys(
     committee_outputs: vector<dkg_committee::DkgCommitteeOutput>
-) acquires ValidatorConfig, ValidatorFees, ValidatorPerformance, ValidatorSet, StakePool {
+) acquires ValidatorConfig, ValidatorPerformance, ValidatorSet, StakePool {
     if (vector::is_empty(&committee_outputs)) { return };
 
     let next_validator_infos = next_validator_consensus_infos();
@@ -3593,15 +3801,16 @@ Each DkgCommitteeOutput contains a threshold_type and corresponding keys for all
                     new_consensus_pubkey
                 }
             );
+        } else {
+            event::emit_event(
+                &mut stake_pool.rotate_consensus_key_events,
+                RotateConsensusKeyEvent {
+                    pool_address: addr,
+                    old_consensus_pubkey,
+                    new_consensus_pubkey
+                }
+            );
         };
-        event::emit_event(
-            &mut stake_pool.rotate_consensus_key_events,
-            RotateConsensusKeyEvent {
-                pool_address: addr,
-                old_consensus_pubkey,
-                new_consensus_pubkey
-            }
-        );
 
         i = i + 1;
     };
@@ -3632,7 +3841,7 @@ only for genesis
 
 
public(friend) fun rotate_consensus_key_genesis(
     operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>
-) acquires StakePool, ValidatorConfig {
+) acquires StakePool, ValidatorConfig, ValidatorSet {
     rotate_consensus_key_internal(
         operator,
         pool_address,
@@ -3664,7 +3873,7 @@ Rotate the consensus key of the validator, it'll take effect in next epoch.
 
 
public entry fun rotate_consensus_key(
     operator: &signer, pool_address: address, new_consensus_pubkey: vector<u8>
-) acquires StakePool, ValidatorConfig {
+) acquires StakePool, ValidatorConfig, ValidatorSet {
     rotate_consensus_key_internal(
         operator,
         pool_address,
@@ -3699,7 +3908,7 @@ Update the network and full node addresses of the validator. This only takes eff
     pool_address: address,
     new_network_addresses: vector<u8>,
     new_fullnode_addresses: vector<u8>
-) acquires StakePool, ValidatorConfig {
+) acquires StakePool, ValidatorConfig, ValidatorSet {
     check_stake_permission(operator);
     assert_reconfig_not_in_progress();
     assert_stake_pool_exists(pool_address);
@@ -3712,6 +3921,9 @@ Update the network and full node addresses of the validator. This only takes eff
         exists<ValidatorConfig>(pool_address),
         error::not_found(EVALIDATOR_CONFIG)
     );
+    assert_network_addresses_unique_in_next_validator_set(
+        pool_address, &new_network_addresses
+    );
     let validator_info = borrow_global_mut<ValidatorConfig>(pool_address);
     let old_network_addresses = validator_info.network_addresses;
     validator_info.network_addresses = new_network_addresses;
@@ -3728,18 +3940,18 @@ Update the network and full node addresses of the validator. This only takes eff
                 new_fullnode_addresses
             }
         );
+    } else {
+        event::emit_event(
+            &mut stake_pool.update_network_and_fullnode_addresses_events,
+            UpdateNetworkAndFullnodeAddressesEvent {
+                pool_address,
+                old_network_addresses,
+                new_network_addresses,
+                old_fullnode_addresses,
+                new_fullnode_addresses
+            }
+        );
     };
-    event::emit_event(
-        &mut stake_pool.update_network_and_fullnode_addresses_events,
-        UpdateNetworkAndFullnodeAddressesEvent {
-            pool_address,
-            old_network_addresses,
-            new_network_addresses,
-            old_fullnode_addresses,
-            new_fullnode_addresses
-        }
-    );
-
 }
 
@@ -3817,15 +4029,16 @@ directly inactive if it's not from an active validator. new_locked_until_secs } ); - }; - event::emit_event( - &mut stake_pool.increase_lockup_events, - IncreaseLockupEvent { - pool_address, - old_locked_until_secs, - new_locked_until_secs - } - ); + } else { + event::emit_event( + &mut stake_pool.increase_lockup_events, + IncreaseLockupEvent { + pool_address, + old_locked_until_secs, + new_locked_until_secs + } + ); + } }
@@ -3912,7 +4125,7 @@ This internal version can only be called by the Genesis module during Genesis. update_voting_power_increase(voting_power); // Add validator to pending_active, to be activated in the next epoch. - let validator_config = borrow_global_mut<ValidatorConfig>(pool_address); + let validator_config = borrow_global<ValidatorConfig>(pool_address); assert!( !vector::is_empty(&validator_config.consensus_pubkey), error::invalid_argument(EINVALID_PUBLIC_KEY) @@ -3933,11 +4146,12 @@ This internal version can only be called by the Genesis module during Genesis. if (std::features::module_event_migration_enabled()) { event::emit(JoinValidatorSet { pool_address }); - }; - event::emit_event( - &mut stake_pool.join_validator_set_events, - JoinValidatorSetEvent { pool_address } - ); + } else { + event::emit_event( + &mut stake_pool.join_validator_set_events, + JoinValidatorSetEvent { pool_address } + ); + } }
@@ -4007,12 +4221,21 @@ Unlock amount from the active stake. Only possible if the lockup ha coin::merge<SupraCoin>(&mut stake_pool.pending_inactive, unlocked_stake); if (std::features::module_event_migration_enabled()) { - event::emit(UnlockStake { pool_address, amount_unlocked: amount }); + event::emit( + UnlockStake { + pool_address, + amount_unlocked: amount, + }, + ); + } else { + event::emit_event( + &mut stake_pool.unlock_stake_events, + UnlockStakeEvent { + pool_address, + amount_unlocked: amount, + }, + ); }; - event::emit_event( - &mut stake_pool.unlock_stake_events, - UnlockStakeEvent { pool_address, amount_unlocked: amount } - ); }
@@ -4090,12 +4313,21 @@ Withdraw from pool_address's inactive stake with the corresponding if (withdraw_amount == 0) return coin::zero<SupraCoin>(); if (std::features::module_event_migration_enabled()) { - event::emit(WithdrawStake { pool_address, amount_withdrawn: withdraw_amount }); + event::emit( + WithdrawStake { + pool_address, + amount_withdrawn: withdraw_amount, + }, + ); + } else { + event::emit_event( + &mut stake_pool.withdraw_stake_events, + WithdrawStakeEvent { + pool_address, + amount_withdrawn: withdraw_amount, + }, + ); }; - event::emit_event( - &mut stake_pool.withdraw_stake_events, - WithdrawStakeEvent { pool_address, amount_withdrawn: withdraw_amount } - ); coin::extract(&mut stake_pool.inactive, withdraw_amount) } @@ -4188,11 +4420,14 @@ Can only be called by the operator of the validator/staking pool. if (std::features::module_event_migration_enabled()) { event::emit(LeaveValidatorSet { pool_address }); + } else { + event::emit_event( + &mut stake_pool.leave_validator_set_events, + LeaveValidatorSetEvent { + pool_address, + }, + ); }; - event::emit_event( - &mut stake_pool.leave_validator_set_events, - LeaveValidatorSetEvent { pool_address } - ); }; }
@@ -4339,7 +4574,7 @@ power. Implementation -
public(friend) fun on_new_epoch() acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+
public(friend) fun on_new_epoch() acquires SupraCoinCapabilities, PendingTransactionFee, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet {
     let validator_set = borrow_global_mut<ValidatorSet>(@supra_framework);
     let config = staking_config::get();
     let validator_perf = borrow_global_mut<ValidatorPerformance>(@supra_framework);
@@ -4388,8 +4623,8 @@ power.
             &mut validator_set.active_validators, i
         );
         let pool_address = old_validator_info.addr;
-        let validator_config = borrow_global_mut<ValidatorConfig>(pool_address);
-        let stake_pool = borrow_global_mut<StakePool>(pool_address);
+        let validator_config = borrow_global<ValidatorConfig>(pool_address);
+        let stake_pool = borrow_global<StakePool>(pool_address);
         let new_validator_info =
             generate_validator_info(pool_address, stake_pool, *validator_config);
 
@@ -4528,7 +4763,7 @@ Return the ValidatorConsensusInfo of each current validator, sorted
 Implementation
 
 
-
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+
public fun next_validator_consensus_infos(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig {
     let new_validator_set = compute_next_validator_set_internal(false);
     validator_consensus_infos_from_validator_set(&new_validator_set)
 }
@@ -4558,7 +4793,7 @@ their configuration do not need to run two copies of themselves to participate i
 Implementation
 
 
-
public fun next_epoch_validator_consensus_infos_for_dkg(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+
public fun next_epoch_validator_consensus_infos_for_dkg(): vector<ValidatorConsensusInfo> acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig {
     // Use the current-epoch config snapshot for active validators so mid-epoch config changes
     // do not take effect during DKG (use_current_config_for_actives=true).
     let new_validator_set = compute_next_validator_set_internal(true);
@@ -4595,7 +4830,7 @@ New joiners (pending_active) always read from compute_next_validator_set_internal(
     use_current_config_for_actives: bool
-): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig {
+): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig {
     // Init.
     let cur_validator_set = borrow_global<ValidatorSet>(@supra_framework);
     let staking_config = staking_config::get();
@@ -4641,32 +4876,29 @@ New joiners (pending_active) always read from coin::value(&stake_pool.pending_active);
         let cur_pending_inactive = coin::value(&stake_pool.pending_inactive);
 
-        let cur_reward =
-            calculate_candidate_reward(
-                candidate,
-                candidate_in_current_validator_set,
-                cur_active,
-                validator_perf,
-                rewards_rate,
-                rewards_rate_denominator
-            );
-
-        let cur_fee = collect_candidate_fee(candidate.addr);
+        let cur_reward = if (candidate_in_current_validator_set && cur_active != 0) {
+            spec {
+                assert candidate.config.validator_index < len(validator_perf.validators);
+            };
+            let cur_perf = vector::borrow(&validator_perf.validators, candidate.config.validator_index);
+            spec {
+                assume cur_perf.successful_proposals + cur_perf.failed_proposals <= MAX_U64;
+            };
+            calculate_rewards_amount(cur_active, cur_perf.successful_proposals, cur_perf.successful_proposals + cur_perf.failed_proposals, rewards_rate, rewards_rate_denominator)
+        } else {
+            0
+        };
 
-        let lockup_expired =
-            get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
+        let lockup_expired = get_reconfig_start_time_secs() >= stake_pool.locked_until_secs;
         spec {
-            assume cur_active + cur_pending_active + cur_reward + cur_fee
-                <= MAX_U64;
-            assume cur_active + cur_pending_inactive + cur_pending_active
-                + cur_reward + cur_fee <= MAX_U64;
+            assume cur_active + cur_pending_active + cur_reward <= MAX_U64;
+            assume cur_active + cur_pending_inactive + cur_pending_active + cur_reward <= MAX_U64;
         };
         let new_voting_power =
             cur_active
-                + if (lockup_expired) { 0 }
-                else {
-                    cur_pending_inactive
-                } + cur_pending_active + cur_reward + cur_fee;
+            + if (lockup_expired) { 0 } else { cur_pending_inactive }
+            + cur_pending_active
+            + cur_reward;
 
         if (new_voting_power >= minimum_stake) {
             let config =
@@ -4763,37 +4995,6 @@ with no active stake.
 
 
 
-
-
-
-
-## Function `collect_candidate_fee`
-
-Returns the accumulated gas fees assigned to candidate_addr, or 0 if fee collection
-is disabled or no fees have been recorded for this validator.
-
-
-
fun collect_candidate_fee(candidate_addr: address): u64
-
- - - -
-Implementation - - -
fun collect_candidate_fee(candidate_addr: address): u64 acquires ValidatorFees {
-    if (features::collect_and_distribute_gas_fees()) {
-        let fees_table = &borrow_global<ValidatorFees>(@supra_framework).fees_table;
-        if (table::contains(fees_table, candidate_addr)) {
-            coin::value(table::borrow(fees_table, candidate_addr))
-        } else { 0 }
-    } else { 0 }
-}
-
- - -
@@ -4969,11 +5170,12 @@ This function shouldn't abort. validator_perf: &ValidatorPerformance, pool_address: address, staking_config: &StakingConfig -) acquires StakePool, SupraCoinCapabilities, ValidatorConfig, ValidatorFees { +) acquires SupraCoinCapabilities, PendingTransactionFee, StakePool, ValidatorConfig { let stake_pool = borrow_global_mut<StakePool>(pool_address); let validator_config = borrow_global<ValidatorConfig>(pool_address); + let validator_index = validator_config.validator_index; let cur_validator_perf = vector::borrow( - &validator_perf.validators, validator_config.validator_index + &validator_perf.validators, validator_index ); let num_successful_proposals = cur_validator_perf.successful_proposals; @@ -5025,22 +5227,25 @@ This function shouldn't abort. spec { assume rewards_active + rewards_pending_inactive <= MAX_U64; }; - let rewards_amount = rewards_active + rewards_pending_inactive; - // Pending active stake can now be active. - coin::merge( - &mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active) - ); - // Additionally, distribute transaction fees. - if (features::collect_and_distribute_gas_fees()) { - let fees_table = - &mut borrow_global_mut<ValidatorFees>(@supra_framework).fees_table; - if (table::contains(fees_table, pool_address)) { - let coin = table::remove(fees_table, pool_address); - coin::merge(&mut stake_pool.active, coin); + if (std::features::is_distribute_transaction_fee_enabled()) { + let mint_cap = &borrow_global<SupraCoinCapabilities>(@supra_framework).mint_cap; + if (fee_active > 0) { + coin::merge(&mut stake_pool.active, coin::mint(fee_active, mint_cap)); + }; + if (fee_pending_inactive > 0) { + coin::merge(&mut stake_pool.pending_inactive, coin::mint(fee_pending_inactive, mint_cap)); + }; + let fee_amount = fee_active + fee_pending_inactive; + if (fee_amount > 0) { + event::emit(DistributeTransactionFee { pool_address, fee_amount }); }; }; + let rewards_amount = rewards_active + rewards_pending_inactive; + // Pending active stake can now be active. + coin::merge(&mut stake_pool.active, coin::extract_all(&mut stake_pool.pending_active)); + // Pending inactive stake is only fully unlocked and moved into inactive if the current lockup cycle has expired let current_lockup_expiration = stake_pool.locked_until_secs; if (get_reconfig_start_time_secs() >= current_lockup_expiration) { @@ -5052,11 +5257,15 @@ This function shouldn't abort. if (std::features::module_event_migration_enabled()) { event::emit(DistributeRewards { pool_address, rewards_amount }); + } else { + event::emit_event( + &mut stake_pool.distribute_rewards_events, + DistributeRewardsEvent { + pool_address, + rewards_amount, + }, + ); }; - event::emit_event( - &mut stake_pool.distribute_rewards_events, - DistributeRewardsEvent { pool_address, rewards_amount } - ); }
@@ -5851,7 +6060,16 @@ Returns validator's next epoch voting power, including pending_active, active, a -
let addr = signer::address_of(account);
+
pragma verify = false;
+pragma aborts_if_is_partial = true;
+include AbortsIfSignerPermissionStake {
+    s: account
+};
+let is_public_key_validated = aptos_std::ed25519::spec_public_key_validate_internal(
+    consensus_pubkey,
+);
+aborts_if !is_public_key_validated;
+let addr = signer::address_of(account);
 let post_addr = signer::address_of(account);
 let allowed = global<AllowedValidators>(@supra_framework);
 aborts_if exists<ValidatorConfig>(addr);
@@ -6054,7 +6272,8 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
include AbortsIfSignerPermissionStake {
+
pragma aborts_if_is_partial = true;
+include AbortsIfSignerPermissionStake {
     s: operator
 };
 let pre_stake_pool = global<StakePool>(pool_address);
@@ -6081,7 +6300,8 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
-
include AbortsIfSignerPermissionStake {
+
pragma aborts_if_is_partial = true;
+include AbortsIfSignerPermissionStake {
     s: operator
 };
 let pre_stake_pool = global<StakePool>(pool_address);
@@ -6407,6 +6627,300 @@ Returns validator's next epoch voting power, including pending_active, active, a
 
 
 
+
+
+
+
+
schema AddStakeWithCapAbortsIfAndEnsures {
+    owner_cap: OwnerCapability;
+    amount: u64;
+    let pool_address = owner_cap.pool_address;
+    aborts_if !exists<StakePool>(pool_address);
+    let config = global<staking_config::StakingConfig>(@supra_framework);
+    let validator_set = global<ValidatorSet>(@supra_framework);
+    let voting_power_increase_limit = config.voting_power_increase_limit;
+    let post post_validator_set = global<ValidatorSet>(@supra_framework);
+    let update_voting_power_increase = amount != 0 && (spec_contains(validator_set.active_validators, pool_address)
+                                                       || spec_contains(validator_set.pending_active, pool_address));
+    aborts_if update_voting_power_increase && validator_set.total_joining_power + amount > MAX_U128;
+    ensures update_voting_power_increase ==> post_validator_set.total_joining_power == validator_set.total_joining_power + amount;
+    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
+            && validator_set.total_voting_power * voting_power_increase_limit > MAX_U128;
+    aborts_if update_voting_power_increase && validator_set.total_voting_power > 0
+            && validator_set.total_joining_power + amount > validator_set.total_voting_power * voting_power_increase_limit / 100;
+    let stake_pool = global<StakePool>(pool_address);
+    let post post_stake_pool = global<StakePool>(pool_address);
+    let value_pending_active = stake_pool.pending_active.value;
+    let value_active = stake_pool.active.value;
+    ensures amount != 0 && spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.pending_active.value == value_pending_active + amount;
+    ensures amount != 0 && !spec_is_current_epoch_validator(pool_address) ==> post_stake_pool.active.value == value_active + amount;
+    let maximum_stake = config.maximum_stake;
+    let value_pending_inactive = stake_pool.pending_inactive.value;
+    let next_epoch_voting_power = value_pending_active + value_active + value_pending_inactive;
+    let voting_power = next_epoch_voting_power + amount;
+    aborts_if amount != 0 && voting_power > MAX_U64;
+    aborts_if amount != 0 && voting_power > maximum_stake;
+}
+
+ + + + + + + +
schema AddStakeAbortsIfAndEnsures {
+    owner: signer;
+    amount: u64;
+    let owner_address = signer::address_of(owner);
+    aborts_if !exists<OwnerCapability>(owner_address);
+    let owner_cap = global<OwnerCapability>(owner_address);
+    include AddStakeWithCapAbortsIfAndEnsures { owner_cap };
+}
+
+ + + + + + + +
fun spec_is_allowed(account: address): bool {
+   if (!exists<AllowedValidators>(@supra_framework)) {
+       true
+   } else {
+       let allowed = global<AllowedValidators>(@supra_framework);
+       contains(allowed.accounts, account)
+   }
+}
+
+ + + + + + + +
fun spec_find_validator(v: vector<ValidatorInfo>, addr: address): Option<u64>;
+
+ + + + + + + +
fun spec_validators_are_initialized(validators: vector<ValidatorInfo>): bool {
+   forall i in 0..len(validators):
+       spec_has_stake_pool(validators[i].addr) &&
+           spec_has_validator_config(validators[i].addr)
+}
+
+ + + + + + + +
fun spec_validators_are_initialized_addrs(addrs: vector<address>): bool {
+   forall i in 0..len(addrs):
+       spec_has_stake_pool(addrs[i]) &&
+           spec_has_validator_config(addrs[i])
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid(validators: vector<ValidatorInfo>): bool {
+   spec_validator_indices_are_valid_addr(validators, spec_validator_index_upper_bound()) &&
+       spec_validator_indices_are_valid_config(validators, spec_validator_index_upper_bound())
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid_addr(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
+   forall i in 0..len(validators):
+       global<ValidatorConfig>(validators[i].addr).validator_index < upper_bound
+}
+
+ + + + + + + +
fun spec_validator_indices_are_valid_config(validators: vector<ValidatorInfo>, upper_bound: u64): bool {
+   forall i in 0..len(validators):
+       validators[i].config.validator_index < upper_bound
+}
+
+ + + + + + + +
fun spec_validator_indices_active_pending_inactive(validator_set: ValidatorSet): bool {
+   len(validator_set.pending_inactive) + len(validator_set.active_validators) == spec_validator_index_upper_bound()
+}
+
+ + + + + + + +
fun spec_validator_index_upper_bound(): u64 {
+   len(global<ValidatorPerformance>(@supra_framework).validators)
+}
+
+ + + + + + + +
fun spec_has_stake_pool(a: address): bool {
+   exists<StakePool>(a)
+}
+
+ + + + + + + +
fun spec_has_validator_config(a: address): bool {
+   exists<ValidatorConfig>(a)
+}
+
+ + + + + + + +
fun spec_rewards_amount(
+   stake_amount: u64,
+   num_successful_proposals: u64,
+   num_total_proposals: u64,
+   rewards_rate: u64,
+   rewards_rate_denominator: u64,
+): u64;
+
+ + + + + + + +
fun spec_contains(validators: vector<ValidatorInfo>, addr: address): bool {
+   exists i in 0..len(validators): validators[i].addr == addr
+}
+
+ + + + + + + +
fun spec_is_current_epoch_validator(pool_address: address): bool {
+   let validator_set = global<ValidatorSet>(@supra_framework);
+   !spec_contains(validator_set.pending_active, pool_address)
+       && (spec_contains(validator_set.active_validators, pool_address)
+       || spec_contains(validator_set.pending_inactive, pool_address))
+}
+
+ + + + + + + +
schema ResourceRequirement {
+    requires exists<SupraCoinCapabilities>(@supra_framework);
+    requires exists<ValidatorPerformance>(@supra_framework);
+    requires exists<ValidatorSet>(@supra_framework);
+    requires exists<StakingConfig>(@supra_framework);
+    requires exists<StakingRewardsConfig>(@supra_framework) || !features::spec_periodical_reward_rate_decrease_enabled();
+    requires exists<timestamp::CurrentTimeMicroseconds>(@supra_framework);
+}
+
+ + + + + + + +
fun spec_get_reward_rate_1(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           0
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           let nominator = aptos_std::fixed_point64::spec_multiply_u128(denominator, epoch_rewards_rate);
+           nominator
+       }
+   } else {
+           config.rewards_rate
+   }
+}
+
+ + + + + + + +
fun spec_get_reward_rate_2(config: StakingConfig): num {
+   if (features::spec_periodical_reward_rate_decrease_enabled()) {
+       let epoch_rewards_rate = global<staking_config::StakingRewardsConfig>(@supra_framework).rewards_rate;
+       if (epoch_rewards_rate.value == 0) {
+           1
+       } else {
+           let denominator_0 = aptos_std::fixed_point64::spec_divide_u128(staking_config::MAX_REWARDS_RATE, epoch_rewards_rate);
+           let denominator = if (denominator_0 > MAX_U64) {
+               MAX_U64
+           } else {
+               denominator_0
+           };
+           denominator
+       }
+   } else {
+           config.rewards_rate_denominator
+   }
+}
+
+ + + ### Function `update_stake_pool` diff --git a/aptos-move/framework/supra-framework/doc/supra_governance.md b/aptos-move/framework/supra-framework/doc/supra_governance.md index cf3a2c02d97..77fd580446d 100644 --- a/aptos-move/framework/supra-framework/doc/supra_governance.md +++ b/aptos-move/framework/supra-framework/doc/supra_governance.md @@ -1531,41 +1531,6 @@ Return a signer for making changes to 0x1 as part of on-chain governance proposa - - - - -## Function `initialize_for_verification` - - - -
#[verify_only]
-public fun initialize_for_verification(supra_framework: &signer, voting_duration_secs: u64, supra_min_voting_threshold: u64, voters: vector<address>)
-
- - - -
-Implementation - - -
public fun initialize_for_verification(
-    supra_framework: &signer,
-    voting_duration_secs: u64,
-    supra_min_voting_threshold: u64,
-    voters: vector<address>
-) {
-    initialize(
-        supra_framework,
-        voting_duration_secs,
-        supra_min_voting_threshold,
-        voters
-    );
-}
-
- - -
diff --git a/aptos-move/framework/supra-framework/sources/configs/dkg_config.move b/aptos-move/framework/supra-framework/sources/configs/dkg_config.move index da159654853..88865c8c74b 100644 --- a/aptos-move/framework/supra-framework/sources/configs/dkg_config.move +++ b/aptos-move/framework/supra-framework/sources/configs/dkg_config.move @@ -130,7 +130,7 @@ module supra_framework::dkg_config { public(friend) fun on_new_epoch(framework: &signer) acquires DkgConfig { system_addresses::assert_supra_framework(framework); if (config_buffer::does_exist()) { - let new_config = config_buffer::extract(); + let new_config = config_buffer::extract_v2(); if (exists(@supra_framework)) { *borrow_global_mut(@supra_framework) = new_config; } else { diff --git a/aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move b/aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move index 0c1ac2066d5..e5adc17770e 100644 --- a/aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move +++ b/aptos-move/framework/supra-framework/sources/configs/leader_ban_registry_config.move @@ -100,7 +100,7 @@ module supra_framework::leader_ban_registry_config { ) acquires BanRegistryParameters, BanRegistryParametersV0 { system_addresses::assert_supra_framework(framework); if (config_buffer::does_exist()) { - let new_config = config_buffer::extract(); + let new_config = config_buffer::extract_v2(); if (exists(@supra_framework)) { *borrow_global_mut(@supra_framework) = new_config; } else { diff --git a/aptos-move/framework/supra-framework/sources/genesis.move b/aptos-move/framework/supra-framework/sources/genesis.move index 9f27fe2ec7c..53866f8c2f2 100644 --- a/aptos-move/framework/supra-framework/sources/genesis.move +++ b/aptos-move/framework/supra-framework/sources/genesis.move @@ -206,7 +206,6 @@ module supra_framework::genesis { reconfiguration::initialize(&supra_framework_account); block::initialize(&supra_framework_account, epoch_interval_microsecs); state_storage::initialize(&supra_framework_account); - timestamp::set_time_has_started(&supra_framework_account, genesis_timestamp_in_microseconds); } /// Genesis step 2: Initialize Supra coin. @@ -337,7 +336,7 @@ module supra_framework::genesis { /// This creates an funds an account if it doesn't exist. /// If it exists, it just returns the signer. fun create_account(supra_framework: &signer, account_address: address, balance: u64): signer { - if (account::exists_at(account_address)) { + let account = if (account::exists_at(account_address)) { create_signer(account_address) } else { account::create_account(account_address) diff --git a/aptos-move/framework/supra-framework/sources/stake.move b/aptos-move/framework/supra-framework/sources/stake.move index 9adb6c011e2..b05af074e8a 100644 --- a/aptos-move/framework/supra-framework/sources/stake.move +++ b/aptos-move/framework/supra-framework/sources/stake.move @@ -218,17 +218,6 @@ module supra_framework::stake { fee_amount: u64, } - /// Transaction fee that is collected in current epoch, indexed by validator_index. - struct PendingTransactionFee has key, store { - pending_fee_by_validator: BigOrderedMap>, - } - - #[event] - struct DistributeTransactionFee has drop, store { - pool_address: address, - fee_amount: u64, - } - /// SupraCoin capabilities, set during genesis and stored in @CoreResource account. /// This allows the Stake module to mint rewards to stakers. struct SupraCoinCapabilities has key { @@ -391,18 +380,6 @@ module supra_framework::stake { fees_table: Table> } - /// Initializes the resource storing information about collected transaction fees per validator. - /// Used by `transaction_fee.move` to initialize fee collection and distribution. - public(friend) fun initialize_validator_fees( - supra_framework: &signer - ) { - system_addresses::assert_supra_framework(supra_framework); - assert!( - permissioned_signer::check_permission_exists(s, StakeManagementPermission {}), - error::permission_denied(ENO_STAKE_PERMISSION), - ); - } - /// Permissions inline fun check_stake_permission(s: &signer) { assert!( @@ -416,20 +393,6 @@ module supra_framework::stake { permissioned_signer::authorize_unlimited(master, permissioned_signer, StakeManagementPermission {}) } - /// Stores the transaction fee collected to the specified validator address. - public(friend) fun add_transaction_fee( - validator_addr: address, fee: Coin - ) acquires ValidatorFees { - let fees_table = - &mut borrow_global_mut(@supra_framework).fees_table; - if (table::contains(fees_table, validator_addr)) { - let collected_fee = table::borrow_mut(fees_table, validator_addr); - coin::merge(collected_fee, fee); - } else { - table::add(fees_table, validator_addr, fee); - } - } - #[view] /// Return the lockup expiration of the stake pool at `pool_address`. /// This will throw an error if there's no stake pool at `pool_address`. @@ -1228,7 +1191,7 @@ module supra_framework::stake { /// Each DkgCommitteeOutput contains a threshold_type and corresponding keys for all validators. public(friend) fun set_dkg_output_keys( committee_outputs: vector - ) acquires ValidatorConfig, ValidatorFees, ValidatorPerformance, ValidatorSet, StakePool { + ) acquires ValidatorConfig, ValidatorPerformance, ValidatorSet, StakePool { if (vector::is_empty(&committee_outputs)) { return }; let next_validator_infos = next_validator_consensus_infos(); @@ -1311,7 +1274,7 @@ module supra_framework::stake { new_consensus_pubkey } ); - } + }; i = i + 1; }; @@ -1934,7 +1897,7 @@ module supra_framework::stake { /// membership (active + pending_active) must reflect the next epoch, but node config /// should reflect current-epoch for the active validators to ensure that validators that update /// their configuration do not need to run two copies of themselves to participate in DKG. - public fun next_epoch_validator_consensus_infos_for_dkg(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig { + public fun next_epoch_validator_consensus_infos_for_dkg(): vector acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig { // Use the current-epoch config snapshot for active validators so mid-epoch config changes // do not take effect during DKG (use_current_config_for_actives=true). let new_validator_set = compute_next_validator_set_internal(true); @@ -1951,7 +1914,7 @@ module supra_framework::stake { /// (which appends via `pop_back`). fun compute_next_validator_set_internal( use_current_config_for_actives: bool - ): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorFees, ValidatorConfig { + ): ValidatorSet acquires ValidatorSet, ValidatorPerformance, StakePool, ValidatorConfig { // Init. let cur_validator_set = borrow_global(@supra_framework); let staking_config = staking_config::get(); @@ -2093,17 +2056,6 @@ module supra_framework::stake { } else { 0 } } - /// Returns the accumulated gas fees assigned to `candidate_addr`, or 0 if fee collection - /// is disabled or no fees have been recorded for this validator. - fun collect_candidate_fee(candidate_addr: address): u64 acquires ValidatorFees { - if (features::collect_and_distribute_gas_fees()) { - let fees_table = &borrow_global(@supra_framework).fees_table; - if (table::contains(fees_table, candidate_addr)) { - coin::value(table::borrow(fees_table, candidate_addr)) - } else { 0 } - } else { 0 } - } - fun validator_consensus_infos_from_validator_set( validator_set: &ValidatorSet ): vector { @@ -2742,7 +2694,7 @@ module supra_framework::stake { #[expected_failure(abort_code = 0x10016, location = Self)] public entry fun test_initialize_validator_rejects_duplicate_consensus_pubkey_active( supra_framework: &signer, validator_1: &signer, validator_2: &signer - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, PendingTransactionFee { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); // validator_1 joins and becomes active in the next epoch. @@ -2755,7 +2707,7 @@ module supra_framework::stake { #[expected_failure(abort_code = 0x10016, location = Self)] public entry fun test_initialize_validator_rejects_duplicate_consensus_pubkey_pending_active( supra_framework: &signer, validator_1: &signer, validator_2: &signer - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, PendingTransactionFee { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); // validator_1 joins pending_active but no epoch transition. @@ -2798,7 +2750,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)] public entry fun test_initialize_validator_allows_two_empty_network_addresses( supra_framework: &signer, validator_1: &signer, validator_2: &signer - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, PendingTransactionFee { initialize_for_test(supra_framework); let (_sk_1, pk_1) = generate_identity(); let (_sk_2, pk_2) = generate_identity(); @@ -2812,7 +2764,7 @@ module supra_framework::stake { #[expected_failure(abort_code = 0x10016, location = Self)] public entry fun test_rotate_consensus_key_rejects_duplicate( supra_framework: &signer, validator_1: &signer, validator_2: &signer - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, PendingTransactionFee { initialize_for_test(supra_framework); let (_sk_1, pk_1) = generate_identity(); let (_sk_2, pk_2) = generate_identity(); @@ -2826,7 +2778,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_rotate_consensus_key_allows_fresh_key( supra_framework: &signer, validator: &signer - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, PendingTransactionFee { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); initialize_test_validator(&pk, validator, 100, true, true); @@ -2838,7 +2790,7 @@ module supra_framework::stake { #[test(supra_framework = @supra_framework, validator = @0x123)] public entry fun test_rotate_consensus_key_allows_self_rotation( supra_framework: &signer, validator: &signer - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, PendingTransactionFee { initialize_for_test(supra_framework); let (_sk, pk) = generate_identity(); let pk_bytes = validator_public_keys::public_key_to_bytes(pk); @@ -2851,7 +2803,7 @@ module supra_framework::stake { #[expected_failure(abort_code = 0x10017, location = Self)] public entry fun test_update_network_addresses_rejects_duplicate( supra_framework: &signer, validator_1: &signer, validator_2: &signer - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees { + ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, PendingTransactionFee { initialize_for_test(supra_framework); let (_sk_1, pk_1) = generate_identity(); let (_sk_2, pk_2) = generate_identity(); @@ -4332,92 +4284,6 @@ module supra_framework::stake { record_fee(vm, vector[1], vector[1]); } - #[test(vm = @0x0, supra_framework = @0x1, validator_0 = @0x123, validator_1 = @0x234)] - public entry fun test_transaction_fee( - vm: &signer, - supra_framework: &signer, - validator_0: &signer, - validator_1: &signer, - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, PendingTransactionFee, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet { - initialize_for_test(supra_framework); - initialize_pending_transaction_fee(supra_framework); - features::change_feature_flags_for_testing(supra_framework, vector[features::get_distribute_transaction_fee_feature()], vector[]); - let address_0 = signer::address_of(validator_0); - let address_1 = signer::address_of(validator_1); - let (_sk_0, pk_0) = generate_identity(); - let (_sk_1, pk_1) = generate_identity(); - initialize_test_validator(&pk_0, validator_0, 100, true, false); - initialize_test_validator(&pk_1, validator_1, 100, true, true); - assert!(vector::length(&borrow_global(@supra_framework).active_validators) == 2, 0); - - let validator_to_remove = signer::address_of(validator_0); - remove_validators(supra_framework, &vector[validator_to_remove]); - assert!(vector::length(&borrow_global(@supra_framework).active_validators) == 1, 0); - - // validator 0 is pending inactive, validator 1 is active, both should get fee. - - { - let fee_table = &borrow_global(@supra_framework).pending_fee_by_validator; - assert!(fee_table.contains(&0), 0); - assert!(fee_table.contains(&1), 0); - }; - - record_fee(vm, vector[], vector[]); - record_fee(vm, vector[get_validator_index(address_0)], vector[1]); - record_fee(vm, vector[get_validator_index(address_1)], vector[2]); - record_fee(vm, vector[get_validator_index(address_0), get_validator_index(address_1)], vector[10, 220]); - - { - let fee_table = &borrow_global(@supra_framework).pending_fee_by_validator; - assert!(fee_table.borrow(&get_validator_index(address_0)).read() == 11, 0); - assert!(fee_table.borrow(&get_validator_index(address_1)).read() == 222, 0); - end_epoch(); - - assert!(event::was_event_emitted(&DistributeTransactionFee { pool_address: address_0, fee_amount: 11 }), 0); - assert!(event::was_event_emitted(&DistributeTransactionFee { pool_address: address_1, fee_amount: 222 }), 0); - }; - - let fee_table = &borrow_global(@supra_framework).pending_fee_by_validator; - // validator 1 is at index 0 now. - assert!(fee_table.contains(&0), 0); - assert!(!fee_table.contains(&1), 0); - - assert!(event::emitted_events().length() == 2, 0); - // No more event is emitted at this epoch ending. - end_epoch(); - assert!(event::emitted_events().length() == 2, 0); - } - - #[test(vm = @0x0, supra_framework = @0x1, validator_0 = @0x123, validator_1 = @0x234)] - #[expected_failure(abort_code = 0x10002, location = 0x1::big_ordered_map)] - public entry fun test_transaction_fee_non_validator( - vm: &signer, - supra_framework: &signer, - validator_0: &signer, - validator_1: &signer, - ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, PendingTransactionFee, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet { - initialize_for_test(supra_framework); - initialize_pending_transaction_fee(supra_framework); - features::change_feature_flags_for_testing(supra_framework, vector[features::get_distribute_transaction_fee_feature()], vector[]); - let (_sk_0, pk_0) = generate_identity(); - let (_sk_1, pk_1) = generate_identity(); - initialize_test_validator(&pk_0, validator_0, 100, true, false); - initialize_test_validator(&pk_1, validator_1, 100, true, true); - assert!(vector::length(&borrow_global(@supra_framework).active_validators) == 2, 0); - - let validator_to_remove = signer::address_of(validator_0); - remove_validators(supra_framework, &vector[validator_to_remove]); - assert!(vector::length(&borrow_global(@supra_framework).active_validators) == 1, 0); - - // validator 0 is pending inactive, validator 1 is active. - - end_epoch(); - assert!(event::emitted_events().length() == 0, 0); - - // Validator index is out of bound, abort. - record_fee(vm, vector[1], vector[1]); - } - #[test_only] public fun end_epoch() acquires SupraCoinCapabilities, PendingTransactionFee, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet { // Set the number of blocks to 1, to give out rewards to non-failing validators. diff --git a/aptos-move/framework/supra-framework/sources/stake.spec.move b/aptos-move/framework/supra-framework/sources/stake.spec.move index 745bd169174..7bbf062f54f 100644 --- a/aptos-move/framework/supra-framework/sources/stake.spec.move +++ b/aptos-move/framework/supra-framework/sources/stake.spec.move @@ -137,7 +137,7 @@ spec supra_framework::stake { let is_public_key_validated = aptos_std::ed25519::spec_public_key_validate_internal( consensus_pubkey, ); - aborts_if !is_public_key_validated;*/ + aborts_if !is_public_key_validated; let addr = signer::address_of(account); let post_addr = signer::address_of(account); let allowed = global(@supra_framework); diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index f2150dfd670..e140c1dbcf0 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -36,7 +36,7 @@ use aptos_types::{ }, move_utils::as_move_value::AsMoveValue, on_chain_config::{ - APTOS_MAX_KNOWN_VERSION, AutomationRegistryConfig, BanRegistryParameters, BanRegistryParametersV0, FeatureFlag, Features, GasScheduleV2, OnChainConsensusConfig, OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit} + APTOS_MAX_KNOWN_VERSION, AutomationRegistryConfig, BanRegistryParameters, FeatureFlag, Features, GasScheduleV2, OnChainConsensusConfig, OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit} }, state_store::state_key::StateKey, transaction::{authenticator::AuthenticationKey, ChangeSet, Transaction, WriteSetPayload}, @@ -718,7 +718,7 @@ fn initialize_supra_native_automation( } fn initialize_leader_ban_config( - session: &mut SessionExt, + session: &mut SessionExt, module_storage: &impl AptosModuleStorage, traversal_context: &mut TraversalContext, genesis_config: &GenesisConfiguration, @@ -728,24 +728,8 @@ fn initialize_leader_ban_config( }; exec_function( session, - module_storage: &impl AptosModuleStorage, - traversal_context: &mut TraversalContext, - GENESIS_MODULE_NAME, - "initialize_leader_ban_registry_config", - vec![], - config.serialize_into_move_values_with_signer(CORE_CODE_ADDRESS), - ); -} - -fn initialize_leader_ban_config( - session: &mut SessionExt, - genesis_config: &GenesisConfiguration, -) { - let Some(config) = &genesis_config.leader_ban_registry_config else { - return; - }; - exec_function( - session, + module_storage, + traversal_context, GENESIS_MODULE_NAME, "initialize_leader_ban_registry_config", vec![], diff --git a/config/src/config/identity_config.rs b/config/src/config/identity_config.rs index 096be32cfc2..82f3ded0cc1 100644 --- a/config/src/config/identity_config.rs +++ b/config/src/config/identity_config.rs @@ -11,7 +11,7 @@ use aptos_crypto::{ }; use aptos_types::{ account_address::{from_identity_public_key, AccountAddress, AccountAddress as PeerId}, - aptos_dkg::{real_dkg::maybe_dk_from_bls_sk, DKGTrait, DefaultDKG}, + dkg::{real_dkg::maybe_dk_from_bls_sk, DKGTrait, DefaultDKG}, }; use serde::{Deserialize, Serialize}; use std::{ diff --git a/execution/executor-types/src/lib.rs b/execution/executor-types/src/lib.rs index 8e9a769f10f..a3734212930 100644 --- a/execution/executor-types/src/lib.rs +++ b/execution/executor-types/src/lib.rs @@ -8,7 +8,7 @@ use aptos_crypto::HashValue; use aptos_scratchpad::SparseMerkleTree; use aptos_types::{ account_config::{NEW_EPOCH_EVENT_MOVE_TYPE_TAG, NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG}, - aptos_dkg::DKG_START_EVENT_MOVE_TYPE_TAG, + dkg::DKG_START_EVENT_MOVE_TYPE_TAG, block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, contract_event::ContractEvent, jwks::OBSERVED_JWK_UPDATED_MOVE_TYPE_TAG, diff --git a/types/Cargo.toml b/types/Cargo.toml index c1f4b85cd84..d07d9cd6b00 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -109,6 +109,7 @@ fuzzing = [ "proptest-derive", "aptos-crypto/fuzzing", "move-core-types/fuzzing", + "arbitrary", ] rest_api_schema = ["utoipa", "arbitrary"] diff --git a/types/src/aptos_dkg/mod.rs b/types/src/aptos_dkg/mod.rs deleted file mode 100644 index e8ff50d530f..00000000000 --- a/types/src/aptos_dkg/mod.rs +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright © Aptos Foundation -// SPDX-License-Identifier: Apache-2.0 - -use self::real_dkg::RealDKG; -use crate::{ - aptos_dkg::real_dkg::rounding::DKGRoundingProfile, - on_chain_config::{OnChainConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct}, - validator_verifier::{ValidatorConsensusInfo, ValidatorConsensusInfoMoveStruct}, -}; -use anyhow::Result; -use aptos_crypto::Uniform; -use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; -use move_core_types::{ - account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, - move_resource::MoveStructType, -}; -use once_cell::sync::Lazy; -use rand::{CryptoRng, RngCore}; -use serde::{Deserialize, Serialize}; -use std::{ - collections::BTreeSet, - fmt::{Debug, Formatter}, - time::Duration, -}; - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, CryptoHasher, BCSCryptoHash)] -pub struct DKGTranscriptMetadata { - pub epoch: u64, - pub author: AccountAddress, -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct DKGStartEvent { - pub session_metadata: DKGSessionMetadata, - pub start_time_us: u64, -} - -impl MoveStructType for DKGStartEvent { - const MODULE_NAME: &'static IdentStr = ident_str!("dkg"); - const STRUCT_NAME: &'static IdentStr = ident_str!("DKGStartEvent"); -} - -pub static DKG_START_EVENT_MOVE_TYPE_TAG: Lazy = - Lazy::new(|| TypeTag::Struct(Box::new(DKGStartEvent::struct_tag()))); - -/// DKG transcript and its metadata. -#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct DKGTranscript { - pub metadata: DKGTranscriptMetadata, - #[serde(with = "serde_bytes")] - pub transcript_bytes: Vec, -} - -impl Debug for DKGTranscript { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("DKGTranscript") - .field("metadata", &self.metadata) - .field("transcript_bytes_len", &self.transcript_bytes.len()) - .finish() - } -} - -impl DKGTranscript { - pub fn new(epoch: u64, author: AccountAddress, transcript_bytes: Vec) -> Self { - Self { - metadata: DKGTranscriptMetadata { epoch, author }, - transcript_bytes, - } - } - - pub fn dummy() -> Self { - Self { - metadata: DKGTranscriptMetadata { - epoch: 0, - author: AccountAddress::ZERO, - }, - transcript_bytes: vec![], - } - } -} - -/// Reflection of `0x1::dkg::DKGSessionMetadata` in rust. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct DKGSessionMetadata { - pub dealer_epoch: u64, - pub randomness_config: RandomnessConfigMoveStruct, - pub dealer_validator_set: Vec, - pub target_validator_set: Vec, -} - -impl DKGSessionMetadata { - pub fn target_validator_consensus_infos_cloned(&self) -> Vec { - self.target_validator_set - .clone() - .into_iter() - .map(|obj| obj.try_into().unwrap()) - .collect() - } - - pub fn dealer_consensus_infos_cloned(&self) -> Vec { - self.dealer_validator_set - .clone() - .into_iter() - .map(|obj| obj.try_into().unwrap()) - .collect() - } - - pub fn randomness_config_derived(&self) -> Option { - OnChainRandomnessConfig::try_from(self.randomness_config.clone()).ok() - } -} - -impl MayHaveRoundingSummary for DKGSessionMetadata { - fn rounding_summary(&self) -> Option<&RoundingSummary> { - None - } -} - -/// Reflection of Move type `0x1::dkg::DKGSessionState`. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct DKGSessionState { - pub metadata: DKGSessionMetadata, - pub start_time_us: u64, - pub transcript: Vec, -} - -impl DKGSessionState { - pub fn target_epoch(&self) -> u64 { - self.metadata.dealer_epoch + 1 - } -} -/// Reflection of Move type `0x1::dkg::DKGState`. -#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] -pub struct DKGState { - pub last_completed: Option, - pub in_progress: Option, -} - -impl DKGState { - pub fn maybe_last_complete(&self, epoch: u64) -> Option<&DKGSessionState> { - match &self.last_completed { - Some(session) if session.target_epoch() == epoch => Some(session), - _ => None, - } - } - - pub fn last_complete(&self) -> &DKGSessionState { - self.last_completed.as_ref().unwrap() - } -} - -impl OnChainConfig for DKGState { - const MODULE_IDENTIFIER: &'static str = "dkg"; - const TYPE_IDENTIFIER: &'static str = "DKGState"; -} - -#[derive(Clone, Debug, Default)] -pub struct RoundingSummary { - pub method: String, - pub output: DKGRoundingProfile, - pub error: Option, - pub exec_time: Duration, -} - -pub trait MayHaveRoundingSummary { - fn rounding_summary(&self) -> Option<&RoundingSummary>; -} - -/// NOTE: this is a subset of the full scheme. Some data items/algorithms are not used in DKG and are omitted. -pub trait DKGTrait: Debug { - type DealerPrivateKey; - type PublicParams: Clone + Debug + Send + Sync + MayHaveRoundingSummary; - type Transcript: Clone + Send + Sync + Serialize + for<'a> Deserialize<'a>; - type InputSecret: Uniform; - type DealtSecret; - type DealtSecretShare; - type DealtPubKeyShare; - type NewValidatorDecryptKey: Uniform; - - fn new_public_params(dkg_session_metadata: &DKGSessionMetadata) -> Self::PublicParams; - fn aggregate_input_secret(secrets: Vec) -> Self::InputSecret; - fn dealt_secret_from_input( - pub_params: &Self::PublicParams, - input: &Self::InputSecret, - ) -> Self::DealtSecret; - fn generate_transcript( - rng: &mut R, - params: &Self::PublicParams, - input_secret: &Self::InputSecret, - my_index: u64, - sk: &Self::DealerPrivateKey, - ) -> Self::Transcript; - - fn verify_transcript(params: &Self::PublicParams, trx: &Self::Transcript) -> Result<()>; - - fn aggregate_transcripts( - params: &Self::PublicParams, - accumulator: &mut Self::Transcript, - element: Self::Transcript, - ); - - fn decrypt_secret_share_from_transcript( - pub_params: &Self::PublicParams, - trx: &Self::Transcript, - player_idx: u64, - dk: &Self::NewValidatorDecryptKey, - ) -> Result<(Self::DealtSecretShare, Self::DealtPubKeyShare)>; - - fn reconstruct_secret_from_shares( - pub_params: &Self::PublicParams, - player_share_pairs: Vec<(u64, Self::DealtSecretShare)>, - ) -> Result; - fn get_dealers(transcript: &Self::Transcript) -> BTreeSet; -} - -pub mod dummy_dkg; -pub mod real_dkg; - -pub type DefaultDKG = RealDKG; diff --git a/types/src/contract_event.rs b/types/src/contract_event.rs index 0e03810a0f2..3b9283d6b64 100644 --- a/types/src/contract_event.rs +++ b/types/src/contract_event.rs @@ -11,6 +11,7 @@ use crate::{ event::EventKey, jwks::ObservedJWKsUpdated, transaction::Version, + on_chain_config::new_epoch_event_key, }; use anyhow::{bail, Error, Result}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; @@ -325,8 +326,10 @@ impl TryFrom<&ContractEvent> for NewBlockEvent { } } -impl From<(u64, NewEpochEvent)> for ContractEvent { - fn from((seq_num, event): (u64, NewEpochEvent)) -> Self { +impl TryFrom<(u64, NewEpochEvent)> for ContractEvent { + type Error = Error; + + fn try_from((seq_num, event): (u64, NewEpochEvent)) -> Result { Self::new_v1( new_epoch_event_key(), seq_num, @@ -336,7 +339,7 @@ impl From<(u64, NewEpochEvent)> for ContractEvent { } } -impl TryFrom<&ContractEvent> for crate::aptos_dkg::DKGStartEvent { +impl TryFrom<&ContractEvent> for DKGStartEvent { type Error = Error; fn try_from(event: &ContractEvent) -> Result { @@ -354,26 +357,10 @@ impl TryFrom<&ContractEvent> for crate::aptos_dkg::DKGStartEvent { } } -impl TryFrom<&ContractEvent> for DKGStartEvent { +impl TryFrom for ContractEvent { type Error = Error; - fn try_from(event: &ContractEvent) -> Result { - match event { - ContractEvent::V1(_) => { - bail!("conversion to dkg start event failed with wrong contract event version"); - }, - ContractEvent::V2(event) => { - if event.type_tag != TypeTag::Struct(Box::new(Self::struct_tag())) { - bail!("conversion to dkg start event failed with wrong type tag") - } - bcs::from_bytes(&event.event_data).map_err(Into::into) - }, - } - } -} - -impl From for ContractEvent { - fn from(event: DKGStartEvent) -> Self { + fn try_from(event: DKGStartEvent) -> Result { Self::new_v2( TypeTag::from(DKGStartEvent::struct_tag()), bcs::to_bytes(&event).unwrap(), @@ -399,71 +386,10 @@ impl TryFrom<&ContractEvent> for DKGFinishEvent { } } -impl From for ContractEvent { - fn from(event: DKGFinishEvent) -> Self { - Self::new_v2( - TypeTag::from(DKGFinishEvent::struct_tag()), - bcs::to_bytes(&event).unwrap(), - ) - } -} - -impl TryFrom<&ContractEvent> for DKGMetaSetEvent { - type Error = Error; - - fn try_from(event: &ContractEvent) -> Result { - match event { - ContractEvent::V1(_) => { - bail!("conversion to dkg meta set event failed with wrong contract event version"); - }, - ContractEvent::V2(event) => { - if event.type_tag != TypeTag::Struct(Box::new(Self::struct_tag())) { - bail!("conversion to dkg meta set event failed with wrong type tag") - } - bcs::from_bytes(&event.event_data).map_err(Into::into) - }, - } - } -} - -impl From for ContractEvent { - fn from(event: DKGMetaSetEvent) -> Self { - Self::new_v2( - TypeTag::from(DKGMetaSetEvent::struct_tag()), - bcs::to_bytes(&event).unwrap(), - ) - } -} - -impl From for ContractEvent { - fn from(event: DKGStartEvent) -> Self { - Self::new_v2( - TypeTag::from(DKGStartEvent::struct_tag()), - bcs::to_bytes(&event).unwrap(), - ) - } -} - -impl TryFrom<&ContractEvent> for DKGFinishEvent { +impl TryFrom for ContractEvent { type Error = Error; - fn try_from(event: &ContractEvent) -> Result { - match event { - ContractEvent::V1(_) => { - bail!("conversion to dkg finish event failed with wrong contract event version"); - }, - ContractEvent::V2(event) => { - if event.type_tag != TypeTag::Struct(Box::new(Self::struct_tag())) { - bail!("conversion to dkg finish event failed with wrong type tag") - } - bcs::from_bytes(&event.event_data).map_err(Into::into) - }, - } - } -} - -impl From for ContractEvent { - fn from(event: DKGFinishEvent) -> Self { + fn try_from(event: DKGFinishEvent) -> Result { Self::new_v2( TypeTag::from(DKGFinishEvent::struct_tag()), bcs::to_bytes(&event).unwrap(), @@ -489,8 +415,10 @@ impl TryFrom<&ContractEvent> for DKGMetaSetEvent { } } -impl From for ContractEvent { - fn from(event: DKGMetaSetEvent) -> Self { +impl TryFrom for ContractEvent { + type Error = Error; + + fn try_from(event: DKGMetaSetEvent) -> Result { Self::new_v2( TypeTag::from(DKGMetaSetEvent::struct_tag()), bcs::to_bytes(&event).unwrap(), @@ -498,18 +426,6 @@ impl From for ContractEvent { } } -impl TryFrom<&ContractEvent> for NewEpochEvent { - type Error = Error; - - fn try_from(event: &ContractEvent) -> Result { - if event.is_new_epoch_event() { - Self::try_from_bytes(event.event_data()) - } else { - bail!("Expected NewEpochEvent") - } - } -} - impl TryFrom<&ContractEvent> for WithdrawEvent { type Error = Error; diff --git a/types/src/aptos_dkg/dummy_dkg/mod.rs b/types/src/dkg/dummy_dkg/mod.rs similarity index 97% rename from types/src/aptos_dkg/dummy_dkg/mod.rs rename to types/src/dkg/dummy_dkg/mod.rs index 7550d4e44e5..8098eb80d09 100644 --- a/types/src/aptos_dkg/dummy_dkg/mod.rs +++ b/types/src/dkg/dummy_dkg/mod.rs @@ -1,10 +1,8 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::aptos_{ - dkg::{DKGSessionMetadata, DKGTrait}, - validator_verifier::ValidatorVerifier, -}; +use crate::dkg::{DKGSessionMetadata, DKGTrait}; +use crate::validator_verifier::ValidatorVerifier; use anyhow::{anyhow, ensure}; use aptos_crypto::{ed25519, Uniform}; use move_core_types::account_address::AccountAddress; diff --git a/types/src/aptos_dkg/dummy_dkg/tests.rs b/types/src/dkg/dummy_dkg/tests.rs similarity index 99% rename from types/src/aptos_dkg/dummy_dkg/tests.rs rename to types/src/dkg/dummy_dkg/tests.rs index b3902cd08d7..b3dcb9137ed 100644 --- a/types/src/aptos_dkg/dummy_dkg/tests.rs +++ b/types/src/dkg/dummy_dkg/tests.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - aptos_dkg::{ + dkg::{ dummy_dkg::{DummyDKG, DummyDKGTranscript, DummySecret}, DKGSessionMetadata, DKGTrait, }, diff --git a/types/src/dkg/mod.rs b/types/src/dkg/mod.rs index 2e3bde94085..8017324fd60 100644 --- a/types/src/dkg/mod.rs +++ b/types/src/dkg/mod.rs @@ -3,12 +3,20 @@ use self::real_dkg::RealDKG; use crate::{ - dkg::real_dkg::rounding::DKGRoundingProfile, + dkg::{ + real_dkg::{ + rounding::DKGRoundingProfile, + Transcripts + }, + dkg_committee::DkgCommittee + }, on_chain_config::{OnChainConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct}, - validator_verifier::{ValidatorConsensusInfo, ValidatorConsensusInfoMoveStruct}, + validator_verifier::{ValidatorConsensusInfo, ValidatorConsensusInfoMoveStruct, ValidatorVerifier}, + validator_public_keys::ValidatorPublicKeys }; -use anyhow::Result; +use anyhow::{anyhow, Context, Result}; use aptos_crypto::Uniform; +use aptos_crypto::bls12381::PublicKey; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use move_core_types::{ account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, @@ -22,6 +30,17 @@ use std::{ fmt::{Debug, Formatter}, time::Duration, }; +use crypto::utils::get_clan_node_indices; + +pub mod dummy_dkg; +pub mod real_dkg; + +pub type DefaultDKG = RealDKG; + +pub mod dkg_committee; +pub mod events; +pub mod state; +pub mod transactions; #[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, CryptoHasher, BCSCryptoHash)] pub struct DKGTranscriptMetadata { @@ -77,6 +96,12 @@ impl DKGTranscript { transcript_bytes: vec![], } } + + pub(crate) fn verify(&self, verifier: &ValidatorVerifier) -> Result<()> { + let transcripts: Transcripts = bcs::from_bytes(&self.transcript_bytes) + .context("Transcripts deserialization failed")?; + RealDKG::verify_transcript_extra(&transcripts, verifier, true, None) + } } /// Reflection of `0x1::dkg::DKGSessionMetadata` in rust. @@ -166,7 +191,6 @@ pub trait MayHaveRoundingSummary { fn rounding_summary(&self) -> Option<&RoundingSummary>; } -/// NOTE: this is a subset of the full scheme. Some data items/algorithms are not used in DKG and are omitted. pub trait DKGTrait: Debug { type DealerPrivateKey; type PublicParams: Clone + Debug + Send + Sync + MayHaveRoundingSummary; @@ -191,8 +215,16 @@ pub trait DKGTrait: Debug { sk: &Self::DealerPrivateKey, ) -> Self::Transcript; + /// NOTE: used in VM. fn verify_transcript(params: &Self::PublicParams, trx: &Self::Transcript) -> Result<()>; + fn verify_transcript_extra( + trx: &Self::Transcript, + verifier: &ValidatorVerifier, + checks_voting_power: bool, + ensures_single_dealer: Option, + ) -> Result<()>; + fn aggregate_transcripts( params: &Self::PublicParams, accumulator: &mut Self::Transcript, @@ -213,7 +245,48 @@ pub trait DKGTrait: Debug { fn get_dealers(transcript: &Self::Transcript) -> BTreeSet; } -pub mod dummy_dkg; -pub mod real_dkg; +/// The threshold required to ensure the presence of honest majority in clan where +/// N = 2f+1 with f byzantine nodes +fn clan_threshold(total: u64) -> u64 { + total / 2 + 1 +} -pub type DefaultDKG = RealDKG; +pub fn get_clan_nodes_bls_keys_from_indices( + dealer_committee: &DkgCommittee, + signers: &Vec, + random_seed: &Vec, +) -> Result> { + let committee = dealer_committee.committee(); + let dealer_clan_committee_indices = + get_clan_node_indices(committee.len() as u32, random_seed.clone()); + + let mut clan_committee_bls_keys = Vec::new(); + if let Some(clan_committee_indices) = dealer_clan_committee_indices { + let clan_threshold = clan_threshold(clan_committee_indices.len() as u64); + + if signers.len() as u64 != clan_threshold { + return Err(anyhow!("dkg::number of signers must match clan_threshold")); + } + + for signer in signers { + let clan_node_index = clan_committee_indices + .get(*signer as usize) + .ok_or(anyhow!("dkg::node Invalid signer index: {signer}"))?; + let clan_node_key = committee + .get(*clan_node_index) + .ok_or(anyhow!("dkg::node Invalid clan node index: {signer}"))? + .dkg_pubkey(); + let clan_node_pk = ValidatorPublicKeys::try_from(clan_node_key).map_err(|e| { + anyhow!("dkg::node validator public key deserialization failed: {e}") + })?; + let clan_node_bls_pubkey_bytes = clan_node_pk.supra_keys().bls_multisig_key(); + let clan_node_bls_pubkey = + PublicKey::try_from(clan_node_bls_pubkey_bytes.as_slice()) + .map_err(|e| anyhow!("dkg::node bls public key deserialization failed: {e}"))?; + clan_committee_bls_keys.push(clan_node_bls_pubkey); + } + Ok(clan_committee_bls_keys) + } else { + Err(anyhow!("dkg::cannot derive clan committee")) + } +} diff --git a/types/src/aptos_dkg/real_dkg/mod.rs b/types/src/dkg/real_dkg/mod.rs similarity index 99% rename from types/src/aptos_dkg/real_dkg/mod.rs rename to types/src/dkg/real_dkg/mod.rs index 8624e66a020..0c0f9bc6c09 100644 --- a/types/src/aptos_dkg/real_dkg/mod.rs +++ b/types/src/dkg/real_dkg/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{ - aptos_dkg::{ + dkg::{ real_dkg::rounding::DKGRounding, DKGSessionMetadata, DKGTrait, MayHaveRoundingSummary, RoundingSummary, }, diff --git a/types/src/aptos_dkg/real_dkg/rounding/mod.rs b/types/src/dkg/real_dkg/rounding/mod.rs similarity index 100% rename from types/src/aptos_dkg/real_dkg/rounding/mod.rs rename to types/src/dkg/real_dkg/rounding/mod.rs diff --git a/types/src/aptos_dkg/real_dkg/rounding/tests.rs b/types/src/dkg/real_dkg/rounding/tests.rs similarity index 99% rename from types/src/aptos_dkg/real_dkg/rounding/tests.rs rename to types/src/dkg/real_dkg/rounding/tests.rs index 55a85096a8f..cdb29db527a 100644 --- a/types/src/aptos_dkg/real_dkg/rounding/tests.rs +++ b/types/src/dkg/real_dkg/rounding/tests.rs @@ -1,7 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::aptos_dkg::real_dkg::rounding::{ +use crate::dkg::real_dkg::rounding::{ is_valid_profile, total_weight_lower_bound, total_weight_upper_bound, DKGRounding, DKGRoundingProfile, DEFAULT_FAST_PATH_SECRECY_THRESHOLD, DEFAULT_RECONSTRUCT_THRESHOLD, DEFAULT_SECRECY_THRESHOLD, diff --git a/types/src/lib.rs b/types/src/lib.rs index 2a733bde6cc..ca6cebcb731 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -7,7 +7,6 @@ pub mod access_path; pub mod account_address; pub mod account_config; -pub mod aptos_dkg; pub mod block_info; pub mod block_metadata; pub mod block_metadata_ext; diff --git a/types/src/transaction/mod.rs b/types/src/transaction/mod.rs index 64bc8cb2170..9d4a499f515 100644 --- a/types/src/transaction/mod.rs +++ b/types/src/transaction/mod.rs @@ -14,7 +14,6 @@ use crate::{ ledger_info::LedgerInfo, proof::{TransactionInfoListWithProof, TransactionInfoWithProof}, serde_helper::vec_bytes, - transaction::automation::RegistrationParams, transaction::authenticator::{ AccountAuthenticator, AnyPublicKey, AnySignature, SingleKeyAuthenticator, TransactionAuthenticator, @@ -59,23 +58,17 @@ pub mod use_case; pub mod user_transaction_context; pub mod webauthn; -use crate::transaction::automated_transaction::AutomatedTransaction; -use crate::transaction::automation::AutomationRegistryRecord; pub use self::block_epilogue::{BlockEndInfo, BlockEpiloguePayload, FeeDistribution}; use crate::{ block_metadata_ext::BlockMetadataExt, - contract_event::TransactionEvent, - executable::ModulePath, fee_statement::FeeStatement, move_utils::MemberId, - function_info::FunctionInfo, keyless::FederatedKeylessPublicKey, on_chain_config::{FeatureFlag, Features}, proof::accumulator::InMemoryEventAccumulator, - serde_helper::vec_bytes, transaction::{ automated_transaction::AutomatedTransaction, automation::{AutomationRegistryRecord, RegistrationParams}, @@ -88,7 +81,6 @@ use crate::{ pub use block_output::BlockOutput; pub use change_set::ChangeSet; pub use module::{Module, ModuleBundle}; -use crate::move_utils::MemberId; pub use move_core_types::transaction_argument::TransactionArgument; use move_core_types::{ identifier::{IdentStr, Identifier}, diff --git a/types/src/unit_tests/automation.rs b/types/src/unit_tests/automation.rs index eb361d3845c..dfc391b2a78 100644 --- a/types/src/unit_tests/automation.rs +++ b/types/src/unit_tests/automation.rs @@ -57,7 +57,9 @@ fn test_registration_params_serde() { assert_eq!(serialized.len(), 8); // Check the order fo serialized items // Address - let v_address = bcs::from_bytes::(&serialized[0]).unwrap(); + // Finding: Cannot Deserialize Signer. + // As it has prefixed of enum master signer, or permission signer + let v_address = bcs::from_bytes::(&serialized[0][1..]).unwrap(); assert_eq!(address, v_address); // EntryFunction double serialized let v_entry_bytes = bcs::from_bytes::>(&serialized[1]).unwrap(); @@ -134,7 +136,9 @@ fn test_registration_params_v2_user_task_serde() { assert_eq!(serialized.len(), 8); // Check the order fo serialized items // Address - let v_address = bcs::from_bytes::(&serialized[0]).unwrap(); + // Finding: Cannot Deserialize Signer. + // As it has prefixed of enum master signer, or permission signer + let v_address = bcs::from_bytes::(&serialized[0][1..]).unwrap(); assert_eq!(address, v_address); // EntryFunction double serialized let v_entry_bytes = bcs::from_bytes::>(&serialized[1]).unwrap(); @@ -232,7 +236,9 @@ fn test_registration_params_system_task_serde() { assert_eq!(serialized.len(), 6); // Check the order fo serialized items // Address - let v_address = bcs::from_bytes::(&serialized[0]).unwrap(); + // Finding: Cannot Deserialize Signer. + // As it has prefixed of enum master signer, or permission signer + let v_address = bcs::from_bytes::(&serialized[0][1..]).unwrap(); assert_eq!(address, v_address); // EntryFunction double serialized let v_entry_bytes = bcs::from_bytes::>(&serialized[1]).unwrap(); diff --git a/types/src/validator_txn.rs b/types/src/validator_txn.rs index 6ed2e52ffda..9378a840537 100644 --- a/types/src/validator_txn.rs +++ b/types/src/validator_txn.rs @@ -1,7 +1,7 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::{aptos_dkg::DKGTranscript, dkg::transactions::DKGTransactionData, jwks, validator_verifier::ValidatorVerifier}; +use crate::{dkg::DKGTranscript, dkg::transactions::DKGTransactionData, jwks, validator_verifier::ValidatorVerifier}; use anyhow::Context; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; use serde::{Deserialize, Serialize}; @@ -53,6 +53,8 @@ impl ValidatorTransaction { pub fn verify(&self, verifier: &ValidatorVerifier) -> anyhow::Result<()> { match self { + // TODO: may be verify txn data here? + ValidatorTransaction::DKG(_) => Ok(()), ValidatorTransaction::DKGResult(dkg_result) => dkg_result .verify(verifier) .context("DKGResult verification failed"), From 2f23999c164964f2be111ae1faf402158c6b35e7 Mon Sep 17 00:00:00 2001 From: Isaac Doidge <30425649+isaacdoidge@users.noreply.github.com> Date: Mon, 22 Jun 2026 15:05:00 +1000 Subject: [PATCH 25/31] Corrected validation logic for new-format validator public keys (#368) (#369) * Updated consensus key rotation logic in stake.move to ensure that only static keys are updated. Renamed consensus_public_key functions in ValidatorConfig to indicate deprecation without strictly marking them with the macro. * Ensured that validators cannot register invalid static public keys. * Added PoP for BLS multisig validator key. CG key already contains a PoP that is evaluated by the native, and the other keys don't require PoP. --- .../framework/supra-framework/doc/stake.md | 340 ++++++++++++- .../doc/validator_public_keys.md | 373 ++++++++++++-- .../supra-framework/sources/stake.move | 480 ++++++++++++++++-- .../sources/validator_public_keys.move | 406 +++++++++++++-- .../delegation_pool_integration_tests.move | 22 +- .../src/validator_cache.rs | 4 +- crates/aptos/src/node/mod.rs | 4 +- .../tests/storage_integration_test.rs | 6 +- network/discovery/src/validator_set.rs | 2 +- types/src/validator_config.rs | 14 +- types/src/validator_info.rs | 14 +- types/src/validator_verifier.rs | 2 +- 12 files changed, 1485 insertions(+), 182 deletions(-) diff --git a/aptos-move/framework/supra-framework/doc/stake.md b/aptos-move/framework/supra-framework/doc/stake.md index 5c049239252..4f79d62654f 100644 --- a/aptos-move/framework/supra-framework/doc/stake.md +++ b/aptos-move/framework/supra-framework/doc/stake.md @@ -85,6 +85,8 @@ or if their stake drops below the min required, they would get removed at the en - [Function `remove_validators`](#0x1_stake_remove_validators) - [Function `initialize_stake_owner`](#0x1_stake_initialize_stake_owner) - [Function `initialize_validator`](#0x1_stake_initialize_validator) +- [Function `initialize_validator_genesis`](#0x1_stake_initialize_validator_genesis) +- [Function `initialize_validator_internal`](#0x1_stake_initialize_validator_internal) - [Function `validate_consensus_public_key`](#0x1_stake_validate_consensus_public_key) - [Function `assert_consensus_pubkey_unique_in_next_validator_set`](#0x1_stake_assert_consensus_pubkey_unique_in_next_validator_set) - [Function `assert_consensus_pubkey_unique_in_validator_list`](#0x1_stake_assert_consensus_pubkey_unique_in_validator_list) @@ -1733,6 +1735,16 @@ Cannot update stake pool's lockup to earlier than current lockup. + + +The submitted BLS multisig proof-of-possession does not verify against the multisig key. + + +
const EINVALID_PROOF_OF_POSSESSION: u64 = 24;
+
+ + + Invalid consensus public key @@ -2710,7 +2722,83 @@ Initialize the validator account and give ownership to the signing account. network_addresses: vector<u8>, fullnode_addresses: vector<u8> ) acquires AllowedValidators, ValidatorSet, ValidatorConfig { - validate_consensus_public_key(consensus_pubkey); + initialize_validator_internal( + account, + consensus_pubkey, + network_addresses, + fullnode_addresses, + false + ); +} +
+ + + + + + + +## Function `initialize_validator_genesis` + +Initialize a validator during genesis. Identical to initialize_validator except that the +consensus key blob is trusted genesis output and therefore carries no operator +proof-of-possession (mirrors rotate_consensus_key / rotate_consensus_key_genesis). + + +
public(friend) fun initialize_validator_genesis(account: &signer, consensus_pubkey: vector<u8>, network_addresses: vector<u8>, fullnode_addresses: vector<u8>)
+
+ + + +
+Implementation + + +
public(friend) fun initialize_validator_genesis(
+    account: &signer,
+    consensus_pubkey: vector<u8>,
+    network_addresses: vector<u8>,
+    fullnode_addresses: vector<u8>
+) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
+    initialize_validator_internal(
+        account,
+        consensus_pubkey,
+        network_addresses,
+        fullnode_addresses,
+        true
+    );
+}
+
+ + + +
+ + + +## Function `initialize_validator_internal` + + + +
fun initialize_validator_internal(account: &signer, consensus_pubkey: vector<u8>, network_addresses: vector<u8>, fullnode_addresses: vector<u8>, genesis: bool)
+
+ + + +
+Implementation + + +
fun initialize_validator_internal(
+    account: &signer,
+    consensus_pubkey: vector<u8>,
+    network_addresses: vector<u8>,
+    fullnode_addresses: vector<u8>,
+    genesis: bool
+) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
+    // Verify the keys (and, for operator submissions, the appended BLS multisig PoP) and keep
+    // only the canonical key bytes (any appended PoP is stripped before storage).
+    let consensus_pubkey = validate_consensus_public_key(consensus_pubkey, genesis);
     let account_addr = signer::address_of(account);
     assert_consensus_pubkey_unique_in_next_validator_set(
         account_addr, &consensus_pubkey
@@ -2741,7 +2829,7 @@ Initialize the validator account and give ownership to the signing account.
 
 
 
-
fun validate_consensus_public_key(consensus_pubkey: vector<u8>)
+
fun validate_consensus_public_key(consensus_pubkey: vector<u8>, genesis: bool): vector<u8>
 
@@ -2750,26 +2838,198 @@ Initialize the validator account and give ownership to the signing account. Implementation -
fun validate_consensus_public_key(consensus_pubkey: vector<u8>) {
-    if (std::features::supra_validator_identity_v2_enabled()) {
-        // Expect the new format.
-        let _valid_public_key =
-            validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey);
-    } else {
-        // Check the old format.
-        let maybe_valid_public_key =
+
fun validate_consensus_public_key(
+    consensus_pubkey: vector<u8>, genesis: bool
+): vector<u8> {
+    // Legacy format (only acceptable before v2): a bare ed25519 key with no aggregatable BLS
+    // key, hence no PoP. Accept and store it unchanged.
+    if (!std::features::supra_validator_identity_v2_enabled()) {
+        let maybe_legacy =
             ed25519::new_validated_public_key_from_bytes(consensus_pubkey);
+        if (option::is_some(&maybe_legacy)) {
+            return consensus_pubkey
+        };
+    };
 
-        if (option::is_none(&maybe_valid_public_key)) {
-            // Fall back to the new format. This enables validators to register their keys in
-            // the new format before the v2 feature flag is activated, which is safe because the
-            // new keys are a superset of the old and the consensus has logic for maintaining
-            // backwards compatibility.
-            let _valid_public_key =
-                validator_public_keys::validator_public_keys_from_bytes(
-                    consensus_pubkey
-                );
-        }
+    // New identity format (v2, or a pre-v2 early-migration submission). Operator (non-genesis)
+    // submissions carry an appended BLS multisig PoP; verify and strip it. Genesis is exempt.
+    let (keys_bytes, maybe_pop) =
+        if (genesis) {
+            (consensus_pubkey, option::none<vector<u8>>())
+        } else {
+            let (keys_bytes, pop) =
+                validator_public_keys::split_consensus_key_and_pop(consensus_pubkey);
+            (keys_bytes, option::some(pop))
+        };
+
+    let valid_public_keys =
+        validator_public_keys::validator_public_keys_from_bytes(keys_bytes);
+
+    if (option::is_some(&maybe_pop)) {
+        assert!(
+            validator_public_keys::verify_bls_multisig_pop(
+                &valid_public_keys, option::extract(&mut maybe_pop)
+            ),
+            error::invalid_argument(EINVALID_PROOF_OF_POSSESSION)
+        );
+    };
+
+    assert!(
+        validator_public_keys::validate_static_keys(&valid_public_keys),
+        error::invalid_argument(EINVALID_PUBLIC_KEY)
+    );
+
+    keys_bytes
+}
+
+ + + +
+ + + +## Function `assert_consensus_pubkey_unique_in_next_validator_set` + +Aborts if any validator other than self_addr in the next validator set +(the union of active_validators and pending_active) already uses +consensus_pubkey as its latest on-chain consensus key. + + +
fun assert_consensus_pubkey_unique_in_next_validator_set(self_addr: address, consensus_pubkey: &vector<u8>)
+
+ + + +
+Implementation + + +
fun assert_consensus_pubkey_unique_in_next_validator_set(
+    self_addr: address, consensus_pubkey: &vector<u8>
+) acquires ValidatorSet, ValidatorConfig {
+    let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+    assert_consensus_pubkey_unique_in_validator_list(
+        self_addr, consensus_pubkey, &validator_set.active_validators
+    );
+    assert_consensus_pubkey_unique_in_validator_list(
+        self_addr, consensus_pubkey, &validator_set.pending_active
+    );
+}
+
+ + + +
+ + + +## Function `assert_consensus_pubkey_unique_in_validator_list` + + + +
fun assert_consensus_pubkey_unique_in_validator_list(self_addr: address, consensus_pubkey: &vector<u8>, validators: &vector<stake::ValidatorInfo>)
+
+ + + +
+Implementation + + +
fun assert_consensus_pubkey_unique_in_validator_list(
+    self_addr: address,
+    consensus_pubkey: &vector<u8>,
+    validators: &vector<ValidatorInfo>
+) acquires ValidatorConfig {
+    let len = vector::length(validators);
+    let i = 0;
+    while (i < len) {
+        let other = vector::borrow(validators, i);
+        if (other.addr != self_addr && exists<ValidatorConfig>(other.addr)) {
+            let other_config = borrow_global<ValidatorConfig>(other.addr);
+            assert!(
+                other_config.consensus_pubkey != *consensus_pubkey,
+                error::invalid_argument(EDUPLICATE_CONSENSUS_PUBKEY)
+            );
+        };
+        i = i + 1;
+    };
+}
+
+ + + +
+ + + +## Function `assert_network_addresses_unique_in_next_validator_set` + +Aborts if any validator other than self_addr in the next validator set +already uses network_addresses. Empty network_addresses is treated +as "unset" and skips the check. + + +
fun assert_network_addresses_unique_in_next_validator_set(self_addr: address, network_addresses: &vector<u8>)
+
+ + + +
+Implementation + + +
fun assert_network_addresses_unique_in_next_validator_set(
+    self_addr: address, network_addresses: &vector<u8>
+) acquires ValidatorSet, ValidatorConfig {
+    if (vector::is_empty(network_addresses)) { return };
+    let validator_set = borrow_global<ValidatorSet>(@supra_framework);
+    assert_network_addresses_unique_in_validator_list(
+        self_addr, network_addresses, &validator_set.active_validators
+    );
+    assert_network_addresses_unique_in_validator_list(
+        self_addr, network_addresses, &validator_set.pending_active
+    );
+}
+
+ + + +
+ + + +## Function `assert_network_addresses_unique_in_validator_list` + + + +
fun assert_network_addresses_unique_in_validator_list(self_addr: address, network_addresses: &vector<u8>, validators: &vector<stake::ValidatorInfo>)
+
+ + + +
+Implementation + + +
fun assert_network_addresses_unique_in_validator_list(
+    self_addr: address,
+    network_addresses: &vector<u8>,
+    validators: &vector<ValidatorInfo>
+) acquires ValidatorConfig {
+    let len = vector::length(validators);
+    let i = 0;
+    while (i < len) {
+        let other = vector::borrow(validators, i);
+        if (other.addr != self_addr && exists<ValidatorConfig>(other.addr)) {
+            let other_config = borrow_global<ValidatorConfig>(other.addr);
+            assert!(
+                other_config.network_addresses != *network_addresses,
+                error::invalid_argument(EDUPLICATE_NETWORK_ADDRESSES)
+            );
+        };
+        i = i + 1;
     };
 }
 
@@ -3426,12 +3686,50 @@ Move amount of coins from pending_inactive to active. exists<ValidatorConfig>(pool_address), error::not_found(EVALIDATOR_CONFIG) ); - validate_consensus_public_key(new_consensus_pubkey); + // Verify the keys (and, for operator submissions, the appended BLS multisig PoP) and keep + // only the canonical key bytes (any appended PoP is stripped before storage/merge). + let new_consensus_pubkey = + validate_consensus_public_key(new_consensus_pubkey, genesis); assert_consensus_pubkey_unique_in_next_validator_set( pool_address, &new_consensus_pubkey ); let validator_info = borrow_global_mut<ValidatorConfig>(pool_address); let old_consensus_pubkey = validator_info.consensus_pubkey; + + // Preserve the DKG-managed BLS threshold keys: an operator rotation must only change the + // static keys. We load the current on-chain keys and copy in only the operator-supplied + // static keys, leaving the threshold keys (written by `set_dkg_output_keys`) intact. + // + // The merge is skipped (and the incoming blob stored verbatim, preserving the original + // behavior) when there is nothing to preserve or the stored blob cannot be parsed: + // - before v2: the stored blob may be a legacy ed25519 key with no threshold keys; + // - genesis: no DKG threshold keys exist yet; + // - an empty stored key: a validator initialized via `initialize_stake_owner` sets its key + // for the first time here, so there is no prior `ValidatorPublicKeys` to merge into + // (parsing the empty blob would abort). + // Under v2 a non-empty stored blob is guaranteed to be a valid `ValidatorPublicKeys` (the + // feature is only enabled once all validators have migrated to the new format), and + // `validate_consensus_public_key` has already verified the incoming blob, so both + // deserializations are safe. + let new_consensus_pubkey = + if (!genesis + && std::features::supra_validator_identity_v2_enabled() + && !vector::is_empty(&old_consensus_pubkey)) { + let current_keys = + validator_public_keys::validator_public_keys_from_bytes( + old_consensus_pubkey + ); + let incoming_keys = + validator_public_keys::validator_public_keys_from_bytes( + new_consensus_pubkey + ); + validator_public_keys::replace_static_keys( + &mut current_keys, &incoming_keys + ); + validator_public_keys::public_key_to_bytes(current_keys) + } else { + new_consensus_pubkey + }; validator_info.consensus_pubkey = new_consensus_pubkey; if (std::features::module_event_migration_enabled()) { diff --git a/aptos-move/framework/supra-framework/doc/validator_public_keys.md b/aptos-move/framework/supra-framework/doc/validator_public_keys.md index 063d42f0467..af5be0c5e11 100644 --- a/aptos-move/framework/supra-framework/doc/validator_public_keys.md +++ b/aptos-move/framework/supra-framework/doc/validator_public_keys.md @@ -29,6 +29,13 @@ - [Function `get_supra_bls_multi_sig_pub_key`](#0x1_validator_public_keys_get_supra_bls_multi_sig_pub_key) - [Function `get_supra_cg_key`](#0x1_validator_public_keys_get_supra_cg_key) - [Function `get_supra_ed_key`](#0x1_validator_public_keys_get_supra_ed_key) +- [Function `replace_static_keys`](#0x1_validator_public_keys_replace_static_keys) +- [Function `validate_static_keys`](#0x1_validator_public_keys_validate_static_keys) +- [Function `is_valid_ed25519_key`](#0x1_validator_public_keys_is_valid_ed25519_key) +- [Function `is_valid_bls12381_key`](#0x1_validator_public_keys_is_valid_bls12381_key) +- [Function `is_valid_cg_key`](#0x1_validator_public_keys_is_valid_cg_key) +- [Function `split_consensus_key_and_pop`](#0x1_validator_public_keys_split_consensus_key_and_pop) +- [Function `verify_bls_multisig_pop`](#0x1_validator_public_keys_verify_bls_multisig_pop) - [Function `rotate_supra_bls_threshold_validity_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_validity_key) - [Function `rotate_supra_bls_threshold_quorum_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_quorum_key) - [Function `rotate_supra_bls_threshold_unanimous_key`](#0x1_validator_public_keys_rotate_supra_bls_threshold_unanimous_key) @@ -48,6 +55,7 @@ use 0x1::option; use 0x1::string; use 0x1::type_info; +use 0x1::vector;
@@ -217,6 +225,16 @@ The size of a serialized bls12381 G1 public key, in bytes. + + +The size of a serialized bls12381 proof-of-possession (a G2 signature), in bytes. + + +
const BLS12381_POP_NUM_BYTES: u64 = 96;
+
+ + + The integer should match the Rust enum value representation in CertificateThresholdType. @@ -304,6 +322,16 @@ The size of a serialized ed25519 public key, in bytes. + + +Error: A consensus key blob is too short to contain an appended BLS proof-of-possession. + + +
const EINVALID_POP_LENGTH: u64 = 2;
+
+ + + Error: Unknown certificate threshold type. @@ -329,7 +357,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_VALIDITY } }
+
public fun validity_certificate_type(): CertificateThresholdType {
+    CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_VALIDITY }
+}
 
@@ -351,7 +381,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_QUORUM } }
+
public fun quorum_certificate_type(): CertificateThresholdType {
+    CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_QUORUM }
+}
 
@@ -373,7 +405,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun unanimous_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS } }
+
public fun unanimous_certificate_type(): CertificateThresholdType {
+    CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS }
+}
 
@@ -395,7 +429,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun bcft_validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY } }
+
public fun bcft_validity_certificate_type(): CertificateThresholdType {
+    CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY }
+}
 
@@ -417,7 +453,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun bcft_quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM } }
+
public fun bcft_quorum_certificate_type(): CertificateThresholdType {
+    CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM }
+}
 
@@ -439,7 +477,11 @@ Error: Unknown certificate threshold type. Implementation -
public fun bcft_fallback_view_change_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE } }
+
public fun bcft_fallback_view_change_certificate_type(): CertificateThresholdType {
+    CertificateThresholdType {
+        tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE
+    }
+}
 
@@ -461,7 +503,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun clan_majority_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY } }
+
public fun clan_majority_certificate_type(): CertificateThresholdType {
+    CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY }
+}
 
@@ -483,7 +527,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun is_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_VALIDITY }
+
public fun is_validity_certificate_type(t: &CertificateThresholdType): bool {
+    t.tag == CERTIFICATE_THRESHOLD_TYPE_VALIDITY
+}
 
@@ -505,7 +551,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun is_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_QUORUM }
+
public fun is_quorum_certificate_type(t: &CertificateThresholdType): bool {
+    t.tag == CERTIFICATE_THRESHOLD_TYPE_QUORUM
+}
 
@@ -527,7 +575,11 @@ Error: Unknown certificate threshold type. Implementation -
public fun is_unanimous_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS }
+
public fun is_unanimous_certificate_type(
+    t: &CertificateThresholdType
+): bool {
+    t.tag == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS
+}
 
@@ -549,7 +601,11 @@ Error: Unknown certificate threshold type. Implementation -
public fun is_bcft_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY }
+
public fun is_bcft_validity_certificate_type(
+    t: &CertificateThresholdType
+): bool {
+    t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY
+}
 
@@ -571,7 +627,11 @@ Error: Unknown certificate threshold type. Implementation -
public fun is_bcft_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM }
+
public fun is_bcft_quorum_certificate_type(
+    t: &CertificateThresholdType
+): bool {
+    t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM
+}
 
@@ -593,7 +653,11 @@ Error: Unknown certificate threshold type. Implementation -
public fun is_bcft_fallback_view_change_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE }
+
public fun is_bcft_fallback_view_change_certificate_type(
+    t: &CertificateThresholdType
+): bool {
+    t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE
+}
 
@@ -615,7 +679,11 @@ Error: Unknown certificate threshold type. Implementation -
public fun is_clan_majority_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY }
+
public fun is_clan_majority_certificate_type(
+    t: &CertificateThresholdType
+): bool {
+    t.tag == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY
+}
 
@@ -639,7 +707,8 @@ Error: Unknown certificate threshold type.
public fun validator_public_keys_from_bytes(bytes: vector<u8>): ValidatorPublicKeys {
     // bcs deserialization
-    let bytes_serialized = any::new(type_info::type_name<ValidatorPublicKeys>(), bytes);
+    let bytes_serialized =
+        any::new(type_info::type_name<ValidatorPublicKeys>(), bytes);
     let validator_public_keys = any::unpack<ValidatorPublicKeys>(bytes_serialized);
     validator_public_keys
 }
@@ -664,7 +733,7 @@ Error: Unknown certificate threshold type.
 Implementation
 
 
-
public fun public_key_to_bytes(pk: ValidatorPublicKeys): vector<u8>{
+
public fun public_key_to_bytes(pk: ValidatorPublicKeys): vector<u8> {
     // bcs deserialization
     bcs::to_bytes<ValidatorPublicKeys>(&pk)
 }
@@ -689,7 +758,7 @@ Error: Unknown certificate threshold type.
 Implementation
 
 
-
public fun get_network_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{
+
public fun get_network_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey {
     pk.network_key
 }
 
@@ -713,7 +782,7 @@ Error: Unknown certificate threshold type. Implementation -
public fun get_supra_bls_multi_sig_pub_key(pk: &ValidatorPublicKeys): bls12381::PublicKey{
+
public fun get_supra_bls_multi_sig_pub_key(pk: &ValidatorPublicKeys): bls12381::PublicKey {
     pk.supra_keys.bls_multisig_key
 }
 
@@ -737,7 +806,7 @@ Error: Unknown certificate threshold type. Implementation -
public fun get_supra_cg_key(pk: &ValidatorPublicKeys): class_groups::CGPublicKey{
+
public fun get_supra_cg_key(pk: &ValidatorPublicKeys): class_groups::CGPublicKey {
     pk.supra_keys.class_group_key
 }
 
@@ -761,13 +830,230 @@ Error: Unknown certificate threshold type. Implementation -
public fun get_supra_ed_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{
+
public fun get_supra_ed_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey {
     pk.supra_keys.ed25519_key
 }
 
+ + + + +## Function `replace_static_keys` + +Overwrites the four static keys of target (network_key, bls_multisig_key, class_group_key, +ed25519_key) with those from source, leaving the DKG-managed BLS threshold key fields of +target untouched. Used by stake::rotate_consensus_key so that an operator key rotation +only changes the static keys and cannot clobber the threshold keys written by the DKG via +stake::set_dkg_output_keys. + + +
public fun replace_static_keys(target: &mut validator_public_keys::ValidatorPublicKeys, source: &validator_public_keys::ValidatorPublicKeys)
+
+ + + +
+Implementation + + +
public fun replace_static_keys(
+    target: &mut ValidatorPublicKeys, source: &ValidatorPublicKeys
+) {
+    target.network_key = source.network_key;
+    target.supra_keys.bls_multisig_key = source.supra_keys.bls_multisig_key;
+    target.supra_keys.class_group_key = source.supra_keys.class_group_key;
+    target.supra_keys.ed25519_key = source.supra_keys.ed25519_key;
+}
+
+ + + +
+ + + +## Function `validate_static_keys` + +Returns true iff the four static (non-DKG) public keys decode to cryptographically valid +keys: the network key, the BLS multisig key, the class-group key and the ed25519 key. + +validator_public_keys_from_bytes reconstructs each key's raw bytes via BCS without +running the per-key validation natives, so a registration blob can carry malformed keys +(the Validated*/PublicKey types are a misnomer after deserialization). This re-runs +each key's validating constructor on the recovered bytes to reject them. + +The DKG-managed BLS threshold key shares are intentionally not checked: they are absent at +registration and are produced/overwritten by the protocol via stake::set_dkg_output_keys +(which validates them). Proof-of-possession is not verified here either (no PoP is supplied +at registration); only key well-formedness / subgroup membership is checked. + + +
public fun validate_static_keys(pk: &validator_public_keys::ValidatorPublicKeys): bool
+
+ + + +
+Implementation + + +
public fun validate_static_keys(pk: &ValidatorPublicKeys): bool {
+    is_valid_ed25519_key(&pk.network_key)
+        && is_valid_bls12381_key(&pk.supra_keys.bls_multisig_key)
+        && is_valid_cg_key(&pk.supra_keys.class_group_key)
+        && is_valid_ed25519_key(&pk.supra_keys.ed25519_key)
+}
+
+ + + +
+ + + +## Function `is_valid_ed25519_key` + + + +
fun is_valid_ed25519_key(pk: &ed25519::ValidatedPublicKey): bool
+
+ + + +
+Implementation + + +
fun is_valid_ed25519_key(pk: &ed25519::ValidatedPublicKey): bool {
+    option::is_some(
+        &ed25519::new_validated_public_key_from_bytes(
+            ed25519::validated_public_key_to_bytes(pk)
+        )
+    )
+}
+
+ + + +
+ + + +## Function `is_valid_bls12381_key` + + + +
fun is_valid_bls12381_key(pk: &bls12381::PublicKey): bool
+
+ + + +
+Implementation + + +
fun is_valid_bls12381_key(pk: &bls12381::PublicKey): bool {
+    option::is_some(
+        &bls12381::public_key_from_bytes(bls12381::public_key_to_bytes(pk))
+    )
+}
+
+ + + +
+ + + +## Function `is_valid_cg_key` + + + +
fun is_valid_cg_key(pk: &class_groups::CGPublicKey): bool
+
+ + + +
+Implementation + + +
fun is_valid_cg_key(pk: &class_groups::CGPublicKey): bool {
+    option::is_some(
+        &class_groups::public_key_from_bytes(class_groups::public_key_to_bytes(pk))
+    )
+}
+
+ + + +
+ + + +## Function `split_consensus_key_and_pop` + +Splits a submitted consensus key blob into its ValidatorPublicKeys bytes (the prefix) and +the appended BLS12-381 proof-of-possession (the trailing BLS12381_POP_NUM_BYTES bytes). +Operators submit the PoP appended to the key bytes so that the contract can verify it +without a dedicated entry-function parameter (Move forbids changing public signatures). + + +
public fun split_consensus_key_and_pop(blob: vector<u8>): (vector<u8>, vector<u8>)
+
+ + + +
+Implementation + + +
public fun split_consensus_key_and_pop(blob: vector<u8>): (vector<u8>, vector<u8>) {
+    let len = vector::length(&blob);
+    assert!(len >= BLS12381_POP_NUM_BYTES, error::invalid_argument(EINVALID_POP_LENGTH));
+    let pop = vector::trim(&mut blob, len - BLS12381_POP_NUM_BYTES);
+    (blob, pop)
+}
+
+ + + +
+ + + +## Function `verify_bls_multisig_pop` + +Returns true iff pop_bytes is a valid BLS12-381 proof-of-possession for the BLS multisig +key in pk. The multisig key is the only aggregatable (hence rogue-key-attackable) key an +operator submits, so it is the only one that requires a PoP; the class-group key carries its +own ZK PoP (verified by its validate_pubkey_internal native), the ed25519 keys are +non-aggregated, and the BLS threshold shares are produced by the DKG. + + +
public fun verify_bls_multisig_pop(pk: &validator_public_keys::ValidatorPublicKeys, pop_bytes: vector<u8>): bool
+
+ + + +
+Implementation + + +
public fun verify_bls_multisig_pop(
+    pk: &ValidatorPublicKeys, pop_bytes: vector<u8>
+): bool {
+    let pk_bytes = bls12381::public_key_to_bytes(&pk.supra_keys.bls_multisig_key);
+    let pop = bls12381::proof_of_possession_from_bytes(pop_bytes);
+    option::is_some(&bls12381::public_key_from_bytes_with_pop(pk_bytes, &pop))
+}
+
+ + +
@@ -785,8 +1071,12 @@ Error: Unknown certificate threshold type. Implementation -
public fun rotate_supra_bls_threshold_validity_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_validity_key: bls12381::PublicKey) {
-    pk.supra_keys.bls_threshold_validity_certificate_key = option::some(new_bls_threshold_validity_key);
+
public fun rotate_supra_bls_threshold_validity_key(
+    pk: &mut ValidatorPublicKeys, new_bls_threshold_validity_key: bls12381::PublicKey
+) {
+    pk.supra_keys.bls_threshold_validity_certificate_key = option::some(
+        new_bls_threshold_validity_key
+    );
 }
 
@@ -809,8 +1099,12 @@ Error: Unknown certificate threshold type. Implementation -
public fun rotate_supra_bls_threshold_quorum_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_quorum_key: bls12381::PublicKey) {
-    pk.supra_keys.bls_threshold_quorum_certificate_key = option::some(new_bls_threshold_quorum_key);
+
public fun rotate_supra_bls_threshold_quorum_key(
+    pk: &mut ValidatorPublicKeys, new_bls_threshold_quorum_key: bls12381::PublicKey
+) {
+    pk.supra_keys.bls_threshold_quorum_certificate_key = option::some(
+        new_bls_threshold_quorum_key
+    );
 }
 
@@ -833,7 +1127,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun rotate_supra_bls_threshold_unanimous_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+
public fun rotate_supra_bls_threshold_unanimous_key(
+    pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+) {
     pk.supra_keys.bls_threshold_unanimous_certificate_key = option::some(new_key);
 }
 
@@ -857,7 +1153,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun rotate_supra_bls_threshold_bcft_validity_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+
public fun rotate_supra_bls_threshold_bcft_validity_key(
+    pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+) {
     pk.supra_keys.bls_threshold_bcft_validity_certificate_key = option::some(new_key);
 }
 
@@ -881,7 +1179,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun rotate_supra_bls_threshold_bcft_quorum_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+
public fun rotate_supra_bls_threshold_bcft_quorum_key(
+    pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+) {
     pk.supra_keys.bls_threshold_bcft_quorum_certificate_key = option::some(new_key);
 }
 
@@ -905,8 +1205,12 @@ Error: Unknown certificate threshold type. Implementation -
public fun rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
-    pk.supra_keys.bls_threshold_bcft_fallback_view_change_certificate_key = option::some(new_key);
+
public fun rotate_supra_bls_threshold_bcft_fallback_view_change_key(
+    pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+) {
+    pk.supra_keys.bls_threshold_bcft_fallback_view_change_certificate_key = option::some(
+        new_key
+    );
 }
 
@@ -929,7 +1233,9 @@ Error: Unknown certificate threshold type. Implementation -
public fun rotate_supra_bls_threshold_clan_majority_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+
public fun rotate_supra_bls_threshold_clan_majority_key(
+    pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+) {
     pk.supra_keys.bls_threshold_clan_majority_certificate_key = option::some(new_key);
 }
 
@@ -955,7 +1261,9 @@ threshold_type: 0=validity, 1=quorum, 2=unanimous, 3=bcft_validity, 4=bcft_quoru Implementation -
public fun rotate_supra_bls_threshold_key_by_type(pk: &mut ValidatorPublicKeys, threshold_type: u8, new_key: bls12381::PublicKey) {
+
public fun rotate_supra_bls_threshold_key_by_type(
+    pk: &mut ValidatorPublicKeys, threshold_type: u8, new_key: bls12381::PublicKey
+) {
     if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_VALIDITY) {
         rotate_supra_bls_threshold_validity_key(pk, new_key);
     } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_QUORUM) {
@@ -966,7 +1274,8 @@ threshold_type: 0=validity, 1=quorum, 2=unanimous, 3=bcft_validity, 4=bcft_quoru
         rotate_supra_bls_threshold_bcft_validity_key(pk, new_key);
     } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM) {
         rotate_supra_bls_threshold_bcft_quorum_key(pk, new_key);
-    } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE) {
+    } else if (threshold_type
+        == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE) {
         rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk, new_key);
     } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY) {
         rotate_supra_bls_threshold_clan_majority_key(pk, new_key);
diff --git a/aptos-move/framework/supra-framework/sources/stake.move b/aptos-move/framework/supra-framework/sources/stake.move
index bc58805b752..94bb1235525 100644
--- a/aptos-move/framework/supra-framework/sources/stake.move
+++ b/aptos-move/framework/supra-framework/sources/stake.move
@@ -95,6 +95,8 @@ module supra_framework::stake {
     const EDUPLICATE_CONSENSUS_PUBKEY: u64 = 22;
     /// Another validator in the next validator set already uses these network addresses.
     const EDUPLICATE_NETWORK_ADDRESSES: u64 = 23;
+    /// The submitted BLS multisig proof-of-possession does not verify against the multisig key.
+    const EINVALID_PROOF_OF_POSSESSION: u64 = 24;
 
     /// Validator status enum. We can switch to proper enum later once Move supports it.
     const VALIDATOR_STATUS_PENDING_ACTIVE: u64 = 1;
@@ -703,7 +705,43 @@ module supra_framework::stake {
         network_addresses: vector,
         fullnode_addresses: vector
     ) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
-        validate_consensus_public_key(consensus_pubkey);
+        initialize_validator_internal(
+            account,
+            consensus_pubkey,
+            network_addresses,
+            fullnode_addresses,
+            false
+        );
+    }
+
+    /// Initialize a validator during genesis. Identical to `initialize_validator` except that the
+    /// consensus key blob is trusted genesis output and therefore carries no operator
+    /// proof-of-possession (mirrors `rotate_consensus_key` / `rotate_consensus_key_genesis`).
+    public(friend) fun initialize_validator_genesis(
+        account: &signer,
+        consensus_pubkey: vector,
+        network_addresses: vector,
+        fullnode_addresses: vector
+    ) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
+        initialize_validator_internal(
+            account,
+            consensus_pubkey,
+            network_addresses,
+            fullnode_addresses,
+            true
+        );
+    }
+
+    fun initialize_validator_internal(
+        account: &signer,
+        consensus_pubkey: vector,
+        network_addresses: vector,
+        fullnode_addresses: vector,
+        genesis: bool
+    ) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
+        // Verify the keys (and, for operator submissions, the appended BLS multisig PoP) and keep
+        // only the canonical key bytes (any appended PoP is stripped before storage).
+        let consensus_pubkey = validate_consensus_public_key(consensus_pubkey, genesis);
         let account_addr = signer::address_of(account);
         assert_consensus_pubkey_unique_in_next_validator_set(
             account_addr, &consensus_pubkey
@@ -723,42 +761,74 @@ module supra_framework::stake {
         );
     }
 
-    // Checks the public key is valid to prevent rogue-key attacks.
+    // Verifies a submitted consensus key blob and returns the canonical key bytes to store.
     //
-    // The deserializer for the new format currently doesn't offer a way for us to handle
-    // failure, so we expect the new format when the related feature flag has been active
-    // (the flag should only be activated after all validators have migrated to the new
-    // format) and fall back to the new format when deserialization fails before the flag
-    // has been activated.
-    fun validate_consensus_public_key(consensus_pubkey: vector) {
-        if (std::features::supra_validator_identity_v2_enabled()) {
-            // Expect the new format.
-            let _valid_public_key =
-                validator_public_keys::validator_public_keys_from_bytes(consensus_pubkey);
-        } else {
-            // Check the old format.
-            let maybe_valid_public_key =
+    // A legacy consensus key (a bare ed25519 public key) is only accepted before the v2 identity
+    // feature flag is activated; it has no aggregatable BLS key and so carries no proof-of-possession.
+    //
+    // Every other (new-format `ValidatorPublicKeys`) submission -- whether under v2 or via the
+    // pre-v2 early-migration path -- must carry an appended BLS12-381 proof-of-possession for the
+    // BLS multisig key (operator / non-genesis submissions only; genesis output is trusted and
+    // carries no PoP). The multisig key is the only operator-submitted key exposed to rogue-key
+    // attacks (the class-group key carries its own ZK PoP verified by its native, the ed25519 keys
+    // are non-aggregated, and the BLS threshold shares are DKG-produced). We split off and verify
+    // that PoP (see `validator_public_keys::split_consensus_key_and_pop`) and return the key bytes
+    // with the PoP stripped, so the stored key keeps its canonical format. PoP enforcement is tied
+    // to the key format, not the v2 flag, so a key registered during the pre-v2 migration window
+    // cannot skip it.
+    //
+    // Deserialization (`validator_public_keys_from_bytes`) only reconstructs each key's bytes
+    // without running the per-key validation natives, so we also re-validate every static key via
+    // `validate_static_keys` (on-curve / subgroup / valid-encoding checks).
+    fun validate_consensus_public_key(
+        consensus_pubkey: vector, genesis: bool
+    ): vector {
+        // Legacy format (only acceptable before v2): a bare ed25519 key with no aggregatable BLS
+        // key, hence no PoP. Accept and store it unchanged.
+        if (!std::features::supra_validator_identity_v2_enabled()) {
+            let maybe_legacy =
                 ed25519::new_validated_public_key_from_bytes(consensus_pubkey);
+            if (option::is_some(&maybe_legacy)) {
+                return consensus_pubkey
+            };
+        };
 
-            if (option::is_none(&maybe_valid_public_key)) {
-                // Fall back to the new format. This enables validators to register their keys in
-                // the new format before the v2 feature flag is activated, which is safe because the
-                // new keys are a superset of the old and the consensus has logic for maintaining
-                // backwards compatibility.
-                let _valid_public_key =
-                    validator_public_keys::validator_public_keys_from_bytes(
-                        consensus_pubkey
-                    );
-            }
+        // New identity format (v2, or a pre-v2 early-migration submission). Operator (non-genesis)
+        // submissions carry an appended BLS multisig PoP; verify and strip it. Genesis is exempt.
+        let (keys_bytes, maybe_pop) =
+            if (genesis) {
+                (consensus_pubkey, option::none>())
+            } else {
+                let (keys_bytes, pop) =
+                    validator_public_keys::split_consensus_key_and_pop(consensus_pubkey);
+                (keys_bytes, option::some(pop))
+            };
+
+        let valid_public_keys =
+            validator_public_keys::validator_public_keys_from_bytes(keys_bytes);
+
+        if (option::is_some(&maybe_pop)) {
+            assert!(
+                validator_public_keys::verify_bls_multisig_pop(
+                    &valid_public_keys, option::extract(&mut maybe_pop)
+                ),
+                error::invalid_argument(EINVALID_PROOF_OF_POSSESSION)
+            );
         };
+
+        assert!(
+            validator_public_keys::validate_static_keys(&valid_public_keys),
+            error::invalid_argument(EINVALID_PUBLIC_KEY)
+        );
+
+        keys_bytes
     }
 
     /// Aborts if any validator other than `self_addr` in the next validator set
     /// (the union of `active_validators` and `pending_active`) already uses
     /// `consensus_pubkey` as its latest on-chain consensus key.
     fun assert_consensus_pubkey_unique_in_next_validator_set(
-        self_addr: address,
-        consensus_pubkey: &vector
+        self_addr: address, consensus_pubkey: &vector
     ) acquires ValidatorSet, ValidatorConfig {
         let validator_set = borrow_global(@supra_framework);
         assert_consensus_pubkey_unique_in_validator_list(
@@ -793,8 +863,7 @@ module supra_framework::stake {
     /// already uses `network_addresses`. Empty `network_addresses` is treated
     /// as "unset" and skips the check.
     fun assert_network_addresses_unique_in_next_validator_set(
-        self_addr: address,
-        network_addresses: &vector
+        self_addr: address, network_addresses: &vector
     ) acquires ValidatorSet, ValidatorConfig {
         if (vector::is_empty(network_addresses)) { return };
         let validator_set = borrow_global(@supra_framework);
@@ -1066,12 +1135,50 @@ module supra_framework::stake {
             exists(pool_address),
             error::not_found(EVALIDATOR_CONFIG)
         );
-        validate_consensus_public_key(new_consensus_pubkey);
+        // Verify the keys (and, for operator submissions, the appended BLS multisig PoP) and keep
+        // only the canonical key bytes (any appended PoP is stripped before storage/merge).
+        let new_consensus_pubkey =
+            validate_consensus_public_key(new_consensus_pubkey, genesis);
         assert_consensus_pubkey_unique_in_next_validator_set(
             pool_address, &new_consensus_pubkey
         );
         let validator_info = borrow_global_mut(pool_address);
         let old_consensus_pubkey = validator_info.consensus_pubkey;
+
+        // Preserve the DKG-managed BLS threshold keys: an operator rotation must only change the
+        // static keys. We load the current on-chain keys and copy in only the operator-supplied
+        // static keys, leaving the threshold keys (written by `set_dkg_output_keys`) intact.
+        //
+        // The merge is skipped (and the incoming blob stored verbatim, preserving the original
+        // behavior) when there is nothing to preserve or the stored blob cannot be parsed:
+        //  - before v2: the stored blob may be a legacy ed25519 key with no threshold keys;
+        //  - genesis: no DKG threshold keys exist yet;
+        //  - an empty stored key: a validator initialized via `initialize_stake_owner` sets its key
+        //    for the first time here, so there is no prior `ValidatorPublicKeys` to merge into
+        //    (parsing the empty blob would abort).
+        // Under v2 a non-empty stored blob is guaranteed to be a valid `ValidatorPublicKeys` (the
+        // feature is only enabled once all validators have migrated to the new format), and
+        // `validate_consensus_public_key` has already verified the incoming blob, so both
+        // deserializations are safe.
+        let new_consensus_pubkey =
+            if (!genesis
+                && std::features::supra_validator_identity_v2_enabled()
+                && !vector::is_empty(&old_consensus_pubkey)) {
+                let current_keys =
+                    validator_public_keys::validator_public_keys_from_bytes(
+                        old_consensus_pubkey
+                    );
+                let incoming_keys =
+                    validator_public_keys::validator_public_keys_from_bytes(
+                        new_consensus_pubkey
+                    );
+                validator_public_keys::replace_static_keys(
+                    &mut current_keys, &incoming_keys
+                );
+                validator_public_keys::public_key_to_bytes(current_keys)
+            } else {
+                new_consensus_pubkey
+            };
         validator_info.consensus_pubkey = new_consensus_pubkey;
 
         if (std::features::module_event_migration_enabled()) {
@@ -2341,7 +2448,8 @@ module supra_framework::stake {
         should_end_epoch: bool
     ) acquires SupraCoinCapabilities, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
         let pk_bytes = validator_public_keys::public_key_to_bytes(*pk);
-        rotate_consensus_key(operator, pool_address, pk_bytes);
+        // Test fixture: rotate through the genesis (PoP-exempt) path.
+        rotate_consensus_key_genesis(operator, pool_address, pk_bytes);
         join_validator_set(operator, pool_address);
         if (should_end_epoch) {
             end_epoch();
@@ -2427,7 +2535,9 @@ module supra_framework::stake {
         };
 
         let pk_bytes = validator_public_keys::public_key_to_bytes(*public_key);
-        initialize_validator(
+        // Test fixtures register through the genesis (PoP-exempt) path; see
+        // `register_test_validator_with_addresses`.
+        initialize_validator_genesis(
             validator,
             pk_bytes,
             vector::empty(),
@@ -2520,13 +2630,13 @@ module supra_framework::stake {
         validator_public_keys::generate_keys()
     }
 
-    /// Returns the serialized bytes of a freshly generated, unique consensus public key.
-    /// Useful for test helpers that previously hardcoded a shared key but now must
-    /// satisfy the on-chain uniqueness requirement enforced by `rotate_consensus_key`.
+    /// Returns the serialized bytes of a freshly generated, unique consensus public key with a
+    /// valid BLS multisig proof-of-possession appended, i.e. exactly what an operator submits to
+    /// `rotate_consensus_key` under the v2 identity format (which is enabled in the test VM).
     #[test_only]
     public fun generate_unique_consensus_pubkey_bytes(): vector {
-        let (_sk, pk) = generate_identity();
-        validator_public_keys::public_key_to_bytes(pk)
+        let (sk, pk) = generate_identity();
+        validator_public_keys::serialized_keys_with_pop_for_test(&sk, &pk)
     }
 
     #[test_only]
@@ -2541,7 +2651,15 @@ module supra_framework::stake {
             account::create_account_for_test(validator_address);
         };
         let pk_bytes = validator_public_keys::public_key_to_bytes(*public_key);
-        initialize_validator(validator, pk_bytes, network_addresses, fullnode_addresses);
+        // Test fixtures register through the genesis (PoP-exempt) path: they are trusted setup and
+        // do not carry an operator proof-of-possession. PoP enforcement is covered by the dedicated
+        // `initialize_validator` / `rotate_consensus_key` tests.
+        initialize_validator_genesis(
+            validator,
+            pk_bytes,
+            network_addresses,
+            fullnode_addresses
+        );
     }
 
     #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
@@ -2620,9 +2738,10 @@ module supra_framework::stake {
         supra_framework: &signer, validator_1: &signer, validator_2: &signer
     ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
         initialize_for_test(supra_framework);
-        let (_sk_1, pk_1) = generate_identity();
+        let (sk_1, pk_1) = generate_identity();
         let (_sk_2, pk_2) = generate_identity();
-        let pk_1_bytes = validator_public_keys::public_key_to_bytes(pk_1);
+        let pk_1_bytes =
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_1, &pk_1);
         initialize_test_validator(&pk_1, validator_1, 100, true, true);
         initialize_test_validator(&pk_2, validator_2, 100, true, true);
         // validator_2 tries to rotate to validator_1's consensus key - should abort.
@@ -2636,8 +2755,9 @@ module supra_framework::stake {
         initialize_for_test(supra_framework);
         let (_sk, pk) = generate_identity();
         initialize_test_validator(&pk, validator, 100, true, true);
-        let (_sk_new, pk_new) = generate_identity();
-        let pk_new_bytes = validator_public_keys::public_key_to_bytes(pk_new);
+        let (sk_new, pk_new) = generate_identity();
+        let pk_new_bytes =
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_new, &pk_new);
         rotate_consensus_key(validator, signer::address_of(validator), pk_new_bytes);
     }
 
@@ -2646,13 +2766,245 @@ module supra_framework::stake {
         supra_framework: &signer, validator: &signer
     ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
         initialize_for_test(supra_framework);
-        let (_sk, pk) = generate_identity();
-        let pk_bytes = validator_public_keys::public_key_to_bytes(pk);
+        let (sk, pk) = generate_identity();
+        let pk_bytes = validator_public_keys::serialized_keys_with_pop_for_test(
+            &sk, &pk
+        );
         initialize_test_validator(&pk, validator, 100, true, true);
         // Rotating to the same key the validator already holds is a no-op and must not abort.
         rotate_consensus_key(validator, signer::address_of(validator), pk_bytes);
     }
 
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    /// An operator rotation must preserve the DKG-managed BLS threshold keys (written by
+    /// `set_dkg_output_keys`) and only swap the static keys. This holds under the v2 identity format.
+    public entry fun test_rotate_consensus_key_preserves_threshold_keys(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        // v2 is enabled by default in the test VM; this makes the dependency explicit.
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[features::get_supra_validator_identity_v2_feature()],
+            vector[]
+        );
+
+        // Seed a DKG-style threshold key on the validator's initial keys. The fixture registers via
+        // the genesis (PoP-exempt) helper, so the seeded keys are stored as-is. Reuse the multisig
+        // key as a stand-in `bls12381::PublicKey` so the test needs no extra crypto imports.
+        let (_sk, pk) = generate_identity();
+        let threshold_key = validator_public_keys::get_supra_bls_multi_sig_pub_key(&pk);
+        validator_public_keys::rotate_supra_bls_threshold_validity_key(
+            &mut pk, threshold_key
+        );
+        initialize_test_validator(&pk, validator, 100, true, true);
+
+        // Rotate to a fresh static identity whose threshold fields are empty (modelling an operator
+        // rotating from a node that has not yet received the latest DKG keys). The operator submits
+        // the keys with an appended BLS multisig proof-of-possession.
+        let (sk_new, pk_new) = generate_identity();
+        let pk_new_bytes =
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_new, &pk_new);
+        rotate_consensus_key(validator, signer::address_of(validator), pk_new_bytes);
+
+        let (stored_bytes, _net, _fn) =
+            get_validator_config(signer::address_of(validator));
+        let stored =
+            validator_public_keys::validator_public_keys_from_bytes(stored_bytes);
+
+        // The DKG threshold key survived the operator rotation (0 = validity certificate type).
+        let preserved =
+            validator_public_keys::get_supra_bls_threshold_key_by_type(&stored, 0);
+        assert!(option::is_some(&preserved), 3001);
+        assert!(option::extract(&mut preserved) == threshold_key, 3002);
+
+        // The static keys were actually rotated to `pk_new`'s.
+        assert!(
+            validator_public_keys::get_supra_ed_key(&stored)
+                == validator_public_keys::get_supra_ed_key(&pk_new),
+            3003
+        );
+        assert!(
+            validator_public_keys::get_network_key(&stored)
+                == validator_public_keys::get_network_key(&pk_new),
+            3004
+        );
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    #[expected_failure(abort_code = 0x1000b, location = Self)]
+    /// Registration must reject a consensus public key blob that deserializes but carries a
+    /// malformed static key (here, an empty network key), even when its appended BLS multisig PoP
+    /// is valid. Validated under the v2 identity format.
+    public entry fun test_initialize_validator_rejects_invalid_consensus_pubkey(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
+        initialize_for_test(supra_framework);
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[features::get_supra_validator_identity_v2_feature()],
+            vector[]
+        );
+        let invalid_pubkey =
+            validator_public_keys::serialized_keys_with_invalid_network_key_and_pop_for_test();
+        initialize_validator(validator, invalid_pubkey, b"net", b"fn");
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    #[expected_failure(abort_code = 0x10018, location = Self)]
+    /// Under v2, an operator key submission whose appended BLS multisig PoP does not verify must be
+    /// rejected with `EINVALID_PROOF_OF_POSSESSION` (24 = 0x18).
+    public entry fun test_initialize_validator_rejects_invalid_pop(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
+        initialize_for_test(supra_framework);
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[features::get_supra_validator_identity_v2_feature()],
+            vector[]
+        );
+        // Well-formed keys, but the appended PoP is generated from a different (freshly generated)
+        // secret, so it does not match pk's multisig key.
+        let (_sk, pk) = generate_identity();
+        let (other_sk, _other_pk) = generate_identity();
+        let blob =
+            validator_public_keys::serialized_keys_with_pop_for_test(&other_sk, &pk);
+        initialize_validator(validator, blob, b"net", b"fn");
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    /// Under v2, a correctly pop-appended operator submission succeeds and the stored key is the
+    /// canonical `ValidatorPublicKeys` with the PoP stripped (parses with no trailing bytes).
+    public entry fun test_rotate_consensus_key_accepts_valid_pop_and_strips_it(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        initialize_test_validator(&pk, validator, 100, true, true);
+
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[features::get_supra_validator_identity_v2_feature()],
+            vector[]
+        );
+
+        let (sk_new, pk_new) = generate_identity();
+        let blob =
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_new, &pk_new);
+        rotate_consensus_key(validator, signer::address_of(validator), blob);
+
+        // The stored key is the canonical (PoP-stripped) ValidatorPublicKeys for pk_new.
+        let (stored_bytes, _net, _fn) =
+            get_validator_config(signer::address_of(validator));
+        let stored =
+            validator_public_keys::validator_public_keys_from_bytes(stored_bytes);
+        assert!(
+            validator_public_keys::get_supra_ed_key(&stored)
+                == validator_public_keys::get_supra_ed_key(&pk_new),
+            6001
+        );
+        assert!(
+            stored_bytes == validator_public_keys::public_key_to_bytes(pk_new),
+            6002
+        );
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    /// Genesis registration is PoP-exempt: under v2, `initialize_validator_genesis` accepts a blob
+    /// with no appended PoP and stores it verbatim.
+    public entry fun test_initialize_validator_genesis_skips_pop(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, ValidatorSet, ValidatorConfig {
+        initialize_for_test(supra_framework);
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[features::get_supra_validator_identity_v2_feature()],
+            vector[]
+        );
+        let (_sk, pk) = generate_identity();
+        let pk_bytes = validator_public_keys::public_key_to_bytes(pk);
+        let validator_address = signer::address_of(validator);
+        if (!account::exists_at(validator_address)) {
+            account::create_account_for_test(validator_address);
+        };
+        initialize_validator_genesis(validator, pk_bytes, b"net", b"fn");
+        let (stored_bytes, _net, _fn) = get_validator_config(validator_address);
+        assert!(stored_bytes == pk_bytes, 7001);
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    /// Pre-v2 migration fallback: an operator new-format submission must still carry a valid BLS
+    /// multisig PoP, which the contract verifies and strips, storing the canonical key. PoP
+    /// enforcement is tied to the key format, not the v2 flag.
+    public entry fun test_rotate_consensus_key_fallback_verifies_pop(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        initialize_test_validator(&pk, validator, 100, true, true);
+
+        // Disable v2 to exercise the pre-v2 migration fallback.
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[],
+            vector[features::get_supra_validator_identity_v2_feature()]
+        );
+
+        let (sk_new, pk_new) = generate_identity();
+        let blob =
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_new, &pk_new);
+        rotate_consensus_key(validator, signer::address_of(validator), blob);
+
+        let (stored_bytes, _net, _fn) =
+            get_validator_config(signer::address_of(validator));
+        assert!(stored_bytes == validator_public_keys::public_key_to_bytes(pk_new), 8001);
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    #[expected_failure(abort_code = 0x10018, location = Self)]
+    /// Pre-v2 migration fallback: a new-format submission with a non-matching PoP is rejected with
+    /// `EINVALID_PROOF_OF_POSSESSION` (24 = 0x18), exactly as under v2.
+    public entry fun test_rotate_consensus_key_fallback_rejects_invalid_pop(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        initialize_test_validator(&pk, validator, 100, true, true);
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[],
+            vector[features::get_supra_validator_identity_v2_feature()]
+        );
+        // PoP generated from a different secret, so it does not match pk_new's multisig key.
+        let (_sk_new, pk_new) = generate_identity();
+        let (other_sk, _other_pk) = generate_identity();
+        let blob =
+            validator_public_keys::serialized_keys_with_pop_for_test(&other_sk, &pk_new);
+        rotate_consensus_key(validator, signer::address_of(validator), blob);
+    }
+
+    #[test(supra_framework = @supra_framework, validator = @0x123)]
+    /// Pre-v2 migration fallback: a bare 32-byte ed25519 consensus key (legacy format) has no
+    /// aggregatable BLS key, so it is accepted without a PoP and stored unchanged.
+    public entry fun test_rotate_consensus_key_fallback_accepts_legacy_ed25519(
+        supra_framework: &signer, validator: &signer
+    ) acquires AllowedValidators, SupraCoinCapabilities, OwnerCapability, StakePool, ValidatorConfig, ValidatorPerformance, ValidatorSet, ValidatorFees {
+        initialize_for_test(supra_framework);
+        let (_sk, pk) = generate_identity();
+        initialize_test_validator(&pk, validator, 100, true, true);
+        features::change_feature_flags_for_testing(
+            supra_framework,
+            vector[],
+            vector[features::get_supra_validator_identity_v2_feature()]
+        );
+        let (_legacy_sk, legacy_pk) = ed25519::generate_keys();
+        let legacy_bytes = ed25519::validated_public_key_to_bytes(&legacy_pk);
+        rotate_consensus_key(validator, signer::address_of(validator), legacy_bytes);
+        let (stored_bytes, _net, _fn) =
+            get_validator_config(signer::address_of(validator));
+        assert!(stored_bytes == legacy_bytes, 8101);
+    }
+
     #[test(supra_framework = @supra_framework, validator_1 = @0x123, validator_2 = @0x234)]
     #[expected_failure(abort_code = 0x10017, location = Self)]
     public entry fun test_update_network_addresses_rejects_duplicate(
@@ -2668,7 +3020,10 @@ module supra_framework::stake {
         // validator_2 registers with empty addresses then tries to claim validator_1's net address.
         initialize_test_validator(&pk_2, validator_2, 100, true, true);
         update_network_and_fullnode_addresses(
-            validator_2, signer::address_of(validator_2), b"net-1", b"fn-2"
+            validator_2,
+            signer::address_of(validator_2),
+            b"net-1",
+            b"fn-2"
         );
     }
 
@@ -2689,7 +3044,10 @@ module supra_framework::stake {
         join_validator_set(validator_2, validator_2_address);
         // Clearing to empty is always allowed (empty == "unset / non-functional").
         update_network_and_fullnode_addresses(
-            validator_2, validator_2_address, vector::empty(), vector::empty()
+            validator_2,
+            validator_2_address,
+            vector::empty(),
+            vector::empty()
         );
     }
 
@@ -2705,7 +3063,10 @@ module supra_framework::stake {
         join_validator_set(validator, validator_address);
         // Re-setting the same address on self must be a no-op, not an abort.
         update_network_and_fullnode_addresses(
-            validator, validator_address, b"net-self", b"fn-self"
+            validator,
+            validator_address,
+            b"net-self",
+            b"fn-self"
         );
     }
 
@@ -3406,9 +3767,15 @@ module supra_framework::stake {
         assert!(validator_config_2.config.validator_index == 1, 5);
 
         // Validator 1 rotates consensus key. Validator 2 leaves. Validator 3 joins.
-        let (_sk_1b, pk_1b) = generate_identity();
+        let (sk_1b, pk_1b) = generate_identity();
+        // `pk_1b_bytes` is the canonical (PoP-stripped) form the contract stores; the submission
+        // carries the appended PoP.
         let pk_1b_bytes = validator_public_keys::public_key_to_bytes(pk_1b);
-        rotate_consensus_key(validator_1, validator_1_address, pk_1b_bytes);
+        rotate_consensus_key(
+            validator_1,
+            validator_1_address,
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_1b, &pk_1b)
+        );
         leave_validator_set(validator_2, validator_2_address);
         join_validator_set(validator_3, validator_3_address);
         // Validator 2 is not effectively removed until next epoch.
@@ -3512,9 +3879,15 @@ module supra_framework::stake {
         assert_validator_state(pool_address, 0, 0, 0, 0, 0);
 
         // Operator can separately rotate consensus key.
-        let (_sk_new, pk_new) = generate_identity();
+        let (sk_new, pk_new) = generate_identity();
+        // `pk_new_bytes` is the canonical (PoP-stripped) form the contract stores; the submission
+        // carries the appended PoP.
         let pk_new_bytes = validator_public_keys::public_key_to_bytes(pk_new);
-        rotate_consensus_key(validator, pool_address, pk_new_bytes);
+        rotate_consensus_key(
+            validator,
+            pool_address,
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_new, &pk_new)
+        );
         let validator_config = borrow_global(pool_address);
         assert!(validator_config.consensus_pubkey == pk_new_bytes, 2);
 
@@ -3958,8 +4331,9 @@ module supra_framework::stake {
 
         // Initialize validator config.
         let validator_address = signer::address_of(validator);
-        let (_sk_new, pk_new) = generate_identity();
-        let pk_new_bytes = validator_public_keys::public_key_to_bytes(pk_new);
+        let (sk_new, pk_new) = generate_identity();
+        let pk_new_bytes =
+            validator_public_keys::serialized_keys_with_pop_for_test(&sk_new, &pk_new);
         rotate_consensus_key(validator, validator_address, pk_new_bytes);
 
         // Join the validator set with enough stake. This now wouldn't fail since the validator config already exists.
diff --git a/aptos-move/framework/supra-framework/sources/validator_public_keys.move b/aptos-move/framework/supra-framework/sources/validator_public_keys.move
index f6dba388b6b..d22e1f1a562 100644
--- a/aptos-move/framework/supra-framework/sources/validator_public_keys.move
+++ b/aptos-move/framework/supra-framework/sources/validator_public_keys.move
@@ -8,6 +8,7 @@ module supra_framework::validator_public_keys {
     use aptos_std::ed25519;
     use aptos_std::type_info;
     use supra_std::class_groups;
+    use std::vector;
     #[test_only]
     use aptos_std::bls12381::public_key_with_pop_to_normal;
     #[test_only]
@@ -37,30 +38,88 @@ module supra_framework::validator_public_keys {
 
     /// Error: Unknown certificate threshold type.
     const EUNKNOWN_THRESHOLD_TYPE: u64 = 1;
+    /// Error: A consensus key blob is too short to contain an appended BLS proof-of-possession.
+    const EINVALID_POP_LENGTH: u64 = 2;
 
     /// Internal tag wrapper
-    struct CertificateThresholdType has copy, drop, store { tag: u8 }
-
-    public fun validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_VALIDITY } }
-    public fun quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_QUORUM } }
-    public fun unanimous_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS } }
-    public fun bcft_validity_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY } }
-    public fun bcft_quorum_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM } }
-    public fun bcft_fallback_view_change_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE } }
-    public fun clan_majority_certificate_type(): CertificateThresholdType { CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY } }
-     
-    public fun is_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_VALIDITY }
-    public fun is_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_QUORUM }
-    public fun is_unanimous_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS }
-    public fun is_bcft_validity_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY }
-    public fun is_bcft_quorum_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM }
-    public fun is_bcft_fallback_view_change_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE }
-    public fun is_clan_majority_certificate_type(t: &CertificateThresholdType): bool { t.tag == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY }
+    struct CertificateThresholdType has copy, drop, store {
+        tag: u8
+    }
+
+    public fun validity_certificate_type(): CertificateThresholdType {
+        CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_VALIDITY }
+    }
+
+    public fun quorum_certificate_type(): CertificateThresholdType {
+        CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_QUORUM }
+    }
+
+    public fun unanimous_certificate_type(): CertificateThresholdType {
+        CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS }
+    }
+
+    public fun bcft_validity_certificate_type(): CertificateThresholdType {
+        CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY }
+    }
+
+    public fun bcft_quorum_certificate_type(): CertificateThresholdType {
+        CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM }
+    }
+
+    public fun bcft_fallback_view_change_certificate_type(): CertificateThresholdType {
+        CertificateThresholdType {
+            tag: CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE
+        }
+    }
+
+    public fun clan_majority_certificate_type(): CertificateThresholdType {
+        CertificateThresholdType { tag: CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY }
+    }
+
+    public fun is_validity_certificate_type(t: &CertificateThresholdType): bool {
+        t.tag == CERTIFICATE_THRESHOLD_TYPE_VALIDITY
+    }
+
+    public fun is_quorum_certificate_type(t: &CertificateThresholdType): bool {
+        t.tag == CERTIFICATE_THRESHOLD_TYPE_QUORUM
+    }
+
+    public fun is_unanimous_certificate_type(
+        t: &CertificateThresholdType
+    ): bool {
+        t.tag == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS
+    }
+
+    public fun is_bcft_validity_certificate_type(
+        t: &CertificateThresholdType
+    ): bool {
+        t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY
+    }
+
+    public fun is_bcft_quorum_certificate_type(
+        t: &CertificateThresholdType
+    ): bool {
+        t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM
+    }
+
+    public fun is_bcft_fallback_view_change_certificate_type(
+        t: &CertificateThresholdType
+    ): bool {
+        t.tag == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE
+    }
+
+    public fun is_clan_majority_certificate_type(
+        t: &CertificateThresholdType
+    ): bool {
+        t.tag == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY
+    }
 
     /// The size of a serialized ed25519 public key, in bytes.
     const ED25519_PUBLIC_KEY_NUM_BYTES: u64 = 32;
     /// The size of a serialized bls12381 G1 public key, in bytes.
     const BLS12381_G1_PUBLIC_KEY_NUM_BYTES: u64 = 48;
+    /// The size of a serialized bls12381 proof-of-possession (a G2 signature), in bytes.
+    const BLS12381_POP_NUM_BYTES: u64 = 96;
 
     /// InternalPublicKeys consists of:
     /// 1. bls multisig key
@@ -77,7 +136,7 @@ module supra_framework::validator_public_keys {
         bls_threshold_bcft_fallback_view_change_certificate_key: option::Option,
         bls_threshold_clan_majority_certificate_key: option::Option,
         class_group_key: class_groups::CGPublicKey,
-        ed25519_key: ed25519::ValidatedPublicKey,
+        ed25519_key: ed25519::ValidatedPublicKey
     }
 
     /// ValidatorPublicKeys consists of:
@@ -85,7 +144,7 @@ module supra_framework::validator_public_keys {
     /// 2. supra's internal keys
     struct ValidatorPublicKeys has copy, drop, store {
         network_key: ed25519::ValidatedPublicKey,
-        supra_keys: InternalPublicKeys,
+        supra_keys: InternalPublicKeys
     }
 
     #[test_only]
@@ -101,68 +160,194 @@ module supra_framework::validator_public_keys {
         supra_bls_threshold_bcft_fallback_view_change_key: option::Option,
         supra_bls_threshold_clan_majority_key: option::Option,
         cg_key: class_groups::SecretKey,
-        supra_ed_key: ed25519::SecretKey,
+        supra_ed_key: ed25519::SecretKey
     }
 
     public fun validator_public_keys_from_bytes(bytes: vector): ValidatorPublicKeys {
         // bcs deserialization
-        let bytes_serialized = any::new(type_info::type_name(), bytes);
+        let bytes_serialized =
+            any::new(type_info::type_name(), bytes);
         let validator_public_keys = any::unpack(bytes_serialized);
         validator_public_keys
     }
 
-    public fun public_key_to_bytes(pk: ValidatorPublicKeys): vector{
+    public fun public_key_to_bytes(pk: ValidatorPublicKeys): vector {
         // bcs deserialization
         bcs::to_bytes(&pk)
     }
 
-    public fun get_network_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{
+    public fun get_network_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey {
         pk.network_key
     }
 
-    public fun get_supra_bls_multi_sig_pub_key(pk: &ValidatorPublicKeys): bls12381::PublicKey{
+    public fun get_supra_bls_multi_sig_pub_key(pk: &ValidatorPublicKeys): bls12381::PublicKey {
         pk.supra_keys.bls_multisig_key
     }
 
-    public fun get_supra_cg_key(pk: &ValidatorPublicKeys): class_groups::CGPublicKey{
+    public fun get_supra_cg_key(pk: &ValidatorPublicKeys): class_groups::CGPublicKey {
         pk.supra_keys.class_group_key
     }
 
-    public fun get_supra_ed_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey{
+    public fun get_supra_ed_key(pk: &ValidatorPublicKeys): ed25519::ValidatedPublicKey {
         pk.supra_keys.ed25519_key
     }
 
-    public fun rotate_supra_bls_threshold_validity_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_validity_key: bls12381::PublicKey) {
-        pk.supra_keys.bls_threshold_validity_certificate_key = option::some(new_bls_threshold_validity_key);
+    /// Overwrites the four static keys of `target` (network_key, bls_multisig_key, class_group_key,
+    /// ed25519_key) with those from `source`, leaving the DKG-managed BLS threshold key fields of
+    /// `target` untouched. Used by `stake::rotate_consensus_key` so that an operator key rotation
+    /// only changes the static keys and cannot clobber the threshold keys written by the DKG via
+    /// `stake::set_dkg_output_keys`.
+    public fun replace_static_keys(
+        target: &mut ValidatorPublicKeys, source: &ValidatorPublicKeys
+    ) {
+        target.network_key = source.network_key;
+        target.supra_keys.bls_multisig_key = source.supra_keys.bls_multisig_key;
+        target.supra_keys.class_group_key = source.supra_keys.class_group_key;
+        target.supra_keys.ed25519_key = source.supra_keys.ed25519_key;
+    }
+
+    /// Returns true iff the four static (non-DKG) public keys decode to cryptographically valid
+    /// keys: the network key, the BLS multisig key, the class-group key and the ed25519 key.
+    ///
+    /// `validator_public_keys_from_bytes` reconstructs each key's raw bytes via BCS without
+    /// running the per-key validation natives, so a registration blob can carry malformed keys
+    /// (the `Validated*`/`PublicKey` types are a misnomer after deserialization). This re-runs
+    /// each key's validating constructor on the recovered bytes to reject them.
+    ///
+    /// The DKG-managed BLS threshold key shares are intentionally not checked: they are absent at
+    /// registration and are produced/overwritten by the protocol via `stake::set_dkg_output_keys`
+    /// (which validates them). Proof-of-possession is not verified here either (no PoP is supplied
+    /// at registration); only key well-formedness / subgroup membership is checked.
+    public fun validate_static_keys(pk: &ValidatorPublicKeys): bool {
+        is_valid_ed25519_key(&pk.network_key)
+            && is_valid_bls12381_key(&pk.supra_keys.bls_multisig_key)
+            && is_valid_cg_key(&pk.supra_keys.class_group_key)
+            && is_valid_ed25519_key(&pk.supra_keys.ed25519_key)
+    }
+
+    fun is_valid_ed25519_key(pk: &ed25519::ValidatedPublicKey): bool {
+        option::is_some(
+            &ed25519::new_validated_public_key_from_bytes(
+                ed25519::validated_public_key_to_bytes(pk)
+            )
+        )
+    }
+
+    fun is_valid_bls12381_key(pk: &bls12381::PublicKey): bool {
+        option::is_some(
+            &bls12381::public_key_from_bytes(bls12381::public_key_to_bytes(pk))
+        )
+    }
+
+    fun is_valid_cg_key(pk: &class_groups::CGPublicKey): bool {
+        option::is_some(
+            &class_groups::public_key_from_bytes(class_groups::public_key_to_bytes(pk))
+        )
+    }
+
+    /// Splits a submitted consensus key blob into its `ValidatorPublicKeys` bytes (the prefix) and
+    /// the appended BLS12-381 proof-of-possession (the trailing `BLS12381_POP_NUM_BYTES` bytes).
+    /// Operators submit the PoP appended to the key bytes so that the contract can verify it
+    /// without a dedicated entry-function parameter (Move forbids changing public signatures).
+    public fun split_consensus_key_and_pop(blob: vector): (vector, vector) {
+        let len = vector::length(&blob);
+        assert!(len >= BLS12381_POP_NUM_BYTES, error::invalid_argument(EINVALID_POP_LENGTH));
+        let pop = vector::trim(&mut blob, len - BLS12381_POP_NUM_BYTES);
+        (blob, pop)
+    }
+
+    /// Returns true iff `pop_bytes` is a valid BLS12-381 proof-of-possession for the BLS multisig
+    /// key in `pk`. The multisig key is the only aggregatable (hence rogue-key-attackable) key an
+    /// operator submits, so it is the only one that requires a PoP; the class-group key carries its
+    /// own ZK PoP (verified by its `validate_pubkey_internal` native), the ed25519 keys are
+    /// non-aggregated, and the BLS threshold shares are produced by the DKG.
+    public fun verify_bls_multisig_pop(
+        pk: &ValidatorPublicKeys, pop_bytes: vector
+    ): bool {
+        let pk_bytes = bls12381::public_key_to_bytes(&pk.supra_keys.bls_multisig_key);
+        let pop = bls12381::proof_of_possession_from_bytes(pop_bytes);
+        option::is_some(&bls12381::public_key_from_bytes_with_pop(pk_bytes, &pop))
     }
 
-    public fun rotate_supra_bls_threshold_quorum_key(pk: &mut ValidatorPublicKeys, new_bls_threshold_quorum_key: bls12381::PublicKey) {
-        pk.supra_keys.bls_threshold_quorum_certificate_key = option::some(new_bls_threshold_quorum_key);
+    #[test_only]
+    /// Returns the BLS threshold key for the given threshold type, used by tests to assert that
+    /// the DKG-managed threshold keys survive an operator key rotation.
+    public fun get_supra_bls_threshold_key_by_type(
+        pk: &ValidatorPublicKeys, threshold_type: u8
+    ): option::Option {
+        if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_VALIDITY) {
+            pk.supra_keys.bls_threshold_validity_certificate_key
+        } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_QUORUM) {
+            pk.supra_keys.bls_threshold_quorum_certificate_key
+        } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_UNANIMOUS) {
+            pk.supra_keys.bls_threshold_unanimous_certificate_key
+        } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_VALIDITY) {
+            pk.supra_keys.bls_threshold_bcft_validity_certificate_key
+        } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM) {
+            pk.supra_keys.bls_threshold_bcft_quorum_certificate_key
+        } else if (threshold_type
+            == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE) {
+            pk.supra_keys.bls_threshold_bcft_fallback_view_change_certificate_key
+        } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY) {
+            pk.supra_keys.bls_threshold_clan_majority_certificate_key
+        } else {
+            abort error::invalid_argument(EUNKNOWN_THRESHOLD_TYPE)
+        }
+    }
+
+    public fun rotate_supra_bls_threshold_validity_key(
+        pk: &mut ValidatorPublicKeys, new_bls_threshold_validity_key: bls12381::PublicKey
+    ) {
+        pk.supra_keys.bls_threshold_validity_certificate_key = option::some(
+            new_bls_threshold_validity_key
+        );
     }
 
-    public fun rotate_supra_bls_threshold_unanimous_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    public fun rotate_supra_bls_threshold_quorum_key(
+        pk: &mut ValidatorPublicKeys, new_bls_threshold_quorum_key: bls12381::PublicKey
+    ) {
+        pk.supra_keys.bls_threshold_quorum_certificate_key = option::some(
+            new_bls_threshold_quorum_key
+        );
+    }
+
+    public fun rotate_supra_bls_threshold_unanimous_key(
+        pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+    ) {
         pk.supra_keys.bls_threshold_unanimous_certificate_key = option::some(new_key);
     }
 
-    public fun rotate_supra_bls_threshold_bcft_validity_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    public fun rotate_supra_bls_threshold_bcft_validity_key(
+        pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+    ) {
         pk.supra_keys.bls_threshold_bcft_validity_certificate_key = option::some(new_key);
     }
 
-    public fun rotate_supra_bls_threshold_bcft_quorum_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    public fun rotate_supra_bls_threshold_bcft_quorum_key(
+        pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+    ) {
         pk.supra_keys.bls_threshold_bcft_quorum_certificate_key = option::some(new_key);
     }
 
-    public fun rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
-        pk.supra_keys.bls_threshold_bcft_fallback_view_change_certificate_key = option::some(new_key);
+    public fun rotate_supra_bls_threshold_bcft_fallback_view_change_key(
+        pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+    ) {
+        pk.supra_keys.bls_threshold_bcft_fallback_view_change_certificate_key = option::some(
+            new_key
+        );
     }
 
-    public fun rotate_supra_bls_threshold_clan_majority_key(pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey) {
+    public fun rotate_supra_bls_threshold_clan_majority_key(
+        pk: &mut ValidatorPublicKeys, new_key: bls12381::PublicKey
+    ) {
         pk.supra_keys.bls_threshold_clan_majority_certificate_key = option::some(new_key);
     }
 
     /// Rotate a threshold key based on the threshold type tag.
     /// threshold_type: 0=validity, 1=quorum, 2=unanimous, 3=bcft_validity, 4=bcft_quorum, 5=bcft_fallback_view_change, 6=clan_majority
-    public fun rotate_supra_bls_threshold_key_by_type(pk: &mut ValidatorPublicKeys, threshold_type: u8, new_key: bls12381::PublicKey) {
+    public fun rotate_supra_bls_threshold_key_by_type(
+        pk: &mut ValidatorPublicKeys, threshold_type: u8, new_key: bls12381::PublicKey
+    ) {
         if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_VALIDITY) {
             rotate_supra_bls_threshold_validity_key(pk, new_key);
         } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_QUORUM) {
@@ -173,7 +358,8 @@ module supra_framework::validator_public_keys {
             rotate_supra_bls_threshold_bcft_validity_key(pk, new_key);
         } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_QUORUM) {
             rotate_supra_bls_threshold_bcft_quorum_key(pk, new_key);
-        } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE) {
+        } else if (threshold_type
+            == CERTIFICATE_THRESHOLD_TYPE_BCFT_FALLBACK_VIEW_CHANGE) {
             rotate_supra_bls_threshold_bcft_fallback_view_change_key(pk, new_key);
         } else if (threshold_type == CERTIFICATE_THRESHOLD_TYPE_CLAN_MAJORITY) {
             rotate_supra_bls_threshold_clan_majority_key(pk, new_key);
@@ -186,11 +372,12 @@ module supra_framework::validator_public_keys {
     /// Generates validator key pair for testing.
     public fun generate_keys(): (ValidatorSecretKeys, ValidatorPublicKeys) {
         let (network_key_sk, network_key_pk) = ed25519::generate_keys();
-        let (supra_bls12381_multi_sig_sk, supra_bls12381_multi_sig_pk) = bls12381::generate_keys();
+        let (supra_bls12381_multi_sig_sk, supra_bls12381_multi_sig_pk) =
+            bls12381::generate_keys();
         let (supra_cg_sk, supra_cg_pk) = class_groups::generate_keys();
         let (supra_ed_key_sk, supra_ed_key_pk) = ed25519::generate_keys();
 
-        let sk = ValidatorSecretKeys{
+        let sk = ValidatorSecretKeys {
             network_key: network_key_sk,
             supra_bls_multi_sig_bls_key: supra_bls12381_multi_sig_sk,
             supra_bls_threshold_validity_key: option::none(),
@@ -201,13 +388,15 @@ module supra_framework::validator_public_keys {
             supra_bls_threshold_bcft_fallback_view_change_key: option::none(),
             supra_bls_threshold_clan_majority_key: option::none(),
             cg_key: supra_cg_sk,
-            supra_ed_key: supra_ed_key_sk,
+            supra_ed_key: supra_ed_key_sk
         };
 
         let pk = ValidatorPublicKeys {
             network_key: network_key_pk,
-            supra_keys: InternalPublicKeys{
-                bls_multisig_key: public_key_with_pop_to_normal(&supra_bls12381_multi_sig_pk),
+            supra_keys: InternalPublicKeys {
+                bls_multisig_key: public_key_with_pop_to_normal(
+                    &supra_bls12381_multi_sig_pk
+                ),
                 bls_threshold_validity_certificate_key: option::none(),
                 bls_threshold_quorum_certificate_key: option::none(),
                 bls_threshold_unanimous_certificate_key: option::none(),
@@ -216,13 +405,57 @@ module supra_framework::validator_public_keys {
                 bls_threshold_bcft_fallback_view_change_certificate_key: option::none(),
                 bls_threshold_clan_majority_certificate_key: option::none(),
                 class_group_key: supra_cg_pk,
-                ed25519_key: supra_ed_key_pk,
-            },
+                ed25519_key: supra_ed_key_pk
+            }
         };
 
         (sk, pk)
     }
 
+    #[test_only]
+    /// Serializes `pk` and appends a valid BLS multisig proof-of-possession generated from `sk`,
+    /// producing the exact blob an operator submits to `stake::rotate_consensus_key` under the v2
+    /// identity format.
+    public fun serialized_keys_with_pop_for_test(
+        sk: &ValidatorSecretKeys, pk: &ValidatorPublicKeys
+    ): vector {
+        let pop = bls12381::generate_proof_of_possession(&sk.supra_bls_multi_sig_bls_key);
+        let blob = public_key_to_bytes(*pk);
+        vector::append(&mut blob, bls12381::proof_of_possession_to_bytes(&pop));
+        blob
+    }
+
+    #[test]
+    fun test_verify_bls_multisig_pop() {
+        let (sk, pk) = validator_public_keys::generate_keys();
+        // A PoP generated from the matching secret verifies.
+        let pop = bls12381::generate_proof_of_possession(&sk.supra_bls_multi_sig_bls_key);
+        assert!(
+            verify_bls_multisig_pop(&pk, bls12381::proof_of_possession_to_bytes(&pop)),
+            5001
+        );
+        // A PoP for a different key does not.
+        let (other_sk, _other_pk) = validator_public_keys::generate_keys();
+        let other_pop =
+            bls12381::generate_proof_of_possession(&other_sk.supra_bls_multi_sig_bls_key);
+        assert!(
+            !verify_bls_multisig_pop(&pk, bls12381::proof_of_possession_to_bytes(&other_pop)),
+            5002
+        );
+    }
+
+    #[test]
+    fun test_split_consensus_key_and_pop_roundtrip() {
+        let (sk, pk) = validator_public_keys::generate_keys();
+        let keys_bytes = public_key_to_bytes(pk);
+        let blob = serialized_keys_with_pop_for_test(&sk, &pk);
+        let (split_keys, split_pop) = split_consensus_key_and_pop(blob);
+        // The prefix is exactly the original key bytes...
+        assert!(split_keys == keys_bytes, 5101);
+        // ...and the suffix is a PoP that verifies against the multisig key.
+        assert!(verify_bls_multisig_pop(&pk, split_pop), 5102);
+    }
+
     #[test]
     fun test_serde_roundtrip() {
         // Generate full keypair
@@ -254,4 +487,87 @@ module supra_framework::validator_public_keys {
         let ed1 = get_supra_ed_key(&parsed);
         assert!(ed0 == ed1, 1004);
     }
+
+    #[test]
+    fun test_replace_static_keys_preserves_threshold_keys() {
+        // `target` carries a DKG-style threshold key; `source` carries only static keys (its
+        // threshold fields are `none`, modelling an operator's rotation payload).
+        let (_sk_a, pk_a) = validator_public_keys::generate_keys();
+        let (_sk_b, pk_b) = validator_public_keys::generate_keys();
+
+        let (_t_sk, t_pop_pk) = bls12381::generate_keys();
+        let threshold_key = public_key_with_pop_to_normal(&t_pop_pk);
+        rotate_supra_bls_threshold_validity_key(&mut pk_a, threshold_key);
+
+        replace_static_keys(&mut pk_a, &pk_b);
+
+        // The four static keys now equal those of `source`.
+        assert!(get_network_key(&pk_a) == get_network_key(&pk_b), 2001);
+        assert!(
+            get_supra_bls_multi_sig_pub_key(&pk_a)
+                == get_supra_bls_multi_sig_pub_key(&pk_b),
+            2002
+        );
+        assert!(get_supra_cg_key(&pk_a) == get_supra_cg_key(&pk_b), 2003);
+        assert!(get_supra_ed_key(&pk_a) == get_supra_ed_key(&pk_b), 2004);
+
+        // The DKG-managed threshold key was preserved (it was `none` in `source`).
+        let preserved =
+            get_supra_bls_threshold_key_by_type(
+                &pk_a, CERTIFICATE_THRESHOLD_TYPE_VALIDITY
+            );
+        assert!(option::is_some(&preserved), 2005);
+        assert!(option::extract(&mut preserved) == threshold_key, 2006);
+    }
+
+    #[test_only]
+    /// Rewrites a serialized `ValidatorPublicKeys` blob so its network key is malformed (replaced
+    /// with an empty byte vector) while keeping the BCS framing intact, so it still deserializes via
+    /// `validator_public_keys_from_bytes` yet fails `validate_static_keys`.
+    fun with_empty_network_key(bytes: vector): vector {
+        // The network key is the first BCS field: a 32-byte vector encoded as `0x20 ++ 32 bytes`.
+        // Replace it with an empty vector (`0x00`) and keep the remaining fields untouched.
+        let corrupt = vector::empty();
+        vector::push_back(&mut corrupt, 0);
+        let i = 33; // skip the original length byte (0x20) plus the 32 key bytes.
+        let len = vector::length(&bytes);
+        while (i < len) {
+            vector::push_back(&mut corrupt, *vector::borrow(&bytes, i));
+            i = i + 1;
+        };
+        corrupt
+    }
+
+    #[test_only]
+    /// Returns a malformed (empty network key) `ValidatorPublicKeys` blob with no appended PoP. Used
+    /// to exercise `validate_static_keys` directly.
+    public fun serialized_keys_with_invalid_network_key_for_test(): vector {
+        let (_sk, pk) = validator_public_keys::generate_keys();
+        with_empty_network_key(public_key_to_bytes(pk))
+    }
+
+    #[test_only]
+    /// Returns a malformed (empty network key) blob with a *valid* BLS multisig PoP appended -- the
+    /// shape an operator submits under v2. PoP verification passes (the multisig key is untouched),
+    /// so `stake::validate_consensus_public_key` reaches and fails the static-key check, exercising
+    /// the full registration path.
+    public fun serialized_keys_with_invalid_network_key_and_pop_for_test(): vector {
+        let (sk, pk) = validator_public_keys::generate_keys();
+        let corrupt = with_empty_network_key(public_key_to_bytes(pk));
+        let pop = bls12381::generate_proof_of_possession(&sk.supra_bls_multi_sig_bls_key);
+        vector::append(&mut corrupt, bls12381::proof_of_possession_to_bytes(&pop));
+        corrupt
+    }
+
+    #[test]
+    fun test_validate_static_keys_rejects_malformed_key() {
+        // Freshly generated keys are valid.
+        let (_sk, pk) = validator_public_keys::generate_keys();
+        assert!(validate_static_keys(&pk), 4001);
+
+        // A blob carrying a malformed (empty) network key deserializes but fails validation.
+        let corrupt = serialized_keys_with_invalid_network_key_for_test();
+        let bad = validator_public_keys_from_bytes(corrupt);
+        assert!(!validate_static_keys(&bad), 4002);
+    }
 }
diff --git a/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move b/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move
index 7bc68221d48..9fec6ac9f86 100644
--- a/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move
+++ b/aptos-move/framework/supra-framework/tests/delegation_pool_integration_tests.move
@@ -14,6 +14,7 @@ module supra_framework::delegation_pool_integration_tests {
     use supra_framework::reconfiguration;
     use supra_framework::pbo_delegation_pool as dp;
     use supra_framework::timestamp;
+    use supra_framework::validator_public_keys;
 
     #[test_only]
     const EPOCH_DURATION: u64 = 60;
@@ -36,9 +37,6 @@ module supra_framework::delegation_pool_integration_tests {
     #[test_only]
     const MODULE_EVENT: u64 = 26;
 
-    #[test_only]
-    const CONSENSUS_KEY_1: vector = x"20ed28c35dc60a6c9629a7eb0a8dfa815c85c6cf2cedc9e43314cc26f02d741dc430b40c7239278dae17d68d06950d51ce61c2c16c032ceea62c9715611be7f577f48525ad610432bb5d13fa5826fc07c6650000000000000080090192000000000000007bb0b330cbdcec145d2671ef2532bb7a856a5155c66d7ad89ef2cb65e854fc08a5d43cd159a7abc77adfee05e764ec9abdfc133db8e8621398dcbe53db1069de56405f02a1347d5399502fe849b44cfa673ad95bdbf33b417f3f8e4fa854b87b4a60eff6426b277d6036ffc0cfcdd25c971d53c2b612ed1df66f33eff839c0064ac16d7e04650d13984b08b2f9e7bb240fe3ff920000000000000014a973f3c74f41cecc3c596a125835264d72803ba1ef9c9270fa2228e8f8442889f20ddfffc60bc073758c3fd13a29219ad4532c512d2a97c3a8421dedfa41e4d8d9ffaa3581049a65a64f57ea533ab831c88527bb3d7ce46b6eebd6fef6d3303cf7716455381c74da2bcbfc3e02de2e5fadb014ed4f7ecf6b62a4ce6c0db90b91f084512a18be5cb8892b1615a7bb7ef35d0192000000000000008c49908494889c8d07e0b6f0cb6871aaf7e97506476d0a63530ce06b58928225a4292dff8ffaccd4f217fd65c2afbac848ac5d5957d15aa83fb8d2f261d85ddf4f16feee49d07f274dd421f84862bd73634925c41d2b470066d751732cc4f9630e886df15e63f962959c8f765b48434b6124fe051c2a02ba91bd94a7d8fc3cf7240ffba508ff73d8bb95a8ba661fa59ed9c9b8030000000000000192000000000000007bb0b330cbdcec145d2671ef2532bb7a856a5155c66d7ad89ef2cb65e854fc08a5d43cd159a7abc77adfee05e764ec9abdfc133db8e8621398dcbe53db1069de56405f02a1347d5399502fe849b44cfa673ad95bdbf33b417f3f8e4fa854b87b4a60eff6426b277d6036ffc0cfcdd25c971d53c2b612ed1df66f33eff839c0064ac16d7e04650d13984b08b2f9e7bb240fe3ff920000000000000014a973f3c74f41cecc3c596a125835264d72803ba1ef9c9270fa2228e8f8442889f20ddfffc60bc073758c3fd13a29219ad4532c512d2a97c3a8421dedfa41e4d8d9ffaa3581049a65a64f57ea533ab831c88527bb3d7ce46b6eebd6fef6d3303cf7716455381c74da2bcbfc3e02de2e5fadb014ed4f7ecf6b62a4ce6c0db90b91f084512a18be5cb8892b1615a7bb7ef35d0192000000000000008c49908494889c8d07e0b6f0cb6871aaf7e97506476d0a63530ce06b58928225a4292dff8ffaccd4f217fd65c2afbac848ac5d5957d15aa83fb8d2f261d85ddf4f16feee49d07f274dd421f84862bd73634925c41d2b470066d751732cc4f9630e886df15e63f962959c8f765b48434b6124fe051c2a02ba91bd94a7d8fc3cf7240ffba508ff73d8bb95a8ba661fa59ed9c9b8030000000000000120000000000000000da685763a376d42546959f3e2d96ff46256cd3e539dd458b800c9d0daf4d981019c00000000000000a529edcfd13d9f5014b4e2fab134f833d266876a0a0fbcf3577ef87ced2656924e235d4a6f48169d0c6b1fd4d77b27f36b0eda1e78fb1691894e077333e7f278444a3e6de72685de03564bcf61466567e34c79279fcdccc42c2354e4c0a836e785f909656badb5950ebcf77a1ef9a3680818abe674760bc09888a446b96d9765779222970aaeb804abaa939c4225c474c2bc925be1d24648c6298d69208e695ae5888320393ef041be5f42d0f2eaac6036daffb8373eb80ad275fcc2b9";
-
     #[test_only]
     public fun initialize_for_test(supra_framework: &signer) {
         initialize_for_test_custom(
@@ -810,8 +808,11 @@ module supra_framework::delegation_pool_integration_tests {
         stake::assert_validator_state(validator_2_address, 100 * ONE_SUPRA, 0, 0, 0, 1);
 
         // Validator 1 rotates consensus key. Validator 2 leaves. Validator 3 joins.
-        let (_sk_1b, _, _) = generate_identity();
-        stake::rotate_consensus_key(validator_1, validator_1_address, CONSENSUS_KEY_1);
+        stake::rotate_consensus_key(
+            validator_1,
+            validator_1_address,
+            stake::generate_unique_consensus_pubkey_bytes()
+        );
         stake::leave_validator_set(validator_2, validator_2_address);
         stake::join_validator_set(validator_3, validator_3_address);
         // Validator 2 is not effectively removed until next epoch.
@@ -878,11 +879,14 @@ module supra_framework::delegation_pool_integration_tests {
         assert!(coin::balance(signer::address_of(validator)) == 101 * ONE_SUPRA, 1);
         stake::assert_validator_state(pool_address, 0, 0, 0, 0, 0);
 
-        // Operator can separately rotate consensus key.
-        let (_sk_new, _, _) = generate_identity();
-        stake::rotate_consensus_key(validator, pool_address, CONSENSUS_KEY_1);
+        // Operator can separately rotate consensus key. The submission carries an appended BLS
+        // multisig PoP, which the contract verifies and strips before storing the canonical key.
+        let new_consensus_key = stake::generate_unique_consensus_pubkey_bytes();
+        stake::rotate_consensus_key(validator, pool_address, new_consensus_key);
         let (consensus_pubkey, _, _) = stake::get_validator_config(pool_address);
-        assert!(consensus_pubkey == CONSENSUS_KEY_1, 2);
+        let (expected_stored, _pop) =
+            validator_public_keys::split_consensus_key_and_pop(new_consensus_key);
+        assert!(consensus_pubkey == expected_stored, 2);
 
         // Operator can update network and fullnode addresses.
         stake::update_network_and_fullnode_addresses(validator, pool_address, b"1", b"2");
diff --git a/crates/aptos-telemetry-service/src/validator_cache.rs b/crates/aptos-telemetry-service/src/validator_cache.rs
index 53afae31d1a..a4fbcd7dc4d 100644
--- a/crates/aptos-telemetry-service/src/validator_cache.rs
+++ b/crates/aptos-telemetry-service/src/validator_cache.rs
@@ -199,7 +199,7 @@ mod tests {
         let validator_info = ValidatorInfo::new(
             PeerId::random(),
             10,
-            ValidatorConfig::new(keypair.public_key, vec![0, 0], vec![0, 0], 2),
+            ValidatorConfig::legacy_new_do_not_use(keypair.public_key, vec![0, 0], vec![0, 0], 2),
         );
         let validator_set = ValidatorSet::new(vec![validator_info]);
 
@@ -242,7 +242,7 @@ mod tests {
         let validator_info = ValidatorInfo::new(
             PeerId::random(),
             10,
-            ValidatorConfig::new(
+            ValidatorConfig::legacy_new_do_not_use(
                 keypair.public_key,
                 bcs::to_bytes(&vec![NetworkAddress::from_str("/dns/a5f3d921730874389bb2f66275f163a5-8f14ad5b5e992c1c.elb.ap-southeast-1.amazonaws.com/tcp/6180/noise-ik/0xc5edf62233096df793b554e1013b07c83d01b3cf50c14ac83a0a7e0cfe340426/handshake/0").unwrap()]).unwrap(),
                 bcs::to_bytes(&vec![NetworkAddress::from_str("/dns/fullnode0.testnet.aptoslabs.com/tcp/6182/noise-ik/0xea19ab47ed9191865f15d85d751ed0663205c0b2f0f465714b1947c023715973/handshake/0").unwrap()]).unwrap(),
diff --git a/crates/aptos/src/node/mod.rs b/crates/aptos/src/node/mod.rs
index 1aaa6916a00..1ca112de70e 100644
--- a/crates/aptos/src/node/mod.rs
+++ b/crates/aptos/src/node/mod.rs
@@ -902,7 +902,7 @@ impl TryFrom<&ValidatorInfo> for ValidatorInfoSummary {
     fn try_from(info: &ValidatorInfo) -> Result {
         let config = info.config();
         let config = ValidatorConfig {
-            consensus_public_key: config.consensus_public_key().to_bytes().to_vec(),
+            consensus_public_key: config.legacy_consensus_public_key_do_not_use().to_bytes().to_vec(),
             validator_network_addresses: config.validator_network_addresses.clone(),
             fullnode_network_addresses: config.fullnode_network_addresses.clone(),
             validator_index: config.validator_index,
@@ -921,7 +921,7 @@ impl From<&ValidatorInfoSummary> for ValidatorInfo {
         ValidatorInfo::new(
             summary.account_address,
             summary.consensus_voting_power,
-            aptos_types::validator_config::ValidatorConfig::new(
+            aptos_types::validator_config::ValidatorConfig::legacy_new_do_not_use(
                 PublicKey::from_encoded_string(&config.consensus_public_key).unwrap(),
                 bcs::to_bytes(&config.validator_network_addresses).unwrap(),
                 bcs::to_bytes(&config.fullnode_network_addresses).unwrap(),
diff --git a/execution/executor/tests/storage_integration_test.rs b/execution/executor/tests/storage_integration_test.rs
index 1e413c1d056..3c68b4f7c29 100644
--- a/execution/executor/tests/storage_integration_test.rs
+++ b/execution/executor/tests/storage_integration_test.rs
@@ -97,11 +97,11 @@ fn test_reconfiguration() {
             .payload()
             .next()
             .unwrap()
-            .consensus_public_key(),
-        &ValidatorConfig::fetch_move_resource(&db_state_view, &validator_account)
+            .legacy_consensus_public_key_do_not_use(),
+        ValidatorConfig::fetch_move_resource(&db_state_view, &validator_account)
             .unwrap()
             .unwrap()
-            .consensus_public_key
+            .legacy_consensus_public_key_do_not_use()
     );
 
     // txn1 = give the validator some money so they can send a tx
diff --git a/network/discovery/src/validator_set.rs b/network/discovery/src/validator_set.rs
index 6f8305950ae..31507209bea 100644
--- a/network/discovery/src/validator_set.rs
+++ b/network/discovery/src/validator_set.rs
@@ -252,7 +252,7 @@ mod tests {
         let validator = ValidatorInfo::new(
             peer_id,
             0,
-            ValidatorConfig::new(
+            ValidatorConfig::legacy_new_do_not_use(
                 consensus_pubkey,
                 validator_encoded_addresses,
                 fullnode_encoded_addresses,
diff --git a/types/src/validator_config.rs b/types/src/validator_config.rs
index 65baf9ed0ea..cc79c18418c 100644
--- a/types/src/validator_config.rs
+++ b/types/src/validator_config.rs
@@ -35,6 +35,8 @@ impl MoveResource for ValidatorOperatorConfigResource {}
 #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
 #[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
 pub struct ValidatorConfig {
+    /// This is a BCS serialized `ValidatorPublicKeys` (see the smr-moonshot type).
+    /// We haven't renamed the field because it is exposed to users.
     consensus_public_key: Vec,
     /// This is an bcs serialized `Vec`
     pub validator_network_addresses: Vec,
@@ -44,7 +46,9 @@ pub struct ValidatorConfig {
 }
 
 impl ValidatorConfig {
-    pub fn new(
+    /// Deprecated function kept to avoid making changes to aptos-core. Must not be used in smr-moonshot.
+    /// TODO: Remove when unused aptos-core code is removed.
+    pub fn legacy_new_do_not_use(
         consensus_public_key: ed25519::PublicKey,
         validator_network_addresses: Vec,
         fullnode_network_addresses: Vec,
@@ -58,11 +62,13 @@ impl ValidatorConfig {
         }
     }
 
-    pub fn consensus_key_raw(&self) -> Vec {
-        self.consensus_public_key.clone()
+    pub fn public_keys(&self) -> &Vec {
+        &self.consensus_public_key
     }
 
-    pub fn consensus_public_key(&self) -> Ed25519PublicKey {
+    /// Deprecated function kept to avoid making changes to aptos-core. Must not be used in smr-moonshot.
+    /// TODO: Remove when unused aptos-core code is removed.
+    pub fn legacy_consensus_public_key_do_not_use(&self) -> Ed25519PublicKey {
         let keys = bcs::from_bytes::(&self.consensus_public_key);
         if let Ok(keys) = keys {
             let ed_key = Ed25519PublicKey::try_from(keys.supra_keys().ed25519_key().as_slice())
diff --git a/types/src/validator_info.rs b/types/src/validator_info.rs
index 999ec011df9..2e9723be959 100644
--- a/types/src/validator_info.rs
+++ b/types/src/validator_info.rs
@@ -60,7 +60,7 @@ impl ValidatorInfo {
         validator_index: u64,
     ) -> Self {
         let addr = NetworkAddress::mock();
-        let config = ValidatorConfig::new(
+        let config = ValidatorConfig::legacy_new_do_not_use(
             consensus_public_key,
             bcs::to_bytes(&vec![addr.clone()]).unwrap(),
             bcs::to_bytes(&vec![addr]).unwrap(),
@@ -80,14 +80,10 @@ impl ValidatorInfo {
         &self.account_address
     }
 
-    /// Returns the key for validating signed messages from this validator
-    pub fn consensus_public_key(&self) -> ed25519::PublicKey {
-        self.config.consensus_public_key()
-    }
-
-    /// Returns the key for validating signed messages from this validator
-    pub fn consensus_key_bytes(&self) -> ed25519::PublicKey {
-        self.config.consensus_public_key()
+    /// Deprecated function kept to avoid making changes to aptos-core. Must not be used in smr-moonshot.
+    /// TODO: Remove when unused aptos-core code is removed.
+    pub fn legacy_consensus_public_key_do_not_use(&self) -> ed25519::PublicKey {
+        self.config.legacy_consensus_public_key_do_not_use()
     }
 
     /// Returns the voting power for this validator
diff --git a/types/src/validator_verifier.rs b/types/src/validator_verifier.rs
index a13f7b69575..9672b98092b 100644
--- a/types/src/validator_verifier.rs
+++ b/types/src/validator_verifier.rs
@@ -476,7 +476,7 @@ impl From<&ValidatorSet> for ValidatorVerifier {
                     info.config().validator_index,
                     ValidatorConsensusInfo::new(
                         info.account_address,
-                        info.consensus_public_key().clone(),
+                        info.legacy_consensus_public_key_do_not_use().clone(),
                         info.consensus_voting_power(),
                     ),
                 )

From f4b0749fb253874ebc6daa2bf973a7745b6661c0 Mon Sep 17 00:00:00 2001
From: Dhaval Purohit 
Date: Mon, 22 Jun 2026 16:55:41 +0530
Subject: [PATCH 26/31] few more test cases fixed

---
 aptos-move/e2e-move-tests/src/harness.rs      |  3 +--
 .../e2e-move-tests/src/tests/fee_payer.rs     | 16 ++++++++++------
 .../src/tests/keyless_feature_gating.rs       |  8 ++++----
 .../e2e-move-tests/src/tests/scripts.rs       |  4 ++--
 .../src/tests/storage_refund.rs               |  2 +-
 .../src/tests/transaction_context.rs          |  6 +++---
 .../src/tests/automation_registration.rs      | 19 +++++++++----------
 7 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/aptos-move/e2e-move-tests/src/harness.rs b/aptos-move/e2e-move-tests/src/harness.rs
index 3b79a435a4d..b347006dabd 100644
--- a/aptos-move/e2e-move-tests/src/harness.rs
+++ b/aptos-move/e2e-move-tests/src/harness.rs
@@ -56,7 +56,7 @@ use std::{
 // Code representing successful transaction, used for run_block_in_parts_and_check
 pub const SUCCESS: u64 = 0;
 
-const DEFAULT_GAS_UNIT_PRICE: u64 = 100;
+const DEFAULT_GAS_UNIT_PRICE: u64 = 100000;
 
 static CACHED_BUILT_PACKAGES: Lazy>>>> =
     Lazy::new(|| Mutex::new(HashMap::new()));
@@ -252,7 +252,6 @@ impl MoveHarness {
     /// Runs a signed transaction. On success, applies the write set.
     pub fn run_raw(&mut self, txn: SignedTransaction) -> TransactionOutput {
         let output = self.executor.execute_transaction(txn);
-        println!("{:?}", output);
         if matches!(output.status(), TransactionStatus::Keep(_)) {
             self.executor.apply_write_set(output.write_set());
             self.executor.append_events(output.events().to_vec());
diff --git a/aptos-move/e2e-move-tests/src/tests/fee_payer.rs b/aptos-move/e2e-move-tests/src/tests/fee_payer.rs
index c60b5f8b4b2..bf0a77a5c82 100644
--- a/aptos-move/e2e-move-tests/src/tests/fee_payer.rs
+++ b/aptos-move/e2e-move-tests/src/tests/fee_payer.rs
@@ -93,7 +93,7 @@ fn test_existing_account_with_fee_payer_aborts() {
 
     let output = h.run_raw(transaction);
     // Alice has an insufficient balance, trying to 1 when she has 0.
-    assert_abort!(output.status(), 65540);
+    assert_abort!(output.status(), 65542);
 
     let alice_after = h.read_aptos_balance(alice.address());
     let bob_after = h.read_aptos_balance(bob.address());
@@ -341,9 +341,13 @@ fn test_account_not_exist_move_abort_with_fee_payer_out_of_gas() {
 
 #[test]
 fn test_account_not_exist_with_fee_payer_without_create_account() {
-    let mut h = MoveHarness::new_with_features(vec![FeatureFlag::GAS_PAYER_ENABLED], vec![
-        FeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_V1_CREATION,
-    ]);
+    // Note: (DP)
+    // Both this feature needs to be enabled as default account feature is disabled.
+    // If we turn on default account feature then it is fine if sponsored feature is disabled.
+    let mut h = MoveHarness::new_with_features(vec![
+        FeatureFlag::GAS_PAYER_ENABLED, 
+        FeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_V1_CREATION
+    ], vec![]);
 
     let alice = Account::new();
     let bob = h.new_account_at(AccountAddress::from_hex_literal("0xb0b").unwrap());
@@ -359,8 +363,8 @@ fn test_account_not_exist_with_fee_payer_without_create_account() {
         .fee_payer(bob.clone())
         .payload(payload)
         .sequence_number(0)
-        .max_gas_amount(1_000_000)
-        .gas_unit_price(1)
+        .max_gas_amount(1_000)
+        .gas_unit_price(100_000)
         .sign_fee_payer();
 
     let output = h.run_raw(transaction);
diff --git a/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs b/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs
index 27ef2f6049d..5fc23f89910 100644
--- a/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs
+++ b/aptos-move/e2e-move-tests/src/tests/keyless_feature_gating.rs
@@ -493,8 +493,8 @@ fn run_jwk_and_config_script(h: &mut MoveHarness) -> Account {
             TransactionArgument::U64(config.max_exp_horizon_secs),
         ]))
         .sequence_number(h.sequence_number(core_resources.address()))
-        .max_gas_amount(1_500_000)
-        .gas_unit_price(1)
+        .max_gas_amount(15_000_000)
+        .gas_unit_price(100_000)
         .sign();
 
     // NOTE: We cannot write the Configuration and Groth16Verification key via MoveHarness::set_resource
@@ -573,7 +573,7 @@ fn federated_keyless_install_jwk(
         ))
         .sequence_number(h.sequence_number(jwk_owner_account.address()))
         .max_gas_amount(1_000_000)
-        .gas_unit_price(1)
+        .gas_unit_price(100_000)
         .sign();
 
     // NOTE: We cannot write the Configuration and Groth16Verification key via MoveHarness::set_resource
@@ -605,7 +605,7 @@ fn run_upgrade_vk_script(h: &mut MoveHarness, core_resources: Account, vk: Groth
         ]))
         .sequence_number(h.sequence_number(core_resources.address()))
         .max_gas_amount(2_500_000)
-        .gas_unit_price(1)
+        .gas_unit_price(100_000)
         .sign();
 
     // NOTE: We cannot write the Groth16Verification key via MoveHarness::set_resource
diff --git a/aptos-move/e2e-move-tests/src/tests/scripts.rs b/aptos-move/e2e-move-tests/src/tests/scripts.rs
index b6a94c0ad68..d11c687c1d1 100644
--- a/aptos-move/e2e-move-tests/src/tests/scripts.rs
+++ b/aptos-move/e2e-move-tests/src/tests/scripts.rs
@@ -99,7 +99,7 @@ fn test_script_with_object_parameter() {
         .script(script.clone())
         .sequence_number(13)
         .max_gas_amount(1_000_000)
-        .gas_unit_price(1)
+        .gas_unit_price(100_000)
         .sign();
 
     let status = h.run(txn);
@@ -111,7 +111,7 @@ fn test_script_with_object_parameter() {
         .script(script.clone())
         .sequence_number(14)
         .max_gas_amount(1_000_000)
-        .gas_unit_price(1)
+        .gas_unit_price(100_000)
         .sign();
 
     let status = h.run(txn);
diff --git a/aptos-move/e2e-move-tests/src/tests/storage_refund.rs b/aptos-move/e2e-move-tests/src/tests/storage_refund.rs
index 80fb3e67dc5..0b466423f80 100644
--- a/aptos-move/e2e-move-tests/src/tests/storage_refund.rs
+++ b/aptos-move/e2e-move-tests/src/tests/storage_refund.rs
@@ -93,7 +93,7 @@ fn test_refunds() {
     assert_result(&mut h, &user_acc, "destroy_collection", vec![], 0, false);
 }
 
-const LEEWAY: u64 = 2000;
+const LEEWAY: u64 = 2000000; // need to 1000x as per gas price
 
 fn read_slot_fee_from_gas_schedule(h: &MoveHarness) -> u64 {
     let slot_fee = h
diff --git a/aptos-move/e2e-move-tests/src/tests/transaction_context.rs b/aptos-move/e2e-move-tests/src/tests/transaction_context.rs
index 300a362fde4..b329b658eaa 100644
--- a/aptos-move/e2e-move-tests/src/tests/transaction_context.rs
+++ b/aptos-move/e2e-move-tests/src/tests/transaction_context.rs
@@ -254,7 +254,7 @@ fn test_transaction_context_max_gas_amount() {
     let account = setup(&mut harness);
 
     let max_gas_amount = call_get_max_gas_amount_from_native_txn_context(&mut harness, &account);
-    assert_eq!(max_gas_amount, 2000000);
+    assert_eq!(max_gas_amount, 100000000);
 }
 
 #[test]
@@ -343,7 +343,7 @@ fn test_transaction_context_secondary_signers() {
     let mut harness = new_move_harness();
 
     let alice = setup(&mut harness);
-    let bob = harness.new_account_with_balance_and_sequence_number(1000000, 0);
+    let bob = harness.new_account_with_balance_and_sequence_number(100_000_000_000, 0);
 
     let fun: MemberId = str::parse(
         "0x1::transaction_context_test::store_secondary_signers_from_native_txn_context_multi",
@@ -366,7 +366,7 @@ fn test_transaction_context_secondary_signers() {
         .payload(payload)
         .sequence_number(harness.sequence_number(alice.address()))
         .max_gas_amount(1_000_000)
-        .gas_unit_price(1)
+        .gas_unit_price(100_000)
         .sign_multi_agent();
 
     let output = harness.run_raw(transaction);
diff --git a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
index e49ad225b2f..fa9ae725a99 100644
--- a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
+++ b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
@@ -97,7 +97,7 @@ impl AutomationRegistrationTestContext {
         root.rotate_key(private_key, public_key);
 
         // Prepare automation registration transaction sender
-        let txn_sender = executor.create_raw_account_data(100_000_000_000, 0);
+        let txn_sender = executor.create_raw_account_data(200_000_000_000, 0);
         executor.add_account_data(&txn_sender);
 
         let multisig_account_data = Self::create_multisig_account_data(&mut executor);
@@ -111,8 +111,8 @@ impl AutomationRegistrationTestContext {
 
     fn create_multisig_account_data(executor: &mut FakeExecutor) -> MultisigAccountData {
         // Prepare multisig_account for system task registration
-        let multisig_owner1 = executor.create_raw_account_data(1_000_000_000, 0);
-        let multisig_owner2 = executor.create_raw_account_data(1_000_000_000, 0);
+        let multisig_owner1 = executor.create_raw_account_data(100_000_000_000, 0);
+        let multisig_owner2 = executor.create_raw_account_data(100_000_000_000, 0);
         executor.add_account_data(&multisig_owner1);
         executor.add_account_data(&multisig_owner2);
         let multisig_address = create_multisig_account_address(
@@ -132,8 +132,8 @@ impl AutomationRegistrationTestContext {
             // The SUP#3 gas-schedule update raised storage fees ~1000x, so creating the
             // multisig account (and its new state slots) now costs ~1.7M gas units at this
             // gas unit price. Budget enough headroom for it.
-            .max_gas_amount(2_000_000)
-            .gas_unit_price(100)
+            .max_gas_amount(1_000_000)
+            .gas_unit_price(100_000)
             .payload(create_multisig_payload)
             .sequence_number(0)
             .sign();
@@ -142,6 +142,7 @@ impl AutomationRegistrationTestContext {
         let transfer_txn = multisig_owner1
             .account()
             .transaction()
+            .gas_unit_price(100_000)
             .max_gas_amount(1000)
             .payload(aptos_stdlib::supra_account_transfer(
                 multisig_address,
@@ -235,8 +236,7 @@ impl AutomationRegistrationTestContext {
             .transaction()
             .payload(automation_txn)
             .sequence_number(seq_num)
-            .gas_unit_price(1)
-            .max_gas_amount(55000000)
+            .gas_unit_price(100_000)
             .sign()
     }
 
@@ -265,8 +265,7 @@ impl AutomationRegistrationTestContext {
             .transaction()
             .payload(automation_txn)
             .sequence_number(seq_num)
-            .max_gas_amount(55000000)
-            .gas_unit_price(1)
+            .gas_unit_price(100_000)
             .sign()
     }
 
@@ -727,7 +726,7 @@ fn check_task_retrieval_performance() {
             inner_entry_function.clone(),
             expiration_time,
             25,
-            100,
+            100_000,
             automation_fee_cap,
         );
         let output = test_context.execute_and_apply(automation_txn);

From d8dd86ce5478094dd909d05bcceb13e0837641a7 Mon Sep 17 00:00:00 2001
From: Dhaval Purohit 
Date: Tue, 23 Jun 2026 19:13:30 +0530
Subject: [PATCH 27/31] Fixed integration issue

---
 consensus/src/epoch_manager.rs              |  2 +-
 crates/aptos-genesis/src/lib.rs             |  2 +-
 crates/aptos-genesis/src/mainnet.rs         |  1 -
 crates/aptos/src/lib.rs                     |  1 -
 dkg/src/agg_trx_producer.rs                 |  2 +-
 dkg/src/dkg_manager/mod.rs                  |  5 ++--
 dkg/src/epoch_manager.rs                    |  2 +-
 dkg/src/transcript_aggregation/mod.rs       |  2 +-
 dkg/src/types.rs                            |  2 +-
 types/src/contract_event.rs                 | 32 ++++++++++++++++++++-
 vm-validator/src/mocks/mock_vm_validator.rs |  5 ++--
 11 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/consensus/src/epoch_manager.rs b/consensus/src/epoch_manager.rs
index 581b5f9bb53..90b2f23f59d 100644
--- a/consensus/src/epoch_manager.rs
+++ b/consensus/src/epoch_manager.rs
@@ -84,7 +84,7 @@ use aptos_safety_rules::{
 };
 use aptos_types::{
     account_address::AccountAddress,
-    aptos_dkg::{real_dkg::maybe_dk_from_bls_sk, DKGState, DKGTrait, DefaultDKG},
+    dkg::{real_dkg::maybe_dk_from_bls_sk, DKGState, DKGTrait, DefaultDKG},
     epoch_change::EpochChangeProof,
     epoch_state::EpochState,
     jwks::SupportedOIDCProviders,
diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs
index 48267f847eb..5a4a87ba755 100644
--- a/crates/aptos-genesis/src/lib.rs
+++ b/crates/aptos-genesis/src/lib.rs
@@ -85,7 +85,7 @@ pub struct GenesisInfo {
     pub randomness_config_override: Option,
     pub jwk_consensus_config_override: Option,
     pub automation_registry_config: Option,
-    pub leader_ban_registry_config: Option
+    pub leader_ban_registry_config: Option,
     pub initial_jwks: Vec,
     pub keyless_groth16_vk: Option,
 }
diff --git a/crates/aptos-genesis/src/mainnet.rs b/crates/aptos-genesis/src/mainnet.rs
index 9fa535abb7a..68589f3a9ed 100644
--- a/crates/aptos-genesis/src/mainnet.rs
+++ b/crates/aptos-genesis/src/mainnet.rs
@@ -19,7 +19,6 @@ use aptos_types::{
     transaction::Transaction,
     waypoint::Waypoint,
 };
-use aptos_types::on_chain_config::AutomationRegistryConfig;
 use aptos_vm::aptos_vm::AptosVMBlockExecutor;
 use aptos_vm_genesis::{AccountBalance, EmployeePool, ValidatorWithCommissionRate};
 
diff --git a/crates/aptos/src/lib.rs b/crates/aptos/src/lib.rs
index cd618b668c5..aec2f8e97dd 100644
--- a/crates/aptos/src/lib.rs
+++ b/crates/aptos/src/lib.rs
@@ -17,7 +17,6 @@ pub mod supra_specific;
 pub mod test;
 pub mod update;
 pub mod workspace;
-pub mod supra_specific;
 
 use crate::common::{
     types::{CliCommand, CliResult, CliTypedResult},
diff --git a/dkg/src/agg_trx_producer.rs b/dkg/src/agg_trx_producer.rs
index 4d760e5a85f..bbe537cea5b 100644
--- a/dkg/src/agg_trx_producer.rs
+++ b/dkg/src/agg_trx_producer.rs
@@ -7,7 +7,7 @@ use crate::{
 use aptos_channels::aptos_channel::Sender;
 use aptos_logger::info;
 use aptos_reliable_broadcast::ReliableBroadcast;
-use aptos_types::{aptos_dkg::DKGTrait, epoch_state::EpochState};
+use aptos_types::{dkg::DKGTrait, epoch_state::EpochState};
 use futures::future::AbortHandle;
 use futures_util::future::Abortable;
 use move_core_types::account_address::AccountAddress;
diff --git a/dkg/src/dkg_manager/mod.rs b/dkg/src/dkg_manager/mod.rs
index 87970058d4b..2976ec6a09a 100644
--- a/dkg/src/dkg_manager/mod.rs
+++ b/dkg/src/dkg_manager/mod.rs
@@ -13,8 +13,9 @@ use aptos_crypto::Uniform;
 use aptos_infallible::duration_since_epoch;
 use aptos_logger::{debug, error, info, warn};
 use aptos_types::{
-    aptos_dkg::{
-        DKGSessionMetadata, DKGSessionState, DKGStartEvent, DKGTrait, DKGTranscript,
+    dkg::{
+        DKGSessionMetadata, DKGSessionState,
+        DKGStartEvent, DKGTrait, DKGTranscript,
         DKGTranscriptMetadata, MayHaveRoundingSummary,
     },
     epoch_state::EpochState,
diff --git a/dkg/src/epoch_manager.rs b/dkg/src/epoch_manager.rs
index 8c29c28c6c7..7561a2c49e8 100644
--- a/dkg/src/epoch_manager.rs
+++ b/dkg/src/epoch_manager.rs
@@ -22,7 +22,7 @@ use aptos_reliable_broadcast::ReliableBroadcast;
 use aptos_safety_rules::{safety_rules_manager::storage, PersistentSafetyStorage};
 use aptos_types::{
     account_address::AccountAddress,
-    aptos_dkg::{DKGStartEvent, DKGState, DefaultDKG},
+    dkg::{DKGStartEvent, DKGState, DefaultDKG},
     epoch_state::EpochState,
     on_chain_config::{
         OnChainConfigPayload, OnChainConfigProvider, OnChainConsensusConfig,
diff --git a/dkg/src/transcript_aggregation/mod.rs b/dkg/src/transcript_aggregation/mod.rs
index 0007a7436e4..1a7ef8d9fee 100644
--- a/dkg/src/transcript_aggregation/mod.rs
+++ b/dkg/src/transcript_aggregation/mod.rs
@@ -8,7 +8,7 @@ use aptos_infallible::{duration_since_epoch, Mutex};
 use aptos_logger::info;
 use aptos_reliable_broadcast::BroadcastStatus;
 use aptos_types::{
-    aptos_dkg::{DKGTrait, DKGTranscript},
+    dkg::{DKGTrait, DKGTranscript},
     epoch_state::EpochState,
     validator_verifier::VerifyError,
 };
diff --git a/dkg/src/types.rs b/dkg/src/types.rs
index 22a9c8820c7..928b6590272 100644
--- a/dkg/src/types.rs
+++ b/dkg/src/types.rs
@@ -4,7 +4,7 @@
 use aptos_crypto_derive::CryptoHasher;
 use aptos_enum_conversion_derive::EnumConversion;
 use aptos_reliable_broadcast::RBMessage;
-pub use aptos_types::aptos_dkg::DKGTranscript;
+pub use aptos_types::dkg::DKGTranscript;
 use serde::{Deserialize, Serialize};
 
 /// Once DKG starts, a validator should send this message to peers in order to collect DKG transcripts from peers.
diff --git a/types/src/contract_event.rs b/types/src/contract_event.rs
index 3b9283d6b64..7736995a73f 100644
--- a/types/src/contract_event.rs
+++ b/types/src/contract_event.rs
@@ -7,7 +7,8 @@ use crate::{
         DepositEvent, NewBlockEvent, NewEpochEvent, WithdrawEvent, NEW_EPOCH_EVENT_MOVE_TYPE_TAG,
         NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG,
     },
-    dkg::events::{DKGFinishEvent, DKGMetaSetEvent, DKGStartEvent},
+    dkg::events::{DKGFinishEvent, DKGMetaSetEvent, DKGStartEvent as SupraDKGStartEvent},
+    dkg::DKGStartEvent,
     event::EventKey,
     jwks::ObservedJWKsUpdated,
     transaction::Version,
@@ -339,6 +340,35 @@ impl TryFrom<(u64, NewEpochEvent)> for ContractEvent {
     }
 }
 
+impl TryFrom<&ContractEvent> for SupraDKGStartEvent {
+    type Error = Error;
+
+    fn try_from(event: &ContractEvent) -> Result {
+        match event {
+            ContractEvent::V1(_) => {
+                bail!("conversion to dkg start event failed with wrong contract event version");
+            },
+            ContractEvent::V2(event) => {
+                if event.type_tag != TypeTag::Struct(Box::new(Self::struct_tag())) {
+                    bail!("conversion to dkg start event failed with wrong type tag")
+                }
+                bcs::from_bytes(&event.event_data).map_err(Into::into)
+            },
+        }
+    }
+}
+
+impl TryFrom for ContractEvent {
+    type Error = Error;
+
+    fn try_from(event: SupraDKGStartEvent) -> Result {
+        Self::new_v2(
+            TypeTag::from(SupraDKGStartEvent::struct_tag()),
+            bcs::to_bytes(&event).unwrap(),
+        )
+    }
+}
+
 impl TryFrom<&ContractEvent> for DKGStartEvent {
     type Error = Error;
 
diff --git a/vm-validator/src/mocks/mock_vm_validator.rs b/vm-validator/src/mocks/mock_vm_validator.rs
index 6ed7b0d2da0..06398bd751a 100644
--- a/vm-validator/src/mocks/mock_vm_validator.rs
+++ b/vm-validator/src/mocks/mock_vm_validator.rs
@@ -11,7 +11,7 @@ use aptos_types::{
     transaction::{SignedTransaction, VMValidatorResult},
     vm_status::StatusCode,
 };
-use aptos_vm::VMValidator;
+use aptos_vm::{VMValidator, move_vm_ext::AptosMoveResolver};
 use move_vm_runtime::ModuleStorage;
 
 pub const ACCOUNT_DNE_TEST_ADD: AccountAddress =
@@ -45,8 +45,7 @@ impl VMValidator for MockVMValidator {
     fn validate_dkg_validator_transaction(
         &self,
         _transaction: DKGTransactionData,
-        _state_view: &impl StateView,
-        _module_storage: &impl ModuleStorage,
+        _resolver: &impl AptosMoveResolver
     ) -> VMValidatorResult {
         VMValidatorResult::new(None, 0)
     }

From 912140a7a97e462cf4abf88b510609685a2ec2a4 Mon Sep 17 00:00:00 2001
From: Dhaval Purohit 
Date: Wed, 1 Jul 2026 20:10:58 +0530
Subject: [PATCH 28/31] Fixed remaining test cases

---
 Cargo.lock                                    |  1 +
 aptos-move/aptos-gas-schedule/src/ver.rs      |  2 +-
 aptos-move/e2e-move-tests/Cargo.toml          |  1 +
 aptos-move/e2e-move-tests/src/stake.rs        | 57 +++++++++++++++++--
 .../src/tests/automation_registry.rs          | 12 +++-
 .../update_rewards_config/Move.toml           |  2 +-
 .../update_rewards_config/sources/main.move   |  3 +
 aptos-move/e2e-move-tests/src/tests/stake.rs  |  1 +
 8 files changed, 70 insertions(+), 9 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index cdd91ee8420..968cd122129 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8471,6 +8471,7 @@ dependencies = [
  "aptos-vm-types",
  "bcs 0.1.4",
  "claims",
+ "crypto",
  "hex",
  "move-binary-format",
  "move-core-types",
diff --git a/aptos-move/aptos-gas-schedule/src/ver.rs b/aptos-move/aptos-gas-schedule/src/ver.rs
index 4b1c50b9348..5599663790a 100644
--- a/aptos-move/aptos-gas-schedule/src/ver.rs
+++ b/aptos-move/aptos-gas-schedule/src/ver.rs
@@ -79,7 +79,7 @@
 ///       global operations.
 /// - V1
 ///   - TBA
-pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_16_SUPRA_V1_9_0;
+pub const LATEST_GAS_FEATURE_VERSION: u64 = gas_feature_versions::RELEASE_V1_34;
 
 pub mod gas_feature_versions {
     pub const RELEASE_V1_8: u64 = 11;
diff --git a/aptos-move/e2e-move-tests/Cargo.toml b/aptos-move/e2e-move-tests/Cargo.toml
index b7f49974f51..b827274dffd 100644
--- a/aptos-move/e2e-move-tests/Cargo.toml
+++ b/aptos-move/e2e-move-tests/Cargo.toml
@@ -31,6 +31,7 @@ aptos-vm = { workspace = true, features = ["testing"] }
 aptos-vm-environment = { workspace = true }
 bcs = { workspace = true }
 claims = { workspace = true }
+crypto = { workspace = true }
 hex = { workspace = true }
 move-binary-format = { workspace = true }
 move-core-types = { workspace = true }
diff --git a/aptos-move/e2e-move-tests/src/stake.rs b/aptos-move/e2e-move-tests/src/stake.rs
index ff11fef80a4..2d59099da04 100644
--- a/aptos-move/e2e-move-tests/src/stake.rs
+++ b/aptos-move/e2e-move-tests/src/stake.rs
@@ -3,15 +3,63 @@
 
 use crate::harness::MoveHarness;
 use aptos_cached_packages::aptos_stdlib;
-use aptos_crypto::{ed25519, PrivateKey, Uniform};
+use aptos_crypto::{
+    ed25519, bls12381, SigningKey, PrivateKey, Uniform, 
+    bls12381::ProofOfPossession
+};
 use aptos_language_e2e_tests::account::Account;
 use aptos_types::{
     account_address::AccountAddress, account_config::CORE_CODE_ADDRESS,
     on_chain_config::ValidatorSet, stake_pool::StakePool, transaction::TransactionStatus,
-    validator_config::ValidatorConfig,
+    validator_config::ValidatorConfig, validator_public_keys::ValidatorPublicKeys
 };
 use move_core_types::parser::parse_struct_tag;
 
+// Used for generating the consesus pub key while doing rotate consensus key
+pub fn generate_consensus_pub_key() -> Vec {
+    let mut rng = rand::thread_rng();
+    let network_key = ed25519::PrivateKey::generate_for_testing();
+    let network_pubkey_bytes = network_key.public_key().to_bytes().to_vec();
+    
+    let bls_key = bls12381::PrivateKey::generate(&mut rng);
+    let bls_pub_key = bls12381::PublicKey::from(&bls_key);
+    let bls_pubkey_bytes = bls_pub_key.to_bytes().to_vec();
+
+    let cg_pubkey_bytes = {
+        let mut cg_rng = crypto::bls12381::cl_utils::rng();
+        crypto::bls12381::cg_encryption::keygen(&mut cg_rng, &[])
+            .expect("CG keygen must succeed")
+            .1
+            .to_vec()
+    };
+
+    let pop = ProofOfPossession::create_with_pubkey(&bls_key, &bls_pub_key);
+    let supra_ed_key = ed25519::PrivateKey::generate_for_testing();
+    let supra_ed_pubkey_bytes = supra_ed_key.public_key().to_bytes().to_vec();
+
+    // When SUPRA_BLS_KEYS feature is enabled (default), the genesis validator key must be
+    // BCS-encoded ValidatorPublicKeys, not a plain ed25519 key.
+    let validator_public_keys = ValidatorPublicKeys::new(
+        network_pubkey_bytes,
+        bls_pubkey_bytes,
+        None,
+        None,
+        None,
+        None,
+        None,
+        None,
+        None,
+        cg_pubkey_bytes,
+        supra_ed_pubkey_bytes,
+    );
+    let mut consensus_pubkey =
+        bcs::to_bytes(&validator_public_keys).expect("ValidatorPublicKeys must serialize");
+    let mut pop_bytes = pop.to_bytes().to_vec();
+    consensus_pubkey.append(&mut pop_bytes);
+    let consensus_pub_key_with_pop = consensus_pubkey;
+    consensus_pub_key_with_pop
+}
+
 pub fn setup_staking(
     harness: &mut MoveHarness,
     account: &Account,
@@ -76,9 +124,8 @@ pub fn rotate_consensus_key(
     account: &Account,
     pool_address: AccountAddress,
 ) -> TransactionStatus {
-    // TODO:(DP) need to fix this rotation with updated keys
-    let consensus_key = ed25519::PrivateKey::generate_for_testing();
-    let consensus_pubkey = consensus_key.public_key().to_bytes().to_vec();
+    // let consensus_key = ed25519::PrivateKey::generate_for_testing();
+    let consensus_pubkey = generate_consensus_pub_key();
     harness.run_transaction_payload(
         account,
         aptos_stdlib::stake_rotate_consensus_key(pool_address, consensus_pubkey),
diff --git a/aptos-move/e2e-move-tests/src/tests/automation_registry.rs b/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
index d04ba33c242..fc5bfba0cee 100644
--- a/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
+++ b/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
@@ -46,6 +46,14 @@ fn run_on_large_stack(f: F) {
 /// This is NOT wrapped with error::invalid_state — it is the plain u64 constant 15.
 const EDISABLED_AUTOMATION_FEATURE: u64 = 15;
 
+// -----------------------------------------------------------------------
+// Module-level abort code constant (mirrors Move's EDISABLED_AUTOMATION_V2_1_FEATURE = 49)
+// -----------------------------------------------------------------------
+
+/// Raw abort code emitted by `automation_registry v2.1` when a required feature is disabled.
+/// This is NOT wrapped with error::invalid_state — it is the plain u64 constant 49.
+const EDISABLED_AUTOMATION_V2_1_FEATURE: u64 = 49;
+
 // -----------------------------------------------------------------------
 // Helpers
 // -----------------------------------------------------------------------
@@ -254,7 +262,7 @@ fn test_register_without_validation_from_smart_contract() {
 }
 
 /// Verifies that calling `register_via_contract` when SUPRA_AUTOMATION_V2_1 is disabled
-/// aborts with EDISABLED_AUTOMATION_FEATURE = 15.
+/// aborts with EDISABLED_AUTOMATION_V2_1_FEATURE = 49.
 ///
 /// This ensures the feature gate in `register_without_validation` is enforced and that
 /// the function cannot be used before the binary upgrade is rolled out to all nodes.
@@ -279,6 +287,6 @@ fn test_register_without_validation_feature_disabled_aborts() {
                 bcs::to_bytes(&user_aux_data()).unwrap(),
             ],
         );
-        assert_abort!(status, EDISABLED_AUTOMATION_FEATURE);
+        assert_abort!(status, EDISABLED_AUTOMATION_V2_1_FEATURE);
     });
 }
diff --git a/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/Move.toml b/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/Move.toml
index a9fced9b015..71a6210a894 100644
--- a/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/Move.toml
+++ b/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/Move.toml
@@ -1,5 +1,5 @@
 [package]
-name = 'FederatedKeylessInitConfig'
+name = 'EnableRewardsRateDecrease'
 version = "0.0.0"
 
 [dependencies]
diff --git a/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/sources/main.move b/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/sources/main.move
index 2c621aec210..4d85798f7b3 100644
--- a/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/sources/main.move
+++ b/aptos-move/e2e-move-tests/src/tests/stake.data/update_rewards_config/sources/main.move
@@ -2,6 +2,7 @@ script {
     use supra_framework::supra_governance;
     use supra_framework::staking_config;
     use aptos_std::fixed_point64;
+    use std::features;
 
     fun main(core_resources: &signer) {
         let framework_signer = supra_governance::get_signer_testnet_only(core_resources, @supra_framework);
@@ -12,6 +13,8 @@ script {
             365 * 24 * 60 * 60,
             fixed_point64::create_from_rational(50, 100),
         );
+        let feature = features::get_periodical_reward_rate_decrease_feature();
+        features::change_feature_flags_for_next_epoch(&framework_signer, vector[feature], vector[]);
         supra_governance::force_end_epoch(&framework_signer);
     }
 }
diff --git a/aptos-move/e2e-move-tests/src/tests/stake.rs b/aptos-move/e2e-move-tests/src/tests/stake.rs
index 8b7f3db6986..0965f9d8d92 100644
--- a/aptos-move/e2e-move-tests/src/tests/stake.rs
+++ b/aptos-move/e2e-move-tests/src/tests/stake.rs
@@ -191,6 +191,7 @@ fn test_staking_rewards() {
     harness.new_block_with_metadata(validator_2_address, vec![]);
 
     // Enable rewards rate decrease and change rewards config. In production it requires governance.
+    // This also enables the feature as by default is is disabled.
     let core_resources =
         harness.new_account_at(AccountAddress::from_hex_literal("0xA550C18").unwrap());
     let script_code = PROPOSAL_SCRIPTS

From aeb003df5d1142436368457e22426ad2a76b753f Mon Sep 17 00:00:00 2001
From: Dhaval Purohit 
Date: Wed, 8 Jul 2026 16:25:00 +0530
Subject: [PATCH 29/31] Some fmt and minor build issues

---
 api/src/tests/transactions_test.rs            |   2 +-
 api/src/transactions.rs                       |   2 +-
 api/types/src/convert.rs                      |  17 +-
 api/types/src/transaction.rs                  |   4 +-
 .../aptos-debugger/src/aptos_debugger.rs      |   6 +-
 .../src/gas_schedule/aptos_framework.rs       |   6 +-
 .../src/components/feature_flags.rs           |   4 +-
 aptos-move/aptos-vm/src/aptos_vm.rs           | 111 ++++++-----
 aptos-move/aptos-vm/src/aptos_vm_viewer.rs    |  41 ++--
 .../src/automated_transaction_processor.rs    |  84 ++++-----
 ...tomation_registry_transaction_processor.rs |  22 ++-
 aptos-move/aptos-vm/src/gas.rs                |  15 +-
 .../src/move_vm_ext/session/session_id.rs     |   6 +-
 .../aptos-vm/src/transaction_metadata.rs      |  51 ++---
 .../aptos-vm/src/transaction_validation.rs    |  39 ++--
 aptos-move/aptos-vm/src/validator_txns/dkg.rs |  10 +-
 aptos-move/aptos-vm/src/validator_txns/mod.rs |   8 +-
 aptos-move/e2e-move-tests/src/harness.rs      |   3 +-
 aptos-move/e2e-move-tests/src/stake.rs        |   7 +-
 .../e2e-move-tests/src/tests/account.rs       |   3 +-
 .../src/tests/automation_registry.rs          |  13 +-
 .../e2e-move-tests/src/tests/fee_payer.rs     |  11 +-
 .../src/tests/fungible_asset.rs               |   4 +-
 aptos-move/e2e-move-tests/src/tests/mod.rs    |   2 +-
 aptos-move/e2e-tests/src/executor.rs          |  21 ++-
 .../src/tests/automated_transactions.rs       |  79 +++-----
 .../src/tests/automation_registration.rs      |  35 ++--
 .../e2e-testsuite/src/tests/create_account.rs |   9 +-
 .../e2e-testsuite/src/tests/verify_txn.rs     |   2 +-
 .../e2e-testsuite/src/tests/vm_viewer.rs      |   5 +-
 .../cached-packages/src/aptos_stdlib.rs       |   2 +-
 .../src/natives/transaction_context.rs        |   1 -
 aptos-move/vm-genesis/src/lib.rs              | 177 ++++++++++++++----
 .../consensus-types/src/round_timeout.rs      |   2 +-
 .../src/persistent_safety_storage.rs          |   4 +-
 consensus/src/epoch_manager.rs                |   3 +-
 consensus/src/quorum_store/counters.rs        |   1 -
 crates/aptos-genesis/src/builder.rs           |   4 +-
 crates/aptos-genesis/src/config.rs            |   3 +-
 crates/aptos-genesis/src/lib.rs               |   6 +-
 crates/aptos-genesis/src/mainnet.rs           |   3 +-
 crates/aptos/src/account/balance.rs           |   2 +-
 crates/aptos/src/common/types.rs              |   4 +-
 crates/aptos/src/governance/mod.rs            |   6 +-
 crates/aptos/src/move_tool/mod.rs             |   5 +-
 crates/aptos/src/node/mod.rs                  |   5 +-
 crates/aptos/src/op/key.rs                    |   9 +-
 crates/aptos/src/update/tool.rs               |   4 +-
 dkg/src/dkg_manager/mod.rs                    |   3 +-
 dkg/src/transcript_aggregation/tests.rs       |   4 +-
 .../indexer-grpc-fullnode/src/convert.rs      |   5 +-
 .../indexer-grpc-utils/src/cache_operator.rs  |   5 +-
 .../src/filters/user_transaction.rs           |   7 +-
 execution/block-partitioner/src/test_utils.rs |   2 +-
 execution/executor-types/src/lib.rs           |   2 +-
 execution/executor/src/metrics.rs             |   4 +-
 sdk/src/transaction_builder.rs                |   4 +-
 .../account_config/events/fungible_asset.rs   |   8 +-
 types/src/contract_event.rs                   |   8 +-
 types/src/dkg/dummy_dkg/mod.rs                |   6 +-
 types/src/dkg/mod.rs                          |  18 +-
 types/src/on_chain_config/aptos_features.rs   |   5 +-
 types/src/on_chain_config/evm_config.rs       |  22 ++-
 .../src/on_chain_config/evm_genesis_config.rs |   3 +-
 .../on_chain_config/leader_ban_registry.rs    |  31 +--
 types/src/on_chain_config/mod.rs              |   5 +-
 types/src/proptest_types.rs                   |  20 +-
 types/src/transaction/analyzed_transaction.rs |   2 +-
 .../src/transaction/automated_transaction.rs  |   1 -
 types/src/transaction/mod.rs                  |  31 +--
 types/src/unit_tests/automation.rs            |   6 +-
 types/src/validator_txn.rs                    |   6 +-
 vm-validator/src/mocks/mock_vm_validator.rs   |   4 +-
 73 files changed, 605 insertions(+), 470 deletions(-)

diff --git a/api/src/tests/transactions_test.rs b/api/src/tests/transactions_test.rs
index 18cf2c6cee9..3f07b26b65f 100644
--- a/api/src/tests/transactions_test.rs
+++ b/api/src/tests/transactions_test.rs
@@ -19,7 +19,7 @@ use aptos_types::{
         authenticator::{AuthenticationKey, TransactionAuthenticator},
         EntryFunction, Script, SignedTransaction,
     },
-    utility_coin::{SupraCoinType, CoinType},
+    utility_coin::{CoinType, SupraCoinType},
 };
 use move_core_types::{
     identifier::Identifier,
diff --git a/api/src/transactions.rs b/api/src/transactions.rs
index 50976838472..7a5cdc0cd4a 100644
--- a/api/src/transactions.rs
+++ b/api/src/transactions.rs
@@ -41,7 +41,7 @@ use aptos_types::{
         TransactionPayload, TransactionPayloadInner,
     },
     vm_status::StatusCode,
-    SupraCoinType, CoinType,
+    CoinType, SupraCoinType,
 };
 use aptos_vm::{AptosSimulationVM, AptosVM};
 use move_core_types::{ident_str, language_storage::ModuleId, vm_status::VMStatus};
diff --git a/api/types/src/convert.rs b/api/types/src/convert.rs
index a71cfdb7236..2b26a46a945 100644
--- a/api/types/src/convert.rs
+++ b/api/types/src/convert.rs
@@ -6,10 +6,10 @@
 use crate::{
     transaction::{
         AutomationRegistrationParams, AutomationRegistrationParamsV1,
-        AutomationRegistrationParamsV2, BlockMetadataTransaction, BlockEpilogueTransaction, DecodedTableData, DeleteModule,
-        DeleteResource, DeleteTableItem, DeletedTableData, MultisigPayload,
-        MultisigTransactionPayload, StateCheckpointTransaction, UserTransactionRequestInner,
-        WriteModule, WriteResource, WriteTableItem,
+        AutomationRegistrationParamsV2, BlockEpilogueTransaction, BlockMetadataTransaction,
+        DecodedTableData, DeleteModule, DeleteResource, DeleteTableItem, DeletedTableData,
+        MultisigPayload, MultisigTransactionPayload, StateCheckpointTransaction,
+        UserTransactionRequestInner, WriteModule, WriteResource, WriteTableItem,
     },
     view::{ViewFunction, ViewRequest},
     Address, Bytecode, DirectWriteSet, EntryFunctionId, EntryFunctionPayload, EventV1, EventV2,
@@ -144,10 +144,7 @@ impl<'a, S: StateView> MoveConverter<'a, S> {
         bytes: &[u8],
     ) -> Result> {
         let resources_with_tag: Vec<(StructTag, Vec)> = bcs::from_bytes::(bytes)
-            .map(|map| {
-                map.into_iter()
-                    .collect::>()
-            })?;
+            .map(|map| map.into_iter().collect::>())?;
 
         resources_with_tag
             .iter()
@@ -927,7 +924,9 @@ impl<'a, S: StateView> MoveConverter<'a, S> {
                                 entry_func_payload,
                             )?),
                             MultisigTransactionPayload::AutomationRegistrationPayload(params) => {
-                                Executable::AutomationRegistration(self.try_into_automation_registration_parameters(params)?)
+                                Executable::AutomationRegistration(
+                                    self.try_into_automation_registration_parameters(params)?,
+                                )
                             },
                         }
                     } else {
diff --git a/api/types/src/transaction.rs b/api/types/src/transaction.rs
index 7460a95cead..96e34753693 100755
--- a/api/types/src/transaction.rs
+++ b/api/types/src/transaction.rs
@@ -19,11 +19,10 @@ use aptos_crypto::{
 use aptos_types::{
     account_address::AccountAddress,
     aggregate_signature::AggregateSignature,
-    dkg::{DKGTranscript, DKGTranscriptMetadata},
     block_metadata::BlockMetadata,
     block_metadata_ext::BlockMetadataExt,
     contract_event::{ContractEvent, EventWithVersion},
-    dkg::transactions::DKGTransactionData,
+    dkg::{transactions::DKGTransactionData, DKGTranscript, DKGTranscriptMetadata},
     function_info::FunctionInfo,
     jwks::{jwk::JWK, ProviderJWKs, QuorumCertifiedUpdate},
     keyless,
@@ -1133,6 +1132,7 @@ impl From<(&ContractEvent, serde_json::Value)> for EventV2 {
 
 impl TryFrom for EventV2 {
     type Error = AnyhowError;
+
     fn try_from(event_v1: EventV1) -> Result {
         let EventV1 {
             guid,
diff --git a/aptos-move/aptos-debugger/src/aptos_debugger.rs b/aptos-move/aptos-debugger/src/aptos_debugger.rs
index f396db16023..6f270f45c36 100644
--- a/aptos-move/aptos-debugger/src/aptos_debugger.rs
+++ b/aptos-move/aptos-debugger/src/aptos_debugger.rs
@@ -163,7 +163,7 @@ impl AptosDebugger {
                     },
                     TransactionExecutableRef::AutomationRegistration(_) => {
                         unimplemented!("not supported yet")
-                    }
+                    },
                 };
                 gas_profiler
             },
@@ -399,7 +399,9 @@ fn print_transaction_stats(sig_verified_txns: &[SignatureVerifiedTransaction], v
                     ),
                     Ok(TransactionExecutableRef::Script(_)) => "script".to_string(),
                     Ok(TransactionExecutableRef::Empty) => "empty".to_string(),
-                    Ok(TransactionExecutableRef::AutomationRegistration(_)) => "automation_registration".to_string(),
+                    Ok(TransactionExecutableRef::AutomationRegistration(_)) => {
+                        "automation_registration".to_string()
+                    },
                     Err(e) => {
                         panic!("deprecated transaction payload: {}", e)
                     },
diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
index 6f2abb44841..9d752dc45e2 100644
--- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
+++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
@@ -8,10 +8,8 @@ use crate::{
     gas_feature_versions::{RELEASE_V1_14, RELEASE_V1_8, RELEASE_V1_9_SKIPPED},
     gas_schedule::NativeGasParameters,
     ver::gas_feature_versions::{
-        
-        RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_16_SUPRA_V1_6_0, RELEASE_V1_23, RELEASE_V1_26, RELEASE_V1_28, RELEASE_V1_16_SUPRA_V1_7_14,
-        RELEASE_V1_16_SUPRA_V1_9_0,
-    
+        RELEASE_V1_12, RELEASE_V1_13, RELEASE_V1_16_SUPRA_V1_6_0, RELEASE_V1_16_SUPRA_V1_7_14,
+        RELEASE_V1_16_SUPRA_V1_9_0, RELEASE_V1_23, RELEASE_V1_26, RELEASE_V1_28,
     },
 };
 use aptos_gas_algebra::{
diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs
index d1247c9490e..a7046e83d81 100644
--- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs
+++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs
@@ -408,7 +408,7 @@ impl From for AptosFeatureFlag {
                 AptosFeatureFlag::CALCULATE_TRANSACTION_FEE_FOR_DISTRIBUTION
             },
             FeatureFlag::DistributeTransactionFee => AptosFeatureFlag::DISTRIBUTE_TRANSACTION_FEE,
-                FeatureFlag::SupraNativeAutomation => AptosFeatureFlag::SUPRA_NATIVE_AUTOMATION,
+            FeatureFlag::SupraNativeAutomation => AptosFeatureFlag::SUPRA_NATIVE_AUTOMATION,
             FeatureFlag::SupraEthTrie => AptosFeatureFlag::SUPRA_ETH_TRIE,
             FeatureFlag::SupraAutomationPayloadGasCheck => {
                 AptosFeatureFlag::SUPRA_AUTOMATION_PAYLOAD_GAS_CHECK
@@ -602,7 +602,7 @@ impl From for FeatureFlag {
                 FeatureFlag::CalculateTransactionFeeForDistribution
             },
             AptosFeatureFlag::DISTRIBUTE_TRANSACTION_FEE => FeatureFlag::DistributeTransactionFee,
-                AptosFeatureFlag::SUPRA_NATIVE_AUTOMATION => FeatureFlag::SupraNativeAutomation,
+            AptosFeatureFlag::SUPRA_NATIVE_AUTOMATION => FeatureFlag::SupraNativeAutomation,
             AptosFeatureFlag::SUPRA_ETH_TRIE => FeatureFlag::SupraEthTrie,
             AptosFeatureFlag::SUPRA_AUTOMATION_PAYLOAD_GAS_CHECK => {
                 FeatureFlag::SupraAutomationPayloadGasCheck
diff --git a/aptos-move/aptos-vm/src/aptos_vm.rs b/aptos-move/aptos-vm/src/aptos_vm.rs
index 271e2a98b2c..f2e7a7837c7 100644
--- a/aptos-move/aptos-vm/src/aptos_vm.rs
+++ b/aptos-move/aptos-vm/src/aptos_vm.rs
@@ -41,8 +41,7 @@ use aptos_crypto::{
     bls12381::{PublicKey, Signature},
     HashValue,
 };
-use aptos_framework::natives::code::PublishRequest;
-use aptos_framework::natives::randomness::RandomnessContext;
+use aptos_framework::natives::{code::PublishRequest, randomness::RandomnessContext};
 use aptos_gas_algebra::{Gas, GasQuantity, NumBytes, Quant};
 use aptos_gas_meter::{AptosGasMeter, GasAlgebra};
 use aptos_gas_schedule::{
@@ -66,11 +65,11 @@ use aptos_types::{
     block_metadata::BlockMetadata,
     block_metadata_ext::{BlockMetadataExt, BlockMetadataWithRandomness},
     chain_id::ChainId,
+    contract_event::ContractEvent,
     dkg::{
         state::DKGState,
         transactions::{DKGTransactionData, DKGTransactionType},
     },
-    contract_event::ContractEvent,
     fee_statement::FeeStatement,
     function_info::FunctionInfo,
     move_utils::as_move_value::AsMoveValue,
@@ -149,8 +148,7 @@ use move_vm_runtime::{
     check_type_tag_dependencies_and_charge_gas,
     logging::expect_no_verification_errors,
     module_traversal::{TraversalContext, TraversalStorage},
-    LoadedFunction,
-    ModuleStorage, RuntimeEnvironment, WithRuntimeEnvironment,
+    LoadedFunction, ModuleStorage, RuntimeEnvironment, WithRuntimeEnvironment,
 };
 use move_vm_types::gas::{GasMeter, UnmeteredGasMeter};
 use num_cpus;
@@ -1055,7 +1053,7 @@ impl AptosVM {
                         entry_fn,
                     )
                 })?;
-            }
+            },
             TransactionExecutableRef::AutomationRegistration(registration_params) => {
                 session.execute(|session| {
                     self.validate_and_execute_automation_registration(
@@ -1118,22 +1116,22 @@ impl AptosVM {
         sender: AccountAddress,
         registration_params: &RegistrationParams,
     ) -> Result<(), VMStatus> {
-            self.validate_automated_function(
-                session,
-                code_storage,
-                serialized_signers,
-                registration_params.automated_function(),
-            )?;
+        self.validate_automated_function(
+            session,
+            code_storage,
+            serialized_signers,
+            registration_params.automated_function(),
+        )?;
 
-            self.execute_automation_registration(
-                session,
-                code_storage,
-                gas_meter,
-                traversal_context,
-                sender,
-                registration_params,
-                txn_data,
-            )?;
+        self.execute_automation_registration(
+            session,
+            code_storage,
+            gas_meter,
+            traversal_context,
+            sender,
+            registration_params,
+            txn_data,
+        )?;
         Ok(())
     }
 
@@ -1172,7 +1170,7 @@ impl AptosVM {
             args,
             gas_meter,
             traversal_context,
-            module_storage
+            module_storage,
         )?;
         Ok(())
     }
@@ -1273,7 +1271,6 @@ impl AptosVM {
         ))
     }
 
-
     // Execute a multisig transaction:
     // 1. Obtain the payload of the transaction to execute. This could have been stored on chain
     // when the multisig transaction was created.
@@ -1341,10 +1338,10 @@ impl AptosVM {
                 );
                 return Ok((s, discarded_output(StatusCode::FEATURE_UNDER_GATING)));
             },
-            TransactionExecutableRef::AutomationRegistration(registration_params) => {
-            bcs::to_bytes(&MultisigTransactionPayload::AutomationRegistration(registration_params.clone()))
-            .map_err(|_| invariant_violation_error())?
-            }
+            TransactionExecutableRef::AutomationRegistration(registration_params) => bcs::to_bytes(
+                &MultisigTransactionPayload::AutomationRegistration(registration_params.clone()),
+            )
+            .map_err(|_| invariant_violation_error())?,
         };
         // Failures here will be propagated back.
         let payload_bytes: Vec> = session
@@ -1478,10 +1475,10 @@ impl AptosVM {
         payload: &MultisigTransactionPayload,
         change_set_configs: &ChangeSetConfigs,
     ) -> Result {
-
-        let multisig_serialized_signer = SerializedSigners::new(vec![serialized_signer(&multisig_address)], None);
+        let multisig_serialized_signer =
+            SerializedSigners::new(vec![serialized_signer(&multisig_address)], None);
         match payload {
-            MultisigTransactionPayload::EntryFunction(entry_function) =>{
+            MultisigTransactionPayload::EntryFunction(entry_function) => {
                 session.execute(|session| {
                     self.validate_and_execute_entry_function(
                         module_storage,
@@ -2118,7 +2115,6 @@ impl AptosVM {
         let payload_timer =
             VM_TIMER.timer_with_label("AptosVM::execute_user_transaction_impl [payload]");
 
-
         // `validate_signed_transaction` function already discards the transactions with `TransactionPayloadInner` type payload if the
         // corresponding feature flag (`TransactionPayloadV2`) is disabled. Therefore, we don't need to check the feature flag here again.
         let executable = match txn.executable_ref() {
@@ -2141,7 +2137,7 @@ impl AptosVM {
                 log_context,
                 change_set_configs,
             )
-        }  else {
+        } else {
             self.execute_script_or_entry_function(
                 resolver,
                 code_storage,
@@ -2153,7 +2149,7 @@ impl AptosVM {
                 executable,
                 log_context,
                 change_set_configs,
-                is_approved_gov_script
+                is_approved_gov_script,
             )
         };
         drop(payload_timer);
@@ -2509,11 +2505,10 @@ impl AptosVM {
         // during epoch change) remain unaffected by test-and-abort attacks, which the bias-ability
         // check is intended to protect against. Similarly, governance is expected not to attempt to
         // bias randomness results. This allows us to continue to manually force epoch changes via
-        // governance when necessary, which would otherwise be impossible due to 
+        // governance when necessary, which would otherwise be impossible due to
         // reconfiguration_with_dkg::try_start relying on access to randomness,
         if self.features().is_enabled(FeatureFlag::SUPRA_DKG) {
-            session
-                .mark_unbiasable();
+            session.mark_unbiasable();
         }
     }
 
@@ -2744,18 +2739,23 @@ impl AptosVM {
         let gas_used = Self::gas_used(max_gas_amount.into(), &gas_meter);
         match execution_result {
             Ok(result) => ViewFunctionOutput::new(Ok(result), gas_used),
-            Err(e) => {
-                vm.view_function_output_from_error(e, gas_used, &module_storage, &traversal_context, &log_context)
-            },
+            Err(e) => vm.view_function_output_from_error(
+                e,
+                gas_used,
+                &module_storage,
+                &traversal_context,
+                &log_context,
+            ),
         }
     }
 
-    pub(crate) fn view_function_output_from_error(&self,
-                                  e: VMError,
-                                  gas_used: u64,
-                                  module_storage: &impl AptosModuleStorage,
-                                  traversal_context: &TraversalContext,
-                                  log_context: &AdapterLogSchema,
+    pub(crate) fn view_function_output_from_error(
+        &self,
+        e: VMError,
+        gas_used: u64,
+        module_storage: &impl AptosModuleStorage,
+        traversal_context: &TraversalContext,
+        log_context: &AdapterLogSchema,
     ) -> ViewFunctionOutput {
         let vm_status = e.clone().into_vm_status();
         match vm_status {
@@ -2772,8 +2772,7 @@ impl AptosVM {
                 );
             },
         }
-        let txn_status =
-            TransactionStatus::from_vm_status(vm_status.clone(), self.features());
+        let txn_status = TransactionStatus::from_vm_status(vm_status.clone(), self.features());
         let execution_status = match txn_status {
             TransactionStatus::Keep(status) => status,
             _ => ExecutionStatus::MiscellaneousError(Some(vm_status.status_code())),
@@ -2789,7 +2788,6 @@ impl AptosVM {
             Some(vm_status.status_code()),
             gas_used,
         )
-
     }
 
     pub(crate) fn gas_used(max_gas_amount: Gas, gas_meter: &impl AptosGasMeter) -> u64 {
@@ -2887,7 +2885,6 @@ impl AptosVM {
             self.is_simulation,
         )?;
 
-
         if let Some(task_registration_params) = executable.as_automation_registration_params() {
             check_automation_task_gas(
                 self.gas_params(log_context)?,
@@ -3069,14 +3066,14 @@ impl AptosVM {
                 )?;
                 (vm_status, output)
             },
-            Transaction::AutomatedTransaction(txn) => AutomatedTransactionProcessor::new(
-                self, AutomationTaskType::User,
-            )
-            .execute_transaction(resolver, code_storage, txn, log_context),
-            Transaction::SystemAutomatedTransaction(txn) => AutomatedTransactionProcessor::new(
-                self, AutomationTaskType::System,
-            )
-            .execute_transaction(resolver, code_storage, txn, log_context),
+            Transaction::AutomatedTransaction(txn) => {
+                AutomatedTransactionProcessor::new(self, AutomationTaskType::User)
+                    .execute_transaction(resolver, code_storage, txn, log_context)
+            },
+            Transaction::SystemAutomatedTransaction(txn) => {
+                AutomatedTransactionProcessor::new(self, AutomationTaskType::System)
+                    .execute_transaction(resolver, code_storage, txn, log_context)
+            },
             Transaction::AutomationRegistryTransaction(txn) => {
                 AutomationRegistryTransactionProcessor::new(self).execute_transaction(
                     resolver,
diff --git a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs
index 9450bab8d9d..61a7c6cba91 100644
--- a/aptos-move/aptos-vm/src/aptos_vm_viewer.rs
+++ b/aptos-move/aptos-vm/src/aptos_vm_viewer.rs
@@ -10,12 +10,13 @@ use aptos_types::{
     state_store::StateView,
     transaction::{EntryFunction, ViewFunction, ViewFunctionOutput},
 };
-use move_core_types::account_address::AccountAddress;
+use aptos_vm_environment::environment::AptosEnvironment;
 use aptos_vm_logging::log_schema::AdapterLogSchema;
-use aptos_vm_types::module_and_script_storage::AsAptosCodeStorage;
-use aptos_vm_types::resolver::NoopBlockSynchronizationKillSwitch;
+use aptos_vm_types::{
+    module_and_script_storage::AsAptosCodeStorage, resolver::NoopBlockSynchronizationKillSwitch,
+};
+use move_core_types::account_address::AccountAddress;
 use move_vm_runtime::module_traversal::{TraversalContext, TraversalStorage};
-use aptos_vm_environment::environment::AptosEnvironment;
 
 /// Move VM with only view function API.
 /// Convenient to use when more than one view function needs to be executed on the same state-view,
@@ -39,10 +40,20 @@ impl<'t, SV: StateView> AptosVMViewer<'t, SV> {
         }
     }
 
-    fn create_gas_meter(&self, max_gas_amount: u64) -> anyhow::Result> {
-        let vm_gas_params = self.vm.gas_params(&self.log_context).map_err(|err| anyhow::Error::msg(err.to_string()))?.vm.clone();
-        let storage_gas_params =
-        self.vm.storage_gas_params(&self.log_context).map_err(|err| anyhow::Error::msg(err.to_string()))?;
+    fn create_gas_meter(
+        &self,
+        max_gas_amount: u64,
+    ) -> anyhow::Result> {
+        let vm_gas_params = self
+            .vm
+            .gas_params(&self.log_context)
+            .map_err(|err| anyhow::Error::msg(err.to_string()))?
+            .vm
+            .clone();
+        let storage_gas_params = self
+            .vm
+            .storage_gas_params(&self.log_context)
+            .map_err(|err| anyhow::Error::msg(err.to_string()))?;
 
         let gas_meter = make_prod_gas_meter(
             self.vm.gas_feature_version(),
@@ -70,7 +81,9 @@ impl<'t, SV: StateView> AptosVMViewer<'t, SV> {
 
         let traversal_storage = TraversalStorage::new();
         let mut traversal_context = TraversalContext::new(&traversal_storage);
-        let module_storage = self.state_view.as_aptos_code_storage(self.vm.environment_ref());
+        let module_storage = self
+            .state_view
+            .as_aptos_code_storage(self.vm.environment_ref());
         let execution_result = AptosVM::execute_view_function_in_vm(
             &mut session,
             &self.vm,
@@ -80,12 +93,18 @@ impl<'t, SV: StateView> AptosVMViewer<'t, SV> {
             arguments,
             &mut gas_meter,
             &mut traversal_context,
-            &module_storage
+            &module_storage,
         );
         let gas_used = AptosVM::gas_used(max_gas_amount.into(), &gas_meter);
         match execution_result {
             Ok(result) => ViewFunctionOutput::new(Ok(result), gas_used),
-            Err(e) => self.vm.view_function_output_from_error(e, gas_used, &module_storage, &traversal_context, &self.log_context),
+            Err(e) => self.vm.view_function_output_from_error(
+                e,
+                gas_used,
+                &module_storage,
+                &traversal_context,
+                &self.log_context,
+            ),
         }
     }
 }
diff --git a/aptos-move/aptos-vm/src/automated_transaction_processor.rs b/aptos-move/aptos-vm/src/automated_transaction_processor.rs
index 97aa3264323..f59713de82f 100644
--- a/aptos-move/aptos-vm/src/automated_transaction_processor.rs
+++ b/aptos-move/aptos-vm/src/automated_transaction_processor.rs
@@ -8,7 +8,8 @@ use crate::{
     gas::{check_gas, make_prod_gas_meter},
     move_vm_ext::{
         session::user_transaction_sessions::{
-            epilogue::EpilogueSession, prologue::PrologueSession, user::UserSession,
+            epilogue::EpilogueSession, prologue::PrologueSession,
+            session_change_sets::SystemSessionChangeSet, user::UserSession,
         },
         AptosMoveResolver, SessionExt,
     },
@@ -29,7 +30,11 @@ use aptos_types::{
 use aptos_vm_logging::log_schema::AdapterLogSchema;
 use aptos_vm_types::{
     change_set::VMChangeSet,
+    module_and_script_storage::{
+        code_storage::AptosCodeStorage, module_storage::AptosModuleStorage,
+    },
     output::VMOutput,
+    resolver::BlockSynchronizationKillSwitch,
     storage::{change_set_configs::ChangeSetConfigs, StorageGasParameters},
 };
 use fail::fail_point;
@@ -37,14 +42,9 @@ use move_binary_format::errors::Location;
 use move_core_types::vm_status::{StatusCode, VMStatus};
 use move_vm_runtime::{
     module_traversal::{TraversalContext, TraversalStorage},
-    LoadedFunction,
+    LoadedFunction, ModuleStorage,
 };
 use std::ops::Deref;
-use aptos_vm_types::module_and_script_storage::code_storage::AptosCodeStorage;
-use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage;
-use aptos_vm_types::resolver::BlockSynchronizationKillSwitch;
-use move_vm_runtime::ModuleStorage;
-use crate::move_vm_ext::session::user_transaction_sessions::session_change_sets::SystemSessionChangeSet;
 
 pub struct AutomatedTransactionProcessor<'m> {
     aptos_vm: &'m AptosVM,
@@ -89,10 +89,7 @@ impl<'m> AutomatedTransactionProcessor<'m> {
             false,
             log_context,
         )?;
-        if self
-            .features()
-            .is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2)
-        {
+        if self.features().is_enabled(FeatureFlag::SUPRA_AUTOMATION_V2) {
             transaction_validation::run_automated_transaction_prologue_v2(
                 session,
                 module_storage,
@@ -225,8 +222,6 @@ impl<'m> AutomatedTransactionProcessor<'m> {
                 .map(|_| ())
                 .map_err(|e| e.into_vm_status())
         })?;
-        
-
 
         let user_session_change_set = self.resolve_pending_code_publish_and_finish_user_session(
             session,
@@ -272,7 +267,6 @@ impl<'m> AutomatedTransactionProcessor<'m> {
         change_set_configs: &ChangeSetConfigs,
         traversal_context: &mut TraversalContext,
     ) -> (VMStatus, VMOutput) {
-
         self.failed_transaction_cleanup(
             prologue_change_set,
             err,
@@ -299,8 +293,7 @@ impl<'m> AutomatedTransactionProcessor<'m> {
         let mut traversal_context = TraversalContext::new(&traversal_storage);
 
         // Revalidate the transaction.
-        let mut prologue_session =
-            PrologueSession::new(self.aptos_vm, &txn_data, resolver);
+        let mut prologue_session = PrologueSession::new(self.aptos_vm, &txn_data, resolver);
 
         let exec_result = prologue_session.execute(|session| {
             self.validate_automated_transaction(
@@ -316,13 +309,7 @@ impl<'m> AutomatedTransactionProcessor<'m> {
         let storage_gas_params = unwrap_or_discard!(self.storage_gas_params(log_context));
         let change_set_configs = &storage_gas_params.change_set_configs;
         let (prologue_change_set, user_session) = unwrap_or_discard!(prologue_session
-            .into_user_session(
-                self,
-                &txn_data,
-                resolver,
-                change_set_configs,
-                code_storage,
-            ));
+            .into_user_session(self, &txn_data, resolver, change_set_configs, code_storage,));
         let TransactionPayload::EntryFunction(automated_entry_function) = txn.payload() else {
             return (
                 VMStatus::error(StatusCode::INVALID_AUTOMATED_PAYLOAD, None),
@@ -416,8 +403,14 @@ impl<'m> AutomatedTransactionProcessor<'m> {
             balance,
             code_storage,
         );
-        let (status, output) =
-            self.execute_transaction_impl(resolver, code_storage, txn, txn_metadata, &mut gas_meter, log_context);
+        let (status, output) = self.execute_transaction_impl(
+            resolver,
+            code_storage,
+            txn,
+            txn_metadata,
+            &mut gas_meter,
+            log_context,
+        );
 
         Ok((status, output, gas_meter))
     }
@@ -479,10 +472,8 @@ impl<'m> AutomatedTransactionProcessor<'m> {
             }
         }
 
-        let txn_status = TransactionStatus::from_vm_status(
-            error_vm_status.clone(),
-            self.features(),
-        );
+        let txn_status =
+            TransactionStatus::from_vm_status(error_vm_status.clone(), self.features());
 
         match txn_status {
             TransactionStatus::Keep(status) => {
@@ -492,17 +483,19 @@ impl<'m> AutomatedTransactionProcessor<'m> {
                 // gas). Even if the previous failure occurred while running the epilogue, it
                 // should not fail now. If it somehow fails here, there is no choice but to
                 // discard the transaction.
-                let txn_output = self.finish_aborted_transaction(
-                    prologue_change_set,
-                    gas_meter,
-                    txn_data,
-                    resolver,
-                    module_storage,
-                    status,
-                    log_context,
-                    change_set_configs,
-                    traversal_context,
-                ).unwrap_or_else(|status| discarded_output(status.status_code()));
+                let txn_output = self
+                    .finish_aborted_transaction(
+                        prologue_change_set,
+                        gas_meter,
+                        txn_data,
+                        resolver,
+                        module_storage,
+                        status,
+                        log_context,
+                        change_set_configs,
+                        traversal_context,
+                    )
+                    .unwrap_or_else(|status| discarded_output(status.status_code()));
                 (error_vm_status, txn_output)
             },
             TransactionStatus::Discard(status_code) => {
@@ -539,7 +532,8 @@ impl<'m> AutomatedTransactionProcessor<'m> {
             module_storage,
             traversal_context,
             log_context,
-            status);
+            status,
+        );
 
         let fee_statement =
             AptosVM::fee_statement_from_gas_meter(txn_data, gas_meter, ZERO_STORAGE_REFUND);
@@ -556,8 +550,12 @@ impl<'m> AutomatedTransactionProcessor<'m> {
                 traversal_context,
             )
         })?;
-        epilogue_session
-            .finish(self.get_fee_statement_for_output(fee_statement), status, change_set_configs, module_storage)
+        epilogue_session.finish(
+            self.get_fee_statement_for_output(fee_statement),
+            status,
+            change_set_configs,
+            module_storage,
+        )
     }
 
     /// The actual charged fee statement for executed automated transaction.
diff --git a/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs b/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs
index 71cc657c8b0..d2fa4ea387e 100644
--- a/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs
+++ b/aptos-move/aptos-vm/src/automation_registry_transaction_processor.rs
@@ -2,7 +2,7 @@
 // SPDX-License-Identifier: Apache-2.0
 
 use crate::{
-    aptos_vm::{get_system_transaction_output},
+    aptos_vm::get_system_transaction_output,
     counters::SYSTEM_TRANSACTIONS_EXECUTED,
     errors::discarded_output,
     gas::make_prod_gas_meter,
@@ -15,21 +15,23 @@ use aptos_types::{
     on_chain_config::FeatureFlag,
     transaction::{
         automation::{AutomationRegistryAction, AutomationRegistryRecord},
-        ExecutionStatus,
-        TransactionStatus,
+        ExecutionStatus, TransactionStatus,
     },
 };
 use aptos_vm_logging::log_schema::AdapterLogSchema;
-use aptos_vm_types::module_and_script_storage::code_storage::AptosCodeStorage;
-use aptos_vm_types::module_write_set::ModuleWriteSet;
-use aptos_vm_types::output::VMOutput;
-use aptos_vm_types::resolver::BlockSynchronizationKillSwitch;
-use aptos_vm_types::storage::change_set_configs::ChangeSetConfigs;
+use aptos_vm_types::{
+    module_and_script_storage::{
+        code_storage::AptosCodeStorage, module_storage::AptosModuleStorage,
+    },
+    module_write_set::ModuleWriteSet,
+    output::VMOutput,
+    resolver::BlockSynchronizationKillSwitch,
+    storage::change_set_configs::ChangeSetConfigs,
+};
 use move_binary_format::errors::VMError;
 use move_core_types::vm_status::{StatusCode, VMStatus};
 use move_vm_runtime::module_traversal::{TraversalContext, TraversalStorage};
 use std::ops::Deref;
-use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage;
 
 pub struct AutomationRegistryTransactionProcessor<'m> {
     aptos_vm: &'m AptosVM,
@@ -91,7 +93,7 @@ impl<'m> AutomationRegistryTransactionProcessor<'m> {
             ));
         }
         let gas_params = self.gas_params(log_context)?.vm.clone();
-        
+
         let max_gas_amount = gas_params.txn.maximum_number_of_gas_units;
         let mut gas_meter = make_prod_gas_meter(
             self.gas_feature_version(),
diff --git a/aptos-move/aptos-vm/src/gas.rs b/aptos-move/aptos-vm/src/gas.rs
index 851910df2a8..0253118cb40 100644
--- a/aptos-move/aptos-vm/src/gas.rs
+++ b/aptos-move/aptos-vm/src/gas.rs
@@ -12,9 +12,7 @@ use aptos_gas_schedule::{
 use aptos_logger::{enabled, Level};
 use aptos_memory_usage_tracker::MemoryTrackedGasMeter;
 use aptos_types::{
-    on_chain_config::{
-        FeatureFlag, Features,
-    },
+    on_chain_config::{FeatureFlag, Features},
     transaction::{automation::RegistrationParams, RawTransaction, TransactionPayload},
 };
 use aptos_vm_logging::{log_schema::AdapterLogSchema, speculative_log, speculative_warn};
@@ -81,7 +79,13 @@ pub(crate) fn check_gas(
         script_size: txn_metadata.script_size,
         is_keyless: txn_metadata.is_keyless(),
     };
-    check_gas_for_parameters(gas_params, gas_feature_version, txn_gas_metadata, is_approved_gov_script, log_context)?;
+    check_gas_for_parameters(
+        gas_params,
+        gas_feature_version,
+        txn_gas_metadata,
+        is_approved_gov_script,
+        log_context,
+    )?;
     let txn_gas_params = &gas_params.vm.txn;
     // If this is for a potentially new account, ensure there's enough gas to cover storage, execution, and IO costs.
     // TODO: This isn't the cleaning code, thus we localize it just here and will remove it
@@ -309,8 +313,7 @@ pub(crate) fn check_gas_for_parameters(
             log_context,
             format!(
                 "[VM] Gas unit error; max {}, submitted {}",
-                txn_gas_params.max_price_per_gas_unit,
-                txn_gas_metadata.gas_unit_price
+                txn_gas_params.max_price_per_gas_unit, txn_gas_metadata.gas_unit_price
             ),
         );
         return Err(VMStatus::error(
diff --git a/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs b/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs
index eb60e420c31..0f8acd2a72e 100644
--- a/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs
+++ b/aptos-move/aptos-vm/src/move_vm_ext/session/session_id.rs
@@ -5,8 +5,10 @@ use crate::transaction_metadata::TransactionMetadata;
 use aptos_crypto::{hash::CryptoHash, HashValue};
 use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher};
 use aptos_types::{
-    block_metadata::BlockMetadata, block_metadata_ext::BlockMetadataExt,
-    transaction::automation::AutomationRegistryRecord, transaction::ReplayProtector, validator_txn::ValidatorTransaction,
+    block_metadata::BlockMetadata,
+    block_metadata_ext::BlockMetadataExt,
+    transaction::{automation::AutomationRegistryRecord, ReplayProtector},
+    validator_txn::ValidatorTransaction,
 };
 use move_core_types::account_address::AccountAddress;
 use serde::{Deserialize, Serialize};
diff --git a/aptos-move/aptos-vm/src/transaction_metadata.rs b/aptos-move/aptos-vm/src/transaction_metadata.rs
index ad21b538924..927d85fd6da 100644
--- a/aptos-move/aptos-vm/src/transaction_metadata.rs
+++ b/aptos-move/aptos-vm/src/transaction_metadata.rs
@@ -9,26 +9,26 @@ use aptos_types::{
     account_address::AccountAddress,
     chain_id::ChainId,
     transaction::{
-        automated_transaction::AutomatedTransaction,
         authenticator::AuthenticationProof,
+        automated_transaction::AutomatedTransaction,
         user_transaction_context::{
-            UserTransactionContext, PayloadTypeReference, PayloadTypeReferenceContext
+            PayloadTypeReference, PayloadTypeReferenceContext, UserTransactionContext,
         },
-        EntryFunction, Multisig, MultisigTransactionPayload, ReplayProtector, SignedTransaction, 
-        TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig, TransactionPayload, 
-        TransactionPayloadInner,
+        EntryFunction, Multisig, MultisigTransactionPayload, ReplayProtector, SignedTransaction,
+        TransactionExecutable, TransactionExecutableRef, TransactionExtraConfig,
+        TransactionPayload, TransactionPayloadInner,
     },
 };
 
 pub type PayloadTypeReferenceMeta = PayloadTypeReference;
 
-fn convert_to_payload_type_reference_meta(payload: &TransactionPayloadInner) -> PayloadTypeReferenceMeta {
+fn convert_to_payload_type_reference_meta(
+    payload: &TransactionPayloadInner,
+) -> PayloadTypeReferenceMeta {
     let TransactionPayloadInner::V1 {
         executable,
-        extra_config:
-        TransactionExtraConfig::V1 {
-            multisig_address,
-            ..
+        extra_config: TransactionExtraConfig::V1 {
+            multisig_address, ..
         },
     } = payload;
     match multisig_address {
@@ -41,19 +41,15 @@ fn convert_to_payload_type_reference_meta(payload: &TransactionPayloadInner) ->
                         Some(MultisigTransactionPayload::EntryFunction(e.clone()))
                     },
                     _ => None,
-                }
+                },
             })
         },
-        None => {
-            match executable {
-                TransactionExecutable::EntryFunction(e) => {
-                    PayloadTypeReferenceMeta::UserEntryFunction(e.clone())
-                }
-                _ => {
-                    PayloadTypeReferenceMeta::Other
-                }
-            }
-        }
+        None => match executable {
+            TransactionExecutable::EntryFunction(e) => {
+                PayloadTypeReferenceMeta::UserEntryFunction(e.clone())
+            },
+            _ => PayloadTypeReferenceMeta::Other,
+        },
     }
 }
 
@@ -89,8 +85,12 @@ impl TransactionMetadata {
                 PayloadTypeReferenceMeta::UserEntryFunction(e.clone())
             },
             TransactionPayload::Multisig(m) => PayloadTypeReferenceMeta::Multisig(m.clone()),
-            TransactionPayload::AutomationRegistration(_) => PayloadTypeReferenceMeta::AutomationRegistration,
-            TransactionPayload::Payload(payload_inner) => convert_to_payload_type_reference_meta(payload_inner),
+            TransactionPayload::AutomationRegistration(_) => {
+                PayloadTypeReferenceMeta::AutomationRegistration
+            },
+            TransactionPayload::Payload(payload_inner) => {
+                convert_to_payload_type_reference_meta(payload_inner)
+            },
         };
         Self {
             sender: txn.sender(),
@@ -232,7 +232,10 @@ impl TransactionMetadata {
         };
         // Safe: txn_consensus_hash is always populated from HashValue::keccak_256_of or txn.hash(),
         // both of which produce exactly 32 bytes.
-        let txn_consensus_hash: [u8; 32] = self.txn_consensus_hash.as_slice().try_into()
+        let txn_consensus_hash: [u8; 32] = self
+            .txn_consensus_hash
+            .as_slice()
+            .try_into()
             .expect("txn_consensus_hash is always a 32-byte Keccak-256 hash");
         UserTransactionContext::new(
             self.sender,
diff --git a/aptos-move/aptos-vm/src/transaction_validation.rs b/aptos-move/aptos-vm/src/transaction_validation.rs
index 3487703c3cc..97eff2af79f 100644
--- a/aptos-move/aptos-vm/src/transaction_validation.rs
+++ b/aptos-move/aptos-vm/src/transaction_validation.rs
@@ -15,14 +15,16 @@ use crate::{
 use aptos_gas_algebra::Gas;
 use aptos_types::{
     account_config::constants::CORE_CODE_ADDRESS,
-   
     fee_statement::FeeStatement,
     move_utils::as_move_value::AsMoveValue,
     on_chain_config::Features,
-   
-    transaction::{automation::AutomationTaskType, {MultisigTransactionPayload, ReplayProtector, TransactionExecutableRef}},
+    transaction::{
+        automation::AutomationTaskType, MultisigTransactionPayload, ReplayProtector,
+        TransactionExecutableRef,
+    },
 };
 use aptos_vm_logging::log_schema::AdapterLogSchema;
+use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage;
 use fail::fail_point;
 use move_binary_format::errors::VMResult;
 use move_core_types::{
@@ -38,7 +40,6 @@ use move_vm_runtime::{
 };
 use move_vm_types::gas::UnmeteredGasMeter;
 use once_cell::sync::Lazy;
-use aptos_vm_types::module_and_script_storage::module_storage::AptosModuleStorage;
 
 pub static APTOS_TRANSACTION_VALIDATION: Lazy =
     Lazy::new(|| TransactionValidation {
@@ -436,12 +437,10 @@ pub(crate) fn run_multisig_prologue(
                 Some("Script payload not supported for multisig transactions".to_string()),
             ));
         },
-        TransactionExecutableRef::AutomationRegistration(params) => {
-            bcs::to_bytes(
-                &MultisigTransactionPayload::AutomationRegistration(params.clone()),
-            )
-                .map_err(|_| unreachable_error.clone())?
-        }
+        TransactionExecutableRef::AutomationRegistration(params) => bcs::to_bytes(
+            &MultisigTransactionPayload::AutomationRegistration(params.clone()),
+        )
+        .map_err(|_| unreachable_error.clone())?,
     };
 
     session
@@ -476,9 +475,7 @@ pub(crate) fn run_automated_transaction_prologue(
     traversal_context: &mut TraversalContext,
 ) -> Result<(), VMStatus> {
     let txn_task_id = match txn_data.replay_protector {
-        ReplayProtector::SequenceNumber(seq_num) => {
-            seq_num
-        },
+        ReplayProtector::SequenceNumber(seq_num) => seq_num,
         ReplayProtector::Nonce(_) => {
             unreachable!("AutomatedTransaction cannot have nonce")
         },
@@ -522,9 +519,7 @@ pub(crate) fn run_automated_transaction_prologue_v2(
     traversal_context: &mut TraversalContext,
 ) -> Result<(), VMStatus> {
     let txn_task_id = match txn_data.replay_protector {
-        ReplayProtector::SequenceNumber(seq_num) => {
-            seq_num
-        },
+        ReplayProtector::SequenceNumber(seq_num) => seq_num,
         ReplayProtector::Nonce(_) => {
             unreachable!("AutomatedTransaction cannot have nonce")
         },
@@ -742,7 +737,7 @@ fn run_automated_txn_epilogue(
                 serialize_values(&args),
                 &mut UnmeteredGasMeter,
                 traversal_context,
-                module_storage
+                module_storage,
             )
             .map(|_return_vals| ())
             .map_err(expect_no_verification_errors)?;
@@ -753,10 +748,10 @@ fn run_automated_txn_epilogue(
         match task_type {
             AutomationTaskType::User => {
                 emit_fee_statement(session, module_storage, fee_statement, traversal_context)?;
-            }
+            },
             AutomationTaskType::System => {
                 emit_as_gas_assessment(session, module_storage, fee_statement, traversal_context)?;
-            }
+            },
         }
     }
 
@@ -797,7 +792,7 @@ fn emit_as_gas_assessment(
             vec![bcs::to_bytes(&fee_statement).expect("Failed to serialize fee statement")],
             &mut UnmeteredGasMeter,
             traversal_context,
-            module_storage
+            module_storage,
         )
         .map(|_return_vals| ())
 }
@@ -908,7 +903,7 @@ pub(crate) fn run_failure_epilogue(
 /// stored in the `TRANSACTION_VALIDATION_MODULE` on chain.
 pub(crate) fn run_automated_txn_failure_epilogue(
     session: &mut SessionExt,
-    module_storage: & impl AptosModuleStorage,
+    module_storage: &impl AptosModuleStorage,
     gas_remaining: Gas,
     fee_statement: FeeStatement,
     features: &Features,
@@ -925,7 +920,7 @@ pub(crate) fn run_automated_txn_failure_epilogue(
         txn_data,
         task_type,
         features,
-        traversal_context
+        traversal_context,
     )
     .or_else(|err| {
         expect_only_successful_execution(
diff --git a/aptos-move/aptos-vm/src/validator_txns/dkg.rs b/aptos-move/aptos-vm/src/validator_txns/dkg.rs
index 1b4d2b3e19c..96489408b8d 100644
--- a/aptos-move/aptos-vm/src/validator_txns/dkg.rs
+++ b/aptos-move/aptos-vm/src/validator_txns/dkg.rs
@@ -6,14 +6,14 @@ use crate::{
     errors::expect_only_successful_execution,
     move_vm_ext::{AptosMoveResolver, SessionId},
     system_module_names::{FINISH_WITH_DKG_RESULT, RECONFIGURATION_WITH_DKG_MODULE, SET_DKG_META},
-    validator_txns::dkg::{
-        ExecutionFailure::{Expected, Unexpected},
-    },
+    validator_txns::dkg::ExecutionFailure::{Expected, Unexpected},
     AptosVM, VMValidator,
 };
 use aptos_types::{
-    dkg::{DKGState, DKGTrait, DKGTranscript, DefaultDKG},
-    dkg::transactions::{DKGTransactionData, DKGTransactionType},
+    dkg::{
+        transactions::{DKGTransactionData, DKGTransactionType},
+        DKGState, DKGTrait, DKGTranscript, DefaultDKG,
+    },
     move_utils::as_move_value::AsMoveValue,
     transaction::{ExecutionStatus, TransactionStatus},
     vm_status::DiscardedVMStatus,
diff --git a/aptos-move/aptos-vm/src/validator_txns/mod.rs b/aptos-move/aptos-vm/src/validator_txns/mod.rs
index 10906a43174..388dbb4de6d 100644
--- a/aptos-move/aptos-vm/src/validator_txns/mod.rs
+++ b/aptos-move/aptos-vm/src/validator_txns/mod.rs
@@ -27,7 +27,13 @@ impl AptosVM {
                     return Err(VMStatus::error(StatusCode::FEATURE_UNDER_GATING, None));
                 }
 
-                self.process_dkg_transaction(resolver, module_storage, log_context, session_id, dkg_node)
+                self.process_dkg_transaction(
+                    resolver,
+                    module_storage,
+                    log_context,
+                    session_id,
+                    dkg_node,
+                )
             },
             ValidatorTransaction::ObservedJWKUpdate(jwk_update) => self.process_jwk_update(
                 resolver,
diff --git a/aptos-move/e2e-move-tests/src/harness.rs b/aptos-move/e2e-move-tests/src/harness.rs
index b347006dabd..aec25ec2a71 100644
--- a/aptos-move/e2e-move-tests/src/harness.rs
+++ b/aptos-move/e2e-move-tests/src/harness.rs
@@ -40,7 +40,8 @@ use claims::assert_ok;
 use move_core_types::{
     language_storage::{StructTag, TypeTag},
     move_resource::MoveStructType,
-    value::MoveValue,vm_status::VMStatus
+    value::MoveValue,
+    vm_status::VMStatus,
 };
 use move_package::package_hooks::register_package_hooks;
 use once_cell::sync::Lazy;
diff --git a/aptos-move/e2e-move-tests/src/stake.rs b/aptos-move/e2e-move-tests/src/stake.rs
index 2d59099da04..791b8cf1727 100644
--- a/aptos-move/e2e-move-tests/src/stake.rs
+++ b/aptos-move/e2e-move-tests/src/stake.rs
@@ -4,14 +4,13 @@
 use crate::harness::MoveHarness;
 use aptos_cached_packages::aptos_stdlib;
 use aptos_crypto::{
-    ed25519, bls12381, SigningKey, PrivateKey, Uniform, 
-    bls12381::ProofOfPossession
+    bls12381, bls12381::ProofOfPossession, ed25519, PrivateKey, SigningKey, Uniform,
 };
 use aptos_language_e2e_tests::account::Account;
 use aptos_types::{
     account_address::AccountAddress, account_config::CORE_CODE_ADDRESS,
     on_chain_config::ValidatorSet, stake_pool::StakePool, transaction::TransactionStatus,
-    validator_config::ValidatorConfig, validator_public_keys::ValidatorPublicKeys
+    validator_config::ValidatorConfig, validator_public_keys::ValidatorPublicKeys,
 };
 use move_core_types::parser::parse_struct_tag;
 
@@ -20,7 +19,7 @@ pub fn generate_consensus_pub_key() -> Vec {
     let mut rng = rand::thread_rng();
     let network_key = ed25519::PrivateKey::generate_for_testing();
     let network_pubkey_bytes = network_key.public_key().to_bytes().to_vec();
-    
+
     let bls_key = bls12381::PrivateKey::generate(&mut rng);
     let bls_pub_key = bls12381::PublicKey::from(&bls_key);
     let bls_pubkey_bytes = bls_pub_key.to_bytes().to_vec();
diff --git a/aptos-move/e2e-move-tests/src/tests/account.rs b/aptos-move/e2e-move-tests/src/tests/account.rs
index 2449cbab191..7970eccf6d9 100644
--- a/aptos-move/e2e-move-tests/src/tests/account.rs
+++ b/aptos-move/e2e-move-tests/src/tests/account.rs
@@ -1,10 +1,9 @@
 // Copyright © Aptos Foundation
 // SPDX-License-Identifier: Apache-2.0
 
-use crate::MoveHarness;
+use crate::{assert_success, MoveHarness};
 use aptos_cached_packages::aptos_stdlib::supra_account_transfer;
 use aptos_language_e2e_tests::account::Account;
-use crate::assert_success;
 
 #[test]
 #[should_panic] // as we disabled the default account feature
diff --git a/aptos-move/e2e-move-tests/src/tests/automation_registry.rs b/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
index fc5bfba0cee..5471e33b8f2 100644
--- a/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
+++ b/aptos-move/e2e-move-tests/src/tests/automation_registry.rs
@@ -80,10 +80,9 @@ fn setup_harness_with_v2_1() -> MoveHarness {
 
 /// Same setup but deliberately *without* SUPRA_AUTOMATION_V2_1, to test the disabled path.
 fn setup_harness_without_v2_1() -> MoveHarness {
-    let mut h = MoveHarness::new_with_features(
-        vec![FeatureFlag::SUPRA_NATIVE_AUTOMATION],
-        vec![FeatureFlag::SUPRA_AUTOMATION_V2_1],
-    );
+    let mut h = MoveHarness::new_with_features(vec![FeatureFlag::SUPRA_NATIVE_AUTOMATION], vec![
+        FeatureFlag::SUPRA_AUTOMATION_V2_1,
+    ]);
     h.executor
         .exec("automation_registry", "on_new_epoch", vec![], vec![]);
     h
@@ -137,11 +136,7 @@ fn get_task_details(h: &mut MoveHarness, task_index: u64) -> AutomationTaskMetaD
 ///
 /// Returning the `SignedTransaction` before submission allows the caller to compute its
 /// Keccak-256 hash and then verify that the same bytes end up stored in the registry.
-fn build_register_txn(
-    h: &mut MoveHarness,
-    user: &Account,
-    expiry_time: u64,
-) -> SignedTransaction {
+fn build_register_txn(h: &mut MoveHarness, user: &Account, expiry_time: u64) -> SignedTransaction {
     h.create_entry_function(
         user,
         str::parse("0xDEADBEEF::automation_contract_test::register_via_contract").unwrap(),
diff --git a/aptos-move/e2e-move-tests/src/tests/fee_payer.rs b/aptos-move/e2e-move-tests/src/tests/fee_payer.rs
index 56c56dd4c3b..586a2367c7b 100644
--- a/aptos-move/e2e-move-tests/src/tests/fee_payer.rs
+++ b/aptos-move/e2e-move-tests/src/tests/fee_payer.rs
@@ -344,10 +344,13 @@ fn test_account_not_exist_with_fee_payer_without_create_account() {
     // Note: (DP)
     // Both this feature needs to be enabled as default account feature is disabled.
     // If we turn on default account feature then it is fine if sponsored feature is disabled.
-    let mut h = MoveHarness::new_with_features(vec![
-        FeatureFlag::GAS_PAYER_ENABLED, 
-        FeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_V1_CREATION
-    ], vec![]);
+    let mut h = MoveHarness::new_with_features(
+        vec![
+            FeatureFlag::GAS_PAYER_ENABLED,
+            FeatureFlag::SPONSORED_AUTOMATIC_ACCOUNT_V1_CREATION,
+        ],
+        vec![],
+    );
 
     let alice = Account::new();
     let bob = h.new_account_at(AccountAddress::from_hex_literal("0xb0b").unwrap());
diff --git a/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs b/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs
index ce64babe212..bd2ab5ba862 100644
--- a/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs
+++ b/aptos-move/e2e-move-tests/src/tests/fungible_asset.rs
@@ -2,13 +2,13 @@
 // SPDX-License-Identifier: Apache-2.0
 
 use crate::{assert_success, tests::common, BlockSplit, MoveHarness, SUCCESS};
-use aptos_cached_packages::aptos_stdlib::{supra_account_batch_transfer, aptos_coin_transfer};
+use aptos_cached_packages::aptos_stdlib::{aptos_coin_transfer, supra_account_batch_transfer};
 use aptos_language_e2e_tests::{
     account::Account,
     executor::{ExecutorMode, FakeExecutor},
 };
 use aptos_types::{
-    account_address::{self, AccountAddress},    
+    account_address::{self, AccountAddress},
     on_chain_config::FeatureFlag,
 };
 use move_core_types::{
diff --git a/aptos-move/e2e-move-tests/src/tests/mod.rs b/aptos-move/e2e-move-tests/src/tests/mod.rs
index 32e2876fdb1..9117965d4e5 100644
--- a/aptos-move/e2e-move-tests/src/tests/mod.rs
+++ b/aptos-move/e2e-move-tests/src/tests/mod.rs
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: Apache-2.0
 
 mod access_path_test;
-mod automation_registry;
 mod account;
 mod aggregator;
 mod aggregator_v2;
@@ -12,6 +11,7 @@ mod aggregator_v2_function_values;
 mod aggregator_v2_runtime_checks;
 mod any;
 mod attributes;
+mod automation_registry;
 mod bcs;
 mod chain_id;
 mod code_publishing;
diff --git a/aptos-move/e2e-tests/src/executor.rs b/aptos-move/e2e-tests/src/executor.rs
index 8c207146d0a..3d5184ec2ee 100644
--- a/aptos-move/e2e-tests/src/executor.rs
+++ b/aptos-move/e2e-tests/src/executor.rs
@@ -56,7 +56,7 @@ use aptos_types::{
     },
     vm_status::VMStatus,
     write_set::{WriteOp, WriteSet, WriteSetMut},
-    SupraCoinType, CoinType,
+    CoinType, SupraCoinType,
 };
 use aptos_validator_interface::{DebuggerStateView, RestDebuggerInterface};
 use aptos_vm::{
@@ -715,9 +715,14 @@ impl FakeExecutor {
     /// Executes the transaction as a singleton block and applies the resulting write set to the
     /// data store. Panics if execution fails
     pub fn execute_and_apply_transaction(&mut self, transaction: Transaction) -> TransactionOutput {
-        let mut outputs = self.execute_transaction_block(vec![transaction.clone()]).unwrap();
+        let mut outputs = self
+            .execute_transaction_block(vec![transaction.clone()])
+            .unwrap();
         assert_eq!(outputs.len(), 1, "transaction outputs size mismatch");
-        println!("transaction execution output: {:#?} : {:#?}", outputs, transaction);
+        println!(
+            "transaction execution output: {:#?} : {:#?}",
+            outputs, transaction
+        );
         let output = outputs.pop().unwrap();
         match output.status() {
             TransactionStatus::Keep(status) => {
@@ -737,7 +742,8 @@ impl FakeExecutor {
                     status,
                     &ExecutionStatus::Success,
                     "transaction failed with {:?}, {:?}",
-                    status,  transaction
+                    status,
+                    transaction
                 );
                 output
             },
@@ -1330,7 +1336,12 @@ impl FakeExecutor {
                 .as_ref()
                 .unwrap()
                 .change_set_configs;
-            finish_session_assert_no_modules(session, &module_storage, change_set_configs, &resolver)
+            finish_session_assert_no_modules(
+                session,
+                &module_storage,
+                change_set_configs,
+                &resolver,
+            )
         };
         self.state_store.apply_write_set(&write_set).unwrap();
 
diff --git a/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs b/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs
index 3076a277eb0..2201536620b 100644
--- a/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs
+++ b/aptos-move/e2e-testsuite/src/tests/automated_transactions.rs
@@ -17,9 +17,7 @@ use aptos_types::{
     },
 };
 use move_core_types::{
-    account_address::AccountAddress,
-    identifier::Identifier,
-    language_storage::ModuleId,
+    account_address::AccountAddress, identifier::Identifier, language_storage::ModuleId,
     vm_status::StatusCode,
 };
 
@@ -71,12 +69,11 @@ fn make_nonexistent_entry_function() -> EntryFunction {
             // 0x0 never has user modules deployed; "phantom_automation_mod" is
             // deliberately absent from the genesis framework.
             AccountAddress::ZERO,
-            Identifier::new("phantom_automation_mod")
-                .expect("identifier must be valid"),
+            Identifier::new("phantom_automation_mod").expect("identifier must be valid"),
         ),
         Identifier::new("phantom_fn").expect("identifier must be valid"),
-        vec![],  // no type arguments
-        vec![],  // no runtime arguments (function signature is irrelevant — it doesn't exist)
+        vec![], // no type arguments
+        vec![], // no runtime arguments (function signature is irrelevant — it doesn't exist)
     )
 }
 
@@ -257,9 +254,9 @@ fn check_automated_transaction_successful_execution() {
         0,
         inner_entry_function.clone(),
         expiration_time,
-        TASK_GAS_PRICE_CAP,   // gas_price_cap = 100
-        TASK_MAX_GAS_AMOUNT,  // max_gas_amount = 1 000
-        AUTOMATION_FEE_CAP,   // automation_fee_cap_for_epoch = 100 000
+        TASK_GAS_PRICE_CAP,  // gas_price_cap = 100
+        TASK_MAX_GAS_AMOUNT, // max_gas_amount = 1 000
+        AUTOMATION_FEE_CAP,  // automation_fee_cap_for_epoch = 100 000
     );
 
     let output = test_context.execute_and_apply(automation_txn);
@@ -358,16 +355,14 @@ fn check_valid_payload_task_registered_without_validation_executes_successfully(
     test_context.set_supra_native_automation(true);
 
     let dest_account = test_context.new_account_data(0, 0);
-    let inner_fn = aptos_framework_sdk_builder::supra_account_transfer(
-        dest_account.address().clone(),
-        100,
-    )
-    .into_entry_function();
+    let inner_fn =
+        aptos_framework_sdk_builder::supra_account_transfer(dest_account.address().clone(), 100)
+            .into_entry_function();
 
     // BCS-encode the valid EntryFunction — this is what the registry stores as
     // `payload_tx` in both the validated and the non-validated registration paths.
-    let valid_payload_bytes = bcs::to_bytes(&inner_fn)
-        .expect("EntryFunction must BCS-serialize successfully");
+    let valid_payload_bytes =
+        bcs::to_bytes(&inner_fn).expect("EntryFunction must BCS-serialize successfully");
 
     let expiry_time = test_context.chain_time_now() + 8_000;
     let sender_address = test_context.sender_account_address();
@@ -396,15 +391,14 @@ fn check_valid_payload_task_registered_without_validation_executes_successfully(
 
     let automated_txn = build_automated_txn(
         &mut test_context,
-        0,          // task_index
-        inner_fn,   // the same valid entry function
-        1,          // gas_unit_price (≤ TASK_GAS_PRICE_CAP)
+        0,        // task_index
+        inner_fn, // the same valid entry function
+        1,        // gas_unit_price (≤ TASK_GAS_PRICE_CAP)
         expiry_time,
     );
 
     // The entry function exists and its arguments match — execution must succeed.
-    let output =
-        test_context.execute_and_apply_transaction(automated_txn.into());
+    let output = test_context.execute_and_apply_transaction(automated_txn.into());
     assert_eq!(
         output.status(),
         &TransactionStatus::Keep(ExecutionStatus::Success),
@@ -414,8 +408,7 @@ fn check_valid_payload_task_registered_without_validation_executes_successfully(
     // Verify the transfer actually happened.
     let dest_balance = test_context.account_balance(*dest_account.address());
     assert_eq!(
-        dest_balance,
-        100,
+        dest_balance, 100,
         "100 tokens should have been transferred to dest_account"
     );
 }
@@ -485,19 +478,12 @@ fn check_invalid_inner_payload_is_discarded_when_v2_1_enabled() {
     // Build the automated transaction carrying the non-existent entry function.
     // The builder itself succeeds because it only BCS-decodes the stored bytes
     // (which are valid) — it does not query the VM for module existence.
-    let automated_txn = build_automated_txn(
-        &mut test_context,
-        0,
-        nonexistent_fn,
-        1,
-        expiry_time,
-    );
+    let automated_txn = build_automated_txn(&mut test_context, 0, nonexistent_fn, 1, expiry_time);
 
     // Execute without applying state changes.  We use execute_tagged_transaction
     // because the output is DISCARDED (no write set to apply) and
     // execute_and_apply_transaction panics on discarded outputs.
-    let output = test_context
-        .execute_tagged_transaction(automated_txn.into());
+    let output = test_context.execute_tagged_transaction(automated_txn.into());
 
     // With SUPRA_AUTOMATION_V2_1 enabled the processor's special path triggers:
     // the output is discarded and no failure epilogue runs.
@@ -517,8 +503,7 @@ fn check_invalid_inner_payload_is_discarded_when_v2_1_enabled() {
     // no write set.  (execute_tagged_transaction does not apply state.)
     let balance_after_exec = test_context.account_balance(sender_address);
     assert_eq!(
-        balance_before_exec,
-        balance_after_exec,
+        balance_before_exec, balance_after_exec,
         "balance must not change when the automated transaction is discarded"
     );
 }
@@ -557,8 +542,8 @@ fn check_invalid_inner_payload_charges_fee_when_v2_1_disabled() {
     test_context.set_feature_flag(FeatureFlag::SUPRA_AUTOMATION_V2_1, false);
 
     let nonexistent_fn = make_nonexistent_entry_function();
-    let invalid_payload_bytes = bcs::to_bytes(&nonexistent_fn)
-        .expect("EntryFunction must BCS-serialize successfully");
+    let invalid_payload_bytes =
+        bcs::to_bytes(&nonexistent_fn).expect("EntryFunction must BCS-serialize successfully");
 
     let expiry_time = test_context.chain_time_now() + 8_000;
     let sender_address = test_context.sender_account_address();
@@ -588,19 +573,12 @@ fn check_invalid_inner_payload_charges_fee_when_v2_1_disabled() {
 
     let balance_before_exec = test_context.account_balance(sender_address);
 
-    let automated_txn = build_automated_txn(
-        &mut test_context,
-        0,
-        nonexistent_fn,
-        1,
-        expiry_time,
-    );
+    let automated_txn = build_automated_txn(&mut test_context, 0, nonexistent_fn, 1, expiry_time);
 
     // Execute via execute_tagged_transaction so we can inspect the output before
     // deciding whether to apply it.  The output is Keep(MiscellaneousError),
     // so the write set contains gas-deduction entries.
-    let output = test_context
-        .execute_tagged_transaction(automated_txn.into());
+    let output = test_context.execute_tagged_transaction(automated_txn.into());
 
     // Without V2_1 the special discard path is bypassed; the failure epilogue
     // runs and the output is Keep(MiscellaneousError).
@@ -728,9 +706,7 @@ fn check_transient_execution_failure_charges_fee_regardless_of_v2_1() {
         TransactionStatus::Keep(ExecutionStatus::MoveAbort { .. }) => {
             // Expected: the execution body aborted at runtime.
         },
-        other => panic!(
-            "expected Keep(MoveAbort) for runtime abort, got: {other:?}"
-        ),
+        other => panic!("expected Keep(MoveAbort) for runtime abort, got: {other:?}"),
     }
 
     // Gas must have been charged by the failure epilogue.
@@ -753,8 +729,7 @@ fn check_transient_execution_failure_charges_fee_regardless_of_v2_1() {
     // was rolled back as part of the abort.
     let dest_balance = test_context.account_balance(*dest_account.address());
     assert_eq!(
-        dest_balance,
-        0,
+        dest_balance, 0,
         "destination must not receive tokens when the transfer aborts"
     );
 }
@@ -842,4 +817,4 @@ fn check_transient_execution_failure_charges_fee_when_v2_1_disabled() {
         balance_after_exec < balance_before_exec,
         "sender balance must decrease (before = {balance_before_exec}, after = {balance_after_exec})"
     );
-}
\ No newline at end of file
+}
diff --git a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
index b532daf8a22..72bb6f6aa4d 100644
--- a/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
+++ b/aptos-move/e2e-testsuite/src/tests/automation_registration.rs
@@ -7,7 +7,6 @@ use aptos_language_e2e_tests::{
     account::{Account, AccountData},
     executor::FakeExecutor,
 };
-use aptos_types::state_store::StateView;
 use aptos_types::{
     account_address::create_multisig_account_address,
     contract_event::ContractEvent,
@@ -15,6 +14,7 @@ use aptos_types::{
         AutomationCycleDetails, AutomationCycleInfo, AutomationCycleState, FeatureFlag,
         OnChainConfig,
     },
+    state_store::StateView,
     transaction::{
         automation::{
             AutomationRegistryAction, AutomationRegistryRecord, AutomationTaskMetaData, Priority,
@@ -557,25 +557,20 @@ impl AutomationRegistrationTestContext {
         // EntryFunction shape) execute here — only the Move code inside `register` runs.
         // This means `payload_bytes` is stored verbatim, even if it encodes a call to a
         // non-existent module/function.
-        self.executor.exec("automation_registry", "register", vec![], vec![
-            MoveValue::Signer(owner_address)
-                .simple_serialize()
-                .expect("Signer serialization must not fail"),
-            bcs::to_bytes(&payload_bytes)
-                .expect("payload bytes must be BCS-serialisable"),
-            bcs::to_bytes(&expiry_time)
-                .expect("expiry_time must be BCS-serialisable"),
-            bcs::to_bytes(&max_gas_amount)
-                .expect("max_gas_amount must be BCS-serialisable"),
-            bcs::to_bytes(&gas_price_cap)
-                .expect("gas_price_cap must be BCS-serialisable"),
-            bcs::to_bytes(&automation_fee_cap)
-                .expect("automation_fee_cap must be BCS-serialisable"),
-            bcs::to_bytes(&tx_hash)
-                .expect("tx_hash must be BCS-serialisable"),
-            bcs::to_bytes(&aux_data)
-                .expect("aux_data must be BCS-serialisable"),
-        ]);
+        self.executor
+            .exec("automation_registry", "register", vec![], vec![
+                MoveValue::Signer(owner_address)
+                    .simple_serialize()
+                    .expect("Signer serialization must not fail"),
+                bcs::to_bytes(&payload_bytes).expect("payload bytes must be BCS-serialisable"),
+                bcs::to_bytes(&expiry_time).expect("expiry_time must be BCS-serialisable"),
+                bcs::to_bytes(&max_gas_amount).expect("max_gas_amount must be BCS-serialisable"),
+                bcs::to_bytes(&gas_price_cap).expect("gas_price_cap must be BCS-serialisable"),
+                bcs::to_bytes(&automation_fee_cap)
+                    .expect("automation_fee_cap must be BCS-serialisable"),
+                bcs::to_bytes(&tx_hash).expect("tx_hash must be BCS-serialisable"),
+                bcs::to_bytes(&aux_data).expect("aux_data must be BCS-serialisable"),
+            ]);
     }
 }
 
diff --git a/aptos-move/e2e-testsuite/src/tests/create_account.rs b/aptos-move/e2e-testsuite/src/tests/create_account.rs
index 0683caea7f3..40280974393 100644
--- a/aptos-move/e2e-testsuite/src/tests/create_account.rs
+++ b/aptos-move/e2e-testsuite/src/tests/create_account.rs
@@ -6,10 +6,13 @@ use aptos_language_e2e_tests::{
     account::Account, common_transactions::create_account_txn, current_function_name,
     executor::FakeExecutor,
 };
-use aptos_types::transaction::{ExecutionStatus, TransactionStatus};
-use aptos_types::{account_config::CoinStoreResource, SupraCoinType};
+use aptos_types::{
+    account_config::CoinStoreResource,
+    transaction::{ExecutionStatus, TransactionStatus},
+    SupraCoinType,
+};
 
-// FIX(DP): as default features to FA transfer and default account is disabled 
+// FIX(DP): as default features to FA transfer and default account is disabled
 // we need to change this test accordingly
 #[test]
 fn create_account() {
diff --git a/aptos-move/e2e-testsuite/src/tests/verify_txn.rs b/aptos-move/e2e-testsuite/src/tests/verify_txn.rs
index 23c3f2d94fd..d9fdfec80fc 100644
--- a/aptos-move/e2e-testsuite/src/tests/verify_txn.rs
+++ b/aptos-move/e2e-testsuite/src/tests/verify_txn.rs
@@ -268,7 +268,7 @@ fn verify_simple_payment() {
 
     // FIX(DP): as Default Account feature is not enabled the validation will fail
     // which says the account does not exists.
-    
+
     // Create a new transaction from a bogus account that doesn't exist
     // let bogus_account = executor.create_raw_account_data(100_000, 10);
     // let txn = bogus_account
diff --git a/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs b/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs
index 2be9f43215f..ff4acca03ac 100644
--- a/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs
+++ b/aptos-move/e2e-testsuite/src/tests/vm_viewer.rs
@@ -79,7 +79,10 @@ fn test_vm_viewer() {
     let viewer_ifc_time = Instant::now();
     let time = Instant::now();
     let vm_viewer = AptosVMViewer::new(test_executor.state_store());
-    debug!("AptosVMViewer creation time: {}", time.elapsed().as_secs_f64());
+    debug!(
+        "AptosVMViewer creation time: {}",
+        time.elapsed().as_secs_f64()
+    );
     let actual_results = accounts
         .iter()
         .map(|account| {
diff --git a/aptos-move/framework/cached-packages/src/aptos_stdlib.rs b/aptos-move/framework/cached-packages/src/aptos_stdlib.rs
index 7d2627ece52..f84d32e99fa 100644
--- a/aptos-move/framework/cached-packages/src/aptos_stdlib.rs
+++ b/aptos-move/framework/cached-packages/src/aptos_stdlib.rs
@@ -12,7 +12,7 @@ use aptos_package_builder::PackageBuilder;
 use aptos_types::{
     account_address::AccountAddress,
     transaction::{EntryFunction, TransactionPayload},
-    SupraCoinType, CoinType,
+    CoinType, SupraCoinType,
 };
 use move_core_types::{ident_str, language_storage::ModuleId};
 
diff --git a/aptos-move/framework/src/natives/transaction_context.rs b/aptos-move/framework/src/natives/transaction_context.rs
index 465813c0647..f5c8f50195c 100644
--- a/aptos-move/framework/src/natives/transaction_context.rs
+++ b/aptos-move/framework/src/natives/transaction_context.rs
@@ -392,7 +392,6 @@ fn native_get_transaction_consensus_hash_internal(
     _ty_args: Vec,
     _args: VecDeque,
 ) -> SafeNativeResult> {
-
     context.charge(TRANSACTION_CONTEXT_GET_TXN_CONSENSUS_HASH_BASE)?;
 
     let user_transaction_context_opt = get_user_transaction_context_opt_from_context(context);
diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs
index 6f1324fe3ee..9a9745f73cf 100644
--- a/aptos-move/vm-genesis/src/lib.rs
+++ b/aptos-move/vm-genesis/src/lib.rs
@@ -8,8 +8,7 @@ mod genesis_context;
 
 use crate::genesis_context::GenesisStateView;
 use aptos_crypto::{
-    bls12381,
-    ed25519,
+    bls12381, ed25519,
     ed25519::{Ed25519PrivateKey, Ed25519PublicKey},
     HashValue, PrivateKey, Uniform,
 };
@@ -20,7 +19,7 @@ use aptos_gas_schedule::{
 use aptos_types::{
     account_address::{create_resource_address, create_seed_for_pbo_module},
     account_config::{
-        self, CORE_CODE_ADDRESS, aptos_test_root_address, events::NewEpochEvent,
+        self, aptos_test_root_address, events::NewEpochEvent, CORE_CODE_ADDRESS,
         EXPERIMENTAL_CODE_ADDRESS,
     },
     chain_id::ChainId,
@@ -36,7 +35,11 @@ use aptos_types::{
     },
     move_utils::as_move_value::AsMoveValue,
     on_chain_config::{
-        APTOS_MAX_KNOWN_VERSION, AutomationRegistryConfig, BanRegistryParameters, FeatureFlag, Features, GasScheduleV2, OnChainConsensusConfig, OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct, randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit}
+        randomness_api_v0_config::{AllowCustomMaxGasFlag, RequiredGasDeposit},
+        AutomationRegistryConfig, BanRegistryParameters, FeatureFlag, Features, GasScheduleV2,
+        OnChainConsensusConfig, OnChainEvmConfig, OnChainEvmContractsDetails,
+        OnChainEvmGenesisConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig,
+        OnChainRandomnessConfig, RandomnessConfigMoveStruct, APTOS_MAX_KNOWN_VERSION,
     },
     state_store::state_key::StateKey,
     transaction::{authenticator::AuthenticationKey, ChangeSet, Transaction, WriteSetPayload},
@@ -73,11 +76,9 @@ use once_cell::sync::Lazy;
 use rand::prelude::*;
 use serde::{Deserialize, Serialize};
 use std::{
-    collections::BTreeSet,
+    collections::{BTreeMap, BTreeSet},
     hash::{Hash, Hasher},
 };
-use aptos_types::on_chain_config::{OnChainEvmContractsDetails, OnChainEvmConfig};
-use std::collections::BTreeMap;
 
 // The seed is arbitrarily picked to produce a consistent key. XXX make this more formal?
 const GENESIS_SEED: [u8; 32] = [42; 32];
@@ -209,26 +210,72 @@ pub fn encode_supra_mainnet_genesis_transaction(
             .map(Features::into_flag_vec),
     );
     initialize_supra_coin(&mut session, &module_storage, &mut traversal_context);
-    initialize_supra_native_automation(&mut session, &module_storage, &mut traversal_context, genesis_config);
-    initialize_on_chain_governance(&mut session, &module_storage, &mut traversal_context, genesis_config);
-    create_accounts(&mut session, &module_storage, &mut traversal_context, accounts);
+    initialize_supra_native_automation(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        genesis_config,
+    );
+    initialize_on_chain_governance(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        genesis_config,
+    );
+    create_accounts(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        accounts,
+    );
 
     if let Some(owner_group) = owner_group {
-        create_multiple_multisig_accounts_with_schema(&mut session, &module_storage, &mut traversal_context, owner_group);
+        create_multiple_multisig_accounts_with_schema(
+            &mut session,
+            &module_storage,
+            &mut traversal_context,
+            owner_group,
+        );
     }
 
-    create_multisig_accounts_with_balance(&mut session, &module_storage, &mut traversal_context, multisig_accounts);
+    create_multisig_accounts_with_balance(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        multisig_accounts,
+    );
 
     // All PBO delegated validators are initialized here
-    create_pbo_delegation_pools(&mut session, &module_storage, &mut traversal_context, delegation_pools);
+    create_pbo_delegation_pools(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        delegation_pools,
+    );
 
-    add_owner_stakes_for_delegation_pools(&mut session, &module_storage, &mut traversal_context, delegation_pools, owner_stake_for_pbo_pool);
+    add_owner_stakes_for_delegation_pools(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        delegation_pools,
+        owner_stake_for_pbo_pool,
+    );
 
     // PBO vesting accounts, employees, investors etc. are placed in their vesting pools
-    create_vesting_without_staking_pools(&mut session, &module_storage, &mut traversal_context, vesting_pools);
+    create_vesting_without_staking_pools(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        vesting_pools,
+    );
 
     // Lock up the remaining available balances of the accounts for TGE
-    create_vesting_without_staking_pools(&mut session, &module_storage, &mut traversal_context, initial_unlock_vesting_pools);
+    create_vesting_without_staking_pools(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        initial_unlock_vesting_pools,
+    );
 
     set_genesis_end(&mut session, &module_storage, &mut traversal_context);
 
@@ -274,7 +321,7 @@ pub fn encode_genesis_transaction_for_testnet(
     supra_config_bytes: Vec,
     evm_genesis_config: Option,
     evm_contracts_details: Option,
-    evm_scalar_config: Option
+    evm_scalar_config: Option,
 ) -> Transaction {
     Transaction::GenesisTransaction(WriteSetPayload::Direct(
         encode_genesis_change_set_for_testnet(
@@ -296,7 +343,7 @@ pub fn encode_genesis_transaction_for_testnet(
             supra_config_bytes,
             evm_genesis_config,
             evm_contracts_details,
-            evm_scalar_config
+            evm_scalar_config,
         ),
     ))
 }
@@ -320,8 +367,7 @@ pub fn encode_genesis_change_set_for_testnet(
     supra_config_bytes: Vec,
     evm_genesis_config: Option,
     evm_contracts_details: Option,
-    evm_scalar_config: Option
-
+    evm_scalar_config: Option,
 ) -> ChangeSet {
     validate_genesis_config(genesis_config);
     // Create a Move VM session so we can invoke on-chain genesis initializations.
@@ -374,7 +420,12 @@ pub fn encode_genesis_change_set_for_testnet(
     } else {
         initialize_supra_coin(&mut session, &module_storage, &mut traversal_context);
     }
-    initialize_supra_native_automation(&mut session, &module_storage, &mut traversal_context, genesis_config);
+    initialize_supra_native_automation(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        genesis_config,
+    );
     initialize_config_buffer(&mut session, &module_storage, &mut traversal_context);
     initialize_dkg(&mut session, &module_storage, &mut traversal_context);
     initialize_reconfiguration_state(&mut session, &module_storage, &mut traversal_context);
@@ -397,23 +448,56 @@ pub fn encode_genesis_change_set_for_testnet(
         &mut traversal_context,
         genesis_config,
     );
-    initialize_leader_ban_config(&mut session, &module_storage, &mut traversal_context, genesis_config);
+    initialize_leader_ban_config(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        genesis_config,
+    );
 
     if let Some(evm_genesis_config) = evm_genesis_config {
-        initialize_evm_genesis_config(&mut session, &module_storage, &mut traversal_context, &evm_genesis_config);
+        initialize_evm_genesis_config(
+            &mut session,
+            &module_storage,
+            &mut traversal_context,
+            &evm_genesis_config,
+        );
     }
 
-    if let (Some(evm_contracts_details), Some(evm_scalar_config)) = (evm_contracts_details, evm_scalar_config) {
-        initialize_evm_config(&mut session, &module_storage, &mut traversal_context, evm_contracts_details, evm_scalar_config);
+    if let (Some(evm_contracts_details), Some(evm_scalar_config)) =
+        (evm_contracts_details, evm_scalar_config)
+    {
+        initialize_evm_config(
+            &mut session,
+            &module_storage,
+            &mut traversal_context,
+            evm_contracts_details,
+            evm_scalar_config,
+        );
     }
 
-    create_accounts(&mut session, &module_storage, &mut traversal_context, accounts);
+    create_accounts(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        accounts,
+    );
 
     if let Some(owner_group) = owner_group {
-        create_multiple_multisig_accounts_with_schema(&mut session, &module_storage, &mut traversal_context, owner_group);
+        create_multiple_multisig_accounts_with_schema(
+            &mut session,
+            &module_storage,
+            &mut traversal_context,
+            owner_group,
+        );
     }
 
-    create_multisig_accounts_with_balance(&mut session, &module_storage, &mut traversal_context, multisig_account);
+    create_multisig_accounts_with_balance(
+        &mut session,
+        &module_storage,
+        &mut traversal_context,
+        multisig_account,
+    );
     initialize_account_abstraction(&mut session, &module_storage, &mut traversal_context);
 
     if validators.len() > 0 {
@@ -425,7 +509,12 @@ pub fn encode_genesis_change_set_for_testnet(
         );
     } else {
         // All PBO delegated validators are initialized here
-        create_pbo_delegation_pools(&mut session, &module_storage, &mut traversal_context, delegation_pools);
+        create_pbo_delegation_pools(
+            &mut session,
+            &module_storage,
+            &mut traversal_context,
+            delegation_pools,
+        );
 
         add_owner_stakes_for_delegation_pools(
             &mut session,
@@ -436,10 +525,20 @@ pub fn encode_genesis_change_set_for_testnet(
         );
 
         // PBO vesting accounts, employees, investors etc. are placed in their vesting pools
-        create_vesting_without_staking_pools(&mut session, &module_storage, &mut traversal_context, vesting_pools);
+        create_vesting_without_staking_pools(
+            &mut session,
+            &module_storage,
+            &mut traversal_context,
+            vesting_pools,
+        );
 
         // Lock up the remaining available balances of the accounts for TGE
-        create_vesting_without_staking_pools(&mut session, &module_storage, &mut traversal_context, initial_unlock_vesting_pools);
+        create_vesting_without_staking_pools(
+            &mut session,
+            &module_storage,
+            &mut traversal_context,
+            initial_unlock_vesting_pools,
+        );
     }
 
     if genesis_config.is_test {
@@ -779,7 +878,6 @@ fn initialize_evm_config(
     evm_contracts_details: OnChainEvmContractsDetails,
     evm_scalar_config: OnChainEvmConfig,
 ) {
-
     let (contract_names, contract_addresses) = evm_contracts_details.to_move_values();
     let (config_keys, config_values) = evm_scalar_config.to_move_values();
 
@@ -795,7 +893,7 @@ fn initialize_evm_config(
             contract_names,
             contract_addresses,
             config_keys,
-            config_values
+            config_values,
         ]),
     );
 }
@@ -1185,8 +1283,8 @@ fn create_accounts(
         exec_function(
             session,
             module_storage,
-        traversal_context,
-        GENESIS_MODULE_NAME,
+            traversal_context,
+            GENESIS_MODULE_NAME,
             "create_accounts",
             vec![],
             serialized_values,
@@ -1198,7 +1296,7 @@ fn create_accounts(
 /// the required accounts, sets the validator operators for each validator owner, and sets the
 /// validator config on-chain.
 fn create_and_initialize_validators(
-    session: &mut SessionExt, 
+    session: &mut SessionExt,
     module_storage: &impl ModuleStorage,
     traversal_context: &mut TraversalContext,
     validators: &[Validator],
@@ -1274,7 +1372,6 @@ fn create_multiple_multisig_accounts_with_schema(
 }
 
 fn create_multisig_accounts_with_balance(
-
     session: &mut SessionExt,
     module_storage: &impl AptosModuleStorage,
     traversal_context: &mut TraversalContext,
@@ -2017,8 +2114,10 @@ pub fn test_mainnet_end_to_end() {
         TOTAL_SUPPLY - (21 * pbo_balance) - (7 * operator_balance) - (9 * employee_balance);
 
     use aptos_types::{
-        account_address, on_chain_config::ValidatorSet, state_store::state_key::StateKey,
-        write_set::TransactionWrite, write_set::WriteSet
+        account_address,
+        on_chain_config::ValidatorSet,
+        state_store::state_key::StateKey,
+        write_set::{TransactionWrite, WriteSet},
     };
 
     let balance = 10_000_000 * APTOS_COINS_BASE_WITH_DECIMALS;
diff --git a/consensus/consensus-types/src/round_timeout.rs b/consensus/consensus-types/src/round_timeout.rs
index bbe96751861..3f662501371 100644
--- a/consensus/consensus-types/src/round_timeout.rs
+++ b/consensus/consensus-types/src/round_timeout.rs
@@ -101,7 +101,7 @@ impl RoundTimeout {
                 self.author(),
                 &self.timeout.signing_format(),
                 // &self.signature,
-                &aptos_crypto::ed25519::Signature::dummy_signature()
+                &aptos_crypto::ed25519::Signature::dummy_signature(),
             )
             .context("Failed to verify 2-chain timeout signature")?;
         Ok(())
diff --git a/consensus/safety-rules/src/persistent_safety_storage.rs b/consensus/safety-rules/src/persistent_safety_storage.rs
index c74ebd7ecf6..c22f8bda01d 100644
--- a/consensus/safety-rules/src/persistent_safety_storage.rs
+++ b/consensus/safety-rules/src/persistent_safety_storage.rs
@@ -96,9 +96,7 @@ impl PersistentSafetyStorage {
         Ok(self.internal_store.get(OWNER_ACCOUNT).map(|v| v.value)?)
     }
 
-    pub fn default_consensus_sk(
-        &self,
-    ) -> Result {
+    pub fn default_consensus_sk(&self) -> Result {
         self.internal_store
             .get::(CONSENSUS_KEY)
             .map(|v| v.value)
diff --git a/consensus/src/epoch_manager.rs b/consensus/src/epoch_manager.rs
index 90b2f23f59d..900fa975c2d 100644
--- a/consensus/src/epoch_manager.rs
+++ b/consensus/src/epoch_manager.rs
@@ -1936,8 +1936,7 @@ impl EpochManager

{ fn load_consensus_key(&self, vv: &ValidatorVerifier) -> anyhow::Result { match vv.get_public_key(&self.author) { - Some(pk) => - self + Some(pk) => self .key_storage .consensus_sk_by_pk(pk) .map_err(|e| anyhow!("could not find sk by pk: {:?}", e)), diff --git a/consensus/src/quorum_store/counters.rs b/consensus/src/quorum_store/counters.rs index 7ba529e4b9f..73f77a0f9e0 100644 --- a/consensus/src/quorum_store/counters.rs +++ b/consensus/src/quorum_store/counters.rs @@ -93,7 +93,6 @@ pub static PROOF_MANAGER_MAIN_LOOP: Lazy = Lazy::new(|| { ) }); - pub static PROOF_QUEUE_ADD_BATCH_SUMMARIES_DURATION: Lazy = Lazy::new(|| { DurationHistogram::new( register_histogram!( diff --git a/crates/aptos-genesis/src/builder.rs b/crates/aptos-genesis/src/builder.rs index 4e971b96e40..f94d9eb975a 100644 --- a/crates/aptos-genesis/src/builder.rs +++ b/crates/aptos-genesis/src/builder.rs @@ -30,7 +30,9 @@ use aptos_types::{ jwks::patch::IssuerJWK, keyless::Groth16VerificationKey, on_chain_config::{ - AutomationRegistryConfig, BanRegistryParameters, Features, GasScheduleV2, OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig + AutomationRegistryConfig, BanRegistryParameters, Features, GasScheduleV2, + OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, + OnChainRandomnessConfig, }, transaction::Transaction, waypoint::Waypoint, diff --git a/crates/aptos-genesis/src/config.rs b/crates/aptos-genesis/src/config.rs index 3785eccfcbd..160351500ee 100644 --- a/crates/aptos-genesis/src/config.rs +++ b/crates/aptos-genesis/src/config.rs @@ -10,7 +10,8 @@ use aptos_types::{ keyless::Groth16VerificationKey, network_address::{DnsName, NetworkAddress, Protocol}, on_chain_config::{ - AutomationRegistryConfig, BanRegistryParameters, OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig + AutomationRegistryConfig, BanRegistryParameters, OnChainConsensusConfig, + OnChainExecutionConfig, OnChainJWKConsensusConfig, }, transaction::authenticator::AuthenticationKey, }; diff --git a/crates/aptos-genesis/src/lib.rs b/crates/aptos-genesis/src/lib.rs index a26e139cc5f..419736400f0 100644 --- a/crates/aptos-genesis/src/lib.rs +++ b/crates/aptos-genesis/src/lib.rs @@ -27,9 +27,9 @@ use aptos_types::{ jwks::patch::IssuerJWK, keyless::Groth16VerificationKey, on_chain_config::{ - AutomationRegistryConfig, Features, GasScheduleV2, OnChainConsensusConfig, - OnChainExecutionConfig, OnChainJWKConsensusConfig, OnChainRandomnessConfig, - BanRegistryParameters, + AutomationRegistryConfig, BanRegistryParameters, Features, GasScheduleV2, + OnChainConsensusConfig, OnChainExecutionConfig, OnChainJWKConsensusConfig, + OnChainRandomnessConfig, }, transaction::Transaction, waypoint::Waypoint, diff --git a/crates/aptos-genesis/src/mainnet.rs b/crates/aptos-genesis/src/mainnet.rs index 68589f3a9ed..8bd8595033d 100644 --- a/crates/aptos-genesis/src/mainnet.rs +++ b/crates/aptos-genesis/src/mainnet.rs @@ -14,7 +14,8 @@ use aptos_types::{ account_address::AccountAddress, chain_id::ChainId, on_chain_config::{ - AutomationRegistryConfig, BanRegistryParameters, Features, OnChainJWKConsensusConfig, OnChainRandomnessConfig + AutomationRegistryConfig, BanRegistryParameters, Features, OnChainJWKConsensusConfig, + OnChainRandomnessConfig, }, transaction::Transaction, waypoint::Waypoint, diff --git a/crates/aptos/src/account/balance.rs b/crates/aptos/src/account/balance.rs index 4ef7980a43b..d065dc3469d 100644 --- a/crates/aptos/src/account/balance.rs +++ b/crates/aptos/src/account/balance.rs @@ -5,7 +5,7 @@ use crate::common::types::{ CliCommand, CliConfig, CliError, CliTypedResult, ConfigSearchMode, ProfileOptions, RestOptions, }; use aptos_api_types::ViewFunction; -use aptos_types::{account_address::AccountAddress, SupraCoinType, CoinType}; +use aptos_types::{account_address::AccountAddress, CoinType, SupraCoinType}; use async_trait::async_trait; use clap::Parser; use move_core_types::{ diff --git a/crates/aptos/src/common/types.rs b/crates/aptos/src/common/types.rs index 446a157122b..85103254ee2 100644 --- a/crates/aptos/src/common/types.rs +++ b/crates/aptos/src/common/types.rs @@ -1110,7 +1110,7 @@ pub struct RestOptions { /// environment variable. #[clap(long, env)] pub node_api_key: Option, - #[clap(long, default_value_t = ApiVersion::V3)] + #[clap(long, default_value_t = ApiVersion::V3)] pub(crate) api_version: ApiVersion, } @@ -1120,7 +1120,7 @@ impl Default for RestOptions { rpc_url: None, connection_timeout_secs: DEFAULT_EXPIRATION_SECS, node_api_key: None, - api_version: Default::default() + api_version: Default::default(), } } } diff --git a/crates/aptos/src/governance/mod.rs b/crates/aptos/src/governance/mod.rs index b3224a35259..680bb4086db 100644 --- a/crates/aptos/src/governance/mod.rs +++ b/crates/aptos/src/governance/mod.rs @@ -8,8 +8,8 @@ use crate::common::utils::read_from_file; use crate::{ common::{ types::{ - CliError, CliTypedResult, MovePackageOptions, PoolAddressArgs, ProfileOptions, PromptOptions, RestOptions, - TransactionOptions, TransactionSummary, + CliError, CliTypedResult, MovePackageOptions, PoolAddressArgs, ProfileOptions, + PromptOptions, RestOptions, TransactionOptions, TransactionSummary, }, utils::prompt_yes_with_override, }, @@ -1119,7 +1119,7 @@ impl CliCommand<()> for GenerateUpgradeProposal { output, testnet, next_execution_hash, - proposal_type + proposal_type, } = self; let package_path = move_options.get_package_path()?; let options = included_artifacts.build_options(&move_options)?; diff --git a/crates/aptos/src/move_tool/mod.rs b/crates/aptos/src/move_tool/mod.rs index 520f2a5d325..159b4059aaa 100644 --- a/crates/aptos/src/move_tool/mod.rs +++ b/crates/aptos/src/move_tool/mod.rs @@ -895,10 +895,7 @@ impl FromStr for IncludedArtifacts { } impl IncludedArtifacts { - pub fn build_options( - self, - move_options: &MovePackageOptions, - ) -> CliTypedResult { + pub fn build_options(self, move_options: &MovePackageOptions) -> CliTypedResult { self.build_options_with_experiments(move_options, vec![], false) } diff --git a/crates/aptos/src/node/mod.rs b/crates/aptos/src/node/mod.rs index 3bb61b55bbc..ca986b765b6 100644 --- a/crates/aptos/src/node/mod.rs +++ b/crates/aptos/src/node/mod.rs @@ -902,7 +902,10 @@ impl TryFrom<&ValidatorInfo> for ValidatorInfoSummary { fn try_from(info: &ValidatorInfo) -> Result { let config = info.config(); let config = ValidatorConfig { - consensus_public_key: config.legacy_consensus_public_key_do_not_use().to_bytes().to_vec(), + consensus_public_key: config + .legacy_consensus_public_key_do_not_use() + .to_bytes() + .to_vec(), validator_network_addresses: config.validator_network_addresses.clone(), fullnode_network_addresses: config.fullnode_network_addresses.clone(), validator_index: config.validator_index, diff --git a/crates/aptos/src/op/key.rs b/crates/aptos/src/op/key.rs index 78961738bb1..85a24dc7dbb 100644 --- a/crates/aptos/src/op/key.rs +++ b/crates/aptos/src/op/key.rs @@ -15,7 +15,9 @@ use crate::{ CliCommand, CliResult, }; use aptos_config::config::{Peer, PeerRole}; -use aptos_crypto::{bls12381, ed25519, encoding_type::EncodingType, x25519, PrivateKey, ValidCryptoMaterial}; +use aptos_crypto::{ + bls12381, ed25519, encoding_type::EncodingType, x25519, PrivateKey, ValidCryptoMaterial, +}; use aptos_genesis::config::HostAndPort; use aptos_types::account_address::{ create_multisig_account_address, from_identity_public_key, AccountAddress, @@ -344,7 +346,10 @@ impl CliCommand> for ExtractPublicKey { .save_params .encoding_options .encoding - .decode_key::("ed25519 private key", private_key_bytes)?; + .decode_key::( + "ed25519 private key", + private_key_bytes, + )?; vec![self.save_params.save_material( &key.public_key(), "ed25519 public key", diff --git a/crates/aptos/src/update/tool.rs b/crates/aptos/src/update/tool.rs index 1489efcbbd7..d8848f962e7 100644 --- a/crates/aptos/src/update/tool.rs +++ b/crates/aptos/src/update/tool.rs @@ -3,9 +3,7 @@ // use super::{aptos::AptosUpdateTool, revela::RevelaUpdateTool}; use crate::{ - { - common::types::{CliCommand, CliResult}, - }, + common::types::{CliCommand, CliResult}, update::{ move_mutation_test::MutationTestUpdaterTool, movefmt::FormatterUpdateTool, prover_dependencies::ProverDependencyInstaller, diff --git a/dkg/src/dkg_manager/mod.rs b/dkg/src/dkg_manager/mod.rs index 2976ec6a09a..5427e41a196 100644 --- a/dkg/src/dkg_manager/mod.rs +++ b/dkg/src/dkg_manager/mod.rs @@ -14,8 +14,7 @@ use aptos_infallible::duration_since_epoch; use aptos_logger::{debug, error, info, warn}; use aptos_types::{ dkg::{ - DKGSessionMetadata, DKGSessionState, - DKGStartEvent, DKGTrait, DKGTranscript, + DKGSessionMetadata, DKGSessionState, DKGStartEvent, DKGTrait, DKGTranscript, DKGTranscriptMetadata, MayHaveRoundingSummary, }, epoch_state::EpochState, diff --git a/dkg/src/transcript_aggregation/tests.rs b/dkg/src/transcript_aggregation/tests.rs index cd865ce106b..3e32a9a239a 100644 --- a/dkg/src/transcript_aggregation/tests.rs +++ b/dkg/src/transcript_aggregation/tests.rs @@ -6,7 +6,9 @@ use aptos_crypto::{ed25519, Uniform}; use aptos_infallible::duration_since_epoch; use aptos_reliable_broadcast::BroadcastStatus; use aptos_types::{ - aptos_dkg::{real_dkg::RealDKG, DKGSessionMetadata, DKGTrait, DKGTranscript, DKGTranscriptMetadata}, + aptos_dkg::{ + real_dkg::RealDKG, DKGSessionMetadata, DKGTrait, DKGTranscript, DKGTranscriptMetadata, + }, epoch_state::EpochState, on_chain_config::OnChainRandomnessConfig, validator_verifier::{ diff --git a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs index 421706cccb1..4d57d5aa18f 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-fullnode/src/convert.rs @@ -989,7 +989,10 @@ pub fn convert_transaction( 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,Some(at.meta.index.0))), + payload: Some(convert_transaction_payload( + &at.meta.payload, + Some(at.meta.index.0), + )), registration_hash: at.meta.registration_hash.0.to_vec(), }), events: convert_events(&at.events), diff --git a/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs b/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs index 3445a4a38fd..308b88ef241 100644 --- a/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs +++ b/ecosystem/indexer-grpc/indexer-grpc-utils/src/cache_operator.rs @@ -264,7 +264,10 @@ impl CacheOperator { for transaction in transactions { let version = transaction.version; let cache_key = CacheEntry::build_key(version, self.storage_format).to_string(); - let timestamp_in_seconds = transaction.timestamp.as_ref().map_or(0, |t| t.seconds as u64); + let timestamp_in_seconds = transaction + .timestamp + .as_ref() + .map_or(0, |t| t.seconds as u64); let cache_entry: CacheEntry = CacheEntry::from_transaction(transaction, self.storage_format); let bytes = cache_entry.into_inner(); diff --git a/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs b/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs index aa801ca1a26..de595845bf8 100644 --- a/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs +++ b/ecosystem/indexer-grpc/transaction-filter/src/filters/user_transaction.rs @@ -4,12 +4,11 @@ use crate::{errors::FilterError, traits::Filterable, utils::standardize_address}; use anyhow::{anyhow, Error}; use aptos_protos::transaction::v1::{ - multisig_transaction_payload, transaction::TxnData, transaction_payload, EntryFunctionId, - EntryFunctionPayload, Transaction, TransactionPayload, + multisig_transaction_payload, multisig_transaction_payload::Payload, transaction::TxnData, + transaction_payload, EntryFunctionId, EntryFunctionPayload, Transaction, TransactionPayload, }; use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; -use aptos_protos::transaction::v1::multisig_transaction_payload::Payload; /// We use this for UserTransactions. /// We support UserPayload and MultisigPayload @@ -287,7 +286,7 @@ fn get_entry_function_payload_from_transaction_payload( multisig_transaction_payload::Payload::EntryFunctionPayload(ef_payload) => { Some(ef_payload) }, - Payload::AutomationPayload(_) => None + Payload::AutomationPayload(_) => None, }), _ => None, } diff --git a/execution/block-partitioner/src/test_utils.rs b/execution/block-partitioner/src/test_utils.rs index 7b083915415..85689bb14f0 100644 --- a/execution/block-partitioner/src/test_utils.rs +++ b/execution/block-partitioner/src/test_utils.rs @@ -30,7 +30,7 @@ use aptos_types::{ analyzed_transaction::AnalyzedTransaction, EntryFunction, RawTransaction, SignedTransaction, Transaction, TransactionPayload, }, - SupraCoinType, CoinType, + CoinType, SupraCoinType, }; use move_core_types::{ account_address::AccountAddress, identifier::Identifier, language_storage::ModuleId, diff --git a/execution/executor-types/src/lib.rs b/execution/executor-types/src/lib.rs index a3734212930..8b60c51ca4c 100644 --- a/execution/executor-types/src/lib.rs +++ b/execution/executor-types/src/lib.rs @@ -8,9 +8,9 @@ use aptos_crypto::HashValue; use aptos_scratchpad::SparseMerkleTree; use aptos_types::{ account_config::{NEW_EPOCH_EVENT_MOVE_TYPE_TAG, NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG}, - dkg::DKG_START_EVENT_MOVE_TYPE_TAG, block_executor::{config::BlockExecutorConfigFromOnchain, partitioner::ExecutableBlock}, contract_event::ContractEvent, + dkg::DKG_START_EVENT_MOVE_TYPE_TAG, jwks::OBSERVED_JWK_UPDATED_MOVE_TYPE_TAG, ledger_info::LedgerInfoWithSignatures, state_store::state_key::StateKey, diff --git a/execution/executor/src/metrics.rs b/execution/executor/src/metrics.rs index 57c7b641766..1626fc060f8 100644 --- a/execution/executor/src/metrics.rs +++ b/execution/executor/src/metrics.rs @@ -358,7 +358,9 @@ pub fn update_counters_for_processed_chunk( Some(Transaction::BlockEpilogue(_)) => "block_epilogue", Some(Transaction::ValidatorTransaction(_)) => "validator_transaction", Some(Transaction::AutomatedTransaction(_)) => "automation_transaction", - Some(Transaction::AutomationRegistryTransaction(_)) => "automation_registry_transaction", + Some(Transaction::AutomationRegistryTransaction(_)) => { + "automation_registry_transaction" + }, Some(Transaction::SystemAutomatedTransaction(_)) => "system_automated_transaction", None => "unknown", }; diff --git a/sdk/src/transaction_builder.rs b/sdk/src/transaction_builder.rs index 5bca483aec0..7db0ecab262 100644 --- a/sdk/src/transaction_builder.rs +++ b/sdk/src/transaction_builder.rs @@ -241,7 +241,7 @@ impl TransactionFactory { signatures_required, vec![], vec![], - timeout_duration + timeout_duration, ), ) } @@ -258,7 +258,7 @@ impl TransactionFactory { signatures_required, vec![], vec![], - timeout_duration + timeout_duration, ), ) } diff --git a/types/src/account_config/events/fungible_asset.rs b/types/src/account_config/events/fungible_asset.rs index 19eb9413703..72b4d541972 100644 --- a/types/src/account_config/events/fungible_asset.rs +++ b/types/src/account_config/events/fungible_asset.rs @@ -4,11 +4,11 @@ use crate::move_utils::move_event_v2::MoveEventV2Type; use derive_getters::Getters; use move_core_types::{ - account_address::AccountAddress, ident_str, identifier::IdentStr, move_resource::MoveStructType, - language_storage::TypeTag, + account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, + move_resource::MoveStructType, }; -use serde::{Deserialize, Serialize}; use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; /// Struct that represents a Withdraw event. #[derive(Debug, Serialize, Deserialize, Getters)] @@ -42,4 +42,4 @@ pub static FA_WITHDRAW_EVENT_TYPE_TAG: Lazy = Lazy::new(|| TypeTag::Struct(Box::new(WithdrawFAEvent::struct_tag()))); pub static FA_DEPOSIT_EVENT_TYPE_TAG: Lazy = - Lazy::new(|| TypeTag::Struct(Box::new(DepositFAEvent::struct_tag()))); \ No newline at end of file + Lazy::new(|| TypeTag::Struct(Box::new(DepositFAEvent::struct_tag()))); diff --git a/types/src/contract_event.rs b/types/src/contract_event.rs index 7736995a73f..62d82ec55e5 100644 --- a/types/src/contract_event.rs +++ b/types/src/contract_event.rs @@ -7,12 +7,14 @@ use crate::{ DepositEvent, NewBlockEvent, NewEpochEvent, WithdrawEvent, NEW_EPOCH_EVENT_MOVE_TYPE_TAG, NEW_EPOCH_EVENT_V2_MOVE_TYPE_TAG, }, - dkg::events::{DKGFinishEvent, DKGMetaSetEvent, DKGStartEvent as SupraDKGStartEvent}, - dkg::DKGStartEvent, + dkg::{ + events::{DKGFinishEvent, DKGMetaSetEvent, DKGStartEvent as SupraDKGStartEvent}, + DKGStartEvent, + }, event::EventKey, jwks::ObservedJWKsUpdated, - transaction::Version, on_chain_config::new_epoch_event_key, + transaction::Version, }; use anyhow::{bail, Error, Result}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; diff --git a/types/src/dkg/dummy_dkg/mod.rs b/types/src/dkg/dummy_dkg/mod.rs index 8098eb80d09..9ce3f3f481a 100644 --- a/types/src/dkg/dummy_dkg/mod.rs +++ b/types/src/dkg/dummy_dkg/mod.rs @@ -1,8 +1,10 @@ // Copyright © Aptos Foundation // SPDX-License-Identifier: Apache-2.0 -use crate::dkg::{DKGSessionMetadata, DKGTrait}; -use crate::validator_verifier::ValidatorVerifier; +use crate::{ + dkg::{DKGSessionMetadata, DKGTrait}, + validator_verifier::ValidatorVerifier, +}; use anyhow::{anyhow, ensure}; use aptos_crypto::{ed25519, Uniform}; use move_core_types::account_address::AccountAddress; diff --git a/types/src/dkg/mod.rs b/types/src/dkg/mod.rs index 8017324fd60..29351a16355 100644 --- a/types/src/dkg/mod.rs +++ b/types/src/dkg/mod.rs @@ -4,20 +4,19 @@ use self::real_dkg::RealDKG; use crate::{ dkg::{ - real_dkg::{ - rounding::DKGRoundingProfile, - Transcripts - }, - dkg_committee::DkgCommittee + dkg_committee::DkgCommittee, + real_dkg::{rounding::DKGRoundingProfile, Transcripts}, }, on_chain_config::{OnChainConfig, OnChainRandomnessConfig, RandomnessConfigMoveStruct}, - validator_verifier::{ValidatorConsensusInfo, ValidatorConsensusInfoMoveStruct, ValidatorVerifier}, - validator_public_keys::ValidatorPublicKeys + validator_public_keys::ValidatorPublicKeys, + validator_verifier::{ + ValidatorConsensusInfo, ValidatorConsensusInfoMoveStruct, ValidatorVerifier, + }, }; use anyhow::{anyhow, Context, Result}; -use aptos_crypto::Uniform; -use aptos_crypto::bls12381::PublicKey; +use aptos_crypto::{bls12381::PublicKey, Uniform}; use aptos_crypto_derive::{BCSCryptoHash, CryptoHasher}; +use crypto::utils::get_clan_node_indices; use move_core_types::{ account_address::AccountAddress, ident_str, identifier::IdentStr, language_storage::TypeTag, move_resource::MoveStructType, @@ -30,7 +29,6 @@ use std::{ fmt::{Debug, Formatter}, time::Duration, }; -use crypto::utils::get_clan_node_indices; pub mod dummy_dkg; pub mod real_dkg; diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index 8ef62fc3c21..9a7dabcb623 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -152,7 +152,6 @@ pub enum FeatureFlag { /// Enables smart contracts to register automation tasks via `register_without_validation`, SUPRA_AUTOMATION_V2_1 = 101, - DERIVABLE_ACCOUNT_ABSTRACTION = 102, /// Whether function values are enabled. ENABLE_FUNCTION_VALUES = 103, @@ -179,7 +178,7 @@ impl FeatureFlag { // Feature flag V6 is used to enable metadata v1 format and needs to stay on, even // if we enable a higher version. FeatureFlag::VM_BINARY_FORMAT_V6, - FeatureFlag::VM_BINARY_FORMAT_V7, // new + FeatureFlag::VM_BINARY_FORMAT_V7, // new FeatureFlag::MULTI_ED25519_PK_VALIDATE_V2_NATIVES, FeatureFlag::BLAKE2B_256_NATIVE, FeatureFlag::RESOURCE_GROUPS, @@ -236,7 +235,7 @@ impl FeatureFlag { FeatureFlag::DISPATCHABLE_FUNGIBLE_ASSET, FeatureFlag::_DEPRECATED_REMOVE_DETAILED_ERROR_FROM_HASH, // FeatureFlag::NEW_ACCOUNTS_DEFAULT_TO_FA_APT_STORE, // new - // FeatureFlag::OPERATIONS_DEFAULT_TO_FA_APT_STORE, // new + // FeatureFlag::OPERATIONS_DEFAULT_TO_FA_APT_STORE, // new FeatureFlag::CONCURRENT_FUNGIBLE_ASSETS, FeatureFlag::AGGREGATOR_V2_IS_AT_LEAST_API, FeatureFlag::CONCURRENT_FUNGIBLE_BALANCE, diff --git a/types/src/on_chain_config/evm_config.rs b/types/src/on_chain_config/evm_config.rs index 003569e460f..fb7f87d8bc7 100644 --- a/types/src/on_chain_config/evm_config.rs +++ b/types/src/on_chain_config/evm_config.rs @@ -2,12 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use crate::on_chain_config::OnChainConfig; -use move_core_types::account_address::AccountAddress; -use move_core_types::value::MoveValue; +use move_core_types::{account_address::AccountAddress, value::MoveValue}; use serde::{Deserialize, Serialize}; -use std::collections::BTreeMap; -use std::fmt::{Display, Formatter}; -use std::str::FromStr; +use std::{ + collections::BTreeMap, + fmt::{Display, Formatter}, + str::FromStr, +}; // -- EvmContractName ----------------------------------------------------------- @@ -79,7 +80,7 @@ impl OnChainEvmContractsDetails { .map(|(key, value)| { ( MoveValue::vector_u8(key.to_string().into_bytes()), - evm_address_as_account_address(&value) + evm_address_as_account_address(&value), ) }) .unzip(); @@ -486,8 +487,8 @@ mod unit_tests { // 20-byte EVM address placed in the lower 20 bytes of a 32-byte Move // address (upper 12 zeroed), matching the to_move_values encoding. let evm_bytes: RawEvmAddress = [ - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, - 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, + 0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, ]; let original = OnChainEvmContractsDetails { name_to_addresses: [(EvmContractName::BlockMetadata, evm_bytes)].into(), @@ -507,14 +508,15 @@ mod unit_tests { assert_eq!(addrs.len(), 1); match &addrs[0] { MoveValue::Address(addr) => { - let recovered_evm_bytes: RawEvmAddress = addr.into_bytes()[AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..] + let recovered_evm_bytes: RawEvmAddress = addr.into_bytes() + [AccountAddress::LENGTH - EVM_ADDRESS_LENGTH..] .try_into() .expect("slice with correct length"); assert_eq!(recovered_evm_bytes, evm_bytes); }, _ => panic!("expected MoveValue::Address in values vector"), } - } + }, _ => panic!("expected MoveValue::Vector"), } } diff --git a/types/src/on_chain_config/evm_genesis_config.rs b/types/src/on_chain_config/evm_genesis_config.rs index 49391060400..4c000dcb916 100644 --- a/types/src/on_chain_config/evm_genesis_config.rs +++ b/types/src/on_chain_config/evm_genesis_config.rs @@ -1,7 +1,6 @@ // Copyright (c) Supra Foundation // SPDX-License-Identifier: Apache-2.0 -use std::fmt::Display; use super::OnChainConfig; use crate::chain_id::ChainId; use anyhow::{anyhow, Result}; @@ -10,6 +9,7 @@ use move_core_types::{ }; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; +use std::fmt::Display; /// The Genesis configuration for EVM that can only be set once at genesis epoch. #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] @@ -30,7 +30,6 @@ impl Display for OnChainEvmGenesisConfig { self.chain_id, self.eoas, self.contracts.iter().map(|c| format!("\n\t\t{}", c)).collect::>().join(", "), ) } - } #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] diff --git a/types/src/on_chain_config/leader_ban_registry.rs b/types/src/on_chain_config/leader_ban_registry.rs index 05943ca61a6..182dc0d131a 100644 --- a/types/src/on_chain_config/leader_ban_registry.rs +++ b/types/src/on_chain_config/leader_ban_registry.rs @@ -1,3 +1,5 @@ +use crate::on_chain_config::OnChainConfig; +use anyhow::{format_err, Result}; use derive_getters::Getters; use derive_more::Constructor; use move_core_types::{ @@ -5,9 +7,6 @@ use move_core_types::{ value::{serialize_values, MoveValue}, }; use serde::{Deserialize, Serialize}; -use anyhow::{format_err, Result}; - -use crate::on_chain_config::OnChainConfig; /// Configuration for a [`BanRegistry`]. Stored in the Move state and updated via governance. /// @@ -21,7 +20,7 @@ pub enum BanRegistryParameters { #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] struct MoveBanRegistryParams { pub config: Vec, - pub version: u8 + pub version: u8, } impl Default for BanRegistryParameters { @@ -35,26 +34,32 @@ impl OnChainConfig for BanRegistryParameters { const TYPE_IDENTIFIER: &'static str = "BanRegistryParameters"; fn deserialize_default_impl(bytes: &[u8]) -> Result { - let move_ban_registry = bcs::from_bytes::(bytes) - .map_err(|e| format_err!("[on-chain config] Failed to deserialize into config: {}", e))?; + let move_ban_registry = bcs::from_bytes::(bytes).map_err(|e| { + format_err!("[on-chain config] Failed to deserialize into config: {}", e) + })?; match move_ban_registry.version { 0 => { let params_v0 = bcs::from_bytes::(&move_ban_registry.config) .map_err(|e| format_err!("[on-chain config] Failed to deserialize into config BanRegistryParametersV0: {}", e))?; Ok(BanRegistryParameters::V0(params_v0)) }, - _ => { - Err(format_err!("[on-chain config] Failed to deserialize into config: Invalid Version: {}", move_ban_registry.version)) - } + _ => Err(format_err!( + "[on-chain config] Failed to deserialize into config: Invalid Version: {}", + move_ban_registry.version + )), } } } impl BanRegistryParameters { - pub fn serialize_into_move_values_with_signer(&self, signer_address: AccountAddress) -> Vec> { - let arguments:Vec = match &self { + pub fn serialize_into_move_values_with_signer( + &self, + signer_address: AccountAddress, + ) -> Vec> { + let arguments: Vec = match &self { BanRegistryParameters::V0(ban_registry_parameters_v0) => { - let params_bytes = bcs::to_bytes(ban_registry_parameters_v0).expect("serialisation of leader ban config failed"); + let params_bytes = bcs::to_bytes(ban_registry_parameters_v0) + .expect("serialisation of leader ban config failed"); vec![ MoveValue::Signer(signer_address), MoveValue::vector_u8(params_bytes), @@ -69,7 +74,7 @@ impl BanRegistryParameters { /// /// BCS field order **must** match the Move struct `BanRegistryParametersV0`: /// `initial_elections_denied, max_elections_denied, minimum_unbanned_proposers, probation_elections`. -/// +/// /// The [`Default`] values of the parameters disable banning. #[derive(Clone, Constructor, Debug, Default, Deserialize, Eq, PartialEq, Getters, Serialize)] pub struct BanRegistryParametersV0 { diff --git a/types/src/on_chain_config/mod.rs b/types/src/on_chain_config/mod.rs index 72947508575..efe9dff5b12 100644 --- a/types/src/on_chain_config/mod.rs +++ b/types/src/on_chain_config/mod.rs @@ -57,11 +57,12 @@ pub use self::{ ValidatorTxnConfig, DEFAULT_ENABLED_WINDOW_SIZE, DEFAULT_WINDOW_SIZE, }, evm_config::{ - EvmContractName, EvmScalarConfigKey, OnChainEvmConfig, OnChainEvmContractsDetails, evm_address_as_account_address + evm_address_as_account_address, EvmContractName, EvmScalarConfigKey, OnChainEvmConfig, + OnChainEvmContractsDetails, }, evm_genesis_config::{ ContractKind, GenesisEvmContract, GenesisEvmEOA, OnChainEvmGenesisConfig, - EVM_GENESIS_EVENT_MOVE_TYPE_TAG + EVM_GENESIS_EVENT_MOVE_TYPE_TAG, }, execution_config::{ BlockGasLimitType, ExecutionConfigV1, ExecutionConfigV2, ExecutionConfigV4, diff --git a/types/src/proptest_types.rs b/types/src/proptest_types.rs index 46039311250..be94d3b7e02 100644 --- a/types/src/proptest_types.rs +++ b/types/src/proptest_types.rs @@ -24,12 +24,13 @@ use crate::{ proof::TransactionInfoListWithProof, state_store::state_key::StateKey, transaction::{ - automated_transaction::AutomatedTransaction, block_epilogue::BlockEndInfo, ChangeSet, EntryFunction, ExecutionStatus, - IndexedTransactionSummary, Module, Multisig, MultisigTransactionPayload, RawTransaction, - ReplayProtector, Script, SignatureCheckedTransaction, SignedTransaction, Transaction, - TransactionArgument, TransactionAuxiliaryData, TransactionExecutable, - TransactionExtraConfig, TransactionInfo, TransactionListWithProof, TransactionPayload, - TransactionPayloadInner, TransactionStatus, TransactionToCommit, Version, WriteSetPayload, + automated_transaction::AutomatedTransaction, block_epilogue::BlockEndInfo, ChangeSet, + EntryFunction, ExecutionStatus, IndexedTransactionSummary, Module, Multisig, + MultisigTransactionPayload, RawTransaction, ReplayProtector, Script, + SignatureCheckedTransaction, SignedTransaction, Transaction, TransactionArgument, + TransactionAuxiliaryData, TransactionExecutable, TransactionExtraConfig, TransactionInfo, + TransactionListWithProof, TransactionPayload, TransactionPayloadInner, TransactionStatus, + TransactionToCommit, Version, WriteSetPayload, }, validator_info::ValidatorInfo, validator_signer::ValidatorSigner, @@ -49,6 +50,7 @@ use aptos_crypto::{ use move_core_types::{ identifier::Identifier, language_storage::{ModuleId, TypeTag}, + vm_status::StatusCode, }; use proptest::{ collection::{vec, SizeRange}, @@ -63,7 +65,6 @@ use std::{ iter::Iterator, sync::Arc, }; -use move_core_types::vm_status::StatusCode; impl Arbitrary for IndexedTransactionSummary { type Parameters = (); @@ -540,7 +541,7 @@ impl Arbitrary for TransactionExecutable { any::