Skip to content

Commit

Permalink
add processing of GeneratedTransaction sharing code where possible. ref
Browse files Browse the repository at this point in the history
  • Loading branch information
wanderingbort committed Aug 25, 2017
1 parent d432b6c commit d54bc83
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 44 deletions.
79 changes: 48 additions & 31 deletions libraries/chain/chain_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ std::vector<block_id_type> chain_controller::get_block_ids_on_fork(block_id_type
return result;
}

const GeneratedTransaction& chain_controller::get_generated_transaction( const generated_transaction_id_type& id ) const {
auto& index = _db.get_index<generated_transaction_multi_index, generated_transaction_object::by_trx_id>();
auto itr = index.find(id);
FC_ASSERT(itr != index.end());
return itr->trx;
}

/**
* Push block "may fail" in which case every partial change is unwound. After
* push block is successful the block is appended to the chain database on disk.
Expand Down Expand Up @@ -247,7 +254,7 @@ ProcessedTransaction chain_controller::_push_transaction(const SignedTransaction
auto temp_session = _db.start_undo_session(true);
validate_referenced_accounts(trx);
check_transaction_authorization(trx);
auto pt = _apply_transaction(trx);
auto pt = apply_transaction(trx);
_pending_transactions.push_back(trx);

// notify_changed_objects();
Expand Down Expand Up @@ -297,7 +304,7 @@ signed_block chain_controller::_generate_block(
FC_ASSERT( producer_obj.signing_key == block_signing_private_key.get_public_key() );


auto& generated = _db.get_index<generated_transaction_multi_index, generated_transaction_object::by_trx_id>();
const auto& generated = _db.get_index<generated_transaction_multi_index, generated_transaction_object::by_status>().equal_range(generated_transaction_object::PENDING);

vector<pending_transaction> pending;
std::set<transaction_id_type> invalid_pending;
Expand Down Expand Up @@ -348,11 +355,12 @@ signed_block chain_controller::_generate_block(
const auto& t = trx.get<std::reference_wrapper<const SignedTransaction>>().get();
validate_referenced_accounts(t);
check_transaction_authorization(t);
auto processed = _apply_transaction(t);
auto processed = apply_transaction(t);
block_thread.user_input.emplace_back(processed);
} else if (trx.contains<std::reference_wrapper<const GeneratedTransaction>>()) {
// auto processed = _apply_transaction(trx.get<std::reference_wrapper<const GeneratedTransaction>>().get());
// block_thread.generated_input.emplace_back(processed);
const auto& t = trx.get<std::reference_wrapper<const GeneratedTransaction>>().get();
auto processed = apply_transaction(t);
block_thread.generated_input.emplace_back(processed);
} else {
FC_THROW_EXCEPTION(tx_scheduling_exception, "Unknown transaction type in block_schedule");
}
Expand Down Expand Up @@ -516,10 +524,12 @@ void chain_controller::_apply_block(const signed_block& next_block)
*/
for (const auto& cycle : next_block.cycles) {
for (const auto& thread : cycle) {
for(const auto& trx : thread.generated_input ) {
for(const auto& ptrx : thread.generated_input ) {
auto const trx = get_generated_transaction(ptrx.id);
apply_transaction(trx);
}
for(const auto& trx : thread.user_input ) {
_apply_transaction(trx);
apply_transaction(trx);
}
}
}
Expand Down Expand Up @@ -578,11 +588,6 @@ void chain_controller::check_transaction_authorization(const SignedTransaction&
"Transaction bears irrelevant signatures from these keys: ${keys}", ("keys", checker.unused_keys()));
}

ProcessedTransaction chain_controller::apply_transaction(const SignedTransaction& trx, uint32_t skip)
{
return with_skip_flags( skip, [&]() { return _apply_transaction(trx); });
}

void chain_controller::validate_scope( const Transaction& trx )const {
EOS_ASSERT(trx.scope.size() > 0, transaction_exception, "No scope specified by transaction" );
for( uint32_t i = 1; i < trx.scope.size(); ++i )
Expand Down Expand Up @@ -621,6 +626,22 @@ void chain_controller::validate_uniqueness( const GeneratedTransaction& trx )con
if( !should_check_for_duplicate_transactions() ) return;
}

void chain_controller::record_transaction(const SignedTransaction& trx) {
//Insert transaction into unique transactions database.
_db.create<transaction_object>([&](transaction_object& transaction) {
transaction.trx_id = trx.id(); /// TODO: consider caching ID
transaction.trx = trx;
});
}

void chain_controller::record_transaction(const GeneratedTransaction& trx) {
_db.modify( _db.get<generated_transaction_object,generated_transaction_object::by_trx_id>(trx.id), [&](generated_transaction_object& transaction) {
transaction.status = generated_transaction_object::PROCESSED;
});
}



void chain_controller::validate_tapos(const Transaction& trx)const {
if (!should_check_tapos()) return;

Expand Down Expand Up @@ -656,7 +677,7 @@ void chain_controller::validate_expiration(const Transaction& trx) const
} FC_CAPTURE_AND_RETHROW((trx)) }


void chain_controller::process_message(const ProcessedTransaction& trx, AccountName code,
void chain_controller::process_message(const Transaction& trx, AccountName code,
const Message& message, MessageOutput& output, apply_context* parent_context) {
apply_context apply_ctx(*this, _db, trx, message, code);
apply_message(apply_ctx);
Expand All @@ -678,7 +699,12 @@ void chain_controller::process_message(const ProcessedTransaction& trx, AccountN
}

for( auto& asynctrx : apply_ctx.async_transactions ) {
output.async_transactions.emplace_back( std::move( asynctrx ) );
_db.create<generated_transaction_object>([&](generated_transaction_object& transaction) {
transaction.trx = asynctrx;
transaction.status = generated_transaction_object::PENDING;
});

output.async_transactions.emplace_back( std::move( asynctrx ) );
}

// propagate used_authorizations up the context chain
Expand Down Expand Up @@ -715,40 +741,31 @@ void chain_controller::apply_message(apply_context& context)

} FC_CAPTURE_AND_RETHROW((context.msg)) }

ProcessedTransaction chain_controller::_apply_transaction(const SignedTransaction& trx)
template<typename T>
typename T::Processed chain_controller::apply_transaction(const T& trx)
{ try {
validate_transaction(trx);

//Insert transaction into unique transactions database.
if (should_check_for_duplicate_transactions())
{
_db.create<transaction_object>([&](transaction_object& transaction) {
transaction.trx_id = trx.id(); /// TODO: consider caching ID
transaction.trx = trx;
});
}

record_transaction(trx);
return process_transaction( trx );

} FC_CAPTURE_AND_RETHROW((trx)) }


/**
* @pre the transaction is assumed valid and all signatures / duplicate checks have bee performed
*/
ProcessedTransaction chain_controller::process_transaction( const SignedTransaction& trx )
template<typename T>
typename T::Processed chain_controller::process_transaction( const T& trx )
{ try {
ProcessedTransaction ptrx( trx );
typename T::Processed ptrx( trx );
ptrx.output.resize( trx.messages.size() );

for( uint32_t i = 0; i < ptrx.messages.size(); ++i ) {
process_message(ptrx, ptrx.messages[i].code, ptrx.messages[i], ptrx.output[i] );
for( uint32_t i = 0; i < trx.messages.size(); ++i ) {
process_message(trx, trx.messages[i].code, trx.messages[i], ptrx.output[i] );
}

return ptrx;
} FC_CAPTURE_AND_RETHROW( (trx) ) }


void chain_controller::require_account(const types::AccountName& name) const {
auto account = _db.find<account_object, by_name>(name);
FC_ASSERT(account != nullptr, "Account not found: ${name}", ("name", name));
Expand Down
29 changes: 18 additions & 11 deletions libraries/chain/include/eos/chain/chain_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,15 @@ namespace eos { namespace chain {
* @return true if the block is in our fork DB or saved to disk as
* part of the official chain, otherwise return false
*/
bool is_known_block( const block_id_type& id )const;
bool is_known_transaction( const transaction_id_type& id )const;
block_id_type get_block_id_for_num( uint32_t block_num )const;
optional<signed_block> fetch_block_by_id( const block_id_type& id )const;
optional<signed_block> fetch_block_by_number( uint32_t num )const;
const SignedTransaction& get_recent_transaction( const transaction_id_type& trx_id )const;
std::vector<block_id_type> get_block_ids_on_fork(block_id_type head_of_fork)const;
bool is_known_block( const block_id_type& id )const;
bool is_known_transaction( const transaction_id_type& id )const;
block_id_type get_block_id_for_num( uint32_t block_num )const;
optional<signed_block> fetch_block_by_id( const block_id_type& id )const;
optional<signed_block> fetch_block_by_number( uint32_t num )const;
const SignedTransaction& get_recent_transaction( const transaction_id_type& trx_id )const;
std::vector<block_id_type> get_block_ids_on_fork(block_id_type head_of_fork)const;
const GeneratedTransaction& get_generated_transaction( const generated_transaction_id_type& id ) const;


/**
* This method will convert a variant to a SignedTransaction using a contract's ABI to
Expand Down Expand Up @@ -275,9 +277,11 @@ namespace eos { namespace chain {

void check_transaction_authorization(const SignedTransaction& trx, bool allow_unused_signatures = false)const;

ProcessedTransaction apply_transaction(const SignedTransaction& trx, uint32_t skip = skip_nothing);
ProcessedTransaction _apply_transaction(const SignedTransaction& trx);
ProcessedTransaction process_transaction( const SignedTransaction& trx );
template<typename T>
typename T::Processed apply_transaction(const T& trx);

template<typename T>
typename T::Processed process_transaction(const T& trx);

void require_account(const AccountName& name) const;

Expand All @@ -304,6 +308,9 @@ namespace eos { namespace chain {
void validate_referenced_accounts(const Transaction& trx)const;
void validate_expiration(const Transaction& trx) const;
void validate_scope(const Transaction& trx) const;

void record_transaction(const SignedTransaction& trx);
void record_transaction(const GeneratedTransaction& trx);
/// @}

/**
Expand All @@ -318,7 +325,7 @@ namespace eos { namespace chain {
types::AccountName code_account,
types::FuncName type) const;

void process_message(const ProcessedTransaction& trx, AccountName code, const Message& message,
void process_message(const Transaction& trx, AccountName code, const Message& message,
MessageOutput& output, apply_context* parent_context = nullptr);
void apply_message(apply_context& c);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,31 @@ namespace eos { namespace chain {
{
OBJECT_CTOR(generated_transaction_object)

enum status_type {
PENDING = 0,
PROCESSED
};


id_type id;
GeneratedTransaction trx;
status_type status;

time_point_sec get_expiration()const { return trx.expiration; }
generated_transaction_id_type get_id() const { return trx.id; }

struct by_trx_id;
struct by_expiration;
struct by_status;
};

using generated_transaction_multi_index = chainbase::shared_multi_index_container<
generated_transaction_object,
indexed_by<
ordered_unique<tag<by_id>, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, generated_transaction_object::id_type, id)>,
hashed_unique<tag<generated_transaction_object::by_trx_id>, const_mem_fun<generated_transaction_object, generated_transaction_id_type, &generated_transaction_object::get_id>>,
ordered_non_unique<tag<generated_transaction_object::by_expiration>, const_mem_fun<generated_transaction_object, time_point_sec, &generated_transaction_object::get_expiration>>
ordered_non_unique<tag<generated_transaction_object::by_expiration>, const_mem_fun<generated_transaction_object, time_point_sec, &generated_transaction_object::get_expiration>>,
ordered_non_unique<tag<generated_transaction_object::by_status>, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, generated_transaction_object::status_type, status)>
>
>;

Expand Down
8 changes: 7 additions & 1 deletion libraries/chain/include/eos/chain/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ namespace eos { namespace chain {
* @{
*/

struct ProcessedTransaction;
struct ProcessedGeneratedTransaction;



/**
Expand Down Expand Up @@ -112,6 +115,8 @@ namespace eos { namespace chain {
generated_transaction_id_type id;

digest_type merkle_digest() const;

typedef ProcessedGeneratedTransaction Processed;
};

/**
Expand Down Expand Up @@ -144,9 +149,10 @@ namespace eos { namespace chain {
void clear() { transaction_helpers::clear(*this); signatures.clear(); }

digest_type merkle_digest() const;

typedef ProcessedTransaction Processed;
};

struct ProcessedTransaction;
struct NotifyOutput;


Expand Down

0 comments on commit d54bc83

Please sign in to comment.