From 3aba2cb8034265d108dbb62e4bbf04186631e4a5 Mon Sep 17 00:00:00 2001 From: vonhenry Date: Wed, 6 May 2020 16:25:23 +0800 Subject: [PATCH] add feature --- ibc.chain/README.md | 11 +++-- ibc.chain/include/ibc.chain/ibc.chain.hpp | 13 ++++++ ibc.chain/src/ibc.chain.cpp | 21 ++++++++-- ibc.token/README.md | 32 ++++++++------- ibc.token/include/ibc.token/ibc.token.hpp | 14 +++++++ ibc.token/src/ibc.token.cpp | 50 +++++++++++++++-------- 6 files changed, 103 insertions(+), 38 deletions(-) diff --git a/ibc.chain/README.md b/ibc.chain/README.md index b7375f2..70a6fb0 100644 --- a/ibc.chain/README.md +++ b/ibc.chain/README.md @@ -23,12 +23,16 @@ Actions called by administrator must be one of `pipeline` (represent DPOS pipeline bft consensus, such as the current EOSIO mainnet consensus) and `batch` (represent DPOS batch pbft consensus, such as the new BOS 3 seconds LIB consensus). - require auth of _self - + +#### setadmin( admin ) + - **admin**, admin account. + - require auth of _self + #### forceinit( ) - three table ( _chaindb, _prodsches, _sections ) will be clear. - this action is needed when repairing the ibc system manually, please refer to [TROUBLESHOOTING](../docs/Troubles_Shooting.md) for detailed IBC system recovery process. - - require auth of _self + - require auth of _self or admin Actions called by ibc_plugin ---------------------------- @@ -66,7 +70,8 @@ ibc.token : `cash`,`rollback`,`rmunablerb` #### void relay( string action, name relay ) - **action**, the string value must be **`add`** to add a relay to the relay set or **`remove`** to remove a relay, you can add multiple relays. - **relay**, the relay account. - + - require auth of _self or admin + #### void reqrelayauth( ) This action is used to facilitate the administrator to check the value of `check_relay_auth`, because this parameter is hard coded in the code and cannot be viewed through the contract table. diff --git a/ibc.chain/include/ibc.chain/ibc.chain.hpp b/ibc.chain/include/ibc.chain/ibc.chain.hpp index 8615076..c90e2b5 100644 --- a/ibc.chain/include/ibc.chain/ibc.chain.hpp +++ b/ibc.chain/include/ibc.chain/ibc.chain.hpp @@ -22,6 +22,12 @@ namespace eosio { const static bool check_relay_auth = true; + struct [[eosio::table("admin"), eosio::contract("ibc.chain")]] admin_struct { + name admin; + EOSLIB_SERIALIZE( admin_struct, (admin)) + }; + typedef eosio::singleton< "admin"_n, admin_struct > admin_singleton; + struct [[eosio::table("global"), eosio::contract("ibc.chain")]] global_state { name chain_name; // the original chain name, ibc_plugin uses this name to interact with the ibc.token contract chain_id_type chain_id; @@ -100,6 +106,8 @@ namespace eosio { global_state _gstate; global_mutable_singleton _global_mutable; global_mutable _gmutable; + admin_singleton _admin_sg; + admin_struct _admin_st; chaindb _chaindb; prodsches _prodsches; sections _sections; @@ -114,6 +122,9 @@ namespace eosio { chain_id_type chain_id, name consensus_algo ); + [[eosio::action]] + void setadmin( name admin ); + [[eosio::action]] void chaininit( const std::vector& header, const producer_schedule& active_schedule, @@ -211,6 +222,8 @@ namespace eosio { capi_public_key get_public_key_form_signature( digest_type digest, signature_type sig ) const; bool only_one_eosio_bp(); + + void check_admin_auth(); }; } /// namespace eosio diff --git a/ibc.chain/src/ibc.chain.cpp b/ibc.chain/src/ibc.chain.cpp index c405cb7..fb8fdfc 100644 --- a/ibc.chain/src/ibc.chain.cpp +++ b/ibc.chain/src/ibc.chain.cpp @@ -11,6 +11,7 @@ namespace eosio { chain::chain( name s, name code, datastream ds ) :contract(s,code,ds), _global_state(_self, _self.value), + _admin_sg(_self, _self.value), _global_mutable(_self, _self.value), _chaindb(_self, _self.value), _prodsches(_self, _self.value), @@ -19,11 +20,13 @@ namespace eosio { { _gstate = _global_state.exists() ? _global_state.get() : global_state{}; _gmutable = _global_mutable.exists() ? _global_mutable.get() : global_mutable{}; + _admin_st = _admin_sg.exists() ? _admin_sg.get() : admin_struct{}; } chain::~chain() { _global_state.set( _gstate, _self ); _global_mutable.set( _gmutable, _self ); + _admin_sg.set( _admin_st , _self ); } void chain::setglobal( name chain_name, @@ -38,6 +41,11 @@ namespace eosio { _gstate.consensus_algo = consensus_algo; } + void chain::setadmin( name admin ){ + require_auth( _self ); + _admin_st.admin = admin; + } + // init for both pipeline and batch light client void chain::chaininit( const std::vector& header_data, const producer_schedule& active_schedule, @@ -840,7 +848,7 @@ namespace eosio { // ------ force init ------ // void chain::forceinit(){ - require_auth(_self); + check_admin_auth(); while ( _prodsches.begin() != _prodsches.end() ){ _prodsches.erase(_prodsches.begin()); } while ( _sections.begin() != _sections.end() ){ _sections.erase(_sections.begin()); } _gmutable = global_mutable{}; @@ -869,7 +877,7 @@ namespace eosio { } void chain::relay( string action, name relay ) { - require_auth( _self ); + check_admin_auth(); auto existing = _relays.find( relay.value ); if ( action == "add" ) { @@ -895,6 +903,13 @@ namespace eosio { } } + void chain::check_admin_auth(){ + if ( ! has_auth(_self) ){ + eosio_assert( _admin_st.admin != name() && is_account( _admin_st.admin ),"admin account not exist"); + require_auth( _admin_st.admin ); + } + } + } /// namespace eosio -EOSIO_DISPATCH( eosio::chain, (setglobal)(chaininit)(pushsection)(rmfirstsctn)(pushblkcmits)(forceinit)(relay)(reqrelayauth) ) +EOSIO_DISPATCH( eosio::chain, (setglobal)(chaininit)(pushsection)(rmfirstsctn)(pushblkcmits)(forceinit)(relay)(reqrelayauth)(setadmin) ) diff --git a/ibc.token/README.md b/ibc.token/README.md index e489ef3..cd1760b 100644 --- a/ibc.token/README.md +++ b/ibc.token/README.md @@ -42,6 +42,10 @@ Actions called by administrators Only when _global_state.active is true can the original IBC transaction be successfully executed. - require auth of _self +#### setadmin( admin ) + - **admin**, admin account. + - require auth of _self + #### regpeerchain ``` void regpeerchain( name peerchain_name, @@ -69,7 +73,7 @@ Actions called by administrators - **cache_cashtrxs_table_records** maximum cashtrxs table records, the recommended value is 1000. - **active** set the initial active state (_peerchains.active). Only when _peerchains.active is true can the original IBC transaction to this peer chain be successfully executed. - - require auth of _self + - require auth of _self or admin Examples: The following examples assume that IBC systems are deployed between the EOS and BOS mainnet, @@ -90,7 +94,7 @@ void setchainbool( name peerchain_name, string which, bool value ); - **which**, must be 'active' - **value**, bool value, set the active state (_peerchains.active). Only when _peerchains.active is true can the original IBC transaction to this peer chain be successfully executed. - - require auth of _self + - require auth of _self or admin #### regacpttoken ``` @@ -125,7 +129,7 @@ This action is used to register blockchain native token, which is originally iss - **failed_fee** use this value to calculate fee for the filed original transaction. - **active** set the initial active state of this token, when active is false, IBC transfers are not allowed, but **cash**s trigger by peerchain action **withdraw** can still execute. - - require auth of _self + - require auth of _self or admin Note: from IBC version 4, the pegged token symbol must same with the original token symbol. @@ -170,7 +174,7 @@ Modify only one member of type `int` in currency_accept struct. - **symcode** the token symbol code - **which** must be "max_tfs_per_minute". - **value** the value to be set. - - require auth of _self + - require auth of _self or admin #### setacptbool ``` @@ -196,7 +200,7 @@ Modify fee related members in currency_accept struct. - **fee_mode** must be "fixed" or "ratio". - **fee_fixed** fixed fee quota, used when fee_mode == fixed - **fee_ratio** charge ratio, used when fee_mode == ratio - - require auth of _self + - require auth of _self or admin #### regpegtoken ``` @@ -224,7 +228,7 @@ This action is used to register pegged token, which is originally issued on othe - **failed_fee** use this value to calculate fee for the filed withdraw transaction. - **active** set the initial active state of this pegged token, when active is false, IBC withdraws are not allowed, but **cash**s trigger by peerchain action **transfer** can still execute. - - require auth of _self + - require auth of _self or admin ``` contract_token=ibc2token555 @@ -275,7 +279,7 @@ this action equals call regpegtoken(...) firstly and then call regacpttoken(...) - **failed_fee** use this value to calculate fee for the filed transfer transaction. - **active** set the initial active state of this pegged token, when active is false, IBC transfers are not allowed, but **cash**s trigger by peerchain action **transfer** can still execute. - - require auth of _self + - require auth of _self or admin ``` contract_token=ibc2token555 @@ -322,7 +326,7 @@ Modify only one member of type `bool` in currency_stats struct. Modify fee related members in currency_stats struct. - **symcode** the symcode of registered pegged token. - **fee** fixed fee quota - - require auth of _self + - require auth of _self or admin #### unregtoken ``` @@ -332,7 +336,7 @@ Modify fee related members in currency_stats struct. - **table** table name, table name must be one of `all` ,`accepts` and `stats`, when it's `all`, all records in table `accepts` or `stats` will be deleted. - **sym_code** token symbol code, e.g. `BOS`,`EOS`. - - require auth of _self + - require auth of _self or admin #### fcrollback ``` @@ -342,7 +346,7 @@ Modify fee related members in currency_stats struct. used to force rollback (refund) specified original transaction records in table `origtrxs`. - **peerchain_name** peer chain name. - **trxs** original transactions that need to be rolled back. - - require auth of _self + - require auth of _self or admin #### fcrmorigtrx ``` @@ -352,7 +356,7 @@ Modify fee related members in currency_stats struct. used to force remove specified original transaction records in table `origtrxs`. - **peerchain_name** peer chain name. - **trxs** original transactions that need to be remove. - - require auth of _self + - require auth of _self or admin #### lockall ``` @@ -360,7 +364,7 @@ void lockall(); ``` - set 'active' of global_state false. - when locked, ibc-transfer and withdraw will not allowed to execute for all token. - - require auth of _self + - require auth of _self or admin #### unlockall ``` @@ -368,7 +372,7 @@ void unlockall(); ``` - set 'active' of global_state true. - when unlocked, the restrictions caused by execute lockall() will be removed. - - require auth of _self + - require auth of _self or admin #### forceinit ``` @@ -382,7 +386,7 @@ void unlockall(); so if the number of records in these three tables is greater than 200, you need to perform this action several times to clear all three tables. When the console prints "force initialization complete", it says that all three tables have been cleared. - - require auth of _self + - require auth of _self or admin #### hubinit ``` diff --git a/ibc.token/include/ibc.token/ibc.token.hpp b/ibc.token/include/ibc.token/ibc.token.hpp index 6a27dc7..fdea27d 100644 --- a/ibc.token/include/ibc.token/ibc.token.hpp +++ b/ibc.token/include/ibc.token/ibc.token.hpp @@ -58,6 +58,9 @@ namespace eosio { [[eosio::action]] void setglobal( name this_chain, bool active ); + [[eosio::action]] + void setadmin( name admin ); + [[eosio::action]] void regpeerchain( name peerchain_name, string peerchain_info, @@ -261,9 +264,18 @@ namespace eosio { EOSLIB_SERIALIZE( global_state, (this_chain)(active)) }; + struct [[eosio::table("admin")]] admin_struct { + name admin; + EOSLIB_SERIALIZE( admin_struct, (admin)) + }; + typedef eosio::singleton< "admin"_n, admin_struct > admin_singleton; + + private: eosio::singleton< "globals"_n, global_state > _global_state; global_state _gstate; + eosio::singleton< "admin"_n, admin_struct > _admin_sg; + admin_struct _admin_st; // code,scope (_self,_self) struct [[eosio::table("freeaccount")]] peer_chain_free_account { @@ -550,6 +562,8 @@ namespace eosio { void delete_by_hub_trx_id( const transaction_id_type& hub_trx_id ); // when successfully completed void rollback_hub_trx( const transaction_id_type& hub_trx_id, asset quantity ); // when ibc transmit fails #endif + + void check_admin_auth(); }; } /// namespace eosio diff --git a/ibc.token/src/ibc.token.cpp b/ibc.token/src/ibc.token.cpp index 14e723a..cea6b1e 100644 --- a/ibc.token/src/ibc.token.cpp +++ b/ibc.token/src/ibc.token.cpp @@ -17,6 +17,7 @@ namespace eosio { token::token( name s, name code, datastream ds ): contract( s, code, ds ), _global_state( _self, _self.value ), + _admin_sg(_self, _self.value), _peerchains( _self, _self.value ), _freeaccount( _self, _self.value ), _peerchainm( _self, _self.value ), @@ -27,6 +28,7 @@ namespace eosio { #endif { _gstate = _global_state.exists() ? _global_state.get() : global_state{}; + _admin_st = _admin_sg.exists() ? _admin_sg.get() : admin_struct{}; #ifdef HUB _hubgs = _hub_globals.exists() ? _hub_globals.get() : hub_globals{}; #endif @@ -34,6 +36,7 @@ namespace eosio { token::~token(){ _global_state.set( _gstate, _self ); + _admin_sg.set( _admin_st , _self ); #ifdef HUB _hub_globals.set( _hubgs, _self ); #endif @@ -45,6 +48,11 @@ namespace eosio { _gstate.active = active; } + void token::setadmin( name admin ){ + require_auth( _self ); + _admin_st.admin = admin; + } + void token::regpeerchain( name peerchain_name, string peerchain_info, name peerchain_ibc_token_contract, @@ -54,7 +62,7 @@ namespace eosio { uint32_t max_origtrxs_table_records, uint32_t cache_cashtrxs_table_records, bool active ){ - require_auth( _self ); + check_admin_auth(); eosio_assert( peerchain_name != name(), "peerchain_name can not be empty"); eosio_assert( peerchain_info.size() < 256, "peerchain_info has more than 256 bytes"); @@ -95,7 +103,7 @@ namespace eosio { } void token::setchainbool( name peerchain_name, string which, bool value ){ - require_auth( _self ); + check_admin_auth(); auto& chain = _peerchains.get( peerchain_name.value, "peerchain not registered"); if ( which == "active" ){ @@ -119,7 +127,7 @@ namespace eosio { double service_fee_ratio, asset failed_fee, bool active ){ - require_auth( _self ); + check_admin_auth(); eosio_assert( is_account( original_contract ), "original_contract account does not exist"); eosio_assert( is_account( administrator ), "administrator account does not exist"); @@ -223,7 +231,7 @@ namespace eosio { void token::setacptint( symbol_code symcode, string which, uint64_t value ) { const auto& acpt = get_currency_accept( symcode ); - require_auth( _self ); + check_admin_auth(); if ( which == "max_tfs_per_minute" ){ eosio_assert( 1 <= value && value <= 500, "max_tfs_per_minute's value must in range [1,500]"); @@ -249,7 +257,7 @@ namespace eosio { name fee_mode, asset fee_fixed, double fee_ratio ) { - require_auth( _self ); + check_admin_auth(); const auto& acpt = get_currency_accept( symcode ); eosio_assert( fee_mode == "fixed"_n || fee_mode == "ratio"_n, "mode can only be fixed or ratio"); @@ -283,7 +291,7 @@ namespace eosio { name administrator, asset failed_fee, bool active ){ - require_auth( _self ); + check_admin_auth(); eosio_assert( is_account( administrator ), "administrator account does not exist"); eosio_assert( _accepts.find(max_supply.symbol.code().raw()) == _accepts.end(), "token symbol conflict in table 'stats' and 'accepts'"); @@ -362,7 +370,7 @@ namespace eosio { void token::setpegint( symbol_code symcode, string which, uint64_t value ) { const auto& st = get_currency_stats( symcode ); - require_auth( _self ); + check_admin_auth(); if ( which == "max_wds_per_minute" ){ eosio_assert( 1 <= value && value <= 500, "max_wds_per_minute's value must in range [1,500]"); @@ -384,7 +392,7 @@ namespace eosio { } void token::setpegtkfee( symbol_code symcode, asset fee) { - require_auth( _self ); + check_admin_auth(); const auto& st = get_currency_stats( symcode ); eosio_assert( fee.symbol == st.supply.symbol && fee.amount >= 0, "service_fee_fixed invalid" ); @@ -396,7 +404,7 @@ namespace eosio { } void token::unregtoken( name table, symbol_code sym_code ){ - require_auth( _self ); + check_admin_auth(); if ( table == "all"_n ){ auto ptr1 = _accepts.find( sym_code.raw() ); @@ -1149,7 +1157,7 @@ namespace eosio { // this action maybe needed when repairing the ibc system manually void token::fcrollback( name peerchain_name, const std::vector trxs ) { - require_auth( _self ); + check_admin_auth(); eosio_assert( trxs.size() != 0, "no transacton" ); auto _origtrxs = origtrxs_table( _self, peerchain_name.value ); @@ -1200,7 +1208,7 @@ namespace eosio { } void token::fcrmorigtrx( name peerchain_name, const std::vector trxs ){ - require_auth( _self ); + check_admin_auth(); eosio_assert( trxs.size() != 0, "no transacton" ); auto _origtrxs = origtrxs_table( _self, peerchain_name.value ); @@ -1212,13 +1220,13 @@ namespace eosio { } void token::lockall() { - require_auth( _self ); + check_admin_auth(); eosio_assert( _gstate.active == true, "_gstate.active == false, nothing to do"); _gstate.active = false; } void token::unlockall() { - require_auth( _self ); + check_admin_auth(); eosio_assert( _gstate.active == false, "_gstate.active == true, nothing to do"); _gstate.active = true; } @@ -1281,7 +1289,7 @@ namespace eosio { } void token::setfreeacnt( name peerchain_name, name account ){ - require_auth( _self ); + check_admin_auth(); auto itr = _freeaccount.find( peerchain_name.value ); if ( itr != _freeaccount.end() ) { @@ -1297,7 +1305,7 @@ namespace eosio { } void token::forceinit( name peerchain_name ) { - require_auth( _self ); + check_admin_auth(); auto _origtrxs = origtrxs_table( _self, peerchain_name.value ); auto _cashtrxs = cashtrxs_table( _self, peerchain_name.value ); @@ -1694,7 +1702,7 @@ namespace eosio { } void token::hubinit( name hub_account ){ - require_auth( _self ); + check_admin_auth(); eosio_assert( _hubgs.is_open == false, "already init"); _hubgs.is_open = true; _hubgs.hub_account = hub_account; @@ -1722,7 +1730,7 @@ namespace eosio { double service_fee_ratio, asset failed_fee, bool active ) { - require_auth( _self ); + check_admin_auth(); /// --- register peg token --- regpegtoken( peerchain_name, @@ -1754,6 +1762,12 @@ namespace eosio { #endif + void token::check_admin_auth(){ + if ( ! has_auth(_self) ){ + eosio_assert( _admin_st.admin != name() && is_account( _admin_st.admin ),"admin account not exist"); + require_auth( _admin_st.admin ); + } + } } /// namespace eosio extern "C" { @@ -1764,7 +1778,7 @@ extern "C" { (regacpttoken)(setacptasset)(setacptstr)(setacptint)(setacptbool)(setacptfee) (regpegtoken)(setpegasset)(setpegint)(setpegbool)(setpegtkfee) (transfer)(cash)(cashconfirm)(rollback)(rmunablerb)(fcrollback)(fcrmorigtrx) - (lockall)(unlockall)(forceinit)(open)(close)(unregtoken)(setfreeacnt) + (lockall)(unlockall)(forceinit)(open)(close)(unregtoken)(setfreeacnt)(setadmin) #ifdef HUB (hubinit)(feetransfer)(regpegtoken2) #endif