未验证 提交 2efc7861 编写于 作者: A arhag 提交者: GitHub

Merge pull request #5723 from EOSIO/5589-fix-get-transaction-bug

 fix history_plugin get_transaction bug
Subproject commit b3816115eb5452dbce1c62c0cb7c2d98233ae0f2 Subproject commit 4dc8375d7d3e02ab1177ab5c22835f75b45c845a
Subproject commit 270e1f9ee63004578c82a2fe594b81afd84c1631 Subproject commit e7d6948d242a9931436c38275d59a9c6036c4095
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/signals2/connection.hpp> #include <boost/signals2/connection.hpp>
namespace eosio { namespace eosio {
using namespace chain; using namespace chain;
using boost::signals2::scoped_connection; using boost::signals2::scoped_connection;
...@@ -51,7 +51,7 @@ namespace eosio { ...@@ -51,7 +51,7 @@ namespace eosio {
indexed_by< indexed_by<
ordered_unique<tag<by_id>, member<action_history_object, action_history_object::id_type, &action_history_object::id>>, 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_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, composite_key< action_history_object,
member<action_history_object, transaction_id_type, &action_history_object::trx_id>, member<action_history_object, transaction_id_type, &action_history_object::trx_id>,
member<action_history_object, uint64_t, &action_history_object::action_sequence_num > member<action_history_object, uint64_t, &action_history_object::action_sequence_num >
...@@ -64,7 +64,7 @@ namespace eosio { ...@@ -64,7 +64,7 @@ namespace eosio {
account_history_object, account_history_object,
indexed_by< indexed_by<
ordered_unique<tag<by_id>, member<account_history_object, account_history_object::id_type, &account_history_object::id>>, 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, composite_key< account_history_object,
member<account_history_object, account_name, &account_history_object::account >, member<account_history_object, account_name, &account_history_object::account >,
member<account_history_object, int32_t, &account_history_object::account_sequence_num > member<account_history_object, int32_t, &account_history_object::account_sequence_num >
...@@ -213,7 +213,7 @@ namespace eosio { ...@@ -213,7 +213,7 @@ namespace eosio {
uint64_t asn = 0; uint64_t asn = 0;
if( itr != idx.begin() ) --itr; if( itr != idx.begin() ) --itr;
if( itr->account == n ) if( itr->account == n )
asn = itr->account_sequence_num + 1; asn = itr->account_sequence_num + 1;
//idump((n)(act.receipt.global_sequence)(asn)); //idump((n)(act.receipt.global_sequence)(asn));
...@@ -268,7 +268,7 @@ namespace eosio { ...@@ -268,7 +268,7 @@ namespace eosio {
aho.block_time = chain.pending_block_time(); aho.block_time = chain.pending_block_time();
aho.trx_id = at.trx_id; aho.trx_id = at.trx_id;
}); });
auto aset = account_set( at ); auto aset = account_set( at );
for( auto a : aset ) { for( auto a : aset ) {
record_account_action( a, at ); record_account_action( a, at );
...@@ -366,7 +366,7 @@ namespace eosio { ...@@ -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 { read_only::get_actions_result read_only::get_actions( const read_only::get_actions_params& params )const {
edump((params)); edump((params));
auto& chain = history->chain_plug->chain(); auto& chain = history->chain_plug->chain();
...@@ -388,7 +388,7 @@ namespace eosio { ...@@ -388,7 +388,7 @@ namespace eosio {
pos = itr->account_sequence_num+1; pos = itr->account_sequence_num+1;
} else if( itr != idx.begin() ) --itr; } else if( itr != idx.begin() ) --itr;
if( itr->account == n ) if( itr->account == n )
pos = itr->account_sequence_num + 1; pos = itr->account_sequence_num + 1;
} }
...@@ -440,13 +440,31 @@ namespace eosio { ...@@ -440,13 +440,31 @@ namespace eosio {
read_only::get_transaction_result read_only::get_transaction( const read_only::get_transaction_params& p )const { read_only::get_transaction_result read_only::get_transaction( const read_only::get_transaction_params& p )const {
auto& chain = history->chain_plug->chain(); auto& chain = history->chain_plug->chain();
const auto abi_serializer_max_time = history->chain_plug->get_abi_serializer_max_time(); 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& db = chain.db();
const auto& idx = db.get_index<action_history_index, by_trx_id>(); 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 ) { 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)); EOS_THROW(tx_not_found, "Transaction ${id} not found in history and no block hint was given", ("id",p.id));
...@@ -454,12 +472,9 @@ namespace eosio { ...@@ -454,12 +472,9 @@ namespace eosio {
get_transaction_result result; get_transaction_result result;
if (in_history) { if( in_history ) {
result.id = p.id;
result.last_irreversible_block = chain.last_irreversible_block_num();
result.id = itr->trx_id; result.id = itr->trx_id;
result.last_irreversible_block = chain.last_irreversible_block_num();
result.block_num = itr->block_num; result.block_num = itr->block_num;
result.block_time = itr->block_time; result.block_time = itr->block_time;
...@@ -509,7 +524,7 @@ namespace eosio { ...@@ -509,7 +524,7 @@ namespace eosio {
if (receipt.trx.contains<packed_transaction>()) { if (receipt.trx.contains<packed_transaction>()) {
auto& pt = receipt.trx.get<packed_transaction>(); auto& pt = receipt.trx.get<packed_transaction>();
auto mtrx = transaction_metadata(pt); 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.id = mtrx.id;
result.last_irreversible_block = chain.last_irreversible_block_num(); result.last_irreversible_block = chain.last_irreversible_block_num();
result.block_num = *p.block_num_hint; result.block_num = *p.block_num_hint;
...@@ -522,7 +537,7 @@ namespace eosio { ...@@ -522,7 +537,7 @@ namespace eosio {
} }
} else { } else {
auto& id = receipt.trx.get<transaction_id_type>(); 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.id = id;
result.last_irreversible_block = chain.last_irreversible_block_num(); result.last_irreversible_block = chain.last_irreversible_block_num();
result.block_num = *p.block_num_hint; result.block_num = *p.block_num_hint;
......
...@@ -30,18 +30,6 @@ class read_only { ...@@ -30,18 +30,6 @@ class read_only {
: history(history) {} : 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 { struct get_actions_params {
chain::account_name account_name; chain::account_name account_name;
optional<int32_t> pos; /// a absolute sequence positon -1 is the end/last action optional<int32_t> pos; /// a absolute sequence positon -1 is the end/last action
...@@ -67,7 +55,7 @@ class read_only { ...@@ -67,7 +55,7 @@ class read_only {
struct get_transaction_params { struct get_transaction_params {
transaction_id_type id; string id;
optional<uint32_t> block_num_hint; optional<uint32_t> block_num_hint;
}; };
...@@ -81,7 +69,7 @@ class read_only { ...@@ -81,7 +69,7 @@ class read_only {
}; };
get_transaction_result get_transaction( const get_transaction_params& )const; get_transaction_result get_transaction( const get_transaction_params& )const;
...@@ -120,13 +108,13 @@ class read_only { ...@@ -120,13 +108,13 @@ class read_only {
/** /**
* This plugin tracks all actions and keys associated with a set of configured accounts. It enables * 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: * An action will be included in the account's history if any of the following:
* - receiver * - receiver
* - any account named in auth list * - 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> { class history_plugin : public plugin<history_plugin> {
public: public:
......
...@@ -2133,12 +2133,7 @@ int main( int argc, char** argv ) { ...@@ -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("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->add_option( "-b,--block-hint", block_num_hint, localized("the block number this transaction may be in") );
getTransaction->set_callback([&] { getTransaction->set_callback([&] {
transaction_id_type transaction_id; auto arg= fc::mutable_variant_object( "id", transaction_id_str);
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);
if ( block_num_hint > 0 ) { if ( block_num_hint > 0 ) {
arg = arg("block_num_hint", block_num_hint); arg = arg("block_num_hint", block_num_hint);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册