Skip to content

Commit d4c6fc2

Browse files
authored
feat: migration guide + migration info on relayer (Templar-Protocol#354)
1 parent b22385b commit d4c6fc2

File tree

2 files changed

+31
-1
lines changed
  • contract/universal-account
  • service/relayer/src/route/universal_account

2 files changed

+31
-1
lines changed

contract/universal-account/README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,25 @@ cargo near deploy build-non-reproducible-wasm <account-id> \
8080
```
8181

8282
1. The action should be executed by the account.
83+
84+
## Upgrade
85+
86+
Older versions of the universal account contract can be upgraded to newer versions.
87+
88+
The first step in this process is always to deploy new contract code to the desired account. Since universal accounts are usually _locked_ (have no native NEAR full-access keys deployed), this should be done via a normal action execution.
89+
90+
Universal account contracts are usually deployed as global contract hashes, so to replace the currently-deployed code on a given account with new code, the account should execute a [`UseGlobalContract` action](https://docs.templarfi.org/doc/templar_universal_account/transaction/enum.Action.html#variant.DeployGlobalContract).
91+
92+
If the universal account was deployed from a registry and you wish to upgrade to a certain version of the contract deployed from that registry, view `get_version_code_hash({"version_key":"<version-key>"})` on the registry contract to retrieve the code hash. If using a relayer, the `version_key` string can be retrieved by `GET /universal_account`.
93+
94+
## Migration
95+
96+
Sometimes a version upgrade will require a migration, and sometimes it will not. To determine if a migration is necessary, perform a view call of `needs_migration`. If the view call resolves to `false`, then no migration is required.
97+
98+
If a migration _is_ required, we prepare a migration payload in order to properly parameterize the migration. Multiple migrations may be required (e.g. the code was upgraded from state version 1 &rarr; 3, so it must first migrate to version 2, then to version 3). Only one state migration can occur at a time.
99+
100+
1. Choose the state migration to perform. The list of state migrations can be found [here](https://docs.templarfi.org/doc/templar_universal_account/contract_state/enum.Migration.html). For example, if the contract is being upgraded from state version 0 to state version 1, we choose `V0`.
101+
2. Parameterize (if necessary). Some migrations require new information, some do not. In our example, the `V0` migration requires a `chain_id` parameter, so we choose `397` (NEAR Mainnet).
102+
3. Call `migrate` with the migration payload. For example: `migrate({"from_version":"v0","chain_id":"397"})`. Note that this function call is annotated with `#[private]`, meaning that the universal account itself is the only account that is allowed to call this function. Therefore, it may be executed as a `FunctionCall` action signed by one of the universal account's keys.
103+
104+
Generally speaking, it should be possible to combine a code upgrade and migration into a single transaction.

service/relayer/src/route/universal_account/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use axum::{
77
routing, Json, Router,
88
};
99
use near_sdk::{
10-
json_types::U64,
10+
json_types::{U128, U64},
1111
serde::{Deserialize, Serialize},
1212
AccountId,
1313
};
@@ -40,6 +40,8 @@ pub fn router() -> Router<App> {
4040
.route("/relay", routing::post(relay::relay))
4141
}
4242

43+
// pub fn
44+
4345
#[derive(Debug, Clone, Deserialize, Serialize)]
4446
#[serde(crate = "near_sdk::serde")]
4547
pub struct Index {
@@ -51,6 +53,10 @@ pub struct Index {
5153
pub pow_difficulty: usize,
5254
/// The block hash that is included in the creation request must not be older than this many seconds.
5355
pub blockref_max_age_secs: U64,
56+
/// The chain ID that the UA must be deployed on and configured to.
57+
pub chain_id: U128,
58+
/// The version key of the UA contract that the relayer will deploy from the registry.
59+
pub version_key: String,
5460
}
5561

5662
pub async fn index(State(app): State<App>) -> impl IntoResponse {
@@ -59,6 +65,8 @@ pub async fn index(State(app): State<App>) -> impl IntoResponse {
5965
registry_id: app.args.ua.registry_id,
6066
pow_difficulty: app.args.ua.pow_difficulty,
6167
blockref_max_age_secs: app.args.ua.blockref_max_age.as_secs().into(),
68+
chain_id: app.args.ua.chain_id.into(),
69+
version_key: app.args.ua.version_key.clone(),
6270
})
6371
}
6472

0 commit comments

Comments
 (0)