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

Added lookup of controlled accounts by controlling account name. #247

Merged
merged 1 commit into from
Aug 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -405,6 +406,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