Skip to content

Commit

Permalink
[upgrade] migrate user receipts for upgrade (#89)
Browse files Browse the repository at this point in the history
Co-authored-by: 0o-de-lally <[email protected]>
Co-authored-by: sirouk <[email protected]>
  • Loading branch information
3 people committed Aug 8, 2024
1 parent cd239b5 commit 26e36df
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 58 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
rev: v4.5.0
hooks:
- id: trailing-whitespace
files: \.(rs|move)$
- id: end-of-file-fixer
files: \.(rs|move)$
- repo: https://github.com/doublify/pre-commit-rust
rev: master
rev: v1.0
hooks:
- id: fmt
111 changes: 55 additions & 56 deletions framework/libra-framework/sources/ol_sources/receipts.move
Original file line number Diff line number Diff line change
Expand Up @@ -18,69 +18,68 @@ module ol_framework::receipts {
use std::signer;
use diem_framework::system_addresses;
use diem_framework::timestamp;
use std::fixed_point32;

// use diem_std::debug::print;
// use ol_framework::epoch_helper;

struct UserReceipts has key {
destination: vector<address>,
cumulative: vector<u64>,
last_payment_timestamp: vector<u64>,
last_payment_value: vector<u64>,
}
struct UserReceipts has key {
destination: vector<address>,
cumulative: vector<u64>,
last_payment_timestamp: vector<u64>,
last_payment_value: vector<u64>,
}

// Utility used at genesis (and on upgrade) to initialize the system state.
public fun user_init(account: &signer) {
let addr = signer::address_of(account);
if (!exists<UserReceipts>(addr)) {
move_to<UserReceipts>(
account,
UserReceipts {
destination: vector::empty<address>(),
last_payment_timestamp: vector::empty<u64>(),
last_payment_value: vector::empty<u64>(),
cumulative: vector::empty<u64>(),
}
)
};
}
// Utility used at genesis (and on upgrade) to initialize the system state.
public fun user_init(account: &signer) {
let addr = signer::address_of(account);
if (!exists<UserReceipts>(addr)) {
move_to<UserReceipts>(
account,
UserReceipts {
destination: vector::empty<address>(),
last_payment_timestamp: vector::empty<u64>(),
last_payment_value: vector::empty<u64>(),
cumulative: vector::empty<u64>(),
}
)
};
}

// should only be called from the genesis script.
fun fork_migrate(
vm: &signer,
account: &signer,
destination: address,
cumulative: u64,
last_payment_timestamp: u64,
last_payment_value: u64,
split_factor: u64, // 6 decimals, or 1m
) acquires UserReceipts {

let split_factor = fixed_point32::create_from_rational(split_factor, 1000000);
let cumulative = if (cumulative > 0) {
fixed_point32::multiply_u64(cumulative, split_factor)
} else { 0 };
let last_payment_value = if (last_payment_value > 0) {
fixed_point32::multiply_u64(last_payment_value, split_factor)
} else { 0 };

system_addresses::assert_vm(vm);
let addr = signer::address_of(account);
assert!(is_init(addr), 0);
let state = borrow_global_mut<UserReceipts>(addr);
vector::push_back(&mut state.destination, destination);
vector::push_back(&mut state.cumulative, cumulative);
vector::push_back(&mut state.last_payment_timestamp, last_payment_timestamp);
vector::push_back(
&mut state.last_payment_value,
last_payment_value
);
// should only be called from the genesis script.
fun genesis_migrate_user(
vm: &signer,
account: &signer,
destination: vector<address>,
cumulative: vector<u64>,
last_payment_timestamp: vector<u64>,
last_payment_value: vector<u64>,
// assume split factor done in rust
) acquires UserReceipts {
system_addresses::assert_ol(vm);
let addr = signer::address_of(account);
if (!exists<UserReceipts>(addr)) {
move_to<UserReceipts>(
account,
UserReceipts {
destination,
last_payment_timestamp,
last_payment_value,
cumulative,
}
)
} else {
let state = borrow_global_mut<UserReceipts>(addr);
state.destination = destination;
state.cumulative = cumulative;
state.last_payment_timestamp = last_payment_timestamp;
state.last_payment_value = last_payment_value;
}
}

public fun is_init(addr: address):bool {
exists<UserReceipts>(addr)
}


public fun is_init(addr: address):bool {
exists<UserReceipts>(addr)
}

public fun write_receipt_vm(
sender: &signer,
Expand Down
Binary file modified framework/releases/head.mrb
Binary file not shown.
86 changes: 86 additions & 0 deletions tools/genesis/src/genesis_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ pub fn genesis_migrate_all_users(
}
}
}

// migrating tower
if a.receipts.is_some() {
match genesis_migrate_receipts(session, a, supply) {
Ok(_) => {}
Err(e) => {
if a.role != AccountRole::System {
println!("Error migrating user: {:?}", e);
}
}
}
}
});
Ok(())
}
Expand Down Expand Up @@ -205,6 +217,80 @@ pub fn genesis_migrate_infra_escrow(
Ok(())
}

pub fn genesis_migrate_receipts(
session: &mut SessionExt,
user_recovery: &LegacyRecovery,
supply: &Supply,
) -> anyhow::Result<()> {
if user_recovery.account.is_none()
|| user_recovery.auth_key.is_none()
|| user_recovery.balance.is_none()
{
anyhow::bail!("no user account found {:?}", user_recovery);
}

// convert between different types from ol_types in diem, to current
let acc_str = user_recovery
.account
.context("could not parse account")?
.to_string();
let new_addr_type = AccountAddress::from_hex_literal(&format!("0x{}", acc_str))?;

if let Some(receipts_vec) = user_recovery.receipts.as_ref() {
let dest_map: Vec<AccountAddress> = receipts_vec
.destination
.iter()
.map(|leg_addr| {
AccountAddress::from_hex_literal(&format!("0x{}", leg_addr))
.expect("could not parse account address")
})
.collect();

let cumu_map: Vec<MoveValue> = receipts_vec
.cumulative
.iter()
.map(|e| {
let scaled = (*e as f64) * supply.split_factor;
MoveValue::U64(scaled as u64)
})
.collect();

let timestamp_map: Vec<MoveValue> = receipts_vec
.last_payment_timestamp
.iter()
.map(|e| MoveValue::U64(*e))
.collect();

let payment_map: Vec<MoveValue> = receipts_vec
.last_payment_value
.iter()
.map(|e| {
let scaled = (*e as f64) * supply.split_factor;
MoveValue::U64(scaled as u64)
})
.collect();

let serialized_values = serialize_values(&vec![
MoveValue::Signer(AccountAddress::ZERO), // is sent by the 0x0 address
MoveValue::Signer(new_addr_type),
MoveValue::vector_address(dest_map),
MoveValue::Vector(cumu_map),
MoveValue::Vector(timestamp_map),
MoveValue::Vector(payment_map),
]);

exec_function(
session,
"receipts",
"genesis_migrate_user",
vec![],
serialized_values,
);
}

Ok(())
}

pub fn genesis_migrate_tower_state(
session: &mut SessionExt,
user_recovery: &LegacyRecovery,
Expand Down
18 changes: 18 additions & 0 deletions tools/genesis/tests/fixtures/sample_end_user_single.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@
"balance": {
"coin": 623727004
},
"receipts": {
"destination": [
"a52ae72d3c444fd3691bc8bd25e38b97",
"bca50d10041fa111d1b44181a264a599"
],
"cumulative": [
200000000000,
115581799092
],
"last_payment_timestamp": [
1652312818,
1680837133
],
"last_payment_value": [
200000000000,
115581799092
]
},
"miner_state": {
"previous_proof_hash": [
233,
Expand Down

0 comments on commit 26e36df

Please sign in to comment.