From 52e0ff188a115eecf876580a15fc71fd8d0de05e Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Sep 2019 18:08:16 -0400 Subject: [PATCH 1/3] add preactive_feature and is_feature_activated intrinsics --- libraries/eosiolib/capi/eosio/privileged.h | 11 ++++- libraries/eosiolib/capi/eosio/system.h | 9 ++++ .../eosiolib/contracts/eosio/privileged.hpp | 41 +++++++++++++------ libraries/eosiolib/contracts/eosio/system.hpp | 23 +++++++++++ libraries/native/intrinsics.cpp | 20 +++++---- .../native/native/eosio/intrinsics_def.hpp | 12 +++--- 6 files changed, 90 insertions(+), 26 deletions(-) diff --git a/libraries/eosiolib/capi/eosio/privileged.h b/libraries/eosiolib/capi/eosio/privileged.h index c304cf7b7a..523bf436a3 100644 --- a/libraries/eosiolib/capi/eosio/privileged.h +++ b/libraries/eosiolib/capi/eosio/privileged.h @@ -1,5 +1,5 @@ #pragma once - +#include "types.h" #ifdef __cplusplus extern "C" { #endif @@ -105,7 +105,14 @@ void set_blockchain_parameters_packed( char* data, uint32_t datalen ); __attribute__((eosio_wasm_import)) uint32_t get_blockchain_parameters_packed( char* data, uint32_t datalen ); +/** + * Pre-activate protocol feature + * + * @param feature_digest - digest of the protocol feature to pre-activate + */ +__attribute__((eosio_wasm_import)) +void preactivate_feature( const capi_checksum256* feature_digest ); + #ifdef __cplusplus } #endif - diff --git a/libraries/eosiolib/capi/eosio/system.h b/libraries/eosiolib/capi/eosio/system.h index 95186027dc..c1a6d818f9 100644 --- a/libraries/eosiolib/capi/eosio/system.h +++ b/libraries/eosiolib/capi/eosio/system.h @@ -76,6 +76,15 @@ void eosio_exit( int32_t code ); __attribute__((eosio_wasm_import)) uint64_t current_time(); +/** + * Check if specified protocol feature has been activated + * + * @param feature_digest - digest of the protocol feature + * @return true if the specified protocol feature has been activated, false otherwise + */ +__attribute__((eosio_wasm_import)) +bool is_feature_activated( const capi_checksum256* feature_digest ); + #ifdef __cplusplus } #endif diff --git a/libraries/eosiolib/contracts/eosio/privileged.hpp b/libraries/eosiolib/contracts/eosio/privileged.hpp index a17375fca2..89d84d391e 100644 --- a/libraries/eosiolib/contracts/eosio/privileged.hpp +++ b/libraries/eosiolib/contracts/eosio/privileged.hpp @@ -1,5 +1,6 @@ #pragma once #include "producer_schedule.hpp" +#include "system.hpp" #include "../../core/eosio/crypto.hpp" #include "../../core/eosio/name.hpp" #include "../../core/eosio/serialize.hpp" @@ -11,23 +12,26 @@ namespace eosio { __attribute__((eosio_wasm_import)) bool is_privileged( uint64_t account ); - __attribute__((eosio_wasm_import)) - void get_resource_limits( uint64_t account, int64_t* ram_bytes, int64_t* net_weight, int64_t* cpu_weight ); + __attribute__((eosio_wasm_import)) + void get_resource_limits( uint64_t account, int64_t* ram_bytes, int64_t* net_weight, int64_t* cpu_weight ); + + __attribute__((eosio_wasm_import)) + void set_resource_limits( uint64_t account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); - __attribute__((eosio_wasm_import)) - void set_resource_limits( uint64_t account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); + __attribute__((eosio_wasm_import)) + void set_privileged( uint64_t account, bool is_priv ); - __attribute__((eosio_wasm_import)) - void set_privileged( uint64_t account, bool is_priv ); + __attribute__((eosio_wasm_import)) + void set_blockchain_parameters_packed( char* data, uint32_t datalen ); - __attribute__((eosio_wasm_import)) - void set_blockchain_parameters_packed( char* data, uint32_t datalen ); + __attribute__((eosio_wasm_import)) + uint32_t get_blockchain_parameters_packed( char* data, uint32_t datalen ); - __attribute__((eosio_wasm_import)) - uint32_t get_blockchain_parameters_packed( char* data, uint32_t datalen ); + __attribute((eosio_wasm_import)) + int64_t set_proposed_producers( char*, uint32_t ); - __attribute((eosio_wasm_import)) - int64_t set_proposed_producers( char*, uint32_t ); + __attribute__((eosio_wasm_import)) + void preactivate_feature( const capi_checksum256* feature_digest ); } } @@ -246,4 +250,17 @@ namespace eosio { internal_use_do_not_use::set_privileged( account.value, is_priv ); } + /** + * Pre-activate protocol feature + * + * @ingroup privileged + * @param feature_digest - digest of the protocol feature to pre-activate + */ + inline void preactivate_feature( const checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + internal_use_do_not_use::preactivate_feature( + reinterpret_cast( feature_digest_data.data() ) + ); + } + } diff --git a/libraries/eosiolib/contracts/eosio/system.hpp b/libraries/eosiolib/contracts/eosio/system.hpp index a65f924319..64c48e8885 100644 --- a/libraries/eosiolib/contracts/eosio/system.hpp +++ b/libraries/eosiolib/contracts/eosio/system.hpp @@ -5,12 +5,20 @@ #pragma once #include "../../core/eosio/time.hpp" #include "../../core/eosio/check.hpp" +#include "../../core/eosio/fixed_bytes.hpp" namespace eosio { namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import, noreturn)) void eosio_exit( int32_t code ); + + struct __attribute__((aligned (16))) capi_checksum256 { + uint8_t hash[32]; + }; + + __attribute__((eosio_wasm_import)) + bool is_feature_activated( const capi_checksum256* feature_digest ); } } @@ -53,4 +61,19 @@ namespace eosio { * @return time in microseconds from 1970 of the current block as a block_timestamp */ block_timestamp current_block_time(); + + + /** + * Check if specified protocol feature has been activated + * + * @ingroup system + * @param feature_digest - digest of the protocol feature + * @return true if the specified protocol feature has been activated, false otherwise + */ + inline bool is_feature_activated( const checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + return internal_use_do_not_use::is_feature_activated( + reinterpret_cast( feature_digest_data.data() ) + ); + } } diff --git a/libraries/native/intrinsics.cpp b/libraries/native/intrinsics.cpp index adb68a6839..87ce058fd2 100644 --- a/libraries/native/intrinsics.cpp +++ b/libraries/native/intrinsics.cpp @@ -40,6 +40,12 @@ extern "C" { void set_privileged( capi_name account, bool is_priv ) { return intrinsics::get().call(account, is_priv); } + bool is_feature_activated( const capi_checksum256* feature_digest ) { + return intrinsics::get().call(feature_digest); + } + void preactivate_feature( const capi_checksum256* feature_digest ) { + return intrinsics::get().call(feature_digest); + } uint32_t get_active_producers( capi_name* producers, uint32_t datalen ) { return intrinsics::get().call(producers, datalen); } @@ -788,7 +794,7 @@ extern "C" { void printui(uint64_t value) { return intrinsics::get().call(value); } - + void printi128(const int128_t* value) { return intrinsics::get().call(value); } @@ -796,7 +802,7 @@ extern "C" { void printui128(const uint128_t* value) { return intrinsics::get().call(value); } - + void printsf(float value) { return intrinsics::get().call(value); } @@ -808,11 +814,11 @@ extern "C" { void printqf(const long double* value) { return intrinsics::get().call(value); } - + void printn(uint64_t nm) { return intrinsics::get().call(nm); } - + void printhex(const void* data, uint32_t len) { return intrinsics::get().call(data, len); } @@ -844,7 +850,7 @@ extern "C" { dest[i] = tmp_buf[i]; return (void*)dest; } - + void eosio_assert(uint32_t test, const char* msg) { if (test == 0) { _prints(msg, eosio::cdt::output_stream_kind::std_err); @@ -870,9 +876,9 @@ extern "C" { longjmp(*___env_ptr, 1); } } - + #pragma clang diagnostic push -#pragma clang diagnostic ignored "-Winvalid-noreturn" +#pragma clang diagnostic ignored "-Winvalid-noreturn" void abort() { eosio_assert(false, "abort"); } diff --git a/libraries/native/native/eosio/intrinsics_def.hpp b/libraries/native/native/eosio/intrinsics_def.hpp index a6f59098e9..a5303cfcf3 100644 --- a/libraries/native/native/eosio/intrinsics_def.hpp +++ b/libraries/native/native/eosio/intrinsics_def.hpp @@ -29,15 +29,15 @@ namespace eosio { namespace native { auto get_args(R(Args...)) { return std::tuple...>{}; } - + template auto create_function(std::index_sequence) { - return std::function::type ...)>{ - [](typename std::tuple_element::type ...) { + return std::function::type ...)>{ + [](typename std::tuple_element::type ...) { eosio_assert(false, "unsupported intrinsic"); return (R)0; } }; - } + } #define INTRINSICS(intrinsic_macro) \ intrinsic_macro(get_resource_limits) \ @@ -48,6 +48,8 @@ intrinsic_macro(get_blockchain_parameters_packed) \ intrinsic_macro(set_blockchain_parameters_packed) \ intrinsic_macro(is_privileged) \ intrinsic_macro(set_privileged) \ +intrinsic_macro(is_feature_activated) \ +intrinsic_macro(preactivate_feature) \ intrinsic_macro(get_active_producers) \ intrinsic_macro(db_idx64_store) \ intrinsic_macro(db_idx64_remove) \ @@ -154,7 +156,7 @@ intrinsic_macro(send_inline) \ intrinsic_macro(send_context_free_inline) \ intrinsic_macro(send_deferred) \ intrinsic_macro(cancel_deferred) \ -intrinsic_macro(get_context_free_data) +intrinsic_macro(get_context_free_data) #define CREATE_ENUM(name) \ name, From 628abd7b7b9a21d3d85378b84d5a1d0bf08eb7e2 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Sep 2019 18:22:21 -0400 Subject: [PATCH 2/3] Until the pruning unused imports fix is in CDT, I needed to move the implementation of the set_proposed_producers overload using the set_proposed_producers_ex intrinsic into an inline function defined in the header to prevent pulling in WASM imports that make the contract invalid on a pre-2.0 EOSIO chain. --- libraries/eosiolib/contracts/eosio/privileged.hpp | 11 ++++++++++- libraries/eosiolib/eosiolib.cpp | 10 ---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/libraries/eosiolib/contracts/eosio/privileged.hpp b/libraries/eosiolib/contracts/eosio/privileged.hpp index 89d84d391e..53f194ef09 100644 --- a/libraries/eosiolib/contracts/eosio/privileged.hpp +++ b/libraries/eosiolib/contracts/eosio/privileged.hpp @@ -32,6 +32,9 @@ namespace eosio { __attribute__((eosio_wasm_import)) void preactivate_feature( const capi_checksum256* feature_digest ); + + __attribute__((eosio_wasm_import)) + int64_t set_proposed_producers_ex( uint64_t producer_data_format, char *producer_data, uint32_t producer_data_size ); } } @@ -225,7 +228,13 @@ namespace eosio { * * @return an optional value of the version of the new proposed schedule if successful */ - std::optional set_proposed_producers( const std::vector& prods ); + inline std::optional set_proposed_producers( const std::vector& prods ) { + auto packed_prods = eosio::pack( prods ); + int64_t ret = internal_use_do_not_use::set_proposed_producers_ex(1, (char*)packed_prods.data(), packed_prods.size()); + if (ret >= 0) + return static_cast(ret); + return {}; + } /** * Check if an account is privileged diff --git a/libraries/eosiolib/eosiolib.cpp b/libraries/eosiolib/eosiolib.cpp index fb1bf9b165..b92bb10130 100644 --- a/libraries/eosiolib/eosiolib.cpp +++ b/libraries/eosiolib/eosiolib.cpp @@ -16,8 +16,6 @@ namespace eosio { __attribute__((eosio_wasm_import)) int64_t set_proposed_producers( char *producer_data, uint32_t producer_data_size ); __attribute__((eosio_wasm_import)) - int64_t set_proposed_producers_ex( uint64_t producer_data_format, char *producer_data, uint32_t producer_data_size ); - __attribute__((eosio_wasm_import)) uint32_t get_active_producers(uint64_t*, uint32_t); } @@ -45,14 +43,6 @@ namespace eosio { return {}; } - std::optional set_proposed_producers( const std::vector& prods ) { - auto packed_prods = eosio::pack( prods ); - int64_t ret = set_proposed_producers_ex(1, (char*)packed_prods.data(), packed_prods.size()); - if (ret >= 0) - return static_cast(ret); - return {}; - } - // system.hpp time_point current_time_point() { static auto ct = time_point(microseconds(static_cast(current_time()))); From b528a65e0119e93a5d729cfbe3e28d31d78f0ea8 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 17 Sep 2019 21:31:35 -0400 Subject: [PATCH 3/3] add get_sender intrinsic --- libraries/eosiolib/capi/eosio/system.h | 8 ++++++++ libraries/eosiolib/contracts/eosio/system.hpp | 14 ++++++++++++++ libraries/native/intrinsics.cpp | 3 +++ libraries/native/native/eosio/intrinsics_def.hpp | 3 ++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/libraries/eosiolib/capi/eosio/system.h b/libraries/eosiolib/capi/eosio/system.h index c1a6d818f9..b7b7cb63a1 100644 --- a/libraries/eosiolib/capi/eosio/system.h +++ b/libraries/eosiolib/capi/eosio/system.h @@ -85,6 +85,14 @@ uint64_t current_time(); __attribute__((eosio_wasm_import)) bool is_feature_activated( const capi_checksum256* feature_digest ); +/** + * Return name of account that sent current inline action + * + * @return name of account that sent the current inline action (empty name if not called from inline action) + */ +__attribute__((eosio_wasm_import)) +capi_name get_sender(); + #ifdef __cplusplus } #endif diff --git a/libraries/eosiolib/contracts/eosio/system.hpp b/libraries/eosiolib/contracts/eosio/system.hpp index 64c48e8885..5c5c21926b 100644 --- a/libraries/eosiolib/contracts/eosio/system.hpp +++ b/libraries/eosiolib/contracts/eosio/system.hpp @@ -6,6 +6,7 @@ #include "../../core/eosio/time.hpp" #include "../../core/eosio/check.hpp" #include "../../core/eosio/fixed_bytes.hpp" +#include "../../core/eosio/name.hpp" namespace eosio { namespace internal_use_do_not_use { @@ -19,6 +20,9 @@ namespace eosio { __attribute__((eosio_wasm_import)) bool is_feature_activated( const capi_checksum256* feature_digest ); + + __attribute__((eosio_wasm_import)) + uint64_t get_sender(); } } @@ -76,4 +80,14 @@ namespace eosio { reinterpret_cast( feature_digest_data.data() ) ); } + + /** + * Return name of account that sent current inline action + * + * @ingroup system + * @return name of account that sent the current inline action (empty name if not called from inline action) + */ + inline name get_sender() { + return name( internal_use_do_not_use::get_sender() ); + } } diff --git a/libraries/native/intrinsics.cpp b/libraries/native/intrinsics.cpp index 87ce058fd2..e023fbd736 100644 --- a/libraries/native/intrinsics.cpp +++ b/libraries/native/intrinsics.cpp @@ -340,6 +340,9 @@ extern "C" { int get_context_free_data( uint32_t index, char* buff, size_t size ) { return intrinsics::get().call(index, buff, size); } + capi_name get_sender() { + return intrinsics::get().call(); + } // softfloat static constexpr uint32_t inv_float_eps = 0x4B000000; diff --git a/libraries/native/native/eosio/intrinsics_def.hpp b/libraries/native/native/eosio/intrinsics_def.hpp index a5303cfcf3..9166d1f2a4 100644 --- a/libraries/native/native/eosio/intrinsics_def.hpp +++ b/libraries/native/native/eosio/intrinsics_def.hpp @@ -156,7 +156,8 @@ intrinsic_macro(send_inline) \ intrinsic_macro(send_context_free_inline) \ intrinsic_macro(send_deferred) \ intrinsic_macro(cancel_deferred) \ -intrinsic_macro(get_context_free_data) +intrinsic_macro(get_context_free_data) \ +intrinsic_macro(get_sender) #define CREATE_ENUM(name) \ name,