Skip to content

Commit

Permalink
[docs] add key rotation document (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xzoz authored May 12, 2024
1 parent 10a2fb1 commit 7fe1ba1
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 76 deletions.
23 changes: 12 additions & 11 deletions Cargo.lock

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

22 changes: 13 additions & 9 deletions docs/hot_upgrades.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@

The "framework" which contains all the consensus, account, econ policies, etc. for the network is written in Move. This code is stored in the network database, and effectively executed on demand. This means that framework upgrades can occur without redeploying the Move VM itself, or the supporting system code (network node software). It also means the state machine can upgrade without a coordinated halt.

- To do this we require the `libra` cli tool. The subcommand `libra move framework` is used for building the artifacts, and `libra txs` for proposing, voting, and ultimately deploying the artifacts.
- To do this we require the `libra` and `libra-framework` cli tools. The command `libra-framework` is used for building the artifacts, and `libra txs` for proposing, voting, and ultimately deploying the artifacts.

## Historical Upgrade Information and Proposing Upgrades
Historical upgrade information since release 7.0.0 is canonically stored in the [upgrade repository](https://github.com/0LNetworkCommunity/upgrades). To submit an upgrade proposal, you should draft a PR with the relevant information detailing the upgrade using the provided [template](https://github.com/0LNetworkCommunity/upgrades/tree/main/proposals/template) and include the upgrade script packages.


## TLDR
- **Fetch the latest release**: `cd libra-framework; git fetch --all; git checkout release-x.x.x`
- **Build framework**: `libra move framework upgrade --output-dir ~/framework_upgrade --framework-local-dir ~/libra-framework/framework/`
- **Propose**: `libra txs governance propose --proposal-script-dir ~/framework_upgrade/1-move-stdlib/ --metadata-url https://www.github.com/0LNetworkCommunity/UpdateProposalTemplate`
- **Build framework**: `libra-framework upgrade --output-dir ~/framework_upgrade --framework-local-dir ~/libra-framework/framework/`
- **Propose**: `libra txs governance propose --proposal-script-dir ~/framework_upgrade/1-move-stdlib/ --metadata-url https://github.com/0LNetworkCommunity/upgrades/tree/main/proposals/template`
- **Validators vote**: `libra txs governance vote --proposal-id <ID>`
- **Resolve**:

Expand Down Expand Up @@ -39,7 +43,7 @@ Multiple framework upgrades require a more nuanced approach, especially regardin
- **Build Framework**: Similar to a single upgrade, start by generating Move transaction scripts for all relevant modules.
- **Proposal for Initial Module**: Propose the upgrade by using the first module (`1-move-stdlib`). This initial proposal is critical as it kickstarts the governance process for the entire upgrade.

Importantly, the transaction script for upgrading this first module includes a significant addition: **the transaction hash for the subsequent modules** that needs upgrading. These hashes, produced during the artifact building phase, serve as secure identifiers for each module's upgrade script.
Importantly, the transaction script for upgrading this first module includes a significant addition: **the transaction hash for the subsequent modules** that needs upgrading. These hashes, produced during the artifact building phase, serve as secure identifiers for each module's upgrade script.

- **Validator Voting**: As with single upgrades, validators vote for or against the proposed upgrade.
- **Achieving Consensus and Sequential Resolution**: Once at least 66% of active validators support the proposal, the initial upgrade can be resolved.
Expand Down Expand Up @@ -72,7 +76,7 @@ This will be a Move package which is machine-generated for a one-time execution.

An upgrade script that is tampered with will yield a different execution hash, and will be prevented from running (it is likely to be blocked by the transaction size limits before entering the mempool).

The `libra move framework upgrade` command will produce a newly compiled Move upgrade transaction script, its binary, and the hash.
The `libra-framework upgrade` command will produce a newly compiled Move upgrade transaction script, its binary, and the hash.

You need to provide:
- `--output-dir`: this directory the upgrade transaction files should be saved to. A new folder called `framework_upgrade` will be created under the output-dir path.
Expand All @@ -83,10 +87,10 @@ Optionally you could provide the flag `--danger-force-upgrade

```
# Note the paths
libra move framework upgrade --output-dir <OUTPUT_DIR> --framework-local-dir <FRAMEWORK_PATH>
libra-framework upgrade --output-dir <OUTPUT_DIR> --framework-local-dir <FRAMEWORK_PATH>
# Example
libra move framework upgrade --output-dir ~/framework_upgrade --framework-local-dir ~/libra-framework/framework/
libra-framework upgrade --output-dir ~/framework_upgrade --framework-local-dir ~/libra-framework/framework/
```
:::note
This creates 3 seperate library upgrade script directories
Expand Down Expand Up @@ -128,7 +132,7 @@ You can query the next proposal using this command: ` libra query view --functio

We assume the default is to vote in favor. To vote "approve" simply:
```
libra txs governance vote --proposal-id <PROPOSAL_ID>
libra txs governance vote --proposal-id <PROPOSAL_ID>
```

If voter would like the proposal to be rejected:
Expand All @@ -139,7 +143,7 @@ libra txs governance vote --proposal-id <PROPOSAL_ID> --should-fail
You can query to see the for and against votes using this command: ` libra query view --function-id 0x1::diem_governance::get_votes --args <proposal_number>`
:::

After everyone has voted (to reach the consensus threshold of 66% as of `V7`), the proposal will be in a "Resolvable" state. Anyone can resolve it by submitting the upgrade transaction. This means the sender must have the source transaction script for the upgrade (step #1 above).
After everyone has voted (to reach the consensus threshold of 66% as of `V7`), the proposal will be in a "Resolvable" state. Anyone can resolve it by submitting the upgrade transaction. This means the sender must have the source transaction script for the upgrade (step #1 above).

##### 6. Use `txs` to resolve a successfully approved proposal
```
Expand Down
93 changes: 93 additions & 0 deletions docs/key_rotation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Key Rotation
> CAUTION: Please read carefully and ensure you understand these instructions. Rotating the wrong key could lock you out of your account and make funds permanently inaccessible.
There are two cases:

1) You are in full control of an account and would like to rotate to a new private key (using a new mnemonic).

This is a single step, and you can simply use the current mnemonic to sign a transaction and the new mnemonic to sign a rotation proof.

2) You are claiming an account from someone else.

This requires two steps where the current owner (Alice) will first authorize an existing account of the new owner (Bob) to rotate keys for the account being claimed. Bob will have two accounts at the end of the process, and the prior owner, Alice, will have none.

## CASE 1: Rotate Keys on Your Wallet

You will be prompted for a mnemonic twice. But these should be DIFFERENT mnemonics.

The first mnemonic is for your current credentials which will be deprecated. It is used to sign and send the rotation transaction to the blockchain.

In the process, you will be prompted for the NEW mnemonic you would like to be using going forward.

Additionally, you can expect the CLI tool to ask you to confirm this operation twice in the process.

```bash
libra txs user rotate-key
```

Note: If you have an advanced case and would like to submit the private key itself, see below.

## CASE 2: Claim an account

There are two steps involved in claiming another account. First, some definitions:
- There are two parties Original Owner (Alice, for example) and New Owner (Bob).

- Alice is offering the Claimed Account (`0x123`) to Bob.

- Bob must already have a separate Delegate Account on-chain (`0x456`). The only reason for this is that Bob needs to do some sensitive signing of keys and submit it to the chain, and there's no way for Alice or really anyone else to do this for him.

- Bob will also require a New Mnemonic, which he will use to control the Claimed Account in the future.

With all that in place:

#### Original Owner Alice's Job

Alice will send a transaction to "delegate" Bob's account `0x456` with the power to rotate the keys to `0x123`.

Alice's job ends here.

#### New Owner Bob's Job

Next, Bob needs his usual credentials for `0x456`, and also the New Mnemonic he plans to use for `0x123`.

He submits a transaction (after a bit of processing of the New Mnemonic private keys), which should successfully rotate the keys to `0x123`.

The job of the Delegate account `0x456` is over (the account could even be disposed of).

## Step 1: Original Owner Delegates Rotation Capability
Grant another user the capability to change the Authentication Key for a specified address. You will be prompted to enter the mnemonic for the address whose authentication key will be changed:

```bash
libra txs user rotation-capability --delegate-address <DELEGATE_ADDRESS>
```

The specified delegate address can now rotate authentication keys on the address for which the mnemonic was provided.

## Step 2: New Owner Rotates Authentication Keys Using the Delegated Address
Enables a delegated user to rotate the Authentication Key for a specified wallet address:

```bash
libra txs user rotate-key --claim-address <ACCOUNT_ADDRESS>
```

# Cheat Sheet

### Create a new mnemonic
```
libra wallet keygen
```

# Advanced: Optionally Input the Private Key
To recover a private key using a mnemonic, use:

```bash
libra wallet keygen --mnemonic <MNEMONIC> --output-dir <OUTPUT_DIR>
```

Your private key will be stored in a file called `private_keys.yaml` in the directory you specified above. Specifically, it's called `account_private_key`. The private key corresponds with the `account_address` above it.

Once you have a private key, you can submit the transaction by explicitly setting the key. In this case, the new mnemonic will not be asked for.

```bash
libra txs user rotate-key --new-private-key <NEW_PRIVATE_KEY> --claim-address <ACCOUNT_ADDRESS>
```
6 changes: 0 additions & 6 deletions private-keys.yaml

This file was deleted.

7 changes: 0 additions & 7 deletions public-keys.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion tools/config/src/make_yaml_public_fullnode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub fn add_peers_to_yaml(

parsed.full_node_networks.iter_mut().for_each(move |e| {
if e.network_id.is_public_network() {
e.seed_addrs = peers.clone();
e.seed_addrs.clone_from(&peers);
}
});

Expand Down
1 change: 1 addition & 0 deletions tools/txs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ repository = { workspace = true }
anyhow = { workspace = true }
bcs = { workspace = true }
clap = { workspace = true }
dialoguer = { workspace = true }
diem = { workspace = true }
diem-crypto = { workspace = true }
diem-framework = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions tools/txs/src/submit_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ impl Sender {
}

pub fn set_tx_cost(&mut self, cost: &TxCost) {
self.tx_cost = cost.to_owned();
cost.clone_into(&mut self.tx_cost);
}

///
/// load from local app configs
pub async fn from_app_cfg(app_cfg: &AppCfg, profile: Option<String>) -> anyhow::Result<Self> {
let profile = app_cfg.get_profile(profile)?;

Expand Down
2 changes: 1 addition & 1 deletion tools/txs/src/txs_cli_community.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl BatchTx {
if let Some((_, pp)) = pending_or_approved.get_key_value(&addr) {
if pp.amount == gas_coin::cast_decimal_to_coin(inst.amount as f64) {
inst.proposed = Some(true);
inst.voters = pp.voters.clone();
inst.voters.clone_from(&pp.voters);
inst.approved = pp.approved;
println!("... found already pending, mark as proposed");
}
Expand Down
Loading

0 comments on commit 7fe1ba1

Please sign in to comment.