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 #241 from brianjohnson5972/trx_by_key_166
Browse files Browse the repository at this point in the history
Account lookup by key
  • Loading branch information
bytemaster authored Aug 28, 2017
2 parents 6245837 + 2aaacad commit d41c7cc
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 11 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 @@ -176,6 +176,7 @@ namespace eos { namespace chain {
chain_property_object_type,
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
balance_object_type, ///< Defined by native_contract library
staked_balance_object_type, ///< Defined by native_contract library
producer_votes_object_type, ///< Defined by native_contract library
Expand Down Expand Up @@ -226,6 +227,7 @@ FC_REFLECT_ENUM(eos::chain::object_type,
(chain_property_object_type)
(account_transaction_history_object_type)
(transaction_history_object_type)
(public_key_history_object_type)
(balance_object_type)
(staked_balance_object_type)
(producer_votes_object_type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,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_transactions),
CHAIN_RO_CALL(get_key_accounts)
});
}

Expand Down
102 changes: 93 additions & 9 deletions plugins/account_history_plugin/account_history_plugin.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <eos/account_history_plugin/account_history_plugin.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>
#include <eos/chain/chain_controller.hpp>
#include <eos/chain/config.hpp>
Expand Down Expand Up @@ -36,6 +37,7 @@ class account_history_plugin_impl {
public:
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;
void applied_block(const signed_block&);

chain_plugin* chain_plug;
Expand All @@ -55,12 +57,25 @@ class account_history_plugin_impl {

optional<block_id_type> find_block_id(const chainbase::database& db, const transaction_id_type& transaction_id) const;
ProcessedTransaction find_transaction(const chain::transaction_id_type& transaction_id, const signed_block& block) const;
ProcessedTransaction find_transaction(const chain::transaction_id_type& transaction_id, const block_id_type& block_id) const;
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);
bool time_exceeded(const fc::time_point& start_time) const;
static const AccountName NEW_ACCOUNT;
static const AccountName UPDATE_AUTH;
static const AccountName DELETE_AUTH;
static const PermissionName OWNER;
static const PermissionName ACTIVE;
static const PermissionName RECOVERY;
};
const int64_t account_history_plugin_impl::DEFAULT_TRANSACTION_TIME_LIMIT = 3;
const AccountName account_history_plugin_impl::NEW_ACCOUNT = "newaccount";
const AccountName account_history_plugin_impl::UPDATE_AUTH = "updateauth";
const AccountName account_history_plugin_impl::DELETE_AUTH = "deleteauth";
const PermissionName account_history_plugin_impl::OWNER = "owner";
const PermissionName account_history_plugin_impl::ACTIVE = "active";
const PermissionName account_history_plugin_impl::RECOVERY = "recovery";

optional<block_id_type> account_history_plugin_impl::find_block_id(const chainbase::database& db, const transaction_id_type& transaction_id) const
{
Expand All @@ -85,13 +100,6 @@ ProcessedTransaction account_history_plugin_impl::find_transaction(const chain::
FC_THROW("Transaction with ID ${tid} was indexed as being in block ID ${bid}, but was not found in that block", ("tid", transaction_id)("bid", block.id()));
}

ProcessedTransaction account_history_plugin_impl::find_transaction(const chain::transaction_id_type& transaction_id, const chain::block_id_type& block_id) const
{
auto block = chain_plug->chain().fetch_block_by_id(block_id);
FC_ASSERT(block, "Transaction with ID ${tid} was indexed as being in block ID ${bid}, but no such block was found", ("tid", transaction_id)("bid", block_id));
return find_transaction(transaction_id, *block);
}

ProcessedTransaction account_history_plugin_impl::get_transaction(const chain::transaction_id_type& transaction_id) const
{
const auto& db = chain_plug->chain().get_database();
Expand All @@ -101,7 +109,9 @@ ProcessedTransaction account_history_plugin_impl::get_transaction(const chain::t
} );
if( block_id.valid() )
{
return find_transaction(transaction_id, *block_id);
auto block = chain_plug->chain().fetch_block_by_id(*block_id);
FC_ASSERT(block, "Transaction with ID ${tid} was indexed as being in block ID ${bid}, but no such block was found", ("tid", transaction_id)("bid", block_id));
return find_transaction(transaction_id, *block);
}

#warning TODO: lookup of recent transactions
Expand Down Expand Up @@ -227,13 +237,30 @@ bool account_history_plugin_impl::time_exceeded(const fc::time_point& start_time
return (fc::time_point::now() - start_time).count() > transactions_time_limit;
}

vector<AccountName> account_history_plugin_impl::get_key_accounts(const public_key_type& public_key) const
{
std::set<AccountName> accounts;
const auto& db = chain_plug->chain().get_database();
db.with_read_lock( [&]() {
const auto& pub_key_idx = db.get_index<public_key_history_multi_index, by_pub_key>();
auto range = pub_key_idx.equal_range( public_key );
for (auto obj = range.first; obj != range.second; ++obj)
{
accounts.insert(obj->account_name);
}
} );
return vector<AccountName>(accounts.begin(), accounts.end());
}

void account_history_plugin_impl::applied_block(const signed_block& block)
{
const auto block_id = block.id();
auto& db = chain_plug->chain().get_mutable_database();
const bool check_relevance = filter_on.size();
for (const auto& cycle : block.cycles)
{
for (const auto& thread : cycle)
{
for (const auto& trx : thread.user_input)
{
if (check_relevance && !is_scope_relevant(trx.scope))
Expand All @@ -251,7 +278,59 @@ void account_history_plugin_impl::applied_block(const signed_block& block)
account_transaction_history.transaction_id = trx.id();
});
}

for (const chain::Message& msg : trx.messages)
{
if (msg.code == config::EosContractName)
{
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);
}
else if (msg.type == UPDATE_AUTH)
{
const auto update = msg.as<types::updateauth>();
remove(db, update.account, update.permission);
add(db, update.authority.keys, update.account, update.permission);
}
else if (msg.type == DELETE_AUTH)
{
const auto del = msg.as<types::deleteauth>();
remove(db, del.account, del.permission);
}
}
}
}
}
}
}

void account_history_plugin_impl::add(chainbase::database& db, const vector<types::KeyPermissionWeight>& keys, const AccountName& account_name, const PermissionName& permission)
{
for (auto pub_key_weight : keys )
{
db.create<public_key_history_object>([&](public_key_history_object& obj) {
obj.public_key = pub_key_weight.key;
obj.account_name = account_name;
obj.permission = permission;
});
}
}

void account_history_plugin_impl::remove(chainbase::database& db, 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)
{
mutatable_acct_perm_idx.remove(*acct_perm);
}
}

bool account_history_plugin_impl::is_scope_relevant(const eos::types::Vector<AccountName>& scope)
Expand Down Expand Up @@ -300,6 +379,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_transaction_history_multi_index>();
db.add_index<public_key_history_multi_index>();
db.add_index<transaction_history_multi_index>();

my->chain_plug->chain().applied_block.connect ([&impl = my](const signed_block& block) {
Expand All @@ -324,5 +404,9 @@ read_only::get_transactions_results read_only::get_transactions(const read_only:
return account_history->get_transactions(params.account_name, params.skip_seq, params.num_seq);
}

read_only::get_key_accounts_results read_only::get_key_accounts(const get_key_accounts_params& params) const
{
return { account_history->get_key_accounts(params.public_key) };
}
} // namespace account_history_apis
} // namespace eos
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ class read_only {
chain::transaction_id_type transaction_id;
fc::variant transaction;
};

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 @@ -51,6 +51,14 @@ 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;
};

class read_write {
Expand Down Expand Up @@ -89,3 +97,5 @@ FC_REFLECT(eos::account_history_apis::read_only::get_transaction_results, (trans
FC_REFLECT(eos::account_history_apis::read_only::get_transactions_params, (account_name)(skip_seq)(num_seq) )
FC_REFLECT(eos::account_history_apis::read_only::ordered_transaction_results, (seq_num)(transaction_id)(transaction) )
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) )
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once

#include <chainbase/chainbase.hpp>
#include <fc/array.hpp>

namespace std {

template<>
struct hash<eos::chain::public_key_type>
{
size_t operator()( const eos::chain::public_key_type& key ) const
{
std::hash<fc::ecc::public_key_data> hash;
return hash(key.key_data);
}
};
}

namespace eos {
using chain::AccountName;
using chain::public_key_type;
using chain::PermissionName;
using namespace boost::multi_index;

class public_key_history_object : public chainbase::object<chain::public_key_history_object_type, public_key_history_object> {
OBJECT_CTOR(public_key_history_object)

id_type id;
public_key_type public_key;
AccountName account_name;
PermissionName permission;
};

struct by_id;
struct by_pub_key;
struct by_account_permission;
using public_key_history_multi_index = chainbase::shared_multi_index_container<
public_key_history_object,
indexed_by<
ordered_unique<tag<by_id>, BOOST_MULTI_INDEX_MEMBER(public_key_history_object, public_key_history_object::id_type, id)>,
hashed_non_unique<tag<by_pub_key>, BOOST_MULTI_INDEX_MEMBER(public_key_history_object, public_key_type, public_key), std::hash<public_key_type> >,
hashed_non_unique<tag<by_account_permission>,
composite_key< public_key_history_object,
member<public_key_history_object, AccountName, &public_key_history_object::account_name>,
member<public_key_history_object, PermissionName, &public_key_history_object::permission>
>,
composite_key_hash<
std::hash<AccountName>,
std::hash<PermissionName>
>
>
>
>;

typedef chainbase::generic_index<public_key_history_multi_index> public_key_history_index;

}

CHAINBASE_SET_INDEX_TYPE( eos::public_key_history_object, eos::public_key_history_multi_index )

FC_REFLECT( eos::public_key_history_object, (public_key)(account_name)(permission) )

19 changes: 19 additions & 0 deletions programs/eosc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const string get_account_func = chain_func_base + "/get_account";
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";

inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
std::sort( names.begin(), names.end() );
Expand Down Expand Up @@ -130,6 +131,15 @@ void create_account( const vector<string>& cmd_line ) {
transaction_helpers::emplace_message(trx, config::EosContractName, vector<types::AccountPermission>{{creator,"active"}}, "newaccount",
types::newaccount{creator, newaccount, owner_auth,
active_auth, recovery_auth, deposit});
if (creator == "inita")
{
fc::optional<fc::ecc::private_key> private_key = eos::utilities::wif_to_key("5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3");
if (private_key)
{
wlog("public key ${k}",("k", private_key->get_public_key()));
trx.sign(*private_key, eos::chain::chain_id_type{});
}
}

std::cout << fc::json::to_pretty_string( push_transaction(trx) ) << std::endl;

Expand Down Expand Up @@ -386,6 +396,15 @@ int send_command (const vector<string> &cmd_line)
? fc::mutable_variant_object( "account_name", account_name)("skip_seq", cmd_line[2])
: fc::mutable_variant_object( "account_name", account_name)("skip_seq", cmd_line[2])("num_seq", cmd_line[3]);
std::cout << fc::json::to_pretty_string( call( get_transactions_func, arg) ) << std::endl;
} else if( command == "accounts" ) {
if( cmd_line.size() != 2 )
{
std::cerr << "usage: " << program << " accounts PUBLIC_KEY\n";
return -1;
}
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;
}
return 0;
}
Expand Down

0 comments on commit d41c7cc

Please sign in to comment.