From 68fb56b01fc6d9899d53d86798a64ba9ee0ea56c Mon Sep 17 00:00:00 2001 From: Mark Tsyrulnyk Date: Wed, 8 Jan 2020 18:00:51 +0200 Subject: [PATCH] Feature adjustable account price (#119) * wip * PoC * review * review * add tests Co-authored-by: Mark Co-authored-by: Vlad Pavlichek --- .../include/rem.system/rem.system.hpp | 8 +- .../rem.system/src/delegate_bandwidth.cpp | 12 +- unittests/rem_account_price_test.cpp | 152 ++++++++++++++++++ 3 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 unittests/rem_account_price_test.cpp diff --git a/contracts/contracts/rem.system/include/rem.system/rem.system.hpp b/contracts/contracts/rem.system/include/rem.system/rem.system.hpp index e462034c9a5..580046ece9f 100644 --- a/contracts/contracts/rem.system/include/rem.system/rem.system.hpp +++ b/contracts/contracts/rem.system/include/rem.system/rem.system.hpp @@ -66,7 +66,6 @@ namespace eosiosystem { static constexpr uint32_t blocks_per_day = 2 * seconds_per_day; // half seconds per day static constexpr int64_t min_activated_stake = 150'000'000'0000; - static constexpr int64_t ram_gift_bytes = 1400; static constexpr int64_t min_pervote_daily_pay = 100'0000; static constexpr uint32_t refund_delay_sec = 3 * seconds_per_day; @@ -76,6 +75,10 @@ namespace eosiosystem { static constexpr int64_t default_inflation_pay_factor = 50000; // producers pay share = 10000 / 50000 = 20% of the inflation static constexpr int64_t default_votepay_factor = 40000; // per-block pay share = 10000 / 40000 = 25% of the producer pay + // 3742 bytes - is size of the new user account for current version + static constexpr int64_t min_account_ram = 3800; + + /** * * @defgroup eosiosystem rem.system @@ -1527,6 +1530,9 @@ namespace eosiosystem { // to keep Guardian status, account should reassert its vote every eosio_global_rem_state::reassertion_period bool vote_is_reasserted( eosio::time_point last_reassertion_time ) const; + // calculates amount of free bytes for current stake + int64_t ram_gift_bytes( int64_t stake ) const; + //defined in rotation.cpp std::vector get_rotated_schedule(); diff --git a/contracts/contracts/rem.system/src/delegate_bandwidth.cpp b/contracts/contracts/rem.system/src/delegate_bandwidth.cpp index a3ebd4d6073..6a1f8dd0678 100644 --- a/contracts/contracts/rem.system/src/delegate_bandwidth.cpp +++ b/contracts/contracts/rem.system/src/delegate_bandwidth.cpp @@ -142,9 +142,10 @@ namespace eosiosystem { int64_t cpu = 0; get_resource_limits( receiver, ram_bytes, net, cpu ); - const auto system_token_max_supply = eosio::token::get_max_supply(token_account, system_contract::get_core_symbol().code() ); + const auto system_token_max_supply = eosio::token::get_max_supply(token_account, system_contract::get_core_symbol().code() ); const double bytes_per_token = (double)_gstate.max_ram_size / (double)system_token_max_supply.amount; - int64_t bytes_for_stake = bytes_per_token * (tot_itr->own_stake_amount + tot_itr->free_stake_amount); + const int64_t staked = tot_itr->own_stake_amount + tot_itr->free_stake_amount; + const int64_t bytes_for_stake = bytes_per_token * staked + ram_gift_bytes( staked ); set_resource_limits( receiver, ram_managed ? ram_bytes : bytes_for_stake, net_managed ? net : tot_itr->net_weight.amount + tot_itr->free_stake_amount, @@ -319,4 +320,11 @@ namespace eosiosystem { refunds_tbl.erase( req ); } } + + int64_t system_contract::ram_gift_bytes( int64_t stake ) const { + const auto system_token_max_supply = eosio::token::get_max_supply(token_account, system_contract::get_core_symbol().code() ); + const double bytes_per_token = (double)_gstate.max_ram_size / (double)system_token_max_supply.amount; + + return std::max( int64_t{0}, min_account_ram - static_cast< int64_t >(stake * bytes_per_token) ); + } } //namespace eosiosystem diff --git a/unittests/rem_account_price_test.cpp b/unittests/rem_account_price_test.cpp new file mode 100644 index 00000000000..3e9a9318229 --- /dev/null +++ b/unittests/rem_account_price_test.cpp @@ -0,0 +1,152 @@ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" +#include +#pragma GCC diagnostic pop + +#include +#include +#include + +#include +#include + +#include + +#include "eosio_system_tester.hpp" + +BOOST_AUTO_TEST_SUITE(rem_account_price_tests) +BOOST_FIXTURE_TEST_CASE(rem_account_price_test, rem_system::eosio_system_tester) { + try { + cross_15_percent_threshold(); + produce_blocks(10); + + // everyone should be able to create account with given price + { + const int64_t account_price = 50'0000; + push_action( config::system_account_name, N(setminstake), mvo()("min_account_stake", account_price) ); + + const auto min_account_stake = get_global_state()["min_account_stake"].as(); + BOOST_REQUIRE_EQUAL(min_account_stake, account_price); + + create_account_with_resources( + N(testuser111), + config::system_account_name, + false, + asset{ account_price } + ); + + produce_blocks(1); + } + + // everyone should be able to create account with given price + { + const int64_t account_price = 10'0000; + push_action( config::system_account_name, N(setminstake), mvo()("min_account_stake", account_price) ); + + const auto min_account_stake = get_global_state()["min_account_stake"].as(); + BOOST_REQUIRE_EQUAL(min_account_stake, account_price); + + create_account_with_resources( + N(testuser222), + config::system_account_name, + false, + asset{ account_price } + ); + + produce_blocks(1); + } + + // everyone should be able to create account with given price + { + const int64_t account_price = 1'0000; + push_action( config::system_account_name, N(setminstake), mvo()("min_account_stake", account_price) ); + + const auto min_account_stake = get_global_state()["min_account_stake"].as(); + BOOST_REQUIRE_EQUAL(min_account_stake, account_price); + + create_account_with_resources( + N(testuser333), + config::system_account_name, + false, + asset{ account_price } + ); + + produce_blocks(1); + } + + // everyone should be able to create account with given price + { + const int64_t account_price = 1; + push_action( config::system_account_name, N(setminstake), mvo()("min_account_stake", account_price) ); + + const auto min_account_stake = get_global_state()["min_account_stake"].as(); + BOOST_REQUIRE_EQUAL(min_account_stake, account_price); + + create_account_with_resources( + N(testuser335), + config::system_account_name, + false, + asset{ account_price } + ); + + produce_blocks(1); + } + + // ram_gift_bytes should be equal 0 in this tests + // everyone should be able to create account with given price + { + const int64_t account_price = 100'0000; + push_action( config::system_account_name, N(setminstake), mvo()("min_account_stake", account_price) ); + + const auto min_account_stake = get_global_state()["min_account_stake"].as(); + BOOST_REQUIRE_EQUAL(min_account_stake, account_price); + + create_account_with_resources( + N(testuser444), + config::system_account_name, + false, + asset{ account_price } + ); + + produce_blocks(1); + } + + // everyone should be able to create account with given price + { + const int64_t account_price = 1000'0000; + push_action( config::system_account_name, N(setminstake), mvo()("min_account_stake", account_price) ); + + const auto min_account_stake = get_global_state()["min_account_stake"].as(); + BOOST_REQUIRE_EQUAL(min_account_stake, account_price); + + create_account_with_resources( + N(testuser555), + config::system_account_name, + false, + asset{ account_price } + ); + + produce_blocks(1); + } + + // everyone should be able to create account with given price + { + const int64_t account_price = 10000'0000; + push_action( config::system_account_name, N(setminstake), mvo()("min_account_stake", account_price) ); + + const auto min_account_stake = get_global_state()["min_account_stake"].as(); + BOOST_REQUIRE_EQUAL(min_account_stake, account_price); + + create_account_with_resources( + N(testuser511), + config::system_account_name, + false, + asset{ account_price } + ); + + produce_blocks(1); + } + } FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_SUITE_END()