Skip to content

Commit fbdb421

Browse files
codilion0o-de-lally
andcommitted
[move] ancestry not implemented for account creation (#131)
Co-authored-by: 0o-de-lally <[email protected]>
1 parent 8a0f456 commit fbdb421

File tree

7 files changed

+109
-92
lines changed

7 files changed

+109
-92
lines changed

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

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,24 @@ module ol_framework::ancestry {
44
use std::vector;
55
use std::error;
66
use std::option::{Self, Option};
7-
// use std::debug::print;
87
use diem_framework::system_addresses;
98

109
friend ol_framework::vouch;
10+
friend ol_framework::ol_account;
1111

1212
/// two accounts are related by ancestry and should not be.
1313
const EACCOUNTS_ARE_FAMILY: u64 = 1;
14+
/// no ancestry tree state on chain, this is probably a migration bug.
15+
const ENO_ANCESTRY_TREE: u64 = 2;
1416

1517
struct Ancestry has key {
1618
// the full tree back to genesis set
1719
tree: vector<address>,
1820
}
1921

20-
// this is limited to onboarding.
21-
// TODO: limit this with `friend` of DiemAccount module.
22-
public fun init(new_account_sig: &signer, onboarder_sig: &signer ) acquires Ancestry{
23-
let parent = signer::address_of(onboarder_sig);
22+
// this is limited to onboarding of users
23+
public(friend) fun adopt_this_child(parent_sig: &signer, new_account_sig: &signer) acquires Ancestry{
24+
let parent = signer::address_of(parent_sig);
2425
set_tree(new_account_sig, parent);
2526
}
2627

@@ -58,49 +59,60 @@ module ol_framework::ancestry {
5859

5960
#[view]
6061
/// Getter for user's unfiltered tree
62+
/// @return vector of addresses if there is an ancestry struct
63+
// Commit NOTE: any transitive function that the VM calls needs to check
64+
// this struct exists.
6165
public fun get_tree(addr: address): vector<address> acquires Ancestry {
62-
if (exists<Ancestry>(addr)) {
63-
*&borrow_global<Ancestry>(addr).tree
64-
} else {
65-
vector::empty()
66-
}
66+
assert!(exists<Ancestry>(addr), ENO_ANCESTRY_TREE);
6767

68+
*&borrow_global<Ancestry>(addr).tree
6869
}
70+
6971
/// helper function to check on transactions (e.g. vouch) if accounts are related
70-
public fun assert_unrelated(left: address, right: address) acquires Ancestry{
72+
public fun assert_unrelated(left: address, right: address) acquires
73+
Ancestry{
7174
let (is, _) = is_family(left, right);
7275
assert!(!is, error::invalid_state(EACCOUNTS_ARE_FAMILY));
7376
}
7477

7578
// checks if two addresses have an intersecting permission tree
7679
// will return true, and the common ancestor at the intersection.
77-
// TODO: test if tree is empty does it abort.
7880
public fun is_family(left: address, right: address): (bool, address) acquires Ancestry {
7981
let is_family = false;
8082
let common_ancestor = @0x0;
8183

82-
let left_tree = get_tree(left);
83-
let right_tree = get_tree(right);
84+
// if there is no ancestry info this is a bug, assume related
85+
// NOTE: we don't want to error here, since the VM calls this
86+
// on epoch boundary
87+
if (!exists<Ancestry>(left)) return (true, @0x666);
88+
if (!exists<Ancestry>(right)) return (true, @0x666);
8489

85-
// check for direct relationship.
86-
if (vector::contains(&left_tree, &right)) return (true, right);
87-
if (vector::contains(&right_tree, &left)) return (true, left);
90+
let left_tree = get_tree(left);
91+
let right_tree = get_tree(right);
8892

93+
// check for direct relationship.
94+
if (vector::contains(&left_tree, &right)) return (true, right);
95+
if (vector::contains(&right_tree, &left)) return (true, left);
8996

90-
let i = 0;
91-
// check every address on the list if there are overlaps.
92-
while (i < vector::length<address>(&left_tree)) {
97+
let i = 0;
98+
// check every address on the list if there are overlaps.
99+
while (i < vector::length<address>(&left_tree)) {
93100

94-
let family_addr = vector::borrow(&left_tree, i);
95-
if (vector::contains(&right_tree, family_addr)) {
96-
is_family = true;
97-
common_ancestor = *family_addr;
101+
let family_addr = vector::borrow(&left_tree, i);
102+
if (vector::contains(&right_tree, family_addr)) {
103+
is_family = true;
104+
common_ancestor = *family_addr;
98105

99-
break
100-
};
101-
i = i + 1;
106+
break
102107
};
108+
i = i + 1;
109+
};
103110

111+
// for TEST compatibility, either no ancestor is found
112+
// or the Vm or Framework created accounts at genesis
113+
if (system_addresses::is_reserved_address(common_ancestor)) {
114+
is_family = false;
115+
};
104116
(is_family, common_ancestor)
105117
}
106118

@@ -201,4 +213,4 @@ module ol_framework::ancestry {
201213
child_ancestry.tree = migrate_tree;
202214
};
203215
}
204-
}
216+
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
/// 4. CommunityWallets have a high threshold for sybils: all multisig authorities must be unrelated in their permission trees, per ancestry.
2323

2424
module ol_framework::community_wallet {
25-
2625
use std::error;
2726
use std::vector;
2827
use std::signer;
@@ -34,6 +33,8 @@ module ol_framework::community_wallet {
3433
use ol_framework::match_index;
3534
use diem_framework::system_addresses;
3635

36+
// use diem_std::debug::print;
37+
3738
/// not authorized to operate on this account
3839
const ENOT_AUTHORIZED: u64 = 1;
3940
/// does not meet criteria for community wallet
@@ -153,7 +154,6 @@ module ol_framework::community_wallet {
153154
let n = (3 * len) / 5;
154155

155156
let (fam, _, _) = ancestry::any_family_in_list(*&init_signers);
156-
157157
assert!(!fam, error::invalid_argument(ESIGNERS_SYBIL));
158158

159159
// set as donor directed with any liquidation going to existing matching index
@@ -184,4 +184,4 @@ module ol_framework::community_wallet {
184184
option::some(vote_duration_epochs)
185185
);
186186
}
187-
}
187+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ module ol_framework::mock {
246246
let musical_chairs_default_seats = 10;
247247
musical_chairs::initialize(root, musical_chairs_default_seats);
248248

249-
250249
let val_addr = personas();
251250
let i = 0;
252251
while (i < num) {
@@ -255,7 +254,8 @@ module ol_framework::mock {
255254

256255
let (_sk, pk, pop) = stake::generate_identity();
257256
// stake::initialize_test_validator(&pk, &pop, &sig, 100, true, true);
258-
validator_universe::test_register_validator(root, &pk, &pop, &sig, 100, true, true);
257+
validator_universe::test_register_validator(root, &pk, &pop, &sig, 100,
258+
true, true);
259259

260260
vouch::init(&sig);
261261
vouch::test_set_buddies(*val, val_addr);

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module ol_framework::ol_account {
1212
use diem_std::math64;
1313

1414

15+
use ol_framework::ancestry;
1516
use ol_framework::libra_coin::{Self, LibraCoin};
1617
use ol_framework::slow_wallet;
1718
use ol_framework::receipts;
@@ -84,21 +85,23 @@ module ol_framework::ol_account {
8485
let (resource_account_sig, cap) = account::create_resource_account(user, seed);
8586
coin::register<LibraCoin>(&resource_account_sig);
8687
(resource_account_sig, cap)
88+
// adopt_this_child(user, resource_account_sig);
8789
}
8890

89-
fun create_impl(auth_key: address) {
90-
let new_signer = account::create_account(auth_key);
91+
fun create_impl(sender: &signer, maybe_new_user: address) {
92+
let new_signer = account::create_account(maybe_new_user);
9193
coin::register<LibraCoin>(&new_signer);
9294
receipts::user_init(&new_signer);
9395
init_burn_tracker(&new_signer);
96+
ancestry::adopt_this_child(sender, &new_signer);
9497
}
9598

9699
// #[test_only]
97100
/// Helper for tests to create acounts
98101
/// Belt and suspenders
99102
public entry fun create_account(root: &signer, auth_key: address) {
100103
system_addresses::assert_ol(root);
101-
create_impl(auth_key);
104+
create_impl(root, auth_key);
102105
}
103106

104107
/// For migrating accounts from a legacy system
@@ -156,15 +159,20 @@ module ol_framework::ol_account {
156159
public entry fun transfer(sender: &signer, to: address, amount: u64)
157160
acquires BurnTracker {
158161
let payer = signer::address_of(sender);
162+
maybe_sender_creates_account(sender, to);
159163
transfer_checks(payer, to, amount);
160164
// both update burn tracker
161165
let c = withdraw(sender, amount);
162166
deposit_coins(to, c);
163167
}
164168

165-
// transfer with capability, and do appropriate checks on both sides, and track the slow wallet
166-
public fun transfer_with_capability(cap: &WithdrawCapability, recipient:
169+
// transfer with capability, and do appropriate checks on both sides, and
170+
// track the slow wallet
171+
// NOTE: this requires that the account exists, since the SENDER signature is not used
172+
fun transfer_with_capability(cap: &WithdrawCapability, recipient:
167173
address, amount: u64) acquires BurnTracker {
174+
if(!account::exists_at(recipient)) return; // exit without abort,
175+
// since this might be called by the 0x0 at an epoch boundary.
168176
let payer = account::get_withdraw_cap_address(cap);
169177
transfer_checks(payer, recipient, amount);
170178
// NOTE: these shoud update BurnTracker
@@ -210,17 +218,18 @@ module ol_framework::ol_account {
210218
coin
211219
}
212220

221+
fun maybe_sender_creates_account(sender: &signer, maybe_new_user: address) {
222+
if (!account::exists_at(maybe_new_user)) {
223+
// creates the account address (with the same bytes as the authentication key).
224+
create_impl(sender, maybe_new_user);
225+
};
226+
}
227+
213228
// actual implementation to allow for capability
214229
fun transfer_checks(payer: address, recipient: address, amount: u64) {
215230
let limit = slow_wallet::unlocked_amount(payer);
216231
assert!(amount < limit, error::invalid_state(EINSUFFICIENT_BALANCE));
217232

218-
if (!account::exists_at(recipient)) {
219-
// creates the account address (with the same bytes as the authentication key).
220-
create_impl(recipient);
221-
};
222-
223-
224233
// TODO: Check if Resource Accounts can register here, since they
225234
// may be created without any coin registration.
226235
assert!(coin::is_account_registered<LibraCoin>(recipient), error::invalid_argument(EACCOUNT_NOT_REGISTERED_FOR_GAS));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#[test_only]
2+
3+
/// tests for external apis, and where a dependency cycle with genesis is created.
4+
module ol_framework::test_account {
5+
use std::vector;
6+
use ol_framework::libra_coin;
7+
use ol_framework::mock;
8+
use ol_framework::ol_account;
9+
use ol_framework::ancestry;
10+
use diem_framework::coin;
11+
use diem_std::debug::print;
12+
// scenario: testing trying send more funds than are unlocked
13+
#[test(root = @ol_framework, alice_sig = @0x1000a)]
14+
fun test_account_create(root: signer, alice_sig: signer) {
15+
let alice_addr = @0x1000a;
16+
let bob_addr = @0x1000b;
17+
18+
mock::ol_test_genesis(&root);
19+
20+
let mint_cap = libra_coin::extract_mint_cap(&root);
21+
ol_account::create_account(&root, alice_addr);
22+
ol_account::deposit_coins(alice_addr, coin::test_mint(100, &mint_cap));
23+
coin::destroy_mint_cap(mint_cap);
24+
25+
let addr_tree = ancestry::get_tree(alice_addr);
26+
assert!(vector::length(&addr_tree) > 0, 7357001);
27+
print(&addr_tree);
28+
assert!(vector::contains(&addr_tree, &@0x1), 7357002);
29+
30+
31+
let (a_balance, _) = ol_account::balance(alice_addr);
32+
assert!(a_balance == 100, 735703);
33+
34+
ol_account::transfer(&alice_sig, bob_addr, 20);
35+
let addr_tree = ancestry::get_tree(bob_addr);
36+
assert!(vector::length(&addr_tree) > 1, 7357004);
37+
assert!(vector::contains(&addr_tree, &alice_addr), 7357005);
38+
39+
print(&addr_tree);
40+
41+
}
42+
}

framework/libra-framework/sources/ol_sources/tests/burn.test.move

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ module ol_framework::test_burn {
282282
// assert!(TransactionFee::get_fees_collected()==1, 735703);
283283
// }
284284

285-
#[test(root=@ol_framework, alice=@0x1000a)]
285+
#[test(root=@ol_framework, alice=@0x1000a)]
286286
fun track_fees(root: &signer, alice: address) {
287287
// use ol_framework::libra_coin;
288288
let _vals = mock::genesis_n_vals(root, 1); // need to include eve to init funds

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

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,21 @@
22
// 0L Module
33
// ValidatorUniverse
44
///////////////////////////////////////////////////////////////////////////
5-
// Stores all the validators who submitted a vdf proof.
6-
// File Prefix for errors: 2201
7-
///////////////////////////////////////////////////////////////////////////
85

96
module diem_framework::validator_universe {
107
use std::signer;
118
use std::vector;
129
use diem_framework::system_addresses;
1310
use ol_framework::jail;
14-
// use ol_framework::grade;
1511
use ol_framework::vouch;
1612
use diem_framework::stake;
1713

18-
// use diem_framework::coin::Coin;
19-
// use ol_framework::libra_coin::LibraCoin;
20-
// use ol_framework::rewards;
2114

2215
#[test_only]
2316
use ol_framework::testnet;
2417
#[test_only]
2518
use diem_std::bls12381;
26-
// use diem_framework::account;
19+
2720
// use diem_std::debug::print;
2821

2922
friend diem_framework::reconfiguration;
@@ -64,7 +57,6 @@ module diem_framework::validator_universe {
6457
jail::init(account);
6558
}
6659

67-
6860
/// This function is called to add validator to the validator universe.
6961
fun add(sender: &signer) acquires ValidatorUniverse {
7062
let addr = signer::address_of(sender);
@@ -77,36 +69,6 @@ module diem_framework::validator_universe {
7769
jail::init(sender);
7870
}
7971

80-
// /// Used at epoch boundaries to evaluate the performance of the validator.
81-
// /// only root can call this, and only by friend modules (reconfiguration). Belt and suspenders.
82-
// public(friend) fun maybe_jail(root: &signer, validator: address): bool {
83-
// system_addresses::assert_ol(root);
84-
// maybe_jail_impl(root, validator)
85-
// }
86-
87-
// /// Common implementation for maybe_jail.
88-
// fun maybe_jail_impl(root: &signer, validator: address): bool {
89-
// system_addresses::assert_ol(root);
90-
91-
// let (compliant, _, _, _) = grade::get_validator_grade(validator);
92-
// // TODO check if there are issues with config. belt and suspenders
93-
94-
// if (compliant) {
95-
// jail::jail(root, validator);
96-
// return true
97-
// };
98-
99-
// false
100-
// }
101-
102-
103-
// /// performs the business logic for admitting new validators
104-
// /// includes proof-of-fee auction and collecting payment
105-
// /// includes drawing from infrastructure escrow into transaction fee account
106-
// public(friend) fun end_epoch_process_incoming() {
107-
108-
// }
109-
11072
//////// GENESIS ////////
11173
/// For 0L genesis, initialize and add the validators
11274
/// both root and validator need to sign. This is only possible at genesis.
@@ -152,12 +114,6 @@ module diem_framework::validator_universe {
152114
add(validator);
153115
}
154116

155-
// #[test_only]
156-
// /// test helper for maybe_jail
157-
// public fun test_maybe_jail(root: &signer, validator: address): bool {
158-
// maybe_jail_impl(root, validator)
159-
// }
160-
161117
#[test_only]
162118
public fun test_helper_add_self_onboard(vm: &signer, addr:address) acquires ValidatorUniverse {
163119
assert!(testnet::is_testnet(), 220101014014);
@@ -178,6 +134,4 @@ module diem_framework::validator_universe {
178134
vector::remove<address>(&mut state.validators, index);
179135
}
180136
}
181-
182-
183137
}

0 commit comments

Comments
 (0)