未验证 提交 3d061601 编写于 作者: K Kevin Heifner 提交者: GitHub

Merge pull request #1368 from wanderingbort/feature/abi-serializer-for-blocks

explode the results of get_block
......@@ -184,7 +184,7 @@ void chain_initializer::prepare_database( chain_controller& chain,
a.privileged = true;
if( name == config::system_account_name ) {
a.set_abi(eos_contract_abi());
a.set_abi(abi_def());
}
});
const auto& owner = db.create<permission_object>([&](permission_object& p) {
......
......@@ -5,6 +5,7 @@
#pragma once
#include <eosio/chain/contracts/types.hpp>
#include <eosio/chain/transaction.hpp>
#include <eosio/chain/block.hpp>
#include <fc/variant_object.hpp>
......@@ -74,7 +75,7 @@ struct abi_serializer {
template<typename Vec>
static bool to_abi(account_name account, const Vec& abi_vec, abi_def& abi)
{
if( !is_empty_abi(abi_vec) ) { /// 4 == packsize of empty Abi
if( !is_empty_abi(abi_vec) || account == eosio::chain::config::system_account_name ) { /// 4 == packsize of empty Abi
fc::datastream<const char*> ds( abi_vec.data(), abi_vec.size() );
fc::raw::unpack( ds, abi );
append_system_abi(account, abi);
......@@ -99,7 +100,10 @@ namespace impl {
std::is_same<T, packed_transaction>::value ||
std::is_same<T, action>::value ||
std::is_same<T, transaction_trace>::value ||
std::is_same<T, action_trace>::value;
std::is_same<T, action_trace>::value ||
std::is_same<T, shard_summary>::value ||
std::is_same<T, region_summary>::value ||
std::is_base_of<signed_block_summary, T>:: value;
}
/**
......
......@@ -358,18 +358,52 @@ fc::variant read_only::get_currency_stats( const read_only::get_currency_stats_p
return results;
}
read_only::get_block_results read_only::get_block(const read_only::get_block_params& params) const {
try {
if (auto block = db.fetch_block_by_id(fc::json::from_string(params.block_num_or_id).as<block_id_type>()))
return *block;
} catch (fc::bad_cast_exception) {/* do nothing */}
template<typename Api>
struct resolver_factory {
static auto make(const Api *api) {
return [api](const account_name &name) -> optional<abi_serializer> {
const auto *accnt = api->db.get_database().template find<account_object, by_name>(name);
if (accnt != nullptr) {
abi_def abi;
if (abi_serializer::to_abi(accnt->name, accnt->abi, abi)) {
return abi_serializer(abi);
}
}
return optional<abi_serializer>();
};
}
};
template<typename Api>
auto make_resolver(const Api *api) {
return resolver_factory<Api>::make(api);
}
fc::variant read_only::get_block(const read_only::get_block_params& params) const {
optional<signed_block> block;
try {
if (auto block = db.fetch_block_by_number(fc::to_uint64(params.block_num_or_id)))
return *block;
block = db.fetch_block_by_id(fc::json::from_string(params.block_num_or_id).as<block_id_type>());
if (!block) {
block = db.fetch_block_by_number(fc::to_uint64(params.block_num_or_id));
}
} catch (fc::bad_cast_exception) {/* do nothing */}
FC_THROW_EXCEPTION(unknown_block_exception,
if (!block)
FC_THROW_EXCEPTION(unknown_block_exception,
"Could not find block: ${block}", ("block", params.block_num_or_id));
fc::variant pretty_output;
abi_serializer::to_variant(*block, pretty_output, make_resolver(this));
return fc::mutable_variant_object(pretty_output.get_object())
("id", block->id())
("block_num",block->block_num())
("ref_block_prefix", block->id()._hash[1]);
}
read_write::push_block_results read_write::push_block(const read_write::push_block_params& params) {
......@@ -379,18 +413,7 @@ read_write::push_block_results read_write::push_block(const read_write::push_blo
read_write::push_transaction_results read_write::push_transaction(const read_write::push_transaction_params& params) {
packed_transaction pretty_input;
auto resolver = [&,this]( const account_name& name ) -> optional<abi_serializer> {
const auto* accnt = db.get_database().find<account_object,by_name>( name );
if (accnt != nullptr) {
abi_def abi;
if (abi_serializer::to_abi(accnt->name, accnt->abi, abi)) {
return abi_serializer(abi);
}
}
return optional<abi_serializer>();
};
auto resolver = make_resolver(this);
abi_serializer::from_variant(params, pretty_input, resolver);
auto result = db.push_transaction(pretty_input, skip_flags);
#warning TODO: get transaction results asynchronously
......
......@@ -41,6 +41,9 @@ struct permission {
authority required_auth;
};
template<typename>
struct resolver_factory;
class read_only {
const chain_controller& db;
......@@ -143,20 +146,7 @@ public:
string block_num_or_id;
};
struct get_block_results : public chain::signed_block {
get_block_results( const chain::signed_block& b )
:signed_block(b),
id(b.id()),
block_num(b.block_num()),
ref_block_prefix( id._hash[1] )
{}
chain::block_id_type id;
uint32_t block_num = 0;
uint32_t ref_block_prefix = 0;
};
get_block_results get_block(const get_block_params& params) const;
fc::variant get_block(const get_block_params& params) const;
struct get_table_rows_params {
bool json = false;
......@@ -292,7 +282,8 @@ public:
}
return result;
}
friend struct resolver_factory<read_only>;
};
class read_write {
......@@ -316,6 +307,8 @@ public:
using push_transactions_params = vector<push_transaction_params>;
using push_transactions_results = vector<push_transaction_results>;
push_transactions_results push_transactions(const push_transactions_params& params);
friend resolver_factory<read_write>;
};
} // namespace chain_apis
......@@ -365,7 +358,6 @@ FC_REFLECT(eosio::chain_apis::read_only::get_info_results,
(recent_slots)(participation_rate))
FC_REFLECT(eosio::chain_apis::read_only::get_block_params, (block_num_or_id))
FC_REFLECT_DERIVED( eosio::chain_apis::read_only::get_block_results, (eosio::chain::signed_block), (id)(block_num)(ref_block_prefix) );
FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) )
FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_params, (json)(code)(scope)(table)(table_key)(lower_bound)(upper_bound)(limit) )
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册