Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

New intrinsic: set_action_return_value #8327

Merged
merged 10 commits into from
Dec 19, 2019
9 changes: 8 additions & 1 deletion libraries/chain/apply_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void apply_context::exec_one()
const account_metadata_object* receiver_account = nullptr;
try {
try {
action_return_value.clear();
receiver_account = &db.get<account_metadata_object,by_name>( receiver );
privileged = receiver_account->is_privileged();
auto native = control.find_apply_handler( receiver, act->account, act->name );
Expand Down Expand Up @@ -143,7 +144,13 @@ void apply_context::exec_one()
r.auth_sequence[auth.actor] = next_auth_sequence( auth.actor );
}

trx_context.executed_action_receipt_digests.emplace_back( r.digest() );
uint32_t version = 0;
if( control.is_builtin_activated( builtin_protocol_feature_t::action_return_value ) ) {
set_field( version, builtin_protocol_feature_t::action_return_value, true );
r.return_value.emplace( std::move( action_return_value ) );
}

trx_context.executed_action_receipt_digests.emplace_back( r.digest( version ) );

finalize_trace( trace, start );

Expand Down
8 changes: 8 additions & 0 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ struct controller_impl {
set_activation_handler<builtin_protocol_feature_t::get_sender>();
set_activation_handler<builtin_protocol_feature_t::webauthn_key>();
set_activation_handler<builtin_protocol_feature_t::wtmsig_block_signatures>();
set_activation_handler<builtin_protocol_feature_t::action_return_value>();

self.irreversible_block.connect([this](const block_state_ptr& bsp) {
wasmif.current_lib(bsp->block_num);
Expand Down Expand Up @@ -3301,6 +3302,13 @@ void controller_impl::on_activation<builtin_protocol_feature_t::wtmsig_block_sig
} );
}

template<>
void controller_impl::on_activation<builtin_protocol_feature_t::action_return_value>() {
db.modify( db.get<protocol_state_object>(), [&]( auto& ps ) {
add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "set_action_return_value" );
} );
}



/// End of protocol feature activation handlers
Expand Down
23 changes: 21 additions & 2 deletions libraries/chain/include/eosio/chain/action_receipt.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <eosio/chain/types.hpp>
#include <eosio/chain/protocol_feature_manager.hpp>

namespace eosio { namespace chain {

Expand All @@ -15,10 +16,28 @@ namespace eosio { namespace chain {
flat_map<account_name,uint64_t> auth_sequence;
fc::unsigned_int code_sequence = 0; ///< total number of setcodes
fc::unsigned_int abi_sequence = 0; ///< total number of setabis
fc::optional<std::vector<char>> return_value; ///< return value of the action

digest_type digest()const { return digest_type::hash(*this); }
/// @param version of digest to calculate
/// 0 for original version
/// set_field( version, builtin_protocol_feature_t::action_return_value, true ) for version of digest with return_value
digest_type digest(uint32_t version)const {
digest_type::encoder e;
fc::raw::pack(e, receiver);
fc::raw::pack(e, act_digest);
fc::raw::pack(e, global_sequence);
fc::raw::pack(e, recv_sequence);
fc::raw::pack(e, auth_sequence);
fc::raw::pack(e, code_sequence);
fc::raw::pack(e, abi_sequence);
if( has_field( version, builtin_protocol_feature_t::action_return_value ) ) {
fc::raw::pack(e, return_value);
}
return e.result();
}
};

} } /// namespace eosio::chain

FC_REFLECT( eosio::chain::action_receipt, (receiver)(act_digest)(global_sequence)(recv_sequence)(auth_sequence)(code_sequence)(abi_sequence) )
FC_REFLECT( eosio::chain::action_receipt,
(receiver)(act_digest)(global_sequence)(recv_sequence)(auth_sequence)(code_sequence)(abi_sequence)(return_value) )
1 change: 1 addition & 0 deletions libraries/chain/include/eosio/chain/apply_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ class apply_context {
bool context_free = false;

public:
std::vector<char> action_return_value;
generic_index<index64_object> idx64;
generic_index<index128_object> idx128;
generic_index<index256_object, uint128_t*, const uint128_t*> idx256;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum class builtin_protocol_feature_t : uint32_t {
ram_restrictions,
webauthn_key,
wtmsig_block_signatures,
action_return_value,
};

struct protocol_feature_subjective_restrictions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ constexpr auto intrinsic_table = boost::hana::make_tuple(
"eosio_injection._eosio_i32_to_f64"_s,
"eosio_injection._eosio_i64_to_f64"_s,
"eosio_injection._eosio_ui32_to_f64"_s,
"eosio_injection._eosio_ui64_to_f64"_s
"eosio_injection._eosio_ui64_to_f64"_s,
"env.set_action_return_value"_s
);

}}}
11 changes: 11 additions & 0 deletions libraries/chain/protocol_feature_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,17 @@ and may have additional signatures in a block extension with ID `2`.
Privileged Contracts:
may continue to use `set_proposed_producers` as they have;
may use a new `set_proposed_producers_ex` intrinsic to access extended features.
*/
{}
} )
( builtin_protocol_feature_t::action_return_value, builtin_protocol_feature_spec{
"ACTION_RETURN_VALUE",
fc::variant("69b064c5178e2738e144ed6caa9349a3995370d78db29e494b3126ebd9111966").as<digest_type>(),
// SHA256 hash of the raw message below within the comment delimiters (do not modify message below).
/*
Builtin protocol feature: ACTION_RETURN_VALUE

Enables new `set_action_return_value` intrinsic which sets a value that is included in action_receipt.
*/
{}
} )
Expand Down
5 changes: 5 additions & 0 deletions libraries/chain/wasm_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,10 @@ class action_api : public context_aware_api {
name current_receiver() {
return context.get_receiver();
}

void set_action_return_value( array_ptr<char> packed_blob, uint32_t datalen ) {
context.action_return_value.assign( packed_blob.value, packed_blob.value + datalen );
}
};

class console_api : public context_aware_api {
Expand Down Expand Up @@ -1964,6 +1968,7 @@ REGISTER_INTRINSICS(action_api,
(read_action_data, int(int, int) )
(action_data_size, int() )
(current_receiver, int64_t() )
(set_action_return_value,void(int, int) )
);

REGISTER_INTRINSICS(authorization_api,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,14 +531,21 @@ datastream<ST>& operator<<(datastream<ST>& ds, const history_serial_wrapper<eosi

template <typename ST>
datastream<ST>& operator<<(datastream<ST>& ds, const history_serial_wrapper<eosio::chain::action_receipt>& obj) {
fc::raw::pack(ds, fc::unsigned_int(0));
if (!obj.obj.return_value) {
fc::raw::pack( ds, fc::unsigned_int( 0 ));
} else {
fc::raw::pack( ds, fc::unsigned_int( 1 ));
}
fc::raw::pack(ds, as_type<uint64_t>(obj.obj.receiver.to_uint64_t()));
fc::raw::pack(ds, as_type<eosio::chain::digest_type>(obj.obj.act_digest));
fc::raw::pack(ds, as_type<uint64_t>(obj.obj.global_sequence));
fc::raw::pack(ds, as_type<uint64_t>(obj.obj.recv_sequence));
history_serialize_container(ds, obj.db, as_type<flat_map<eosio::name, uint64_t>>(obj.obj.auth_sequence));
fc::raw::pack(ds, as_type<fc::unsigned_int>(obj.obj.code_sequence));
fc::raw::pack(ds, as_type<fc::unsigned_int>(obj.obj.abi_sequence));
if (obj.obj.return_value) {
fc::raw::pack(ds, as_type<eosio::bytes>(*obj.obj.return_value));
}
return ds;
}

Expand Down
14 changes: 13 additions & 1 deletion plugins/state_history_plugin/state_history_plugin_abi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ extern const char* const state_history_plugin_abi = R"({
{ "name": "abi_sequence", "type": "varuint32" }
]
},
{
"name": "action_receipt_v1", "fields": [
{ "name": "receiver", "type": "name" },
{ "name": "act_digest", "type": "checksum256" },
{ "name": "global_sequence", "type": "uint64" },
{ "name": "recv_sequence", "type": "uint64" },
{ "name": "auth_sequence", "type": "account_auth_sequence[]" },
{ "name": "code_sequence", "type": "varuint32" },
{ "name": "abi_sequence", "type": "varuint32" },
{ "name": "return_value", "type": "bytes" }
]
},
{
"name": "account_delta", "fields": [
{ "name": "account", "type": "name" },
Expand Down Expand Up @@ -500,7 +512,7 @@ extern const char* const state_history_plugin_abi = R"({
{ "name": "request", "types": ["get_status_request_v0", "get_blocks_request_v0", "get_blocks_ack_request_v0"] },
{ "name": "result", "types": ["get_status_result_v0", "get_blocks_result_v0"] },

{ "name": "action_receipt", "types": ["action_receipt_v0"] },
{ "name": "action_receipt", "types": ["action_receipt_v0", "action_receipt_v1"] },
{ "name": "action_trace", "types": ["action_trace_v0"] },
{ "name": "partial_transaction", "types": ["partial_transaction_v0"] },
{ "name": "transaction_trace", "types": ["transaction_trace_v0"] },
Expand Down
Loading