From aee408086a89ff0107e112152d7e678179ed5373 Mon Sep 17 00:00:00 2001 From: Jeeyong Um Date: Thu, 8 Nov 2018 03:24:40 +0900 Subject: [PATCH] Add support for removal of table without multi_index typedefs to eosio.system --- .../include/eosio.system/eosio.system.hpp | 31 +++++++++++++++++++ eosio.system/src/eosio.system.cpp | 28 ++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 32ccdce76..ca0c67416 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -176,6 +176,34 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; + template + int32_t remove_secondary_index( uint64_t code, uint64_t scope, uint64_t table ) { + using namespace eosio::_multi_index_detail; + + uint64_t pk; + + auto min = secondary_key_traits::lowest(); + auto itr = secondary_index_db_functions::db_idx_lowerbound( code, scope, table, min, pk ); + + // itr == -1, no secondary index + // itr < -1, type mismatch + if( itr <= -1 ) return itr; + + while( itr > -1 ) { + auto next_itr = secondary_index_db_functions::db_idx_next( itr, &pk ); + secondary_index_db_functions::db_idx_remove( itr ); + itr = next_itr; + } + + // secondary index is removed + return 0; + } + +#define REMOVE_SECONDARY_INDEX( ITR, TYPE, CODE, SCOPE, TABLE ) \ + ITR = remove_secondary_index( CODE, SCOPE, TABLE ); \ + if ( ITR == -1 ) break; \ + else if ( ITR == 0 ) continue; + class [[eosio::contract("eosio.system")]] system_contract : public native { private: voters_table _voters; @@ -317,6 +345,9 @@ namespace eosiosystem { [[eosio::action]] void bidrefund( name bidder, name newname ); + [[eosio::action]] + void removetable( name code, uint64_t scope, name table ); + private: // Implementation details: diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index eb99a2081..97089bb88 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -218,6 +218,32 @@ namespace eosiosystem { refunds_table.erase( it ); } + void system_contract::removetable( name code, uint64_t scope, name table ) { + require_auth( code ); + + auto itr = db_end_i64( code.value, scope, table.value ); + eosio_assert( itr != -1, "table not found" ); + + for( uint64_t i = 0; i < 0x10; ++i ) { + REMOVE_SECONDARY_INDEX( itr, uint64_t, code.value, scope, table.value | i ) + REMOVE_SECONDARY_INDEX( itr, uint128_t, code.value, scope, table.value | i ) + REMOVE_SECONDARY_INDEX( itr, double, code.value, scope, table.value | i ) + REMOVE_SECONDARY_INDEX( itr, long double, code.value, scope, table.value | i ) + REMOVE_SECONDARY_INDEX( itr, eosio::key256, code.value, scope, table.value | i ) + //REMOVE_SECONDARY_INDEX( itr, eosio::digest256, code.value, scope, table.value | i ) + } + + uint64_t pk; + + itr = db_lowerbound_i64( code.value, scope, table.value, std::numeric_limits::min() ); + + while( itr > -1 ) { + auto next_itr = db_next_i64( itr, &pk ); + db_remove_i64( itr ); + itr = next_itr; + } + } + /** * Called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. @@ -308,7 +334,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp - (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) + (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund)(removetable) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp