Skip to content

Commit

Permalink
creating an agent explicitly #75
Browse files Browse the repository at this point in the history
  • Loading branch information
kaynarov committed Apr 26, 2019
1 parent 476147f commit fd9b76b
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 42 deletions.
12 changes: 12 additions & 0 deletions cyber.stake/abi/cyber.stake.abi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
{ "type": "uint16", "name": "payout_steps_num" },
{ "type": "int64", "name": "min_own_staked_for_election" }
]
},{
"name": "open_args",
"base": "",
"fields": [
{ "type": "name", "name": "owner" },
{ "type": "symbol_code", "name": "token_code" },
{ "type": "name?", "name": "ram_payer" }
]
},{
"name": "enable_args",
"base": "",
Expand Down Expand Up @@ -108,6 +116,10 @@
"name": "create",
"type": "create_args",
"ricardian_contract": ""
},{
"name": "open",
"type": "open_args",
"ricardian_contract": ""
},{
"name": "enable",
"type": "enable_args",
Expand Down
5 changes: 4 additions & 1 deletion cyber.stake/include/cyber.stake/cyber.stake.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ struct structures {
//return: share
int64_t delegate_traversal(symbol_code token_code, agents_idx_t& agents_idx, grants_idx_t& grants_idx, name agent_name, int64_t amount, bool refill = false);

agents_idx_t::const_iterator get_agent_itr(symbol_code token_code, agents_idx_t& agents_idx, name agent_name, int16_t proxy_level_for_emplaced = -1, agents* agents_table = nullptr, bool* emplaced = nullptr);
agents_idx_t::const_iterator get_agent_itr(symbol_code token_code, agents_idx_t& agents_idx, name agent_name);
void emplace_agent(name account, agents& agents_table, const structures::param& param, name ram_payer);
void add_proxy(symbol_code token_code, grants& grants_table, const structures::agent& grantor_as_agent, const structures::agent& agent,
int16_t pct, int64_t share, int16_t break_fee = -1, int64_t break_min_own_staked = -1);

Expand Down Expand Up @@ -212,6 +213,8 @@ struct structures {
int64_t min_own_staked_for_election);

[[eosio::action]] void enable(symbol token_symbol);

[[eosio::action]] void open(name owner, symbol_code token_code, std::optional<name> ram_payer);

[[eosio::action]] void delegate(name grantor_name, name agent_name, asset quantity);

Expand Down
75 changes: 38 additions & 37 deletions cyber.stake/src/cyber.stake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void stake::setgrntterms(name grantor_name, name agent_name, symbol_code token_c
eosio_assert(pct_sum <= config::_100percent, "too high pct value\n");
}
if (!agent_found && pct) {
auto grantor_as_agent = get_agent_itr(token_code, agents_idx, grantor_name, param.max_proxies.size(), &agents_table);
auto grantor_as_agent = get_agent_itr(token_code, agents_idx, grantor_name);
eosio_assert(proxies_num < param.max_proxies[grantor_as_agent->proxy_level - 1], "proxy cannot be added");
update_stake_proxied(token_code, agent_name);
auto agent = get_agent_itr(token_code, agents_idx, agent_name);
Expand All @@ -191,8 +191,11 @@ void stake::on_transfer(name from, name to, asset quantity, std::string memo) {

agents agents_table(table_owner, table_owner.value);
auto agents_idx = agents_table.get_index<"bykey"_n>();
auto agent = get_agent_itr(token_code, agents_idx, account, param.max_proxies.size(), &agents_table);

auto agent = agents_idx.find(std::make_tuple(token_code, account));
if (agent == agents_idx.end()) {
emplace_agent(account, agents_table, param, from);
agent = agents_idx.find(std::make_tuple(token_code, account));
}
update_stake_proxied(token_code, account);

grants grants_table(table_owner, table_owner.value);
Expand Down Expand Up @@ -371,11 +374,10 @@ void stake::setproxylvl(name account, symbol_code token_code, uint8_t level) {
eosio_assert(level <= param.max_proxies.size(), "level too high");
agents agents_table(table_owner, table_owner.value);
auto agents_idx = agents_table.get_index<"bykey"_n>();
bool emplaced = false;
auto agent = get_agent_itr(token_code, agents_idx, account, level, &agents_table, &emplaced);
auto agent = get_agent_itr(token_code, agents_idx, account);
eosio_assert(level || agent->min_own_staked >= param.min_own_staked_for_election,
"min_own_staked can't be less than min_own_staked_for_election for users with an ultimate level");
eosio_assert(emplaced || (level != agent->proxy_level), "proxy level has not been changed");
eosio_assert(level != agent->proxy_level, "proxy level has not been changed");
grants grants_table(table_owner, table_owner.value);
auto grants_idx = grants_table.get_index<"bykey"_n>();
uint8_t proxies_num = 0;
Expand All @@ -387,12 +389,10 @@ void stake::setproxylvl(name account, symbol_code token_code, uint8_t level) {
eosio_assert(level || !proxies_num, "can't set an ultimate level because the user has a proxy");
eosio_assert(!level || proxies_num <= param.max_proxies[level - 1], "can't set proxy level, user has too many proxies");

if(!emplaced) {
agents_idx.modify(agent, name(), [&](auto& a) {
a.proxy_level = level;
a.votes = level ? -1 : a.balance;
});
}
agents_idx.modify(agent, name(), [&](auto& a) {
a.proxy_level = level;
a.votes = level ? -1 : a.balance;
});
}

void stake::create(symbol token_symbol, std::vector<uint8_t> max_proxies,
Expand Down Expand Up @@ -444,33 +444,34 @@ void stake::enable(symbol token_symbol) {
});
}

stake::agents_idx_t::const_iterator stake::get_agent_itr(symbol_code token_code, stake::agents_idx_t& agents_idx, name agent_name, int16_t proxy_level_for_emplaced, agents* agents_table, bool* emplaced) {
auto key = std::make_tuple(token_code, agent_name);
auto agent = agents_idx.find(key);
void stake::open(name owner, symbol_code token_code, std::optional<name> ram_payer = std::nullopt) {

auto actual_ram_payer = ram_payer.value_or(owner);
require_auth(actual_ram_payer);

if (emplaced)
*emplaced = false;
params params_table(table_owner, table_owner.value);
const auto& param = params_table.get(token_code.raw(), "no staking for token");
agents agents_table(table_owner, table_owner.value);
auto agents_idx = agents_table.get_index<"bykey"_n>();
eosio_assert(agents_idx.find(std::make_tuple(token_code, owner)) == agents_idx.end(), "agent already exists");
emplace_agent(owner, agents_table, param, actual_ram_payer);
}

if(proxy_level_for_emplaced < 0) {
eosio_assert(agent != agents_idx.end(), ("agent " + agent_name.to_string() + " doesn't exist").c_str());
}
else if(agent == agents_idx.end()) {
stake::agents_idx_t::const_iterator stake::get_agent_itr(symbol_code token_code, stake::agents_idx_t& agents_idx, name agent_name) {
auto ret = agents_idx.find(std::make_tuple(token_code, agent_name));
eosio_assert(ret != agents_idx.end(), ("agent " + agent_name.to_string() + " doesn't exist").c_str());
return ret;
}

eosio_assert(static_cast<bool>(agents_table), "SYSTEM: agents_table can't be null");
(*agents_table).emplace(agent_name, [&](auto& a) { a = {
.id = agents_table->available_primary_key(),
.token_code = token_code,
.account = agent_name,
.proxy_level = static_cast<uint8_t>(proxy_level_for_emplaced),
.votes = proxy_level_for_emplaced ? -1 : 0,
.last_proxied_update = time_point_sec(::now())
};});

agent = agents_idx.find(key);
if (emplaced)
*emplaced = true;
}
return agent;
void stake::emplace_agent(name account, agents& agents_table, const structures::param& param, name ram_payer) {
agents_table.emplace(ram_payer, [&](auto& a) { a = {
.id = agents_table.available_primary_key(),
.token_code = param.token_symbol.code(),
.account = account,
.proxy_level = static_cast<uint8_t>(param.max_proxies.size()),
.votes = -1,
.last_proxied_update = time_point_sec(::now())
};});
}

void stake::updatefunds(name account, symbol_code token_code) {
Expand Down Expand Up @@ -525,7 +526,7 @@ void stake::reward(name account, asset quantity) {
} /// namespace cyber

DISPATCH_WITH_TRANSFER(cyber::stake, cyber::config::token_name, on_transfer,
(create)(enable)(delegate)(setgrntterms)(recall)(withdraw)(claim)(cancelwd)
(create)(enable)(open)(delegate)(setgrntterms)(recall)(withdraw)(claim)(cancelwd)
(setproxylvl)(setproxyfee)(setminstaked)(setkey)
(updatefunds)(reward)
)
3 changes: 2 additions & 1 deletion tests/cyber.govern_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ BOOST_FIXTURE_TEST_CASE(set_producers_test, cyber_govern_tester) try {
BOOST_CHECK_EQUAL(govern.get_active_elected_producers(), govern.make_producers_group(crowd_and_bob));

BOOST_CHECK_EQUAL(success(), token.issue(_issuer, _carol, asset(3, token._symbol), ""));
BOOST_CHECK_EQUAL(success(), token.transfer(_carol, stake_account_name, asset(1, token._symbol)));
BOOST_CHECK_EQUAL(success(), stake.setproxylvl(_carol, token._symbol.to_symbol_code(), 1));

BOOST_CHECK_EQUAL(success(), token.transfer(_carol, stake_account_name, asset(1, token._symbol)));
BOOST_CHECK_EQUAL(success(), stake.delegate(_carol, _bob, asset(1, token._symbol)));

govern.wait_schedule_activation();
Expand Down Expand Up @@ -317,6 +317,7 @@ BOOST_FIXTURE_TEST_CASE(set_producers_test, cyber_govern_tester) try {
BOOST_FIXTURE_TEST_CASE(no_key_test, cyber_govern_tester) try {
BOOST_TEST_MESSAGE("no_key_test");
deploy_sys_contracts();
BOOST_CHECK_EQUAL(success(), stake.open(_alice, token._symbol.to_symbol_code()));
BOOST_CHECK_EQUAL(success(), stake.setproxylvl(_alice, token._symbol.to_symbol_code(), 0));
stake.register_candidate(_bob, token._symbol.to_symbol_code());
govern.wait_schedule_activation();
Expand Down
14 changes: 12 additions & 2 deletions tests/cyber.stake_test_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ struct cyber_stake_api: base_contract_api {
);
}

action_result open(account_name owner, symbol_code token_code, account_name ram_payer = account_name(0)) {
return ram_payer ?
push(N(open), ram_payer, args()("owner", owner)("token_code", token_code)("ram_payer", ram_payer)) :
push(N(open), owner, args()("owner", owner)("token_code", token_code));
}

action_result enable(account_name issuer, symbol token_symbol) {
return push(N(enable), issuer, args()
("token_symbol", token_symbol)
Expand Down Expand Up @@ -132,8 +138,12 @@ struct cyber_stake_api: base_contract_api {
);
}

action_result register_candidate(account_name account, symbol_code token_code) {

action_result register_candidate(account_name account, symbol_code token_code, bool need_to_open = true) {
if (need_to_open) {
auto ret = open(account, token_code);
if(ret != base_tester::success())
return ret;
}
auto ret = setproxylvl(account, token_code, 0);
if(ret != base_tester::success())
return ret;
Expand Down
34 changes: 33 additions & 1 deletion tests/cyber.stake_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class cyber_stake_tester : public golos_tester {
BOOST_CHECK_EQUAL(success(), token.issue(_issuer, acc, token.from_amount(stake_amount), ""));
BOOST_CHECK_EQUAL(success(), token.transfer(acc, _code, token.from_amount(stake_amount)));
}
else {
BOOST_CHECK_EQUAL(success(), stake.open(acc, token._symbol.to_symbol_code()));
}
if (level != max_proxy_level || !stake_amount) {
BOOST_CHECK_EQUAL(success(), stake.setproxylvl(acc, token._symbol.to_symbol_code(), level));
}
Expand Down Expand Up @@ -112,6 +115,9 @@ class cyber_stake_tester : public golos_tester {
static string no_agent() {
return "agent doesn't exist";
}
const string agent_exists() {
return amsg(std::string("agent already exists"));
}
const string no_funds() {
return amsg(std::string("insufficient funds"));
}
Expand Down Expand Up @@ -187,6 +193,9 @@ BOOST_FIXTURE_TEST_CASE(basic_tests, cyber_stake_tester) try {
BOOST_CHECK_EQUAL(success(), token.issue(_issuer, _carol, stake_c, ""));

BOOST_CHECK_EQUAL(success(), stake.create(_issuer, token._symbol, max_proxies, frame_length, 7 * 24 * 60 * 60, 52));
BOOST_CHECK_EQUAL(success(), stake.open(_alice, token._symbol.to_symbol_code()));
BOOST_CHECK_EQUAL(success(), stake.open(_bob, token._symbol.to_symbol_code()));
BOOST_CHECK_EQUAL(success(), stake.open(_carol, token._symbol.to_symbol_code()));

BOOST_TEST_MESSAGE("--- alice stakes " << stake_a);
BOOST_CHECK_EQUAL(success(), token.transfer(_alice, _code, stake_a));
Expand Down Expand Up @@ -275,6 +284,9 @@ BOOST_FIXTURE_TEST_CASE(increase_proxy_level_test, cyber_stake_tester) try {
asset staked(10000000, token._symbol);
BOOST_CHECK_EQUAL(success(), token.create(_issuer, asset(1000000000, token._symbol)));
BOOST_CHECK_EQUAL(success(), stake.create(_issuer, token._symbol, max_proxies, frame_length, 7 * 24 * 60 * 60, 52));
BOOST_CHECK_EQUAL(success(), stake.open(_alice, token._symbol.to_symbol_code()));
BOOST_CHECK_EQUAL(success(), stake.open(_bob, token._symbol.to_symbol_code()));
BOOST_CHECK_EQUAL(success(), stake.open(_carol, token._symbol.to_symbol_code()));

BOOST_CHECK_EQUAL(success(), token.issue(_issuer, _carol, staked, ""));
BOOST_CHECK_EQUAL(success(), token.issue(_issuer, _alice, staked, ""));
Expand Down Expand Up @@ -325,6 +337,23 @@ BOOST_FIXTURE_TEST_CASE(increase_proxy_level_test, cyber_stake_tester) try {

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(open_test, cyber_stake_tester) try {
asset stake_u(100, token._symbol);
BOOST_CHECK_EQUAL(success(), token.create(_issuer, asset(10000000000, token._symbol)));
BOOST_CHECK_EQUAL(success(), token.issue(_issuer, _alice, stake_u , ""));
BOOST_CHECK_EQUAL(success(), stake.create(_issuer, token._symbol, {1}, 1, 7 * 24 * 60 * 60, 52));
BOOST_CHECK_EQUAL(success(), token.transfer(_alice, _code, stake_u));
BOOST_CHECK_EQUAL(err.agent_exists(), stake.open(_alice, token._symbol.to_symbol_code()));
BOOST_CHECK_EQUAL(success(), stake.open(_bob, token._symbol.to_symbol_code()));
BOOST_CHECK_EQUAL(success(), stake.enable(_issuer, token._symbol));
BOOST_CHECK(err.is_costs_too_much_mssg(stake.open(_carol, token._symbol.to_symbol_code())));
BOOST_CHECK_EQUAL(err.no_agent(), stake.delegate(_alice, _carol, stake_u));
BOOST_CHECK_EQUAL(success(), stake.open(_carol, token._symbol.to_symbol_code(), _alice));
produce_block();
BOOST_CHECK_EQUAL(err.agent_exists(), stake.open(_carol, token._symbol.to_symbol_code(), _alice));
produce_block();
} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(bw_tests, cyber_stake_tester) try {
BOOST_TEST_MESSAGE("Basic bw tests");

Expand Down Expand Up @@ -967,7 +996,10 @@ BOOST_FIXTURE_TEST_CASE(recursive_update_test, cyber_stake_tester) try {
cur_level_accs.emplace_back(user);
create_accounts({user});
BOOST_CHECK_EQUAL(success(), token.issue(_issuer, user, staked, ""));
BOOST_CHECK_EQUAL(success(), stake.setproxylvl(user, token._symbol.to_symbol_code(), level));
BOOST_CHECK_EQUAL(success(), stake.open(user, token._symbol.to_symbol_code()));
if (level != max_proxies.size()) {
BOOST_CHECK_EQUAL(success(), stake.setproxylvl(user, token._symbol.to_symbol_code(), level));
}
for (auto proxy : prev_level_accs) {
int16_t pct = (1.0 / prev_level_accs.size()) * cfg::_100percent;
BOOST_TEST_MESSAGE("--- setgrntterms pct: " << pct << " " << user << " -> " << proxy);
Expand Down

0 comments on commit fd9b76b

Please sign in to comment.