Skip to content

Commit

Permalink
Merge pull request #1280 from AntelopeIO/GH-1197-get-transaction-id-h…
Browse files Browse the repository at this point in the history
…ex-data

[4.0] if actions.data & actions.hex_data provided, use the hex_data in api call get_transaction_id
  • Loading branch information
vladtr authored Jun 15, 2023
2 parents b9c2e73 + e165ba9 commit 88c9d3f
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
49 changes: 49 additions & 0 deletions plugins/chain_api_plugin/chain_api_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,55 @@ parse_params<chain_apis::read_only::get_transaction_status_params, http_params_t
}
}

// if actions.data & actions.hex_data provided, use the hex_data since only currently support unexploded data
template<>
chain_apis::read_only::get_transaction_id_params
parse_params<chain_apis::read_only::get_transaction_id_params, http_params_types::params_required>(const std::string& body) {
if (body.empty()) {
EOS_THROW(chain::invalid_http_request, "A Request body is required");
}

try {
fc::variant trx_var = fc::json::from_string( body );
if( trx_var.is_object() ) {
fc::variant_object& vo = trx_var.get_object();
if( vo.contains("actions") && vo["actions"].is_array() ) {
fc::mutable_variant_object mvo = vo;
fc::variants& action_variants = mvo["actions"].get_array();
for( auto& action_v : action_variants ) {
if( action_v.is_object() ) {
fc::variant_object& action_vo = action_v.get_object();
if( action_vo.contains( "data" ) && action_vo.contains( "hex_data" ) ) {
fc::mutable_variant_object maction_vo = action_vo;
maction_vo["data"] = maction_vo["hex_data"];
action_vo = maction_vo;
vo = mvo;
} else if( action_vo.contains( "data" ) ) {
if( !action_vo["data"].is_string() ) {
EOS_THROW(chain::invalid_http_request, "Request supports only un-exploded 'data' (hex form)");
}
}
}
else {
EOS_THROW(chain::invalid_http_request, "Transaction contains invalid or empty action");
}
}
}
else {
EOS_THROW(chain::invalid_http_request, "Transaction actions are missing or invalid");
}
}
else {
EOS_THROW(chain::invalid_http_request, "Transaction object is missing or invalid");
}
auto trx = trx_var.as<chain_apis::read_only::get_transaction_id_params>();
if( trx.id() == transaction().id() ) {
EOS_THROW(chain::invalid_http_request, "Invalid transaction object");
}
return trx;
} EOS_RETHROW_EXCEPTIONS(chain::invalid_http_request, "Invalid transaction");
}

#define CALL_WITH_400(api_name, api_handle, api_namespace, call_name, http_response_code, params_type) \
{std::string("/v1/" #api_name "/" #call_name), \
[api_handle](string&&, string&& body, url_response_callback&& cb) mutable { \
Expand Down
46 changes: 46 additions & 0 deletions tests/plugin_http_api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,35 @@ def test_ChainApi(self) :
ret_json = self.nodeos.processUrllibRequest(resource, command, self.http_post_invalid_param)
self.assertEqual(ret_json["code"], 400)
self.assertEqual(ret_json["error"]["code"], 3200006)
# get_transaction_id with missing actions
payload_no_actions = {"expiration":"2020-08-01T07:15:49",
"ref_block_num": 34881,
"ref_block_prefix":2972818865,
"max_net_usage_words":0,
"max_cpu_usage_ms":0,
"delay_sec":0,
"context_free_actions":[],
"transaction_extensions": [],
"signatures": ["SIG_K1_KeqfqiZu1GwUxQb7jzK9Fdks6HFaVBQ9AJtCZZj56eG9qGgvVMVtx8EerBdnzrhFoX437sgwtojf2gfz6S516Ty7c22oEp"],
"context_free_data": []}
ret_json = self.nodeos.processUrllibRequest(resource, command, payload_no_actions)
self.assertEqual(ret_json["code"], 400)
self.assertEqual(ret_json["error"]["code"], 3200006)
# get_transaction_id with invalid actions
payload_invalid_actions = {"expiration":"2020-08-01T07:15:49",
"ref_block_num": 34881,
"ref_block_prefix":2972818865,
"max_net_usage_words":0,
"max_cpu_usage_ms":0,
"delay_sec":0,
"context_free_actions":[],
"actions": "hello_world",
"transaction_extensions": [],
"signatures": ["SIG_K1_KeqfqiZu1GwUxQb7jzK9Fdks6HFaVBQ9AJtCZZj56eG9qGgvVMVtx8EerBdnzrhFoX437sgwtojf2gfz6S516Ty7c22oEp"],
"context_free_data": []}
ret_json = self.nodeos.processUrllibRequest(resource, command, payload_invalid_actions)
self.assertEqual(ret_json["code"], 400)
self.assertEqual(ret_json["error"]["code"], 3200006)
# get_transaction_id with valid parameter
payload = {"expiration":"2020-08-01T07:15:49",
"ref_block_num": 34881,
Expand All @@ -614,6 +643,23 @@ def test_ChainApi(self) :
"context_free_data": []}
ret_str = self.nodeos.processUrllibRequest(resource, command, payload, returnType=ReturnType.raw).decode('ascii')
self.assertEqual(ret_str, "\"0be762a6406bab15530e87f21e02d1c58e77944ee55779a76f4112e3b65cac48\"")
# transaction that has hex_data
payload_hex = {"expiration":"2020-08-01T07:15:49",
"ref_block_num": 34881,
"ref_block_prefix":2972818865,
"max_net_usage_words":0,
"max_cpu_usage_ms":0,
"delay_sec":0,
"context_free_actions":[],
"actions":[{"account":"eosio.token","name": "transfer","authorization": [{"actor": "han","permission": "active"}],
"data": "{\"entry\":774831,\"miner\":\"eosminer1111\",\"nonce\":139429}\"}",
"hex_data": "000000000000a6690000000000ea305501000000000000000453595300000000016d"}],
"transaction_extensions": [],
"signatures": ["SIG_K1_KeqfqiZu1GwUxQb7jzK9Fdks6HFaVBQ9AJtCZZj56eG9qGgvVMVtx8EerBdnzrhFoX437sgwtojf2gfz6S516Ty7c22oEp"],
"context_free_data": []}
ret_str = self.nodeos.processUrllibRequest(resource, command, payload_hex, returnType=ReturnType.raw).decode('ascii')
self.assertEqual(ret_str, "\"0be762a6406bab15530e87f21e02d1c58e77944ee55779a76f4112e3b65cac48\"")


# push_block with empty parameter
command = "push_block"
Expand Down
2 changes: 1 addition & 1 deletion tests/read_only_trx_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ def chainApiTests():
runReadOnlyTrxAndRpcInParallel("chain", "get_currency_balance", code=200, payload = {"code":"eosio.token", "account":testAccountName})
runReadOnlyTrxAndRpcInParallel("chain", "get_currency_stats", fieldIn="SYS", payload = {"code":"eosio.token", "symbol":"SYS"})
runReadOnlyTrxAndRpcInParallel("chain", "get_required_keys", code=400)
runReadOnlyTrxAndRpcInParallel("chain", "get_transaction_id", code=200, payload = {"ref_block_num":"1"})
runReadOnlyTrxAndRpcInParallel("chain", "get_transaction_id", code=400, payload = {"ref_block_num":"1"})
runReadOnlyTrxAndRpcInParallel("chain", "push_block", code=202, payload = {"block":"signed_block"})
runReadOnlyTrxAndRpcInParallel("chain", "get_producer_schedule", "active")
runReadOnlyTrxAndRpcInParallel("chain", "get_scheduled_transactions", "transactions", payload = {"json":"true","lower_bound":""})
Expand Down

0 comments on commit 88c9d3f

Please sign in to comment.