提交 581aaefe 编写于 作者: D Daniel Larimer

get transaction works

 - any transaction which results in an action trace being logged by the
 history plugin can be queried by get_transaction
 - support for short trx ids of at least first 8 characters (lower bound used)
 - return the trx receipt, block number, last irr block, and traces for
 actions that executed as a result of the transaction
上级 9cc476fa
......@@ -97,7 +97,7 @@ namespace impl {
return std::is_base_of<transaction, T>::value ||
std::is_same<T, packed_transaction>::value ||
std::is_same<T, action_trace>::value ||
// std::is_same<T, transaction_trace>::value ||
std::is_same<T, signed_transaction>::value ||
std::is_same<T, action>::value;
}
......
......@@ -48,6 +48,7 @@ void history_api_plugin::plugin_startup() {
app().get_plugin<http_plugin>().add_api({
// CHAIN_RO_CALL(get_transaction),
CHAIN_RO_CALL(get_actions),
CHAIN_RO_CALL(get_transaction),
// CHAIN_RO_CALL(get_key_accounts),
// CHAIN_RO_CALL(get_controlled_accounts)
});
......
......@@ -30,6 +30,7 @@ namespace eosio {
shared_vector<char> packed_action_trace;
uint32_t block_num;
block_timestamp_type block_time;
transaction_id_type trx_id;
};
using account_history_id_type = account_history_object::id_type;
using action_history_id_type = action_history_object::id_type;
......@@ -37,12 +38,19 @@ namespace eosio {
struct by_action_sequence_num;
struct by_account_action_seq;
struct by_trx_id;
using action_history_index = chainbase::shared_multi_index_container<
action_history_object,
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_action_sequence_num>, member<action_history_object, uint64_t, &action_history_object::action_sequence_num>>,
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 >
>
>
>
>;
......@@ -129,6 +137,7 @@ namespace eosio {
aho.action_sequence_num = at.receipt.global_sequence;
aho.block_num = chain.pending_block_state()->block_num;
aho.block_time = chain.pending_block_time();
aho.trx_id = at.trx_id;
});
auto aset = account_set( at );
......@@ -199,7 +208,7 @@ namespace eosio {
auto& chain = history->chain_plug->chain();
const auto& db = chain.db();
const auto& idx = db.get_index<account_history_index, by_account_action_seq>();
const auto& idx = db.get_index<account_history_index, by_account_action_seq>();
int32_t start = 0;
int32_t pos = params.pos ? *params.pos : -1;
......@@ -261,7 +270,66 @@ namespace eosio {
}
return result;
}
read_only::get_transaction_result read_only::get_transaction( const read_only::get_transaction_params& p )const {
auto& chain = history->chain_plug->chain();
get_transaction_result result;
result.id = p.id;
result.last_irreversible_block = chain.last_irreversible_block_num();
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) );
if( itr == idx.end() ) {
return result;
}
result.id = itr->trx_id;
result.block_num = itr->block_num;
result.block_time = itr->block_time;
if( fc::variant(result.id).as_string().substr(0,8) != fc::variant(p.id).as_string().substr(0,8) )
return result;
while( itr != idx.end() && itr->trx_id == result.id ) {
fc::datastream<const char*> ds( itr->packed_action_trace.data(), itr->packed_action_trace.size() );
action_trace t;
fc::raw::unpack( ds, t );
result.traces.emplace_back( chain.to_variant_with_abi(t) );
++itr;
}
auto blk = chain.fetch_block_by_number( result.block_num );
for( const auto& receipt: blk->transactions ) {
if( receipt.trx.contains<packed_transaction>() ) {
auto& pt = receipt.trx.get<packed_transaction>();
auto mtrx = transaction_metadata(pt);
if( mtrx.id == result.id ) {
fc::mutable_variant_object r( "receipt", receipt );
r( "trx", chain.to_variant_with_abi(mtrx.trx) );
result.trx = move(r);
break;
}
} else {
auto& id = receipt.trx.get<transaction_id_type>();
if( id == result.id ) {
fc::mutable_variant_object r( "receipt", receipt );
result.trx = move(r);
break;
}
}
}
return result;
}
} /// history_apis
} /// namespace eosio
......@@ -66,6 +66,24 @@ class read_only {
get_actions_result get_actions( const get_actions_params& )const;
struct get_transaction_params {
transaction_id_type id;
};
struct get_transaction_result {
transaction_id_type id;
fc::variant trx;
chain::block_timestamp_type block_time;
uint32_t block_num = 0;
uint32_t last_irreversible_block = 0;
vector<fc::variant> traces;
};
get_transaction_result get_transaction( const get_transaction_params& )const;
/*
struct ordered_transaction_results {
uint32_t seq_num;
......@@ -133,6 +151,9 @@ class history_plugin : public plugin<history_plugin> {
FC_REFLECT( eosio::history_apis::read_only::get_actions_params, (account_name)(pos)(offset) )
FC_REFLECT( eosio::history_apis::read_only::get_actions_result, (actions)(last_irreversible_block)(time_limit_exceeded_error) )
FC_REFLECT( eosio::history_apis::read_only::ordered_action_result, (global_action_seq)(account_action_seq)(block_num)(block_time)(action_trace) )
FC_REFLECT( eosio::history_apis::read_only::get_transaction_params, (id) )
FC_REFLECT( eosio::history_apis::read_only::get_transaction_result, (id)(trx)(block_time)(block_num)(last_irreversible_block)(traces) )
/*
FC_REFLECT(eosio::history_apis::read_only::get_transaction_params, (transaction_id) )
FC_REFLECT(eosio::history_apis::read_only::get_transaction_results, (transaction_id)(transaction) )
......
......@@ -25,9 +25,9 @@ namespace eosio { namespace client { namespace http {
const string history_func_base = "/v1/history";
const string get_actions_func = history_func_base + "/get_actions";
const string get_transaction_func = history_func_base + "/get_transaction";
const string account_history_func_base = "/v1/account_history";
const string get_transaction_func = account_history_func_base + "/get_transaction";
const string get_transactions_func = account_history_func_base + "/get_transactions";
const string get_key_accounts_func = account_history_func_base + "/get_key_accounts";
const string get_controlled_accounts_func = account_history_func_base + "/get_controlled_accounts";
......
......@@ -1089,9 +1089,10 @@ int main( int argc, char** argv ) {
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( "transaction_id", transaction_id);
auto arg= fc::mutable_variant_object( "id", transaction_id);
std::cout << fc::json::to_pretty_string(call(get_transaction_func, arg)) << std::endl;
});
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册