Skip to content

Commit

Permalink
Merge pull request #40 from AntelopeIO/restore-gbhs
Browse files Browse the repository at this point in the history
restore `get_block_header_state` endpoint for usage both pre and post Savanna activation
  • Loading branch information
spoonincode authored Apr 17, 2024
2 parents 21e66b5 + b89af83 commit adf5c38
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 0 deletions.
24 changes: 24 additions & 0 deletions plugins/chain_api_plugin/chain.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,30 @@ paths:
schema:
description: Returns Nothing

/get_block_header_state:
post:
description: Retrieves a block header state object with only block_num, id, header, and additional_signatures filled. Other fields are left empty or defaulted to a static value.
operationId: get_block_header_state
requestBody:
content:
application/json:
schema:
type: object
required:
- block_num_or_id
properties:
block_num_or_id:
type: string
description: Provide a block_number or a block_id

responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "https://docs.eosnetwork.com/openapi/v2.0/BlockHeaderState.yaml"

/get_abi:
post:
description: Retrieves the ABI for a contract based on its account name
Expand Down
1 change: 1 addition & 0 deletions plugins/chain_api_plugin/chain_api_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ void chain_api_plugin::plugin_startup() {
CHAIN_RO_CALL(get_activated_protocol_features, 200, http_params_types::possible_no_params),
CHAIN_RO_CALL_POST(get_block, fc::variant, 200, http_params_types::params_required), // _POST because get_block() returns a lambda to be executed on the http thread pool
CHAIN_RO_CALL(get_block_info, 200, http_params_types::params_required),
CHAIN_RO_CALL(get_block_header_state, 200, http_params_types::params_required),
CHAIN_RO_CALL_POST(get_account, chain_apis::read_only::get_account_results, 200, http_params_types::params_required),
CHAIN_RO_CALL(get_code, 200, http_params_types::params_required),
CHAIN_RO_CALL(get_code_hash, 200, http_params_types::params_required),
Expand Down
30 changes: 30 additions & 0 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <eosio/chain/permission_link_object.hpp>
#include <eosio/chain/global_property_object.hpp>
#include <eosio/chain/chainbase_environment.hpp>
#include <eosio/chain/block_header_state_utils.hpp>

#include <eosio/resource_monitor_plugin/resource_monitor_plugin.hpp>

Expand Down Expand Up @@ -2015,6 +2016,35 @@ fc::variant read_only::get_block_info(const read_only::get_block_info_params& pa
("ref_block_prefix", ref_block_prefix);
}

fc::variant read_only::get_block_header_state(const get_block_header_state_params& params, const fc::time_point&) const {
signed_block_ptr sbp;
std::optional<uint64_t> block_num;

try {
block_num = fc::to_uint64(params.block_num_or_id);
} catch( ... ) {}

if( block_num ) {
sbp = db.fetch_block_by_number(*block_num);
} else {
try {
sbp = db.fetch_block_by_id(block_id_type(params.block_num_or_id));
} EOS_RETHROW_EXCEPTIONS(chain::block_id_type_exception, "Invalid block ID: ${block_num_or_id}", ("block_num_or_id", params.block_num_or_id))
}

EOS_ASSERT( sbp, unknown_block_exception, "Could not find block: ${block}", ("block", params.block_num_or_id));

block_header_state_legacy ret;
ret.block_num = sbp->block_num();
ret.id = sbp->calculate_id();
ret.header = *sbp;
ret.additional_signatures = detail::extract_additional_signatures(sbp);

fc::variant vo;
fc::to_variant( ret, vo );
return vo;
}

void read_write::push_block(read_write::push_block_params&& params, next_function<read_write::push_block_results> next) {
try {
auto b = std::make_shared<signed_block>( std::move(params) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,12 @@ class read_only : public api_base {

fc::variant get_block_info(const get_block_info_params& params, const fc::time_point& deadline) const;

struct get_block_header_state_params {
string block_num_or_id;
};

fc::variant get_block_header_state(const get_block_header_state_params& params, const fc::time_point& deadline) const;

struct get_table_rows_params {
bool json = false;
name code;
Expand Down Expand Up @@ -1022,6 +1028,7 @@ FC_REFLECT(eosio::chain_apis::read_only::get_activated_protocol_features_params,
FC_REFLECT(eosio::chain_apis::read_only::get_activated_protocol_features_results, (activated_protocol_features)(more) )
FC_REFLECT(eosio::chain_apis::read_only::get_raw_block_params, (block_num_or_id))
FC_REFLECT(eosio::chain_apis::read_only::get_block_info_params, (block_num))
FC_REFLECT(eosio::chain_apis::read_only::get_block_header_state_params, (block_num_or_id))
FC_REFLECT(eosio::chain_apis::read_only::get_block_header_params, (block_num_or_id)(include_extensions))
FC_REFLECT(eosio::chain_apis::read_only::get_block_header_result, (id)(signed_block_header)(block_extensions))

Expand Down
45 changes: 45 additions & 0 deletions tests/plugin_http_api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,51 @@ def test_ChainApi(self) :
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
self.assertEqual(ret_json["payload"]["block_num"], 1)

# get_block_header_state with empty parameter
command = "get_block_header_state"
ret_json = self.nodeos.processUrllibRequest(resource, command, endpoint=endpoint)
self.assertEqual(ret_json["code"], 400)
self.assertEqual(ret_json["error"]["code"], 3200006)
# get_block_header_state with empty content parameter
ret_json = self.nodeos.processUrllibRequest(resource, command, self.empty_content_dict, endpoint=endpoint)
self.assertEqual(ret_json["code"], 400)
self.assertEqual(ret_json["error"]["code"], 3200006)
# get_block_header_state with invalid parameter
ret_json = self.nodeos.processUrllibRequest(resource, command, self.http_post_invalid_param, endpoint=endpoint)
self.assertEqual(ret_json["code"], 400)
self.assertEqual(ret_json["error"]["code"], 3200006)
self.nodeos.waitForNextBlock()
# get_block_header_state with reversible block
head_block_num = self.nodeos.getHeadBlockNum()
payload = {"block_num_or_id":head_block_num}
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
self.assertEqual(ret_json["payload"]["block_num"], head_block_num)
self.assertEqual(ret_json["payload"]["header"]["producer"], "eosio")
# and by id
ret_json = self.nodeos.processUrllibRequest(resource, command, {"block_num_or_id":ret_json["payload"]["id"]}, endpoint=endpoint)
self.assertEqual(ret_json["payload"]["block_num"], head_block_num)
self.assertEqual(ret_json["payload"]["header"]["producer"], "eosio")
# get_block_header_state with irreversible block
lib_block_num = self.nodeos.getIrreversibleBlockNum()
payload = {"block_num_or_id":lib_block_num}
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
self.assertEqual(ret_json["payload"]["block_num"], lib_block_num)
self.assertEqual(ret_json["payload"]["header"]["producer"], "eosio")
# and by id
ret_json = self.nodeos.processUrllibRequest(resource, command, {"block_num_or_id":ret_json["payload"]["id"]}, endpoint=endpoint)
self.assertEqual(ret_json["payload"]["block_num"], lib_block_num)
self.assertEqual(ret_json["payload"]["header"]["producer"], "eosio")
# get_block_header_state with block far in future
payload = {"block_num_or_id":head_block_num+2000000}
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
self.assertEqual(ret_json["code"], 400)
self.assertEqual(ret_json["error"]["code"], 3100002)
#invalid num and invalid sha256
payload = {"block_num_or_id":"spoon was here"}
ret_json = self.nodeos.processUrllibRequest(resource, command, payload, endpoint=endpoint)
self.assertEqual(ret_json["code"], 500)
self.assertEqual(ret_json["error"]["code"], 3010008)

# get_account with empty parameter
command = "get_account"
ret_json = self.nodeos.processUrllibRequest(resource, command, endpoint=endpoint)
Expand Down

0 comments on commit adf5c38

Please sign in to comment.