diff --git a/libraries/api/chain_api_properties.cpp b/libraries/api/chain_api_properties.cpp index 9aa306d4fd..92295a6e1a 100644 --- a/libraries/api/chain_api_properties.cpp +++ b/libraries/api/chain_api_properties.cpp @@ -10,11 +10,11 @@ namespace golos { namespace api { sbd_interest_rate(src.sbd_interest_rate) { if (db.has_hardfork(STEEMIT_HARDFORK_0_18__673)) { - create_account_with_golos_modifier = src.create_account_with_golos_modifier; - create_account_delegation_ratio = src.create_account_delegation_ratio; + create_account_min_golos_fee = src.create_account_min_golos_fee; + create_account_min_delegation = src.create_account_min_delegation; create_account_delegation_time = src.create_account_delegation_time; - min_delegation_multiplier = src.min_delegation_multiplier; + min_delegation = src.min_delegation; } } -} } // golos::api \ No newline at end of file +} } // golos::api diff --git a/libraries/api/include/golos/api/chain_api_properties.hpp b/libraries/api/include/golos/api/chain_api_properties.hpp index 9a3e761f8b..7f60db0ef2 100644 --- a/libraries/api/include/golos/api/chain_api_properties.hpp +++ b/libraries/api/include/golos/api/chain_api_properties.hpp @@ -16,16 +16,16 @@ namespace golos { namespace api { uint32_t maximum_block_size; uint16_t sbd_interest_rate; - fc::optional create_account_with_golos_modifier; - fc::optional create_account_delegation_ratio; - fc::optional create_account_delegation_time; - fc::optional min_delegation_multiplier; + fc::optional create_account_min_golos_fee; + fc::optional create_account_min_delegation; + fc::optional create_account_delegation_time; + fc::optional min_delegation; }; } } // golos::api FC_REFLECT( (golos::api::chain_api_properties), - (account_creation_fee)(maximum_block_size)(maximum_block_size) - (create_account_with_golos_modifier)(create_account_delegation_ratio) - (create_account_delegation_time)(min_delegation_multiplier)) \ No newline at end of file + (account_creation_fee)(maximum_block_size)(sbd_interest_rate) + (create_account_min_golos_fee)(create_account_min_delegation) + (create_account_delegation_time)(min_delegation)) diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 2b7301e576..eb532e8f74 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -1671,10 +1671,10 @@ namespace golos { namespace chain { calc_median(&chain_properties_17::account_creation_fee); calc_median(&chain_properties_17::maximum_block_size); calc_median(&chain_properties_17::sbd_interest_rate); - calc_median(&chain_properties_18::create_account_with_golos_modifier); - calc_median(&chain_properties_18::create_account_delegation_ratio); + calc_median(&chain_properties_18::create_account_min_golos_fee); + calc_median(&chain_properties_18::create_account_min_delegation); calc_median(&chain_properties_18::create_account_delegation_time); - calc_median(&chain_properties_18::min_delegation_multiplier); + calc_median(&chain_properties_18::min_delegation); modify(wso, [&](witness_schedule_object &_wso) { _wso.median_props = median_props; diff --git a/libraries/chain/steem_evaluator.cpp b/libraries/chain/steem_evaluator.cpp index f8d5faf242..2016d98eda 100644 --- a/libraries/chain/steem_evaluator.cpp +++ b/libraries/chain/steem_evaluator.cpp @@ -108,20 +108,14 @@ namespace golos { namespace chain { } void account_create_evaluator::do_apply(const account_create_operation &o) { - database &_db = db(); - const auto &creator = _db.get_account(o.creator); - - const auto &props = _db.get_dynamic_global_properties(); - const auto& median_props = _db.get_witness_schedule_object().median_props; + const auto& creator = _db.get_account(o.creator); - FC_ASSERT(creator.balance >= - o.fee, "Insufficient balance to create account.", ("creator.balance", creator.balance)("required", o.fee)); + FC_ASSERT(creator.balance >= o.fee, + "Insufficient balance to create account.", ("creator.balance", creator.balance)("required", o.fee)); if (_db.has_hardfork(STEEMIT_HARDFORK_0_1)) { - auto min_fee = _db.get_witness_schedule_object().median_props.account_creation_fee; - if (_db.has_hardfork(STEEMIT_HARDFORK_0_18__535)) { - min_fee *= median_props.create_account_with_golos_modifier; - } + const auto& median_props = _db.get_witness_schedule_object().median_props; + auto min_fee = median_props.account_creation_fee; FC_ASSERT(o.fee >= min_fee, "Insufficient Fee: ${f} required, ${p} provided.", ("f", min_fee)("p", o.fee)); } @@ -145,6 +139,7 @@ namespace golos { namespace chain { c.balance -= o.fee; }); + const auto& props = _db.get_dynamic_global_properties(); const auto& new_account = _db.create([&](account_object& acc) { acc.name = o.new_account_name; acc.memo_key = o.memo_key; @@ -187,18 +182,20 @@ namespace golos { namespace chain { const auto& v_share_price = _db.get_dynamic_global_properties().get_vesting_share_price(); const auto& median_props = _db.get_witness_schedule_object().median_props; - auto target_delegation = - median_props.create_account_delegation_ratio * - median_props.create_account_with_golos_modifier * - median_props.account_creation_fee * v_share_price; - auto current_delegation = - median_props.create_account_delegation_ratio * o.fee * v_share_price + o.delegation; + const auto target = median_props.create_account_min_golos_fee + median_props.create_account_min_delegation; + auto target_delegation = target * v_share_price; + auto min_fee = median_props.account_creation_fee.amount.value; +#ifdef STEEMIT_BUILD_TESTNET + if (!min_fee) + min_fee = 1; +#endif + auto current_delegation = o.fee * target.amount.value / min_fee * v_share_price + o.delegation; FC_ASSERT(current_delegation >= target_delegation, "Inssufficient Delegation ${f} required, ${p} provided.", ("f", target_delegation)("p", current_delegation)("o.fee", o.fee) ("o.delegation", o.delegation)); - FC_ASSERT(o.fee >= median_props.account_creation_fee, - "Insufficient Fee: ${f} required, ${p} provided.", ("f", median_props.account_creation_fee)("p", o.fee)); + FC_ASSERT(o.fee >= median_props.create_account_min_golos_fee, + "Insufficient Fee: ${f} required, ${p} provided.", ("f", median_props.create_account_min_golos_fee)("p", o.fee)); for (auto& a : o.owner.account_auths) { _db.get_account(a.first); @@ -239,7 +236,7 @@ namespace golos { namespace chain { d.delegator = o.creator; d.delegatee = o.new_account_name; d.vesting_shares = o.delegation; - d.min_delegation_time = now + median_props.create_account_delegation_time; + d.min_delegation_time = now + fc::seconds(median_props.create_account_delegation_time); }); } if (o.fee.amount > 0) { @@ -2200,8 +2197,8 @@ namespace golos { namespace chain { const auto& median_props = _db.get_witness_schedule_object().median_props; const auto v_share_price = _db.get_dynamic_global_properties().get_vesting_share_price(); - auto min_delegation = median_props.account_creation_fee * median_props.min_delegation_multiplier * v_share_price; - auto min_update = median_props.account_creation_fee * v_share_price; + auto min_delegation = median_props.min_delegation * v_share_price; + auto min_update = median_props.create_account_min_golos_fee * v_share_price; auto now = _db.head_block_time(); auto delta = delegation ? diff --git a/libraries/protocol/include/golos/protocol/steem_operations.hpp b/libraries/protocol/include/golos/protocol/steem_operations.hpp index 4c7370d00f..483eb09698 100644 --- a/libraries/protocol/include/golos/protocol/steem_operations.hpp +++ b/libraries/protocol/include/golos/protocol/steem_operations.hpp @@ -443,6 +443,7 @@ namespace golos { namespace protocol { uint16_t sbd_interest_rate = STEEMIT_DEFAULT_SBD_INTEREST_RATE; void validate() const { + FC_ASSERT(account_creation_fee.symbol == STEEM_SYMBOL); FC_ASSERT(account_creation_fee.amount >= STEEMIT_MIN_ACCOUNT_CREATION_FEE); FC_ASSERT(maximum_block_size >= STEEMIT_MIN_BLOCK_SIZE_LIMIT); FC_ASSERT(sbd_interest_rate >= 0); @@ -462,39 +463,42 @@ namespace golos { namespace protocol { struct chain_properties_18: public chain_properties_17 { /** - * Modifier for delegated GP on account creation - * - * target_delegation = - * create_account_delegation_ratio * create_account_with_golos_modifier * account_creation_fee + * Minimum fee (in GOLOS) payed when create account with delegation */ - uint32_t create_account_with_golos_modifier = GOLOS_CREATE_ACCOUNT_WITH_GOLOS_MODIFIER; + asset create_account_min_golos_fee = + asset(STEEMIT_MIN_ACCOUNT_CREATION_FEE * GOLOS_CREATE_ACCOUNT_WITH_GOLOS_MODIFIER, STEEM_SYMBOL); /** - * Ratio for delegated GP on account creation + * Minimum GP delegation amount when create account with delegation * - * target_delegation = - * create_account_delegation_ratio * create_account_with_golos_modifier * account_creation_fee + * Note: this minimum is applied only when fee is minimal. If fee is greater, + * then actual delegation can be less (up to 0 if fee part is greater or equal than account_creation_fee) */ - uint32_t create_account_delegation_ratio = GOLOS_CREATE_ACCOUNT_DELEGATION_RATIO; + asset create_account_min_delegation = + asset(STEEMIT_MIN_ACCOUNT_CREATION_FEE * + GOLOS_CREATE_ACCOUNT_WITH_GOLOS_MODIFIER * GOLOS_CREATE_ACCOUNT_DELEGATION_RATIO, STEEM_SYMBOL); /** - * Minimum time of delegated GP on create account + * Minimum time of delegated GP on create account (in seconds) */ - fc::microseconds create_account_delegation_time = GOLOS_CREATE_ACCOUNT_DELEGATION_TIME; + uint32_t create_account_delegation_time = (GOLOS_CREATE_ACCOUNT_DELEGATION_TIME).to_seconds(); /** - * Multiplier of minimum delegated GP - * - * minimum delegated GP = delegation_multiplier * account_creation_fee + * Minimum delegated GP */ - uint32_t min_delegation_multiplier = GOLOS_MIN_DELEGATION_MULTIPLIER; + asset min_delegation = + asset(STEEMIT_MIN_ACCOUNT_CREATION_FEE * GOLOS_MIN_DELEGATION_MULTIPLIER, STEEM_SYMBOL); + void validate() const { chain_properties_17::validate(); - FC_ASSERT(min_delegation_multiplier > 0); - FC_ASSERT(create_account_delegation_time.count() > GOLOS_CREATE_ACCOUNT_DELEGATION_TIME.count() / 2); - FC_ASSERT(create_account_delegation_ratio > 0); - FC_ASSERT(create_account_with_golos_modifier > 0); + FC_ASSERT(create_account_min_golos_fee.amount > 0); + FC_ASSERT(create_account_min_golos_fee.symbol == STEEM_SYMBOL); + FC_ASSERT(create_account_min_delegation.amount > 0); + FC_ASSERT(create_account_min_delegation.symbol == STEEM_SYMBOL); + FC_ASSERT(min_delegation.amount > 0); + FC_ASSERT(min_delegation.symbol == STEEM_SYMBOL); + FC_ASSERT(create_account_delegation_time > (GOLOS_CREATE_ACCOUNT_DELEGATION_TIME).to_seconds() / 2); } chain_properties_18& operator=(const chain_properties_17& src) { @@ -1153,8 +1157,8 @@ FC_REFLECT( (account_creation_fee)(maximum_block_size)(sbd_interest_rate)) FC_REFLECT_DERIVED( (golos::protocol::chain_properties_18),((golos::protocol::chain_properties_17)), - (create_account_with_golos_modifier)(create_account_delegation_ratio) - (create_account_delegation_time)(min_delegation_multiplier)) + (create_account_min_golos_fee)(create_account_min_delegation) + (create_account_delegation_time)(min_delegation)) FC_REFLECT_TYPENAME((golos::protocol::versioned_chain_properties)) diff --git a/libraries/wallet/include/golos/wallet/wallet.hpp b/libraries/wallet/include/golos/wallet/wallet.hpp index cfb19e3c6f..91795ec17d 100644 --- a/libraries/wallet/include/golos/wallet/wallet.hpp +++ b/libraries/wallet/include/golos/wallet/wallet.hpp @@ -32,6 +32,17 @@ namespace golos { namespace wallet { vector key_approvals_to_remove; }; + struct optional_chain_props { + fc::optional account_creation_fee; + fc::optional maximum_block_size; + fc::optional sbd_interest_rate; + + fc::optional create_account_min_golos_fee; + fc::optional create_account_min_delegation; + fc::optional create_account_delegation_time; + fc::optional min_delegation; + }; + struct memo_data { static optional from_string( string str ) { @@ -678,7 +689,7 @@ namespace golos { namespace wallet { */ annotated_signed_transaction update_chain_properties( string witness_name, - const chain_properties& props, + const optional_chain_props& props, bool broadcast = false ); @@ -1203,10 +1214,15 @@ FC_API( golos::wallet::wallet_api, (get_outbox) ) -FC_REFLECT( (golos::wallet::memo_data), (from)(to)(nonce)(check)(encrypted) ) +FC_REFLECT((golos::wallet::memo_data), (from)(to)(nonce)(check)(encrypted)) FC_REFLECT( (golos::wallet::approval_delta), (active_approvals_to_add)(active_approvals_to_remove) (owner_approvals_to_add)(owner_approvals_to_remove) (posting_approvals_to_add)(posting_approvals_to_remove) - (key_approvals_to_add)(key_approvals_to_remove) ) + (key_approvals_to_add)(key_approvals_to_remove)) + +FC_REFLECT((golos::wallet::optional_chain_props), + (account_creation_fee)(maximum_block_size)(sbd_interest_rate) + (create_account_min_golos_fee)(create_account_min_delegation) + (create_account_delegation_time)(min_delegation)) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 50c8d46113..65efe2a299 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -290,10 +290,10 @@ namespace golos { namespace wallet { auto hf = _remote_database_api->get_hardfork_version(); if (hf >= hardfork_version(0, STEEMIT_HARDFORK_0_18)) { - result["create_account_with_golos_modifier"] = median_props.create_account_with_golos_modifier; - result["create_account_delegation_ratio"] = median_props.create_account_delegation_ratio; + result["create_account_min_golos_fee"] = median_props.create_account_min_golos_fee; + result["create_account_min_delegation"] = median_props.create_account_min_delegation; result["create_account_delegation_time"] = median_props.create_account_delegation_time; - result["min_delegation_multiplier"] = median_props.min_delegation_multiplier; + result["min_delegation"] = median_props.min_delegation; } return result; @@ -1834,9 +1834,6 @@ fc::ecc::private_key wallet_api::derive_private_key(const std::string& prefix_st auto prop = my->_remote_database_api->get_chain_properties(); auto hf = my->_remote_database_api->get_hardfork_version(); fee = prop.account_creation_fee; - if (hf >= hardfork_version(0, STEEMIT_HARDFORK_0_18)) { - fee *= prop.create_account_with_golos_modifier; - } } return create_account_with_keys( creator, new_account_name, json_meta, fee, @@ -1895,16 +1892,40 @@ fc::ecc::private_key wallet_api::derive_private_key(const std::string& prefix_st annotated_signed_transaction wallet_api::update_chain_properties( string witness_account_name, - const chain_properties& props, + const optional_chain_props& props, bool broadcast ) { FC_ASSERT(!is_locked()); signed_transaction tx; chain_properties_update_operation op; + chain_api_properties ap; + chain_properties p; + + // copy defaults in case of missing witness object + ap.account_creation_fee = p.account_creation_fee; + ap.maximum_block_size = p.maximum_block_size; + ap.sbd_interest_rate = p.sbd_interest_rate; + + auto wit = my->_remote_witness_api->get_witness_by_account(witness_account_name); + if (wit.valid()) { + FC_ASSERT(wit->owner == witness_account_name); + ap = wit->props; + } +#define SET_PROP(X) {p.X = !!props.X ? *(props.X) : ap.X;} + SET_PROP(account_creation_fee); + SET_PROP(maximum_block_size); + SET_PROP(sbd_interest_rate); +#undef SET_PROP +#define SET_PROP(X) {if (!!props.X) p.X = *(props.X); else if (!!ap.X) p.X = *(ap.X);} + SET_PROP(create_account_min_golos_fee); + SET_PROP(create_account_min_delegation); + SET_PROP(create_account_delegation_time); + SET_PROP(min_delegation); +#undef SET_PROP op.owner = witness_account_name; - op.props = props; + op.props = p; tx.operations.push_back(op); tx.validate(); diff --git a/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp b/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp index 3013de7de9..37ea1ad4e3 100644 --- a/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp +++ b/plugins/mongo_db/include/golos/plugins/mongo_db/mongo_db_state.hpp @@ -92,6 +92,8 @@ namespace mongo_db { bool format_comment(const std::string& auth, const std::string& perm); + void format_account(const std::string& name); + named_document create_document(const std::string& name, const std::string& key, const std::string& keyval); diff --git a/plugins/mongo_db/mongo_db_state.cpp b/plugins/mongo_db/mongo_db_state.cpp index 1b3ade6855..8c6a98cb4a 100644 --- a/plugins/mongo_db/mongo_db_state.cpp +++ b/plugins/mongo_db/mongo_db_state.cpp @@ -156,6 +156,95 @@ namespace mongo_db { } } + void state_writer::format_account(const std::string& name) { + try { + auto& account = db_.get_account(name); + auto oid = name; + auto oid_hash = hash_oid(oid); + + auto doc = create_document("account_object", "_id", oid_hash); + auto& body = doc.doc; + + body << "$set" << open_document; + + format_oid(body, oid); + + format_value(body, "name", account.name); + format_value(body, "memo_key", std::string(account.memo_key)); + format_value(body, "proxy", account.proxy); + + format_value(body, "last_account_update", account.last_account_update); + + format_value(body, "created", account.created); + format_value(body, "mined", account.mined); + format_value(body, "owner_challenged", account.owner_challenged); + format_value(body, "active_challenged", account.active_challenged); + format_value(body, "last_owner_proved", account.last_owner_proved); + format_value(body, "last_active_proved", account.last_active_proved); + format_value(body, "recovery_account", account.recovery_account); + format_value(body, "reset_account", account.reset_account); + format_value(body, "last_account_recovery", account.last_account_recovery); + format_value(body, "comment_count", account.comment_count); + format_value(body, "lifetime_vote_count", account.lifetime_vote_count); + format_value(body, "post_count", account.post_count); + + format_value(body, "can_vote", account.can_vote); + format_value(body, "voting_power", account.voting_power); + format_value(body, "last_vote_time", account.last_vote_time); + + format_value(body, "balance", account.balance); + format_value(body, "savings_balance", account.savings_balance); + + format_value(body, "sbd_balance", account.sbd_balance); + format_value(body, "sbd_seconds", account.sbd_seconds); + format_value(body, "sbd_seconds_last_update", account.sbd_seconds_last_update); + format_value(body, "sbd_last_interest_payment", account.sbd_last_interest_payment); + + format_value(body, "savings_sbd_balance", account.savings_sbd_balance); + format_value(body, "savings_sbd_seconds", account.savings_sbd_seconds); + format_value(body, "savings_sbd_seconds_last_update", account.savings_sbd_seconds_last_update); + format_value(body, "savings_sbd_last_interest_payment", account.savings_sbd_last_interest_payment); + + format_value(body, "savings_withdraw_requests", account.savings_withdraw_requests); + + format_value(body, "curation_rewards", account.curation_rewards); + format_value(body, "posting_rewards", account.posting_rewards); + + format_value(body, "vesting_shares", account.vesting_shares); + format_value(body, "delegated_vesting_shares", account.delegated_vesting_shares); + format_value(body, "received_vesting_shares", account.received_vesting_shares); + + format_value(body, "vesting_withdraw_rate", account.vesting_withdraw_rate); + format_value(body, "next_vesting_withdrawal", account.next_vesting_withdrawal); + format_value(body, "withdrawn", account.withdrawn); + format_value(body, "to_withdraw", account.to_withdraw); + format_value(body, "withdraw_routes", account.withdraw_routes); + + if (account.proxied_vsf_votes.size() != 0) { + array ben_array; + for (auto& b: account.proxied_vsf_votes) { + ben_array << b; + } + body << "proxied_vsf_votes" << ben_array; + } + + format_value(body, "witnesses_voted_for", account.witnesses_voted_for); + + format_value(body, "last_post", account.last_post); + + body << close_document; + + bmi_insert_or_replace(all_docs, std::move(doc)); + + } +// catch (fc::exception& ex) { +// ilog("MongoDB operations fc::exception during formatting comment. ${e}", ("e", ex.what())); +// } + catch (...) { + // ilog("Unknown exception during formatting comment."); + } + } + auto state_writer::operator()(const vote_operation& op) -> result_type { format_comment(op.author, op.permlink); @@ -266,6 +355,9 @@ namespace mongo_db { } } + format_account(op.from); + format_account(op.to); + all_docs.push_back(std::move(doc)); } @@ -294,19 +386,19 @@ namespace mongo_db { } auto state_writer::operator()(const account_create_operation& op) -> result_type { - + format_account(op.new_account_name); } auto state_writer::operator()(const account_update_operation& op) -> result_type { - + format_account(op.account); } auto state_writer::operator()(const account_create_with_delegation_operation& op) -> result_type { - + format_account(op.new_account_name); } auto state_writer::operator()(const account_metadata_operation& op) -> result_type { - + format_account(op.account); } auto state_writer::operator()(const witness_update_operation& op) -> result_type { diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index 3dc9b988ea..7dfce6c315 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -6287,7 +6287,6 @@ BOOST_FIXTURE_TEST_SUITE(operation_tests, clean_database_fixture) signed_transaction tx; ACTOR(alice); - // 150 * fee = (5 * GOLOS) + GP generate_blocks(1); fund("alice", ASSET_GOLOS(10)); vest("alice", ASSET_GOLOS(10000)); @@ -6346,9 +6345,9 @@ BOOST_FIXTURE_TEST_SUITE(operation_tests, clean_database_fixture) BOOST_TEST_MESSAGE("--- Test success using only GOLOS to reach target delegation"); const auto& gp = db->get_dynamic_global_properties(); - const auto fee_mult = GOLOS_CREATE_ACCOUNT_WITH_GOLOS_MODIFIER * GOLOS_CREATE_ACCOUNT_DELEGATION_RATIO; - auto min_fee = db->get_witness_schedule_object().median_props.account_creation_fee; - auto required_fee = fee_mult * min_fee; + const auto& mp = db->get_witness_schedule_object().median_props; + auto min_fee = mp.create_account_min_golos_fee; + auto required_fee = min_fee + mp.create_account_min_delegation; auto required_gests = required_fee * gp.get_vesting_share_price(); op.fee = required_fee; op.delegation = ASSET_GESTS(0);