diff --git a/contracts/bos.oracle/include/bos.oracle/bos.oracle.hpp b/contracts/bos.oracle/include/bos.oracle/bos.oracle.hpp index 20dd21702..0831bc96b 100755 --- a/contracts/bos.oracle/include/bos.oracle/bos.oracle.hpp +++ b/contracts/bos.oracle/include/bos.oracle/bos.oracle.hpp @@ -100,7 +100,7 @@ class [[eosio::contract("bos.oracle")]] bos_oracle : public eosio::contract { /** * @brief Clears data when oracle data's accessable time is timeout */ - [[eosio::action]] void cleardata(uint64_t service_id, uint32_t time_length); + [[eosio::action]] void cleardata(name provider, uint64_t service_id, uint32_t time_length); /** * @brief Sets config parameters diff --git a/contracts/bos.oracle/src/bos.provider.cpp b/contracts/bos.oracle/src/bos.provider.cpp index 0f35e3a76..2c2e5ffd1 100755 --- a/contracts/bos.oracle/src/bos.provider.cpp +++ b/contracts/bos.oracle/src/bos.provider.cpp @@ -240,16 +240,22 @@ void bos_oracle::update_stake_asset(uint64_t service_id, name account, asset amo check(provider_itr->total_stake_amount >= asset(std::abs(amount.amount), core_symbol()), "total stake amount should be greater than unstake asset amount"); check(provision_itr->amount >= asset(std::abs(amount.amount), core_symbol()), "service stake amount should be greater than unstake asset amount"); } + providertable.modify(provider_itr, same_payer, [&](auto& p) { p.total_stake_amount += amount; }); provisionstable.modify(provision_itr, same_payer, [&](auto& p) { p.amount += amount; - check(p.amount >= service_itr->base_stake_amount, "stake amount could not be less than the base_stake amount of the service"); + if (provision_status::provision_unreg != p.status && p.amount - p.freeze_amount >= service_itr->base_stake_amount) { p.status = provision_status::provision_reg; } + + if (provision_status::provision_reg == p.status) + { + check(p.amount >= service_itr->base_stake_amount, "stake amount could not be less than the base_stake amount of the service"); + } }); if (amount < asset(0, core_symbol())) { @@ -724,37 +730,50 @@ void bos_oracle::save_publish_data(uint64_t service_id, uint64_t cycle_number, u * @param service_id oracle service id * @param time_length time length */ -void bos_oracle::cleardata(uint64_t service_id, uint32_t time_length) { - require_auth(_self); +void bos_oracle::cleardata(name provider, uint64_t service_id, uint32_t time_length) { + require_auth(provider); + + data_services svctable(_self, _self.value); + auto service_itr = svctable.find(service_id); + check(service_itr != svctable.end(), "no service id in cleardata"); + + data_service_provisions provisionstable(_self, service_id); + + auto provision_itr = provisionstable.find(provider.value); + check(provision_itr != provisionstable.end(), "the account does not provide services"); + + if (provision_status::provision_unreg != provision_itr->status || provision_itr->amount - provision_itr->freeze_amount < service_itr->base_stake_amount) { + return; + } + clear_data(service_id, time_length); } void bos_oracle::clear_data(uint64_t service_id, uint32_t time_length) { auto begin_time = bos_oracle::current_time_point_sec().sec_since_epoch(); oracle_data oracledatatable(_self, service_id); - const uint8_t run_time = 10; // seconds - - for (auto itr = oracledatatable.begin(); itr != oracledatatable.end();) { + const uint64_t max_rows = 100; // rows + uint64_t row = 0; + for (auto itr = oracledatatable.begin(); itr != oracledatatable.end() && row < max_rows;++row) { print("\n traverse record_id=", itr->record_id, ",c=", bos_oracle::current_time_point_sec().sec_since_epoch(), ",t=", itr->timestamp); - if (bos_oracle::current_time_point_sec().sec_since_epoch() - itr->timestamp < time_length || bos_oracle::current_time_point_sec().sec_since_epoch() - begin_time > run_time) { + if (bos_oracle::current_time_point_sec().sec_since_epoch() - itr->timestamp < time_length) { break; } print("\n removed record_id=", itr->record_id); itr = oracledatatable.erase(itr); } - data_service_provision_logs logtable(_self, service_id); - for (auto itr = logtable.begin(); itr != logtable.end();) { + row=0; + for (auto itr = logtable.begin(); itr != logtable.end() && row < max_rows;++row) { print("\n traverse log_id=", itr->log_id, ",c=", bos_oracle::current_time_point_sec().sec_since_epoch(), ",t=", itr->update_time.sec_since_epoch()); - if (bos_oracle::current_time_point_sec().sec_since_epoch() - itr->update_time.sec_since_epoch() < time_length || bos_oracle::current_time_point_sec().sec_since_epoch() - begin_time > run_time) { + if (bos_oracle::current_time_point_sec().sec_since_epoch() - itr->update_time.sec_since_epoch() < time_length ) { break; } print("\n removed log_id=", itr->log_id); itr = logtable.erase(itr); } - } uint64_t bos_oracle::get_provider_count(uint64_t service_id) { diff --git a/tests/bos.oracle_tests.cpp b/tests/bos.oracle_tests.cpp index 61ae628b2..fd290607c 100644 --- a/tests/bos.oracle_tests.cpp +++ b/tests/bos.oracle_tests.cpp @@ -445,8 +445,10 @@ class bos_oracle_tester : public tester { return push_action(N(oracle.bos), N(starttimer), mvo()("service_id", service_id)("cycle_number", cycle_number)("request_id", request_id)); } - action_result cleardata(uint64_t service_id, uint32_t time_length) { return push_action(N(oracle.bos), N(cleardata), mvo()("service_id", service_id)("time_length", time_length)); } - + action_result cleardata(name provider,uint64_t service_id, uint32_t time_length) { return push_action(provider, N(cleardata), mvo()("provider", provider)("service_id", service_id)("time_length", time_length)); } + action_result unstakeasset(uint64_t service_id, name account, asset amount, string memo) { + return push_action(account, N(unstakeasset), mvo()("service_id", service_id)("account", account)("amount", amount)("memo", memo)); + } action_result addfeetypes(uint64_t service_id, std::vector fee_types, std::vector service_prices) { return push_action(N(oracle.bos), N(addfeetypes), mvo()("service_id", service_id)("fee_types", fee_types)("service_prices", service_prices)); } @@ -976,10 +978,10 @@ try { asset amount = core_sym::from_string("1000.0000"); stake_asset(service_id, account, amount); - const uint8_t status_cancel = 1; - const uint8_t status_pause = 2; - auto token = unregservice(service_id, account, status_pause); - BOOST_TEST_REQUIRE(status_pause == get_data_service_provision(service_id, account)["status"].as()); + const uint8_t status_unreg = 1; + const uint8_t status_suspend = 2; + auto token = unregservice(service_id, account, status_unreg); + BOOST_TEST_REQUIRE(status_unreg == get_data_service_provision(service_id, account)["status"].as()); // BOOST_TEST_REQUIRE( status_pause == get_svc_provision_cancel_apply(service_id)["status"].as() ); } @@ -1042,6 +1044,46 @@ try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE(unstakeasset_test, bos_oracle_tester) +try { + + name account = N(alice); + + uint64_t new_service_id = reg_service(account); + uint64_t new_second_service_id = reg_service(account); + + // BOOST_TEST("" == "====reg test true"); + produce_blocks(1); + /// stake asset + { + uint64_t service_id = new_service_id; + name account = N(alice); + asset amount = core_sym::from_string("1000.0000"); + string memo = ""; + stake_asset(service_id, account, amount); + BOOST_TEST_REQUIRE(amount == get_data_provider(account)["total_stake_amount"].as()); + + asset add_amount = core_sym::from_string("10.0001"); + stake_asset(service_id, account, add_amount); + BOOST_TEST_REQUIRE((amount + add_amount) == get_data_provider(account)["total_stake_amount"].as()); + } + + { + uint64_t service_id = new_service_id; + const uint8_t status_unreg = 1; + auto token = unregservice(service_id, account, status_unreg); + BOOST_TEST_REQUIRE(status_unreg == get_data_service_provision(service_id, account)["status"].as()); + + produce_blocks(10); + asset amount = core_sym::from_string("1000.0000"); + BOOST_TEST(core_sym::from_string("1989.9999") == get_balance(account)); + unstakeasset(service_id, account, amount, ""); + BOOST_TEST(core_sym::from_string("2989.9999") == get_balance(account)); + } + +} +FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE(pushdata_test, bos_oracle_tester) try { @@ -1089,7 +1131,7 @@ try { produce_block(fc::days(3)); produce_blocks(10); - auto cdata = cleardata(service_id, 10800); + auto cdata = cleardata(provider,service_id, 10800); } } FC_LOG_AND_RETHROW()