Skip to content

Commit d091001

Browse files
siroukIsa StaccatoCaro di PianoLucietta Von HindGiulietta Coney
authored andcommitted
[move] handle malformed timestamps in activity.move (#401)
Co-authored-by: Isa Staccato <[email protected]> Co-authored-by: Caro di Piano <[email protected]> Co-authored-by: Lucietta Von Hind <[email protected]> Co-authored-by: Giulietta Coney <[email protected]>
1 parent 187b56c commit d091001

File tree

4 files changed

+71
-18
lines changed

4 files changed

+71
-18
lines changed

framework/libra-framework/sources/ol_sources/activity.move

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ module ol_framework::activity {
2222

2323
//////// ERROR CODES ///////
2424
/// account not initialized on v8 chain
25-
const EACCOUNT_MALFORMED: u64 = 1;
25+
const EACCOUNT_NOT_MIGRATED: u64 = 0;
26+
/// account has malformed timestamp
27+
const ETIMESTAMP_MALFORMED: u64 = 1;
2628

2729
struct Activity has key {
2830
last_touch_usecs: u64,
2931
onboarding_usecs: u64,
3032
}
3133

3234
/// Initialize the activity timestamp of a user
33-
public(friend) fun lazy_initialize(user: &signer, timestamp: u64) {
34-
if (!exists<Activity>(signer::address_of(user))) {
35+
public(friend) fun lazy_initialize(user: &signer) {
36+
let timestamp = timestamp::now_seconds();
37+
if (!is_initialized(signer::address_of(user))) {
3538
move_to<Activity>(user, Activity {
3639
last_touch_usecs: timestamp,
3740
onboarding_usecs: timestamp
@@ -41,33 +44,32 @@ module ol_framework::activity {
4144

4245
/// Increment the activity timestamp of a user
4346
// NOTE: this serves to gate users who have not onboarded since v8 upgrade
44-
public(friend) fun increment(user: &signer, timestamp: u64) acquires Activity {
45-
46-
assert!(exists<Activity>(signer::address_of(user)), error::invalid_state(EACCOUNT_MALFORMED));
47+
public(friend) fun increment(user: &signer) acquires Activity {
48+
is_initialized(signer::address_of(user));
49+
maybe_fix_malformed(user);
4750

4851
let state = borrow_global_mut<Activity>(signer::address_of(user));
49-
state.last_touch_usecs = timestamp;
52+
state.last_touch_usecs = timestamp::now_seconds();
5053
}
5154

5255
#[view]
5356
/// get the last activity timestamp of a user
5457
public fun get_last_activity_usecs(user: address): u64 acquires Activity {
55-
if (exists<Activity>(user)) {
58+
if (is_initialized(user)) {
5659
let state = borrow_global<Activity>(user);
5760
return state.last_touch_usecs
5861
};
5962
0
6063
}
6164

62-
public(friend) fun maybe_onboard(user_sig: &signer){
63-
65+
public(friend) fun maybe_onboard(user_sig: &signer) {
6466
// genesis accounts should not start at 0
6567
let onboarding_usecs = timestamp::now_seconds();
6668
if (onboarding_usecs == 0) {
6769
onboarding_usecs = 1;
6870
};
6971

70-
if (!exists<Activity>(signer::address_of(user_sig))) {
72+
if (!is_initialized(signer::address_of(user_sig))) {
7173
move_to<Activity>(user_sig, Activity {
7274
last_touch_usecs: 0, // how we identify if a users has used the account after a peer created it.
7375
onboarding_usecs,
@@ -78,19 +80,56 @@ module ol_framework::activity {
7880
/// migrate or heal a pre-v8 account
7981
public(friend) fun migrate(user_sig: &signer) acquires Activity {
8082
let addr = signer::address_of(user_sig);
81-
if (!exists<Activity>(addr)) {
83+
if (!is_initialized(addr)) {
8284
move_to<Activity>(user_sig, Activity {
8385
last_touch_usecs: 0,
8486
onboarding_usecs: 0,
8587
})
86-
} else if (is_pre_v8(addr)) {
88+
};
89+
90+
maybe_fix_malformed(user_sig);
91+
92+
if (is_pre_v8(addr)) {
8793
// this is a pre-v8 account that might be malformed
8894
let state = borrow_global_mut<Activity>(addr);
8995
state.last_touch_usecs = 0;
9096
state.onboarding_usecs = 0;
9197
}
9298
}
9399

100+
fun assert_initialized(user: address) {
101+
// check malformed accounts with microsecs
102+
assert!(exists<Activity>(user), error::invalid_state(EACCOUNT_NOT_MIGRATED));
103+
}
104+
105+
/// some accounts with transactions immediately after the v8 upgrade
106+
/// may have a malformed timestamp
107+
// NOTE: make this an entry function to allow for
108+
// manual migration
109+
public entry fun maybe_fix_malformed(user: &signer) acquires Activity {
110+
assert_initialized(signer::address_of(user));
111+
if (!is_timestamp_secs(signer::address_of(user))) {
112+
let state = borrow_global_mut<Activity>(signer::address_of(user));
113+
state.onboarding_usecs = 0;
114+
// last_touch_usecs should be set in the transaction_validation
115+
// but we'll set it here to be safe
116+
state.last_touch_usecs = timestamp::now_seconds();
117+
}
118+
}
119+
120+
/// check for edge cases in initialization during v8 migration
121+
fun is_timestamp_secs(acc: address): bool acquires Activity {
122+
// check if this is incorrectly in microsecs
123+
if (
124+
get_last_activity_usecs(acc) > 1_000_000_000_000 ||
125+
get_onboarding_usecs(acc) > 1_000_000_000_000
126+
) {
127+
return false
128+
};
129+
130+
true
131+
}
132+
94133

95134
#[view]
96135
// check if this is an account that has activity
@@ -107,12 +146,16 @@ module ol_framework::activity {
107146

108147
#[view]
109148
public fun get_last_touch_usecs(user: address): u64 acquires Activity {
149+
assert_initialized(user);
150+
110151
let state = borrow_global<Activity>(user);
111152
state.last_touch_usecs
112153
}
113154

114155
#[view]
115156
public fun get_onboarding_usecs(user: address): u64 acquires Activity {
157+
// check malformed accounts with microsecs
158+
assert_initialized(user);
116159
let state = borrow_global<Activity>(user);
117160
state.onboarding_usecs
118161
}
@@ -128,10 +171,21 @@ module ol_framework::activity {
128171
#[view]
129172
// check the timestamp prior to v8 launch
130173
public fun is_pre_v8(user: address): bool acquires Activity {
174+
assert_initialized(user);
175+
131176
if (testnet::is_testnet()) {
132177
return false
133178
};
134-
get_onboarding_usecs(user) < 1747267200 // Date and time (GMT): Thursday, May 15, 2025 12:00:00 AM
179+
180+
// catch edge cases of malformed timestamp
181+
// should be considered a pre-v8 for
182+
// purposes of triggering a migration
183+
if (!is_timestamp_secs(user)) {
184+
return true
185+
};
186+
187+
get_onboarding_usecs(user) < 1_747_267_200
188+
// Date and time (GMT): Thursday, May 15, 2025 12:00:00 AM
135189
}
136190

137191

framework/libra-framework/sources/ol_sources/donor_voice_migration.move

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ module ol_framework::donor_voice_migration {
1313
use std::vector;
1414
use diem_framework::multisig_account;
1515
use diem_framework::system_addresses;
16-
use diem_framework::timestamp;
1716
use ol_framework::activity;
1817
use ol_framework::multi_action;
1918
use ol_framework::migration_capability::{Self, MigrationCapability};
@@ -64,7 +63,7 @@ module ol_framework::donor_voice_migration {
6463
community_wallet_advance::initialize(&multisig_signer);
6564

6665
donor_voice_governance::maybe_init_dv_governance(&multisig_signer);
67-
activity::lazy_initialize(&multisig_signer, timestamp::now_seconds());
66+
activity::lazy_initialize(&multisig_signer);
6867

6968
}
7069
}

framework/libra-framework/sources/ol_sources/mock.move

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ public fun simulate_v8_migration(sender: &signer) {
581581
// Note, Activity and Founder struct should have been set above
582582
filo_migration::maybe_migrate(sender);
583583
// touching the account will also increment activity
584-
activity::increment(sender, timestamp::now_seconds());
584+
activity::increment(sender);
585585
}
586586

587587
//////// META TESTS ////////

framework/libra-framework/sources/transaction_validation.move

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ module diem_framework::transaction_validation {
207207

208208
//////// OL ////////
209209
// increments the activity tracker
210-
activity::increment(&account, timestamp::now_microseconds());
210+
activity::increment(&account);
211211

212212
// Increment sequence number
213213
account::increment_sequence_number(addr);

0 commit comments

Comments
 (0)