mirror of
https://github.com/AntelopeIO/spring.git
synced 2026-07-23 15:03:39 +00:00
158 lines
6.9 KiB
C++
158 lines
6.9 KiB
C++
#include <eosio/trace_api/request_handler.hpp>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <fc/variant_object.hpp>
|
|
|
|
namespace {
|
|
using namespace eosio::trace_api;
|
|
|
|
std::string to_iso8601_datetime( const fc::time_point& t) {
|
|
return t.to_iso_string() + "Z";
|
|
}
|
|
|
|
fc::variants process_authorizations(const std::vector<authorization_trace_v0>& authorizations) {
|
|
fc::variants result;
|
|
result.reserve(authorizations.size());
|
|
for ( const auto& a: authorizations) {
|
|
result.emplace_back(fc::mutable_variant_object()
|
|
("account", a.account.to_string())
|
|
("permission", a.permission.to_string())
|
|
);
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
template<typename ActionTrace>
|
|
fc::variants process_actions(const std::vector<ActionTrace>& actions, const data_handler_function & data_handler) {
|
|
fc::variants result;
|
|
result.reserve(actions.size());
|
|
// create a vector of indices to sort based on actions to avoid copies
|
|
std::vector<int> indices(actions.size());
|
|
std::iota(indices.begin(), indices.end(), 0);
|
|
std::sort(indices.begin(), indices.end(), [&actions](const int& lhs, const int& rhs) -> bool {
|
|
return actions.at(lhs).global_sequence < actions.at(rhs).global_sequence;
|
|
});
|
|
for ( int index : indices) {
|
|
const auto& a = actions.at(index);
|
|
auto action_variant = fc::mutable_variant_object();
|
|
|
|
action_variant("global_sequence", a.global_sequence)
|
|
("receiver", a.receiver.to_string())
|
|
("account", a.account.to_string())
|
|
("action", a.action.to_string())
|
|
("authorization", process_authorizations(a.authorization))
|
|
("data", fc::to_hex(a.data.data(), a.data.size()));
|
|
|
|
if constexpr(std::is_same_v<ActionTrace, action_trace_v0>){
|
|
auto [params, return_data] = data_handler(a);
|
|
if (!params.is_null()) {
|
|
action_variant("params", params);
|
|
}
|
|
}
|
|
else if constexpr(std::is_same_v<ActionTrace, action_trace_v1>){
|
|
action_variant("return_value", fc::to_hex(a.return_value.data(),a.return_value.size())) ;
|
|
auto [params, return_data] = data_handler(a);
|
|
if (!params.is_null()) {
|
|
action_variant("params", params);
|
|
}
|
|
if(return_data.has_value()){
|
|
action_variant("return_data", *return_data);
|
|
}
|
|
}
|
|
result.emplace_back( std::move(action_variant) );
|
|
}
|
|
return result;
|
|
}
|
|
|
|
template<typename TransactionTrace>
|
|
fc::variants process_transactions(const std::vector<TransactionTrace>& transactions, const data_handler_function& data_handler) {
|
|
fc::variants result;
|
|
result.reserve(transactions.size());
|
|
for ( const auto& t: transactions) {
|
|
if constexpr(std::is_same_v<TransactionTrace, transaction_trace_v0>){
|
|
result.emplace_back(
|
|
fc::mutable_variant_object()
|
|
("id", t.id.str())
|
|
("actions", process_actions<action_trace_v0>(t.actions, data_handler)));
|
|
} else {
|
|
auto common_mvo = fc::mutable_variant_object();
|
|
common_mvo("status", t.status)
|
|
("cpu_usage_us", t.cpu_usage_us)
|
|
("net_usage_words", t.net_usage_words)
|
|
("signatures", t.signatures)
|
|
("transaction_header", t.trx_header);
|
|
if constexpr(std::is_same_v<TransactionTrace, transaction_trace_v1>){
|
|
result.emplace_back(
|
|
fc::mutable_variant_object()
|
|
("id", t.id.str())
|
|
("actions", process_actions<action_trace_v0>(t.actions, data_handler))
|
|
(std::move(common_mvo)));
|
|
}
|
|
else if constexpr(std::is_same_v<TransactionTrace, transaction_trace_v2>){
|
|
result.emplace_back(
|
|
fc::mutable_variant_object()
|
|
("id", t.id.str())
|
|
("actions", process_actions<action_trace_v1>(std::get<std::vector<action_trace_v1>>(t.actions), data_handler))
|
|
(std::move(common_mvo)));
|
|
}
|
|
else if constexpr(std::is_same_v<TransactionTrace, transaction_trace_v3>){
|
|
result.emplace_back(
|
|
fc::mutable_variant_object()
|
|
("id", t.id.str())
|
|
("block_num", t.block_num)
|
|
("block_time", t.block_time)
|
|
("producer_block_id", t.producer_block_id)
|
|
("actions", process_actions<action_trace_v1>(std::get<std::vector<action_trace_v1>>(t.actions), data_handler))
|
|
(std::move(common_mvo))
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
namespace eosio::trace_api::detail {
|
|
fc::variant response_formatter::process_block( const data_log_entry& trace, bool irreversible, const data_handler_function& data_handler ) {
|
|
auto common_mvo = std::visit([&](auto&& arg) -> fc::mutable_variant_object {
|
|
return fc::mutable_variant_object()
|
|
("id", arg.id.str())
|
|
("number", arg.number )
|
|
("previous_id", arg.previous_id.str())
|
|
("status", irreversible ? "irreversible" : "pending" )
|
|
("timestamp", to_iso8601_datetime(arg.timestamp))
|
|
("producer", arg.producer.to_string());}, trace);
|
|
if (std::holds_alternative<block_trace_v0> (trace)){
|
|
auto& block_trace = std::get<block_trace_v0>(trace);
|
|
return fc::mutable_variant_object()
|
|
(std::move(common_mvo))
|
|
("transactions", process_transactions<transaction_trace_v0>(block_trace.transactions, data_handler ));
|
|
}else if(std::holds_alternative<block_trace_v1>(trace)){
|
|
auto& block_trace = std::get<block_trace_v1>(trace);
|
|
return fc::mutable_variant_object()
|
|
(std::move(common_mvo))
|
|
("transaction_mroot", block_trace.transaction_mroot)
|
|
("action_mroot", block_trace.action_mroot)
|
|
("schedule_version", block_trace.schedule_version)
|
|
("transactions", process_transactions<transaction_trace_v1>( block_trace.transactions_v1, data_handler )) ;
|
|
}else if(std::holds_alternative<block_trace_v2>(trace)){
|
|
auto& block_trace = std::get<block_trace_v2>(trace);
|
|
auto transactions = std::visit([&](auto&& arg){
|
|
return process_transactions(arg, data_handler);
|
|
}, block_trace.transactions);
|
|
return fc::mutable_variant_object()
|
|
(std::move(common_mvo))
|
|
("transaction_mroot", block_trace.transaction_mroot)
|
|
("action_mroot", block_trace.action_mroot)
|
|
("schedule_version", block_trace.schedule_version)
|
|
("transactions", transactions) ;
|
|
}else{
|
|
return fc::mutable_variant_object();
|
|
}
|
|
}
|
|
}
|