From 021b0c3b3ae73571fab88d8e25344bcab77c1c32 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 18 Dec 2023 10:04:11 -0600 Subject: [PATCH] GH-1510 Copy over reference boot contract --- unittests/contracts/CMakeLists.txt | 1 + unittests/contracts/eosio.boot/CMakeLists.txt | 6 + unittests/contracts/eosio.boot/eosio.boot.abi | 328 ++++++++++++++++++ unittests/contracts/eosio.boot/eosio.boot.cpp | 19 + unittests/contracts/eosio.boot/eosio.boot.hpp | 260 ++++++++++++++ .../contracts/eosio.boot/eosio.boot.wasm | Bin 0 -> 4917 bytes 6 files changed, 614 insertions(+) create mode 100644 unittests/contracts/eosio.boot/CMakeLists.txt create mode 100644 unittests/contracts/eosio.boot/eosio.boot.abi create mode 100644 unittests/contracts/eosio.boot/eosio.boot.cpp create mode 100644 unittests/contracts/eosio.boot/eosio.boot.hpp create mode 100755 unittests/contracts/eosio.boot/eosio.boot.wasm diff --git a/unittests/contracts/CMakeLists.txt b/unittests/contracts/CMakeLists.txt index 289450ccf1..9293c7cc13 100644 --- a/unittests/contracts/CMakeLists.txt +++ b/unittests/contracts/CMakeLists.txt @@ -21,6 +21,7 @@ elseif( USE_EOSIO_CDT_1_8_X ) add_definitions(-DUSE_EOSIO_CDT_1_8_X=true) endif() +add_subdirectory(eosio.boot) add_subdirectory(eosio.msig) add_subdirectory(eosio.system) add_subdirectory(eosio.token) diff --git a/unittests/contracts/eosio.boot/CMakeLists.txt b/unittests/contracts/eosio.boot/CMakeLists.txt new file mode 100644 index 0000000000..3b37a86c76 --- /dev/null +++ b/unittests/contracts/eosio.boot/CMakeLists.txt @@ -0,0 +1,6 @@ +if( EOSIO_COMPILE_TEST_CONTRACTS ) + add_contract( eosio.boot eosio.boot eosio.boot.cpp ) +else() + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/eosio.boot.wasm ${CMAKE_CURRENT_BINARY_DIR}/eosio.boot.wasm COPYONLY ) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/eosio.boot.abi ${CMAKE_CURRENT_BINARY_DIR}/eosio.boot.abi COPYONLY ) +endif() diff --git a/unittests/contracts/eosio.boot/eosio.boot.abi b/unittests/contracts/eosio.boot/eosio.boot.abi new file mode 100644 index 0000000000..fa76e88486 --- /dev/null +++ b/unittests/contracts/eosio.boot/eosio.boot.abi @@ -0,0 +1,328 @@ +{ + "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", + "version": "eosio::abi/1.2", + "types": [], + "structs": [ + { + "name": "activate", + "base": "", + "fields": [ + { + "name": "feature_digest", + "type": "checksum256" + } + ] + }, + { + "name": "authority", + "base": "", + "fields": [ + { + "name": "threshold", + "type": "uint32" + }, + { + "name": "keys", + "type": "key_weight[]" + }, + { + "name": "accounts", + "type": "permission_level_weight[]" + }, + { + "name": "waits", + "type": "wait_weight[]" + } + ] + }, + { + "name": "canceldelay", + "base": "", + "fields": [ + { + "name": "canceling_auth", + "type": "permission_level" + }, + { + "name": "trx_id", + "type": "checksum256" + } + ] + }, + { + "name": "deleteauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "permission", + "type": "name" + } + ] + }, + { + "name": "key_weight", + "base": "", + "fields": [ + { + "name": "key", + "type": "public_key" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "linkauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "code", + "type": "name" + }, + { + "name": "type", + "type": "name" + }, + { + "name": "requirement", + "type": "name" + } + ] + }, + { + "name": "newaccount", + "base": "", + "fields": [ + { + "name": "creator", + "type": "name" + }, + { + "name": "name", + "type": "name" + }, + { + "name": "owner", + "type": "authority" + }, + { + "name": "active", + "type": "authority" + } + ] + }, + { + "name": "onerror", + "base": "", + "fields": [ + { + "name": "sender_id", + "type": "uint128" + }, + { + "name": "sent_trx", + "type": "bytes" + } + ] + }, + { + "name": "permission_level", + "base": "", + "fields": [ + { + "name": "actor", + "type": "name" + }, + { + "name": "permission", + "type": "name" + } + ] + }, + { + "name": "permission_level_weight", + "base": "", + "fields": [ + { + "name": "permission", + "type": "permission_level" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "reqactivated", + "base": "", + "fields": [ + { + "name": "feature_digest", + "type": "checksum256" + } + ] + }, + { + "name": "setabi", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "abi", + "type": "bytes" + } + ] + }, + { + "name": "setcode", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "vmtype", + "type": "uint8" + }, + { + "name": "vmversion", + "type": "uint8" + }, + { + "name": "code", + "type": "bytes" + } + ] + }, + { + "name": "unlinkauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "code", + "type": "name" + }, + { + "name": "type", + "type": "name" + } + ] + }, + { + "name": "updateauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "permission", + "type": "name" + }, + { + "name": "parent", + "type": "name" + }, + { + "name": "auth", + "type": "authority" + } + ] + }, + { + "name": "wait_weight", + "base": "", + "fields": [ + { + "name": "wait_sec", + "type": "uint32" + }, + { + "name": "weight", + "type": "uint16" + } + ] + } + ], + "actions": [ + { + "name": "activate", + "type": "activate", + "ricardian_contract": "" + }, + { + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + }, + { + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + }, + { + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + }, + { + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + }, + { + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + }, + { + "name": "reqactivated", + "type": "reqactivated", + "ricardian_contract": "" + }, + { + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + }, + { + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + }, + { + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + }, + { + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + } + ], + "tables": [], + "ricardian_clauses": [], + "variants": [], + "action_results": [] +} \ No newline at end of file diff --git a/unittests/contracts/eosio.boot/eosio.boot.cpp b/unittests/contracts/eosio.boot/eosio.boot.cpp new file mode 100644 index 0000000000..33c5f91ea2 --- /dev/null +++ b/unittests/contracts/eosio.boot/eosio.boot.cpp @@ -0,0 +1,19 @@ +#include "eosio.boot.hpp" +#include + +namespace eosioboot { + +void boot::onerror( ignore, ignore> ) { + check( false, "the onerror action cannot be called directly" ); +} + +void boot::activate( const eosio::checksum256& feature_digest ) { + require_auth( get_self() ); + eosio::preactivate_feature( feature_digest ); +} + +void boot::reqactivated( const eosio::checksum256& feature_digest ) { + check( eosio::is_feature_activated( feature_digest ), "protocol feature is not activated" ); +} + +} diff --git a/unittests/contracts/eosio.boot/eosio.boot.hpp b/unittests/contracts/eosio.boot/eosio.boot.hpp new file mode 100644 index 0000000000..422c2e2df6 --- /dev/null +++ b/unittests/contracts/eosio.boot/eosio.boot.hpp @@ -0,0 +1,260 @@ +#pragma once + +#include +#include + +namespace eosioboot { + + using eosio::action_wrapper; + using eosio::check; + using eosio::checksum256; + using eosio::ignore; + using eosio::name; + using eosio::permission_level; + using eosio::public_key; + + /** + * A weighted permission. + * + * @details Defines a weighted permission, that is a permission which has a weight associated. + * A permission is defined by an account name plus a permission name. The weight is going to be + * used against a threshold, if the weight is equal or greater than the threshold set then authorization + * will pass. + */ + struct permission_level_weight { + permission_level permission; + uint16_t weight; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) + }; + + /** + * Weighted key. + * + * @details A weighted key is defined by a public key and an associated weight. + */ + struct key_weight { + eosio::public_key key; + uint16_t weight; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( key_weight, (key)(weight) ) + }; + + /** + * Wait weight. + * + * @details A wait weight is defined by a number of seconds to wait for and a weight. + */ + struct wait_weight { + uint32_t wait_sec; + uint16_t weight; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) + }; + + /** + * Blockchain authority. + * + * @details An authority is defined by: + * - a vector of key_weights (a key_weight is a public key plus a weight), + * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) + * - a vector of wait_weights (a wait_weight is defined by a number of seconds to wait and a weight) + * - a threshold value + */ + struct authority { + uint32_t threshold = 0; + std::vector keys; + std::vector accounts; + std::vector waits; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) + }; + + /** + * @defgroup eosioboot eosio.boot + * @ingroup eosiocontracts + * + * eosio.boot is a extremely minimalistic system contract that only supports the native actions and an + * activate action that allows activating desired protocol features prior to deploying a system contract + * with more features such as eosio.bios or eosio.system. + * + * @{ + */ + class [[eosio::contract("eosio.boot")]] boot : public eosio::contract { + public: + using contract::contract; + /** + * @{ + * These actions map one-on-one with the ones defined in + * [Native Action Handlers](@ref native_action_handlers) section. + * They are present here so they can show up in the abi file and thus user can send them + * to this contract, but they have no specific implementation at this contract level, + * they will execute the implementation at the core level and nothing else. + */ + /** + * New account action + * + * @details Creates a new account. + * + * @param creator - the creator of the account + * @param name - the name of the new account + * @param owner - the authority for the owner permission of the new account + * @param active - the authority for the active permission of the new account + */ + [[eosio::action]] + void newaccount( name creator, + name name, + ignore owner, + ignore active) {} + /** + * Update authorization action. + * + * @details Updates pemission for an account. + * + * @param account - the account for which the permission is updated, + * @param pemission - the permission name which is updated, + * @param parem - the parent of the permission which is updated, + * @param aut - the json describing the permission authorization. + */ + [[eosio::action]] + void updateauth( ignore account, + ignore permission, + ignore parent, + ignore auth ) {} + + /** + * Delete authorization action. + * + * @details Deletes the authorization for an account's permision. + * + * @param account - the account for which the permission authorization is deleted, + * @param permission - the permission name been deleted. + */ + [[eosio::action]] + void deleteauth( ignore account, + ignore permission ) {} + + /** + * Link authorization action. + * + * @details Assigns a specific action from a contract to a permission you have created. Five system + * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. + * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the + * action needed to be authorized (and the contract belonging to), and looks up which permission + * is needed to pass authorization validation. If a link is set, that permission is used for authoraization + * validation otherwise then active is the default, with the exception of `eosio.any`. + * `eosio.any` is an implicit permission which exists on every account; you can link actions to `eosio.any` + * and that will make it so linked actions are accessible to any permissions defined for the account. + * + * @param account - the permission's owner to be linked and the payer of the RAM needed to store this link, + * @param code - the owner of the action to be linked, + * @param type - the action to be linked, + * @param requirement - the permission to be linked. + */ + [[eosio::action]] + void linkauth( ignore account, + ignore code, + ignore type, + ignore requirement ) {} + + /** + * Unlink authorization action. + * + * @details It's doing the reverse of linkauth action, by unlinking the given action. + * + * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, + * @param code - the owner of the action to be unlinked, + * @param type - the action to be unlinked. + */ + [[eosio::action]] + void unlinkauth( ignore account, + ignore code, + ignore type ) {} + + /** + * Cancel delay action. + * + * @details Cancels a deferred transaction. + * + * @param canceling_auth - the permission that authorizes this action, + * @param trx_id - the deferred transaction id to be cancelled. + */ + [[eosio::action]] + void canceldelay( ignore canceling_auth, ignore trx_id ) {} + + /** + * Set code action. + * + * @details Sets the contract code for an account. + * + * @param account - the account for which to set the contract code. + * @param vmtype - reserved, set it to zero. + * @param vmversion - reserved, set it to zero. + * @param code - the code content to be set, in the form of a blob binary.. + */ + [[eosio::action]] + void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} + + /** + * Set abi for contract. + * + * @details Set the abi for contract identified by `account` name. + * + * @param account - the name of the account to set the abi for + * @param abi - the abi hash represented as a vector of characters + */ + [[eosio::action]] + void setabi( name account, const std::vector& abi ) {} + + /** @}*/ + + /** + * On error action. + * + * @details Notification of this action is delivered to the sender of a deferred transaction + * when an objective error occurs while executing the deferred transaction. + * This action is not meant to be called directly. + * + * @param sender_id - the id for the deferred transaction chosen by the sender, + * @param sent_trx - the deferred transaction that failed. + */ + [[eosio::action]] + void onerror( ignore sender_id, ignore> sent_trx ); + + /** + * Activates a protocol feature. + * + * @details Activates a protocol feature + * + * @param feature_digest - hash of the protocol feature to activate. + */ + [[eosio::action]] + void activate( const eosio::checksum256& feature_digest ); + + /** + * Asserts that a protocol feature has been activated. + * + * @details Asserts that a protocol feature has been activated + * + * @param feature_digest - hash of the protocol feature to check for activation. + */ + [[eosio::action]] + void reqactivated( const eosio::checksum256& feature_digest ); + + using newaccount_action = action_wrapper<"newaccount"_n, &boot::newaccount>; + using updateauth_action = action_wrapper<"updateauth"_n, &boot::updateauth>; + using deleteauth_action = action_wrapper<"deleteauth"_n, &boot::deleteauth>; + using linkauth_action = action_wrapper<"linkauth"_n, &boot::linkauth>; + using unlinkauth_action = action_wrapper<"unlinkauth"_n, &boot::unlinkauth>; + using canceldelay_action = action_wrapper<"canceldelay"_n, &boot::canceldelay>; + using setcode_action = action_wrapper<"setcode"_n, &boot::setcode>; + using setabi_action = action_wrapper<"setabi"_n, &boot::setabi>; + using activate_action = action_wrapper<"activate"_n, &boot::activate>; + using reqactivated_action = action_wrapper<"reqactivated"_n, &boot::reqactivated>; + }; + /** @}*/ // end of @defgroup eosioboot eosio.boot +} /// namespace eosioboot diff --git a/unittests/contracts/eosio.boot/eosio.boot.wasm b/unittests/contracts/eosio.boot/eosio.boot.wasm new file mode 100755 index 0000000000000000000000000000000000000000..0da4b8c9838bad3f3f00a8e3746c51058c196e52 GIT binary patch literal 4917 zcmeHLO^jPt6+ZXp*`9eb%*#(FlLW|pF9Vnb(m1i_YmeO$ zl%h}x2|OC#bI(2ZoO93LJ-$@#tP3I%55H%XXjOK*v?{jn&tq3~R|)^X;#+m?pu1aJ zSY+H5R<{6wUTtmRTjERpSq3U;oSsUWom#V0?sSrNM#7@n$;M`_os`O(*(s8Y+Sh6) zeRlFkY~|gRkgH(HOetM zx1Ow5T4yQG6R&)t33Z6!i4wFswU*WHrvlGSC&@}D)|!=iX2s4jw^qB^YIc$;1J%t6SkVNFnyPHJ+esrUWwrH$CK_xw5Yz6Hvw-$QO9enNQVR%`7n?V0?cIjAYv@Bdzspoo+US8?-{(Aj#|I%;2(KQltMhEZp zfPU_kuYLWSmp?bczHf+q_7^{=5&Hd%?%jO;*7mipj`27$pnmbnpFTSxHo(5|z3adH z{7`Ob}%5pm?Oy}w)>$9}+JfAF{8{o%V~@;+$MFF*gnOP4-2V(}qw z<>|{eZoGQo(koZSh>M;f*1Ff*zH;$b^clSz+xd-aFWmalA1Rpe$36osEalK*xU~_{qU{s?8X7+QoxaVfDYJc!A|vxIsX7D zVDw56khIVOAl{@`jsb!hjIwn57VEod+;1)1vk5W&7&|5@L7 zyT0*uedEPrzVV!I93A_{(XnqF-T#ztINt+hv-zgW=7FPrEQB5;v<#6S^CXw~FVK;m zCb%0pS3r`&^Kl^!y(umZ;HKlAegp(M*c(b9VOH%bfK5m{54=MI27}EY$v-+RxLAGV zs;wz-M_dSU13E555F#!AGaGTi)t><^v>VXI0msup1ht*I4^3O$->GUSX#Z!@ z+IWk*oK1cvT}&)sZ4?tOA~+QO%@_bvgWG7{4TcA!)5u$tMHe1(*58N>)OZ&dMipf- z^mv#LB^aQp?|R<`3Eyw?*oOcb3zC1{cYyZ^8(|FCd-2Zu27+eaw!tdSS6wiQWs}-~ z4vrpz2GFsY&)txcrJzhjN8N1rut;IfQ!!dyz#r_K!Fp z21H1nj}YPboDWbrw<(c(^b;DF_(dr^v?;b`Fqg<4T1TpG1Wt}d0QNXe*kx7X<0{@M;%*v=X_}Jg z1<<|lNi<{|wnyB344uOcK6y@l$)?1jjNb%GA&#I7ESI6}Q6~4u;mB4#Yk6C%RB#_h z6>3@<+N&Xrbf`wUDDHyPt`0to#^-ce2nec&nuW&VVaS5A@Hroyt%yawB z=tT+3bA$+l#taC81LXf&*!mT}t66rJ9Qzl^b#F2M*ge)|#MWiLqilV?pgoNQ!Y>fl zOx&hB7o|I1OpN5v7+y>sG7>SYaWVPG#2jL;nDPyW{?6WTL5i!zA_kSo4FR03<0E4Q z%CbpABv$+~rAR)*0e~S53&1U;;RL5SgiPA7Vj`V}E<0r``RbfRzlT8eKT6b(a@@;> zlZdG?+AKA!8cdDUWr0XE=f+hUo? zu_ZN!1O&9Oq)Ln>c~15v^=U_Kxd-SD;@iaK^ruSc zVO#lM6A5n#0qc8j;QRcz?+dO_Ip61D^ z9r>Q+z1{bS=Yj7bf&J*@-MjC(eGJmz@UAEQTLM{!UzYykC(E_9q-wIJDX-xr1+O}$ zRemz*P