Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #247 from brianjohnson5972/lkup_by_acct_ctrl_167
Browse files Browse the repository at this point in the history
Added lookup of controlled accounts by controlling account name.
  • Loading branch information
bytemaster authored Aug 29, 2017
2 parents ba749f3 + d79c72b commit fa57a75
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 13 deletions.
2 changes: 2 additions & 0 deletions libraries/chain/include/eos/chain/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ namespace eos { namespace chain {
generated_transaction_object_type,
producer_object_type,
chain_property_object_type,
account_control_history_object_type, ///< Defined by account_history_plugin
account_transaction_history_object_type, ///< Defined by account_history_plugin
transaction_history_object_type, ///< Defined by account_history_plugin
public_key_history_object_type, ///< Defined by account_history_plugin
Expand Down Expand Up @@ -225,6 +226,7 @@ FC_REFLECT_ENUM(eos::chain::object_type,
(generated_transaction_object_type)
(producer_object_type)
(chain_property_object_type)
(account_control_history_object_type)
(account_transaction_history_object_type)
(transaction_history_object_type)
(public_key_history_object_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ void account_history_api_plugin::plugin_startup() {
app().get_plugin<http_plugin>().add_api({
CHAIN_RO_CALL(get_transaction),
CHAIN_RO_CALL(get_transactions),
CHAIN_RO_CALL(get_key_accounts)
CHAIN_RO_CALL(get_key_accounts),
CHAIN_RO_CALL(get_controlled_accounts)
});
}

Expand Down
70 changes: 58 additions & 12 deletions plugins/account_history_plugin/account_history_plugin.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <eos/account_history_plugin/account_history_plugin.hpp>
#include <eos/account_history_plugin/account_control_history_object.hpp>
#include <eos/account_history_plugin/account_transaction_history_object.hpp>
#include <eos/account_history_plugin/public_key_history_object.hpp>
#include <eos/account_history_plugin/transaction_history_object.hpp>
Expand All @@ -25,6 +26,7 @@ namespace eos {

using chain::AccountName;
using chain::block_id_type;
using chain::PermissionName;
using chain::ProcessedTransaction;
using chain::signed_block;
using boost::multi_index_container;
Expand All @@ -38,6 +40,7 @@ class account_history_plugin_impl {
ProcessedTransaction get_transaction(const chain::transaction_id_type& transaction_id) const;
get_transactions_results get_transactions(const AccountName& account_name, const optional<uint32_t>& skip_seq, const optional<uint32_t>& num_seq) const;
vector<AccountName> get_key_accounts(const public_key_type& public_key) const;
vector<AccountName> get_controlled_accounts(const AccountName& controlling_account) const;
void applied_block(const signed_block&);

chain_plugin* chain_plug;
Expand All @@ -60,7 +63,20 @@ class account_history_plugin_impl {
bool is_scope_relevant(const eos::types::Vector<AccountName>& scope);
get_transactions_results ordered_transactions(const block_transaction_id_map& block_transaction_ids, const fc::time_point& start_time, const uint32_t begin, const uint32_t end) const;
static void add(chainbase::database& db, const vector<types::KeyPermissionWeight>& keys, const AccountName& account_name, const PermissionName& permission);
static void remove(chainbase::database& db, const AccountName& account_name, const PermissionName& permission);
template<typename MultiIndex, typename LookupType>
static void remove(chainbase::database& db, const AccountName& account_name, const PermissionName& permission)
{
const auto& idx = db.get_index<MultiIndex, LookupType>();
auto& mutatable_idx = db.get_mutable_index<MultiIndex>();
auto range = idx.equal_range( boost::make_tuple( account_name, permission ) );

for (auto acct_perm = range.first; acct_perm != range.second; ++acct_perm)
{
mutatable_idx.remove(*acct_perm);
}
}

static void add(chainbase::database& db, const vector<types::AccountPermissionWeight>& controlling_accounts, const AccountName& account_name, const PermissionName& permission);
bool time_exceeded(const fc::time_point& start_time) const;
static const AccountName NEW_ACCOUNT;
static const AccountName UPDATE_AUTH;
Expand Down Expand Up @@ -252,6 +268,21 @@ vector<AccountName> account_history_plugin_impl::get_key_accounts(const public_k
return vector<AccountName>(accounts.begin(), accounts.end());
}

vector<AccountName> account_history_plugin_impl::get_controlled_accounts(const AccountName& controlling_account) const
{
std::set<AccountName> accounts;
const auto& db = chain_plug->chain().get_database();
db.with_read_lock( [&]() {
const auto& account_control_idx = db.get_index<account_control_history_multi_index, by_controlling>();
auto range = account_control_idx.equal_range( controlling_account );
for (auto obj = range.first; obj != range.second; ++obj)
{
accounts.insert(obj->controlled_account);
}
} );
return vector<AccountName>(accounts.begin(), accounts.end());
}

void account_history_plugin_impl::applied_block(const signed_block& block)
{
const auto block_id = block.id();
Expand Down Expand Up @@ -286,22 +317,30 @@ void account_history_plugin_impl::applied_block(const signed_block& block)
if (msg.type == NEW_ACCOUNT)
{
const auto create = msg.as<types::newaccount>();
auto count = create.owner.keys.size() + create.active.keys.size() + create.recovery.keys.size();
add(db, create.owner.keys, create.name, OWNER);
add(db, create.active.keys, create.name, ACTIVE);
add(db, create.recovery.keys, create.name, RECOVERY);

add(db, create.owner.accounts, create.name, OWNER);
add(db, create.active.accounts, create.name, ACTIVE);
add(db, create.recovery.accounts, create.name, RECOVERY);
}
else if (msg.type == UPDATE_AUTH)
{
const auto update = msg.as<types::updateauth>();
remove(db, update.account, update.permission);
remove<public_key_history_multi_index, by_account_permission>(db, update.account, update.permission);
add(db, update.authority.keys, update.account, update.permission);

remove<account_control_history_multi_index, by_controlled_authority>(db, update.account, update.permission);
add(db, update.authority.accounts, update.account, update.permission);
}
else if (msg.type == DELETE_AUTH)
{
const auto del = msg.as<types::deleteauth>();
remove(db, del.account, del.permission);
}
remove<public_key_history_multi_index, by_account_permission>(db, del.account, del.permission);

remove<account_control_history_multi_index, by_controlled_authority>(db, del.account, del.permission);
}
}
}
}
Expand All @@ -321,15 +360,15 @@ void account_history_plugin_impl::add(chainbase::database& db, const vector<type
}
}

void account_history_plugin_impl::remove(chainbase::database& db, const AccountName& account_name, const PermissionName& permission)
void account_history_plugin_impl::add(chainbase::database& db, const vector<types::AccountPermissionWeight>& controlling_accounts, const AccountName& account_name, const PermissionName& permission)
{
const auto& acct_perm_idx = db.get_index<public_key_history_multi_index, by_account_permission>();
auto& mutatable_acct_perm_idx = db.get_mutable_index<public_key_history_multi_index>();
auto range = acct_perm_idx.equal_range( boost::make_tuple( account_name, permission ) );

for (auto acct_perm = range.first; acct_perm != range.second; ++acct_perm)
for (auto controlling_account : controlling_accounts )
{
mutatable_acct_perm_idx.remove(*acct_perm);
db.create<account_control_history_object>([&](account_control_history_object& obj) {
obj.controlled_account = account_name;
obj.controlled_permission = permission;
obj.controlling_account = controlling_account.permission.account;
});
}
}

Expand Down Expand Up @@ -378,6 +417,7 @@ void account_history_plugin::plugin_startup()
{
my->chain_plug = app().find_plugin<chain_plugin>();
auto& db = my->chain_plug->chain().get_mutable_database();
db.add_index<account_control_history_multi_index>();
db.add_index<account_transaction_history_multi_index>();
db.add_index<public_key_history_multi_index>();
db.add_index<transaction_history_multi_index>();
Expand Down Expand Up @@ -408,5 +448,11 @@ read_only::get_key_accounts_results read_only::get_key_accounts(const get_key_ac
{
return { account_history->get_key_accounts(params.public_key) };
}

read_only::get_controlled_accounts_results read_only::get_controlled_accounts(const get_controlled_accounts_params& params) const
{
return { account_history->get_controlled_accounts(params.controlling_account) };
}

} // namespace account_history_apis
} // namespace eos
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once

#include <chainbase/chainbase.hpp>
#include <eos/chain/types.hpp>

namespace eos {
using chain::AccountName;
using chain::PermissionName;
using chain::shared_vector;
using chain::transaction_id_type;
using namespace boost::multi_index;

class account_control_history_object : public chainbase::object<chain::account_control_history_object_type, account_control_history_object> {
OBJECT_CTOR(account_control_history_object)

id_type id;
AccountName controlled_account;
PermissionName controlled_permission;
AccountName controlling_account;
};

struct by_id;
struct by_controlling;
struct by_controlled_authority;
using account_control_history_multi_index = chainbase::shared_multi_index_container<
account_control_history_object,
indexed_by<
ordered_unique<tag<by_id>, BOOST_MULTI_INDEX_MEMBER(account_control_history_object, account_control_history_object::id_type, id)>,
hashed_non_unique<tag<by_controlling>, BOOST_MULTI_INDEX_MEMBER(account_control_history_object, AccountName, controlling_account), std::hash<AccountName>>,
hashed_non_unique<tag<by_controlled_authority>,
composite_key< account_control_history_object,
member<account_control_history_object, AccountName, &account_control_history_object::controlled_account>,
member<account_control_history_object, PermissionName, &account_control_history_object::controlled_permission>
>,
composite_key_hash< std::hash<AccountName>, std::hash<PermissionName> >
>
>
>;

typedef chainbase::generic_index<account_control_history_multi_index> account_control_history_index;

}

CHAINBASE_SET_INDEX_TYPE( eos::account_control_history_object, eos::account_control_history_multi_index )

FC_REFLECT( eos::account_control_history_object, (controlled_account)(controlled_permission)(controlling_account) )

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class read_only {
read_only(account_history_const_ptr&& account_history)
: account_history(account_history) {}


struct get_transaction_params {
chain::transaction_id_type transaction_id;
};
Expand All @@ -35,6 +36,7 @@ class read_only {
};
get_transaction_results get_transaction(const get_transaction_params& params) const;


struct get_transactions_params {
chain::AccountName account_name;
optional<uint32_t> skip_seq;
Expand All @@ -52,13 +54,23 @@ class read_only {

get_transactions_results get_transactions(const get_transactions_params& params) const;


struct get_key_accounts_params {
chain::public_key_type public_key;
};
struct get_key_accounts_results {
vector<chain::AccountName> account_names;
};
get_key_accounts_results get_key_accounts(const get_key_accounts_params& params) const;


struct get_controlled_accounts_params {
chain::AccountName controlling_account;
};
struct get_controlled_accounts_results {
vector<chain::AccountName> controlled_accounts;
};
get_controlled_accounts_results get_controlled_accounts(const get_controlled_accounts_params& params) const;
};

class read_write {
Expand Down Expand Up @@ -99,3 +111,5 @@ FC_REFLECT(eos::account_history_apis::read_only::ordered_transaction_results, (s
FC_REFLECT(eos::account_history_apis::read_only::get_transactions_results, (transactions)(time_limit_exceeded_error) )
FC_REFLECT(eos::account_history_apis::read_only::get_key_accounts_params, (public_key) )
FC_REFLECT(eos::account_history_apis::read_only::get_key_accounts_results, (account_names) )
FC_REFLECT(eos::account_history_apis::read_only::get_controlled_accounts_params, (controlling_account) )
FC_REFLECT(eos::account_history_apis::read_only::get_controlled_accounts_results, (controlled_accounts) )
10 changes: 10 additions & 0 deletions programs/eosc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const string account_history_func_base = "/v1/account_history";
const string get_transaction_func = account_history_func_base + "/get_transaction";
const string get_transactions_func = account_history_func_base + "/get_transactions";
const string get_key_accounts_func = account_history_func_base + "/get_key_accounts";
const string get_controlled_accounts_func = account_history_func_base + "/get_controlled_accounts";

inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
std::sort( names.begin(), names.end() );
Expand Down Expand Up @@ -409,6 +410,15 @@ int send_command (const vector<string> &cmd_line)
chain::public_key_type public_key(cmd_line[1]);
auto arg = fc::mutable_variant_object( "public_key", public_key);
std::cout << fc::json::to_pretty_string( call( get_key_accounts_func, arg) ) << std::endl;
} else if( command == "servants" ) {
if( cmd_line.size() != 2 )
{
std::cerr << "usage: " << program << " servants CONTROLLING_ACCOUNT_NAME\n";
return -1;
}
chain::AccountName controlling_account_name(cmd_line[1]);
auto arg = fc::mutable_variant_object( "controlling_account", controlling_account_name);
std::cout << fc::json::to_pretty_string( call( get_controlled_accounts_func, arg) ) << std::endl;
}
return 0;
}
Expand Down

0 comments on commit fa57a75

Please sign in to comment.