Skip to content

Commit

Permalink
Account genesis (#123)
Browse files Browse the repository at this point in the history
* Handle EVM accounts and pruge locks

Signed-off-by: Xavier Lau <xavier@inv.cafe>

* Refactor account genesis

* Purge locks

* Update scope

* Update special accounts list

Signed-off-by: Xavier Lau <xavier@inv.cafe>
  • Loading branch information
AurevoirXavier authored Dec 14, 2022
1 parent 5b19e28 commit d4922e1
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 148 deletions.
10 changes: 8 additions & 2 deletions tool/state-processor/Cargo.lock

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

4 changes: 2 additions & 2 deletions tool/state-processor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
[package]
authors = ["Xavier Lau <xavier@inv.cafe>"]
edition = "2021"
license = "GPL-3.0"
name = "state-processor"
version = "0.0.0"

[dependencies]
# crates.io
anyhow = { version = "1.0" }
array-bytes = { version = "4.1" }
array-bytes = { version = "6.0" }
fxhash = { version = "0.2" }
log = { version = "0.4" }
parity-scale-codec = { version = "3.2", features = ["derive"] }
pretty_env_logger = { version = "0.4" }
serde = { version = "1.0" }
serde_json = { version = "1.0" }

# hack-ink
subhasher = { git = "https://github.com/hack-ink/subalfred" }
subspector = { git = "https://github.com/hack-ink/subalfred" }
Expand Down
112 changes: 82 additions & 30 deletions tool/state-processor/src/balances/mod.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,89 @@
// darwinia
use crate::*;

type Locks = Vec<BalanceLock>;

impl Processor {
pub fn process_balances(
&mut self,
ring_locks: &mut Map<Vec<BalanceLock>>,
kton_locks: &mut Map<Vec<BalanceLock>>,
) -> &mut Self {
log::info!("take solo balance locks");
pub fn process_balances(&mut self) -> (u128, u128) {
let mut solo_ring_total_issuance = u128::default();
let mut kton_total_issuance = u128::default();
let mut solo_ring_locks = <Map<Locks>>::default();
let mut solo_kton_locks = <Map<Locks>>::default();
let mut para_ring_locks = <Map<Locks>>::default();
let mut para_ring_total_issuance = u128::default();

log::info!("take solo balances total issuances and locks");
self.solo_state
.take::<Vec<BalanceLock>, _>(
b"Balances",
b"Locks",
ring_locks,
get_blake2_128_concat_suffix,
)
.take::<Vec<BalanceLock>, _>(
b"Kton",
b"Locks",
kton_locks,
get_blake2_128_concat_suffix,
);

// ---
// Currently, there are only fee-market locks.
// I suggest shutting down the fee-market before merging.
// So, we could ignore the para balance locks migration.
// ---

log::info!("adjust solo balance lock decimals");
ring_locks.iter_mut().for_each(|(_, v)| v.iter_mut().for_each(|l| l.amount *= GWEI));
kton_locks.iter_mut().for_each(|(_, v)| v.iter_mut().for_each(|l| l.amount *= GWEI));

self
.take_value(b"Balances", b"TotalIssuance", &mut solo_ring_total_issuance)
.take_value(b"Kton", b"TotalIssuance", &mut kton_total_issuance)
.take_map(b"Balances", b"Locks", &mut solo_ring_locks, get_hashed_key)
.take_map(b"Kton", b"Locks", &mut solo_kton_locks, get_hashed_key);

log::info!("prune solo balance locks");
prune(&mut solo_ring_locks);
prune(&mut solo_kton_locks);

log::info!("adjust solo balances items' decimals");
solo_ring_total_issuance *= GWEI;
kton_total_issuance *= GWEI;
// solo_ring_locks.iter_mut().for_each(|(_, v)| v.iter_mut().for_each(|l| l.amount *=
// GWEI)); solo_kton_locks.iter_mut().for_each(|(_, v)| v.iter_mut().for_each(|l| l.amount
// *= GWEI));

log::info!("take para balances total issuances and locks");
self.para_state
.take_value(b"Balances", b"TotalIssuance", &mut para_ring_total_issuance)
.take_map(b"Balances", b"Locks", &mut para_ring_locks, get_hashed_key);

log::info!("check solo ring locks, there should not be any `solo_ring_locks`");
check_locks(solo_ring_locks);
log::info!("check solo kton locks, there should not be any `solo_kton_locks`");
check_locks(solo_kton_locks);
log::info!("check para locks, there should not be any `para_ring_locks`");
check_locks(para_ring_locks);

(solo_ring_total_issuance + para_ring_total_issuance, kton_total_issuance)
}
}

fn prune(locks: &mut Map<Locks>) {
// https://github.dev/darwinia-network/darwinia-common/blob/6a9392cfb9fe2c99b1c2b47d0c36125d61991bb7/frame/staking/src/primitives.rs#L39
const STAKING: [u8; 8] = *b"da/staki";
// https://github.dev/darwinia-network/darwinia/blob/2d1c1436594b2c397d450e317c35eb16c71105d6/runtime/crab/src/pallets/elections_phragmen.rs#L8
const PHRAGMEN_ELECTION: [u8; 8] = *b"phrelect";
// https://github.dev/paritytech/substrate/blob/19162e43be45817b44c7d48e50d03f074f60fbf4/frame/democracy/src/lib.rs#L190
const DEMOCRACY: [u8; 8] = *b"democrac";
// https://github.dev/paritytech/substrate/blob/19162e43be45817b44c7d48e50d03f074f60fbf4/frame/vesting/src/lib.rs#L86
const VESTING: [u8; 8] = *b"vesting ";
const RELAY_AUTHORITY: [u8; 8] = *b"ethrauth";
// https://github.dev/darwinia-network/darwinia/blob/2d1c1436594b2c397d450e317c35eb16c71105d6/runtime/crab/src/pallets/fee_market.rs#L35
const FEE_MARKET_0: [u8; 8] = *b"da/feelf";
// https://github.dev/darwinia-network/darwinia/blob/2d1c1436594b2c397d450e317c35eb16c71105d6/runtime/crab/src/pallets/fee_market.rs#L36
const FEE_MARKET_1: [u8; 8] = *b"da/feecp";
// https://github.dev/darwinia-network/darwinia/blob/2d1c1436594b2c397d450e317c35eb16c71105d6/runtime/darwinia/src/pallets/fee_market.rs#L37
const FEE_MARKET_2: [u8; 8] = *b"da/feedp";

locks.retain(|k, v| {
v.retain(|l| match l.id {
STAKING | PHRAGMEN_ELECTION | DEMOCRACY | VESTING | RELAY_AUTHORITY | FEE_MARKET_0
| FEE_MARKET_1 | FEE_MARKET_2 => false,
id => {
log::error!(
"pruned unknown lock id({}) of account({})",
String::from_utf8_lossy(&id),
get_last_64(k)
);

false
},
});

!v.is_empty()
});
}

fn check_locks(locks: Map<Locks>) {
locks
.into_iter()
.for_each(|(k, _)| log::error!("found unexpected locks of account({})", get_last_64(&k)));
}
51 changes: 43 additions & 8 deletions tool/state-processor/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod balances;
mod system;
mod vesting;

mod type_registry;
use type_registry::*;
Expand Down Expand Up @@ -45,6 +46,7 @@ impl Processor {

fn process(mut self) -> Result<()> {
self.process_system();
self.process_vesting();

self.save()
}
Expand Down Expand Up @@ -108,7 +110,23 @@ impl State {
self
}

fn take<D, F>(
fn take_value<D>(&mut self, pallet: &[u8], item: &[u8], value: &mut D) -> &mut Self
where
D: Decode,
{
let key = item_key(pallet, item);

if let Some(v) = self.0.remove(&key) {
match decode(&v) {
Ok(v) => *value = v,
Err(e) => log::warn!("failed to decode `{key}:{v}`, due to `{e}`"),
}
}

self
}

fn take_map<D, F>(
&mut self,
pallet: &[u8],
item: &[u8],
Expand All @@ -119,6 +137,7 @@ impl State {
D: Decode,
F: Fn(&str, &str) -> String,
{
let len = buffer.len();
let item_key = item_key(pallet, item);

self.0.retain(|full_key, v| {
Expand All @@ -136,6 +155,14 @@ impl State {
}
});

if buffer.len() == len {
log::info!(
"no new item inserted for {}::{}",
String::from_utf8_lossy(pallet),
String::from_utf8_lossy(item)
);
}

self
}
}
Expand All @@ -157,7 +184,7 @@ where
fn pallet_key(pallet: &[u8]) -> String {
let prefix = subhasher::twox128(pallet);

array_bytes::bytes2hex("0x", &prefix)
array_bytes::bytes2hex("0x", prefix)
}

fn item_key(pallet: &[u8], item: &[u8]) -> String {
Expand All @@ -166,6 +193,10 @@ fn item_key(pallet: &[u8], item: &[u8]) -> String {
array_bytes::bytes2hex("0x", &k.0)
}

fn full_key(pallet: &[u8], item: &[u8], hash: &str) -> String {
format!("{}{hash}", item_key(pallet, item))
}

fn encode_value<V>(v: V) -> String
where
V: Encode,
Expand All @@ -182,13 +213,17 @@ where
Ok(D::decode(&mut &*v)?)
}

// twox128(pallet) + twox128(item) + blake2_256_concat(item_key) -> blake2_256_concat(item_key)
fn get_blake2_128_concat_suffix(full_key: &str, item_key: &str) -> String {
// twox128(pallet) + twox128(item) -> twox128(pallet) + twox128(item)
fn get_identity_key(key: &str, _: &str) -> String {
key.into()
}

// twox128(pallet) + twox128(item) + *(item_key) -> *(item_key)
fn get_hashed_key(full_key: &str, item_key: &str) -> String {
full_key.trim_start_matches(item_key).into()
}

// twox128(pallet) + twox128(item) + blake2_256_concat(account_id_32) -> account_id_32
#[allow(unused)]
fn get_concat_suffix(full_key: &str, _: &str) -> String {
format!("0x{}", &full_key[full_key.len() - 64..])
// twox128(pallet) + twox128(item) + *_concat(account_id_32) -> account_id_32
fn get_last_64(key: &str) -> String {
format!("0x{}", &key[key.len() - 64..])
}
36 changes: 36 additions & 0 deletions tool/state-processor/src/system/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
### Process steps
- take solo account infos and remaining balances
- merge solo remaining balances
- adjust solo balance decimals
- take para account infos
- process balances
- take solo balances total issuances and locks
- prune solo balance locks
- prune staking, phragmen election, democracy, vesting, relay authority, fee market locks
- check if there are any other locks
- adjust solo balances items' decimals
- take para balances total issuances and locks
- there should not be any locks on parachain
- use all previous data to build the new accounts and calculate total issuances
- merge solo and para account infos
- how to deal with the account references? - TODO
- set `Balances::TotalIssuance`
- compare the calculated one with the storage one
- remove para backing account - TODO
- check remaining sum - TODO
- XCM relate - TODO
- set KTON total issuances - TODO
- compare the calculated one with the storage one
- check remaining sum - TODO
- set accounts
- if is EVM address
- insert to `System::Account`
- if is Substrate address
- reset the nonce
- insert to `AccountMigration::Accounts`
- calculate misc frozen and fee frozen

- some remaining accounts, bridge endpoint accounts - TODO
- special accounts - TODO
- parachain backing account 0x8c585F9791EE5b4B23fe82888cE576DBB69607eB
- bridge root account 0x726f6f7400000000000000000000000000000000
Loading

0 comments on commit d4922e1

Please sign in to comment.