未验证 提交 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 @@
#include <boost/algorithm/string.hpp>
#include <boost/signals2/connection.hpp>
namespace eosio {
namespace eosio {
using namespace chain;
using boost::signals2::scoped_connection;
......@@ -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 >
......@@ -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 >
......@@ -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));
......@@ -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 );
......@@ -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();
......@@ -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;
}
......@@ -440,13 +440,31 @@ 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));
......@@ -454,12 +472,9 @@ namespace eosio {
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;
......@@ -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;
......@@ -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;
......
......@@ -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
......@@ -67,7 +55,7 @@ class read_only {
struct get_transaction_params {
transaction_id_type id;
string id;
optional<uint32_t> block_num_hint;
};
......@@ -81,7 +69,7 @@ class read_only {
};
get_transaction_result get_transaction( const get_transaction_params& )const;
......@@ -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:
......
......@@ -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);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册