Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ aptos-framework-upgrade-gas-release = { path = "protocol-units/execution/maptos/
aptos-framework-known-release = { path = "protocol-units/execution/maptos/framework/releases/known-release" }
aptos-framework-set-feature-flags-release = { path = "protocol-units/execution/maptos/framework/releases/feature-flags" }
aptos-framework-release-script-release = { path = "protocol-units/execution/maptos/framework/releases/release-script" }
mvt-aptos-l1-migration = { path = "protocol-units/execution/maptos/framework/releases/l1-migration" }


# framework migrations
aptos-framework-elsa-to-biarritz-rc1-migration = { path = "protocol-units/execution/maptos/framework/migrations/elsa-to-biarritz-rc1" }
Expand Down
4 changes: 4 additions & 0 deletions networks/movement/movement-full-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ movement-da-sequencer-config = { workspace = true }
ed25519-dalek = { workspace = true }
mcr-settlement-setup = { workspace = true }

mvt-aptos-l1-migration = { workspace = true }

aptos-logger = { workspace = true }

url = { workspace = true }


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::common_args::MovementArgs;
use clap::Parser;
use mvt_aptos_l1_migration::set_epoch_duration;

#[derive(Debug, Parser, Clone)]
#[clap(rename_all = "kebab-case", about = "Rotates the key for a core resource account.")]
pub struct ChangeEpochDuration {
#[clap(flatten)]
pub movement_args: MovementArgs,
pub new_epoch_duration: Option<u64>,
}

impl ChangeEpochDuration {
pub async fn execute(&self) -> Result<(), anyhow::Error> {
// get the movement config from dot movement
let _dot_movement = self.movement_args.dot_movement()?;
let epoch_duration = self.new_epoch_duration.unwrap_or(7_200_000_000); // default 2hours, 7_200_000_000 micro second.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit const this val

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

set_epoch_duration(epoch_duration).await?;
Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use crate::admin::l1_migration::change_epoch_duration::ChangeEpochDuration;
use clap::Subcommand;

mod change_epoch_duration;

#[derive(Subcommand, Debug)]
#[clap(rename_all = "kebab-case", about = "Commands for rotating keys")]
pub enum L1Migration {
ChangeEpoch(ChangeEpochDuration),
}

impl L1Migration {
pub async fn execute(&self) -> Result<(), anyhow::Error> {
match self {
L1Migration::ChangeEpoch(change_epoch_duration) => {
change_epoch_duration.execute().await
}
}
}
}
4 changes: 4 additions & 0 deletions networks/movement/movement-full-node/src/admin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod bring_up;
pub mod config;
pub mod framework;
pub mod governed_gas_pool;
pub mod l1_migration;
pub mod mcr;
pub mod ops;
pub mod rotate_key;
Expand All @@ -28,6 +29,8 @@ pub enum Admin {
Config(config::Config),
#[clap(subcommand)]
TestKey(testkey::TestKey),
#[clap(subcommand)]
L1Migration(l1_migration::L1Migration),
}

impl Admin {
Expand All @@ -41,6 +44,7 @@ impl Admin {
Admin::Framework(framework) => framework.execute().await,
Admin::Config(config) => config.execute().await,
Admin::TestKey(key) => key.execute().await,
Admin::L1Migration(l1_migration) => l1_migration.execute().await,
}
}
}
23 changes: 13 additions & 10 deletions networks/movement/movement-full-node/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
#![forbid(unsafe_code)]
use clap::*;
use movement_full_node::MovementFullNode;
use tracing_subscriber::EnvFilter;
// use tracing_subscriber::EnvFilter;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Initialize logger (for debugging)
aptos_logger::Logger::builder().level(aptos_logger::Level::Debug).build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: default to info and use RUST_LOG=debug to enable debug logging.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I activate the Aptos logger to see if I get more details about the Tx discarded issue I get after the epoch change. I'll revert this code to set the initial logger because I didn't get anything new.


// Initialize default tracing
tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
)
.init();
// tracing_subscriber::fmt()
// .with_env_filter(
// EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
// )
// .init();

// Initialize telemetry if MOVEMENT_METRICS_ADDR is set
if std::env::var("MOVEMENT_METRICS_ADDR").is_ok() {
movement_tracing::ensure_telemetry_initialized();
}
// // Initialize telemetry if MOVEMENT_METRICS_ADDR is set
// if std::env::var("MOVEMENT_METRICS_ADDR").is_ok() {
// movement_tracing::ensure_telemetry_initialized();
// }

let suzuka_util = MovementFullNode::parse();
let result = suzuka_util.execute().await;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ processes:
setup:
environment:
- "MAYBE_RUN_LOCAL=true"
- APTOS_ACCOUNT_WHITELIST=$DOT_MOVEMENT_PATH/default_signer_address_whitelist
- MAPTOS_PRIVATE_KEY=random
command: |
RUST_BACKTRACE=1 movement-full-node setup all
depends_on:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[package]
name = "mvt-aptos-l1-migration"
description = "Mvt Aptos L1 migration functions."
authors = { workspace = true }
edition = { workspace = true }
homepage = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
version = { workspace = true }

[lib]
path = "src/lib.rs"

[dependencies]
aptos-crypto = { workspace = true }
serde = { workspace = true }
maptos-framework-release-util = { workspace = true }
movement-config = { workspace = true }
movement-client = { workspace = true }
once_cell = { workspace = true }
aptos-framework = { workspace = true }
tokio = { workspace = true }
anyhow = { workspace = true }
url = { workspace = true }
dot-movement = { workspace = true }
tempfile = { workspace = true }
bcs = { workspace = true }
aptos-framework-upgrade-gas-release = { workspace = true }
aptos-framework-set-feature-flags-release = { workspace = true }
aptos-framework-release-script-release = { workspace = true }
aptos-types = { workspace = true }
aptos-gas-schedule = { workspace = true }
aptos-sdk = { workspace = true }
aptos-release-builder = { workspace = true }
hex = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
rand = { workspace = true }
ed25519-dalek = { workspace = true }

[build-dependencies]
maptos-framework-release-util = { workspace = true }
movement-config = { workspace = true }
movement-client = { workspace = true }
once_cell = { workspace = true }
aptos-framework = { workspace = true }
tokio = { workspace = true }
anyhow = { workspace = true }
url = { workspace = true }
dot-movement = { workspace = true }
tempfile = { workspace = true }
bcs = { workspace = true }
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
script {
use aptos_framework::aptos_governance;
// use aptos_framework::signer;
use aptos_framework::block;

fun main(core_resources: &signer, new_interval_us: u64) {
let core_signer = aptos_governance::get_signer_testnet_only(core_resources, @0000000000000000000000000000000000000000000000000000000000000001);

block::update_epoch_interval_microsecs(&core_signer, new_interval_us); //2h 7_200_000_000
Copy link
Contributor

@larryl3u larryl3u Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use aptos_sdk::rest_client::Resource;
use aptos_sdk::types::transaction::TransactionArgument;
use aptos_sdk::{
rest_client::Client,
transaction_builder::TransactionFactory,
types::{account_address::AccountAddress, transaction::TransactionPayload},
};
use aptos_types::{chain_id::ChainId, transaction::Script};
use movement_client::types::{account_config::aptos_test_root_address, LocalAccount};
use once_cell::sync::Lazy;
use std::str::FromStr;
use url::Url;

static MOVEMENT_CONFIG: Lazy<movement_config::Config> = Lazy::new(|| {
let dot_movement = dot_movement::DotMovement::try_from_env().unwrap();
dot_movement.try_get_config_from_json::<movement_config::Config>().unwrap()
});

static NODE_URL: Lazy<Url> = Lazy::new(|| {
let addr = MOVEMENT_CONFIG
.execution_config
.maptos_config
.client
.maptos_rest_connection_hostname
.clone();
let port = MOVEMENT_CONFIG
.execution_config
.maptos_config
.client
.maptos_rest_connection_port
.clone();
Url::from_str(&format!("http://{}:{}", addr, port)).unwrap()
});

const GAS_UNIT_LIMIT: u64 = 100_000;

const CHANGE_EPOCH_MV: &[u8] = include_bytes!("../move/build/change_epoch.mv");

pub async fn set_epoch_duration(epoch_duration: u64) -> Result<(), anyhow::Error> {
let rest_client = Client::new(NODE_URL.clone());

// Core resources (aptos_test_root) address
let gov_root_address = aptos_test_root_address();
tracing::info!("aptos_test_root_address() (constant): {}", gov_root_address);
// Load *core_resources* private key (from your config/genesis)
let raw_private_key = MOVEMENT_CONFIG
.execution_config
.maptos_config
.chain
.maptos_private_key_signer_identifier
.try_raw_private_key()?;
let gov_priv =
movement_client::crypto::ed25519::Ed25519PrivateKey::try_from(raw_private_key.as_slice())?;

// Build signer by *forcing* core_resources address + current on-chain seq
let gov_root_account = {
let onchain = rest_client.get_account(gov_root_address).await?.into_inner();
LocalAccount::new(gov_root_address, gov_priv.clone(), onchain.sequence_number)
};
tracing::info!("Signer (gov_root_account) address: {}", gov_root_account.address());

let ledger_info = rest_client.get_ledger_information().await?.into_inner();
let factory = TransactionFactory::new(ChainId::new(ledger_info.chain_id))
.with_gas_unit_price(100)
.with_max_gas_amount(GAS_UNIT_LIMIT);

let payload = TransactionPayload::Script(Script::new(
CHANGE_EPOCH_MV.to_vec(),
vec![], // no type args
vec![TransactionArgument::U64(epoch_duration)], // no value args; 7_200_000_000 is hardcoded inside
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

));

// Sign & submit
let signed_txn = gov_root_account.sign_with_transaction_builder(factory.payload(payload));
let res = rest_client.submit_and_wait(&signed_txn).await?.into_inner();

// Verify the epoch has been changed
let block_res: Resource = rest_client
.get_account_resource(AccountAddress::from_hex_literal("0x1")?, "0x1::block::BlockResource")
.await?
.into_inner()
.unwrap();

let interval_str = block_res.data["epoch_interval"]
.as_str()
.ok_or_else(|| anyhow::anyhow!("epoch_interval missing or not a string"))?;

let onchain_duration: u64 = interval_str.parse()?;

assert!(
onchain_duration == epoch_duration,
"Epoch duration not updated, epoch after update is:{onchain_duration}"
);

tracing::info!(
"✅ Executed change epoch script, new epoch duration:{onchain_duration}, with Tx hash: {}",
res.transaction_info().unwrap().hash
);
Ok(())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod change_epoch;

pub use change_epoch::set_epoch_duration;
Loading