forked from 0LNetworkCommunity/libra-framework
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Patch config init (0LNetworkCommunity#77)
Co-authored-by: 0o-de-lally <[email protected]>
- Loading branch information
Showing
4 changed files
with
123 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
//! Validator subcommands | ||
use crate::submit_transaction::Sender; | ||
use diem::common::types::RotationProofChallenge; | ||
use diem_sdk::crypto::{PrivateKey, SigningKey, ValidCryptoMaterialStringExt}; | ||
use diem_types::{ | ||
account_address::AccountAddress, account_config::CORE_CODE_ADDRESS, | ||
transaction::TransactionPayload, | ||
}; | ||
use libra_cached_packages::libra_stdlib::account_rotate_authentication_key; | ||
use libra_types::{ | ||
exports::{AuthenticationKey, Ed25519PrivateKey}, | ||
type_extensions::client_ext::ClientExt, | ||
}; | ||
use libra_wallet::account_keys::get_keys_from_prompt; | ||
|
||
#[derive(clap::Subcommand)] | ||
pub enum UserTxs { | ||
RotateKey(RotateKeyTx), | ||
} | ||
|
||
#[derive(clap::Args)] | ||
pub struct RotateKeyTx { | ||
#[clap(short, long)] | ||
/// The new authkey to be used | ||
new_private_key: Option<String>, // Dev NOTE: account address has the same bytes as AuthKey | ||
} | ||
|
||
impl UserTxs { | ||
pub async fn run(&self, sender: &mut Sender) -> anyhow::Result<()> { | ||
match &self { | ||
UserTxs::RotateKey(tx) => match tx.run(sender).await { | ||
Ok(_) => println!("SUCCESS: privated key rotated"), | ||
Err(e) => { | ||
println!("ERROR: could not rotate private key, message: {}", e); | ||
} | ||
}, | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
impl RotateKeyTx { | ||
pub async fn run(&self, sender: &mut Sender) -> anyhow::Result<()> { | ||
let user_account: AccountAddress = sender.local_account.address(); | ||
|
||
let new_private_key = if let Some(pk) = &self.new_private_key { | ||
Ed25519PrivateKey::from_encoded_string(pk)? | ||
} else { | ||
let legacy = get_keys_from_prompt()?; | ||
legacy.child_0_owner.pri_key | ||
}; | ||
|
||
let seq = sender.client().get_sequence_number(user_account).await?; | ||
let payload = rotate_key( | ||
user_account, | ||
sender.local_account.private_key().to_owned(), | ||
sender.local_account.authentication_key(), | ||
seq, | ||
new_private_key, | ||
)?; | ||
|
||
sender.sign_submit_wait(payload).await?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
/// create the TransactionPayload for a key rotation (a signed rotation challenge) | ||
pub fn rotate_key( | ||
sender_address: AccountAddress, | ||
current_private_key: Ed25519PrivateKey, | ||
auth_key: AuthenticationKey, | ||
sequence_number: u64, | ||
new_private_key: Ed25519PrivateKey, | ||
) -> anyhow::Result<TransactionPayload> { | ||
// form a rotation proof challence. See account.move | ||
let rotation_proof = RotationProofChallenge { | ||
account_address: CORE_CODE_ADDRESS, | ||
module_name: "account".to_string(), | ||
struct_name: "RotationProofChallenge".to_string(), | ||
sequence_number, | ||
originator: sender_address, | ||
current_auth_key: AccountAddress::from_bytes(auth_key)?, | ||
new_public_key: new_private_key.public_key().to_bytes().to_vec(), | ||
}; | ||
|
||
// get the bytes of the challenge | ||
let rotation_msg = bcs::to_bytes(&rotation_proof)?; | ||
|
||
// Signs the struct using both the current private key and the next private key | ||
let rotation_proof_signed_by_current_private_key = | ||
current_private_key.sign_arbitrary_message(&rotation_msg); | ||
let rotation_proof_signed_by_new_private_key = | ||
new_private_key.sign_arbitrary_message(&rotation_msg); | ||
|
||
let payload = account_rotate_authentication_key( | ||
0, | ||
// Existing public key | ||
current_private_key.public_key().to_bytes().to_vec(), | ||
0, | ||
// New public key | ||
new_private_key.public_key().to_bytes().to_vec(), | ||
rotation_proof_signed_by_current_private_key | ||
.to_bytes() | ||
.to_vec(), | ||
rotation_proof_signed_by_new_private_key.to_bytes().to_vec(), | ||
); | ||
|
||
Ok(payload) | ||
} |