Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rename action which requires authorization by 2/3+1 of the chief … #668

Merged
merged 5 commits into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contracts/eden/include/accounts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ namespace eden
std::optional<account> get_account(eosio::name owner);
void add_balance(eosio::name owner, const eosio::asset& quantity, bool enforce_minimum);
void sub_balance(eosio::name owner, const eosio::asset& quantity);
void on_rename(eosio::name old_account, eosio::name new_account);

// this method is used only for administrative purposes,
// it should never be used outside genesis or test environments
Expand Down
1 change: 1 addition & 0 deletions contracts/eden/include/bylaws.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace eden
// - Approvals on the pending bylaws are cleared
void new_board();
void on_resign(eosio::name member);
void on_rename(eosio::name member, eosio::name new_account);

void clear_all();
};
Expand Down
1 change: 1 addition & 0 deletions contracts/eden/include/distributions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ namespace eden
eosio::asset amount);
uint32_t on_election_kick(eosio::name member, uint32_t max_steps);
void on_resign(const member& member);
void on_rename(eosio::name old_account, eosio::name new_account);
void clear_all();
};
} // namespace eden
3 changes: 3 additions & 0 deletions contracts/eden/include/eden.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ namespace eden

void resign(eosio::name member);

void rename(eosio::name member, eosio::name newaccount);

void setencpubkey(eosio::name member, const eosio::public_key& key);

void electsettime(eosio::time_point_sec election_time);
Expand Down Expand Up @@ -288,6 +290,7 @@ namespace eden
eden_verb(inductcancel, 9, account, id, ricardian_contract(inductcancel_ricardian)),
action(inducted, inductee, ricardian_contract(inducted_ricardian)),
action(resign, account),
action(rename, old_account, new_account),
action(gc, limit, ricardian_contract(gc_ricardian)),
action(migrate, limit),
action(unmigrate),
Expand Down
2 changes: 1 addition & 1 deletion contracts/eden/include/eden_dispatcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ namespace eden
#define EDEN_GET_SESSION_ACTION_INTERNAL_1(r, type, member) \
f(EDEN_EXTRACT_SESSION_ACTION_INDEX(member), \
BOOST_PP_STRINGIZE(EOSIO_EXTRACT_ACTION_NAME(member)), \
&type::EOSIO_EXTRACT_ACTION_NAME(member));
&type::EOSIO_EXTRACT_ACTION_NAME(member));
#define EDEN_GET_SESSION_ACTION_INTERNAL(r, type, member) \
BOOST_PP_IIF(EDEN_MATCH_SESSION_ACTION(member), EDEN_GET_SESSION_ACTION_INTERNAL_1, \
EOSIO_EMPTY) \
Expand Down
4 changes: 3 additions & 1 deletion contracts/eden/include/elections.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ namespace eden
uint32_t randomize_voters(current_election_state_init_voters_v0& state, uint32_t max_steps);
std::vector<eosio::name> extract_board();
void finish_election(std::vector<eosio::name>&& board, eosio::name winner);
void set_board_permission(const std::vector<eosio::name>& board);
bool remove_from_board(eosio::name member);

public:
Expand All @@ -281,6 +280,8 @@ namespace eden
globals(contract)
{
}
void set_board_permission(const std::vector<eosio::name>& board);
void link_board_permission();
std::optional<eosio::block_timestamp> get_next_election_time();
std::uint8_t election_schedule_version();
void set_time(uint8_t day, const std::string& time);
Expand All @@ -292,6 +293,7 @@ namespace eden
uint32_t prepare_election(uint32_t max_steps);
uint32_t finish_round(uint32_t max_steps);
void on_resign(eosio::name member);
void on_rename(eosio::name old_account, eosio::name new_account);
// \pre voter and candidate are members of the same group
void vote(uint8_t round, eosio::name voter, eosio::name candidate);
boost::logic::tribool can_upload_video(uint8_t round, eosio::name voter);
Expand Down
2 changes: 2 additions & 0 deletions contracts/eden/include/inductions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ namespace eden
// Should only be used during genesis
void endorse_all(const induction& induction);

void on_rename(eosio::name old_account, eosio::name new_account);

// this method is used only for administrative purposes,
// it should never be used outside genesis or test environments
void clear_all();
Expand Down
1 change: 1 addition & 0 deletions contracts/eden/include/members.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ namespace eden
member_table_type::const_iterator erase(member_table_type::const_iterator iter);
void remove(eosio::name account);
void remove_if_pending(eosio::name account);
void rename(eosio::name old_account, eosio::name new_account);
bool is_new_member(eosio::name account) const;
void check_active_member(eosio::name account);
void check_pending_member(eosio::name account);
Expand Down
23 changes: 23 additions & 0 deletions contracts/eden/include/migrations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ namespace eden
eosio::name contract;
migration_singleton migration_sing;

template <int N>
static constexpr bool is_no_migration(const no_migration<N>&)
{
return true;
}
template <typename T>
static constexpr bool is_no_migration(const T&)
{
return false;
}

public:
migrations(eosio::name contract) : contract(contract), migration_sing(contract, default_scope)
{
Expand Down Expand Up @@ -65,5 +76,17 @@ namespace eden
return migration_sing.exists() &&
migration_sing.get().index() > boost::mp11::mp_find<migration_variant, T>::value;
}
void on_rename(eosio::name /*old_account*/, eosio::name /*new_account*/)
{
if (migration_sing.exists())
{
std::visit(
[](const auto& var) {
eosio::check(is_no_migration(var),
"Cannot rename account while a migration is in progress");
},
migration_sing.get());
}
}
};
} // namespace eden
13 changes: 13 additions & 0 deletions contracts/eden/src/accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,19 @@ namespace eden
account_tb.modify(record, contract, [&](auto& r) { r.balance() -= quantity; });
}

void accounts::on_rename(eosio::name old_account, eosio::name new_account)
{
auto record = account_tb.find(old_account.value);
if (record != account_tb.end())
{
account_tb.emplace(contract, [&](auto& new_record) {
new_record = *record;
new_record.owner() = new_account;
});
account_tb.erase(record);
}
}

void accounts::clear_all() { clear_table(account_tb); }

void add_to_pool(eosio::name contract, eosio::name pool, eosio::asset amount)
Expand Down
2 changes: 2 additions & 0 deletions contracts/eden/src/actions/genesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ namespace eden

elections elections{get_self()};
elections.set_time(election_day, election_time);
elections.set_board_permission({});
elections.link_board_permission();

auto inviter = get_self();
auto total_endorsements = initial_members.size() - 1;
Expand Down
21 changes: 21 additions & 0 deletions contracts/eden/src/actions/induct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,25 @@ namespace eden
bylaws.on_resign(account);
}

void eden::rename(eosio::name account, eosio::name new_account)
{
eosio::require_auth(new_account);
eosio::require_auth(eosio::permission_level{get_self(), "board.major"_n});
accounts accounts{get_self()};
accounts.on_rename(account, new_account);
members members{get_self()};
members.check_active_member(account);
distributions dist{get_self()};
dist.on_rename(account, new_account);
elections elections{get_self()};
elections.on_rename(account, new_account);
inductions inductions{get_self()};
inductions.on_rename(account, new_account);
members.rename(account, new_account);
bylaws bylaws{get_self()};
bylaws.on_rename(account, new_account);
migrations migrations{get_self()};
migrations.on_rename(account, new_account);
}

} // namespace eden
15 changes: 15 additions & 0 deletions contracts/eden/src/bylaws.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,20 @@ namespace eden
}
}

void bylaws::on_rename(eosio::name old_account, eosio::name new_account)
{
for (auto key : {proposed, pending})
{
auto pos = bylaws_tb.find(key.value);
if (pos != bylaws_tb.end())
{
bylaws_tb.modify(pos, contract, [&](auto& row) {
std::replace(row.approvals().begin(), row.approvals().end(), old_account,
new_account);
});
}
}
}

void bylaws::clear_all() { clear_table(bylaws_tb); }
} // namespace eden
24 changes: 24 additions & 0 deletions contracts/eden/src/distributions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,30 @@ namespace eden
}
}

void distributions::on_rename(eosio::name old_account, eosio::name new_account)
{
{
distribution_table_type distribution_tb{contract, default_scope};
auto iter = distribution_tb.begin();
eosio::check(iter == distribution_tb.end() ||
!std::holds_alternative<current_distribution>(iter->value),
"Cannot rename member while a distribution is in progress");
}

accounts owned_accounts{contract, "owned"_n};
setup_distribution(contract, owned_accounts);
auto member_idx = distribution_account_tb.get_index<"byowner"_n>();
for (auto iter = member_idx.lower_bound(uint128_t(old_account.value) << 64),
end = member_idx.end();
iter != end && iter->owner() == old_account;)
{
auto next = iter;
++next;
member_idx.modify(iter, contract, [&](auto& acct) { acct.owner() = new_account; });
iter = next;
}
}

void distributions::clear_all()
{
clear_table(distribution_account_tb);
Expand Down
33 changes: 33 additions & 0 deletions contracts/eden/src/elections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,15 @@ namespace eden
.send();
}

void elections::link_board_permission()
{
eosio::action{{contract, "active"_n},
"eosio"_n,
"linkauth"_n,
std::tuple(contract, contract, "rename"_n, "board.major"_n)}
.send();
}

void elections::finish_election(std::vector<eosio::name>&& board, eosio::name winner)
{
election_state_singleton results(contract, default_scope);
Expand Down Expand Up @@ -1020,6 +1029,30 @@ namespace eden
}
}

void elections::on_rename(eosio::name old_account, eosio::name new_account)
{
eosio::check(!is_election_running(state_sing), "Cannot rename account during an election");

// Update the board
election_state_singleton global_state{contract, default_scope};
if (!global_state.exists())
{
return;
}
auto value = std::get<election_state_v0>(global_state.get());
auto pos = std::find(value.board.begin(), value.board.end(), old_account);
if (pos != value.board.end())
{
*pos = new_account;
global_state.set(value, contract);
set_board_permission(value.board);
}
if (old_account == value.lead_representative)
{
value.lead_representative = new_account;
tbfleming marked this conversation as resolved.
Show resolved Hide resolved
}
}

boost::logic::tribool elections::can_upload_video(uint8_t round, eosio::name voter)
{
auto iter = vote_tb.find(voter.value);
Expand Down
21 changes: 21 additions & 0 deletions contracts/eden/src/inductions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,27 @@ namespace eden
return pos != invitee_idx.end() && pos->invitee() == invitee;
}

void inductions::on_rename(eosio::name old_account, eosio::name new_account)
tbfleming marked this conversation as resolved.
Show resolved Hide resolved
{
eosio::check(!has_induction(old_account), "Cannot rename: gc required");
// change all endorsements
auto endorser_idx = endorsement_tb.get_index<"byendorser"_n>();
for (auto iter = endorser_idx.lower_bound(uint128_t{old_account.value} << 64),
end = endorser_idx.end();
iter != end && iter->endorser() == old_account;)
{
auto next = iter;
++next;
endorser_idx.modify(iter, contract,
[&](auto& endorsement) { endorsement.endorser() = new_account; });
iter = next;
}
auto inviter_idx = induction_tb.get_index<"byinviter"_n>();
auto iter = inviter_idx.lower_bound(combine_names(old_account, ""_n));
eosio::check(iter == inviter_idx.end() || iter->inviter() != old_account,
"Cannot rename an account that is the inviter of a pending invitation");
}

void inductions::clear_all()
{
clear_table(induction_tb);
Expand Down
29 changes: 29 additions & 0 deletions contracts/eden/src/members.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,35 @@ namespace eden
}
}

void members::rename(eosio::name account, eosio::name new_account)
{
auto iter = member_tb.find(account.value);
std::uint8_t rank = iter->election_rank();
tbfleming marked this conversation as resolved.
Show resolved Hide resolved
eosio::check(iter != member_tb.end(), "Unknown member");
remove_sessions(contract, account);
// Update the members table entry
member_tb.emplace(contract, [&](auto& new_member) {
new_member = *iter;
new_member.account() = new_account;
});
member_tb.erase(iter);
// update delegate records
auto delegate_idx = member_tb.get_index<"byrep"_n>();
for (uint8_t i = 0; i <= rank; ++i)
{
for (auto iter = delegate_idx.lower_bound((uint128_t{i} << 64) | account.value),
end = delegate_idx.end();
iter != end && iter->representative() == account;)
{
auto next = iter;
++next;
delegate_idx.modify(iter, contract,
[&](auto& member) { member.representative() = new_account; });
iter = next;
}
}
}

void members::set_nft(eosio::name account, int32_t nft_template_id)
{
check_pending_member(account);
Expand Down
30 changes: 30 additions & 0 deletions contracts/eden/tests/test-eden.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,32 @@ TEST_CASE("board resignation")
t.pip.act<actions::resign>("pip"_n);
}

TEST_CASE("renaming")
{
eden_tester t;
t.genesis();
auto distribution_time = t.next_election_time();
t.run_election();
t.alice.act<actions::distribute>(100);
t.alice.act<actions::fundtransfer>("alice"_n, distribution_time, 1, "alice"_n, s2a("0.0001 EOS"),
"");
test_chain::user_context{t.chain, {{"eden.gm"_n, "board.major"_n}, {"ahab"_n, "active"_n}}}
.act<actions::rename>("alice"_n, "ahab"_n);

expect(t.alice.trace<actions::withdraw>("alice"_n, s2a("0.0001 EOS")), "insufficient balance");
t.ahab.act<actions::withdraw>("ahab"_n, s2a("0.0001 EOS"));

t.chain.start_block();
expect(t.alice.trace<actions::fundtransfer>("alice"_n, distribution_time, 1, "alice"_n,
s2a("0.0001 EOS"), ""),
"member alice not found");
t.ahab.act<actions::fundtransfer>("ahab"_n, distribution_time, 1, "ahab"_n, s2a("0.0001 EOS"),
"");

CHECK(get_eden_membership("pip"_n).representative() == "ahab"_n);
CHECK(get_eden_membership("ahab"_n).representative() == "ahab"_n);
}

TEST_CASE("auction")
{
eden_tester t;
Expand Down Expand Up @@ -1176,6 +1202,10 @@ TEST_CASE("clearall")
eden_tester t;
t.genesis();
t.eden_gm.act<actions::clearall>();
t.chain.transact({{{"eden.gm"_n, "active"_n},
"eosio"_n,
"unlinkauth"_n,
std::tuple("eden.gm"_n, "eden.gm"_n, "rename"_n)}});
t.chain.start_block();
t.genesis();
}
Expand Down