-
Notifications
You must be signed in to change notification settings - Fork 21
feat: add automatic-generate-keys command to partner-chains CLI #867
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -40,6 +41,9 @@ plutus-datum-derive = { workspace = true } | |||
ed25519-zebra = { workspace = true } | |||
sp-session-validator-management = { workspace = true, features = ["std"] } | |||
pallet-session-validator-management = { workspace = true, features = ["std"] } | |||
subxt = "0.35" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put these on the main cargo.toml on top level - use the workspace syntax { workspace = true }
#[derive(Debug, Serialize, Deserialize)] | ||
pub struct SessionKeyInfo { | ||
pub key_type: String, | ||
pub key_type_bytes: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need key_type_bytes
// Step 1: Generate keys using author_rotateKeys RPC via jsonrpsee | ||
context.eprint("⚙️ Calling author_rotateKeys() RPC method..."); | ||
|
||
let rpc_client = HttpClientBuilder::default() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May not need this - use subxt api
.build(&config.node_url) | ||
.context("Failed to build RPC client")?; | ||
|
||
let keys_hex: String = rpc_client |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here - use subxt (online client)
.context("Failed to connect to node")?; | ||
|
||
context.eprint("✅ Connected to node successfully"); | ||
context.eprint("🔍 Extracting SessionKeys type definition from runtime metadata..."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this step is not needed anymore. We can get ready list by invoking RPC command on the node
// Step 2: Decode the keys using the extracted type information | ||
context.eprint("🔍 Decoding session keys using runtime type information..."); | ||
|
||
let decoded_keys = decode_session_keys_from_type_info(&keys_hex, &session_keys_type_info) | ||
.context("Failed to decode session keys using type information")?; | ||
|
||
context.eprint(&format!("✅ Successfully decoded {} session keys:", decoded_keys.len())); | ||
for (key_type, key_bytes) in &decoded_keys { | ||
let key_type_str = String::from_utf8_lossy(key_type); | ||
let key_hex = format!("0x{}", hex::encode(key_bytes)); | ||
context.eprint(&format!(" • {} key: {}", key_type_str, key_hex)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above, decoding will be done by the node, we have to convert the output to our internal output
let keys_hex = context | ||
.run_command(&format!("{node_executable} rpc author_rotateKeys --url {}", config.node_url))? | ||
.trim() | ||
.to_string(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should use some client module for execution of RPC calls
/// Extract the actual SessionKeys type definition from runtime metadata | ||
/// This is truly runtime-aware - it reads the actual type definition | ||
fn extract_session_keys_type_from_metadata( | ||
metadata: &subxt::Metadata, | ||
) -> Result<Vec<SessionKeyTypeInfo>> { | ||
// Look for the SessionKeys type in the metadata | ||
let session_keys_type = find_session_keys_type(metadata) | ||
.context("SessionKeys type not found in runtime metadata")?; | ||
|
||
// Parse the SessionKeys type definition | ||
parse_session_keys_type(session_keys_type, metadata) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will be done by the node, we don't need it anymore
parse_session_keys_type(session_keys_type, metadata) | ||
} | ||
|
||
/// Find the SessionKeys type in the metadata by looking at type paths |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that all the below lines are not needed then
d21fec0
to
ddf2921
Compare
cd4b818
to
2654c45
Compare
|
||
let mut session_keys = Vec::new(); | ||
let mut offset = 0; | ||
let key_types = ["aura", "gran", "imon", "auth"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this code still assumes key types
|
||
/// Parse session keys from hex string by splitting into common key lengths | ||
/// Substrate session keys are typically concatenated public keys of fixed lengths | ||
fn parse_session_keys_hex<C: IOContext>(keys_hex: &str, context: &C) -> Vec<SessionKeyInfo> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should not parse anything, it is already done by the node
8ad297f
to
ea3b076
Compare
a35816b
to
c85315d
Compare
bbbb6ec
to
7663893
Compare
7663893
to
8b38ac2
Compare
8b38ac2
to
9cffa3f
Compare
Replaced by this PR: https://github.com/input-output-hk/partner-chains/pull/924/files |
Description
Overview
Added a new automatic-generate-keys command that automatically generates session keys by connecting to a running Partner Chain node via RPC, eliminating the need for manual key generation and parsing. Jira Ticket ETCM-11971
Implementation Details
Command Structure:
Uses a clean two-RPC-call approach:
Key Benefits:
✅ No assumptions - Node provides actual key types (e.g., "gran", "imon", "aura")
✅ Runtime-agnostic - Works with any SessionKeys configuration
✅ No manual parsing - Node handles all SCALE decoding internally
✅ Always accurate - Impossible to get key order wrong
Checklist
changelog.md
for affected crate