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

Commit

Permalink
fix history_plugin get_transaction bug #5589
Browse files Browse the repository at this point in the history
  • Loading branch information
arhag committed Sep 18, 2018
1 parent 45e609f commit ae8edf2
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 40 deletions.
2 changes: 1 addition & 1 deletion libraries/fc
49 changes: 32 additions & 17 deletions plugins/history_plugin/history_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/signals2/connection.hpp>

namespace eosio {
namespace eosio {
using namespace chain;
using boost::signals2::scoped_connection;

Expand Down Expand Up @@ -51,7 +51,7 @@ namespace eosio {
indexed_by<
ordered_unique<tag<by_id>, member<action_history_object, action_history_object::id_type, &action_history_object::id>>,
ordered_unique<tag<by_action_sequence_num>, member<action_history_object, uint64_t, &action_history_object::action_sequence_num>>,
ordered_unique<tag<by_trx_id>,
ordered_unique<tag<by_trx_id>,
composite_key< action_history_object,
member<action_history_object, transaction_id_type, &action_history_object::trx_id>,
member<action_history_object, uint64_t, &action_history_object::action_sequence_num >
Expand All @@ -64,7 +64,7 @@ namespace eosio {
account_history_object,
indexed_by<
ordered_unique<tag<by_id>, member<account_history_object, account_history_object::id_type, &account_history_object::id>>,
ordered_unique<tag<by_account_action_seq>,
ordered_unique<tag<by_account_action_seq>,
composite_key< account_history_object,
member<account_history_object, account_name, &account_history_object::account >,
member<account_history_object, int32_t, &account_history_object::account_sequence_num >
Expand Down Expand Up @@ -213,7 +213,7 @@ namespace eosio {

uint64_t asn = 0;
if( itr != idx.begin() ) --itr;
if( itr->account == n )
if( itr->account == n )
asn = itr->account_sequence_num + 1;

//idump((n)(act.receipt.global_sequence)(asn));
Expand Down Expand Up @@ -268,7 +268,7 @@ namespace eosio {
aho.block_time = chain.pending_block_time();
aho.trx_id = at.trx_id;
});

auto aset = account_set( at );
for( auto a : aset ) {
record_account_action( a, at );
Expand Down Expand Up @@ -366,7 +366,7 @@ namespace eosio {



namespace history_apis {
namespace history_apis {
read_only::get_actions_result read_only::get_actions( const read_only::get_actions_params& params )const {
edump((params));
auto& chain = history->chain_plug->chain();
Expand All @@ -388,7 +388,7 @@ namespace eosio {
pos = itr->account_sequence_num+1;
} else if( itr != idx.begin() ) --itr;

if( itr->account == n )
if( itr->account == n )
pos = itr->account_sequence_num + 1;
}

Expand Down Expand Up @@ -440,26 +440,41 @@ namespace eosio {
read_only::get_transaction_result read_only::get_transaction( const read_only::get_transaction_params& p )const {
auto& chain = history->chain_plug->chain();
const auto abi_serializer_max_time = history->chain_plug->get_abi_serializer_max_time();
auto short_id = fc::variant(p.id).as_string().substr(0,8);

transaction_id_type input_id;
auto input_id_length = p.id.size();
try {
FC_ASSERT( input_id_length <= 64, "hex string is too long to represent an actual transaction id" );
FC_ASSERT( input_id_length >= 8, "hex string representing transaction id should be at least 8 characters long to avoid excessive collisions" );
input_id = transaction_id_type(p.id);
} EOS_RETHROW_EXCEPTIONS(transaction_id_type_exception, "Invalid transaction ID: ${transaction_id}", ("transaction_id", p.id))

auto txn_id_matched = [&input_id, input_id_size = input_id_length/2, no_half_byte_at_end = (input_id_length % 2 == 0)]
( const transaction_id_type &id ) -> bool // hex prefix comparison
{
bool whole_byte_prefix_matches = memcmp( input_id.data(), id.data(), input_id_size ) == 0;
if( !whole_byte_prefix_matches || no_half_byte_at_end )
return whole_byte_prefix_matches;

// check if half byte at end of specified part of input_id matches
return (*(input_id.data() + input_id_size) & 0xF0) == (*(id.data() + input_id_size) & 0xF0);
};

const auto& db = chain.db();
const auto& idx = db.get_index<action_history_index, by_trx_id>();
auto itr = idx.lower_bound( boost::make_tuple(p.id) );
auto itr = idx.lower_bound( boost::make_tuple( input_id ) );

bool in_history = (itr != idx.end() && fc::variant(itr->trx_id).as_string().substr(0,8) == short_id );
bool in_history = (itr != idx.end() && txn_id_matched(itr->trx_id) );

if( !in_history && !p.block_num_hint ) {
EOS_THROW(tx_not_found, "Transaction ${id} not found in history and no block hint was given", ("id",p.id));
}

get_transaction_result result;

if (in_history) {
result.id = p.id;
result.last_irreversible_block = chain.last_irreversible_block_num();


if( in_history ) {
result.id = itr->trx_id;
result.last_irreversible_block = chain.last_irreversible_block_num();
result.block_num = itr->block_num;
result.block_time = itr->block_time;

Expand Down Expand Up @@ -509,7 +524,7 @@ namespace eosio {
if (receipt.trx.contains<packed_transaction>()) {
auto& pt = receipt.trx.get<packed_transaction>();
auto mtrx = transaction_metadata(pt);
if (fc::variant(mtrx.id).as_string().substr(0, 8) == short_id) {
if( txn_id_matched(mtrx.id) ) {
result.id = mtrx.id;
result.last_irreversible_block = chain.last_irreversible_block_num();
result.block_num = *p.block_num_hint;
Expand All @@ -522,7 +537,7 @@ namespace eosio {
}
} else {
auto& id = receipt.trx.get<transaction_id_type>();
if (fc::variant(id).as_string().substr(0, 8) == short_id) {
if( txn_id_matched(id) ) {
result.id = id;
result.last_irreversible_block = chain.last_irreversible_block_num();
result.block_num = *p.block_num_hint;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,6 @@ class read_only {
: history(history) {}


/*
struct get_transaction_params {
chain::transaction_id_type transaction_id;
};
struct get_transaction_results {
chain::transaction_id_type transaction_id;
fc::variant transaction;
};
get_transaction_results get_transaction(const get_transaction_params& params) const;
*/


struct get_actions_params {
chain::account_name account_name;
optional<int32_t> pos; /// a absolute sequence positon -1 is the end/last action
Expand All @@ -67,7 +55,7 @@ class read_only {


struct get_transaction_params {
transaction_id_type id;
string id;
optional<uint32_t> block_num_hint;
};

Expand All @@ -81,7 +69,7 @@ class read_only {
};

get_transaction_result get_transaction( const get_transaction_params& )const;




Expand Down Expand Up @@ -120,13 +108,13 @@ class read_only {

/**
* This plugin tracks all actions and keys associated with a set of configured accounts. It enables
* wallets to paginate queries for history.
* wallets to paginate queries for history.
*
* An action will be included in the account's history if any of the following:
* - receiver
* - any account named in auth list
*
* A key will be linked to an account if the key is referneced in authorities of updateauth or newaccount
* A key will be linked to an account if the key is referneced in authorities of updateauth or newaccount
*/
class history_plugin : public plugin<history_plugin> {
public:
Expand Down
7 changes: 1 addition & 6 deletions programs/cleos/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2133,12 +2133,7 @@ int main( int argc, char** argv ) {
getTransaction->add_option("id", transaction_id_str, localized("ID of the transaction to retrieve"))->required();
getTransaction->add_option( "-b,--block-hint", block_num_hint, localized("the block number this transaction may be in") );
getTransaction->set_callback([&] {
transaction_id_type transaction_id;
try {
while( transaction_id_str.size() < 64 ) transaction_id_str += "0";
transaction_id = transaction_id_type(transaction_id_str);
} EOS_RETHROW_EXCEPTIONS(transaction_id_type_exception, "Invalid transaction ID: ${transaction_id}", ("transaction_id", transaction_id_str))
auto arg= fc::mutable_variant_object( "id", transaction_id);
auto arg= fc::mutable_variant_object( "id", transaction_id_str);
if ( block_num_hint > 0 ) {
arg = arg("block_num_hint", block_num_hint);
}
Expand Down

0 comments on commit ae8edf2

Please sign in to comment.