diff --git a/contracts/eden/src/eden-micro-chain.cpp b/contracts/eden/src/eden-micro-chain.cpp index 3adc861bc..374a8ed6d 100644 --- a/contracts/eden/src/eden-micro-chain.cpp +++ b/contracts/eden/src/eden-micro-chain.cpp @@ -1662,6 +1662,94 @@ void resign(eosio::name account) remove_if_exists(db.members, account); } +void rename(eosio::name old_account, eosio::name new_account) +{ + auto update = [&](auto& acc) { + if (acc == old_account) + acc = new_account; + }; + auto update_vec = [&](auto& vec) { + std::replace(vec.begin(), vec.end(), old_account, new_account); + }; + + db.status.modify(get_status(), [&](auto& status) { update_vec(status.status.initialMembers); }); + + if (auto* obj = get_ptr(db.balances, old_account)) + db.balances.modify(*obj, [&](auto& obj) { obj.account = new_account; }); + + for (auto& obj : db.balance_history) + db.balance_history.modify(obj, [&](auto& obj) { + update(obj.account); + update(obj.other_account); + }); + + if (auto* obj = get_ptr(db.encryption_keys, old_account)) + db.encryption_keys.modify(*obj, [&](auto& obj) { obj.account = new_account; }); + + for (auto& obj : db.inductions) + db.inductions.modify(obj, [&](auto& obj) { + update(obj.induction.inviter.first); + for (auto& w : obj.induction.witnesses) + update(w.first); + }); + + for (auto& obj : db.members) + db.members.modify(obj, [&](auto& obj) { + update(obj.member.account); + update(obj.member.inviter); + update_vec(obj.member.inductionWitnesses); + }); + + for (auto& obj : db.election_groups) + db.election_groups.modify(obj, [&](auto& obj) { + // first_member is kept as is since it's only used by events + // which have already occurred, and it isn't exposed to the UI + update(obj.winner); + }); + + for (auto& obj : db.votes) + db.votes.modify(obj, [&](auto& obj) { + update(obj.voter); + update(obj.candidate); + }); + + { + auto& idx = db.distribution_funds.get(); + for (auto it = idx.lower_bound(distribution_fund_key{old_account, {}, 0}); + it != idx.end() && it->owner == old_account;) + { + auto next = it; + ++next; + db.distribution_funds.modify(*it, [&](auto& obj) { obj.owner = new_account; }); + it = next; + } + } + + { + auto& idx = db.nfts.get(); + for (auto it = idx.lower_bound(nft_account_key{old_account, {}, 0}); + it != idx.end() && it->member == old_account;) + { + auto next = it; + ++next; + db.nfts.modify(*it, [&](auto& obj) { obj.member = new_account; }); + it = next; + } + } + + { + auto& idx = db.nfts.get(); + for (auto it = idx.lower_bound(nft_account_key{old_account, {}, 0}); + it != idx.end() && it->owner == old_account;) + { + auto next = it; + ++next; + db.nfts.modify(*it, [&](auto& obj) { obj.owner = new_account; }); + it = next; + } + } +} // rename + void clear_participating() { auto& idx = db.members.template get(); @@ -2103,6 +2191,8 @@ bool dispatch(eosio::name action_name, const action_context& context, eosio::inp call(inductendors, context, s); else if (action_name == "resign"_n) call(resign, context, s); + else if (action_name == "rename"_n) + call(rename, context, s); else if (action_name == "electopt"_n) call(electopt, context, s); else if (action_name == "electvote"_n) diff --git a/contracts/eden/tests/test-eden.cpp b/contracts/eden/tests/test-eden.cpp index 218454023..21936440a 100644 --- a/contracts/eden/tests/test-eden.cpp +++ b/contracts/eden/tests/test-eden.cpp @@ -1292,6 +1292,8 @@ TEST_CASE("election-events") t.run_election(true, 10000, true); t.skip_to("2021-02-01T15:30:00.000"); t.alice.act(250); + test_chain::user_context{t.chain, {{"eden.gm"_n, "board.major"_n}, {"ahab"_n, "active"_n}}} + .act("alice"_n, "ahab"_n); t.write_dfuse_history("dfuse-test-election.json"); CompareFile{"test-election"}.write_events(t.chain).compare(); }