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

Commit

Permalink
Add transaction_metadata create_signing_keys_future method
Browse files Browse the repository at this point in the history
  • Loading branch information
heifner committed Dec 12, 2018
1 parent 98a8bc3 commit 659fc92
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 37 deletions.
2 changes: 1 addition & 1 deletion libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ add_library( eosio_chain
# contracts/chain_initializer.cpp


# transaction_metadata.cpp
transaction_metadata.cpp
${HEADERS}
)

Expand Down
26 changes: 7 additions & 19 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@
#include <eosio/chain/authorization_manager.hpp>
#include <eosio/chain/resource_limits.hpp>
#include <eosio/chain/chain_snapshot.hpp>
#include <eosio/chain/thread_utils.hpp>

#include <chainbase/chainbase.hpp>
#include <fc/io/json.hpp>
#include <fc/scoped_exit.hpp>
#include <fc/variant_object.hpp>

#include <boost/asio/thread_pool.hpp>
#include <boost/asio/post.hpp>


namespace eosio { namespace chain {

Expand Down Expand Up @@ -147,14 +145,6 @@ struct controller_impl {
*/
map<digest_type, transaction_metadata_ptr> unapplied_transactions;

// async on thread_pool and return future
template<typename F>
auto async_thread_pool( F&& f ) {
auto task = std::make_shared<std::packaged_task<decltype( f() )()>>( std::forward<F>( f ) );
boost::asio::post( thread_pool, [task]() { (*task)(); } );
return task->get_future();
}

void pop_block() {
auto prev = fork_db.get_block( head->header.previous );
EOS_ASSERT( prev, block_validate_exception, "attempt to pop beyond last irreversible block" );
Expand Down Expand Up @@ -1202,13 +1192,7 @@ struct controller_impl {
auto& pt = receipt.trx.get<packed_transaction>();
auto mtrx = std::make_shared<transaction_metadata>( std::make_shared<packed_transaction>( pt ) );
if( !self.skip_auth_check() ) {
std::weak_ptr<transaction_metadata> mtrx_wp = mtrx;
mtrx->signing_keys_future = async_thread_pool( [chain_id = this->chain_id, mtrx_wp]() {
auto mtrx = mtrx_wp.lock();
return mtrx ?
std::make_pair( chain_id, mtrx->trx.get_signature_keys( chain_id ) ) :
std::make_pair( chain_id, decltype( mtrx->trx.get_signature_keys( chain_id ) ){} );
} );
transaction_metadata::create_signing_keys_future( mtrx, thread_pool, chain_id );
}
packed_transactions.emplace_back( std::move( mtrx ) );
}
Expand Down Expand Up @@ -1286,7 +1270,7 @@ struct controller_impl {
auto prev = fork_db.get_block( b->previous );
EOS_ASSERT( prev, unlinkable_block_exception, "unlinkable block ${id}", ("id", id)("previous", b->previous) );

return async_thread_pool( [b, prev]() {
return async_thread_pool( thread_pool, [b, prev]() {
const bool skip_validate_signee = false;
return std::make_shared<block_state>( *prev, move( b ), skip_validate_signee );
} );
Expand Down Expand Up @@ -1780,6 +1764,10 @@ void controller::abort_block() {
my->abort_block();
}

boost::asio::thread_pool& controller::get_thread_pool() {
return my->thread_pool;
}

std::future<block_state_ptr> controller::create_block_state_future( const signed_block_ptr& b ) {
return my->create_block_state_future( b );
}
Expand Down
8 changes: 6 additions & 2 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
namespace chainbase {
class database;
}

namespace boost { namespace asio {
class thread_pool;
}}

namespace eosio { namespace chain {

Expand Down Expand Up @@ -87,7 +89,7 @@ namespace eosio { namespace chain {
incomplete = 3, ///< this is an incomplete block (either being produced by a producer or speculatively produced by a node)
};

controller( const config& cfg );
explicit controller( const config& cfg );
~controller();

void add_indices();
Expand Down Expand Up @@ -144,6 +146,8 @@ namespace eosio { namespace chain {
std::future<block_state_ptr> create_block_state_future( const signed_block_ptr& b );
void push_block( std::future<block_state_ptr>& block_state_future );

boost::asio::thread_pool& get_thread_pool();

const chainbase::database& db()const;

const fork_database& fork_db()const;
Expand Down
24 changes: 24 additions & 0 deletions libraries/chain/include/eosio/chain/thread_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once

#include <boost/asio/thread_pool.hpp>
#include <boost/asio/post.hpp>
#include <future>
#include <memory>

namespace eosio { namespace chain {

// async on thread_pool and return future
template<typename F>
auto async_thread_pool( boost::asio::thread_pool& thread_pool, F&& f ) {
auto task = std::make_shared<std::packaged_task<decltype( f() )()>>( std::forward<F>( f ) );
boost::asio::post( thread_pool, [task]() { (*task)(); } );
return task->get_future();
}

} } // eosio::chain


25 changes: 10 additions & 15 deletions libraries/chain/include/eosio/chain/transaction_metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
#include <eosio/chain/types.hpp>
#include <future>

namespace boost { namespace asio {
class thread_pool;
}}

namespace eosio { namespace chain {

class transaction_metadata;
using transaction_metadata_ptr = std::shared_ptr<transaction_metadata>;
/**
* This data structure should store context-free cached data about a transaction such as
* packed/unpacked/compressed and recovered keys
Expand Down Expand Up @@ -43,23 +49,12 @@ class transaction_metadata {
signed_id = digest_type::hash(*packed_trx);
}

const flat_set<public_key_type>& recover_keys( const chain_id_type& chain_id ) {
// Unlikely for more than one chain_id to be used in one nodeos instance
if( !signing_keys || signing_keys->first != chain_id ) {
if( signing_keys_future.valid() ) {
signing_keys = signing_keys_future.get();
if( signing_keys->first == chain_id ) {
return signing_keys->second;
}
}
signing_keys = std::make_pair( chain_id, trx.get_signature_keys( chain_id ));
}
return signing_keys->second;
}
const flat_set<public_key_type>& recover_keys( const chain_id_type& chain_id );

static void create_signing_keys_future( transaction_metadata_ptr& mtrx,
boost::asio::thread_pool& thread_pool, const chain_id_type& chain_id );

uint32_t total_actions()const { return trx.context_free_actions.size() + trx.actions.size(); }
};

using transaction_metadata_ptr = std::shared_ptr<transaction_metadata>;

} } // eosio::chain
34 changes: 34 additions & 0 deletions libraries/chain/transaction_metadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <eosio/chain/transaction_metadata.hpp>
#include <eosio/chain/thread_utils.hpp>
#include <boost/asio/thread_pool.hpp>

namespace eosio { namespace chain {


const flat_set<public_key_type>& transaction_metadata::recover_keys( const chain_id_type& chain_id ) {
// Unlikely for more than one chain_id to be used in one nodeos instance
if( !signing_keys || signing_keys->first != chain_id ) {
if( signing_keys_future.valid() ) {
signing_keys = signing_keys_future.get();
if( signing_keys->first == chain_id ) {
return signing_keys->second;
}
}
signing_keys = std::make_pair( chain_id, trx.get_signature_keys( chain_id ));
}
return signing_keys->second;
}

void transaction_metadata::create_signing_keys_future( transaction_metadata_ptr& mtrx,
boost::asio::thread_pool& thread_pool, const chain_id_type& chain_id ) {
std::weak_ptr<transaction_metadata> mtrx_wp = mtrx;
mtrx->signing_keys_future = async_thread_pool( thread_pool, [chain_id, mtrx_wp]() {
auto mtrx = mtrx_wp.lock();
return mtrx ?
std::make_pair( chain_id, mtrx->trx.get_signature_keys( chain_id ) ) :
std::make_pair( chain_id, decltype( mtrx->trx.get_signature_keys( chain_id ) ){} );
} );
}


} } // eosio::chain

0 comments on commit 659fc92

Please sign in to comment.