Skip to content

Commit e0e9f60

Browse files
authored
[network] onchain discovery tool (#228)
## Description <!-- Please include a summary of the change, including which issue it fixes or what feature it adds. Include relevant motivation, context and documentation as appropriate. List dependencies that are required for this change, if any. --> This change implements a tool that can decodes a node address into BCS format and validator can update their onchain address to make them discoverable. * Top level ``` adhoc command for l1 migration Usage: l1-migration <COMMAND> Commands: generate-waypoint-genesis Generate waypoint and genesis files from database network-address Convert between multiaddr strings and BCS hex format help Print this message or the help of the given subcommand(s) Options: -h, --help Print help -V, --version Print version ``` * Network address command ``` Convert between multiaddr strings and BCS hex format Usage: l1-migration network-address <COMMAND> Commands: encode Encode multiaddr string to BCS hex decode Decode BCS hex to multiaddr string help Print this message or the help of the given subcommand(s) Options: -h, --help Print help ``` * Encode ``` ./l1-migration network-address encode --help Encode multiaddr string to BCS hex Usage: l1-migration network-address encode <MULTIADDR> Arguments: <MULTIADDR> Multiaddr string to encode to BCS hex format Example: /dns/validator.example.com/tcp/6180/noise-ik/a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890/handshake/1 Options: -h, --help Print help (see a summary with '-h') ``` * Decode ``` ./l1-migration network-address decode --help Decode BCS hex to multiaddr string Usage: l1-migration network-address decode <HEX> Arguments: <HEX> BCS hex string to decode to multiaddr format Example: 0x013f04021576616c696461746f722e6578616d706c652e636f6d0524180720a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef12345678900801 Options: -h, --help Print help (see a summary with '-h') ``` ## Type of Change - [x] New feature - [ ] Bug fix - [ ] Breaking change - [ ] Performance improvement - [ ] Refactoring - [ ] Dependency update - [ ] Documentation update - [ ] Tests ## Which Components or Systems Does This Change Impact? - [ ] Validator Node - [ ] Full Node (API, Indexer, etc.) - [ ] Move/Aptos Virtual Machine - [ ] Aptos Framework - [ ] Aptos CLI/SDK - [ ] Developer Infrastructure - [x] Other (specify) tools ## How Has This Been Tested? <!-- - Please ensure that the functionality introduced by this change is well tested and verified to work as expected. - Ensure tests cover both happy and unhappy paths. - List and link relevant tests. --> Testnet address is updated onchain. everything looks good. ## Key Areas to Review <!-- - Identify any critical parts of the code that require special attention or understanding. Explain why these parts are crucial to the functionality or architecture of the project. - Point out any areas where complex logic has been implemented. Provide a brief explanation of the logic and your approach to make it easier for reviewers to follow. - Highlight any areas where you are particularly concerned or unsure about the code's impact on the change. This can include potential performance or security issues, or compatibility with existing features. --> ## Checklist - [ ] I have read and followed the [CONTRIBUTING](https://github.com/aptos-labs/aptos-core/blob/main/CONTRIBUTING.md) doc - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I identified and added all stakeholders and component owners affected by this change as reviewers - [ ] I tested both happy and unhappy path of the functionality - [ ] I have made corresponding changes to the documentation <!-- Thank you for your contribution! -->
2 parents 01f0203 + 3de6119 commit e0e9f60

File tree

3 files changed

+94
-5
lines changed

3 files changed

+94
-5
lines changed

tools/l1-migration/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ rust-version = { workspace = true }
1212

1313

1414
[dependencies]
15-
anyhow = "1.0"
15+
anyhow = { workspace = true }
1616
aptos-config = { workspace = true }
1717
aptos-crypto = { workspace = true }
1818
aptos-db = { workspace = true }
@@ -21,4 +21,4 @@ aptos-types = { workspace = true }
2121
bcs = { workspace = true }
2222
clap = { workspace = true }
2323
serde_yaml = { workspace = true }
24-
hex = "0.4"
24+
hex = { workspace = true }

tools/l1-migration/src/main.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use anyhow::Result;
22
use clap::Parser;
3-
use l1_migration::extract_genesis_and_waypoint;
3+
use l1_migration::{
4+
extract_genesis_and_waypoint,
5+
utils::{decode_network_address, encode_network_address},
6+
};
47
use std::path::PathBuf;
58

69
/// L1 Migration Tool - Extract genesis and waypoint from database
@@ -22,6 +25,32 @@ enum Commands {
2225
/// Destination directory for extracted files
2326
destination_path: PathBuf,
2427
},
28+
/// Network address encoding/decoding tool
29+
#[command(about = "Convert between multiaddr strings and BCS hex format")]
30+
NetworkAddress {
31+
#[command(subcommand)]
32+
command: NetworkAddressCommands,
33+
},
34+
}
35+
36+
#[derive(Parser)]
37+
enum NetworkAddressCommands {
38+
/// Encode multiaddr string to BCS hex
39+
Encode {
40+
/// Multiaddr string to encode to BCS hex format
41+
///
42+
/// Example: /dns/validator.example.com/tcp/6180/noise-ik/a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef1234567890/handshake/1
43+
#[arg(help = "Multiaddr string to encode to BCS hex format")]
44+
multiaddr: String,
45+
},
46+
/// Decode BCS hex to multiaddr string
47+
Decode {
48+
/// BCS hex string to decode to multiaddr format
49+
///
50+
/// Example: 0x013f04021576616c696461746f722e6578616d706c652e636f6d0524180720a1b2c3d4e5f67890abcdef1234567890abcdef1234567890abcdef12345678900801
51+
#[arg(help = "BCS hex string to decode to multiaddr format")]
52+
hex: String,
53+
},
2554
}
2655

2756
fn main() -> Result<()> {
@@ -52,5 +81,9 @@ fn main() -> Result<()> {
5281

5382
extract_genesis_and_waypoint(&db_path_str, &destination_path_str)
5483
},
84+
Commands::NetworkAddress { command } => match command {
85+
NetworkAddressCommands::Encode { multiaddr } => encode_network_address(&multiaddr),
86+
NetworkAddressCommands::Decode { hex } => decode_network_address(&hex),
87+
},
5588
}
5689
}

tools/l1-migration/src/utils.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use anyhow::Result;
22
use aptos_config::config::{RocksdbConfigs, StorageDirPaths, NO_OP_STORAGE_PRUNER_CONFIG};
33
use aptos_db::AptosDB;
44
use aptos_storage_interface::DbReader;
5-
use aptos_types::{transaction::Transaction, waypoint::Waypoint};
6-
use std::{fs, path::Path};
5+
use aptos_types::{network_address::NetworkAddress, transaction::Transaction, waypoint::Waypoint};
6+
use std::{fs, path::Path, str::FromStr};
77

88
/// Extract genesis transaction and waypoint from an Aptos database
99
pub fn extract_genesis_and_waypoint(db_path: &str, output_dir: &str) -> Result<()> {
@@ -155,3 +155,59 @@ fn print_genesis_transaction_info(genesis_transaction: &Transaction) {
155155
},
156156
}
157157
}
158+
159+
/// Encode a network address from multiaddr string to BCS hex format
160+
pub fn encode_network_address(multiaddr_input: &str) -> Result<()> {
161+
let mut addresses = Vec::new();
162+
163+
// Split by comma and parse each address
164+
for addr_str in multiaddr_input.split(',') {
165+
let addr_str = addr_str.trim();
166+
if !addr_str.is_empty() {
167+
let network_address = NetworkAddress::from_str(addr_str)
168+
.map_err(|e| anyhow::anyhow!("Invalid multiaddr string '{}': {}. Please provide a valid multiaddr string (e.g., /dns/example.com/tcp/6180/noise-ik/.../handshake/1)", addr_str, e))?;
169+
addresses.push(network_address);
170+
}
171+
}
172+
173+
if addresses.is_empty() {
174+
return Err(anyhow::anyhow!(
175+
"No valid network addresses found. Please provide at least one valid multiaddr string"
176+
));
177+
}
178+
179+
let encoded_bytes = bcs::to_bytes(&addresses)?;
180+
let hex_output = format!("0x{}", hex::encode(&encoded_bytes));
181+
182+
println!("{}", hex_output);
183+
184+
Ok(())
185+
}
186+
187+
/// Decode a network address from BCS hex format to multiaddr string
188+
pub fn decode_network_address(bcs_hex: &str) -> Result<()> {
189+
let hex_str = bcs_hex.strip_prefix("0x").unwrap_or(bcs_hex);
190+
let bcs_bytes = hex::decode(hex_str).map_err(|e| {
191+
anyhow::anyhow!(
192+
"Invalid hex string: {}. Please provide a valid hex string (with or without 0x prefix)",
193+
e
194+
)
195+
})?;
196+
197+
// Try to decode as Vec<NetworkAddress> first (most common case)
198+
if let Ok(addresses) = bcs::from_bytes::<Vec<NetworkAddress>>(&bcs_bytes) {
199+
let addr_strings: Vec<String> = addresses.iter().map(|addr| addr.to_string()).collect();
200+
let multiaddr_output = addr_strings.join(", ");
201+
202+
println!("{}", multiaddr_output);
203+
204+
Ok(())
205+
} else if let Ok(network_address) = bcs::from_bytes::<NetworkAddress>(&bcs_bytes) {
206+
// Try to decode as single NetworkAddress
207+
println!("{}", network_address);
208+
209+
Ok(())
210+
} else {
211+
Err(anyhow::anyhow!("Failed to decode network address from BCS hex. Please ensure the input is a valid BCS-encoded NetworkAddress or Vec<NetworkAddress>"))
212+
}
213+
}

0 commit comments

Comments
 (0)