From 415ed634c22788f95d5ec41daaf10285c1c128ae Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Mon, 4 Jan 2021 13:58:04 -0500 Subject: [PATCH 001/204] Upgrade existing brew packages before installing new ones. --- .cicd/pipeline.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 298f3198fd..1bfdddbeb9 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -59,6 +59,7 @@ steps: - label: ":darwin: macOS 10.14 - Build" command: + - "brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -84,6 +85,7 @@ steps: - label: ":darwin: macOS 10.15 - Build" command: + - "brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -165,6 +167,7 @@ steps: - label: ":darwin: macOS 10.14 - Unit Tests" command: + - "brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -190,6 +193,7 @@ steps: - label: ":darwin: macOS 10.15 - Unit Tests" command: + - "brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -268,6 +272,7 @@ steps: - label: ":darwin: macOS 10.14 - Toolchain Tests" command: + - "brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -293,6 +298,7 @@ steps: - label: ":darwin: macOS 10.15 - Toolchain Tests" command: + - "brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" From 145e9171e71fb187bc079f3dae163c483c3548ca Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 5 Jan 2021 16:47:52 +0200 Subject: [PATCH 002/204] correct the link to built_in_types to be a fixed one for develop branch, each release/x.y.z branch will have its own specific link though --- .../08_abi/00_understanding-abi-files.md | 2 +- examples/kv_map/include/kv_map.hpp | 5 ++++ examples/kv_map/src/kv_map.cpp | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/05_best-practices/08_abi/00_understanding-abi-files.md b/docs/05_best-practices/08_abi/00_understanding-abi-files.md index 71356d0ff1..1cb7e9995e 100644 --- a/docs/05_best-practices/08_abi/00_understanding-abi-files.md +++ b/docs/05_best-practices/08_abi/00_understanding-abi-files.md @@ -35,7 +35,7 @@ Start with an empty ABI, for exemplification we will work based on the `eosio.to An ABI enables any client or interface to interpret and even generate a GUI for your contract. For this to work consistently, describe the custom types that are used as a parameter in any public action or struct that needs to be described in the ABI. [[info | Built-in Types]] -| EOSIO implements a number of custom built-ins. Built-in types don't need to be described in an ABI file. If you would like to familiarize yourself with EOSIO's built-ins, they are defined [here](https://github.com/EOSIO/eos/blob/master/libraries/chain/abi_serializer.cpp#L59-L100) +| EOSIO implements a number of custom built-ins. Built-in types don't need to be described in an ABI file. If you would like to familiarize yourself with EOSIO's built-ins, they are defined [here](https://github.com/EOSIO/eos/blob/76565937064d5acccb089b50aa8ea797cd92dc82/libraries/chain/abi_serializer.cpp#L90) ```json diff --git a/examples/kv_map/include/kv_map.hpp b/examples/kv_map/include/kv_map.hpp index cc5664f64e..4fafe3eb63 100644 --- a/examples/kv_map/include/kv_map.hpp +++ b/examples/kv_map/include/kv_map.hpp @@ -67,6 +67,10 @@ class [[eosio::contract]] kv_map : public eosio::contract { std::string country, std::string personal_id); + // same as upsert only that it takes a user defined type as input parameter + [[eosio::action]] + void upsert2(int id, person pers); + // inserts a person if not exists, or updates it if already exists. // the payer is the account_name, specified as input parameter. [[eosio::action]] @@ -100,6 +104,7 @@ class [[eosio::contract]] kv_map : public eosio::contract { using get_action = eosio::action_wrapper<"get"_n, &kv_map::get>; using upsert_action = eosio::action_wrapper<"upsert"_n, &kv_map::upsert>; + using upsert_action2 = eosio::action_wrapper<"upsert2"_n, &kv_map::upsert2>; using upsertwpayer_action = eosio::action_wrapper<"upsertwpayer"_n, &kv_map::upsertwpayer>; using erase_action = eosio::action_wrapper<"erase"_n, &kv_map::erase>; using is_pers_id_in_cntry_action = eosio::action_wrapper<"checkpidcntr"_n, &kv_map::checkpidcntr>; diff --git a/examples/kv_map/src/kv_map.cpp b/examples/kv_map/src/kv_map.cpp index 42ebbc036d..74be0f0c42 100644 --- a/examples/kv_map/src/kv_map.cpp +++ b/examples/kv_map/src/kv_map.cpp @@ -81,6 +81,36 @@ void kv_map::upsert( } } +[[eosio::action]] +void kv_map::upsert2( + int id, person pers) { + + const person& person_upsert = person_factory::get_person( + pers.account_name, + pers.first_name, + pers.last_name, + pers.street, + pers.city, + pers.state, + pers.country, + pers.personal_id); + + // retrieve the person by account name, if it doesn't exist we get an emtpy person + const person& existing_person = get(id); + + // upsert into kv::map, the payer is the account owning the kv::map, owning the smart contract + my_map[id] = person_upsert; + + // print customized message for insert vs update + if (existing_person.account_name.value == 0) { + eosio::print_f("Person (%, %, %) was successfully added.", + person_upsert.first_name, person_upsert.last_name, person_upsert.personal_id); + } + else { + eosio::print_f("Person with ID % was successfully updated.", id); + } +} + // inserts a person if not exists, or updates it if already exists. // the payer is the account_name, specified as input parameter. [[eosio::action]] From 2f2d840d5881d03bf17198bdfc3a6823f6f65328 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 5 Jan 2021 16:57:54 +0200 Subject: [PATCH 003/204] resolves #818 add warning for iterator_to as well --- docs/index.md | 8 ++-- .../eosiolib/contracts/eosio/multi_index.hpp | 42 ++++++++++++++++--- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/docs/index.md b/docs/index.md index f5932023e8..57d2dcbd1d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,14 +1,14 @@ # EOSIO.CDT (Contract Development Toolkit) -## Version : 1.7.0 - EOSIO.CDT is a toolchain for WebAssembly (WASM) and set of tools to facilitate smart contract development for the EOSIO platform. In addition to being a general purpose WebAssembly toolchain, [EOSIO](https://github.com/eosio/eos) specific optimizations are available to support building EOSIO smart contracts. This new toolchain is built around [Clang 7](https://github.com/eosio/llvm), which means that EOSIO.CDT has the most currently available optimizations and analyses from LLVM, but as the WASM target is still considered experimental, some optimizations are incomplete or not available. ## New Introductions -As of this release two new repositories are under the suite of tools provided by **EOSIO.CDT**. These are the [Ricardian Template Toolkit](https://github.com/eosio/ricardian-template-toolkit) and the [Ricardian Specification](https://github.com/eosio/ricardian-spec). The **Ricardian Template Toolkit** is a set of libraries to facilitate smart contract writers in crafting their Ricardian contracts. The Ricardian specification is the working specification for the above mentioned toolkit. Please note that both projects are **alpha** releases and are subject to change. + +As of this release two new repositories are under the suite of tools provided by **EOSIO.CDT**. These are the [Ricardian Template Toolkit](https://github.com/eosio/ricardian-template-toolkit) and the [Ricardian Specification](https://github.com/eosio/ricardian-spec). The **Ricardian Template Toolkit** is a set of libraries to facilitate smart contract writers in crafting their Ricardian contracts. The Ricardian specification is the working specification for the above mentioned toolkit. Please note that both projects are **alpha** releases and are subject to change. ## Upgrading -There's been a round of braking changes, if you are upgrading please read the [Upgrade guide from 1.2 to 1.3](./04_upgrading/1.2-to-1.3.md) and [Upgrade guide from 1.5 to 1.6](./04_upgrading/1.5-to-1.6.md). + +There's been a round of braking changes, if you are upgrading from older version please read the [Upgrade guide from 1.2 to 1.3](./04_upgrading/1.2-to-1.3.md) and [Upgrade guide from 1.5 to 1.6](./04_upgrading/1.5-to-1.6.md). ## Contributing diff --git a/libraries/eosiolib/contracts/eosio/multi_index.hpp b/libraries/eosiolib/contracts/eosio/multi_index.hpp index 7592667dd0..4838197119 100644 --- a/libraries/eosiolib/contracts/eosio/multi_index.hpp +++ b/libraries/eosiolib/contracts/eosio/multi_index.hpp @@ -634,11 +634,26 @@ class multi_index return lb; } + /** + * Gets the object with the smallest primary key in the case where the secondary key is not unique. + * + * Avoid the common pitfall of copy-assigning the T& reference returned + * to a stack-allocated local variable and then passing that into modify of the multi-index. + * The most common mistake is when the local variable is defined as auto + * typename, instead it should be of type auto& or decltype(auto). + */ const T& get( secondary_key_type&& secondary, const char* error_msg = "unable to find secondary key" )const { return get( secondary, error_msg ); } - // Gets the object with the smallest primary key in the case where the secondary key is not unique. + /** + * Gets the object with the smallest primary key in the case where the secondary key is not unique. + * + * Avoid the common pitfall of copy-assigning the T& reference returned + * to a stack-allocated local variable and then passing that into modify of the multi-index. + * The most common mistake is when the local variable is defined as auto + * typename, instead it should be of type auto& or decltype(auto). + */ const T& get( const secondary_key_type& secondary, const char* error_msg = "unable to find secondary key" )const { auto result = find( secondary ); eosio::check( result != cend(), error_msg ); @@ -680,7 +695,11 @@ class multi_index return {this, &mi}; } - + /** + * Warning: the interator_to can have undefined behavior if the caller + * passes in a reference to a stack-allocated object rather than the + * reference returned by get or by dereferencing a const_iterator. + */ const_iterator iterator_to( const T& obj ) { using namespace _multi_index_detail; @@ -1483,6 +1502,10 @@ class multi_index * } * EOSIO_DISPATCH( addressbook, (myaction) ) * @endcode + * + * Warning: the interator_to can have undefined behavior if the caller + * passes in a reference to a stack-allocated object rather than the + * reference returned by get or by dereferencing a const_iterator. */ const_iterator iterator_to( const T& obj )const { const auto& objitem = static_cast(obj); @@ -1719,10 +1742,10 @@ class multi_index * Retrieves an existing object from a table using its primary key. * @ingroup multiindex * - * @param primary - Primary key value of the object - * @return A constant reference to the object containing the specified primary key. + * @param primary - Primary key value of the object. + * @return A constant reference to the object containing the specified primary key. * - * Exception - No object matches the given key + * Exception - No object matches the given key. * * Example: * @@ -1733,12 +1756,19 @@ class multi_index * // create reference to address_index - see emplace example * // add dan account to table - see emplace example * - * auto user = addresses.get("dan"_n); + * auto& user = addresses.get("dan"_n); * eosio::check(user.first_name == "Daniel", "Couldn't get him."); * } * } * EOSIO_DISPATCH( addressbook, (myaction) ) * @endcode + * + * Warning: + * + * Avoid the common pitfall of copy-assigning the T& reference returned + * to a stack-allocated local variable and then passing that into modify of the multi-index. + * The most common mistake is when the local variable is defined as auto + * typename, instead it should be of type auto& or decltype(auto). */ const T& get( uint64_t primary, const char* error_msg = "unable to find key" )const { auto result = find( primary ); From 80238a405ca24c95a9304bf5d25fb0e705472b51 Mon Sep 17 00:00:00 2001 From: Qing Zhang Date: Fri, 8 Jan 2021 08:35:59 -0800 Subject: [PATCH 004/204] Add additional warnings to eosio_exit annotations --- libraries/eosiolib/contracts/eosio/system.hpp | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/libraries/eosiolib/contracts/eosio/system.hpp b/libraries/eosiolib/contracts/eosio/system.hpp index 5c5c21926b..b438e7269b 100644 --- a/libraries/eosiolib/contracts/eosio/system.hpp +++ b/libraries/eosiolib/contracts/eosio/system.hpp @@ -33,19 +33,27 @@ namespace eosio { */ /** - * This method will abort execution of wasm without failing the contract. This is used to bypass all cleanup / destructors that would normally be called. + * This method will abort execution of wasm without failing the contract. + * This is used to bypass all cleanup / destructors that would normally be + * called. + * + * WARNING: this method immediately abort execution of wasm code that is on + * the stack and would be executed as the method normally returned. + * Problems can occur with write-caches, RAII, reference counting + * when this method aborts execution of wasm code immediately. * * @ingroup system + * * @param code - the exit code - * Example: + * Example: * - * @code - * eosio_exit(0); - * eosio_exit(1); - * eosio_exit(2); - * eosio_exit(3); - * @endcode - */ + * @code + * eosio_exit(0); + * eosio_exit(1); + * eosio_exit(2); + * eosio_exit(3); + * @endcode + */ inline void eosio_exit( int32_t code ) { internal_use_do_not_use::eosio_exit(code); } From a9465858f9f20da43d05bcd24daba4a0ad45695c Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Thu, 31 Dec 2020 11:16:45 -0500 Subject: [PATCH 005/204] initial fix for jira issue EPE-450 --- tools/cc/eosio-cpp.cpp.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index cc8fffa9fd..7230779022 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -76,6 +76,8 @@ void generate(const std::vector& base_options, std::string input, s std::string abi_s; abigen::get().to_json().dump(abi_s); codegen::get().set_abi(abi_s); + } else { + throw std::runtime_error("abigen error"); } tool_run = ctool.run(newFrontendActionFactory().get()); From ec9dd0c13e87324acd62792e1e5e5d71a0e008ca Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 8 Jan 2021 12:59:26 -0500 Subject: [PATCH 006/204] add field for internal contract name --- tools/cc/eosio-cpp.cpp.in | 11 ++++++++++- tools/include/eosio/gen.hpp | 10 ++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index 7230779022..ed51a699ca 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -77,7 +77,16 @@ void generate(const std::vector& base_options, std::string input, s abigen::get().to_json().dump(abi_s); codegen::get().set_abi(abi_s); } else { - throw std::runtime_error("abigen error"); + const std::string& name = abigen::get().get_internal_contract_name(); + if (name.empty()) { + // there are no actions, tables or maps, so the actural contract name could not be retrieved + // a warning is output, and later `wasm-ld` will output an error + std::cout << "Warning, ABI is empty and will not be generated\n"; + } else if (name != contract_name) { + throw std::runtime_error("abigen error: please check the specified WASM name or contract name is correct"); + } else { + throw std::runtime_error("abigen error"); // unknown error + } } tool_run = ctool.run(newFrontendActionFactory().get()); diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 446012b097..55e8e0432e 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -105,6 +105,7 @@ struct simple_ricardian_tokenizer { struct generation_utils { std::vector resource_dirs; std::string contract_name; + inline static std::string name = ""; // internal contract name bool suppress_ricardian_warnings; generation_utils() : resource_dirs({"./"}) {} @@ -154,6 +155,7 @@ struct generation_utils { inline void set_contract_name( const std::string& cn ) { contract_name = cn; } inline std::string get_contract_name()const { return contract_name; } + static inline std::string get_internal_contract_name() { return name; } inline void set_resource_dirs( const std::vector& rd ) { llvm::SmallString<128> cwd; auto has_real_path = llvm::sys::fs::real_path("./", cwd, true); @@ -271,7 +273,9 @@ struct generation_utils { } static inline bool is_eosio_contract( const clang::CXXMethodDecl* decl, const std::string& cn ) { - std::string name = ""; + if (!name.empty()) { + return name == cn; + } if (decl->isEosioContract()) name = decl->getEosioContractAttr()->getName(); else if (decl->getParent()->isEosioContract()) @@ -283,7 +287,9 @@ struct generation_utils { } static inline bool is_eosio_contract( const clang::CXXRecordDecl* decl, const std::string& cn ) { - std::string name = ""; + if (!name.empty()) { + return name == cn; + } auto pd = llvm::dyn_cast(decl->getParent()); if (decl->isEosioContract()) { auto nm = decl->getEosioContractAttr()->getName().str(); From 5bacfcd62479aea8df307f598a95b23e7a1fad28 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Sun, 10 Jan 2021 15:33:02 -0500 Subject: [PATCH 007/204] only output error when --abigen is set; code cleanup --- tools/cc/eosio-cpp.cpp.in | 17 +++++++------- tools/include/eosio/gen.hpp | 46 ++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index ed51a699ca..e033a579f4 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -75,15 +75,14 @@ void generate(const std::vector& base_options, std::string input, s if (!abigen::get().is_empty()) { std::string abi_s; abigen::get().to_json().dump(abi_s); - codegen::get().set_abi(abi_s); - } else { - const std::string& name = abigen::get().get_internal_contract_name(); - if (name.empty()) { - // there are no actions, tables or maps, so the actural contract name could not be retrieved + } else if (abigen) { + const std::string& real_contract_name = abigen::get().get_real_contract_name(); + if (real_contract_name.empty()) { + // if the contract is empty, the real contract name could not be obtained by parsing methods or records // a warning is output, and later `wasm-ld` will output an error - std::cout << "Warning, ABI is empty and will not be generated\n"; - } else if (name != contract_name) { - throw std::runtime_error("abigen error: please check the specified WASM name or contract name is correct"); + std::cout << "Warning, contract is empty and ABI file is not generated\n"; + } else if (contract_name != real_contract_name) { + throw std::runtime_error("abigen error: the contract name from -o or --contract doesn't match the real contract name"); } else { throw std::runtime_error("abigen error"); // unknown error } @@ -137,7 +136,7 @@ int main(int argc, const char **argv) { input = tmp_file; } output = tmp_file+".o"; - + if (!opts.link) { output = opts.output_fn.empty() ? "a.out" : opts.output_fn; } diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 55e8e0432e..9942974236 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -105,7 +105,7 @@ struct simple_ricardian_tokenizer { struct generation_utils { std::vector resource_dirs; std::string contract_name; - inline static std::string name = ""; // internal contract name + inline static std::string real_contract_name = ""; // obtained by parsing methods/records bool suppress_ricardian_warnings; generation_utils() : resource_dirs({"./"}) {} @@ -155,7 +155,7 @@ struct generation_utils { inline void set_contract_name( const std::string& cn ) { contract_name = cn; } inline std::string get_contract_name()const { return contract_name; } - static inline std::string get_internal_contract_name() { return name; } + static inline std::string get_real_contract_name() { return real_contract_name; } inline void set_resource_dirs( const std::vector& rd ) { llvm::SmallString<128> cwd; auto has_real_path = llvm::sys::fs::real_path("./", cwd, true); @@ -273,33 +273,31 @@ struct generation_utils { } static inline bool is_eosio_contract( const clang::CXXMethodDecl* decl, const std::string& cn ) { - if (!name.empty()) { - return name == cn; - } - if (decl->isEosioContract()) - name = decl->getEosioContractAttr()->getName(); - else if (decl->getParent()->isEosioContract()) - name = decl->getParent()->getEosioContractAttr()->getName(); - if (name.empty()) { - name = decl->getParent()->getName().str(); + if (real_contract_name.empty()) { + if (decl->isEosioContract()) + real_contract_name = decl->getEosioContractAttr()->getName(); + else if (decl->getParent()->isEosioContract()) + real_contract_name = decl->getParent()->getEosioContractAttr()->getName(); + if (real_contract_name.empty()) { + real_contract_name = decl->getParent()->getName().str(); + } } - return name == cn; + return cn == real_contract_name; } static inline bool is_eosio_contract( const clang::CXXRecordDecl* decl, const std::string& cn ) { - if (!name.empty()) { - return name == cn; - } - auto pd = llvm::dyn_cast(decl->getParent()); - if (decl->isEosioContract()) { - auto nm = decl->getEosioContractAttr()->getName().str(); - name = nm.empty() ? decl->getName().str() : nm; - } - else if (pd && pd->isEosioContract()) { - auto nm = pd->getEosioContractAttr()->getName().str(); - name = nm.empty() ? pd->getName().str() : nm; + if (real_contract_name.empty()) { + auto pd = llvm::dyn_cast(decl->getParent()); + if (decl->isEosioContract()) { + auto nm = decl->getEosioContractAttr()->getName().str(); + real_contract_name = nm.empty() ? decl->getName().str() : nm; + } + else if (pd && pd->isEosioContract()) { + auto nm = pd->getEosioContractAttr()->getName().str(); + real_contract_name = nm.empty() ? pd->getName().str() : nm; + } } - return cn == name; + return cn == real_contract_name; } inline bool is_template_specialization( const clang::QualType& type, const std::vector& names ) { From 245b5c176acd77958885bae418a3c7d0430e757e Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Sun, 10 Jan 2021 15:48:57 -0500 Subject: [PATCH 008/204] add back wrongly deleted statement; rephrase error message --- tools/cc/eosio-cpp.cpp.in | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index e033a579f4..79c81b5426 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -75,14 +75,15 @@ void generate(const std::vector& base_options, std::string input, s if (!abigen::get().is_empty()) { std::string abi_s; abigen::get().to_json().dump(abi_s); + codegen::get().set_abi(abi_s); } else if (abigen) { const std::string& real_contract_name = abigen::get().get_real_contract_name(); if (real_contract_name.empty()) { // if the contract is empty, the real contract name could not be obtained by parsing methods or records - // a warning is output, and later `wasm-ld` will output an error + // a warning is output here, and `wasm-ld` will output an error later std::cout << "Warning, contract is empty and ABI file is not generated\n"; } else if (contract_name != real_contract_name) { - throw std::runtime_error("abigen error: the contract name from -o or --contract doesn't match the real contract name"); + throw std::runtime_error("abigen error: the specified contract name by WASM name or --contract doesn't match the real contract name"); } else { throw std::runtime_error("abigen error"); // unknown error } From 66dc056d019a468bb62c1136fbdb815cca8f8956 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Sun, 10 Jan 2021 23:30:47 -0500 Subject: [PATCH 009/204] replace real_contract_name by parsed_contract_name --- tools/cc/eosio-cpp.cpp.in | 24 +++++++++------ tools/include/compiler_options.hpp.in | 15 +++++++-- tools/include/eosio/gen.hpp | 44 +++++++++++++-------------- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index 79c81b5426..ad301201ef 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -39,7 +39,7 @@ using namespace llvm; using namespace eosio; using namespace eosio::cdt; -void generate(const std::vector& base_options, std::string input, std::string contract_name, const std::vector& resource_paths, const std::pair& abi_version, bool abigen, bool suppress_ricardian_warning) { +void generate(const std::vector& base_options, std::string input, std::string contract_name, const std::vector& resource_paths, const std::pair& abi_version, bool abigen, bool suppress_ricardian_warning, bool has_o_opt, bool has_contract_opt) { std::vector options; options.push_back("eosio-cpp"); options.push_back(input); // don't remove oddity of CommonOptionsParser? @@ -77,13 +77,19 @@ void generate(const std::vector& base_options, std::string input, s abigen::get().to_json().dump(abi_s); codegen::get().set_abi(abi_s); } else if (abigen) { - const std::string& real_contract_name = abigen::get().get_real_contract_name(); - if (real_contract_name.empty()) { - // if the contract is empty, the real contract name could not be obtained by parsing methods or records + const std::string& parsed_contract_name = abigen::get().get_parsed_contract_name(); + if (parsed_contract_name.empty()) { + // if the contract is empty, the contract name could not be obtained by parsing methods or records // a warning is output here, and `wasm-ld` will output an error later - std::cout << "Warning, contract is empty and ABI file is not generated\n"; - } else if (contract_name != real_contract_name) { - throw std::runtime_error("abigen error: the specified contract name by WASM name or --contract doesn't match the real contract name"); + std::cout << "Warning, contract is empty and ABI is not generated\n"; + } else if (contract_name != parsed_contract_name) { + if (has_contract_opt) { + throw std::runtime_error("abigen error: '--contract' specified name doesn't match the real contract name"); + } else if (has_o_opt) { + throw std::runtime_error("abigen error: '-o' specified WASM name doesn't match the real contract name"); + } else { + throw std::runtime_error("abigen error: contract filename doesn't match the real contract name"); + } } else { throw std::runtime_error("abigen error"); // unknown error } @@ -126,7 +132,7 @@ int main(int argc, const char **argv) { tool_opts.erase(std::remove_if(tool_opts.begin(), tool_opts.end(), [&](const auto& opt){ return non_tool_opts.count(opt); }), tool_opts.end()); - generate(tool_opts, input, opts.abigen_contract, opts.abigen_resources, opts.abi_version, opts.abigen, opts.suppress_ricardian_warning); + generate(tool_opts, input, opts.abigen_contract, opts.abigen_resources, opts.abi_version, opts.abigen, opts.suppress_ricardian_warning, opts.has_o_opt, opts.has_contract_opt); auto src = SmallString<64>(input); llvm::sys::path::remove_filename(src); @@ -137,7 +143,7 @@ int main(int argc, const char **argv) { input = tmp_file; } output = tmp_file+".o"; - + if (!opts.link) { output = opts.output_fn.empty() ? "a.out" : opts.output_fn; } diff --git a/tools/include/compiler_options.hpp.in b/tools/include/compiler_options.hpp.in index a35926f21c..fc2a523d7a 100644 --- a/tools/include/compiler_options.hpp.in +++ b/tools/include/compiler_options.hpp.in @@ -385,6 +385,8 @@ struct Options { bool debug; bool native; std::pair abi_version; + bool has_o_opt; + bool has_contract_opt; }; static void GetCompDefaults(std::vector& copts) { @@ -544,6 +546,8 @@ static Options CreateOptions(bool add_defaults=true) { std::string pp_dir; std::string abigen_output; std::string abigen_contract; + bool has_o_opt; + bool has_contract_opt; #ifdef ONLY_LD bool abigen = false; @@ -833,11 +837,13 @@ static Options CreateOptions(bool add_defaults=true) { ldopts.emplace_back("-o"+output_fn); } #endif + has_o_opt = false; } else { ldopts.emplace_back("-o"); ldopts.emplace_back(o_opt); output_fn = o_opt; + has_o_opt = true; } if (!fnative_opt) { @@ -882,12 +888,15 @@ static Options CreateOptions(bool add_defaults=true) { agopts.emplace_back("-fstrict-vtable-pointers"); } #endif - if (!contract_name.empty()) + if (!contract_name.empty()) { abigen_contract = contract_name; + has_contract_opt = true; + } else { llvm::SmallString<256> fn = llvm::sys::path::filename(output_fn); llvm::sys::path::replace_extension(fn, ""); abigen_contract = fn.str(); + has_contract_opt = false; } for ( auto resource : resources ) { @@ -910,8 +919,8 @@ static Options CreateOptions(bool add_defaults=true) { } #ifndef ONLY_LD - return {output_fn, inputs, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}}; + return {output_fn, inputs, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt}; #else - return {output_fn, {}, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}}; + return {output_fn, {}, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt}; #endif } diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 9942974236..78f780af17 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -105,7 +105,7 @@ struct simple_ricardian_tokenizer { struct generation_utils { std::vector resource_dirs; std::string contract_name; - inline static std::string real_contract_name = ""; // obtained by parsing methods/records + inline static std::string parsed_contract_name = ""; // obtained by parsing methods/records bool suppress_ricardian_warnings; generation_utils() : resource_dirs({"./"}) {} @@ -155,7 +155,7 @@ struct generation_utils { inline void set_contract_name( const std::string& cn ) { contract_name = cn; } inline std::string get_contract_name()const { return contract_name; } - static inline std::string get_real_contract_name() { return real_contract_name; } + static inline std::string get_parsed_contract_name() { return parsed_contract_name; } inline void set_resource_dirs( const std::vector& rd ) { llvm::SmallString<128> cwd; auto has_real_path = llvm::sys::fs::real_path("./", cwd, true); @@ -273,31 +273,31 @@ struct generation_utils { } static inline bool is_eosio_contract( const clang::CXXMethodDecl* decl, const std::string& cn ) { - if (real_contract_name.empty()) { - if (decl->isEosioContract()) - real_contract_name = decl->getEosioContractAttr()->getName(); - else if (decl->getParent()->isEosioContract()) - real_contract_name = decl->getParent()->getEosioContractAttr()->getName(); - if (real_contract_name.empty()) { - real_contract_name = decl->getParent()->getName().str(); - } + std::string name = ""; + if (decl->isEosioContract()) + name = decl->getEosioContractAttr()->getName(); + else if (decl->getParent()->isEosioContract()) + name = decl->getParent()->getEosioContractAttr()->getName(); + if (name.empty()) { + name = decl->getParent()->getName().str(); } - return cn == real_contract_name; + parsed_contract_name = name; + return cn == parsed_contract_name; } static inline bool is_eosio_contract( const clang::CXXRecordDecl* decl, const std::string& cn ) { - if (real_contract_name.empty()) { - auto pd = llvm::dyn_cast(decl->getParent()); - if (decl->isEosioContract()) { - auto nm = decl->getEosioContractAttr()->getName().str(); - real_contract_name = nm.empty() ? decl->getName().str() : nm; - } - else if (pd && pd->isEosioContract()) { - auto nm = pd->getEosioContractAttr()->getName().str(); - real_contract_name = nm.empty() ? pd->getName().str() : nm; - } + std::string name = ""; + auto pd = llvm::dyn_cast(decl->getParent()); + if (decl->isEosioContract()) { + auto nm = decl->getEosioContractAttr()->getName().str(); + name = nm.empty() ? decl->getName().str() : nm; + } + else if (pd && pd->isEosioContract()) { + auto nm = pd->getEosioContractAttr()->getName().str(); + name = nm.empty() ? pd->getName().str() : nm; } - return cn == real_contract_name; + parsed_contract_name = name; + return cn == parsed_contract_name; } inline bool is_template_specialization( const clang::QualType& type, const std::vector& names ) { From 06e3d4d0f58982db25a1d361a3058f43c8c6d943 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 12 Jan 2021 14:56:47 +0200 Subject: [PATCH 010/204] update links and bullet list at the bottom --- docs/02_installation.md | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/02_installation.md b/docs/02_installation.md index 8b93611ec8..ac9595735b 100644 --- a/docs/02_installation.md +++ b/docs/02_installation.md @@ -7,39 +7,46 @@ EOSIO.CDT currently supports Mac OS X brew, Linux x86_64 Debian packages, and Li **If you have previously installed EOSIO.CDT, run the `uninstall` script (it is in the directory where you cloned EOSIO.CDT) before downloading and using the binary releases.** ## Mac OS X Brew Install + ```sh $ brew tap eosio/eosio.cdt $ brew install eosio.cdt ``` ## Mac OS X Brew Uninstall + ```sh $ brew remove eosio.cdt ``` ## Debian Package Install + ```sh -$ wget https://github.com/eosio/eosio.cdt/releases/download/v1.6.3/eosio.cdt_1.6.3-1-ubuntu-18.04_amd64.deb -$ sudo apt install ./eosio.cdt_1.6.3-1-ubuntu-18.04_amd64.deb +$ wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb +$ sudo apt install ./eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb ``` ## Debian Package Uninstall + ```sh $ sudo apt remove eosio.cdt ``` ## RPM Package Install + ```sh -$ wget https://github.com/eosio/eosio.cdt/releases/download/v1.6.3/eosio.cdt-1.6.3-1.el7.x86_64.rpm -$ sudo yum install ./eosio.cdt-1.6.3-1.el7.x86_64.rpm +$ wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt-1.8.0-rc1.el7.x86_64.rpm +$ sudo yum install ./eosio.cdt-1.8.0-rc1.el7.x86_64.rpm ``` ## RPM Package Uninstall + ```sh $ sudo yum remove eosio.cdt ``` # Guided Installation or Building from Scratch + ```sh $ git clone --recursive https://github.com/eosio/eosio.cdt $ cd eosio.cdt @@ -64,8 +71,8 @@ $ sudo rm -fr /usr/local/lib/cmake/eosio.cdt $ sudo rm /usr/local/bin/eosio-* ``` - # Installed Tools + * eosio-cpp * eosio-cc * eosio-ld @@ -78,13 +85,13 @@ $ sudo rm /usr/local/bin/eosio-* * eosio-objdump * eosio-readelf -Below tools are not installed after brew install, you get them only by building the repository and installing from scracth, [see here](#guided_installation_or_building_from_scratch) -eosio-abidiff -eosio-ranlib -eosio-ar -eosio-objdump -eosio-readelf +The following tools are not installed after brew install, you get them when build the repository and install it from scratch, [see here](#guided-installation-or-building-from-scratch): +* eosio-abidiff +* eosio-ranlib +* eosio-ar +* eosio-objdump +* eosio-readelf License [MIT](../LICENSE) From 5fc62c12c836953edc8bc0dd28b3274268a2d02b Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 12 Jan 2021 15:18:22 +0200 Subject: [PATCH 011/204] fix informational --- .../40_multi-index/how-to-modify-data-in-a-multi-index-table.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index c3be46ea60..174e6026d3 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -37,5 +37,5 @@ To modify data in the multi index table defined in the above tutorial, you will } ``` -[[Info | Full example location] +[[Info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). From 396d251a120340f619d03498722da06c198f8a41 Mon Sep 17 00:00:00 2001 From: Qing Zhang Date: Tue, 12 Jan 2021 08:17:35 -0800 Subject: [PATCH 012/204] fix grammar error --- libraries/eosiolib/contracts/eosio/system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/eosiolib/contracts/eosio/system.hpp b/libraries/eosiolib/contracts/eosio/system.hpp index b438e7269b..c35f7ce015 100644 --- a/libraries/eosiolib/contracts/eosio/system.hpp +++ b/libraries/eosiolib/contracts/eosio/system.hpp @@ -37,7 +37,7 @@ namespace eosio { * This is used to bypass all cleanup / destructors that would normally be * called. * - * WARNING: this method immediately abort execution of wasm code that is on + * WARNING: this method will immediately abort execution of wasm code that is on * the stack and would be executed as the method normally returned. * Problems can occur with write-caches, RAII, reference counting * when this method aborts execution of wasm code immediately. From c4dd2d3b00496d86d3cea7b70a02514a9137d698 Mon Sep 17 00:00:00 2001 From: Qing Zhang Date: Tue, 12 Jan 2021 08:38:34 -0800 Subject: [PATCH 013/204] add html markup to the comment --- libraries/eosiolib/contracts/eosio/system.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/eosiolib/contracts/eosio/system.hpp b/libraries/eosiolib/contracts/eosio/system.hpp index c35f7ce015..84eb1ebb5b 100644 --- a/libraries/eosiolib/contracts/eosio/system.hpp +++ b/libraries/eosiolib/contracts/eosio/system.hpp @@ -37,11 +37,12 @@ namespace eosio { * This is used to bypass all cleanup / destructors that would normally be * called. * - * WARNING: this method will immediately abort execution of wasm code that is on - * the stack and would be executed as the method normally returned. - * Problems can occur with write-caches, RAII, reference counting - * when this method aborts execution of wasm code immediately. - * +

+ WARNING: this method will immediately abort execution of wasm code that is on + the stack and would be executed as the method normally returned. + Problems can occur with write-caches, RAII, reference counting + when this method aborts execution of wasm code immediately. +

* @ingroup system * * @param code - the exit code From 9f12f3258f98cd4a13747f7ef528160d207282db Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 13 Jan 2021 18:07:30 +0200 Subject: [PATCH 014/204] English improvement --- docs/02_installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02_installation.md b/docs/02_installation.md index ac9595735b..9bb8b0f970 100644 --- a/docs/02_installation.md +++ b/docs/02_installation.md @@ -85,7 +85,7 @@ $ sudo rm /usr/local/bin/eosio-* * eosio-objdump * eosio-readelf -The following tools are not installed after brew install, you get them when build the repository and install it from scratch, [see here](#guided-installation-or-building-from-scratch): +The following tools are not installed after brew install, you get them when you build the repository and install it from scratch, [see here](#guided-installation-or-building-from-scratch): * eosio-abidiff * eosio-ranlib From 68fd8d0b3d2ed9a0c4244ff2b4bb0eeff4da658d Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 15 Jan 2021 01:34:34 +0200 Subject: [PATCH 015/204] delete the `$` from featured command lines --- docs/02_installation.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/02_installation.md b/docs/02_installation.md index 9bb8b0f970..a611c652a2 100644 --- a/docs/02_installation.md +++ b/docs/02_installation.md @@ -9,51 +9,51 @@ EOSIO.CDT currently supports Mac OS X brew, Linux x86_64 Debian packages, and Li ## Mac OS X Brew Install ```sh -$ brew tap eosio/eosio.cdt -$ brew install eosio.cdt +brew tap eosio/eosio.cdt +brew install eosio.cdt ``` ## Mac OS X Brew Uninstall ```sh -$ brew remove eosio.cdt +brew remove eosio.cdt ``` ## Debian Package Install ```sh -$ wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb -$ sudo apt install ./eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb +wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb +sudo apt install ./eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb ``` ## Debian Package Uninstall ```sh -$ sudo apt remove eosio.cdt +sudo apt remove eosio.cdt ``` ## RPM Package Install ```sh -$ wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt-1.8.0-rc1.el7.x86_64.rpm -$ sudo yum install ./eosio.cdt-1.8.0-rc1.el7.x86_64.rpm +wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt-1.8.0-rc1.el7.x86_64.rpm +sudo yum install ./eosio.cdt-1.8.0-rc1.el7.x86_64.rpm ``` ## RPM Package Uninstall ```sh -$ sudo yum remove eosio.cdt +sudo yum remove eosio.cdt ``` # Guided Installation or Building from Scratch ```sh -$ git clone --recursive https://github.com/eosio/eosio.cdt -$ cd eosio.cdt -$ mkdir build -$ cd build -$ cmake .. -$ make -j8 +git clone --recursive https://github.com/eosio/eosio.cdt +cd eosio.cdt +mkdir build +cd build +cmake .. +make -j8 ``` From here onward you can build your contracts code by simply exporting the `build` directory to your path, so you don't have to install globally (makes things cleaner). @@ -66,9 +66,9 @@ sudo make install ## Uninstall after manual installation ```sh -$ sudo rm -fr /usr/local/eosio.cdt -$ sudo rm -fr /usr/local/lib/cmake/eosio.cdt -$ sudo rm /usr/local/bin/eosio-* +sudo rm -fr /usr/local/eosio.cdt +sudo rm -fr /usr/local/lib/cmake/eosio.cdt +sudo rm /usr/local/bin/eosio-* ``` # Installed Tools From 7f3398692cfac965455fc1ff017e1622902b2c22 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 15 Jan 2021 16:15:45 -0500 Subject: [PATCH 016/204] add unit tests; clean up code --- .../toolchain/abigen-fail/empty_contract.cpp | 4 +++ .../toolchain/abigen-fail/empty_contract.json | 22 ++++++++++++ .../empty_contract_with_other_contract.cpp | 24 +++++++++++++ .../empty_contract_with_other_contract.json | 22 ++++++++++++ .../abigen-fail/wrong_contract_name.cpp | 22 ++++++++++++ .../abigen-fail/wrong_contract_name.json | 22 ++++++++++++ tools/cc/eosio-cpp.cpp.in | 36 ++++++++++--------- tools/toolchain-tester/tests.py | 9 +++++ tools/toolchain-tester/testsuite.py | 2 ++ 9 files changed, 147 insertions(+), 16 deletions(-) create mode 100644 tests/toolchain/abigen-fail/empty_contract.cpp create mode 100644 tests/toolchain/abigen-fail/empty_contract.json create mode 100644 tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp create mode 100644 tests/toolchain/abigen-fail/empty_contract_with_other_contract.json create mode 100644 tests/toolchain/abigen-fail/wrong_contract_name.cpp create mode 100644 tests/toolchain/abigen-fail/wrong_contract_name.json diff --git a/tests/toolchain/abigen-fail/empty_contract.cpp b/tests/toolchain/abigen-fail/empty_contract.cpp new file mode 100644 index 0000000000..ada82aec5d --- /dev/null +++ b/tests/toolchain/abigen-fail/empty_contract.cpp @@ -0,0 +1,4 @@ +#include +using namespace eosio; + +CONTRACT hello : public contract {}; diff --git a/tests/toolchain/abigen-fail/empty_contract.json b/tests/toolchain/abigen-fail/empty_contract.json new file mode 100644 index 0000000000..890b7d8c7c --- /dev/null +++ b/tests/toolchain/abigen-fail/empty_contract.json @@ -0,0 +1,22 @@ +{ + "tests" : [ + { + "compile_flags": ["--abigen", "--contract=hello"], + "expected" : { + "stderr": "wasm-ld: error" + } + }, + { + "compile_flags": ["--abigen", "-o=hello.wasm"], + "expected" : { + "stderr": "wasm-ld: error" + } + }, + { + "compile_flags": ["--abigen"], + "expected" : { + "stderr": "wasm-ld: error" + } + } + ] +} diff --git a/tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp b/tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp new file mode 100644 index 0000000000..69aa30dbf5 --- /dev/null +++ b/tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp @@ -0,0 +1,24 @@ +#include +using namespace eosio; + +CONTRACT hello : public contract {}; + +CONTRACT another_hello : public contract { + public: + using contract::contract; + + ACTION hi( name nm ); + ACTION check( name nm ); + + using hi_action = action_wrapper<"hi"_n, &hello::hi>; + using check_action = action_wrapper<"check"_n, &hello::check>; +}; + +ACTION hello::hi( name nm ) { + print_f("Name : %\n", nm); +} + +ACTION hello::check( name nm ) { + print_f("Name : %\n", nm); + eosio::check(nm == "hello"_n, "check name not equal to `hello`"); +} diff --git a/tests/toolchain/abigen-fail/empty_contract_with_other_contract.json b/tests/toolchain/abigen-fail/empty_contract_with_other_contract.json new file mode 100644 index 0000000000..1f8eb5bdf5 --- /dev/null +++ b/tests/toolchain/abigen-fail/empty_contract_with_other_contract.json @@ -0,0 +1,22 @@ +{ + "tests" : [ + { + "compile_flags": ["--abigen", "--contract=hello"], + "expected" : { + "stderr": "abigen error" + } + }, + { + "compile_flags": ["--abigen", "-o=hello.wasm"], + "expected" : { + "stderr": "abigen error" + } + }, + { + "compile_flags": ["--abigen"], + "expected" : { + "stderr": "abigen error" + } + } + ] +} diff --git a/tests/toolchain/abigen-fail/wrong_contract_name.cpp b/tests/toolchain/abigen-fail/wrong_contract_name.cpp new file mode 100644 index 0000000000..a86034b1aa --- /dev/null +++ b/tests/toolchain/abigen-fail/wrong_contract_name.cpp @@ -0,0 +1,22 @@ +#include +using namespace eosio; + +CONTRACT hello : public contract { + public: + using contract::contract; + + ACTION hi( name nm ); + ACTION check( name nm ); + + using hi_action = action_wrapper<"hi"_n, &hello::hi>; + using check_action = action_wrapper<"check"_n, &hello::check>; +}; + +ACTION hello::hi( name nm ) { + print_f("Name : %\n", nm); +} + +ACTION hello::check( name nm ) { + print_f("Name : %\n", nm); + eosio::check(nm == "hello"_n, "check name not equal to `hello`"); +} diff --git a/tests/toolchain/abigen-fail/wrong_contract_name.json b/tests/toolchain/abigen-fail/wrong_contract_name.json new file mode 100644 index 0000000000..4bdbc8e126 --- /dev/null +++ b/tests/toolchain/abigen-fail/wrong_contract_name.json @@ -0,0 +1,22 @@ +{ + "tests" : [ + { + "compile_flags": ["--abigen", "--contract=nothello"], + "expected" : { + "stderr": "abigen error" + } + }, + { + "compile_flags": ["--abigen", "-o=nothello.wasm"], + "expected" : { + "stderr": "abigen error" + } + }, + { + "compile_flags": ["--abigen"], + "expected" : { + "stderr": "abigen error" + } + } + ] +} diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index ad301201ef..85f7b4c1d7 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -39,6 +39,8 @@ using namespace llvm; using namespace eosio; using namespace eosio::cdt; +void handle_empty_abigen(const std::string& contract_name, bool has_o_opt, bool has_contract_opt); + void generate(const std::vector& base_options, std::string input, std::string contract_name, const std::vector& resource_paths, const std::pair& abi_version, bool abigen, bool suppress_ricardian_warning, bool has_o_opt, bool has_contract_opt) { std::vector options; options.push_back("eosio-cpp"); @@ -77,22 +79,7 @@ void generate(const std::vector& base_options, std::string input, s abigen::get().to_json().dump(abi_s); codegen::get().set_abi(abi_s); } else if (abigen) { - const std::string& parsed_contract_name = abigen::get().get_parsed_contract_name(); - if (parsed_contract_name.empty()) { - // if the contract is empty, the contract name could not be obtained by parsing methods or records - // a warning is output here, and `wasm-ld` will output an error later - std::cout << "Warning, contract is empty and ABI is not generated\n"; - } else if (contract_name != parsed_contract_name) { - if (has_contract_opt) { - throw std::runtime_error("abigen error: '--contract' specified name doesn't match the real contract name"); - } else if (has_o_opt) { - throw std::runtime_error("abigen error: '-o' specified WASM name doesn't match the real contract name"); - } else { - throw std::runtime_error("abigen error: contract filename doesn't match the real contract name"); - } - } else { - throw std::runtime_error("abigen error"); // unknown error - } + handle_empty_abigen(contract_name, has_o_opt, has_contract_opt); } tool_run = ctool.run(newFrontendActionFactory().get()); @@ -101,6 +88,23 @@ void generate(const std::vector& base_options, std::string input, s } } +void handle_empty_abigen(const std::string& contract_name, bool has_o_opt, bool has_contract_opt) { + const std::string& parsed_contract_name = abigen::get().get_parsed_contract_name(); + if (parsed_contract_name.empty()) { + // if no contract name could be obtained by parsing methods/records, it means the contract is empty + std::cout << "Warning, contract is empty and ABI is not generated\n"; + } else if (contract_name != parsed_contract_name) { + // if contract is empty but the contract file contains other contracts, the parsed contract name could be wrong + std::string err = "abigen error: contract is empty, or "; + // or, the contract is not empty but the specified or inferred contract name is wrong + err += has_contract_opt ? "'--contract' specified name" : (has_o_opt ? "'-o' specified name" : "contract filename"); + err += " doesn't match the real contract name"; + throw std::runtime_error(err); + } else { + throw std::runtime_error("abigen error"); // unknown error + } +} + int main(int argc, const char **argv) { // fix to show version info without having to have any other arguments diff --git a/tools/toolchain-tester/tests.py b/tools/toolchain-tester/tests.py index dfbb5601a5..0a21695363 100644 --- a/tools/toolchain-tester/tests.py +++ b/tools/toolchain-tester/tests.py @@ -194,3 +194,12 @@ def _run(self, eosio_cpp, args): self.handle_test_result(res, expected_pass=False) return res + +class AbigenFailTest(Test): + def _run(self, eosio_cpp, args): + command = [eosio_cpp, self.cpp_file, "-abigen_output=''"] + command.extend(args) + res = subprocess.run(command, capture_output=True) + self.handle_test_result(res, expected_pass=False) + + return res diff --git a/tools/toolchain-tester/testsuite.py b/tools/toolchain-tester/testsuite.py index 21e940577b..422cb94849 100644 --- a/tools/toolchain-tester/testsuite.py +++ b/tools/toolchain-tester/testsuite.py @@ -73,6 +73,8 @@ def __init__(self, directory: str, cdt_path: str): self.tests.append(tests.CompileFailTest(*args)) elif self.test_type == TestType.ABIGEN_PASS: self.tests.append(tests.AbigenPassTest(*args)) + elif self.test_type == TestType.ABIGEN_FAIL: + self.tests.append(tests.AbigenFailTest(*args)) def _get_test_type(self) -> TestType: return TestType.from_str(self.directory.split("/")[-1]) From c7ad21cc045724a2257714d44ee5a0cf4d0c716c Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 20 Jan 2021 16:01:54 +0200 Subject: [PATCH 017/204] fixes #819 --- libraries/eosiolib/capi/eosio/db.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/eosiolib/capi/eosio/db.h b/libraries/eosiolib/capi/eosio/db.h index d0a2ee8883..451b7a28f2 100644 --- a/libraries/eosiolib/capi/eosio/db.h +++ b/libraries/eosiolib/capi/eosio/db.h @@ -61,6 +61,11 @@ int32_t db_store_i64(uint64_t scope, capi_name table, capi_name payer, uint64_t * @pre `*((uint64_t*)data)` stores the primary key * @pre `iterator` points to an existing table row in the table * @post the record contained in the table row pointed to by `iterator` is replaced with the new updated record + * @details This function does not allow changing the primary key of a + * table row. The serialized data that is stored in the table row of a + * primary table may include a primary key and that primary key value + * could be changed by the contract calling the db_update_i64 intrinsic; + * but that does not change the actual primary key of the table row. */ __attribute__((eosio_wasm_import)) void db_update_i64(int32_t iterator, capi_name payer, const void* data, uint32_t len); From 4042ec72d541ae3e0b678e484d724a40b1656de8 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 20 Jan 2021 17:20:04 +0200 Subject: [PATCH 018/204] include c api (*.h files) and tell doxygen to ignore the __attribute__ macros --- docs.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs.json b/docs.json index 639938cb87..f9fb477152 100644 --- a/docs.json +++ b/docs.json @@ -11,7 +11,11 @@ "name": "doxygen_to_xml", "options": { "INPUT": "libraries/eosiolib", - "EXCLUDE_PATTERNS": "*.cpp *.c *.h" + "EXCLUDE_PATTERNS": "*.cpp *.c", + "ENABLE_PREPROCESSING": "YES", + "MACRO_EXPANSION": "YES", + "EXPAND_ONLY_PREDEF": "YES", + "PREDEFINED": "__attribute__(x)=" } }, { From 1ef65f139784b064f9e4ac84ba2f48e692cb6b61 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 26 Jan 2021 15:01:07 +0200 Subject: [PATCH 019/204] fix annotations for kv map, kv table and multi index --- .../contracts/eosio/doxy/map_iterator.dox | 102 -- libraries/eosiolib/contracts/eosio/map.hpp | 131 +- .../eosiolib/contracts/eosio/multi_index.hpp | 1532 +++++++++-------- libraries/eosiolib/contracts/eosio/table.hpp | 46 +- 4 files changed, 919 insertions(+), 892 deletions(-) delete mode 100644 libraries/eosiolib/contracts/eosio/doxy/map_iterator.dox diff --git a/libraries/eosiolib/contracts/eosio/doxy/map_iterator.dox b/libraries/eosiolib/contracts/eosio/doxy/map_iterator.dox deleted file mode 100644 index 8b5c15e265..0000000000 --- a/libraries/eosiolib/contracts/eosio/doxy/map_iterator.dox +++ /dev/null @@ -1,102 +0,0 @@ -// -*-c++-*- - -/** - * @brief This class represents the iterator for the `eosio::kv::map` data type. - * @details You will use the sets of functions and operations associated with this type to - * iterate through values in the map and reference them. - * - * Note that this iterator type in `eosio::kv::map` is defined as `eosio::kv::map::iterator_t`. - * There is also a reverse iterator available, it is defined as `eosio::kv::map::reverse_iterator_t`. - * The only difference between iterator_t and reverse_iterator_t is the direction the ++ and -- operators go. - */ -class iterator { - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief Constructor for the iterator type. - * @param owner This is the owner of the table object. - */ - iterator(name owner); - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief Utility function to see if the iterator is valid or is pointing at `end` or one past the last or first element. - */ - bool is_valid() const; - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief This will take a `key_type` key and find the value that is equal to or greater than that key. - * @details If no element is greater than or equal to the key the iterator will now hold `end`. - * @param key This is the key which you wish to query with. - */ - iterator& lower_bound(const key_type& key); - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief This will take a `key_type` key and find the value that is strictly greater than that key. - * @details If no element is strictly greater than the key the iterator will now hold `end`. - * @param key This is the key which you wish to query with. - */ - iterator& upper_bound(const key_type& key); - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief This will take a `key_type` key and find the value that exactly matches that key. - * @details If no element is equal to the key the iterator will now hold `end`. - * @param key This is the key which you wish to query with. - */ - iterator& find(const key_type& key); - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief Function to advance the iterator to the beginning of the map's key value pairs. - */ - iterator& seek_to_begin(); - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief Function to advance the iterator to the element past the last element of the map's key value pairs. - */ - iterator& seek_to_end(); - - /* @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief Function to advance the iterator to the last element of the map's key value pairs. - */ - iterator& seek_to_last(); - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief Function to increment the iterator to the next element (sorted in lexicographic order). - * @details Note this is the prefix operator, i.e. `++it`, the `it++` operator is explicitly missing because - * of performance issues. If you increment past the last element this iterator will then be invalid and point to `end`. - */ - iterator& operator++(); - - /** - * @defgroup keyvalue Key Value Map - * @ingroup contracts - * - * @brief Function to decrement the iterator to the next element (sorted in lexicographic order). - * @details Note this is the prefix operator, i.e. `--it`, the `it--` operator is explicitly missing because - * of performance issues. If you decrement past the first element this iterator will then be invalid and point to `end`. - */ - iterator& operator--(); -}; diff --git a/libraries/eosiolib/contracts/eosio/map.hpp b/libraries/eosiolib/contracts/eosio/map.hpp index c4995a2838..d3537cd1d5 100644 --- a/libraries/eosiolib/contracts/eosio/map.hpp +++ b/libraries/eosiolib/contracts/eosio/map.hpp @@ -11,6 +11,11 @@ #include #include +/** + * @defgroup keyvaluemap Key Value Map + * @ingroup contracts + */ + namespace eosio::kv { namespace internal_use_do_not_use { extern "C" { @@ -61,7 +66,6 @@ namespace eosio::kv { } } - /* @cond PRIVATE */ // tag used by some of the types to delineate overloads between key_type (std::string) and the map's key type struct packed_tag {}; @@ -132,6 +136,15 @@ namespace eosio::kv { return internal_use_do_not_use::kv_it_lower_bound(itr, "", 0, _k, _v); } + /** + * @ingroup keyvaluemap + * + * @brief This struct represents the data type stored in map. + * @details You will use the sets of functions and operations associated with this type to + * access the items stored in the map. + * + * Note that this type in `eosio::kv::map` is defined as `eosio::kv::map::elem_t`. + */ template struct elem { using key_t = typename KV::key_t; @@ -157,6 +170,17 @@ namespace eosio::kv { name payer; }; + /** + * @ingroup keyvaluemap + * + * @brief This struct represents the iterator for the `eosio::kv::map` data type. + * @details You will use the sets of functions and operations associated with this type to + * iterate through values in the map and reference them. + * + * Note that this iterator type in `eosio::kv::map` is defined as `eosio::kv::map::iterator_t`. + * There is also a reverse iterator available, it is defined as `eosio::kv::map::reverse_iterator_t`. + * The only difference between iterator_t and reverse_iterator_t is the direction the ++ and -- operators go. + */ template struct iterator { using elem_t = elem; @@ -176,6 +200,12 @@ namespace eosio::kv { return Stat == static_cast(stat); } + /** + * @ingroup keyvaluemap + * + * @brief Constructor for the iterator type. + * @param owner This is the owner of the table object. + */ inline iterator(name owner) : element(), handle(itr_create(owner, {KV::prefix().data(), KV::prefix().size()})) {} @@ -216,29 +246,64 @@ namespace eosio::kv { itr_destroy(handle); } + /** + * @ingroup keyvaluemap + * + * @brief Utility function to see if the iterator is valid or is pointing + * at `end` or one past the last or first element. + */ inline bool is_valid() const { return query_status(current_status); } + /** + * @ingroup keyvaluemap + * + * @brief Function to advance the iterator to the beginning of the map's key value pairs. + */ iterator& seek_to_begin() { current_status = static_cast(itr_lower_bound(handle)); return *this; } + /** + * @ingroup keyvaluemap + * + * @brief Function to advance the iterator to the last element of the map's key value pairs. + */ iterator& seek_to_last() { current_status = static_cast(itr_move_to_end(handle)); current_status = static_cast(itr_prev(handle)); return *this; } + /** + * @ingroup keyvaluemap + * + * @brief Function to advance the iterator to the element past the last element of the map's key value pairs. + */ iterator& seek_to_end() { current_status = static_cast(itr_move_to_end(handle)); return *this; } + /** + * @ingroup keyvaluemap + * + * @brief This will take a `key_type` key and find the value that is equal to or greater than that key. + * @details If no element is greater than or equal to the key the iterator will now hold `end`. + * @param key This is the key which you wish to query with. + */ iterator& lower_bound(const key_type& k) { current_status = static_cast(itr_lower_bound(handle, {k.data(), k.size()})); return *this; } + /** + * @ingroup keyvaluemap + * + * @brief This will take a `key_type` key and find the value that exactly matches that key. + * @details If no element is equal to the key the iterator will now hold `end`. + * @param key This is the key which you wish to query with. + */ iterator& find(const key_type& k) { lower_bound(k); if (itr_key_compare(handle, {k.data(), k.size()}) != 0) @@ -263,6 +328,13 @@ namespace eosio::kv { return &element; } + /** + * @ingroup keyvaluemap + * + * @brief Function to increment the iterator to the next element (sorted in lexicographic order). + * @details Note this is the prefix operator, i.e. `++it`, the `it++` operator is explicitly missing because + * of performance issues. If you increment past the last element this iterator will then be invalid and point to `end`. + */ iterator& operator++() { if constexpr (Reverse) { current_status = static_cast(itr_prev(handle)); @@ -276,6 +348,13 @@ namespace eosio::kv { return *this; } + /** + * @ingroup keyvaluemap + * + * @brief Function to decrement the iterator to the next element (sorted in lexicographic order). + * @details Note this is the prefix operator, i.e. `--it`, the `it--` operator is explicitly missing because + * of performance issues. If you decrement past the first element this iterator will then be invalid and point to `end`. + */ iterator& operator--() { if constexpr (Reverse) { check(query_status(current_status), "decrementing past end or an erased iterator"); @@ -289,6 +368,11 @@ namespace eosio::kv { return *this; } + /** + * @ingroup keyvaluemap + * + * @brief Function to test equality. + */ inline bool operator==(const iterator& o) const { // ignoring key_size and value_size as they shouldn't play a role in equality return (std::tie(handle, current_status) == std::tie(o.handle, o.current_status)) || @@ -296,6 +380,11 @@ namespace eosio::kv { !itr_compare(handle, o.handle); } + /** + * @ingroup keyvaluemap + * + * @brief Function to test inequality. + */ inline bool operator!=(const iterator& o) const { return !((*this) == o); } void materialize() const { @@ -317,12 +406,21 @@ namespace eosio::kv { status current_status = status::ok; }; } // namespace eosio::kv::detail -/* @endcond */ - -#if EOSIO_CDT_DOXYGEN -#include "doxy/map_iterator.dox" -#endif + /** + * @ingroup keyvaluemap + * + * @brief Defines an EOSIO Key Value Map + * @details EOSIO Key Value API provides a C++ interface to the EOSIO Key Value database. + * The Key Value Map offered by the KV API serves as a storage location which is organized + * as a sorted associative container that contains key-value pairs with unique keys. + * Keys are sorted lexicographically. Search, removal, and insertion operations have + * logarithmic complexity, O(log(n)). 'KV Map' is designed to offer a comparable + * interface to std::map template class. + * + * @tparam K - the type of the data stored as the key of the map + * @tparam V - the type of the data stored as the value of the map + */ template class [[eosio::table]] map { public: @@ -436,6 +534,13 @@ namespace eosio::kv { return it == end(); } + /** + * @ingroup keyvaluemap + * + * @brief This will take a `key_t` key and find the value that exactly matches that key. + * @details If no element is equal to the key the iterator will now hold `end`. + * @param key This is the key which you wish to query with. + */ iterator_t find(const key_t& k) const { auto fk = full_key(k); iterator_t it = {owner}; @@ -457,12 +562,26 @@ namespace eosio::kv { return it; } + /** + * @ingroup keyvaluemap + * + * @brief This will take a `key_t` key and find the value that is equal to or greater than that key. + * @details If no element is greater than or equal to the key the iterator will now hold `end`. + * @param key This is the key which you wish to query with. + */ inline iterator_t lower_bound(const key_t& k) const { iterator_t it = {owner}; it.lower_bound(full_key(k)); return it; } + /** + * @ingroup keyvaluemap + * + * @brief This will take a `key_t` key and find the value that is strictly greater than that key. + * @details If no element is strictly greater than the key the iterator will now hold `end`. + * @param key This is the key which you wish to query with. + */ inline iterator_t upper_bound(const key_t& k) const { auto fk = full_key(k); detail::increment_bytes(fk); // add '1' to the last byte, this should get us to the next value up diff --git a/libraries/eosiolib/contracts/eosio/multi_index.hpp b/libraries/eosiolib/contracts/eosio/multi_index.hpp index 4838197119..bdc72caf1f 100644 --- a/libraries/eosiolib/contracts/eosio/multi_index.hpp +++ b/libraries/eosiolib/contracts/eosio/multi_index.hpp @@ -1,6 +1,6 @@ /** - * @file - * @copyright defined in eos/LICENSE + * @file + * @copyright defined in eos/LICENSE */ #pragma once @@ -20,6 +20,11 @@ #include #include +/** + * @defgroup multiindex Multi Index Table + * @ingroup contracts + */ + namespace eosio { namespace internal_use_do_not_use { extern "C" { @@ -333,36 +338,36 @@ namespace _multi_index_detail { } /** - * The indexed_by struct is used to instantiate the indices for the Multi-Index table. In EOSIO, up to 16 secondary indices can be specified. + * The indexed_by struct is used to instantiate the indices for the Multi-Index table. In EOSIO, up to 16 secondary indices can be specified. + * + * @ingroup multiindex + * @tparam IndexName - is the name of the index. The name must be provided as an EOSIO base32 encoded 64-bit integer and must conform to the EOSIO naming requirements of a maximum of 13 characters, the first twelve from the lowercase characters a-z, digits 1-5, and ".", and if there is a 13th character, it is restricted to lowercase characters a-p and ".". + * @tparam Extractor - is a function call operator that takes a const reference to the table object type and returns either a secondary key type or a reference to a secondary key type. It is recommended to use the `eosio::const_mem_fun` template, which is a type alias to the `boost::multi_index::const_mem_fun`. See the documentation for the Boost `const_mem_fun` key extractor for more details. * - * @ingroup multiindex - * @tparam IndexName - is the name of the index. The name must be provided as an EOSIO base32 encoded 64-bit integer and must conform to the EOSIO naming requirements of a maximum of 13 characters, the first twelve from the lowercase characters a-z, digits 1-5, and ".", and if there is a 13th character, it is restricted to lowercase characters a-p and ".". - * @tparam Extractor - is a function call operator that takes a const reference to the table object type and returns either a secondary key type or a reference to a secondary key type. It is recommended to use the `eosio::const_mem_fun` template, which is a type alias to the `boost::multi_index::const_mem_fun`. See the documentation for the Boost `const_mem_fun` key extractor for more details. + * Example: * - * Example: - * -* - * @code - * #include - * using namespace eosio; - * class mycontract: eosio::contract { - * struct record { - * uint64_t primary; - * uint128_t secondary; - * uint64_t primary_key() const { return primary; } - * uint128_t get_secondary() const { return secondary; } - * }; - * public: - * mycontract(name receiver, name code, datastream ds):contract(receiver, code, ds){} - * void myaction() { - * auto code = _self; - * auto scope = _self; - * multi_index<"mytable"_n, record, - * indexed_by< "bysecondary"_n, const_mem_fun > > table( code, scope); - * } - * } - * EOSIO_DISPATCH( mycontract, (myaction) ) - * @endcode + * + * @code + * #include + * using namespace eosio; + * class mycontract: eosio::contract { + * struct record { + * uint64_t primary; + * uint128_t secondary; + * uint64_t primary_key() const { return primary; } + * uint128_t get_secondary() const { return secondary; } + * }; + * public: + * mycontract(name receiver, name code, datastream ds):contract(receiver, code, ds){} + * void myaction() { + * auto code = _self; + * auto scope = _self; + * multi_index<"mytable"_n, record, + * indexed_by< "bysecondary"_n, const_mem_fun > > table( code, scope); + * } + * } + * EOSIO_DISPATCH( mycontract, (myaction) ) + * @endcode */ template struct indexed_by { @@ -371,60 +376,59 @@ struct indexed_by { }; /** - * @defgroup multiindex Multi Index Table - * @ingroup contracts + * @ingroup multiindex * - * @brief Defines EOSIO Multi Index Table - * @details EOSIO Multi-Index API provides a C++ interface to the EOSIO database. It is patterned after Boost Multi Index Container. - * EOSIO Multi-Index table requires exactly a uint64_t primary key. For the table to be able to retrieve the primary key, - * the object stored inside the table is required to have a const member function called primary_key() that returns uint64_t. - * EOSIO Multi-Index table also supports up to 16 secondary indices. The type of the secondary indices could be any of: - * - uint64_t - * - uint128_t - * - double - * - long double - * - eosio::checksum256 + * @brief Defines EOSIO Multi Index Table + * @details EOSIO Multi-Index API provides a C++ interface to the EOSIO database. It is patterned after Boost Multi Index Container. + * EOSIO Multi-Index table requires exactly a uint64_t primary key. For the table to be able to retrieve the primary key, + * the object stored inside the table is required to have a const member function called primary_key() that returns uint64_t. + * EOSIO Multi-Index table also supports up to 16 secondary indices. The type of the secondary indices could be any of: + * - uint64_t + * - uint128_t + * - double + * - long double + * - eosio::checksum256 * - * @tparam TableName - name of the table - * @tparam T - type of the data stored inside the table - * @tparam Indices - secondary indices for the table, up to 16 indices is supported here + * @tparam TableName - name of the table + * @tparam T - type of the data stored inside the table + * @tparam Indices - secondary indices for the table, up to 16 indices is supported here * - * Example: - * - * @code - * #include - * using namespace eosio; - * class mycontract: contract { - * struct record { - * uint64_t primary; - * uint64_t secondary_1; - * uint128_t secondary_2; - * checksum256 secondary_3; - * double secondary_4; - * long double secondary_5; - * uint64_t primary_key() const { return primary; } - * uint64_t get_secondary_1() const { return secondary_1; } - * uint128_t get_secondary_2() const { return secondary_2; } - * checksum256 get_secondary_3() const { return secondary_3; } - * double get_secondary_4() const { return secondary_4; } - * long double get_secondary_5() const { return secondary_5; } - * }; - * public: - * mycontract(name receiver, name code, datastream ds):contract(receiver, code, ds){} - * void myaction() { - * auto code = _self; - * auto scope = _self; - * multi_index<"mytable"_n, record, - * indexed_by< "bysecondary1"_n, const_mem_fun >, - * indexed_by< "bysecondary2"_n, const_mem_fun >, - * indexed_by< "bysecondary3"_n, const_mem_fun >, - * indexed_by< "bysecondary4"_n, const_mem_fun >, - * indexed_by< "bysecondary5"_n, const_mem_fun > - * > table( code, scope); - * } - * } - * EOSIO_DISPATCH( mycontract, (myaction) ) - * @endcode + * Example: + * + * @code + * #include + * using namespace eosio; + * class mycontract: contract { + * struct record { + * uint64_t primary; + * uint64_t secondary_1; + * uint128_t secondary_2; + * checksum256 secondary_3; + * double secondary_4; + * long double secondary_5; + * uint64_t primary_key() const { return primary; } + * uint64_t get_secondary_1() const { return secondary_1; } + * uint128_t get_secondary_2() const { return secondary_2; } + * checksum256 get_secondary_3() const { return secondary_3; } + * double get_secondary_4() const { return secondary_4; } + * long double get_secondary_5() const { return secondary_5; } + * }; + * public: + * mycontract(name receiver, name code, datastream ds):contract(receiver, code, ds){} + * void myaction() { + * auto code = _self; + * auto scope = _self; + * multi_index<"mytable"_n, record, + * indexed_by< "bysecondary1"_n, const_mem_fun >, + * indexed_by< "bysecondary2"_n, const_mem_fun >, + * indexed_by< "bysecondary3"_n, const_mem_fun >, + * indexed_by< "bysecondary4"_n, const_mem_fun >, + * indexed_by< "bysecondary5"_n, const_mem_fun > + * > table( code, scope); + * } + * } + * EOSIO_DISPATCH( mycontract, (myaction) ) + * @endcode */ template @@ -696,9 +700,9 @@ class multi_index return {this, &mi}; } /** - * Warning: the interator_to can have undefined behavior if the caller - * passes in a reference to a stack-allocated object rather than the - * reference returned by get or by dereferencing a const_iterator. + * Warning: the interator_to can have undefined behavior if the caller + * passes in a reference to a stack-allocated object rather than the + * reference returned by get or by dereferencing a const_iterator. */ const_iterator iterator_to( const T& obj ) { using namespace _multi_index_detail; @@ -828,95 +832,95 @@ class multi_index public: /** - * Constructs an instance of a Multi-Index table. - * @ingroup multiindex - * - * @param code - Account that owns table - * @param scope - Scope identifier within the code hierarchy - * - * @pre code and scope member properties are initialized - * @post each secondary index table initialized - * @post Secondary indices are updated to refer to the newly added object. If the secondary index tables do not exist, they are created. - * @post The payer is charged for the storage usage of the new object and, if the table (and secondary index tables) must be created, for the overhead of the table creation. - * - * Notes - * The `eosio::multi_index` template has template parameters ``, where: - * - `TableName` is the name of the table, maximum 12 characters long, characters in the name from the set of lowercase letters, digits 1 to 5, and the "." (period) character and is converted to a eosio::raw - which wraps uint64_t; - * - `T` is the object type (i.e., row definition); - * - `Indices` is a list of up to 16 secondary indices. - * - Each must be a default constructable class or struct - * - Each must have a function call operator that takes a const reference to the table object type and returns either a secondary key type or a reference to a secondary key type - * - It is recommended to use the eosio::const_mem_fun template, which is a type alias to the boost::multi_index::const_mem_fun. See the documentation for the Boost const_mem_fun key extractor for more details. - * - * Example: - * - * @code - * #include - * using namespace eosio; - * using namespace std; - * class addressbook: contract { - * struct address { - * uint64_t account_name; - * string first_name; - * string last_name; - * string street; - * string city; - * string state; - * uint64_t primary_key() const { return account_name; } - * }; - * public: - * addressbook(name self):contract(self) {} - * typedef eosio::multi_index< "address"_n, address > address_index; - * void myaction() { - * address_index addresses(_self, _self.value); // code, scope - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Constructs an instance of a Multi-Index table. + * @ingroup multiindex + * + * @param code - Account that owns table + * @param scope - Scope identifier within the code hierarchy + * + * @pre code and scope member properties are initialized + * @post each secondary index table initialized + * @post Secondary indices are updated to refer to the newly added object. If the secondary index tables do not exist, they are created. + * @post The payer is charged for the storage usage of the new object and, if the table (and secondary index tables) must be created, for the overhead of the table creation. + * + * Notes + * The `eosio::multi_index` template has template parameters ``, where: + * - `TableName` is the name of the table, maximum 12 characters long, characters in the name from the set of lowercase letters, digits 1 to 5, and the "." (period) character and is converted to a eosio::raw - which wraps uint64_t; + * - `T` is the object type (i.e., row definition); + * - `Indices` is a list of up to 16 secondary indices. + * - Each must be a default constructable class or struct + * - Each must have a function call operator that takes a const reference to the table object type and returns either a secondary key type or a reference to a secondary key type + * - It is recommended to use the eosio::const_mem_fun template, which is a type alias to the boost::multi_index::const_mem_fun. See the documentation for the Boost const_mem_fun key extractor for more details. + * + * Example: + * + * @code + * #include + * using namespace eosio; + * using namespace std; + * class addressbook: contract { + * struct address { + * uint64_t account_name; + * string first_name; + * string last_name; + * string street; + * string city; + * string state; + * uint64_t primary_key() const { return account_name; } + * }; + * public: + * addressbook(name self):contract(self) {} + * typedef eosio::multi_index< "address"_n, address > address_index; + * void myaction() { + * address_index addresses(_self, _self.value); // code, scope + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ multi_index( name code, uint64_t scope ) :_code(code),_scope(scope),_next_primary_key(unset_next_primary_key) {} /** - * Returns the `code` member property. - * @ingroup multiindex + * Returns the `code` member property. + * @ingroup multiindex * - * @return Account name of the Code that owns the Primary Table. + * @return Account name of the Code that owns the Primary Table. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * address_index addresses("dan"_n, "dan"_n.value); // code, scope - * eosio::check(addresses.get_code() == "dan"_n, "Codes don't match."); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * void myaction() { + * address_index addresses("dan"_n, "dan"_n.value); // code, scope + * eosio::check(addresses.get_code() == "dan"_n, "Codes don't match."); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ name get_code()const { return _code; } /** - * Returns the `scope` member property. - * @ingroup multiindex + * Returns the `scope` member property. + * @ingroup multiindex * - * @return Scope id of the Scope within the Code of the Current Receiver under which the desired Primary Table instance can be found. + * @return Scope id of the Scope within the Code of the Current Receiver under which the desired Primary Table instance can be found. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * address_index addresses("dan"_n, "dan"_n.value); // code, scope - * eosio::check(addresses.get_scope() == "dan"_n.value, "Scopes don't match"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * void myaction() { + * address_index addresses("dan"_n, "dan"_n.value); // code, scope + * eosio::check(addresses.get_scope() == "dan"_n.value, "Scopes don't match"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ uint64_t get_scope()const { return _scope; } @@ -984,283 +988,283 @@ class multi_index typedef std::reverse_iterator const_reverse_iterator; /** - * Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. - * @ingroup multiindex + * Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. + * @ingroup multiindex * - * @return An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. + * @return An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr == addresses.cbegin(), "Only address is not at front."); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * auto itr = addresses.find("dan"_n); + * eosio::check(itr == addresses.cbegin(), "Only address is not at front."); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_iterator cbegin()const { return lower_bound(std::numeric_limits::lowest()); } /** - * Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. - * @ingroup multiindex + * Returns an iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. + * @ingroup multiindex * - * @return An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. + * @return An iterator pointing to the object_type with the lowest primary key value in the Multi-Index table. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr == addresses.begin(), "Only address is not at front."); - * } - * } - * EOSIO_ABI( addressbook, (myaction) ) - * @endcode + * auto itr = addresses.find("dan"_n); + * eosio::check(itr == addresses.begin(), "Only address is not at front."); + * } + * } + * EOSIO_ABI( addressbook, (myaction) ) + * @endcode */ const_iterator begin()const { return cbegin(); } /** - * Returns an iterator referring to the `past-the-end` element in the multi index container. The `past-the-end` element is the theoretical element that would follow the last element in the vector. It does not point to any element, and thus shall not be dereferenced. - * @ingroup multiindex + * Returns an iterator referring to the `past-the-end` element in the multi index container. The `past-the-end` element is the theoretical element that would follow the last element in the vector. It does not point to any element, and thus shall not be dereferenced. + * @ingroup multiindex * - * @return An iterator referring to the `past-the-end` element in the multi index container. + * @return An iterator referring to the `past-the-end` element in the multi index container. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr != addresses.cend(), "Address for account doesn't exist"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * auto itr = addresses.find("dan"_n); + * eosio::check(itr != addresses.cend(), "Address for account doesn't exist"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_iterator cend()const { return const_iterator( this ); } /** - * Returns an iterator referring to the `past-the-end` element in the multi index container. The `past-the-end` element is the theoretical element that would follow the last element in the vector. It does not point to any element, and thus shall not be dereferenced. - * @ingroup multiindex + * Returns an iterator referring to the `past-the-end` element in the multi index container. The `past-the-end` element is the theoretical element that would follow the last element in the vector. It does not point to any element, and thus shall not be dereferenced. + * @ingroup multiindex * - * @return An iterator referring to the `past-the-end` element in the multi index container. + * @return An iterator referring to the `past-the-end` element in the multi index container. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr != addresses.end(), "Address for account doesn't exist"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * auto itr = addresses.find("dan"_n); + * eosio::check(itr != addresses.end(), "Address for account doesn't exist"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_iterator end()const { return cend(); } /** - * Returns a reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. - * @ingroup multiindex - * - * @return A reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * }); - * auto itr = addresses.crbegin(); - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Last Record "); - * itr++; - * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect Second Last Record"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns a reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. + * @ingroup multiindex + * + * @return A reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * }); + * auto itr = addresses.crbegin(); + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Last Record "); + * itr++; + * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect Second Last Record"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_reverse_iterator crbegin()const { return std::make_reverse_iterator(cend()); } /** - * Returns a reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. - * @ingroup multiindex - * - * @return A reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * }); - * auto itr = addresses.rbegin(); - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Last Record "); - * itr++; - * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect Second Last Record"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns a reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. + * @ingroup multiindex + * + * @return A reverse iterator pointing to the `object_type` with the highest primary key value in the Multi-Index table. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * }); + * auto itr = addresses.rbegin(); + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Last Record "); + * itr++; + * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect Second Last Record"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_reverse_iterator rbegin()const { return crbegin(); } /** - * Returns an iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. - * @ingroup multiindex - * - * @return An iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * }); - * auto itr = addresses.crend(); - * itr--; - * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Record "); - * itr--; - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Record"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns an iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. + * @ingroup multiindex + * + * @return An iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * }); + * auto itr = addresses.crend(); + * itr--; + * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Record "); + * itr--; + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Record"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_reverse_iterator crend()const { return std::make_reverse_iterator(cbegin()); } /** - * Returns an iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. - * @ingroup multiindex - * - * @return An iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * }); - * auto itr = addresses.rend(); - * itr--; - * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Record "); - * itr--; - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Record"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns an iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. + * @ingroup multiindex + * + * @return An iterator pointing to the `object_type` with the lowest primary key value in the Multi-Index table. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * }); + * auto itr = addresses.rend(); + * itr--; + * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Record "); + * itr--; + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Record"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_reverse_iterator rend()const { return crend(); } /** - * Searches for the `object_type` with the lowest primary key that is greater than or equal to a given primary key. - * @ingroup multiindex - * - * @param primary - Primary key that establishes the target value for the lower bound search. - * @return An iterator pointing to the `object_type` that has the lowest primary key that is greater than or equal to `primary`. If an object could not be found, or if the table does not exist**, it will return the `end` iterator. - * - * Example: - * - * @code - * // This assumes the code from the get_index() example below. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * address.zip = 93445; - * }); - * uint32_t zipnumb = 93445; - * auto zip_index = addresses.get_index(); - * auto itr = zip_index.lower_bound(zipnumb); - * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Lower Bound Record "); - * itr++; - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Lower Bound Record"); - * itr++; - * eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Searches for the `object_type` with the lowest primary key that is greater than or equal to a given primary key. + * @ingroup multiindex + * + * @param primary - Primary key that establishes the target value for the lower bound search. + * @return An iterator pointing to the `object_type` that has the lowest primary key that is greater than or equal to `primary`. If an object could not be found, or if the table does not exist**, it will return the `end` iterator. + * + * Example: + * + * @code + * // This assumes the code from the get_index() example below. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * address.zip = 93445; + * }); + * uint32_t zipnumb = 93445; + * auto zip_index = addresses.get_index(); + * auto itr = zip_index.lower_bound(zipnumb); + * eosio::check(itr->account_name == name("brendan"), "Lock arf, Incorrect First Lower Bound Record "); + * itr++; + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Second Lower Bound Record"); + * itr++; + * eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_iterator lower_bound( uint64_t primary )const { auto itr = internal_use_do_not_use::db_lowerbound_i64( _code.value, _scope, static_cast(TableName), primary ); @@ -1270,41 +1274,41 @@ class multi_index } /** - * Searches for the `object_type` with the lowest primary key that is greater than a given primary key. - * @ingroup multiindex - * - * @param primary - Primary key that establishes the target value for the upper bound search - * @return An iterator pointing to the `object_type` that has the lowest primary key that is greater than a given `primary` key. If an object could not be found, or if the table does not exist**, it will return the `end` iterator. - * - * Example: - * - * @code - * // This assumes the code from the get_index() example below. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * address.zip = 93445; - * }); - * uint32_t zipnumb = 93445; - * auto zip_index = addresses.get_index(); - * auto itr = zip_index.upper_bound(zipnumb); - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect First Upper Bound Record "); - * itr++; - * eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Searches for the `object_type` with the lowest primary key that is greater than a given primary key. + * @ingroup multiindex + * + * @param primary - Primary key that establishes the target value for the upper bound search + * @return An iterator pointing to the `object_type` that has the lowest primary key that is greater than a given `primary` key. If an object could not be found, or if the table does not exist**, it will return the `end` iterator. + * + * Example: + * + * @code + * // This assumes the code from the get_index() example below. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * address.zip = 93445; + * }); + * uint32_t zipnumb = 93445; + * auto zip_index = addresses.get_index(); + * auto itr = zip_index.upper_bound(zipnumb); + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect First Upper Bound Record "); + * itr++; + * eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_iterator upper_bound( uint64_t primary )const { auto itr = internal_use_do_not_use::db_upperbound_i64( _code.value, _scope, static_cast(TableName), primary ); @@ -1314,35 +1318,35 @@ class multi_index } /** - * Returns an available primary key. - * @ingroup multiindex - * - * @return An available (unused) primary key value. - * - * Notes: - * Intended to be used in tables in which the primary keys of the table are strictly intended to be auto-incrementing, and thus will never be set to custom values by the contract. Violating this expectation could result in the table appearing to be full due to inability to allocate an available primary key. - * Ideally this method would only be used to determine the appropriate primary key to use within new objects added to a table in which the primary keys of the table are strictly intended from the beginning to be autoincrementing and thus will not ever be set to custom arbitrary values by the contract. Violating this agreement could result in the table appearing full when in reality there is plenty of space left. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * address_index addresses(_self, _self.value); // code, scope - * // add to table, first argument is account to bill for storage - * addresses.emplace(payer, [&](auto& address) { - * address.key = addresses.available_primary_key(); - * address.first_name = "Daniel"; - * address.last_name = "Larimer"; - * address.street = "1 EOS Way"; - * address.city = "Blacksburg"; - * address.state = "VA"; - * }); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns an available primary key. + * @ingroup multiindex + * + * @return An available (unused) primary key value. + * + * Notes: + * Intended to be used in tables in which the primary keys of the table are strictly intended to be auto-incrementing, and thus will never be set to custom values by the contract. Violating this expectation could result in the table appearing to be full due to inability to allocate an available primary key. + * Ideally this method would only be used to determine the appropriate primary key to use within new objects added to a table in which the primary keys of the table are strictly intended from the beginning to be autoincrementing and thus will not ever be set to custom arbitrary values by the contract. Violating this agreement could result in the table appearing full when in reality there is plenty of space left. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * address_index addresses(_self, _self.value); // code, scope + * // add to table, first argument is account to bill for storage + * addresses.emplace(payer, [&](auto& address) { + * address.key = addresses.available_primary_key(); + * address.first_name = "Daniel"; + * address.last_name = "Larimer"; + * address.street = "1 EOS Way"; + * address.city = "Blacksburg"; + * address.state = "VA"; + * }); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ uint64_t available_primary_key()const { if( _next_primary_key == unset_next_primary_key ) { @@ -1364,45 +1368,45 @@ class multi_index } /** - * Returns an appropriately typed Secondary Index. - * @ingroup multiindex - * - * @tparam IndexName - the ID of the desired secondary index - * - * @return An index of the appropriate type: Primitive 64-bit unsigned integer key (idx64), Primitive 128-bit unsigned integer key (idx128), 128-bit fixed-size lexicographical key (idx128), 256-bit fixed-size lexicographical key (idx256), Floating point key, Double precision floating point key, Long Double (quadruple) precision floating point key - * - * Example: - * - * @code - * #include - * using namespace eosio; - * using namespace std; - * class addressbook: contract { - * struct address { - * uint64_t account_name; - * string first_name; - * string last_name; - * string street; - * string city; - * string state; - * uint32_t zip = 0; - * uint64_t primary_key() const { return account_name; } - * uint64_t by_zip() const { return zip; } - * }; - * public: - * addressbook(name receiver, name code, datastream ds):contract(receiver, code, ds) {} - * typedef eosio::multi_index< name("address"), address, indexed_by< name("zip"), const_mem_fun > address_index; - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * uint32_t zipnumb = 93446; - * auto zip_index = addresses.get_index(); - * auto itr = zip_index.find(zipnumb); - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Record "); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns an appropriately typed Secondary Index. + * @ingroup multiindex + * + * @tparam IndexName - the ID of the desired secondary index + * + * @return An index of the appropriate type: Primitive 64-bit unsigned integer key (idx64), Primitive 128-bit unsigned integer key (idx128), 128-bit fixed-size lexicographical key (idx128), 256-bit fixed-size lexicographical key (idx256), Floating point key, Double precision floating point key, Long Double (quadruple) precision floating point key + * + * Example: + * + * @code + * #include + * using namespace eosio; + * using namespace std; + * class addressbook: contract { + * struct address { + * uint64_t account_name; + * string first_name; + * string last_name; + * string street; + * string city; + * string state; + * uint32_t zip = 0; + * uint64_t primary_key() const { return account_name; } + * uint64_t by_zip() const { return zip; } + * }; + * public: + * addressbook(name receiver, name code, datastream ds):contract(receiver, code, ds) {} + * typedef eosio::multi_index< name("address"), address, indexed_by< name("zip"), const_mem_fun > address_index; + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * uint32_t zipnumb = 93446; + * auto zip_index = addresses.get_index(); + * auto itr = zip_index.find(zipnumb); + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect Record "); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ template auto get_index() { @@ -1418,42 +1422,42 @@ class multi_index } /** - * Returns an appropriately typed Secondary Index. - * @ingroup multiindex - * - * @tparam IndexName - the ID of the desired secondary index - * - * @return An index of the appropriate type: Primitive 64-bit unsigned integer key (idx64), Primitive 128-bit unsigned integer key (idx128), 128-bit fixed-size lexicographical key (idx128), 256-bit fixed-size lexicographical key (idx256), Floating point key, Double precision floating point key, Long Double (quadruple) precision floating point key - * - * Example: - * - * @code - * // This assumes the code from the get_index() example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * address.zip = 93445; - * }); - * uint32_t zipnumb = 93445; - * auto zip_index = addresses.get_index(); - * auto itr = zip_index.upper_bound(zipnumb); - * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect First Upper Bound Record "); - * itr++; - * eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns an appropriately typed Secondary Index. + * @ingroup multiindex + * + * @tparam IndexName - the ID of the desired secondary index + * + * @return An index of the appropriate type: Primitive 64-bit unsigned integer key (idx64), Primitive 128-bit unsigned integer key (idx128), 128-bit fixed-size lexicographical key (idx128), 256-bit fixed-size lexicographical key (idx256), Floating point key, Double precision floating point key, Long Double (quadruple) precision floating point key + * + * Example: + * + * @code + * // This assumes the code from the get_index() example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * address.zip = 93445; + * }); + * uint32_t zipnumb = 93445; + * auto zip_index = addresses.get_index(); + * auto itr = zip_index.upper_bound(zipnumb); + * eosio::check(itr->account_name == name("dan"), "Lock arf, Incorrect First Upper Bound Record "); + * itr++; + * eosio::check(itr == zip_index.end(), "Lock arf, Incorrect End of Iterator"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ template auto get_index()const { @@ -1469,43 +1473,43 @@ class multi_index } /** - * Returns an iterator to the given object in a Multi-Index table. - * @ingroup multiindex - * - * @param obj - A reference to the desired object - * - * @return An iterator to the given object - * - * Example: - * - * @code - * // This assumes the code from the get_index() example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example below - * // add dan account to table - see emplace example below - * // add additional account - brendan - * - * addresses.emplace(payer, [&](auto& address) { - * address.account_name = "brendan"_n; - * address.first_name = "Brendan"; - * address.last_name = "Blumer"; - * address.street = "1 EOS Way"; - * address.city = "Hong Kong"; - * address.state = "HK"; - * address.zip = 93445; - * }); - * auto user = addresses.get("dan"_n); - * auto itr = address.find("dan"_n); - * eosio::check(iterator_to(user) == itr, "Invalid iterator"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Returns an iterator to the given object in a Multi-Index table. + * @ingroup multiindex + * + * @param obj - A reference to the desired object + * + * @return An iterator to the given object + * + * Example: + * + * @code + * // This assumes the code from the get_index() example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example below + * // add dan account to table - see emplace example below + * // add additional account - brendan + * + * addresses.emplace(payer, [&](auto& address) { + * address.account_name = "brendan"_n; + * address.first_name = "Brendan"; + * address.last_name = "Blumer"; + * address.street = "1 EOS Way"; + * address.city = "Hong Kong"; + * address.state = "HK"; + * address.zip = 93445; + * }); + * auto user = addresses.get("dan"_n); + * auto itr = address.find("dan"_n); + * eosio::check(iterator_to(user) == itr, "Invalid iterator"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode * - * Warning: the interator_to can have undefined behavior if the caller - * passes in a reference to a stack-allocated object rather than the - * reference returned by get or by dereferencing a const_iterator. + * Warning: the interator_to can have undefined behavior if the caller + * passes in a reference to a stack-allocated object rather than the + * reference returned by get or by dereferencing a const_iterator. */ const_iterator iterator_to( const T& obj )const { const auto& objitem = static_cast(obj); @@ -1513,41 +1517,41 @@ class multi_index return {this, &objitem}; } /** - * Adds a new object (i.e., row) to the table. - * @ingroup multiindex - * - * @param payer - Account name of the payer for the Storage usage of the new object - * @param constructor - Lambda function that does an in-place initialization of the object to be created in the table - * - * @pre A multi index table has been instantiated - * @post A new object is created in the Multi-Index table, with a unique primary key (as specified in the object). The object is serialized and written to the table. If the table does not exist, it is created. - * @post Secondary indices are updated to refer to the newly added object. If the secondary index tables do not exist, they are created. - * @post The payer is charged for the storage usage of the new object and, if the table (and secondary index tables) must be created, for the overhead of the table creation. - * - * @return A primary key iterator to the newly created object - * - * Exception - The account is not authorized to write to the table. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * address_index addresses(_self, _self.value); // code, scope - * // add to table, first argument is account to bill for storage - * addresses.emplace(_self, [&](auto& address) { - * address.account_name = "dan"_n; - * address.first_name = "Daniel"; - * address.last_name = "Larimer"; - * address.street = "1 EOS Way"; - * address.city = "Blacksburg"; - * address.state = "VA"; - * }); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Adds a new object (i.e., row) to the table. + * @ingroup multiindex + * + * @param payer - Account name of the payer for the Storage usage of the new object + * @param constructor - Lambda function that does an in-place initialization of the object to be created in the table + * + * @pre A multi index table has been instantiated + * @post A new object is created in the Multi-Index table, with a unique primary key (as specified in the object). The object is serialized and written to the table. If the table does not exist, it is created. + * @post Secondary indices are updated to refer to the newly added object. If the secondary index tables do not exist, they are created. + * @post The payer is charged for the storage usage of the new object and, if the table (and secondary index tables) must be created, for the overhead of the table creation. + * + * @return A primary key iterator to the newly created object + * + * Exception - The account is not authorized to write to the table. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * address_index addresses(_self, _self.value); // code, scope + * // add to table, first argument is account to bill for storage + * addresses.emplace(_self, [&](auto& address) { + * address.account_name = "dan"_n; + * address.first_name = "Daniel"; + * address.last_name = "Larimer"; + * address.street = "1 EOS Way"; + * address.city = "Blacksburg"; + * address.state = "VA"; + * }); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ template const_iterator emplace( name payer, Lambda&& constructor ) { @@ -1595,44 +1599,44 @@ class multi_index } /** - * Modifies an existing object in a table. - * @ingroup multiindex - * - * @param itr - an iterator pointing to the object to be updated - * @param payer - account name of the payer for the storage usage of the updated row - * @param updater - lambda function that updates the target object - * - * @pre itr points to an existing element - * @pre payer is a valid account that is authorized to execute the action and be billed for storage usage. - * - * @post The modified object is serialized, then replaces the existing object in the table. - * @post Secondary indices are updated; the primary key of the updated object is not changed. - * @post The payer is charged for the storage usage of the updated object. - * @post If payer is the same as the existing payer, payer only pays for the usage difference between existing and updated object (and is refunded if this difference is negative). - * @post If payer is different from the existing payer, the existing payer is refunded for the storage usage of the existing object. - * - * Exceptions: - * If called with an invalid precondition, execution is aborted. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example - * // add dan account to table - see emplace example - * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr != addresses.end(), "Address for account not found"); - * addresses.modify( itr, account payer, [&]( auto& address ) { - * address.city = "San Luis Obispo"; - * address.state = "CA"; - * }); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Modifies an existing object in a table. + * @ingroup multiindex + * + * @param itr - an iterator pointing to the object to be updated + * @param payer - account name of the payer for the storage usage of the updated row + * @param updater - lambda function that updates the target object + * + * @pre itr points to an existing element + * @pre payer is a valid account that is authorized to execute the action and be billed for storage usage. + * + * @post The modified object is serialized, then replaces the existing object in the table. + * @post Secondary indices are updated; the primary key of the updated object is not changed. + * @post The payer is charged for the storage usage of the updated object. + * @post If payer is the same as the existing payer, payer only pays for the usage difference between existing and updated object (and is refunded if this difference is negative). + * @post If payer is different from the existing payer, the existing payer is refunded for the storage usage of the existing object. + * + * Exceptions: + * If called with an invalid precondition, execution is aborted. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example + * // add dan account to table - see emplace example + * + * auto itr = addresses.find("dan"_n); + * eosio::check(itr != addresses.end(), "Address for account not found"); + * addresses.modify( itr, account payer, [&]( auto& address ) { + * address.city = "San Luis Obispo"; + * address.state = "CA"; + * }); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ template void modify( const_iterator itr, name payer, Lambda&& updater ) { @@ -1642,45 +1646,45 @@ class multi_index } /** - * Modifies an existing object in a table. - * @ingroup multiindex - * - * @param obj - a reference to the object to be updated - * @param payer - account name of the payer for the storage usage of the updated row - * @param updater - lambda function that updates the target object - * - * @pre obj is an existing object in the table - * @pre payer is a valid account that is authorized to execute the action and be billed for storage usage. - * - * @post The modified object is serialized, then replaces the existing object in the table. - * @post Secondary indices are updated; the primary key of the updated object is not changed. - * @post The payer is charged for the storage usage of the updated object. - * @post If payer is the same as the existing payer, payer only pays for the usage difference between existing and updated object (and is refunded if this difference is negative). - * @post If payer is different from the existing payer, the existing payer is refunded for the storage usage of the existing object. - * - * Exceptions: - * If called with an invalid precondition, execution is aborted. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * // create reference to address_index - see emplace example - * // add dan account to table - see emplace example - * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr != addresses.end(), "Address for account not found"); - * addresses.modify( *itr, payer, [&]( auto& address ) { - * address.city = "San Luis Obispo"; - * address.state = "CA"; - * }); - * eosio::check(itr->city == "San Luis Obispo", "Lock arf, Address not modified"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Modifies an existing object in a table. + * @ingroup multiindex + * + * @param obj - a reference to the object to be updated + * @param payer - account name of the payer for the storage usage of the updated row + * @param updater - lambda function that updates the target object + * + * @pre obj is an existing object in the table + * @pre payer is a valid account that is authorized to execute the action and be billed for storage usage. + * + * @post The modified object is serialized, then replaces the existing object in the table. + * @post Secondary indices are updated; the primary key of the updated object is not changed. + * @post The payer is charged for the storage usage of the updated object. + * @post If payer is the same as the existing payer, payer only pays for the usage difference between existing and updated object (and is refunded if this difference is negative). + * @post If payer is different from the existing payer, the existing payer is refunded for the storage usage of the existing object. + * + * Exceptions: + * If called with an invalid precondition, execution is aborted. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * // create reference to address_index - see emplace example + * // add dan account to table - see emplace example + * + * auto itr = addresses.find("dan"_n); + * eosio::check(itr != addresses.end(), "Address for account not found"); + * addresses.modify( *itr, payer, [&]( auto& address ) { + * address.city = "San Luis Obispo"; + * address.state = "CA"; + * }); + * eosio::check(itr->city == "San Luis Obispo", "Lock arf, Address not modified"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ template void modify( const T& obj, name payer, Lambda&& updater ) { @@ -1739,36 +1743,36 @@ class multi_index } /** - * Retrieves an existing object from a table using its primary key. - * @ingroup multiindex + * Retrieves an existing object from a table using its primary key. + * @ingroup multiindex * - * @param primary - Primary key value of the object. - * @return A constant reference to the object containing the specified primary key. + * @param primary - Primary key value of the object. + * @return A constant reference to the object containing the specified primary key. * - * Exception - No object matches the given key. + * Exception - No object matches the given key. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * // create reference to address_index - see emplace example - * // add dan account to table - see emplace example + * void myaction() { + * // create reference to address_index - see emplace example + * // add dan account to table - see emplace example * - * auto& user = addresses.get("dan"_n); - * eosio::check(user.first_name == "Daniel", "Couldn't get him."); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * auto& user = addresses.get("dan"_n); + * eosio::check(user.first_name == "Daniel", "Couldn't get him."); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode * - * Warning: + * Warning: * - * Avoid the common pitfall of copy-assigning the T& reference returned - * to a stack-allocated local variable and then passing that into modify of the multi-index. - * The most common mistake is when the local variable is defined as auto - * typename, instead it should be of type auto& or decltype(auto). + * Avoid the common pitfall of copy-assigning the T& reference returned + * to a stack-allocated local variable and then passing that into modify of the multi-index. + * The most common mistake is when the local variable is defined as auto + * typename, instead it should be of type auto& or decltype(auto). */ const T& get( uint64_t primary, const char* error_msg = "unable to find key" )const { auto result = find( primary ); @@ -1777,27 +1781,27 @@ class multi_index } /** - * Search for an existing object in a table using its primary key. - * @ingroup multiindex + * Search for an existing object in a table using its primary key. + * @ingroup multiindex * - * @param primary - Primary key value of the object - * @return An iterator to the found object which has a primary key equal to `primary` OR the `end` iterator of the referenced table if an object with primary key `primary` is not found. + * @param primary - Primary key value of the object + * @return An iterator to the found object which has a primary key equal to `primary` OR the `end` iterator of the referenced table if an object with primary key `primary` is not found. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * // create reference to address_index - see emplace example - * // add dan account to table - see emplace example + * void myaction() { + * // create reference to address_index - see emplace example + * // add dan account to table - see emplace example * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr != addresses.end(), "Couldn't get him."); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * auto itr = addresses.find("dan"_n); + * eosio::check(itr != addresses.end(), "Couldn't get him."); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ const_iterator find( uint64_t primary )const { auto itr2 = std::find_if(_items_vector.rbegin(), _items_vector.rend(), [&](const item_ptr& ptr) { @@ -1814,12 +1818,12 @@ class multi_index } /** - * Search for an existing object in a table using its primary key. - * @ingroup multiindex + * Search for an existing object in a table using its primary key. + * @ingroup multiindex * - * @param primary - Primary key value of the object - * @param error_msg - error message if an object with primary key `primary` is not found. - * @return An iterator to the found object which has a primary key equal to `primary` OR throws an exception if an object with primary key `primary` is not found. + * @param primary - Primary key value of the object + * @param error_msg - error message if an object with primary key `primary` is not found. + * @return An iterator to the found object which has a primary key equal to `primary` OR throws an exception if an object with primary key `primary` is not found. */ const_iterator require_find( uint64_t primary, const char* error_msg = "unable to find key" )const { @@ -1837,40 +1841,40 @@ class multi_index } /** - * Remove an existing object from a table using its primary key. - * @ingroup multiindex + * Remove an existing object from a table using its primary key. + * @ingroup multiindex * - * @param itr - An iterator pointing to the object to be removed + * @param itr - An iterator pointing to the object to be removed * - * @pre itr points to an existing element - * @post The object is removed from the table and all associated storage is reclaimed. - * @post Secondary indices associated with the table are updated. - * @post The existing payer for storage usage of the object is refunded for the table and secondary indices usage of the removed object, and if the table and indices are removed, for the associated overhead. + * @pre itr points to an existing element + * @post The object is removed from the table and all associated storage is reclaimed. + * @post Secondary indices associated with the table are updated. + * @post The existing payer for storage usage of the object is refunded for the table and secondary indices usage of the removed object, and if the table and indices are removed, for the associated overhead. * - * @return For the signature with `const_iterator`, returns a pointer to the object following the removed object. + * @return For the signature with `const_iterator`, returns a pointer to the object following the removed object. * - * Exceptions: - * The object to be removed is not in the table. - * The action is not authorized to modify the table. - * The given iterator is invalid. + * Exceptions: + * The object to be removed is not in the table. + * The action is not authorized to modify the table. + * The given iterator is invalid. * - * Example: + * Example: * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} * - * void myaction() { - * // create reference to address_index - see emplace example - * // add dan account to table - see emplace example + * void myaction() { + * // create reference to address_index - see emplace example + * // add dan account to table - see emplace example * - * auto itr = addresses.find("dan"_n); - * eosio::check(itr != addresses.end(), "Address for account not found"); - * addresses.erase( itr ); - * eosio::check(itr != addresses.end(), "Everting lock arf, Address not erased properly"); - * } - * } - * EOSIO_ABI( addressbook, (myaction) ) - * @endcode + * auto itr = addresses.find("dan"_n); + * eosio::check(itr != addresses.end(), "Address for account not found"); + * addresses.erase( itr ); + * eosio::check(itr != addresses.end(), "Everting lock arf, Address not erased properly"); + * } + * } + * EOSIO_ABI( addressbook, (myaction) ) + * @endcode */ const_iterator erase( const_iterator itr ) { eosio::check( itr != end(), "cannot pass end iterator to erase" ); @@ -1884,36 +1888,36 @@ class multi_index } /** - * Remove an existing object from a table using its primary key. - * @ingroup multiindex - * - * @param obj - Object to be removed - * - * @pre obj is an existing object in the table - * @post The object is removed from the table and all associated storage is reclaimed. - * @post Secondary indices associated with the table are updated. - * @post The existing payer for storage usage of the object is refunded for the table and secondary indices usage of the removed object, and if the table and indices are removed, for the associated overhead. - * - * Exceptions: - * The object to be removed is not in the table. - * The action is not authorized to modify the table. - * The given iterator is invalid. - * - * Example: - * - * @code - * // This assumes the code from the constructor example. Replace myaction() {...} - * - * void myaction() { - * auto itr = addresses.find("dan"_n); - * eosio::check(itr != addresses.end(), "Record is not found"); - * addresses.erase(*itr); - * itr = addresses.find("dan"_n); - * eosio::check(itr == addresses.end(), "Record is not deleted"); - * } - * } - * EOSIO_DISPATCH( addressbook, (myaction) ) - * @endcode + * Remove an existing object from a table using its primary key. + * @ingroup multiindex + * + * @param obj - Object to be removed + * + * @pre obj is an existing object in the table + * @post The object is removed from the table and all associated storage is reclaimed. + * @post Secondary indices associated with the table are updated. + * @post The existing payer for storage usage of the object is refunded for the table and secondary indices usage of the removed object, and if the table and indices are removed, for the associated overhead. + * + * Exceptions: + * The object to be removed is not in the table. + * The action is not authorized to modify the table. + * The given iterator is invalid. + * + * Example: + * + * @code + * // This assumes the code from the constructor example. Replace myaction() {...} + * + * void myaction() { + * auto itr = addresses.find("dan"_n); + * eosio::check(itr != addresses.end(), "Record is not found"); + * addresses.erase(*itr); + * itr = addresses.find("dan"_n); + * eosio::check(itr == addresses.end(), "Record is not deleted"); + * } + * } + * EOSIO_DISPATCH( addressbook, (myaction) ) + * @endcode */ void erase( const T& obj ) { using namespace _multi_index_detail; diff --git a/libraries/eosiolib/contracts/eosio/table.hpp b/libraries/eosiolib/contracts/eosio/table.hpp index 0578bcd54b..ddda9f6bb5 100644 --- a/libraries/eosiolib/contracts/eosio/table.hpp +++ b/libraries/eosiolib/contracts/eosio/table.hpp @@ -11,9 +11,16 @@ #warning "eosio::kv::table is designated as `alpha` and should not be used in production code" +/** + * @defgroup keyvaluetable Key Value Table + * @ingroup contracts + */ + #define EOSIO_CDT_GET_RETURN_T(value_class, index_name) std::decay_t()))> /** + * @ingroup keyvaluetable + * * @brief Macro to define an index. * @details This macro allows users to conveniently define an index without having to specify * the index template type, as those can be large/unwieldy to type out. It can be used for both primary and secondary indexes. @@ -304,7 +311,7 @@ namespace internal { /** * Returns the value that the iterator points to. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return The value that the iterator points to. */ @@ -393,9 +400,8 @@ namespace internal { } /** - * @defgroup keyvalue Key Value Table - * @ingroup contracts - * + * @ingroup keyvaluetable + * * @brief Defines an EOSIO Key Value Table * @details EOSIO Key Value API provides a C++ interface to the EOSIO Key Value database. * Key Value Tables require 1 primary index, of any type that can be serialized to a binary representation. @@ -403,7 +409,7 @@ namespace internal { * Indexes must be a member variable or a member function. * * @tparam T - the type of the data stored as the value of the table - */ + */ template class table : internal::table_base { public: @@ -423,7 +429,7 @@ class table : internal::table_base { using iterator_base::iterator_base; /** * Returns the value that the iterator points to. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return The value that the iterator points to. */ @@ -589,7 +595,7 @@ class table : internal::table_base { using value_type = T; /** - * @ingroup keyvalue + * @ingroup keyvaluetable * * @brief Defines an index on an EOSIO Key Value Table * @details A Key Value Index allows a user of the table to search based on a given field. @@ -617,7 +623,7 @@ class table : internal::table_base { /** * Search for an existing object in a table by the index, using the given key. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @param key - The key to search for. * @return An iterator to the found object OR the `end` iterator if the given key was not found. @@ -640,7 +646,7 @@ class table : internal::table_base { /** * Check if a given key exists in the index. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @param key - The key to check for. * @return If the key exists or not. @@ -654,7 +660,7 @@ class table : internal::table_base { /** * Get the value for an existing object in a table by the index, using the given key. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @param key - The key to search for. * @return The value corresponding to the key. @@ -667,7 +673,7 @@ class table : internal::table_base { /** * Get the value for an existing object in a table by the index, using the given key. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @param key - The key to search for. * @return A std::optional of the value corresponding to the key. @@ -681,7 +687,7 @@ class table : internal::table_base { /** * Returns an iterator to the object with the lowest key (by this index) in the table. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return An iterator to the object with the lowest key (by this index) in the table. */ @@ -694,7 +700,7 @@ class table : internal::table_base { /** * Returns an iterator pointing past the end. It does not point to any element, therefore `value` should not be called on it. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return An iterator pointing past the end. */ @@ -704,7 +710,7 @@ class table : internal::table_base { /** * Returns a reverse iterator to the object with the highest key (by this index) in the table. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return A reverse iterator to the object with the highest key (by this index) in the table. */ @@ -717,7 +723,7 @@ class table : internal::table_base { /** * Returns a reverse iterator pointing past the beginning. It does not point to any element, therefore `value` should not be called on it. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return A reverse iterator pointing past the beginning. */ @@ -727,7 +733,7 @@ class table : internal::table_base { /** * Returns an iterator pointing to the element with the lowest key greater than or equal to the given key. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return An iterator pointing to the element with the lowest key greater than or equal to the given key. */ @@ -742,7 +748,7 @@ class table : internal::table_base { /** * Returns an iterator pointing to the first element greater than the given key. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @return An iterator pointing to the first element greater than the given key. */ @@ -766,7 +772,7 @@ class table : internal::table_base { /** * Returns a vector of objects that fall between the specifed range. The range is inclusive, exclusive. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @param begin - The beginning of the range (inclusive). * @param end - The end of the range (exclusive). @@ -788,7 +794,7 @@ class table : internal::table_base { }; /** - * @ingroup keyvalue + * @ingroup keyvaluetable * Puts a value into the table. If the value already exists, it updates the existing entry. * The key is determined from the defined primary index. * If the put attempts to store over an existing secondary index, the transaction will be aborted. @@ -819,7 +825,7 @@ class table : internal::table_base { /** * Removes a value from the table. - * @ingroup keyvalue + * @ingroup keyvaluetable * * @param key - The key of the value to be removed. */ From b5ee37aba8bc0267d7c63ed87f5a85d3a0c0259f Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 26 Jan 2021 15:11:08 +0200 Subject: [PATCH 020/204] for this particular case use @remark instead of @details --- libraries/eosiolib/capi/eosio/db.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/eosiolib/capi/eosio/db.h b/libraries/eosiolib/capi/eosio/db.h index 451b7a28f2..477c8afe01 100644 --- a/libraries/eosiolib/capi/eosio/db.h +++ b/libraries/eosiolib/capi/eosio/db.h @@ -61,7 +61,7 @@ int32_t db_store_i64(uint64_t scope, capi_name table, capi_name payer, uint64_t * @pre `*((uint64_t*)data)` stores the primary key * @pre `iterator` points to an existing table row in the table * @post the record contained in the table row pointed to by `iterator` is replaced with the new updated record - * @details This function does not allow changing the primary key of a + * @remark This function does not allow changing the primary key of a * table row. The serialized data that is stored in the table row of a * primary table may include a primary key and that primary key value * could be changed by the contract calling the db_update_i64 intrinsic; From 5745a72582b101d1390069c0c66d161b90f7153f Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 26 Jan 2021 15:19:58 +0200 Subject: [PATCH 021/204] remove redundant annotations froom db.h file --- libraries/eosiolib/capi/eosio/db.h | 206 ++--------------------------- 1 file changed, 13 insertions(+), 193 deletions(-) diff --git a/libraries/eosiolib/capi/eosio/db.h b/libraries/eosiolib/capi/eosio/db.h index 477c8afe01..e21f20caf7 100644 --- a/libraries/eosiolib/capi/eosio/db.h +++ b/libraries/eosiolib/capi/eosio/db.h @@ -30,9 +30,6 @@ extern "C" { */ /** - * - * Store a record in a primary 64-bit integer index table - * * @brief Store a record in a primary 64-bit integer index table * @param scope - The scope where the table resides (implied to be within the code of the current receiver) * @param table - The table name @@ -49,9 +46,6 @@ __attribute__((eosio_wasm_import)) int32_t db_store_i64(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const void* data, uint32_t len); /** - * - * Update a record in a primary 64-bit integer index table - * * @brief Update a record in a primary 64-bit integer index table * @param iterator - Iterator to the table row containing the record to update * @param payer - The account that pays for the storage costs (use 0 to continue using current payer) @@ -71,9 +65,6 @@ __attribute__((eosio_wasm_import)) void db_update_i64(int32_t iterator, capi_name payer, const void* data, uint32_t len); /** - * - * Remove a record from a primary 64-bit integer index table - * * @brief Remove a record from a primary 64-bit integer index table * @param iterator - Iterator to the table row to remove * @pre `iterator` points to an existing table row in the table @@ -91,9 +82,6 @@ __attribute__((eosio_wasm_import)) void db_remove_i64(int32_t iterator); /** - * - * Get a record in a primary 64-bit integer index table - * * @brief Get a record in a primary 64-bit integer index table * @param iterator - The iterator to the table row containing the record to retrieve * @param data - Pointer to the buffer which will be filled with the retrieved record @@ -116,9 +104,6 @@ __attribute__((eosio_wasm_import)) int32_t db_get_i64(int32_t iterator, const void* data, uint32_t len); /** - * - * Find the table row following the referenced table row in a primary 64-bit integer index table - * * @brief Find the table row following the referenced table row in a primary 64-bit integer index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the next table row @@ -140,9 +125,6 @@ __attribute__((eosio_wasm_import)) int32_t db_next_i64(int32_t iterator, uint64_t* primary); /** - * - * Find the table row preceding the referenced table row in a primary 64-bit integer index table - * * @brief Find the table row preceding the referenced table row in a primary 64-bit integer index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the previous table row @@ -161,9 +143,6 @@ __attribute__((eosio_wasm_import)) int32_t db_previous_i64(int32_t iterator, uint64_t* primary); /** - * - * Find a table row in a primary 64-bit integer index table by primary key - * * @brief Find a table row in a primary 64-bit integer index table by primary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -181,11 +160,8 @@ __attribute__((eosio_wasm_import)) int32_t db_find_i64(capi_name code, uint64_t scope, capi_name table, uint64_t id); /** - * - * Find the table row in a primary 64-bit integer index table that matches the lowerbound condition for a given primary key - * The table row that matches the lowerbound condition is the first table row in the table with the lowest primary key that is >= the given key - * * @brief Find the table row in a primary 64-bit integer index table that matches the lowerbound condition for a given primary key + * @details The table row that matches the lowerbound condition is the first table row in the table with the lowest primary key that is >= the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -196,11 +172,8 @@ __attribute__((eosio_wasm_import)) int32_t db_lowerbound_i64(capi_name code, uint64_t scope, capi_name table, uint64_t id); /** - * - * Find the table row in a primary 64-bit integer index table that matches the upperbound condition for a given primary key - * The table row that matches the upperbound condition is the first table row in the table with the lowest primary key that is > the given key - * * @brief Find the table row in a primary 64-bit integer index table that matches the upperbound condition for a given primary key + * @details The table row that matches the upperbound condition is the first table row in the table with the lowest primary key that is > the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -211,9 +184,6 @@ __attribute__((eosio_wasm_import)) int32_t db_upperbound_i64(capi_name code, uint64_t scope, capi_name table, uint64_t id); /** - * - * Get an iterator representing just-past-the-end of the last table row of a primary 64-bit integer index table - * * @brief Get an iterator representing just-past-the-end of the last table row of a primary 64-bit integer index table * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -224,9 +194,6 @@ __attribute__((eosio_wasm_import)) int32_t db_end_i64(capi_name code, uint64_t scope, capi_name table); /** - * - * Store an association of a 64-bit integer secondary key to a primary key in a secondary 64-bit integer index table - * * @brief Store an association of a 64-bit integer secondary key to a primary key in a secondary 64-bit integer index table * @param scope - The scope where the table resides (implied to be within the code of the current receiver) * @param table - The table name @@ -240,9 +207,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx64_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const uint64_t* secondary); /** - * - * Update an association for a 64-bit integer secondary key to a primary key in a secondary 64-bit integer index table - * * @brief Update an association for a 64-bit integer secondary key to a primary key in a secondary 64-bit integer index table * @param iterator - The iterator to the table row containing the secondary key association to update * @param payer - The account that pays for the storage costs (use 0 to continue using current payer) @@ -254,9 +218,6 @@ __attribute__((eosio_wasm_import)) void db_idx64_update(int32_t iterator, capi_name payer, const uint64_t* secondary); /** - * - * Remove a table row from a secondary 64-bit integer index table - * * @brief Remove a table row from a secondary 64-bit integer index table * @param iterator - Iterator to the table row to remove * @pre `iterator` points to an existing table row in the table @@ -266,9 +227,6 @@ __attribute__((eosio_wasm_import)) void db_idx64_remove(int32_t iterator); /** - * - * Find the table row following the referenced table row in a secondary 64-bit integer index table - * * @brief Find the table row following the referenced table row in a secondary 64-bit integer index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the next table row @@ -280,9 +238,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx64_next(int32_t iterator, uint64_t* primary); /** - * - * Find the table row preceding the referenced table row in a secondary 64-bit integer index table - * * @brief Find the table row preceding the referenced table row in a secondary 64-bit integer index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the previous table row @@ -294,9 +249,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx64_previous(int32_t iterator, uint64_t* primary); /** - * - * Find a table row in a secondary 64-bit integer index table by primary key - * * @brief Find a table row in a secondary 64-bit integer index table by primary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -310,9 +262,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx64_find_primary(capi_name code, uint64_t scope, capi_name table, uint64_t* secondary, uint64_t primary); /** - * - * Find a table row in a secondary 64-bit integer index table by secondary key - * * @brief Find a table row in a secondary 64-bit integer index table by secondary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -326,11 +275,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx64_find_secondary(capi_name code, uint64_t scope, capi_name table, const uint64_t* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary 64-bit integer index table that matches the lowerbound condition for a given secondary key - * The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key - * * @brief Find the table row in a secondary 64-bit integer index table that matches the lowerbound condition for a given secondary key + * @details The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -344,11 +290,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx64_lowerbound(capi_name code, uint64_t scope, capi_name table, uint64_t* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary 64-bit integer index table that matches the upperbound condition for a given secondary key - * The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key - * * @brief Find the table row in a secondary 64-bit integer index table that matches the upperbound condition for a given secondary key + * @details The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -362,9 +305,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx64_upperbound(capi_name code, uint64_t scope, capi_name table, uint64_t* secondary, uint64_t* primary); /** - * - * Get an end iterator representing just-past-the-end of the last table row of a secondary 64-bit integer index table - * * @brief Get an end iterator representing just-past-the-end of the last table row of a secondary 64-bit integer index table * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -377,9 +317,6 @@ int32_t db_idx64_end(capi_name code, uint64_t scope, capi_name table); /** - * - * Store an association of a 128-bit integer secondary key to a primary key in a secondary 128-bit integer index table - * * @brief Store an association of a 128-bit integer secondary key to a primary key in a secondary 128-bit integer index table * @param scope - The scope where the table resides (implied to be within the code of the current receiver) * @param table - The table name @@ -393,9 +330,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const uint128_t* secondary); /** - * - * Update an association for a 128-bit integer secondary key to a primary key in a secondary 128-bit integer index table - * * @brief Update an association for a 128-bit integer secondary key to a primary key in a secondary 128-bit integer index table * @param iterator - The iterator to the table row containing the secondary key association to update * @param payer - The account that pays for the storage costs (use 0 to continue using current payer) @@ -407,9 +341,6 @@ __attribute__((eosio_wasm_import)) void db_idx128_update(int32_t iterator, capi_name payer, const uint128_t* secondary); /** - * - * Remove a table row from a secondary 128-bit integer index table - * * @brief Remove a table row from a secondary 128-bit integer index table * @param iterator - Iterator to the table row to remove * @pre `iterator` points to an existing table row in the table @@ -419,9 +350,6 @@ __attribute__((eosio_wasm_import)) void db_idx128_remove(int32_t iterator); /** - * - * Find the table row following the referenced table row in a secondary 128-bit integer index table - * * @brief Find the table row following the referenced table row in a secondary 128-bit integer index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the next table row @@ -433,9 +361,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_next(int32_t iterator, uint64_t* primary); /** - * - * Find the table row preceding the referenced table row in a secondary 128-bit integer index table - * * @brief Find the table row preceding the referenced table row in a secondary 128-bit integer index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the previous table row @@ -447,9 +372,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_previous(int32_t iterator, uint64_t* primary); /** - * - * Find a table row in a secondary 128-bit integer index table by primary key - * * @brief Find a table row in a secondary 128-bit integer index table by primary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -463,9 +385,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_find_primary(capi_name code, uint64_t scope, capi_name table, uint128_t* secondary, uint64_t primary); /** - * - * Find a table row in a secondary 128-bit integer index table by secondary key - * * @brief Find a table row in a secondary 128-bit integer index table by secondary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -479,11 +398,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_find_secondary(capi_name code, uint64_t scope, capi_name table, const uint128_t* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary 128-bit integer index table that matches the lowerbound condition for a given secondary key - * The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key - * * @brief Find the table row in a secondary 128-bit integer index table that matches the lowerbound condition for a given secondary key + * @details The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -497,11 +413,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_lowerbound(capi_name code, uint64_t scope, capi_name table, uint128_t* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary 128-bit integer index table that matches the upperbound condition for a given secondary key - * The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key - * * @brief Find the table row in a secondary 128-bit integer index table that matches the upperbound condition for a given secondary key + * @details The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -515,9 +428,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_upperbound(capi_name code, uint64_t scope, capi_name table, uint128_t* secondary, uint64_t* primary); /** - * - * Get an end iterator representing just-past-the-end of the last table row of a secondary 128-bit integer index table - * * @brief Get an end iterator representing just-past-the-end of the last table row of a secondary 128-bit integer index table * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -528,9 +438,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx128_end(capi_name code, uint64_t scope, capi_name table); /** - * - * Store an association of a 256-bit secondary key to a primary key in a secondary 256-bit index table - * * @brief Store an association of a 256-bit secondary key to a primary key in a secondary 256-bit index table * @param scope - The scope where the table resides (implied to be within the code of the current receiver) * @param table - The table name @@ -545,9 +452,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const uint128_t* data, uint32_t data_len ); /** - * - * Update an association for a 256-bit secondary key to a primary key in a secondary 256-bit index table - * * @brief Update an association for a 256-bit secondary key to a primary key in a secondary 256-bit index table * @param iterator - The iterator to the table row containing the secondary key association to update * @param payer - The account that pays for the storage costs (use 0 to continue using current payer) @@ -560,9 +464,6 @@ __attribute__((eosio_wasm_import)) void db_idx256_update(int32_t iterator, capi_name payer, const uint128_t* data, uint32_t data_len); /** - * - * Remove a table row from a secondary 256-bit index table - * * @brief Remove a table row from a secondary 256-bit index table * @param iterator - Iterator to the table row to remove * @pre `iterator` points to an existing table row in the table @@ -572,9 +473,6 @@ __attribute__((eosio_wasm_import)) void db_idx256_remove(int32_t iterator); /** - * - * Find the table row following the referenced table row in a secondary 256-bit index table - * * @brief Find the table row following the referenced table row in a secondary 256-bit index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the next table row @@ -586,9 +484,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_next(int32_t iterator, uint64_t* primary); /** - * - * Find the table row preceding the referenced table row in a secondary 256-bit index table - * * @brief Find the table row preceding the referenced table row in a secondary 256-bit index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the previous table row @@ -600,9 +495,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_previous(int32_t iterator, uint64_t* primary); /** - * - * Find a table row in a secondary 256-bit index table by primary key - * * @brief Find a table row in a secondary 128-bit integer index table by primary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -617,9 +509,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_find_primary(capi_name code, uint64_t scope, capi_name table, uint128_t* data, uint32_t data_len, uint64_t primary); /** - * - * Find a table row in a secondary 256-bit index table by secondary key - * * @brief Find a table row in a secondary 256-bit index table by secondary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -634,11 +523,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_find_secondary(capi_name code, uint64_t scope, capi_name table, const uint128_t* data, uint32_t data_len, uint64_t* primary); /** - * - * Find the table row in a secondary 256-bit index table that matches the lowerbound condition for a given secondary key - * The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key (uses lexicographical ordering on the 256-bit keys) - * * @brief Find the table row in a secondary 256-bit index table that matches the lowerbound condition for a given secondary key + * @details The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key (uses lexicographical ordering on the 256-bit keys) * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -653,11 +539,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_lowerbound(capi_name code, uint64_t scope, capi_name table, uint128_t* data, uint32_t data_len, uint64_t* primary); /** - * - * Find the table row in a secondary 256-bit index table that matches the upperbound condition for a given secondary key - * The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key (uses lexicographical ordering on the 256-bit keys) - * * @brief Find the table row in a secondary 256-bit index table that matches the upperbound condition for a given secondary key + * @details The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key (uses lexicographical ordering on the 256-bit keys) * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -672,9 +555,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_upperbound(capi_name code, uint64_t scope, capi_name table, uint128_t* data, uint32_t data_len, uint64_t* primary); /** - * - * Get an end iterator representing just-past-the-end of the last table row of a secondary 256-bit index table - * * @brief Get an end iterator representing just-past-the-end of the last table row of a secondary 256-bit index table * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -685,9 +565,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx256_end(capi_name code, uint64_t scope, capi_name table); /** - * - * Store an association of a double-precision floating-point secondary key to a primary key in a secondary double-precision floating-point index table - * * @brief Store an association of a double-precision floating-point secondary key to a primary key in a secondary double-precision floating-point index table * @param scope - The scope where the table resides (implied to be within the code of the current receiver) * @param table - The table name @@ -701,9 +578,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const double* secondary); /** - * - * Update an association for a double-precision floating-point secondary key to a primary key in a secondary double-precision floating-point index table - * * @brief Update an association for a double-precision floating-point secondary key to a primary key in a secondary double-precision floating-point index table * @param iterator - The iterator to the table row containing the secondary key association to update * @param payer - The account that pays for the storage costs (use 0 to continue using current payer) @@ -715,9 +589,6 @@ __attribute__((eosio_wasm_import)) void db_idx_double_update(int32_t iterator, capi_name payer, const double* secondary); /** - * - * Remove a table row from a secondary double-precision floating-point index table - * * @brief Remove a table row from a secondary double-precision floating-point index table * @param iterator - Iterator to the table row to remove * @pre `iterator` points to an existing table row in the table @@ -727,9 +598,6 @@ __attribute__((eosio_wasm_import)) void db_idx_double_remove(int32_t iterator); /** - * - * Find the table row following the referenced table row in a secondary double-precision floating-point index table - * * @brief Find the table row following the referenced table row in a secondary double-precision floating-point index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the next table row @@ -741,9 +609,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_next(int32_t iterator, uint64_t* primary); /** - * - * Find the table row preceding the referenced table row in a secondary double-precision floating-point index table - * * @brief Find the table row preceding the referenced table row in a secondary double-precision floating-point index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the previous table row @@ -755,9 +620,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_previous(int32_t iterator, uint64_t* primary); /** - * - * Find a table row in a secondary double-precision floating-point index table by primary key - * * @brief Find a table row in a secondary double-precision floating-point index table by primary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -771,9 +633,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_find_primary(capi_name code, uint64_t scope, capi_name table, double* secondary, uint64_t primary); /** - * - * Find a table row in a secondary double-precision floating-point index table by secondary key - * * @brief Find a table row in a secondary double-precision floating-point index table by secondary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -787,11 +646,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_find_secondary(capi_name code, uint64_t scope, capi_name table, const double* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary double-precision floating-point index table that matches the lowerbound condition for a given secondary key - * The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key - * * @brief Find the table row in a secondary double-precision floating-point index table that matches the lowerbound condition for a given secondary key + * @details The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -805,11 +661,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_lowerbound(capi_name code, uint64_t scope, capi_name table, double* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary double-precision floating-point index table that matches the upperbound condition for a given secondary key - * The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key - * * @brief Find the table row in a secondary double-precision floating-point index table that matches the upperbound condition for a given secondary key + * @details The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -823,9 +676,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_upperbound(capi_name code, uint64_t scope, capi_name table, double* secondary, uint64_t* primary); /** - * - * Get an end iterator representing just-past-the-end of the last table row of a secondary double-precision floating-point index table - * * @brief Get an end iterator representing just-past-the-end of the last table row of a secondary double-precision floating-point index table * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -836,9 +686,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_double_end(capi_name code, uint64_t scope, capi_name table); /** - * - * Store an association of a quadruple-precision floating-point secondary key to a primary key in a secondary quadruple-precision floating-point index table - * * @brief Store an association of a quadruple-precision floating-point secondary key to a primary key in a secondary quadruple-precision floating-point index table * @param scope - The scope where the table resides (implied to be within the code of the current receiver) * @param table - The table name @@ -852,9 +699,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const long double* secondary); /** - * - * Update an association for a quadruple-precision floating-point secondary key to a primary key in a secondary quadruple-precision floating-point index table - * * @brief Update an association for a quadruple-precision floating-point secondary key to a primary key in a secondary quadruple-precision floating-point index table * @param iterator - The iterator to the table row containing the secondary key association to update * @param payer - The account that pays for the storage costs (use 0 to continue using current payer) @@ -866,9 +710,6 @@ __attribute__((eosio_wasm_import)) void db_idx_long_double_update(int32_t iterator, capi_name payer, const long double* secondary); /** - * - * Remove a table row from a secondary quadruple-precision floating-point index table - * * @brief Remove a table row from a secondary quadruple-precision floating-point index table * @param iterator - Iterator to the table row to remove * @pre `iterator` points to an existing table row in the table @@ -878,10 +719,7 @@ __attribute__((eosio_wasm_import)) void db_idx_long_double_remove(int32_t iterator); /** - * - * Find the table row following the referenced table row in a secondary quadruple-precision floating-point index table - * - * @brief Find the table row following the referenced table row in a secondary quadruple-precision floating-point index table + * @brief Find the table row following the referenced table row in a secondary quadruple-precision floating-point index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the next table row * @return iterator to the table row following the referenced table row (or the end iterator of the table if the referenced table row is the last one in the table) @@ -892,9 +730,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_next(int32_t iterator, uint64_t* primary); /** - * - * Find the table row preceding the referenced table row in a secondary quadruple-precision floating-point index table - * * @brief Find the table row preceding the referenced table row in a secondary quadruple-precision floating-point index table * @param iterator - The iterator to the referenced table row * @param primary - Pointer to a `uint64_t` variable which will have its value set to the primary key of the previous table row @@ -906,9 +741,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_previous(int32_t iterator, uint64_t* primary); /** - * - * Find a table row in a secondary quadruple-precision floating-point index table by primary key - * * @brief Find a table row in a secondary quadruple-precision floating-point index table by primary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -922,9 +754,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_find_primary(capi_name code, uint64_t scope, capi_name table, long double* secondary, uint64_t primary); /** - * - * Find a table row in a secondary quadruple-precision floating-point index table by secondary key - * * @brief Find a table row in a secondary quadruple-precision floating-point index table by secondary key * @param code - The name of the owner of the table * @param scope - The scope where the table resides @@ -938,11 +767,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_find_secondary(capi_name code, uint64_t scope, capi_name table, const long double* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary quadruple-precision floating-point index table that matches the lowerbound condition for a given secondary key - * The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key - * * @brief Find the table row in a secondary quadruple-precision floating-point index table that matches the lowerbound condition for a given secondary key + * @details The table row that matches the lowerbound condition is the first table row in the table with the lowest secondary key that is >= the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -956,11 +782,8 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_lowerbound(capi_name code, uint64_t scope, capi_name table, long double* secondary, uint64_t* primary); /** - * - * Find the table row in a secondary quadruple-precision floating-point index table that matches the upperbound condition for a given secondary key - * The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key - * * @brief Find the table row in a secondary quadruple-precision floating-point index table that matches the upperbound condition for a given secondary key + * @details The table row that matches the upperbound condition is the first table row in the table with the lowest secondary key that is > the given key * @param code - The name of the owner of the table * @param scope - The scope where the table resides * @param table - The table name @@ -974,9 +797,6 @@ __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_upperbound(capi_name code, uint64_t scope, capi_name table, long double* secondary, uint64_t* primary); /** - * - * Get an end iterator representing just-past-the-end of the last table row of a secondary quadruple-precision floating-point index table - * * @brief Get an end iterator representing just-past-the-end of the last table row of a secondary quadruple-precision floating-point index table * @param code - The name of the owner of the table * @param scope - The scope where the table resides From c33647a45c252a500024658d0f0570fbaf7acfba Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 27 Jan 2021 15:21:53 +0200 Subject: [PATCH 022/204] updates based on peer review (Philip) --- libraries/eosiolib/contracts/eosio/map.hpp | 13 +++++++------ libraries/eosiolib/contracts/eosio/table.hpp | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/libraries/eosiolib/contracts/eosio/map.hpp b/libraries/eosiolib/contracts/eosio/map.hpp index d3537cd1d5..bb4275372a 100644 --- a/libraries/eosiolib/contracts/eosio/map.hpp +++ b/libraries/eosiolib/contracts/eosio/map.hpp @@ -140,8 +140,8 @@ namespace eosio::kv { * @ingroup keyvaluemap * * @brief This struct represents the data type stored in map. - * @details You will use the sets of functions and operations associated with this type to - * access the items stored in the map. + * @details You will use the set of functions and operations associated + * with this type to access the items stored in the map. * * Note that this type in `eosio::kv::map` is defined as `eosio::kv::map::elem_t`. */ @@ -174,8 +174,8 @@ namespace eosio::kv { * @ingroup keyvaluemap * * @brief This struct represents the iterator for the `eosio::kv::map` data type. - * @details You will use the sets of functions and operations associated with this type to - * iterate through values in the map and reference them. + * @details You will use the set of functions and operations associated with + * this type to iterate through values in the map and reference them. * * Note that this iterator type in `eosio::kv::map` is defined as `eosio::kv::map::iterator_t`. * There is also a reverse iterator available, it is defined as `eosio::kv::map::reverse_iterator_t`. @@ -249,8 +249,9 @@ namespace eosio::kv { /** * @ingroup keyvaluemap * - * @brief Utility function to see if the iterator is valid or is pointing - * at `end` or one past the last or first element. + * @brief Utility function which returns true if iterator is valid or false + * if iterator is not valid. An iterator is not valid if is pointing at + * `end` or one past the last or first element. */ inline bool is_valid() const { return query_status(current_status); } diff --git a/libraries/eosiolib/contracts/eosio/table.hpp b/libraries/eosiolib/contracts/eosio/table.hpp index ddda9f6bb5..dc43212ab8 100644 --- a/libraries/eosiolib/contracts/eosio/table.hpp +++ b/libraries/eosiolib/contracts/eosio/table.hpp @@ -408,7 +408,7 @@ namespace internal { * Key Value Tables support 0 or more secondary index, of any type that can be serialized to a binary representation. * Indexes must be a member variable or a member function. * - * @tparam T - the type of the data stored as the value of the table + * @tparam T - the type of the data stored as the value in the table */ template class table : internal::table_base { From fbaed1807311709cbe6075b605f62f28bca15040 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 29 Jan 2021 10:38:50 -0500 Subject: [PATCH 023/204] simplify the contracts for abigen-fail testing --- .../empty_contract_with_other_contract.cpp | 17 +++-------------- .../abigen-fail/wrong_contract_name.cpp | 17 +++-------------- tools/include/compiler_options.hpp.in | 3 +-- 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp b/tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp index 69aa30dbf5..94f425e1e9 100644 --- a/tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp +++ b/tests/toolchain/abigen-fail/empty_contract_with_other_contract.cpp @@ -7,18 +7,7 @@ CONTRACT another_hello : public contract { public: using contract::contract; - ACTION hi( name nm ); - ACTION check( name nm ); - - using hi_action = action_wrapper<"hi"_n, &hello::hi>; - using check_action = action_wrapper<"check"_n, &hello::check>; + ACTION hi( name nm ) { + print_f("Name : %\n", nm); + } }; - -ACTION hello::hi( name nm ) { - print_f("Name : %\n", nm); -} - -ACTION hello::check( name nm ) { - print_f("Name : %\n", nm); - eosio::check(nm == "hello"_n, "check name not equal to `hello`"); -} diff --git a/tests/toolchain/abigen-fail/wrong_contract_name.cpp b/tests/toolchain/abigen-fail/wrong_contract_name.cpp index a86034b1aa..46093ceeb5 100644 --- a/tests/toolchain/abigen-fail/wrong_contract_name.cpp +++ b/tests/toolchain/abigen-fail/wrong_contract_name.cpp @@ -5,18 +5,7 @@ CONTRACT hello : public contract { public: using contract::contract; - ACTION hi( name nm ); - ACTION check( name nm ); - - using hi_action = action_wrapper<"hi"_n, &hello::hi>; - using check_action = action_wrapper<"check"_n, &hello::check>; + ACTION hi( name nm ) { + print_f("Name : %\n", nm); + } }; - -ACTION hello::hi( name nm ) { - print_f("Name : %\n", nm); -} - -ACTION hello::check( name nm ) { - print_f("Name : %\n", nm); - eosio::check(nm == "hello"_n, "check name not equal to `hello`"); -} diff --git a/tools/include/compiler_options.hpp.in b/tools/include/compiler_options.hpp.in index fc2a523d7a..6b7c8e55c3 100644 --- a/tools/include/compiler_options.hpp.in +++ b/tools/include/compiler_options.hpp.in @@ -891,8 +891,7 @@ static Options CreateOptions(bool add_defaults=true) { if (!contract_name.empty()) { abigen_contract = contract_name; has_contract_opt = true; - } - else { + } else { llvm::SmallString<256> fn = llvm::sys::path::filename(output_fn); llvm::sys::path::replace_extension(fn, ""); abigen_contract = fn.str(); From 9bdfdc71451c2232f273f222efbbc78e9ee5b70f Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 3 Feb 2021 16:34:57 +0200 Subject: [PATCH 024/204] add troubleshooting item --- docs/08_troubleshooting.md | 70 +++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting.md index b41d979018..2affa59534 100644 --- a/docs/08_troubleshooting.md +++ b/docs/08_troubleshooting.md @@ -3,7 +3,9 @@ content_title: Troubleshooting --- ## When sending an action to the blockchain you get the error below -```{ + +```console +{ "code":500, "message":"Internal Service Error", "error":{ @@ -21,76 +23,91 @@ content_title: Troubleshooting } } ``` + __Possible solution__: Verify if you did not forget to set code for contract, is it possible that you only set the `abi` for the contract but not the code as well? -## When sending an action to the blockchain an error similar to the one below is encountered: -```sh +## When sending an action to the blockchain an error similar to the one below is encountered + +```console Error 3015014: Pack data exception Error Details: Unexpected input encountered while processing struct 'action_name_here' ``` -__Possible solution__: You did not specify correctly the parameter when sending the action to the blockchain. When no parameter is needed the command should look like the one below: + +__Possible solution__: You did not specify correctly the parameter when sending the action to the blockchain. When no parameter is needed the command should look like the one below + ```sh cleos push action eostutorial1 get '[]' -p eostutorial1@active ``` + The command above is one way of sending correctly `get` action with no parameters to the blockchain. -## When sending an action to the blockchain an error similar to the one below is encountered: -```sh +## When sending an action to the blockchain an error similar to the one below is encountered + +```console error 2019-09-25T07:38:14.859 thread-0 main.cpp:3449 main ] Failed with error: Assert Exception (10) !action_type.empty(): Unknown action action_name in contract eostutorial1 ``` + __Possible solution__: Verify if the action attribute `[[eosio::action]]` is used when defining and/or declaring the action `action_name` for the contract. -## When deploying a contract code to the blockchain a similar error with the ones below is encountered: -```sh +## When deploying a contract code to the blockchain a similar error with the ones below is encountered + +```console Error 3160010: No abi file found or Error 3160009: No wasm file found ``` + __Possible solution__: Verify that `abi` and `wasm` files exist in the directory specified in the `cleos set contract` command, and that their names match the directory name. ## Action triggers ram charge which cannot be initiated from a notification. __Possible solution__: The reason for this error is because the notification action doesn't have authorization to buy the needed RAM. In the context of multi index tables, there’s a table payer and a row payer. Only the contract can modify rows. The contract can create rows with a payer that didn’t authorize the action if the total amount of ram charged that payer doesn’t increase (e.g. delete a row and add another with the same payer). The table payer can’t change until the last row is deleted. For the purposes of billing, a table is identified by the tuple `contract, scope, table`. When you create a row for a `contract, scope, table` tuple that doesn’t exist, you create a table with the same payer. This can outlive the original row which created it, if other rows were created with that combination and this prevents the original payer from getting their ram back. Secondary indexes throw in more complexity since they use the lower 4 bits of the table name, producing additional `contract, scope, table` tuples combinations. Key takeaway: payer is about billing, not access control -## You successfully re-deployed the contract code, but when you query the table you get the custom message that you coded when the table is not initialized (doesn't exist), or the system error message below in case you do not have code that checks first if table exist: -```sh +## You successfully re-deployed the contract code, but when you query the table you get the custom message that you coded when the table is not initialized (doesn't exist), or the system error message below in case you do not have code that checks first if table exist + +```console Error 3050003: eosio_assert_message assertion failure Error Details: assertion failure with message: singleton does not exist pending console output: ``` + __Possible solution__: It is possible that you changed the table name? That is the first, of `eosio::name` type, parameter which you passed to the `eosio::template` type alias definition. Or did you change the table structure definition at all? If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./05_best-practices/04_data-design-and-migration.md) section. -## You successfully re-deployed the contract code, but when you query the table you get the fields of the row values swapped, that is, it appears the values stored in table rows are the same only that they are swapped between fields/columns. +## You successfully re-deployed the contract code, but when you query the table you get the fields of the row values swapped, that is, it appears the values stored in table rows are the same only that they are swapped between fields/columns __Possible solution__: It is possible that you changed the order of the fields the table struct definition? If you change the order of the table struct definition, if the swapped fields have the same type you will see the data in the fields correctly, however if the types of the fields are different the results could be of something undefined. If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./05_best-practices/04_data-design-and-migration.md) section. -## You successfully re-deployed the contract code, but when you query the table you get a parse error, like the one below, or the returned data seems to be garbage. -```sh +## You successfully re-deployed the contract code, but when you query the table you get a parse error, like the one below, or the returned data seems to be garbage + +```console error 2019-09-26T07:05:54.825 thread-0 main.cpp:3449 main ] Failed with error: Parse Error (4) Couldn't parse type_name ``` + __Possible solution__: It is possible that you changed the type of the fields for the table struct definition? If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./05_best-practices/04_data-design-and-migration.md) section. -## eosio-cpp process never completes. +## eosio-cpp process never completes __Possible solution__: make sure you have at least 2 cores on the host that executes the eosio-cpp (e.g. docker container, VM, local sub-system) -## You can not find the `now()` time function, or the result of the `current_time_point` functions are not what you expected them to be. +## You can not find the `now()` time function, or the result of the `current_time_point` functions are not what you expected them to be __Possible solution__: The `now()` function has been replaced by `current_time_point().sec_since_epoch()`, it returns the time in microseconds from 1970 of the `current block` as a time_point. There's also available `current_block_time()` which returns the time in microseconds from 1970 of the `current block` as a `block_timestamp`. Be aware that for time base functions, the assumption is when you call something like `now()` or `current_time()` you will get the exact now/current time, however that is not the case with EOSIO, you get __the block time__, and only ever get __the block time__ from the available `sec_since_epoch()` or `current_block_time()` no matter how many times you call it. -## You successfully re-deployed the contract code, but when you broadcast one of the contracts methods to the blockchain you get below error message: -```sh +## You successfully re-deployed the contract code, but when you broadcast one of the contracts methods to the blockchain you get below error message + +```console Error 3050004: eosio_assert_code assertion failure Error Details: assertion failure with error code: 8000000000000000000 ``` + __Possible solution__: If you are referencing a smart contract from another smart contract and each of them have at least one action with the same name you will experience the above error when sending to the blockchain one of those actions, so what you have to do is to make sure the action names between those two contracts are not common. -## Print statements from smart contract code are not seen in the output. +## Print statements from smart contract code are not seen in the output __Possible solution__: There are a few reasons print statements do not show up in the output. One reason could be because an error occurs, in which case the whole transaction is rolled back and the print statements output is replaced by the error that occurs instead; Another reason is if you are in a loop, iterating through a table's rows for example and for each row you have a print statement that prints also the new line char at the `'\n'` only the chars before the new line char from the first iteration will be printed, nothing else after that, nothing from the second iteration onwards either. @@ -105,6 +122,7 @@ The below code will print just the first line of the iteration. ``` The below code will print all lines of the iteration separated by `'|'` char. + ```cpp auto index=0; for (auto& item : testtab) @@ -113,7 +131,7 @@ The below code will print all lines of the iteration separated by `'|'` char. } ``` -## Print statements from smart contract code are not shown in the `expected order`. +## Print statements from smart contract code are not shown in the `expected order` __Possible solution__: The key point here is the `expected order` and what you think it should be. Although the EOSIO is single threaded, when looking at your smart contract action code implementation, which let's say it has a series of `print` (either `print_f` or `printf`) statements, they might not necessarily be outputted in the order the `apparent` code workflow is. One example is when inline transactions are sent from your smart contract action code, and you expect to see the `print` statements from within the inline action code outputted before the `print` statements made after the inline action `send` statement. For better exemplification let's look at the code below: @@ -131,4 +149,16 @@ __Possible solution__: The key point here is the `expected order` and what you t } ``` -The code above has one `print` statement before the `singleton_set.send` and another one after the `singleton_set.send`. If you wrote some more `print` statements in the code that implements the `singleton_set.send` action and expect to see them before the second `print` statement then it is a wrong assumption. The inline actions are broadcasted to the network and they are executed at a different time, asynchronous of the current execution thread of the current `multi_index_example::mod` action, therefor it is impossible to predict when the `print` statements from inline action code will be outputted. \ No newline at end of file +The code above has one `print` statement before the `singleton_set.send` and another one after the `singleton_set.send`. If you wrote some more `print` statements in the code that implements the `singleton_set.send` action and expect to see them before the second `print` statement then it is a wrong assumption. The inline actions are broadcasted to the network and they are executed at a different time, asynchronous of the current execution thread of the current `multi_index_example::mod` action, therefor it is impossible to predict when the `print` statements from inline action code will be outputted. + +## Assertion failure while creating an account after eosio.system was installed + +```console +cleos create account eosio bob EOS5HUanbay86UUnr1d4fuBsQ3ksjfgZYoLUVvrYVLy6pj4i8xqVY +Error 3050003: eosio_assert_message assertion failure +Error Details: +assertion failure with message: system contract must first be initialized +``` + +The failure is stating that `eosio.system` init action hasn't been called yet. The init action implementation is done through `void init(uint64_t, symbol)` function. The first parameter is the version, this should always be `0` for now, until a new version of `init` will be created that handles more information. +The second parameter is the system's symbol (i.e. for main net this is `EOS`). If you followed the [BIOS Boot Sequence](https://developers.eos.io/welcome/latest/tutorials/bios-boot-sequence) tutorial and created a system with the default symbol `SYS` then `SYS` shall be used as the system's symbol in the init action. It is whatever symbol you as the chain creator want to use in your `EOSIO` based blockchain. From 3a67714928f9110d2b560084c4e2cb52c281daca Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 3 Feb 2021 16:38:23 +0200 Subject: [PATCH 025/204] correction --- docs/08_troubleshooting.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting.md index 2affa59534..5657d9fe6d 100644 --- a/docs/08_troubleshooting.md +++ b/docs/08_troubleshooting.md @@ -160,5 +160,5 @@ Error Details: assertion failure with message: system contract must first be initialized ``` -The failure is stating that `eosio.system` init action hasn't been called yet. The init action implementation is done through `void init(uint64_t, symbol)` function. The first parameter is the version, this should always be `0` for now, until a new version of `init` will be created that handles more information. -The second parameter is the system's symbol (i.e. for main net this is `EOS`). If you followed the [BIOS Boot Sequence](https://developers.eos.io/welcome/latest/tutorials/bios-boot-sequence) tutorial and created a system with the default symbol `SYS` then `SYS` shall be used as the system's symbol in the init action. It is whatever symbol you as the chain creator want to use in your `EOSIO` based blockchain. +The failure is stating that `eosio.system` `init` action hasn't been called yet. The `init` action implementation is done through `void init(uint64_t, symbol)` function. The first parameter is the version, this should always be `0` for now, until a new version of `init` will be created that handles more information. +The second parameter is the system's symbol (i.e. for main net this is `EOS`). If you followed the [BIOS Boot Sequence](https://developers.eos.io/welcome/latest/tutorials/bios-boot-sequence) tutorial and created a system with the default symbol `SYS` then `SYS` shall be used as the system's symbol in the `init` action. It is whatever symbol you as the chain creator want to use in your `EOSIO` based blockchain. From cca3d05a7351c81eea0ddb9d8815259903458fb6 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 3 Feb 2021 17:00:49 +0200 Subject: [PATCH 026/204] correction --- docs/08_troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting.md index 5657d9fe6d..15e22c7cab 100644 --- a/docs/08_troubleshooting.md +++ b/docs/08_troubleshooting.md @@ -160,5 +160,5 @@ Error Details: assertion failure with message: system contract must first be initialized ``` -The failure is stating that `eosio.system` `init` action hasn't been called yet. The `init` action implementation is done through `void init(uint64_t, symbol)` function. The first parameter is the version, this should always be `0` for now, until a new version of `init` will be created that handles more information. +The failure is stating that `eosio.system` `init` action was not called yet. The `init` action is implemented by the `void init(uint64_t, symbol)` function. The first parameter is the version, this should always be `0` for now, until a new version of `init` will be created that handles more information. The second parameter is the system's symbol (i.e. for main net this is `EOS`). If you followed the [BIOS Boot Sequence](https://developers.eos.io/welcome/latest/tutorials/bios-boot-sequence) tutorial and created a system with the default symbol `SYS` then `SYS` shall be used as the system's symbol in the `init` action. It is whatever symbol you as the chain creator want to use in your `EOSIO` based blockchain. From 802169f67b4a018ba6807ba69a5bc545457f2b29 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 3 Feb 2021 17:28:12 +0200 Subject: [PATCH 027/204] the `@cond IMPLEMENTATIONS` was preventing doxygen from parsing the annotation for ""_n opearator --- libraries/eosiolib/core/eosio/name.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libraries/eosiolib/core/eosio/name.hpp b/libraries/eosiolib/core/eosio/name.hpp index 0021be3fd2..c7ad00e579 100644 --- a/libraries/eosiolib/core/eosio/name.hpp +++ b/libraries/eosiolib/core/eosio/name.hpp @@ -313,11 +313,7 @@ namespace eosio { } /// namespace detail } /// namespace eosio -/// @cond IMPLEMENTATIONS - /** - * %name literal operator - * * @ingroup name * @brief "foo"_n is a shortcut for name("foo") */ @@ -329,5 +325,3 @@ inline constexpr eosio::name operator""_n() { return x; } #pragma clang diagnostic pop - -/// @endcond From 7479baaff642d8c876c18ec7b0f51e92044de0e0 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 3 Feb 2021 09:39:02 -0600 Subject: [PATCH 028/204] Delete old files from Docker dir & add script for new binary --- .cicd/create-docker-from-binary.sh | 52 ++++++++++++++++++++++++++++++ docker/Dockerfile | 13 -------- docker/dev/Dockerfile | 10 ------ docker/install_deb.sh | 19 ----------- 4 files changed, 52 insertions(+), 42 deletions(-) create mode 100755 .cicd/create-docker-from-binary.sh delete mode 100644 docker/Dockerfile delete mode 100644 docker/dev/Dockerfile delete mode 100755 docker/install_deb.sh diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh new file mode 100755 index 0000000000..e7bdb07d43 --- /dev/null +++ b/.cicd/create-docker-from-binary.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +set -euo pipefail + +buildkite-agent artifact download '*.deb' --step ':ubuntu: Ubuntu 18.04 - Package Builder' . +echo ":done: download successful" + +SANITIZED_BRANCH=$(echo "$BUILDKITE_BRANCH" | sed 's.^/..' | sed 's/[:/]/_/g') +SANITIZED_TAG=$(echo "$BUILDKITE_TAG" | sed 's.^/..' | tr '/' '_') +echo "$SANITIZED_BRANCH" +echo "$SANITIZED_TAG" + +# do docker build +echo ":docker::build: Building image..." +DOCKERHUB_REGISTRY="docker.io/eosio/eos" + +BUILD_TAG=${BUILDKITE_BUILD_NUMBER:-latest} +DOCKER_BUILD_GEN="docker build -t eos_image:$BUILD_TAG -f ./docker/dockerfile ." +echo "$ $DOCKER_BUILD_GEN" +eval $DOCKER_BUILD_GEN + +#tag and push on each destination AWS & DOCKERHUB + +EOSIO_REGS=("$EOSIO_REGISTRY" "$DOCKERHUB_REGISTRY") +for REG in ${EOSIO_REGS[@]}; do + DOCKER_TAG_COMMIT="docker tag eos_image:$BUILD_TAG $REG:$BUILDKITE_COMMIT" + DOCKER_TAG_BRANCH="docker tag eos_image:$BUILD_TAG $REG:$SANITIZED_BRANCH" + echo -e "$ Tagging Images: \n$DOCKER_TAG_COMMIT \n$DOCKER_TAG_BRANCH" + eval $DOCKER_TAG_COMMIT + eval $DOCKER_TAG_BRANCH + DOCKER_PUSH_COMMIT="docker push $REG:$BUILDKITE_COMMIT" + DOCKER_PUSH_BRANCH="docker push $REG:$SANITIZED_BRANCH" + echo -e "$ Pushing Images: \n$DOCKER_PUSH_COMMIT \n$DOCKER_PUSH_BRANCH" + eval $DOCKER_PUSH_COMMIT + eval $DOCKER_PUSH_BRANCH + CLEAN_IMAGE_COMMIT="docker rmi $REG:$BUILDKITE_COMMIT" + CLEAN_IMAGE_BRANCH="docker rmi $REG:$SANITIZED_BRANCH" + echo -e "Cleaning Up: \n$CLEAN_IMAGE_COMMIT \n$CLEAN_IMAGE_BRANCH$" + eval $CLEAN_IMAGE_COMMIT + eval $CLEAN_IMAGE_BRANCH + if [[ ! -z "$SANITIZED_TAG" ]]; then + DOCKER_TAG="docker tag eos_image $REG:$SANITIZED_TAG" + DOCKER_REM="docker rmi $REG:$SANITIZED_TAG" + echo -e "$ \n Tagging Image: \n$DOCKER_TAG \n Cleaning Up: \n$DOCKER_REM" + eval $DOCKER_TAG + eval $DOCKER_REM + fi +done + +DOCKER_GEN="docker rmi eos_image:$BUILD_TAG" +echo "Clean up base image" +eval $DOCKER_GEN \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 63c170d8eb..0000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM ubuntu:18.04 - -# Arguments that may be overridden by the user -ARG release=latest - -# Install required packages -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install openssl ca-certificates curl wget && rm -rf /var/lib/apt/lists/* - -# Install CDT from deb package -ADD install_deb.sh / -RUN /install_deb.sh $release && rm -f install_deb.sh - -USER root diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile deleted file mode 100644 index 584686a6ea..0000000000 --- a/docker/dev/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:18.04 - -# Install required packages -RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install openssl ca-certificates curl wget && rm -rf /var/lib/apt/lists/* - -# Install CDT from deb package -ADD build/packages/*.deb / -RUN for filename in $(ls *.deb); do /usr/bin/dpkg -i "$filename" && rm -f "$filename"; done - -USER root \ No newline at end of file diff --git a/docker/install_deb.sh b/docker/install_deb.sh deleted file mode 100755 index 43c6cb25a9..0000000000 --- a/docker/install_deb.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -if [ "$1" = "" ]; then - echo "In order to continue, you must specify either latest or the release version." - exit 1 -elif [ "$1" = "latest" ]; then - deb=$(/usr/bin/curl -s https://api.github.com/repos/EOSIO/eosio.cdt/releases/latest | grep "browser_download_url.*deb" | cut -d '"' -f 4) - filename=$(/usr/bin/curl -s https://api.github.com/repos/EOSIO/eosio.cdt/releases/latest | grep "name.*deb" | cut -d '"' -f 4) -else - deb=$(/usr/bin/curl -s https://api.github.com/repos/EOSIO/eosio.cdt/releases/tags/$1 | grep "browser_download_url.*deb" | cut -d '"' -f 4) - filename=$(/usr/bin/curl -s https://api.github.com/repos/EOSIO/eosio.cdt/releases/tags/$1 | grep "name.*deb" | cut -d '"' -f 4) -fi - -if [ "$deb" = "" ]; then - echo "Either $1 is not a valid release, or there is not a published .deb package for the release." - exit 1 -fi - -/usr/bin/wget $deb && /usr/bin/dpkg -i "$filename" && rm -f "$filename" From 4af93eb580aaa18f101d814ad7ebeb50e53cb166 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 3 Feb 2021 09:49:54 -0600 Subject: [PATCH 029/204] Create new Dockerfile and update reference to it --- .cicd/create-docker-from-binary.sh | 12 ++++++------ docker/Dockerfile | 8 ++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 docker/Dockerfile diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index e7bdb07d43..6bc630b735 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -12,10 +12,10 @@ echo "$SANITIZED_TAG" # do docker build echo ":docker::build: Building image..." -DOCKERHUB_REGISTRY="docker.io/eosio/eos" +DOCKERHUB_REGISTRY="docker.io/eosio/eosio.cdt" BUILD_TAG=${BUILDKITE_BUILD_NUMBER:-latest} -DOCKER_BUILD_GEN="docker build -t eos_image:$BUILD_TAG -f ./docker/dockerfile ." +DOCKER_BUILD_GEN="docker build -t eosio_cdt_image:$BUILD_TAG -f ./docker/Dockerfile ." echo "$ $DOCKER_BUILD_GEN" eval $DOCKER_BUILD_GEN @@ -23,8 +23,8 @@ eval $DOCKER_BUILD_GEN EOSIO_REGS=("$EOSIO_REGISTRY" "$DOCKERHUB_REGISTRY") for REG in ${EOSIO_REGS[@]}; do - DOCKER_TAG_COMMIT="docker tag eos_image:$BUILD_TAG $REG:$BUILDKITE_COMMIT" - DOCKER_TAG_BRANCH="docker tag eos_image:$BUILD_TAG $REG:$SANITIZED_BRANCH" + DOCKER_TAG_COMMIT="docker tag eosio_cdt_image:$BUILD_TAG $REG:$BUILDKITE_COMMIT" + DOCKER_TAG_BRANCH="docker tag eosio_cdt_image:$BUILD_TAG $REG:$SANITIZED_BRANCH" echo -e "$ Tagging Images: \n$DOCKER_TAG_COMMIT \n$DOCKER_TAG_BRANCH" eval $DOCKER_TAG_COMMIT eval $DOCKER_TAG_BRANCH @@ -39,7 +39,7 @@ for REG in ${EOSIO_REGS[@]}; do eval $CLEAN_IMAGE_COMMIT eval $CLEAN_IMAGE_BRANCH if [[ ! -z "$SANITIZED_TAG" ]]; then - DOCKER_TAG="docker tag eos_image $REG:$SANITIZED_TAG" + DOCKER_TAG="docker tag eosio_cdt_image $REG:$SANITIZED_TAG" DOCKER_REM="docker rmi $REG:$SANITIZED_TAG" echo -e "$ \n Tagging Image: \n$DOCKER_TAG \n Cleaning Up: \n$DOCKER_REM" eval $DOCKER_TAG @@ -47,6 +47,6 @@ for REG in ${EOSIO_REGS[@]}; do fi done -DOCKER_GEN="docker rmi eos_image:$BUILD_TAG" +DOCKER_GEN="docker rmi eosio_cdt_image:$BUILD_TAG" echo "Clean up base image" eval $DOCKER_GEN \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000000..7ea19b7494 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,8 @@ +FROM ubuntu:18.04 + +COPY *.deb / + +RUN apt update && \ + apt install -y curl wget && \ + apt install -y /*.deb && \ + rm -rf /*.deb /var/lib/apt/lists/* \ No newline at end of file From b9f7a30b62c57a746164adcc3c3abc05aeb38d82 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 3 Feb 2021 09:54:36 -0600 Subject: [PATCH 030/204] add step to the pipeline --- .cicd/pipeline.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 1bfdddbeb9..c3f3490868 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -421,6 +421,14 @@ steps: timeout: 20 skip: ${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} + - wait + + - label: ":docker::ubuntu: Docker - Build 18.04 Docker Image" + command: "./.cicd/create-docker-from-binary.sh" + agents: + queue: "automation-eks-eos-builder-fleet" + timeout: 10 + - label: ":git: Git Submodule Regression Check" command: - "./.cicd/submodule-regression-checker.sh" From 9e52a29815655f21f44ee44f9776b67b0b5b0c49 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 3 Feb 2021 14:08:05 -0500 Subject: [PATCH 031/204] Use filenames consistent with the eos repo --- docker/{Dockerfile => dockerfile} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docker/{Dockerfile => dockerfile} (100%) diff --git a/docker/Dockerfile b/docker/dockerfile similarity index 100% rename from docker/Dockerfile rename to docker/dockerfile From ffaa858aa0355c733d6b58f19445b5bdbffd6b77 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 3 Feb 2021 14:27:53 -0500 Subject: [PATCH 032/204] Add log folding groups + POSIX newline at EOF --- .cicd/create-docker-from-binary.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index 6bc630b735..4f248f97cd 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -1,5 +1,5 @@ #!/bin/bash - +echo '--- :evergreen_tree: Configuring Environment' set -euo pipefail buildkite-agent artifact download '*.deb' --step ':ubuntu: Ubuntu 18.04 - Package Builder' . @@ -11,6 +11,7 @@ echo "$SANITIZED_BRANCH" echo "$SANITIZED_TAG" # do docker build +echo '+++ :docker: Building Container' echo ":docker::build: Building image..." DOCKERHUB_REGISTRY="docker.io/eosio/eosio.cdt" @@ -20,7 +21,7 @@ echo "$ $DOCKER_BUILD_GEN" eval $DOCKER_BUILD_GEN #tag and push on each destination AWS & DOCKERHUB - +echo '+++ :arrow_up: Pushing Container' EOSIO_REGS=("$EOSIO_REGISTRY" "$DOCKERHUB_REGISTRY") for REG in ${EOSIO_REGS[@]}; do DOCKER_TAG_COMMIT="docker tag eosio_cdt_image:$BUILD_TAG $REG:$BUILDKITE_COMMIT" @@ -49,4 +50,4 @@ done DOCKER_GEN="docker rmi eosio_cdt_image:$BUILD_TAG" echo "Clean up base image" -eval $DOCKER_GEN \ No newline at end of file +eval $DOCKER_GEN From be242af2dae684372a70002fb685bd8c8e96475a Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 3 Feb 2021 17:30:59 -0600 Subject: [PATCH 033/204] Remove curl install from dockerfile & updated to the new ECR repo name --- .cicd/create-docker-from-binary.sh | 4 ++-- docker/dockerfile | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index 4f248f97cd..98fa89dabb 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -16,13 +16,13 @@ echo ":docker::build: Building image..." DOCKERHUB_REGISTRY="docker.io/eosio/eosio.cdt" BUILD_TAG=${BUILDKITE_BUILD_NUMBER:-latest} -DOCKER_BUILD_GEN="docker build -t eosio_cdt_image:$BUILD_TAG -f ./docker/Dockerfile ." +DOCKER_BUILD_GEN="docker build -t eosio_cdt_image:$BUILD_TAG -f ./docker/dockerfile ." echo "$ $DOCKER_BUILD_GEN" eval $DOCKER_BUILD_GEN #tag and push on each destination AWS & DOCKERHUB echo '+++ :arrow_up: Pushing Container' -EOSIO_REGS=("$EOSIO_REGISTRY" "$DOCKERHUB_REGISTRY") +EOSIO_REGS=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") for REG in ${EOSIO_REGS[@]}; do DOCKER_TAG_COMMIT="docker tag eosio_cdt_image:$BUILD_TAG $REG:$BUILDKITE_COMMIT" DOCKER_TAG_BRANCH="docker tag eosio_cdt_image:$BUILD_TAG $REG:$SANITIZED_BRANCH" diff --git a/docker/dockerfile b/docker/dockerfile index 7ea19b7494..f0176ddef6 100644 --- a/docker/dockerfile +++ b/docker/dockerfile @@ -3,6 +3,5 @@ FROM ubuntu:18.04 COPY *.deb / RUN apt update && \ - apt install -y curl wget && \ apt install -y /*.deb && \ rm -rf /*.deb /var/lib/apt/lists/* \ No newline at end of file From ba58fe2a8cfed9a41c3907855cd9d1708f45e6d5 Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Fri, 5 Feb 2021 13:19:18 -0600 Subject: [PATCH 034/204] Update apt to apt-get and POSIX & changed to tester fleet in pipeline --- .cicd/pipeline.yml | 2 +- docker/dockerfile | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index c3f3490868..c63304e3b8 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -426,7 +426,7 @@ steps: - label: ":docker::ubuntu: Docker - Build 18.04 Docker Image" command: "./.cicd/create-docker-from-binary.sh" agents: - queue: "automation-eks-eos-builder-fleet" + queue: "automation-eks-eos-tester-fleet" timeout: 10 - label: ":git: Git Submodule Regression Check" diff --git a/docker/dockerfile b/docker/dockerfile index f0176ddef6..340058a969 100644 --- a/docker/dockerfile +++ b/docker/dockerfile @@ -2,6 +2,8 @@ FROM ubuntu:18.04 COPY *.deb / -RUN apt update && \ - apt install -y /*.deb && \ - rm -rf /*.deb /var/lib/apt/lists/* \ No newline at end of file +RUN apt-get update && \ + apt-get install -y /*.deb && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + \ No newline at end of file From 6229477ed1769baf7b1d3766e5a3a9a6c8409e40 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Fri, 5 Feb 2021 15:42:08 -0500 Subject: [PATCH 035/204] Fix whitespace --- docker/dockerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/docker/dockerfile b/docker/dockerfile index 340058a969..20978c92e0 100644 --- a/docker/dockerfile +++ b/docker/dockerfile @@ -1,9 +1,6 @@ FROM ubuntu:18.04 - COPY *.deb / - RUN apt-get update && \ apt-get install -y /*.deb && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* - \ No newline at end of file From 4bb3f5655ed99a62b83ec2189ce5bee5cc0a9fb6 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 9 Feb 2021 14:36:04 +0200 Subject: [PATCH 036/204] use console and sh --- docs/08_troubleshooting.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting.md index 15e22c7cab..e8da1593a9 100644 --- a/docs/08_troubleshooting.md +++ b/docs/08_troubleshooting.md @@ -153,8 +153,11 @@ The code above has one `print` statement before the `singleton_set.send` and ano ## Assertion failure while creating an account after eosio.system was installed -```console +```sh cleos create account eosio bob EOS5HUanbay86UUnr1d4fuBsQ3ksjfgZYoLUVvrYVLy6pj4i8xqVY +``` + +```console Error 3050003: eosio_assert_message assertion failure Error Details: assertion failure with message: system contract must first be initialized From 371978edd55446bb46eb1d39cb05bf68d3ff9dcc Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 10 Feb 2021 21:27:11 +0200 Subject: [PATCH 037/204] fixes #971 [docs] Deferred transaction collisions and NO_DUPLICATE_DEFERRED_ID --- docs/05_best-practices/09_deferred_transactions.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/05_best-practices/09_deferred_transactions.md b/docs/05_best-practices/09_deferred_transactions.md index 7866fed4cd..e9aafb080a 100644 --- a/docs/05_best-practices/09_deferred_transactions.md +++ b/docs/05_best-practices/09_deferred_transactions.md @@ -10,3 +10,6 @@ As already mentioned, deferred communication will get scheduled later at the pro | As of [EOSIO 2.0 RC1](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) deferred transactions are deprecated. Due to the above described behaviors it is not recommended to use `deferred transactions`. + +[[warning | Duplicate deferred transaction IDs in the same block]] +| In earlier versions, prior to `v1.8.0`, it is possible to observe rare deferred transaction hash collisions because technically the protocol's validation rules allow any number of duplicate deferred transaction IDs. However, the block producing code prior to `v1.8.0` limited this to exactly one duplicate ID in the same block followed by at-most one duplicate ID in the following block. This behavior was mitigated starting with version `v1.8.0` making it functionally impossible to be achieved at the block producing code level. On top of that, the same version `v1.8.0` introduced the optional `NO_DUPLICATE_DEFERRED_ID` protocol feature which, if deployed, it makes this behavior impossible at the protocol layer as well. From e5c85711fd554c8fc184666f93c9ef2a5826a370 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 10 Feb 2021 21:38:56 +0200 Subject: [PATCH 038/204] small update/correction for callout title --- docs/05_best-practices/09_deferred_transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/05_best-practices/09_deferred_transactions.md b/docs/05_best-practices/09_deferred_transactions.md index e9aafb080a..0233696a71 100644 --- a/docs/05_best-practices/09_deferred_transactions.md +++ b/docs/05_best-practices/09_deferred_transactions.md @@ -11,5 +11,5 @@ As already mentioned, deferred communication will get scheduled later at the pro Due to the above described behaviors it is not recommended to use `deferred transactions`. -[[warning | Duplicate deferred transaction IDs in the same block]] +[[warning | Duplicate deferred transaction IDs]] | In earlier versions, prior to `v1.8.0`, it is possible to observe rare deferred transaction hash collisions because technically the protocol's validation rules allow any number of duplicate deferred transaction IDs. However, the block producing code prior to `v1.8.0` limited this to exactly one duplicate ID in the same block followed by at-most one duplicate ID in the following block. This behavior was mitigated starting with version `v1.8.0` making it functionally impossible to be achieved at the block producing code level. On top of that, the same version `v1.8.0` introduced the optional `NO_DUPLICATE_DEFERRED_ID` protocol feature which, if deployed, it makes this behavior impossible at the protocol layer as well. From 66737cd21baf2545d16b41aa8ce770b93f78f44f Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 10 Feb 2021 21:51:47 +0200 Subject: [PATCH 039/204] update based on review feedback --- docs/05_best-practices/09_deferred_transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/05_best-practices/09_deferred_transactions.md b/docs/05_best-practices/09_deferred_transactions.md index 0233696a71..82036a6734 100644 --- a/docs/05_best-practices/09_deferred_transactions.md +++ b/docs/05_best-practices/09_deferred_transactions.md @@ -12,4 +12,4 @@ As already mentioned, deferred communication will get scheduled later at the pro Due to the above described behaviors it is not recommended to use `deferred transactions`. [[warning | Duplicate deferred transaction IDs]] -| In earlier versions, prior to `v1.8.0`, it is possible to observe rare deferred transaction hash collisions because technically the protocol's validation rules allow any number of duplicate deferred transaction IDs. However, the block producing code prior to `v1.8.0` limited this to exactly one duplicate ID in the same block followed by at-most one duplicate ID in the following block. This behavior was mitigated starting with version `v1.8.0` making it functionally impossible to be achieved at the block producing code level. On top of that, the same version `v1.8.0` introduced the optional `NO_DUPLICATE_DEFERRED_ID` protocol feature which, if deployed, it makes this behavior impossible at the protocol layer as well. +| In earlier versions, prior to `v1.8.0`, it is possible to observe rare deferred transaction ID collisions because technically the protocol's validation rules allow any number of duplicate deferred transaction IDs. However, the block producing code prior to `v1.8.0` limited this to exactly one duplicate ID in the same block followed by at-most one duplicate ID in the following block. This behavior was mitigated starting with version `v1.8.0` making it functionally impossible to be achieved at the block producing code level. On top of that, the same version `v1.8.0` introduced the optional `NO_DUPLICATE_DEFERRED_ID` protocol feature which, if deployed, it makes this behavior impossible at the protocol layer as well. From a46cde21e2f9fd7a9c14bb1987754ca696e61536 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 26 Feb 2021 08:55:29 -0500 Subject: [PATCH 040/204] add testing smart contract for read-only query --- tests/unit/test_contracts/read_only_tests.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/unit/test_contracts/read_only_tests.cpp diff --git a/tests/unit/test_contracts/read_only_tests.cpp b/tests/unit/test_contracts/read_only_tests.cpp new file mode 100644 index 0000000000..8a6f07e92a --- /dev/null +++ b/tests/unit/test_contracts/read_only_tests.cpp @@ -0,0 +1,12 @@ +#include "transfer.hpp" +#include +using namespace eosio; + +class [[eosio::contract]] read_only_tests : public contract { + public: + using contract::contract; + [[eosio::action, eosio::read_only]] + void hi( name user ) { + print( "Hello, ", user); + } +}; From 3e74845c43330280c5435eb0a584436ca68f5215 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Mon, 8 Feb 2021 11:24:21 -0600 Subject: [PATCH 041/204] Adding ubuntu 16.04, centos 8, and amazon_linux 2 support --- .cicd/docker/centos-8.dockerfile | 9 ++++ .cicd/package.sh | 4 +- .cicd/pipeline.yml | 75 ++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 .cicd/docker/centos-8.dockerfile diff --git a/.cicd/docker/centos-8.dockerfile b/.cicd/docker/centos-8.dockerfile new file mode 100644 index 0000000000..5ddb698b83 --- /dev/null +++ b/.cicd/docker/centos-8.dockerfile @@ -0,0 +1,9 @@ +FROM centos:8 +# install dependencies +RUN yum update -y && \ + yum install -y gdisk && \ + yum install -y cmake && \ + yum install -y git autoconf automake bzip2 \ + libtool make \ + libicu-devel.x86_64 bzip2.x86_64 bzip2-devel.x86_64 openssl-devel.x86_64 \ + gmp-devel.x86_64 python38 python3-devel gettext-devel.x86_64 gcc-c++.x86_64 perl diff --git a/.cicd/package.sh b/.cicd/package.sh index 9f75d1134d..540f657b7b 100755 --- a/.cicd/package.sh +++ b/.cicd/package.sh @@ -33,7 +33,7 @@ else # Linux ARTIFACT='*.deb' PACKAGE_TYPE='deb' PACKAGE_COMMANDS="./generate_package.sh $PACKAGE_TYPE" - elif [[ "$IMAGE_TAG" =~ "centos" ]]; then + elif [[ "$IMAGE_TAG" =~ "centos" || "$IMAGE_TAG" =~ "amazonlinux" ]]; then ARTIFACT='*.rpm' PACKAGE_TYPE='rpm' PACKAGE_COMMANDS="mkdir -p ~/rpmbuild/BUILD && mkdir -p ~/rpmbuild/BUILDROOT && mkdir -p ~/rpmbuild/RPMS && mkdir -p ~/rpmbuild/SOURCES && mkdir -p ~/rpmbuild/SPECS && mkdir -p ~/rpmbuild/SRPMS && yum install -y rpm-build && ./generate_package.sh $PACKAGE_TYPE" @@ -63,4 +63,4 @@ else # Linux fi done -fi \ No newline at end of file +fi diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index c63304e3b8..196e45b4d1 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -24,6 +24,17 @@ steps: timeout: ${TIMEOUT:-60} skip: $SKIP_CENTOS_7 + - label: ":centos: CentOS 8 - Build" + command: + - "./.cicd/build.sh" + - "tar -pczf build.tar.gz build && buildkite-agent artifact upload build.tar.gz" + env: + IMAGE_TAG: "centos-8" + agents: + queue: "automation-eks-eos-builder-fleet" + timeout: ${TIMEOUT:-60} + skip: $SKIP_CENTOS_8 + - label: ":ubuntu: Ubuntu 16.04 - Build" command: - "./.cicd/build.sh" @@ -132,6 +143,17 @@ steps: timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_7}${SKIP_UNIT_TESTS} + - label: ":centos: CentOS 8 - Unit Tests" + command: + - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 8 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" + - "./.cicd/tests.sh" + env: + IMAGE_TAG: "centos-8" + agents: + queue: "automation-eks-eos-tester-fleet" + timeout: ${TIMEOUT:-10} + skip: ${SKIP_CENTOS_8}${SKIP_UNIT_TESTS} + - label: ":ubuntu: Ubuntu 16.04 - Unit Tests" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 16.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -237,6 +259,17 @@ steps: timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_7}${SKIP_TOOLCHAIN_TESTS} + - label: ":centos: CentOS 8 - Toolchain Tests" + command: + - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 8 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" + - "./.cicd/toolchain-tests.sh" + env: + IMAGE_TAG: "centos-8" + agents: + queue: "automation-eks-eos-tester-fleet" + timeout: ${TIMEOUT:-10} + skip: ${SKIP_CENTOS_8}${SKIP_TOOLCHAIN_TESTS} + - label: ":ubuntu: Ubuntu 16.04 - Toolchain Tests" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 16.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -349,6 +382,20 @@ steps: - wait + - label: ":aws: Amazon_Linux 2 - Package Builder" + command: + - "buildkite-agent artifact download build.tar.gz . --step ':aws: Amazon_Linux 2 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" + - "./.cicd/package.sh" + env: + BUILDKITE_AGENT_ACCESS_TOKEN: + IMAGE_TAG: "amazonlinux-2" + OS: "amzn" # OS and PKGTYPE required for lambdas + PKGTYPE: "rpm" + agents: + queue: "automation-eks-eos-tester-fleet" + timeout: ${TIMEOUT:-10} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER} + - label: ":centos: Centos 7.7 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 7.7 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -363,6 +410,34 @@ steps: timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER} + - label: ":centos: Centos 8 - Package Builder" + command: + - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 8 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" + - "./.cicd/package.sh" + env: + BUILDKITE_AGENT_ACCESS_TOKEN: + IMAGE_TAG: "centos-8" + OS: "centos" # OS and PKGTYPE required for lambdas + PKGTYPE: "rpm" + agents: + queue: "automation-eks-eos-tester-fleet" + timeout: ${TIMEOUT:-10} + skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER} + + - label: ":ubuntu: Ubuntu 16.04 - Package Builder" + command: + - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 16.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" + - "./.cicd/package.sh" + env: + BUILDKITE_AGENT_ACCESS_TOKEN: + IMAGE_TAG: "ubuntu-16.04" + OS: "ubuntu-16.04" # OS and PKGTYPE required for lambdas + PKGTYPE: "deb" + agents: + queue: "automation-eks-eos-tester-fleet" + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 18.04 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" From 1273916ddef1542f974420b33f0b6e1d33744900 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Tue, 9 Feb 2021 10:48:45 -0600 Subject: [PATCH 042/204] Updating toolchain tests for centos 8 --- .cicd/toolchain-tests.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.cicd/toolchain-tests.sh b/.cicd/toolchain-tests.sh index 749409a0c6..dce065489e 100755 --- a/.cicd/toolchain-tests.sh +++ b/.cicd/toolchain-tests.sh @@ -15,11 +15,20 @@ else # Linux ARGS=${ARGS:-"--rm --init -v $(pwd):$MOUNTED_DIR"} - PRE_COMMANDS="cd $MOUNTED_DIR/build" - SET_PYTHON_PATH="export CICD_PYTHON_PATH=/usr/local/bin/python3" - TEST="./tools/toolchain-tester/toolchain-tester ../tests/toolchain/" - - COMMANDS="$PRE_COMMANDS && $SET_PYTHON_PATH && $TEST" + if [[ "$IMAGE_TAG" == "centos-8" ]]; then + PRE_COMMANDS="cd $MOUNTED_DIR/build" + PACKAGE_COMMANDS="yum install -y python38" + SET_PYTHON_PATH="export CICD_PYTHON_PATH=/usr/local/bin/python3.8" + TEST="./tools/toolchain-tester/toolchain-tester ../tests/toolchain/" + + COMMANDS="$PRE_COMMANDS && $PACKAGE_COMMANDS && $SET_PYTHON_PATH && $TEST" + else + PRE_COMMANDS="cd $MOUNTED_DIR/build" + SET_PYTHON_PATH="export CICD_PYTHON_PATH=/usr/local/bin/python3" + TEST="./tools/toolchain-tester/toolchain-tester ../tests/toolchain/" + + COMMANDS="$PRE_COMMANDS && $SET_PYTHON_PATH && $TEST" + fi . $HELPERS_DIR/docker-hash.sh From 0c9afb75e937e3c663515b1fb363efbbb04a7cfa Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Tue, 9 Feb 2021 11:46:26 -0600 Subject: [PATCH 043/204] More toolchain test script changes for centos 8 --- .cicd/toolchain-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/toolchain-tests.sh b/.cicd/toolchain-tests.sh index dce065489e..7437600f97 100755 --- a/.cicd/toolchain-tests.sh +++ b/.cicd/toolchain-tests.sh @@ -18,7 +18,7 @@ else # Linux if [[ "$IMAGE_TAG" == "centos-8" ]]; then PRE_COMMANDS="cd $MOUNTED_DIR/build" PACKAGE_COMMANDS="yum install -y python38" - SET_PYTHON_PATH="export CICD_PYTHON_PATH=/usr/local/bin/python3.8" + SET_PYTHON_PATH="export CICD_PYTHON_PATH=/usr/bin/python3.8" TEST="./tools/toolchain-tester/toolchain-tester ../tests/toolchain/" COMMANDS="$PRE_COMMANDS && $PACKAGE_COMMANDS && $SET_PYTHON_PATH && $TEST" From 1783cd71fe32d43b31cc8b1b9d89206b265a00e0 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Wed, 17 Feb 2021 14:45:17 -0600 Subject: [PATCH 044/204] More rpath changes for testing --- tools/cc/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cc/CMakeLists.txt b/tools/cc/CMakeLists.txt index afb9265f7d..c43c4a6adf 100644 --- a/tools/cc/CMakeLists.txt +++ b/tools/cc/CMakeLists.txt @@ -4,3 +4,5 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/eosio-cpp.cpp.in ${CMAKE_BINARY_DIR}/ add_tool(eosio-cc) add_tool(eosio-cpp) + +set_target_properties(eosio-cpp PROPERTIES LINK_FLAGS "-Wl,-rpath,\"\\$ORIGIN/../lib\"") From 2e853dd362f4bd1086fbf6e562266b8bd395a91e Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Thu, 18 Feb 2021 10:01:24 -0600 Subject: [PATCH 045/204] Adding clang 9 libc++.so to ubuntu 16.04 package, and more rpath changes --- .cicd/package.sh | 2 +- scripts/generate_deb.sh | 8 ++- scripts/generate_package.sh.in | 3 +- scripts/generate_tarball_ubuntu-16.04.sh | 70 ++++++++++++++++++++++++ tools/abidiff/CMakeLists.txt | 2 + tools/cc/CMakeLists.txt | 1 + tools/external/wabt/CMakeLists.txt | 1 + tools/init/CMakeLists.txt | 2 + tools/ld/CMakeLists.txt | 2 + 9 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 scripts/generate_tarball_ubuntu-16.04.sh diff --git a/.cicd/package.sh b/.cicd/package.sh index 540f657b7b..dbcb56e50e 100755 --- a/.cicd/package.sh +++ b/.cicd/package.sh @@ -32,7 +32,7 @@ else # Linux if [[ "$IMAGE_TAG" =~ "ubuntu" ]]; then ARTIFACT='*.deb' PACKAGE_TYPE='deb' - PACKAGE_COMMANDS="./generate_package.sh $PACKAGE_TYPE" + PACKAGE_COMMANDS="./generate_package.sh $PACKAGE_TYPE $OS" elif [[ "$IMAGE_TAG" =~ "centos" || "$IMAGE_TAG" =~ "amazonlinux" ]]; then ARTIFACT='*.rpm' PACKAGE_TYPE='rpm' diff --git a/scripts/generate_deb.sh b/scripts/generate_deb.sh index b0460aa17a..d669bc9029 100644 --- a/scripts/generate_deb.sh +++ b/scripts/generate_deb.sh @@ -1,5 +1,7 @@ #! /bin/bash +OS=$1 + PREFIX="usr" SPREFIX=${PREFIX} SUBPREFIX="opt/${PROJECT}/${VERSION}" @@ -29,7 +31,11 @@ export SUBPREFIX export SPREFIX export SSUBPREFIX -. ./generate_tarball.sh ${NAME} +if [[ "$OS" == "ubuntu-16.04" ]]; then + . ./generate_tarball_ubuntu-16.04.sh ${NAME} +else + . ./generate_tarball.sh ${NAME} +fi echo "Unpacking tarball: ${NAME}.tar.gz..." tar -xzvf ${NAME}.tar.gz -C ${PROJECT} || exit 1 dpkg-deb --build ${PROJECT} || exit 1 diff --git a/scripts/generate_package.sh.in b/scripts/generate_package.sh.in index 4874a1b424..10cd58f2ce 100644 --- a/scripts/generate_package.sh.in +++ b/scripts/generate_package.sh.in @@ -1,6 +1,7 @@ #! /bin/bash VARIANT=$1 +OS=$2 VERSION_NO_SUFFIX="@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@" VERSION_SUFFIX="@VERSION_SUFFIX@" @@ -30,7 +31,7 @@ mkdir -p tmp if [[ ${VARIANT} == "brew" ]]; then . ./generate_bottle.sh elif [[ ${VARIANT} == "deb" ]]; then - . ./generate_deb.sh + . ./generate_deb.sh ${OS} elif [[ ${VARIANT} == "rpm" ]]; then . ./generate_rpm.sh else diff --git a/scripts/generate_tarball_ubuntu-16.04.sh b/scripts/generate_tarball_ubuntu-16.04.sh new file mode 100644 index 0000000000..b07f1d4a03 --- /dev/null +++ b/scripts/generate_tarball_ubuntu-16.04.sh @@ -0,0 +1,70 @@ +#! /bin/bash + +NAME=$1 +CDT_PREFIX=${PREFIX}/${SUBPREFIX} +mkdir -p ${PREFIX}/bin/ +mkdir -p ${PREFIX}/lib/cmake/${PROJECT} +mkdir -p ${CDT_PREFIX}/bin +mkdir -p ${CDT_PREFIX}/include +mkdir -p ${CDT_PREFIX}/lib/cmake/${PROJECT} +mkdir -p ${CDT_PREFIX}/cmake +mkdir -p ${CDT_PREFIX}/scripts +mkdir -p ${CDT_PREFIX}/licenses + +#echo "${PREFIX} ** ${SUBPREFIX} ** ${CDT_PREFIX}" + +# install binaries +cp -R ${BUILD_DIR}/bin/* ${CDT_PREFIX}/bin || exit 1 +cp -R ${BUILD_DIR}/licenses/* ${CDT_PREFIX}/licenses || exit 1 + +# install cmake modules +sed "s/_PREFIX_/\/${SPREFIX}/g" ${BUILD_DIR}/modules/EosioCDTMacrosPackage.cmake &> ${CDT_PREFIX}/lib/cmake/${PROJECT}/EosioCDTMacros.cmake || exit 1 +sed "s/_PREFIX_/\/${SPREFIX}/g" ${BUILD_DIR}/modules/EosioWasmToolchainPackage.cmake &> ${CDT_PREFIX}/lib/cmake/${PROJECT}/EosioWasmToolchain.cmake || exit 1 +sed "s/_PREFIX_/\/${SPREFIX}\/${SSUBPREFIX}/g" ${BUILD_DIR}/modules/${PROJECT}-config.cmake.package &> ${CDT_PREFIX}/lib/cmake/${PROJECT}/${PROJECT}-config.cmake || exit 1 + +# install scripts +cp -R ${BUILD_DIR}/scripts/* ${CDT_PREFIX}/scripts || exit 1 + +# install misc. +cp ${BUILD_DIR}/eosio.imports ${CDT_PREFIX} || exit 1 + +# install wasm includes +cp -R ${BUILD_DIR}/include/* ${CDT_PREFIX}/include || exit 1 + +# install wasm libs +cp ${BUILD_DIR}/lib/*.a ${CDT_PREFIX}/lib || exit 1 + +# install libc++.so +cp /usr/lib/libc++.so.1.0 ${CDT_PREFIX}/lib || exit 1 + +# make symlinks +pushd ${PREFIX}/lib/cmake/${PROJECT} &> /dev/null +ln -sf ../../../${SUBPREFIX}/lib/cmake/${PROJECT}/${PROJECT}-config.cmake ${PROJECT}-config.cmake || exit 1 +ln -sf ../../../${SUBPREFIX}/lib/cmake/${PROJECT}/EosioWasmToolchain.cmake EosioWasmToolchain.cmake || exit 1 +ln -sf ../../../${SUBPREFIX}/lib/cmake/${PROJECT}/EosioCDTMacros.cmake EosioCDTMacros.cmake || exit 1 +popd &> /dev/null + +create_symlink() { + ln -sf ../${SUBPREFIX}/bin/$1 ${PREFIX}/bin/$2 || exit 1 +} + +create_symlink eosio-cc eosio-cc +create_symlink eosio-cpp eosio-cpp +create_symlink eosio-ld eosio-ld +create_symlink eosio-pp eosio-pp +create_symlink eosio-init eosio-init +create_symlink eosio-wasm2wast eosio-wasm2wast +create_symlink eosio-wast2wasm eosio-wast2wasm +create_symlink eosio-ar eosio-ar +create_symlink eosio-abidiff eosio-abidiff +create_symlink eosio-nm eosio-nm +create_symlink eosio-objcopy eosio-objcopy +create_symlink eosio-objdump eosio-objdump +create_symlink eosio-ranlib eosio-ranlib +create_symlink eosio-readelf eosio-readelf +create_symlink eosio-strip eosio-strip +create_symlink ${CDT_PREFIX}/lib/libc++.so.1.0 ${CDT_PREFIX}/lib/libc++.so.1 + +echo "Generating Tarball $NAME.tar.gz..." +tar -cvzf $NAME.tar.gz ./${PREFIX}/* || exit 1 +rm -r ${PREFIX} || exit 1 diff --git a/tools/abidiff/CMakeLists.txt b/tools/abidiff/CMakeLists.txt index 07fa7cc3ac..15c2e2106e 100644 --- a/tools/abidiff/CMakeLists.txt +++ b/tools/abidiff/CMakeLists.txt @@ -1,3 +1,5 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/eosio-abidiff.cpp.in ${CMAKE_BINARY_DIR}/eosio-abidiff.cpp) add_tool(eosio-abidiff) + +set_target_properties(eosio-abidiff PROPERTIES LINK_FLAGS "-Wl,-rpath,\"\\$ORIGIN/../lib\"") diff --git a/tools/cc/CMakeLists.txt b/tools/cc/CMakeLists.txt index c43c4a6adf..52e2dc2100 100644 --- a/tools/cc/CMakeLists.txt +++ b/tools/cc/CMakeLists.txt @@ -5,4 +5,5 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/eosio-cpp.cpp.in ${CMAKE_BINARY_DIR}/ add_tool(eosio-cc) add_tool(eosio-cpp) +set_target_properties(eosio-cc PROPERTIES LINK_FLAGS "-Wl,-rpath,\"\\$ORIGIN/../lib\"") set_target_properties(eosio-cpp PROPERTIES LINK_FLAGS "-Wl,-rpath,\"\\$ORIGIN/../lib\"") diff --git a/tools/external/wabt/CMakeLists.txt b/tools/external/wabt/CMakeLists.txt index cda05652d7..c152bc75ef 100644 --- a/tools/external/wabt/CMakeLists.txt +++ b/tools/external/wabt/CMakeLists.txt @@ -285,6 +285,7 @@ if (NOT EMSCRIPTEN) target_link_libraries(${name} libwabt) set_property(TARGET ${name} PROPERTY CXX_STANDARD 11) set_property(TARGET ${name} PROPERTY CXX_STANDARD_REQUIRED ON) + set_target_properties(${name} PROPERTIES LINK_FLAGS "-Wl,-rpath,\"\\$ORIGIN/../lib\"") list(APPEND WABT_EXECUTABLES ${name}) set(WABT_EXECUTABLES ${WABT_EXECUTABLES} PARENT_SCOPE) diff --git a/tools/init/CMakeLists.txt b/tools/init/CMakeLists.txt index 722734af52..67552090d8 100644 --- a/tools/init/CMakeLists.txt +++ b/tools/init/CMakeLists.txt @@ -1,3 +1,5 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/eosio-init.cpp ${CMAKE_BINARY_DIR}/eosio-init.cpp @ONLY) add_tool(eosio-init) + +set_target_properties(eosio-init PROPERTIES LINK_FLAGS "-Wl,-rpath,\"\\$ORIGIN/../lib\"") diff --git a/tools/ld/CMakeLists.txt b/tools/ld/CMakeLists.txt index e2c41b4b3a..7ef6380aee 100644 --- a/tools/ld/CMakeLists.txt +++ b/tools/ld/CMakeLists.txt @@ -1,3 +1,5 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/eosio-ld.cpp.in ${CMAKE_BINARY_DIR}/eosio-ld.cpp) add_tool(eosio-ld) + +set_target_properties(eosio-ld PROPERTIES LINK_FLAGS "-Wl,-rpath,\"\\$ORIGIN/../lib\"") From 3a69956c474f61ef5e7a4d13a91dca7014f3da97 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Thu, 18 Feb 2021 13:04:22 -0600 Subject: [PATCH 046/204] Fixing buildkite errors --- scripts/generate_deb.sh | 6 +- scripts/generate_tarball.sh | 7 +++ scripts/generate_tarball_ubuntu-16.04.sh | 70 ------------------------ 3 files changed, 8 insertions(+), 75 deletions(-) delete mode 100644 scripts/generate_tarball_ubuntu-16.04.sh diff --git a/scripts/generate_deb.sh b/scripts/generate_deb.sh index d669bc9029..6126fbd7bc 100644 --- a/scripts/generate_deb.sh +++ b/scripts/generate_deb.sh @@ -31,11 +31,7 @@ export SUBPREFIX export SPREFIX export SSUBPREFIX -if [[ "$OS" == "ubuntu-16.04" ]]; then - . ./generate_tarball_ubuntu-16.04.sh ${NAME} -else - . ./generate_tarball.sh ${NAME} -fi +. ./generate_tarball.sh ${NAME} ${OS} echo "Unpacking tarball: ${NAME}.tar.gz..." tar -xzvf ${NAME}.tar.gz -C ${PROJECT} || exit 1 dpkg-deb --build ${PROJECT} || exit 1 diff --git a/scripts/generate_tarball.sh b/scripts/generate_tarball.sh index 2a9a56120f..6e73d37612 100644 --- a/scripts/generate_tarball.sh +++ b/scripts/generate_tarball.sh @@ -1,6 +1,7 @@ #! /bin/bash NAME=$1 +OS=$2 CDT_PREFIX=${PREFIX}/${SUBPREFIX} mkdir -p ${PREFIX}/bin/ mkdir -p ${PREFIX}/lib/cmake/${PROJECT} @@ -34,6 +35,12 @@ cp -R ${BUILD_DIR}/include/* ${CDT_PREFIX}/include || exit 1 # install wasm libs cp ${BUILD_DIR}/lib/*.a ${CDT_PREFIX}/lib || exit 1 +# install libc++.so +if [[ "$OS" == "ubuntu-16.04" ]]; then + cp /usr/lib/libc++.so.1.0 ${CDT_PREFIX}/lib || exit 1 + ln -sf ${CDT_PREFIX}/lib/libc++.so.1.0 ${CDT_PREFIX}/lib/libc++.so.1 +fi + # make symlinks pushd ${PREFIX}/lib/cmake/${PROJECT} &> /dev/null ln -sf ../../../${SUBPREFIX}/lib/cmake/${PROJECT}/${PROJECT}-config.cmake ${PROJECT}-config.cmake || exit 1 diff --git a/scripts/generate_tarball_ubuntu-16.04.sh b/scripts/generate_tarball_ubuntu-16.04.sh deleted file mode 100644 index b07f1d4a03..0000000000 --- a/scripts/generate_tarball_ubuntu-16.04.sh +++ /dev/null @@ -1,70 +0,0 @@ -#! /bin/bash - -NAME=$1 -CDT_PREFIX=${PREFIX}/${SUBPREFIX} -mkdir -p ${PREFIX}/bin/ -mkdir -p ${PREFIX}/lib/cmake/${PROJECT} -mkdir -p ${CDT_PREFIX}/bin -mkdir -p ${CDT_PREFIX}/include -mkdir -p ${CDT_PREFIX}/lib/cmake/${PROJECT} -mkdir -p ${CDT_PREFIX}/cmake -mkdir -p ${CDT_PREFIX}/scripts -mkdir -p ${CDT_PREFIX}/licenses - -#echo "${PREFIX} ** ${SUBPREFIX} ** ${CDT_PREFIX}" - -# install binaries -cp -R ${BUILD_DIR}/bin/* ${CDT_PREFIX}/bin || exit 1 -cp -R ${BUILD_DIR}/licenses/* ${CDT_PREFIX}/licenses || exit 1 - -# install cmake modules -sed "s/_PREFIX_/\/${SPREFIX}/g" ${BUILD_DIR}/modules/EosioCDTMacrosPackage.cmake &> ${CDT_PREFIX}/lib/cmake/${PROJECT}/EosioCDTMacros.cmake || exit 1 -sed "s/_PREFIX_/\/${SPREFIX}/g" ${BUILD_DIR}/modules/EosioWasmToolchainPackage.cmake &> ${CDT_PREFIX}/lib/cmake/${PROJECT}/EosioWasmToolchain.cmake || exit 1 -sed "s/_PREFIX_/\/${SPREFIX}\/${SSUBPREFIX}/g" ${BUILD_DIR}/modules/${PROJECT}-config.cmake.package &> ${CDT_PREFIX}/lib/cmake/${PROJECT}/${PROJECT}-config.cmake || exit 1 - -# install scripts -cp -R ${BUILD_DIR}/scripts/* ${CDT_PREFIX}/scripts || exit 1 - -# install misc. -cp ${BUILD_DIR}/eosio.imports ${CDT_PREFIX} || exit 1 - -# install wasm includes -cp -R ${BUILD_DIR}/include/* ${CDT_PREFIX}/include || exit 1 - -# install wasm libs -cp ${BUILD_DIR}/lib/*.a ${CDT_PREFIX}/lib || exit 1 - -# install libc++.so -cp /usr/lib/libc++.so.1.0 ${CDT_PREFIX}/lib || exit 1 - -# make symlinks -pushd ${PREFIX}/lib/cmake/${PROJECT} &> /dev/null -ln -sf ../../../${SUBPREFIX}/lib/cmake/${PROJECT}/${PROJECT}-config.cmake ${PROJECT}-config.cmake || exit 1 -ln -sf ../../../${SUBPREFIX}/lib/cmake/${PROJECT}/EosioWasmToolchain.cmake EosioWasmToolchain.cmake || exit 1 -ln -sf ../../../${SUBPREFIX}/lib/cmake/${PROJECT}/EosioCDTMacros.cmake EosioCDTMacros.cmake || exit 1 -popd &> /dev/null - -create_symlink() { - ln -sf ../${SUBPREFIX}/bin/$1 ${PREFIX}/bin/$2 || exit 1 -} - -create_symlink eosio-cc eosio-cc -create_symlink eosio-cpp eosio-cpp -create_symlink eosio-ld eosio-ld -create_symlink eosio-pp eosio-pp -create_symlink eosio-init eosio-init -create_symlink eosio-wasm2wast eosio-wasm2wast -create_symlink eosio-wast2wasm eosio-wast2wasm -create_symlink eosio-ar eosio-ar -create_symlink eosio-abidiff eosio-abidiff -create_symlink eosio-nm eosio-nm -create_symlink eosio-objcopy eosio-objcopy -create_symlink eosio-objdump eosio-objdump -create_symlink eosio-ranlib eosio-ranlib -create_symlink eosio-readelf eosio-readelf -create_symlink eosio-strip eosio-strip -create_symlink ${CDT_PREFIX}/lib/libc++.so.1.0 ${CDT_PREFIX}/lib/libc++.so.1 - -echo "Generating Tarball $NAME.tar.gz..." -tar -cvzf $NAME.tar.gz ./${PREFIX}/* || exit 1 -rm -r ${PREFIX} || exit 1 From f3ba70ee68c791d695b3ca714f263ecc3ad0c4e2 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Thu, 18 Feb 2021 15:38:24 -0600 Subject: [PATCH 047/204] Adding clang 9 libc++abi.so to ubuntu 16.04 package --- scripts/generate_tarball.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/generate_tarball.sh b/scripts/generate_tarball.sh index 6e73d37612..6605d25797 100644 --- a/scripts/generate_tarball.sh +++ b/scripts/generate_tarball.sh @@ -38,7 +38,10 @@ cp ${BUILD_DIR}/lib/*.a ${CDT_PREFIX}/lib || exit 1 # install libc++.so if [[ "$OS" == "ubuntu-16.04" ]]; then cp /usr/lib/libc++.so.1.0 ${CDT_PREFIX}/lib || exit 1 - ln -sf ${CDT_PREFIX}/lib/libc++.so.1.0 ${CDT_PREFIX}/lib/libc++.so.1 + cp /usr/lib/libc++abi.so.1.0 ${CDT_PREFIX}/lib || exit 1 + cd ${CDT_PREFIX}/lib || exit 1 + ln -sf libc++.so.1.0 libc++.so.1 || exit 1 + ln -sf libc++abi.so.1.0 libc++abi.so.1 || exit 1 fi # make symlinks From d4e22d69496aeb45c620b7ef7e7d03ee9f9fe142 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Thu, 18 Feb 2021 17:50:13 -0600 Subject: [PATCH 048/204] Fixing buildkite errors --- scripts/generate_tarball.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/generate_tarball.sh b/scripts/generate_tarball.sh index 6605d25797..c36286dfb9 100644 --- a/scripts/generate_tarball.sh +++ b/scripts/generate_tarball.sh @@ -39,9 +39,11 @@ cp ${BUILD_DIR}/lib/*.a ${CDT_PREFIX}/lib || exit 1 if [[ "$OS" == "ubuntu-16.04" ]]; then cp /usr/lib/libc++.so.1.0 ${CDT_PREFIX}/lib || exit 1 cp /usr/lib/libc++abi.so.1.0 ${CDT_PREFIX}/lib || exit 1 + DIR=`pwd` cd ${CDT_PREFIX}/lib || exit 1 ln -sf libc++.so.1.0 libc++.so.1 || exit 1 ln -sf libc++abi.so.1.0 libc++abi.so.1 || exit 1 + cd ${DIR} || exit 1 fi # make symlinks From 9e3dee8e9bcce5b86374f70b34d58fa4050ac0f5 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Mon, 1 Mar 2021 17:45:43 -0600 Subject: [PATCH 049/204] Checking presence of OS variable for deb package, as argument of generate_package script --- scripts/generate_package.sh.in | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/generate_package.sh.in b/scripts/generate_package.sh.in index 10cd58f2ce..fc07948b7e 100644 --- a/scripts/generate_package.sh.in +++ b/scripts/generate_package.sh.in @@ -1,7 +1,14 @@ #! /bin/bash VARIANT=$1 -OS=$2 +if [[ ${VARIANT} == "deb" ]]; then + if [ -z "$2" ]; then + echo "Error, OS argument missing for deb package type" + exit -1 + else + OS=$2 + fi +fi VERSION_NO_SUFFIX="@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@" VERSION_SUFFIX="@VERSION_SUFFIX@" From 41860adba1458fc768b494f37beb58b09da586d1 Mon Sep 17 00:00:00 2001 From: Venu Kailasa Date: Tue, 2 Mar 2021 17:21:01 -0600 Subject: [PATCH 050/204] Adding ubuntu 20.04 package builder --- .cicd/pipeline.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 196e45b4d1..812e7aadb3 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -452,6 +452,20 @@ steps: timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 20.04 - Package Builder" + command: + - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 20.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" + - "./.cicd/package.sh" + env: + BUILDKITE_AGENT_ACCESS_TOKEN: + IMAGE_TAG: "ubuntu-20.04" + OS: "ubuntu-20.04" # OS and PKGTYPE required for lambdas + PKGTYPE: "deb" + agents: + queue: "automation-eks-eos-tester-fleet" + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER} + - label: ":darwin: Mojave - Package Builder" command: - "git clone $BUILDKITE_REPO eosio.cdt" From 2839f32907eed66f9ec9c558bbc097b7d85067e2 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Tue, 9 Mar 2021 12:10:23 -0500 Subject: [PATCH 051/204] add FunctionDecl visitor --- tests/unit/test_contracts/read_only_tests.cpp | 26 ++++++++++- tools/include/eosio/codegen.hpp | 44 ++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_contracts/read_only_tests.cpp b/tests/unit/test_contracts/read_only_tests.cpp index 8a6f07e92a..b66f777a20 100644 --- a/tests/unit/test_contracts/read_only_tests.cpp +++ b/tests/unit/test_contracts/read_only_tests.cpp @@ -1,11 +1,35 @@ -#include "transfer.hpp" +#include "transfer.hpp" #include +#include + +extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); + using namespace eosio; class [[eosio::contract]] read_only_tests : public contract { public: using contract::contract; + void foo1() { bar(); } + void bar() {} + void foo2( name user, int64_t limit ) { set_resource_limit(user.value, "disk"_n.value, limit); } + [[eosio::action, eosio::read_only]] + void testreadonly( name user, int64_t limit ) { + print( "Hello, ", user); + int i; + foo1(); + set_resource_limit(user.value, "disk"_n.value, limit); + foo2(user, limit); + } + + [[eosio::action, eosio::read_only]] + void hireadonly( name user ) { + print( "Hello, ", user); + int i; + foo1(); + } + + [[eosio::action]] void hi( name user ) { print( "Hello, ", user); } diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 8e35b93cce..8f798e79f5 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -61,7 +61,7 @@ namespace eosio { namespace cdt { llvm::ArrayRef sources; size_t source_index = 0; std::map tmp_files; - + std::set read_only_actions; using generation_utils::generation_utils; static codegen& get() { @@ -234,6 +234,13 @@ namespace eosio { namespace cdt { create_action_dispatch(decl); } cg.actions.insert(full_action_name); // insert the method action, so we don't create the dispatcher twice + + if (decl->isEosioReadOnly()) { + cg.read_only_actions.insert(decl); + // for (auto it = cg.read_only_actions.begin(); it != cg.read_only_actions.end(); it++) { + // std::cout << (*it)->getDeclName().getAsString() << std::endl; + // } + } } else if (decl->isEosioNotify()) { @@ -265,6 +272,41 @@ namespace eosio { namespace cdt { return true; } + std::string ExprToString(Stmt *expr) + { + SourceRange expr_range = expr->getSourceRange(); + int range_size = get_rewriter().getRangeSize(expr_range); + if (range_size == -1) { + return ""; + } + + SourceLocation startLoc = expr_range.getBegin(); + const char *str_start = get_rewriter().getSourceMgr().getCharacterData(startLoc); + + std::string expr_str; + expr_str.assign(str_start, range_size); + return expr_str; + } + + virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { + std::cout << "FunctionDecl name: " << decl->getNameAsString() << "\n"; + + if (Stmt *stmts = decl->getBody()) { + for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { + if (CallExpr *call = dyn_cast(*it)) { + std::cout << "- Call: " << ExprToString(*it) << std::endl; + if (FunctionDecl *func_decl = call->getDirectCallee()) { + std::cout << " - Function call: " << func_decl->getNameInfo().getName().getAsString() << std::endl; + } else { + std::cout << " - Expression call: " << call->getCallee()->getStmtClassName() << std::endl; + } + } + } + } + + return true; + } + virtual bool VisitDecl(clang::Decl* decl) { if (auto* fd = dyn_cast(decl)) { if (fd->getNameInfo().getAsString() == "apply") From 740a9c630d7d10468e52333373b9e0b1fbba04aa Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Wed, 10 Mar 2021 15:32:00 -0600 Subject: [PATCH 052/204] add security group support --- .../eosiolib/capi/eosio/security_group.h | 56 ++++++++++++ .../contracts/eosio/security_group.hpp | 88 +++++++++++++++++++ libraries/native/intrinsics.cpp | 17 ++++ .../native/native/eosio/intrinsics_def.hpp | 8 +- 4 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 libraries/eosiolib/capi/eosio/security_group.h create mode 100644 libraries/eosiolib/contracts/eosio/security_group.hpp diff --git a/libraries/eosiolib/capi/eosio/security_group.h b/libraries/eosiolib/capi/eosio/security_group.h new file mode 100644 index 0000000000..9e362c63e6 --- /dev/null +++ b/libraries/eosiolib/capi/eosio/security_group.h @@ -0,0 +1,56 @@ +#pragma once +#include "types.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Propose new participants to the security group. + * + * @param data - the buffer containing the packed participants. + * @param datalen - size of the packed participants + * @pre `data` is a valid pointer to a range of memory at least `datalen` bytes long that contains packed participants data + * + * @return -1 if proposing a new security group was unsuccessful, otherwise returns 0. +*/ +__attribute__((eosio_wasm_import)) +int64_t add_security_group_participants(const char* data, uint32_t datalen); + +/** + * Propose to remove participants from the security group. + * + * @param data - the buffer containing the packed participants. + * @param datalen - size of the packed participants + * @pre `data` is a valid pointer to a range of memory at least `datalen` bytes long that contains packed participants data + * + * @return -1 if proposing a new security group was unsuccessful, otherwise returns 0. +*/ +__attribute__((eosio_wasm_import)) +int64_t remove_security_group_participants(const char* data, uint32_t datalen); + +/** + * Check if the specified accounts are all in the active security group. + * + * @param data - the buffer containing the packed participants. + * @param datalen - size of the packed participants + * + * @return Returns true if the specified accounts are all in the active security group. +*/ +__attribute__((eosio_wasm_import)) +bool in_active_security_group(const char* data, uint32_t datalen); + +/** + * Gets the active security group + * + * @param[out] data - the output buffer containing the packed security group. + * @param datalen - size of the `data` buffer + * + * @return Returns the size required in the buffer (if the buffer is too small, nothing is written). + * +*/ +__attribute__((eosio_wasm_import)) +uint32_t get_active_security_group(char* data, uint32_t datalen); + +#ifdef __cplusplus +} +#endif diff --git a/libraries/eosiolib/contracts/eosio/security_group.hpp b/libraries/eosiolib/contracts/eosio/security_group.hpp new file mode 100644 index 0000000000..cdb1b51888 --- /dev/null +++ b/libraries/eosiolib/contracts/eosio/security_group.hpp @@ -0,0 +1,88 @@ +#pragma once +#include +#include "../../core/eosio/name.hpp" +#include "../../core/eosio/serialize.hpp" + +namespace eosio { + +namespace internal_use_do_not_use { +extern "C" { +__attribute__((eosio_wasm_import)) int64_t add_security_group_participants(const char* data, uint32_t datalen); + +__attribute__((eosio_wasm_import)) int64_t remove_security_group_participants(const char* data, + uint32_t datalen); + +__attribute__((eosio_wasm_import)) bool in_active_security_group(const char* data, uint32_t datalen); + +__attribute__((eosio_wasm_import)) uint32_t get_active_security_group(char* data, uint32_t datalen); +} +} // namespace internal_use_do_not_use + + +/** + * @defgroup security_group Security Group + * @ingroup contracts + * @brief Defines C++ security group API + */ + +struct security_group { + uint32_t version; + std::set participants; + CDT_REFLECT(version, participants); +}; + +/** + * Propose new participants to the security group. + * + * @ingroup security_group + * @param participants - the participants. + * + * @return -1 if proposing a new security group was unsuccessful, otherwise returns 0. + */ +inline int64_t add_security_group_participants(const std::set& participants) { + auto packed_participants = eosio::pack( participants ); + return internal_use_do_not_use::add_security_group_participants( packed_participants.data(), packed_participants.size() ); +} + +/** + * Propose to remove participants from the security group. + *å + * @ingroup security_group + * @param participants - the participants. + *å + * @return -1 if proposing a new security group was unsuccessful, otherwise returns 0. + */ +inline int64_t remove_security_group_participants(const std::set& participants){ + auto packed_participants = eosio::pack( participants ); + return internal_use_do_not_use::remove_security_group_participants( packed_participants.data(), packed_participants.size() ); +} + +/** + * Check if the specified accounts are all in the active security group. + * + * @ingroup security_group + * @param participants - the participants. + * + * @return Returns true if the specified accounts are all in the active security group. + */ +inline bool in_active_security_group(const std::set& participants){ + auto packed_participants = eosio::pack( participants ); + return internal_use_do_not_use::in_active_security_group( packed_participants.data(), packed_participants.size() ); +} + +/** + * Gets the active security group + * + * @ingroup security_group + * @param[out] packed_security_group - the buffer containing the packed security_group. + * + * @return Returns the size required in the buffer (if the buffer is too small, nothing is written). + * + */ +inline security_group get_active_security_group() { + size_t buffer_size = internal_use_do_not_use::get_active_security_group(0, 0); + std::vector buffer(buffer_size); + internal_use_do_not_use::get_active_security_group(buffer.data(), buffer_size); + return eosio::unpack(buffer); +} +} // namespace eosio \ No newline at end of file diff --git a/libraries/native/intrinsics.cpp b/libraries/native/intrinsics.cpp index 4ad6d335e7..86d956077f 100644 --- a/libraries/native/intrinsics.cpp +++ b/libraries/native/intrinsics.cpp @@ -892,4 +892,21 @@ extern "C" { eosio_assert(false, "abort"); } #pragma clang diagnostic pop + + int64_t add_security_group_participants(const char* data, uint32_t datalen) { + return intrinsics::get().call(data, datalen); + } + + int64_t remove_security_group_participants(const char* data, uint32_t datalen){ + return intrinsics::get().call(data, datalen); + } + + bool in_active_security_group(const char* data, uint32_t datalen){ + return intrinsics::get().call(data, datalen); + } + + uint32_t get_active_security_group(char* data, uint32_t datalen){ + return intrinsics::get().call(data, datalen); + } + } diff --git a/libraries/native/native/eosio/intrinsics_def.hpp b/libraries/native/native/eosio/intrinsics_def.hpp index cca4667242..772a0141c0 100644 --- a/libraries/native/native/eosio/intrinsics_def.hpp +++ b/libraries/native/native/eosio/intrinsics_def.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -159,7 +160,12 @@ intrinsic_macro(send_deferred) \ intrinsic_macro(cancel_deferred) \ intrinsic_macro(get_context_free_data) \ intrinsic_macro(get_sender) \ -intrinsic_macro(set_action_return_value) +intrinsic_macro(set_action_return_value) \ +intrinsic_macro(add_security_group_participants) \ +intrinsic_macro(remove_security_group_participants) \ +intrinsic_macro(in_active_security_group) \ +intrinsic_macro(get_active_security_group) + #define CREATE_ENUM(name) \ name, From 0c305e5fe0b02b0ebecae93583cddbaa4bf9ad6b Mon Sep 17 00:00:00 2001 From: Keke Li Date: Wed, 10 Mar 2021 13:43:50 -0800 Subject: [PATCH 053/204] Add read only query test contract as a part of read only query TDD. --- tests/unit/test_contracts/CMakeLists.txt | 1 + .../test_contracts/read_only_query_tests.cpp | 156 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 tests/unit/test_contracts/read_only_query_tests.cpp diff --git a/tests/unit/test_contracts/CMakeLists.txt b/tests/unit/test_contracts/CMakeLists.txt index 6f9586a257..dfd75dce4a 100644 --- a/tests/unit/test_contracts/CMakeLists.txt +++ b/tests/unit/test_contracts/CMakeLists.txt @@ -6,6 +6,7 @@ add_contract(transfer_contract transfer_contract transfer.cpp) add_contract(minimal_tests minimal_tests minimal_tests.cpp) add_contract(kv_single_index_tests kv_single_index_tests kv_single_index_tests.cpp) add_contract(kv_multiple_indices_tests kv_multiple_indices_tests kv_multiple_indices_tests.cpp) +add_contract(read_only_query_tests read_only_query_tests read_only_query_tests.cpp) add_contract(kv_make_key_tests kv_make_key_tests kv_make_key_tests.cpp) add_contract(kv_map_tests kv_map_tests kv_map_tests.cpp) add_contract(capi_tests capi_tests capi/capi.c capi/action.c capi/chain.c capi/crypto.c capi/db.c capi/permission.c diff --git a/tests/unit/test_contracts/read_only_query_tests.cpp b/tests/unit/test_contracts/read_only_query_tests.cpp new file mode 100644 index 0000000000..d2e6fd6237 --- /dev/null +++ b/tests/unit/test_contracts/read_only_query_tests.cpp @@ -0,0 +1,156 @@ +#include +#include + +class [[eosio::contract]] read_only_query_tests : public eosio::contract { +public: + struct my_struct { + uint32_t id; + std::string name; + uint32_t gender; + uint32_t age; + + bool operator==(const my_struct& b) const { + return id == b.id && + name == b.name && + gender == b.gender && + age == b.age; + } + }; + + struct [[eosio::table]] my_table_m : eosio::kv::table { + KV_NAMED_INDEX("id"_n, id) + + my_table_m(eosio::name contract_name) { + init(contract_name, id); + } + }; + struct [[eosio::table]] my_table_f : eosio::kv::table { + KV_NAMED_INDEX("id"_n, id) + + my_table_f(eosio::name contract_name) { + init(contract_name, id); + } + }; + using contract::contract; + my_struct s1{ + .id = 1, + .name = "Bob Smith", + .gender = 1, + .age = 25 + }; + my_struct s2{ + .id = 2, + .name = "Alice Smith", + .gender = 0, + .age = 20 + }; + my_struct s3{ + .id = 3, + .name = "John Smith", + .gender = 1, + .age = 42 + }; + my_struct s4{ + .id = 4, + .name = "Jack Smith", + .gender = 1, + .age = 27 + }; + my_struct s5{ + .id = 5, + .name = "Youko Niihara", + .gender = 0, + .age = 26 + }; + my_struct s6{ + .id = 6, + .name = "Rose Lee", + .gender = 0, + .age = 18, + }; + my_struct s7{ + .id = 7, + .name = "Youko Kawakami", + .gender = 0, + .age = 25, + }; + my_struct s8{ + .id = 8, + .name = "Yuu Yamada", + .gender = 0, + .age = 24, + }; + + [[eosio::action]] + void setup() { + my_table_m tm{"eosio"_n}; + my_table_f tf{"eosio"_n}; + + tm.put(s1, get_self()); + tf.put(s2, get_self()); + tm.put(s3, get_self()); + tm.put(s4, get_self()); + tf.put(s5, get_self()); + tf.put(s6, get_self()); + tf.put(s7, get_self()); + tf.put(s8, get_self()); + } + + [[eosio::action]] + std::vector get() { + my_table_m tm{"eosio"_n}; + my_table_f tf{"eosio"_n}; + + std::vector ret; + auto itm = tm.id.begin(); + auto itm_e = tm.id.end(); + eosio::cout << "Males: \n"; + while(itm != itm_e){ + auto row = itm.value(); + eosio::cout << "id=" << row.id << ", name=" << row.name << ",gender=" << row.gender << ", age=" << row.age << "\n"; + my_struct s; + s.id = row.id; + s.name = row.name; + s.gender = row.gender; + s.age = row.age; + ret.push_back(s); + ++itm; + } + eosio::cout << "Females: \n"; + auto itf = tf.id.begin(); + auto itf_e = tf.id.end(); + while(itf != itf_e){ + auto row = itf.value(); + eosio::cout << "id=" << row.id << ", name=" << row.name << ",gender=" << row.gender << ", age=" << row.age << "\n"; + my_struct s; + s.id = row.id; + s.name = row.name; + s.gender = row.gender; + s.age = row.age; + ret.push_back(s); + ++itf; + } + return ret; + } + [[eosio::action]] + // usage: cleos -v push action eosio put '{"id":10,"name":"GULU","gender":1,"age":128}' -p eosio@active + void put(uint32_t id, std::string name, uint32_t gender, uint32_t age ) { + my_table_m tm{"eosio"_n}; + my_table_f tf{"eosio"_n}; + if(gender == 0){ + tf.put({ + .id = id, + .name = name, + .gender = gender, + .age = age + }, get_self()); + } else { + tm.put({ + .id = id, + .name = name, + .gender = gender, + .age = age + }, get_self()); + } + } +}; From d6af6b7d1418ac3adf85190f0606bb7fcb8052f0 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Fri, 12 Mar 2021 11:48:45 -0600 Subject: [PATCH 054/204] fix identation --- libraries/eosiolib/contracts/eosio/security_group.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/eosiolib/contracts/eosio/security_group.hpp b/libraries/eosiolib/contracts/eosio/security_group.hpp index cdb1b51888..b5575b8835 100644 --- a/libraries/eosiolib/contracts/eosio/security_group.hpp +++ b/libraries/eosiolib/contracts/eosio/security_group.hpp @@ -9,8 +9,7 @@ namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import)) int64_t add_security_group_participants(const char* data, uint32_t datalen); -__attribute__((eosio_wasm_import)) int64_t remove_security_group_participants(const char* data, - uint32_t datalen); +__attribute__((eosio_wasm_import)) int64_t remove_security_group_participants(const char* data, uint32_t datalen); __attribute__((eosio_wasm_import)) bool in_active_security_group(const char* data, uint32_t datalen); @@ -18,7 +17,6 @@ __attribute__((eosio_wasm_import)) uint32_t get_active_security_group(char* data } } // namespace internal_use_do_not_use - /** * @defgroup security_group Security Group * @ingroup contracts From 51233fdd050ef3248e070138e1dc8e8f1aa4fa1c Mon Sep 17 00:00:00 2001 From: Keke Li Date: Fri, 12 Mar 2021 17:56:44 -0800 Subject: [PATCH 055/204] Add host functions test actions. not finished, continue next week --- tests/unit/test_contracts/CMakeLists.txt | 1 + .../test_contracts/host_functions_tests.cpp | 227 ++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 tests/unit/test_contracts/host_functions_tests.cpp diff --git a/tests/unit/test_contracts/CMakeLists.txt b/tests/unit/test_contracts/CMakeLists.txt index dfd75dce4a..f821d0bed6 100644 --- a/tests/unit/test_contracts/CMakeLists.txt +++ b/tests/unit/test_contracts/CMakeLists.txt @@ -7,6 +7,7 @@ add_contract(minimal_tests minimal_tests minimal_tests.cpp) add_contract(kv_single_index_tests kv_single_index_tests kv_single_index_tests.cpp) add_contract(kv_multiple_indices_tests kv_multiple_indices_tests kv_multiple_indices_tests.cpp) add_contract(read_only_query_tests read_only_query_tests read_only_query_tests.cpp) +add_contract(host_functions_tests host_functions_tests host_functions_tests.cpp) add_contract(kv_make_key_tests kv_make_key_tests kv_make_key_tests.cpp) add_contract(kv_map_tests kv_map_tests kv_map_tests.cpp) add_contract(capi_tests capi_tests capi/capi.c capi/action.c capi/chain.c capi/crypto.c capi/db.c capi/permission.c diff --git a/tests/unit/test_contracts/host_functions_tests.cpp b/tests/unit/test_contracts/host_functions_tests.cpp new file mode 100644 index 0000000000..819875e160 --- /dev/null +++ b/tests/unit/test_contracts/host_functions_tests.cpp @@ -0,0 +1,227 @@ +/* host functions which are not allowed to use in read only query contract, so the functions should never return true. it should compile failed (compile time) or throw exception(run time). +set_resource_limits : yes +set_wasm_parameters_packed +set_resource_limit : yes +set_proposed_producers +set_proposed_producers_ex +set_blockchain_parameters_packed : yes +set_parameters_packed +set_kv_parameters_packed : yes +set_privileged : yes +kv_erase +kv_set +send_deferred +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); +extern "C" __attribute__((eosio_wasm_import)) uint32_t get_kv_parameters_packed(void* params, uint32_t size, uint32_t max_version); +extern "C" __attribute__((eosio_wasm_import)) void set_kv_parameters_packed(const char* params, uint32_t size); +extern "C" __attribute__((eosio_wasm_import)) void set_blockchain_parameters_packed( char* data, uint32_t datalen ); +extern "C" __attribute__((eosio_wasm_import)) uint32_t get_blockchain_parameters_packed( char* data, uint32_t datalen ); + +typedef uint64_t capi_name; +extern "C" __attribute__((eosio_wasm_import)) int32_t db_store_i64(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const void* data, uint32_t len); +extern "C" __attribute__((eosio_wasm_import)) void db_update_i64(int32_t iterator, capi_name payer, const void* data, uint32_t len); +extern "C" __attribute__((eosio_wasm_import)) void db_remove_i64(int32_t iterator); +extern "C" __attribute__((eosio_wasm_import)) int32_t db_idx64_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const uint64_t* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx64_update(int32_t iterator, capi_name payer, const uint64_t* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx64_remove(int32_t iterator); +extern "C" __attribute__((eosio_wasm_import)) int32_t db_idx128_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const uint128_t* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx128_update(int32_t iterator, capi_name payer, const uint128_t* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx128_remove(int32_t iterator); +extern "C" __attribute__((eosio_wasm_import)) int32_t db_idx256_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const uint128_t* data, uint32_t data_len ); +extern "C" __attribute__((eosio_wasm_import)) void db_idx256_update(int32_t iterator, capi_name payer, const uint128_t* data, uint32_t data_len); +extern "C" __attribute__((eosio_wasm_import)) void db_idx256_remove(int32_t iterator); +extern "C" __attribute__((eosio_wasm_import)) int32_t db_idx_double_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const double* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx_double_update(int32_t iterator, capi_name payer, const double* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx_double_remove(int32_t iterator); +extern "C" __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_store(uint64_t scope, capi_name table, capi_name payer, uint64_t id, const long double* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx_long_double_update(int32_t iterator, capi_name payer, const long double* secondary); +extern "C" __attribute__((eosio_wasm_import)) void db_idx_long_double_remove(int32_t iterator); + +#define ACTION_TYPE [[eosio::action]] + +class [[eosio::contract]] host_functions_tests : public eosio::contract { +public: + using contract::contract; + + ACTION_TYPE + bool resource() { + int64_t ram_bytes; + int64_t net_weight; + int64_t cpu_weight; + get_resource_limits( "eosio"_n, ram_bytes, net_weight, cpu_weight ) ; + eosio::cout << "Get resource: ram_bytes=" << ram_bytes << " net_weight=" << net_weight << " cpu_weight=" << cpu_weight << " \n"; + set_resource_limits( "eosio"_n, ram_bytes , net_weight , cpu_weight ); + get_resource_limits( "eosio"_n, ram_bytes, net_weight, cpu_weight ) ; + eosio::cout << "Get resource: ram_bytes=" << ram_bytes << " net_weight=" << net_weight << " cpu_weight=" << cpu_weight << " \n"; + return true; + } + ACTION_TYPE + bool setrelimit () { + int64_t ram_bytes; + int64_t net_weight; + int64_t cpu_weight; + get_resource_limits( "eosio"_n, ram_bytes, net_weight, cpu_weight ) ; + eosio::cout << "Get resource: ram_bytes=" << ram_bytes << " net_weight=" << net_weight << " cpu_weight=" << cpu_weight << " \n"; + set_resource_limit( "eosio"_n.value, "ram"_n.value , ram_bytes ); + get_resource_limits( "eosio"_n, ram_bytes, net_weight, cpu_weight ) ; + eosio::cout << "Get resource: ram_bytes=" << ram_bytes << " net_weight=" << net_weight << " cpu_weight=" << cpu_weight << " \n"; + return true; + } + ACTION_TYPE + bool bcpara () { + char buf[sizeof(eosio::blockchain_parameters)]; + size_t size = get_blockchain_parameters_packed( buf, sizeof(buf) ); + eosio::cout << "Block chain parameter size : " << size << "\n"; + set_blockchain_parameters_packed(buf, size); + return true; + } + ACTION_TYPE + bool setkvpara(){ + uint32_t limits[4]; + limits[0] = 0; + limits[1] = 1024; + limits[2] = 4096; + limits[3] = 1024; + char limits_buf[sizeof(limits)]; + memcpy(limits_buf, limits, sizeof(limits)); + set_kv_parameters_packed(limits_buf, sizeof(limits)); + return true; + } + ACTION_TYPE + bool setpriv() { + bool ispr = is_privileged("eosio"_n); + eosio::cout << "eosio is privileged : " << ispr << "\n"; + set_privileged("eosio"_n, ispr); + return true; + } +/* all tested +db_store_i64 +db_update_i64 +db_remove_i64 +db_idx64_store +db_idx64_update +db_idx64_remove +db_idx128_store +db_idx128_update +db_idx128_remove +db_idx256_store +db_idx256_update +db_idx256_remove +db_idx_double_store +db_idx_double_update +db_idx_double_remove +db_idx_long_double_store +db_idx_long_double_update +db_idx_long_double_remove +*/ +// abcde means 67890 a4 means 64 12c means 128 so as to no conflict with naming rule +// Name should be less than 13 characters and only contains the following symbol 12345abcdefghijklmnopqrstuvwxyz + ACTION_TYPE + bool dbia4s(){ + db_store_i64(0, 0, 0, 0, NULL, 0); + return true; + } + ACTION_TYPE + bool dbia4u(){ + db_update_i64(0, 0, NULL, 0); + return true; + } + ACTION_TYPE + bool dbia4r(){ + db_remove_i64(0); + return true; + } + ACTION_TYPE + bool dbidxa4s() { + db_idx64_store(0, 0, 0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidxa4u() { + db_idx64_update(0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidxa4r() { + db_idx64_remove(0); + return true; + } + ACTION_TYPE + bool dbidx12cs() { + db_idx128_store(0, 0, 0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidx12cu() { + db_idx128_update(0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidx12cr() { + db_idx128_remove(0); + return true; + } + ACTION_TYPE + bool dbidx25as() { + db_idx256_store(0, 0, 0, 0, NULL, 0); + return true; + } + ACTION_TYPE + bool dbidx25au() { + db_idx256_update(0, 0, NULL, 0); + return true; + } + ACTION_TYPE + bool dbidx25ar() { + db_idx256_remove(0); + return true; + } + ACTION_TYPE + bool dbidxdbs(){ + db_idx_double_store(0, 0, 0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidxdbu(){ + db_idx_double_update(0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidxdbr(){ + db_idx_double_remove(0); + return true; + } + ACTION_TYPE + bool dbidxldbs (){ + db_idx_long_double_store(0, 0, 0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidxldbu(){ + db_idx_long_double_update(0, 0, NULL); + return true; + } + ACTION_TYPE + bool dbidxldbr(){ + db_idx_long_double_remove(0); + return true; + } +}; From 2abede037e429756d40c33915cce8e47e86434a0 Mon Sep 17 00:00:00 2001 From: Keke Li Date: Mon, 15 Mar 2021 19:09:03 -0700 Subject: [PATCH 056/204] Add test action for some host functions --- .../test_contracts/host_functions_tests.cpp | 57 ++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/tests/unit/test_contracts/host_functions_tests.cpp b/tests/unit/test_contracts/host_functions_tests.cpp index 819875e160..8f0fad93e5 100644 --- a/tests/unit/test_contracts/host_functions_tests.cpp +++ b/tests/unit/test_contracts/host_functions_tests.cpp @@ -1,16 +1,16 @@ /* host functions which are not allowed to use in read only query contract, so the functions should never return true. it should compile failed (compile time) or throw exception(run time). set_resource_limits : yes -set_wasm_parameters_packed +set_wasm_parameters_packed : yes set_resource_limit : yes -set_proposed_producers -set_proposed_producers_ex +set_proposed_producers : yes +set_proposed_producers_ex : yes set_blockchain_parameters_packed : yes -set_parameters_packed +set_parameters_packed : yes set_kv_parameters_packed : yes set_privileged : yes -kv_erase -kv_set -send_deferred +kv_erase : yes +kv_set : yes +send_deferred : yes */ #include @@ -55,6 +55,14 @@ extern "C" __attribute__((eosio_wasm_import)) int32_t db_idx_long_double_store(u extern "C" __attribute__((eosio_wasm_import)) void db_idx_long_double_update(int32_t iterator, capi_name payer, const long double* secondary); extern "C" __attribute__((eosio_wasm_import)) void db_idx_long_double_remove(int32_t iterator); +extern "C" __attribute__((eosio_wasm_import)) int64_t kv_erase(uint64_t contract, const char* key, uint32_t key_size); +extern "C" __attribute__((eosio_wasm_import)) int64_t kv_set(uint64_t contract, const char* key, uint32_t key_size, const char* value, uint32_t value_size, uint64_t payer); +extern "C" __attribute__((eosio_wasm_import)) void send_deferred(const uint128_t&, uint64_t, const char*, size_t, uint32_t); +extern "C" __attribute__((eosio_wasm_import)) int64_t set_proposed_producers( char*, uint32_t ); +extern "C" __attribute__((eosio_wasm_import)) int64_t set_proposed_producers_ex( uint64_t producer_data_format, char *producer_data, uint32_t producer_data_size ); +extern "C" __attribute__((eosio_wasm_import)) void set_wasm_parameters_packed(const void*, std::size_t); +extern "C" __attribute__((eosio_wasm_import)) void set_parameters_packed( const char* params, uint32_t params_size ); + #define ACTION_TYPE [[eosio::action]] class [[eosio::contract]] host_functions_tests : public eosio::contract { @@ -224,4 +232,39 @@ db_idx_long_double_remove db_idx_long_double_remove(0); return true; } + ACTION_TYPE + bool kverase(){ + kv_erase(0, NULL, 0); + return true; + } + ACTION_TYPE + bool kvset(){ + kv_set(0, NULL, 0, NULL, 0, 0); + return true; + } + ACTION_TYPE + bool senddefer(){ + send_deferred(0, 0, NULL, 0, 0); + return true; + } + ACTION_TYPE + bool setpp(){ + set_proposed_producers(NULL, 0); + return true; + } + ACTION_TYPE + bool setppex(){ + set_proposed_producers_ex( 0, NULL, 0 ); + return true; + } + ACTION_TYPE + bool swpp(){ + set_wasm_parameters_packed(NULL, 0); + return true; + } + ACTION_TYPE + bool spp(){ + set_parameters_packed( NULL, 0 ); + return true; + } }; From f3c7af6f2fc350f01074e37aa684b840b5bfd387 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Tue, 16 Mar 2021 13:09:04 -0400 Subject: [PATCH 057/204] add implementation for read-only checking --- tests/unit/test_contracts/read_only_tests.cpp | 36 +++---- tools/include/compiler_options.hpp.in | 10 +- tools/include/eosio/codegen.hpp | 97 +++++++++++++++---- tools/include/eosio/gen.hpp | 59 +++++++++++ 4 files changed, 165 insertions(+), 37 deletions(-) diff --git a/tests/unit/test_contracts/read_only_tests.cpp b/tests/unit/test_contracts/read_only_tests.cpp index b66f777a20..edfd3eb78f 100644 --- a/tests/unit/test_contracts/read_only_tests.cpp +++ b/tests/unit/test_contracts/read_only_tests.cpp @@ -1,32 +1,34 @@ -#include "transfer.hpp" #include #include -extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); - using namespace eosio; +//extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); class [[eosio::contract]] read_only_tests : public contract { public: - using contract::contract; - void foo1() { bar(); } - void bar() {} - void foo2( name user, int64_t limit ) { set_resource_limit(user.value, "disk"_n.value, limit); } - + [[eosio::action, eosio::read_only]] void testreadonly( name user, int64_t limit ) { - print( "Hello, ", user); - int i; - foo1(); - set_resource_limit(user.value, "disk"_n.value, limit); - foo2(user, limit); + internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); + foo(user); } [[eosio::action, eosio::read_only]] - void hireadonly( name user ) { - print( "Hello, ", user); - int i; - foo1(); + void test2( name user, int64_t limit ) { + internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); + } + + void foo(name user) { + internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); + } + + [[eosio::action, eosio::read_only]] + void test3( name user, int64_t limit ) { + foo1(user); + } + + void foo1(name user) { + foo(user); } [[eosio::action]] diff --git a/tools/include/compiler_options.hpp.in b/tools/include/compiler_options.hpp.in index 6b7c8e55c3..a56b4dc9de 100644 --- a/tools/include/compiler_options.hpp.in +++ b/tools/include/compiler_options.hpp.in @@ -347,7 +347,10 @@ static cl::opt contract_name( "contract", cl::desc("Contract name"), cl::cat(EosioCompilerToolCategory)); - +static cl::opt warn_action_read_only_opt( + "warn-action-read-only", + cl::desc("Issue a warning if a read-only action uses a write API and continue compilation"), + cl::cat(EosioCompilerToolCategory)); /// end c/c++ options /// begin c++ options @@ -548,6 +551,7 @@ static Options CreateOptions(bool add_defaults=true) { std::string abigen_contract; bool has_o_opt; bool has_contract_opt; + bool is_warn_action_read_only; #ifdef ONLY_LD bool abigen = false; @@ -917,6 +921,10 @@ static Options CreateOptions(bool add_defaults=true) { abi_version_minor = ((tmp - (int)tmp)*10); } + /* TODO */ + // if(warn_action_read_only_opt) { + // } + #ifndef ONLY_LD return {output_fn, inputs, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt}; #else diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 8f798e79f5..45bc0a5d17 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -61,7 +61,7 @@ namespace eosio { namespace cdt { llvm::ArrayRef sources; size_t source_index = 0; std::map tmp_files; - std::set read_only_actions; + using generation_utils::generation_utils; static codegen& get() { @@ -88,8 +88,12 @@ namespace eosio { namespace cdt { bool apply_was_found = false; public: + using call_map_t = std::map>; + std::vector action_decls; std::vector notify_decls; + std::set read_only_actions; + call_map_t func_calls; explicit eosio_codegen_visitor(CompilerInstance *CI) : generation_utils(), ci(CI) { @@ -236,10 +240,7 @@ namespace eosio { namespace cdt { cg.actions.insert(full_action_name); // insert the method action, so we don't create the dispatcher twice if (decl->isEosioReadOnly()) { - cg.read_only_actions.insert(decl); - // for (auto it = cg.read_only_actions.begin(); it != cg.read_only_actions.end(); it++) { - // std::cout << (*it)->getDeclName().getAsString() << std::endl; - // } + read_only_actions.insert(decl); } } else if (decl->isEosioNotify()) { @@ -272,7 +273,7 @@ namespace eosio { namespace cdt { return true; } - std::string ExprToString(Stmt *expr) + std::string expr_to_str(Stmt *expr) { SourceRange expr_range = expr->getSourceRange(); int range_size = get_rewriter().getRangeSize(expr_range); @@ -280,30 +281,60 @@ namespace eosio { namespace cdt { return ""; } - SourceLocation startLoc = expr_range.getBegin(); - const char *str_start = get_rewriter().getSourceMgr().getCharacterData(startLoc); - + const char *str_start = get_rewriter().getSourceMgr().getCharacterData(expr_range.getBegin()); std::string expr_str; expr_str.assign(str_start, range_size); return expr_str; } - virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { - std::cout << "FunctionDecl name: " << decl->getNameAsString() << "\n"; - - if (Stmt *stmts = decl->getBody()) { + void process_function(FunctionDecl *func_decl) { + if (is_write_host_func(func_decl->getQualifiedNameAsString())) { + func_calls[func_decl] = {(CallExpr*)func_decl}; + } else if (func_decl->hasBody()) { + Stmt *stmts = func_decl->getBody(); + std::cout << "- Body: " << expr_to_str(stmts) << std::endl; for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { + // std::cout << "\n- iter: " << expr_to_str(*it) << std::endl + // << "- type: " << it->getStmtClassName() << std::endl; if (CallExpr *call = dyn_cast(*it)) { - std::cout << "- Call: " << ExprToString(*it) << std::endl; - if (FunctionDecl *func_decl = call->getDirectCallee()) { - std::cout << " - Function call: " << func_decl->getNameInfo().getName().getAsString() << std::endl; - } else { - std::cout << " - Expression call: " << call->getCallee()->getStmtClassName() << std::endl; + // std::cout << "- Call: " << expr_to_str(*it) << std::endl; + if (FunctionDecl *fd = call->getDirectCallee()) { + // std::cout << " - Function call: " << fd->getQualifiedNameAsString() + // << "(" << fd->getID() << ")" << std::endl; + if (func_calls.count(fd) == 0) { + process_function(fd); + } + if (!func_calls[fd].empty()) { + func_calls[func_decl].push_back(call); + std::cout << "++key: " << func_decl->getQualifiedNameAsString() + << ", value: " << expr_to_str(*it) << std::endl; + if (func_decl->getLocation().isValid()) + // CDT_WARN("codegen_warn", func_decl->getLocation(), "add value"); + std::cout << func_decl->getLocation().printToString(ci->getSourceManager()) << std::endl; + if (fd->getLocation().isValid()) + // CDT_WARN("codegen_warn", fd->getLocation(), "add value"); + std::cout << fd->getLocation().printToString(ci->getSourceManager()) << std::endl; + break; + } } } } } + } + virtual bool VisitFunctionDecl(FunctionDecl* func_decl) { + SourceManager &sm = get_rewriter().getSourceMgr(); + if (sm.isInSystemHeader(func_decl->getLocation()) || sm.isInExternCSystemHeader(func_decl->getLocation())) { + return true; + } + + if (is_write_host_func(func_decl->getQualifiedNameAsString())) { + std::cout << "Write host function: " << func_decl->getQualifiedNameAsString() << "(" << func_decl->getID() << ")" << std::endl; + func_calls[func_decl] = {(CallExpr*)func_decl}; + std::cout << "++key: " << func_decl->getQualifiedNameAsString() << ", value: (itself)" << std::endl; + } else if (func_decl->isThisDeclarationADefinition()) { + process_function(func_decl); + } return true; } @@ -316,7 +347,7 @@ namespace eosio { namespace cdt { } }; - class eosio_codegen_consumer : public ASTConsumer { + class eosio_codegen_consumer : public ASTConsumer, public generation_utils { private: eosio_codegen_visitor *visitor; std::string main_file; @@ -337,6 +368,34 @@ namespace eosio { namespace cdt { visitor->set_main_fid(fid); visitor->set_main_name(main_fe->getName()); visitor->TraverseDecl(Context.getTranslationUnitDecl()); + + for (auto const& fc : visitor->func_calls) { + std::cout << "key: " << fc.first->getQualifiedNameAsString() << " value: { "; + for (auto const& v : fc.second) { + std::cout << visitor->expr_to_str(v) << ", "; + } + std::cout << "}" << std::endl; + } + + for (auto const& ra : visitor->read_only_actions) { + std::cout << ra->getQualifiedNameAsString() << std::endl; + auto it = visitor->func_calls.find(ra); + if (it != visitor->func_calls.end()) { + std::cout << "codedgen_error: action should be read only" << std::endl; + std::cout << it->first->getQualifiedNameAsString() << std::endl; + if (ra->getLocation().isValid()) { + // CDT_ERROR("codegen_error", ra->getLocation(), "read only"); + std::cout << "Caller location: " << ra->getLocation().printToString(src_mgr) << std::endl; + } + for (auto val : it->second) { + if (val->getExprLoc().isValid()) { + // CDT_WARN("codegen_warn", it->second[0]->getExprLoc(), "read only"); + std::cout << "Callee location: " << val->getExprLoc().printToString(src_mgr) << std::endl; + } + } + } + } + for (auto ad : visitor->action_decls) visitor->create_action_dispatch(ad); diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 78f780af17..1e369f3fd4 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -683,5 +683,64 @@ struct generation_utils { return in_kv_namespace && is_internal; } + + inline bool is_write_host_func( const std::string& t ) { + static const std::set write_host_funcs = + { + "eosio::internal_use_do_not_use::set_resource_limits", + "eosio::chain::webassembly::interface::set_wasm_parameters_packed", + "eosio::chain::webassembly::interface::set_resource_limit", // ? + "eosio::chain::controller::set_proposed_producers", // ? + "eosio::internal_use_do_not_use::set_proposed_producers_ex", + "eosio::internal_use_do_not_use::set_blockchain_parameters_packed", + "eosio::chain::webassembly::interface::set_parameters_packed", // ? + "eosio::internal_use_do_not_use::set_kv_parameters_packed", + "eosio::internal_use_do_not_use::set_privileged", + "eosio::internal_use_do_not_use::db_store_i64", + "eosio::internal_use_do_not_use::db_update_i64", + "eosio::internal_use_do_not_use::db_remove_i64", + "eosio::internal_use_do_not_use::db_idx64_store", + "eosio::internal_use_do_not_use::db_idx64_update", + "eosio::internal_use_do_not_use::db_idx64_remove", + "eosio::internal_use_do_not_use::db_idx128_store", + "eosio::internal_use_do_not_use::db_idx128_update", + "eosio::internal_use_do_not_use::db_idx128_remove", + "eosio::internal_use_do_not_use::db_idx256_store", + "eosio::internal_use_do_not_use::db_idx256_update", + "eosio::internal_use_do_not_use::db_idx256_remove", + "eosio::internal_use_do_not_use::db_idx_double_store", + "eosio::internal_use_do_not_use::db_idx_double_update", + "eosio::internal_use_do_not_use::db_idx_double_remove", + "eosio::internal_use_do_not_use::db_idx_long_double_store", + "eosio::internal_use_do_not_use::db_idx_long_double_update", + "eosio::internal_use_do_not_use::db_idx_long_double_remove", + "eosio::kv::internal_use_do_not_use::kv_erase", + "eosio::kv::internal_use_do_not_use::kv_setkv_set", + // deferred transactions + "eosio::internal_use_do_not_use::send_deferred", + // inline actions + "eosio::internal_use_do_not_use::send_inline", + "eosio::internal_use_do_not_use::send_context_free_inline" + }; + return write_host_funcs.count(t) >= 1; + } + + inline bool is_deferred_transaction_func( const std::string& t ) { + static const std::set deferred_transaction_funcs = + { + "eosio::internal_use_do_not_use::send_deferred", + }; + return deferred_transaction_funcs.count(t) >= 1; + } + + inline bool is_inline_action_func( const std::string& t ) { + static const std::set inline_action_funcs = + { + "eosio::internal_use_do_not_use::send_inline", + "eosio::internal_use_do_not_use::send_context_free_inline" + }; + return inline_action_funcs.count(t) >= 1; + } + }; }} // ns eosio::cdt From 0d0d176ca3ebc7cc47236763bded0fec979969a9 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 19 Mar 2021 10:49:38 -0400 Subject: [PATCH 058/204] add checking for extern c function --- tests/unit/test_contracts/read_only_tests.cpp | 30 ++++++--- tools/include/eosio/codegen.hpp | 66 +++++++++---------- tools/include/eosio/gen.hpp | 31 ++++++++- 3 files changed, 79 insertions(+), 48 deletions(-) diff --git a/tests/unit/test_contracts/read_only_tests.cpp b/tests/unit/test_contracts/read_only_tests.cpp index edfd3eb78f..8c4448e6fd 100644 --- a/tests/unit/test_contracts/read_only_tests.cpp +++ b/tests/unit/test_contracts/read_only_tests.cpp @@ -2,37 +2,47 @@ #include using namespace eosio; -//extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); +extern "C" __attribute__((weak)) __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); class [[eosio::contract]] read_only_tests : public contract { public: [[eosio::action, eosio::read_only]] - void testreadonly( name user, int64_t limit ) { - internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); - foo(user); + void test1( name user, int64_t limit ) { + print( "Hello, ", user); + set_resource_limit(user.value, 0, 0); } - [[eosio::action, eosio::read_only]] + [[eosio::action]] void test2( name user, int64_t limit ) { internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); } - void foo(name user) { + [[eosio::action, eosio::read_only]] + void test3( name user, int64_t limit ) { internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); } [[eosio::action, eosio::read_only]] - void test3( name user, int64_t limit ) { + void test4( name user, int64_t limit ) { foo1(user); } + [[eosio::action, eosio::read_only]] + void test5( name user, int64_t limit ) { + foo3(user); + } + void foo1(name user) { foo(user); } - [[eosio::action]] - void hi( name user ) { - print( "Hello, ", user); + void foo(name user) { + internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); + } + + void foo3(name user) { + set_resource_limit(user.value, 0, 0); } + }; diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 45bc0a5d17..3b5144d5ee 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -288,34 +288,30 @@ namespace eosio { namespace cdt { } void process_function(FunctionDecl *func_decl) { - if (is_write_host_func(func_decl->getQualifiedNameAsString())) { - func_calls[func_decl] = {(CallExpr*)func_decl}; - } else if (func_decl->hasBody()) { - Stmt *stmts = func_decl->getBody(); - std::cout << "- Body: " << expr_to_str(stmts) << std::endl; - for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { - // std::cout << "\n- iter: " << expr_to_str(*it) << std::endl - // << "- type: " << it->getStmtClassName() << std::endl; - if (CallExpr *call = dyn_cast(*it)) { - // std::cout << "- Call: " << expr_to_str(*it) << std::endl; - if (FunctionDecl *fd = call->getDirectCallee()) { - // std::cout << " - Function call: " << fd->getQualifiedNameAsString() - // << "(" << fd->getID() << ")" << std::endl; - if (func_calls.count(fd) == 0) { - process_function(fd); - } - if (!func_calls[fd].empty()) { - func_calls[func_decl].push_back(call); - std::cout << "++key: " << func_decl->getQualifiedNameAsString() - << ", value: " << expr_to_str(*it) << std::endl; - if (func_decl->getLocation().isValid()) - // CDT_WARN("codegen_warn", func_decl->getLocation(), "add value"); - std::cout << func_decl->getLocation().printToString(ci->getSourceManager()) << std::endl; - if (fd->getLocation().isValid()) - // CDT_WARN("codegen_warn", fd->getLocation(), "add value"); - std::cout << fd->getLocation().printToString(ci->getSourceManager()) << std::endl; - break; - } + Stmt *stmts = func_decl->getBody(); + std::cout << "- Body: " << expr_to_str(stmts) << std::endl; + for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { + // std::cout << "\n- iter: " << expr_to_str(*it) << std::endl + // << "- type: " << it->getStmtClassName() << std::endl; + if (CallExpr *call = dyn_cast(*it)) { + // std::cout << "- Call: " << expr_to_str(*it) << std::endl; + if (FunctionDecl *fd = call->getDirectCallee()) { + // std::cout << " - Function call: " << fd->getQualifiedNameAsString() + // << "(" << fd->getID() << ")" << std::endl; + if (func_calls.count(fd) == 0) { + process_function(fd); + } + if (!func_calls[fd].empty()) { + func_calls[func_decl].push_back(call); + std::cout << "++key: " << func_decl->getQualifiedNameAsString() + << ", value: " << expr_to_str(*it) << std::endl; + if (func_decl->getLocation().isValid()) + // CDT_WARN("codegen_warn", func_decl->getLocation(), "add value"); + std::cout << func_decl->getLocation().printToString(ci->getSourceManager()) << std::endl; + if (fd->getLocation().isValid()) + // CDT_WARN("codegen_warn", fd->getLocation(), "add value"); + std::cout << fd->getLocation().printToString(ci->getSourceManager()) << std::endl; + break; } } } @@ -328,11 +324,11 @@ namespace eosio { namespace cdt { return true; } - if (is_write_host_func(func_decl->getQualifiedNameAsString())) { - std::cout << "Write host function: " << func_decl->getQualifiedNameAsString() << "(" << func_decl->getID() << ")" << std::endl; + std::string func_name = func_decl->getQualifiedNameAsString(); + if (func_calls.count(func_decl) == 0 && (is_write_host_func(func_name) || is_eosio_wasm_import_write_func(func_decl))) { func_calls[func_decl] = {(CallExpr*)func_decl}; - std::cout << "++key: " << func_decl->getQualifiedNameAsString() << ", value: (itself)" << std::endl; - } else if (func_decl->isThisDeclarationADefinition()) { + // std::cout << "++key: " << func_decl->getQualifiedNameAsString() << ", value: (itself)" << std::endl; + } else if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { process_function(func_decl); } return true; @@ -381,16 +377,16 @@ namespace eosio { namespace cdt { std::cout << ra->getQualifiedNameAsString() << std::endl; auto it = visitor->func_calls.find(ra); if (it != visitor->func_calls.end()) { - std::cout << "codedgen_error: action should be read only" << std::endl; + std::cout << "codedgen_error: read-only action cannot call write host function" << std::endl; std::cout << it->first->getQualifiedNameAsString() << std::endl; if (ra->getLocation().isValid()) { // CDT_ERROR("codegen_error", ra->getLocation(), "read only"); - std::cout << "Caller location: " << ra->getLocation().printToString(src_mgr) << std::endl; + std::cout << " - " << ra->getLocation().printToString(src_mgr) << std::endl; } for (auto val : it->second) { if (val->getExprLoc().isValid()) { // CDT_WARN("codegen_warn", it->second[0]->getExprLoc(), "read only"); - std::cout << "Callee location: " << val->getExprLoc().printToString(src_mgr) << std::endl; + std::cout << " -- " << val->getExprLoc().printToString(src_mgr) << std::endl; } } } diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 1e369f3fd4..c37c5d67f1 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -5,6 +5,7 @@ #include "clang/Basic/Builtins.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" +#include "clang/AST/Decl.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -688,12 +689,12 @@ struct generation_utils { static const std::set write_host_funcs = { "eosio::internal_use_do_not_use::set_resource_limits", - "eosio::chain::webassembly::interface::set_wasm_parameters_packed", - "eosio::chain::webassembly::interface::set_resource_limit", // ? + // "eosio::chain::webassembly::interface::set_wasm_parameters_packed", + // "eosio::chain::webassembly::interface::set_resource_limit", // ? "eosio::chain::controller::set_proposed_producers", // ? "eosio::internal_use_do_not_use::set_proposed_producers_ex", "eosio::internal_use_do_not_use::set_blockchain_parameters_packed", - "eosio::chain::webassembly::interface::set_parameters_packed", // ? + // "eosio::chain::webassembly::interface::set_parameters_packed", // ? "eosio::internal_use_do_not_use::set_kv_parameters_packed", "eosio::internal_use_do_not_use::set_privileged", "eosio::internal_use_do_not_use::db_store_i64", @@ -742,5 +743,29 @@ struct generation_utils { return inline_action_funcs.count(t) >= 1; } + inline bool is_eosio_wasm_import_write_func( const clang::FunctionDecl *func_decl ) { + static const std::set eosio_wasm_import_write_funcs = + { + "set_resource_limit", + "set_wasm_parameters_packed", + "set_parameters_packed" + }; + + if (eosio_wasm_import_write_funcs.count(func_decl->getQualifiedNameAsString()) == 0) { + return false; + } + + if (func_decl->isInExternCContext()) { + auto attrs = func_decl->getAttrs(); + for (auto const &a : attrs) { + std::cout << "attr:" << a->getSpelling() << "," << a->getKind() << std::endl; + if (a->getSpelling() == "eosio_wasm_import") { + return true; + } + } + } + + return false; + } }; }} // ns eosio::cdt From 70b08b611f6e7d385c99fc50eef5b528e0cb1708 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Sun, 21 Mar 2021 20:07:23 -0400 Subject: [PATCH 059/204] fix if condition for process_function --- tools/include/eosio/codegen.hpp | 54 +++++++++++++++++---------------- tools/include/eosio/gen.hpp | 2 +- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 3b5144d5ee..27af6c00f3 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -288,30 +288,32 @@ namespace eosio { namespace cdt { } void process_function(FunctionDecl *func_decl) { - Stmt *stmts = func_decl->getBody(); - std::cout << "- Body: " << expr_to_str(stmts) << std::endl; - for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { - // std::cout << "\n- iter: " << expr_to_str(*it) << std::endl - // << "- type: " << it->getStmtClassName() << std::endl; - if (CallExpr *call = dyn_cast(*it)) { - // std::cout << "- Call: " << expr_to_str(*it) << std::endl; - if (FunctionDecl *fd = call->getDirectCallee()) { - // std::cout << " - Function call: " << fd->getQualifiedNameAsString() - // << "(" << fd->getID() << ")" << std::endl; - if (func_calls.count(fd) == 0) { - process_function(fd); - } - if (!func_calls[fd].empty()) { - func_calls[func_decl].push_back(call); - std::cout << "++key: " << func_decl->getQualifiedNameAsString() - << ", value: " << expr_to_str(*it) << std::endl; - if (func_decl->getLocation().isValid()) - // CDT_WARN("codegen_warn", func_decl->getLocation(), "add value"); - std::cout << func_decl->getLocation().printToString(ci->getSourceManager()) << std::endl; - if (fd->getLocation().isValid()) - // CDT_WARN("codegen_warn", fd->getLocation(), "add value"); - std::cout << fd->getLocation().printToString(ci->getSourceManager()) << std::endl; - break; + if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { + Stmt *stmts = func_decl->getBody(); + std::cout << "- Body: " << expr_to_str(stmts) << std::endl; + for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { + std::cout << "\n- iter: " << expr_to_str(*it) << std::endl + << "- type: " << it->getStmtClassName() << std::endl; + if (CallExpr *call = dyn_cast(*it)) { + std::cout << "- Call: " << expr_to_str(*it) << std::endl; + if (FunctionDecl *fd = call->getDirectCallee()) { + std::cout << " - Function call: " << fd->getQualifiedNameAsString() + << "(" << fd->getID() << ")" << std::endl; + if (func_calls.count(fd) == 0) { + process_function(fd); + } + if (!func_calls[fd].empty()) { + func_calls[func_decl].push_back(call); + std::cout << "++key: " << func_decl->getQualifiedNameAsString() + << ", value: " << expr_to_str(*it) << std::endl; + if (func_decl->getLocation().isValid()) + // CDT_WARN("codegen_warn", func_decl->getLocation(), "add value"); + std::cout << func_decl->getLocation().printToString(ci->getSourceManager()) << std::endl; + if (fd->getLocation().isValid()) + // CDT_WARN("codegen_warn", fd->getLocation(), "add value"); + std::cout << fd->getLocation().printToString(ci->getSourceManager()) << std::endl; + break; + } } } } @@ -327,8 +329,8 @@ namespace eosio { namespace cdt { std::string func_name = func_decl->getQualifiedNameAsString(); if (func_calls.count(func_decl) == 0 && (is_write_host_func(func_name) || is_eosio_wasm_import_write_func(func_decl))) { func_calls[func_decl] = {(CallExpr*)func_decl}; - // std::cout << "++key: " << func_decl->getQualifiedNameAsString() << ", value: (itself)" << std::endl; - } else if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { + std::cout << "++key: " << func_decl->getQualifiedNameAsString() << ", value: (itself)" << std::endl; + } else { process_function(func_decl); } return true; diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index c37c5d67f1..62570a48cd 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -716,7 +716,7 @@ struct generation_utils { "eosio::internal_use_do_not_use::db_idx_long_double_update", "eosio::internal_use_do_not_use::db_idx_long_double_remove", "eosio::kv::internal_use_do_not_use::kv_erase", - "eosio::kv::internal_use_do_not_use::kv_setkv_set", + "eosio::kv::internal_use_do_not_use::kv_set", // deferred transactions "eosio::internal_use_do_not_use::send_deferred", // inline actions From 22d7d23f503a6c24b63c14803b4a6f1d125eaafc Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 24 Mar 2021 15:21:16 +0200 Subject: [PATCH 060/204] [docs] Deprecate [[eosio::action]] use for structs Deprecate `[[eosio::action]]` use for structs. --- .../08_abi/01_abi-code-generator-attributes-explained.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md index b34ad827ce..f4931df137 100644 --- a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md +++ b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md @@ -6,7 +6,7 @@ link_text: ABI/Code generator attributes The new ABI generator tool uses C++11 or GNU style attributes to mark `actions` and `tables`. ## [[eosio::action]] -This attribute marks either a struct or a method as an action. +This attribute marks a method as an action. Example (four ways to declare an action for ABI generation): ```cpp // this is the C++11 and greater style attribute From b231e24146e0df37dfaccfa0a86157ae6c706fae Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Wed, 24 Mar 2021 16:39:02 -0400 Subject: [PATCH 061/204] add option -warn-action-read-only --- tools/cc/eosio-cpp.cpp.in | 7 ++-- tools/include/compiler_options.hpp.in | 19 +++++++---- tools/include/eosio/codegen.hpp | 46 +++++++++++++++++++++++---- 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index 85f7b4c1d7..3d268d602b 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -41,7 +41,7 @@ using namespace eosio::cdt; void handle_empty_abigen(const std::string& contract_name, bool has_o_opt, bool has_contract_opt); -void generate(const std::vector& base_options, std::string input, std::string contract_name, const std::vector& resource_paths, const std::pair& abi_version, bool abigen, bool suppress_ricardian_warning, bool has_o_opt, bool has_contract_opt) { +void generate(const std::vector& base_options, std::string input, std::string contract_name, const std::vector& resource_paths, const std::pair& abi_version, bool abigen, bool suppress_ricardian_warning, bool has_o_opt, bool has_contract_opt, bool warn_action_read_only) { std::vector options; options.push_back("eosio-cpp"); options.push_back(input); // don't remove oddity of CommonOptionsParser? @@ -67,13 +67,14 @@ void generate(const std::vector& base_options, std::string input, s abigen::get().set_abi_version(std::get<0>(abi_version), std::get<1>(abi_version)); abigen::get().set_suppress_ricardian_warning(suppress_ricardian_warning); codegen::get().set_contract_name(contract_name); + codegen::get().set_warn_action_read_only(warn_action_read_only); int tool_run = -1; tool_run = ctool.run(newFrontendActionFactory().get()); if (tool_run != 0) { throw std::runtime_error("abigen error"); } - + if (!abigen::get().is_empty()) { std::string abi_s; abigen::get().to_json().dump(abi_s); @@ -136,7 +137,7 @@ int main(int argc, const char **argv) { tool_opts.erase(std::remove_if(tool_opts.begin(), tool_opts.end(), [&](const auto& opt){ return non_tool_opts.count(opt); }), tool_opts.end()); - generate(tool_opts, input, opts.abigen_contract, opts.abigen_resources, opts.abi_version, opts.abigen, opts.suppress_ricardian_warning, opts.has_o_opt, opts.has_contract_opt); + generate(tool_opts, input, opts.abigen_contract, opts.abigen_resources, opts.abi_version, opts.abigen, opts.suppress_ricardian_warning, opts.has_o_opt, opts.has_contract_opt, opts.warn_action_read_only); auto src = SmallString<64>(input); llvm::sys::path::remove_filename(src); diff --git a/tools/include/compiler_options.hpp.in b/tools/include/compiler_options.hpp.in index a56b4dc9de..3953af2557 100644 --- a/tools/include/compiler_options.hpp.in +++ b/tools/include/compiler_options.hpp.in @@ -390,6 +390,7 @@ struct Options { std::pair abi_version; bool has_o_opt; bool has_contract_opt; + bool warn_action_read_only; }; static void GetCompDefaults(std::vector& copts) { @@ -551,7 +552,7 @@ static Options CreateOptions(bool add_defaults=true) { std::string abigen_contract; bool has_o_opt; bool has_contract_opt; - bool is_warn_action_read_only; + bool warn_action_read_only; #ifdef ONLY_LD bool abigen = false; @@ -909,6 +910,14 @@ static Options CreateOptions(bool add_defaults=true) { ldopts.emplace_back("-fnative"); if (fuse_main_opt) ldopts.emplace_back("-fuse-main"); + + /* TODO */ + if(warn_action_read_only_opt) { + warn_action_read_only = true; + } else { + warn_action_read_only = false; + } + #endif /* TODO add some way of defaulting these to the current highest version */ @@ -921,13 +930,9 @@ static Options CreateOptions(bool add_defaults=true) { abi_version_minor = ((tmp - (int)tmp)*10); } - /* TODO */ - // if(warn_action_read_only_opt) { - // } - #ifndef ONLY_LD - return {output_fn, inputs, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt}; + return {output_fn, inputs, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt, warn_action_read_only}; #else - return {output_fn, {}, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt}; + return {output_fn, {}, link, abigen, no_missing_ricardian_clause_opt, pp_only, pp_dir, abigen_output, abigen_contract, copts, ldopts, agopts, agresources, debug, fnative_opt, {abi_version_major, abi_version_minor}, has_o_opt, has_contract_opt, warn_action_read_only}; #endif } diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 27af6c00f3..7e8b22c5cc 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -61,6 +61,7 @@ namespace eosio { namespace cdt { llvm::ArrayRef sources; size_t source_index = 0; std::map tmp_files; + bool warn_action_read_only; using generation_utils::generation_utils; @@ -76,6 +77,10 @@ namespace eosio { namespace cdt { void set_abi(std::string s) { abi = s; } + + void set_warn_action_read_only(bool w) { + warn_action_read_only = w; + } }; class eosio_codegen_visitor : public RecursiveASTVisitor, public generation_utils { @@ -218,14 +223,24 @@ namespace eosio { namespace cdt { } virtual bool VisitCXXMethodDecl(CXXMethodDecl* decl) { + std::cout << "=VisitCXXMethodDecl=" << decl->getQualifiedNameAsString() << std::endl; std::string name = decl->getNameAsString(); static std::set _action_set; //used for validations static std::set _notify_set; //used for validations if (decl->isEosioAction()) { + std::cout << "==is eosio action==" << std::endl; + name = generation_utils::get_action_name(decl); - validate_name(name, [&](auto s) { - CDT_ERROR("codegen_error", decl->getLocation(), std::string("action name (")+s+") is not a valid eosio name"); - }); + + // test_cdt_warn(name, [&](auto s) { + // CDT_ERROR("codegen_error", decl->getLocation(), std::string("action name (")+s+") TEST_CDT_WARN"); + // }); + + // validate_name(name, [&](auto s) { + // CDT_ERROR("codegen_error", decl->getLocation(), std::string("action name (")+s+") is not a valid eosio name"); + // }); + + validate_name( decl->getNameAsString(), [&](auto s) { CDT_ERROR("abigen_error", decl->getLocation(), s); } ); if (!_action_set.count(name)) _action_set.insert(name); @@ -241,10 +256,15 @@ namespace eosio { namespace cdt { if (decl->isEosioReadOnly()) { read_only_actions.insert(decl); + std::cout << decl->getLocation().printToString(ci->getSourceManager()) << std::endl; + // CDT_WARN("codegen_warn", decl->getLocation(), "is read-only"); + } } else if (decl->isEosioNotify()) { + std::cout << "==is eosio notify==" << std::endl; + name = generation_utils::get_notify_pair(decl); auto first = name.substr(0, name.find("::")); if (first != "*") @@ -378,19 +398,31 @@ namespace eosio { namespace cdt { for (auto const& ra : visitor->read_only_actions) { std::cout << ra->getQualifiedNameAsString() << std::endl; auto it = visitor->func_calls.find(ra); + // CDT_CHECK_WARN(it == visitor->func_calls.end(), "codegen_warn", ra->getLocation(), "read only"); + + if (it != visitor->func_calls.end()) { - std::cout << "codedgen_error: read-only action cannot call write host function" << std::endl; - std::cout << it->first->getQualifiedNameAsString() << std::endl; + if (cg.warn_action_read_only) { + std::cout << "WARNING: read-only action cannot call write host function" << std::endl; + } else { + std::cout << "ERROR: read-only action cannot call write host function" << std::endl; + // std::cout << it->first->getQualifiedNameAsString() << std::endl; + } if (ra->getLocation().isValid()) { // CDT_ERROR("codegen_error", ra->getLocation(), "read only"); - std::cout << " - " << ra->getLocation().printToString(src_mgr) << std::endl; + std::cout << " Caller: " << ra->getLocation().printToString(src_mgr) << std::endl; } for (auto val : it->second) { if (val->getExprLoc().isValid()) { // CDT_WARN("codegen_warn", it->second[0]->getExprLoc(), "read only"); - std::cout << " -- " << val->getExprLoc().printToString(src_mgr) << std::endl; + std::cout << " Callee: " << val->getExprLoc().printToString(src_mgr) << std::endl; } } + + // if (cg.warn_action_read_only == false) { + // // std::cout << "*** ERR***" << std::endl; + // return; + // } } } From 68b6fca6aee5737f62b3ffe88d37602100a18c15 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 25 Mar 2021 10:13:37 +0200 Subject: [PATCH 062/204] [docs] fix typo "privious"->"previous" [docs] fix typo "privious"->"previous" --- .../40_multi-index/how-to-instantiate-a-multi-index-table.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index 9ab286ef0a..607508dae5 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -53,7 +53,7 @@ using namespace eosio; + typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; ``` -6. Define the multi index table data member of type `test_tables` defined in the privious step +6. Define the multi index table data member of type `test_tables` defined in the previous step ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { @@ -130,4 +130,4 @@ class [[eosio::contract]] multi_index_example : public contract { ``` [[Info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). From f3f2c5ba40d8bfa198f3d83d1e4a63ad0e65159f Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 25 Mar 2021 10:14:52 +0200 Subject: [PATCH 063/204] Update how-to-instantiate-a-multi-index-table.md From 439bb3901752a226abbe530e13686ebb02b9c92a Mon Sep 17 00:00:00 2001 From: Keke Li Date: Thu, 25 Mar 2021 12:07:42 -0700 Subject: [PATCH 064/204] Add test case for inline host functions. --- tests/unit/test_contracts/host_functions_tests.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/unit/test_contracts/host_functions_tests.cpp b/tests/unit/test_contracts/host_functions_tests.cpp index 8f0fad93e5..bc58eb88b6 100644 --- a/tests/unit/test_contracts/host_functions_tests.cpp +++ b/tests/unit/test_contracts/host_functions_tests.cpp @@ -63,6 +63,9 @@ extern "C" __attribute__((eosio_wasm_import)) int64_t set_proposed_producers_ex( extern "C" __attribute__((eosio_wasm_import)) void set_wasm_parameters_packed(const void*, std::size_t); extern "C" __attribute__((eosio_wasm_import)) void set_parameters_packed( const char* params, uint32_t params_size ); +extern "C" __attribute__((eosio_wasm_import)) void send_inline(char *serialized_action, size_t size); +extern "C" __attribute__((eosio_wasm_import)) void send_context_free_inline(char *serialized_action, size_t size); + #define ACTION_TYPE [[eosio::action]] class [[eosio::contract]] host_functions_tests : public eosio::contract { @@ -267,4 +270,14 @@ db_idx_long_double_remove set_parameters_packed( NULL, 0 ); return true; } + ACTION_TYPE + bool sendil(){ + send_inline(NULL, 0); + return true; + } + ACTION_TYPE + bool sendcfiil(){ + send_context_free_inline(NULL, 0); + return true; + } }; From 52cebae51e3da1b7e46ed44fc17bb28460729840 Mon Sep 17 00:00:00 2001 From: Keke Li Date: Thu, 25 Mar 2021 16:11:14 -0700 Subject: [PATCH 065/204] Add alias test for host functions --- tests/unit/test_contracts/CMakeLists.txt | 1 + .../test_contracts/hf_indirect_call_tests.cpp | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 tests/unit/test_contracts/hf_indirect_call_tests.cpp diff --git a/tests/unit/test_contracts/CMakeLists.txt b/tests/unit/test_contracts/CMakeLists.txt index f821d0bed6..5cd54f1681 100644 --- a/tests/unit/test_contracts/CMakeLists.txt +++ b/tests/unit/test_contracts/CMakeLists.txt @@ -8,6 +8,7 @@ add_contract(kv_single_index_tests kv_single_index_tests kv_single_index_tests.c add_contract(kv_multiple_indices_tests kv_multiple_indices_tests kv_multiple_indices_tests.cpp) add_contract(read_only_query_tests read_only_query_tests read_only_query_tests.cpp) add_contract(host_functions_tests host_functions_tests host_functions_tests.cpp) +add_contract(hf_indirect_call_tests hf_indirect_call_tests hf_indirect_call_tests.cpp) add_contract(kv_make_key_tests kv_make_key_tests kv_make_key_tests.cpp) add_contract(kv_map_tests kv_map_tests kv_map_tests.cpp) add_contract(capi_tests capi_tests capi/capi.c capi/action.c capi/chain.c capi/crypto.c capi/db.c capi/permission.c diff --git a/tests/unit/test_contracts/hf_indirect_call_tests.cpp b/tests/unit/test_contracts/hf_indirect_call_tests.cpp new file mode 100644 index 0000000000..b6152c4239 --- /dev/null +++ b/tests/unit/test_contracts/hf_indirect_call_tests.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +/* + tests which create aliases and indirect calls for host functions. + at least one host function called within a C++ lambda. It can be a trivial lambda which simply calls the host function and nothing else. + at least one host function "renamed" with a using directive and called via the alternative name. + at least one host function "renamed" with a #define and called using that alternative name. + Possibly in two different versions, one which #defines just the function name and one which #defines both the function name and the parameters passed to it. + Yes, both versions I think. It may not be functionally different to the compiler but it looks different to a human, so let's try it. + And finally, combine all four in a chain of aliases +*/ + +extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); + + +#define ACTION_TYPE [[eosio::action]] + +class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { +public: + using contract::contract; + + ACTION_TYPE + bool tlambda() { + auto set_rsc = [](){ + set_resource_limit(0, 0, 0); + }; + set_rsc(); + return true; + } + ACTION_TYPE + bool tlambdap() { + auto set_rsc = [](int64_t a, int64_t b, int64_t c){ + set_resource_limit(a, b, c); + }; + set_rsc(0, 0, 0); + return true; + } + ACTION_TYPE + bool tlambdap2(int64_t a, int64_t b, int64_t c) { + auto set_rsc = [=](int64_t x, int64_t y, int64_t z){ + set_resource_limit(x, y, z); + }; + set_rsc(a, b, c); + return true; + } + using func = void (*)(int64_t, int64_t, int64_t); + ACTION_TYPE + bool talias () { + func srl = set_resource_limit; + srl(0,0,0); + return true; + } + #define setfun set_resource_limit + ACTION_TYPE + bool tdefine(){ + setfun(0,0,0); + return true; + } + #define setfunp() set_resource_limit(0,0,0) + ACTION_TYPE + bool tdefinep(){ + setfunp(); + return true; + } + #define setfunpi(a, b, c) set_resource_limit(a,b,c) + ACTION_TYPE + bool tdefinepi(){ + setfunpi(0,0,0); + return true; + } + ACTION_TYPE + bool combine(){ + func srl = set_resource_limit; + srl(0,0,0); + setfun(0,0,0); + setfunp(); + setfunpi(0,0,0); + return true; + } + ACTION_TYPE + bool combinea(){ + tlambdap(); + tlambdap2(0,0,0); + talias(); + tdefine(); + tdefinep(); + tdefinepi(); + combine(); + return true; + } +}; From 1615f770ff1b488932f8a8a9344f536323293434 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 26 Mar 2021 13:03:43 -0400 Subject: [PATCH 066/204] fix cmake_args --- modules/ClangExternalProject.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ClangExternalProject.txt b/modules/ClangExternalProject.txt index 356045bd3b..3b9342b3f4 100644 --- a/modules/ClangExternalProject.txt +++ b/modules/ClangExternalProject.txt @@ -4,7 +4,7 @@ include(GNUInstallDirs) ExternalProject_Add( EosioClang - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/llvm -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_BUILD_TYPE=${TOOLS_BUILD_TYPE} -DEOSIO_TOOL_DIR=${CMAKE_SOURCE_DIR}/tools -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -LLVM_CCACHE_BUILD=On + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/llvm -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_BUILD_TYPE=${TOOLS_BUILD_TYPE} -DEOSIO_TOOL_DIR=${CMAKE_SOURCE_DIR}/tools -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DLLVM_CCACHE_BUILD=On SOURCE_DIR "${CMAKE_SOURCE_DIR}/eosio_llvm" BINARY_DIR "${CMAKE_BINARY_DIR}/eosio_llvm" From 29d031c716adbbe63fe85d1fc52d4269aa6c68ab Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 29 Mar 2021 11:01:07 -0400 Subject: [PATCH 067/204] install ccache and turn on LLVM_CCACHE_BUILD --- .cicd/docker/amazonlinux-2.dockerfile | 2 +- .cicd/docker/centos-7.7.dockerfile | 2 +- .cicd/docker/centos-8.dockerfile | 2 +- .cicd/docker/ubuntu-16.04.dockerfile | 2 +- .cicd/docker/ubuntu-18.04.dockerfile | 2 +- .cicd/docker/ubuntu-20.04.dockerfile | 2 +- .cicd/pipeline.yml | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.cicd/docker/amazonlinux-2.dockerfile b/.cicd/docker/amazonlinux-2.dockerfile index 99e78df328..b8277dc304 100644 --- a/.cicd/docker/amazonlinux-2.dockerfile +++ b/.cicd/docker/amazonlinux-2.dockerfile @@ -3,7 +3,7 @@ FROM amazonlinux:2.0.20190508 RUN yum update -y && \ yum install -y git gcc.x86_64 gcc-c++.x86_64 autoconf automake libtool make bzip2 \ bzip2-devel.x86_64 openssl-devel.x86_64 gmp-devel.x86_64 libstdc++.x86_64 \ - python.x86_64 python3-devel.x86_64 libedit-devel.x86_64 doxygen.x86_64 graphviz.x86_64 perl + python.x86_64 python3-devel.x86_64 libedit-devel.x86_64 doxygen.x86_64 graphviz.x86_64 perl ccache # build lcov RUN git clone https://github.com/linux-test-project/lcov.git && \ cd lcov && \ diff --git a/.cicd/docker/centos-7.7.dockerfile b/.cicd/docker/centos-7.7.dockerfile index 6555a26aef..01f2451465 100644 --- a/.cicd/docker/centos-7.7.dockerfile +++ b/.cicd/docker/centos-7.7.dockerfile @@ -7,7 +7,7 @@ RUN yum update -y && \ libtool ocaml.x86_64 doxygen graphviz-devel.x86_64 \ libicu-devel.x86_64 bzip2.x86_64 bzip2-devel.x86_64 openssl-devel.x86_64 \ gmp-devel.x86_64 gettext-devel.x86_64 gcc-c++.x86_64 perl \ - libffi-devel.x86_64 + libffi-devel.x86_64 ccache # build Python 3.7.4 RUN curl -LO https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz && \ diff --git a/.cicd/docker/centos-8.dockerfile b/.cicd/docker/centos-8.dockerfile index 5ddb698b83..6d1ec01190 100644 --- a/.cicd/docker/centos-8.dockerfile +++ b/.cicd/docker/centos-8.dockerfile @@ -6,4 +6,4 @@ RUN yum update -y && \ yum install -y git autoconf automake bzip2 \ libtool make \ libicu-devel.x86_64 bzip2.x86_64 bzip2-devel.x86_64 openssl-devel.x86_64 \ - gmp-devel.x86_64 python38 python3-devel gettext-devel.x86_64 gcc-c++.x86_64 perl + gmp-devel.x86_64 python38 python3-devel gettext-devel.x86_64 gcc-c++.x86_64 perl ccache diff --git a/.cicd/docker/ubuntu-16.04.dockerfile b/.cicd/docker/ubuntu-16.04.dockerfile index 74e145daa5..147745faf1 100644 --- a/.cicd/docker/ubuntu-16.04.dockerfile +++ b/.cicd/docker/ubuntu-16.04.dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get upgrade -y && \ lldb-4.0 make automake libbz2-dev libssl-dev \ libgmp3-dev autotools-dev build-essential libicu-dev python2.7-dev \ autoconf libtool curl zlib1g-dev doxygen graphviz \ - wget libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev xz-utils + wget libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev xz-utils ccache # install cmake RUN curl -LO https://cmake.org/files/v3.10/cmake-3.10.2.tar.gz && \ diff --git a/.cicd/docker/ubuntu-18.04.dockerfile b/.cicd/docker/ubuntu-18.04.dockerfile index ea7647b55e..c9ab345650 100644 --- a/.cicd/docker/ubuntu-18.04.dockerfile +++ b/.cicd/docker/ubuntu-18.04.dockerfile @@ -6,7 +6,7 @@ RUN apt-get update && apt-get upgrade -y && \ lldb-4.0 libclang-4.0-dev cmake make automake libbz2-dev libssl-dev \ libgmp3-dev autotools-dev build-essential libicu-dev python2.7-dev \ autoconf libtool curl zlib1g-dev doxygen graphviz \ - libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev + libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev ccache # install Python 3.7.4 RUN curl -LO https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz && \ diff --git a/.cicd/docker/ubuntu-20.04.dockerfile b/.cicd/docker/ubuntu-20.04.dockerfile index 7543e0a3d2..f19b4e25a8 100644 --- a/.cicd/docker/ubuntu-20.04.dockerfile +++ b/.cicd/docker/ubuntu-20.04.dockerfile @@ -6,6 +6,6 @@ RUN apt-get update && apt-get upgrade -y && \ lldb-8 libclang-8-dev cmake make automake libbz2-dev libssl-dev \ libgmp3-dev autotools-dev build-essential libicu-dev python2.7-dev python3 \ autoconf libtool curl zlib1g-dev doxygen graphviz \ - libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev + libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev ccache RUN ln -sfn /usr/bin/python3 /usr/local/bin/python3 diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 812e7aadb3..37406c7921 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -71,7 +71,7 @@ steps: - label: ":darwin: macOS 10.14 - Build" command: - "brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" + - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3 ccache" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -97,7 +97,7 @@ steps: - label: ":darwin: macOS 10.15 - Build" command: - "brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" + - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3 ccache" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" From 98f9dd0e71124ddbe6f6fa5ffe6771199f603a5c Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 29 Mar 2021 13:07:48 -0400 Subject: [PATCH 068/204] turn off LLVM_CCACHE_BUILD --- .cicd/docker/amazonlinux-2.dockerfile | 2 +- .cicd/docker/centos-7.7.dockerfile | 2 +- .cicd/docker/centos-8.dockerfile | 2 +- .cicd/docker/ubuntu-16.04.dockerfile | 2 +- .cicd/docker/ubuntu-18.04.dockerfile | 2 +- .cicd/docker/ubuntu-20.04.dockerfile | 2 +- .cicd/pipeline.yml | 4 ++-- modules/ClangExternalProject.txt | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.cicd/docker/amazonlinux-2.dockerfile b/.cicd/docker/amazonlinux-2.dockerfile index b8277dc304..99e78df328 100644 --- a/.cicd/docker/amazonlinux-2.dockerfile +++ b/.cicd/docker/amazonlinux-2.dockerfile @@ -3,7 +3,7 @@ FROM amazonlinux:2.0.20190508 RUN yum update -y && \ yum install -y git gcc.x86_64 gcc-c++.x86_64 autoconf automake libtool make bzip2 \ bzip2-devel.x86_64 openssl-devel.x86_64 gmp-devel.x86_64 libstdc++.x86_64 \ - python.x86_64 python3-devel.x86_64 libedit-devel.x86_64 doxygen.x86_64 graphviz.x86_64 perl ccache + python.x86_64 python3-devel.x86_64 libedit-devel.x86_64 doxygen.x86_64 graphviz.x86_64 perl # build lcov RUN git clone https://github.com/linux-test-project/lcov.git && \ cd lcov && \ diff --git a/.cicd/docker/centos-7.7.dockerfile b/.cicd/docker/centos-7.7.dockerfile index 01f2451465..6555a26aef 100644 --- a/.cicd/docker/centos-7.7.dockerfile +++ b/.cicd/docker/centos-7.7.dockerfile @@ -7,7 +7,7 @@ RUN yum update -y && \ libtool ocaml.x86_64 doxygen graphviz-devel.x86_64 \ libicu-devel.x86_64 bzip2.x86_64 bzip2-devel.x86_64 openssl-devel.x86_64 \ gmp-devel.x86_64 gettext-devel.x86_64 gcc-c++.x86_64 perl \ - libffi-devel.x86_64 ccache + libffi-devel.x86_64 # build Python 3.7.4 RUN curl -LO https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz && \ diff --git a/.cicd/docker/centos-8.dockerfile b/.cicd/docker/centos-8.dockerfile index 6d1ec01190..5ddb698b83 100644 --- a/.cicd/docker/centos-8.dockerfile +++ b/.cicd/docker/centos-8.dockerfile @@ -6,4 +6,4 @@ RUN yum update -y && \ yum install -y git autoconf automake bzip2 \ libtool make \ libicu-devel.x86_64 bzip2.x86_64 bzip2-devel.x86_64 openssl-devel.x86_64 \ - gmp-devel.x86_64 python38 python3-devel gettext-devel.x86_64 gcc-c++.x86_64 perl ccache + gmp-devel.x86_64 python38 python3-devel gettext-devel.x86_64 gcc-c++.x86_64 perl diff --git a/.cicd/docker/ubuntu-16.04.dockerfile b/.cicd/docker/ubuntu-16.04.dockerfile index 147745faf1..74e145daa5 100644 --- a/.cicd/docker/ubuntu-16.04.dockerfile +++ b/.cicd/docker/ubuntu-16.04.dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && apt-get upgrade -y && \ lldb-4.0 make automake libbz2-dev libssl-dev \ libgmp3-dev autotools-dev build-essential libicu-dev python2.7-dev \ autoconf libtool curl zlib1g-dev doxygen graphviz \ - wget libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev xz-utils ccache + wget libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev xz-utils # install cmake RUN curl -LO https://cmake.org/files/v3.10/cmake-3.10.2.tar.gz && \ diff --git a/.cicd/docker/ubuntu-18.04.dockerfile b/.cicd/docker/ubuntu-18.04.dockerfile index c9ab345650..ea7647b55e 100644 --- a/.cicd/docker/ubuntu-18.04.dockerfile +++ b/.cicd/docker/ubuntu-18.04.dockerfile @@ -6,7 +6,7 @@ RUN apt-get update && apt-get upgrade -y && \ lldb-4.0 libclang-4.0-dev cmake make automake libbz2-dev libssl-dev \ libgmp3-dev autotools-dev build-essential libicu-dev python2.7-dev \ autoconf libtool curl zlib1g-dev doxygen graphviz \ - libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev ccache + libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev # install Python 3.7.4 RUN curl -LO https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz && \ diff --git a/.cicd/docker/ubuntu-20.04.dockerfile b/.cicd/docker/ubuntu-20.04.dockerfile index f19b4e25a8..7543e0a3d2 100644 --- a/.cicd/docker/ubuntu-20.04.dockerfile +++ b/.cicd/docker/ubuntu-20.04.dockerfile @@ -6,6 +6,6 @@ RUN apt-get update && apt-get upgrade -y && \ lldb-8 libclang-8-dev cmake make automake libbz2-dev libssl-dev \ libgmp3-dev autotools-dev build-essential libicu-dev python2.7-dev python3 \ autoconf libtool curl zlib1g-dev doxygen graphviz \ - libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev ccache + libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev RUN ln -sfn /usr/bin/python3 /usr/local/bin/python3 diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 37406c7921..812e7aadb3 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -71,7 +71,7 @@ steps: - label: ":darwin: macOS 10.14 - Build" command: - "brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3 ccache" + - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -97,7 +97,7 @@ steps: - label: ":darwin: macOS 10.15 - Build" command: - "brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3 ccache" + - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" diff --git a/modules/ClangExternalProject.txt b/modules/ClangExternalProject.txt index 3b9342b3f4..5120b6965e 100644 --- a/modules/ClangExternalProject.txt +++ b/modules/ClangExternalProject.txt @@ -4,7 +4,7 @@ include(GNUInstallDirs) ExternalProject_Add( EosioClang - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/llvm -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_BUILD_TYPE=${TOOLS_BUILD_TYPE} -DEOSIO_TOOL_DIR=${CMAKE_SOURCE_DIR}/tools -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DLLVM_CCACHE_BUILD=On + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}/llvm -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_BUILD_TYPE=${TOOLS_BUILD_TYPE} -DEOSIO_TOOL_DIR=${CMAKE_SOURCE_DIR}/tools -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DLLVM_CCACHE_BUILD=Off SOURCE_DIR "${CMAKE_SOURCE_DIR}/eosio_llvm" BINARY_DIR "${CMAKE_BINARY_DIR}/eosio_llvm" From 350297207af7cbed5a70417ad936bce2cabe64cd Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 29 Mar 2021 14:22:37 -0400 Subject: [PATCH 069/204] add support for CDT_WARN/ERROR in codegen --- tools/include/eosio/codegen.hpp | 47 ++++++++++++++------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 7e8b22c5cc..1bf892d593 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -105,6 +105,7 @@ namespace eosio { namespace cdt { cg.ast_context = &(CI->getASTContext()); cg.codegen_ci = CI; rewriter.setSourceMgr(CI->getASTContext().getSourceManager(), CI->getASTContext().getLangOpts()); + get_error_emitter().set_compiler_instance(CI); } void set_main_fid(FileID fid) { @@ -232,15 +233,10 @@ namespace eosio { namespace cdt { name = generation_utils::get_action_name(decl); - // test_cdt_warn(name, [&](auto s) { - // CDT_ERROR("codegen_error", decl->getLocation(), std::string("action name (")+s+") TEST_CDT_WARN"); - // }); - // validate_name(name, [&](auto s) { - // CDT_ERROR("codegen_error", decl->getLocation(), std::string("action name (")+s+") is not a valid eosio name"); - // }); - - validate_name( decl->getNameAsString(), [&](auto s) { CDT_ERROR("abigen_error", decl->getLocation(), s); } ); + validate_name(name, [&](auto s) { + CDT_ERROR("codegen_error", decl->getLocation(), std::string("action name (")+s+") is not a valid eosio name"); + }); if (!_action_set.count(name)) _action_set.insert(name); @@ -257,8 +253,6 @@ namespace eosio { namespace cdt { if (decl->isEosioReadOnly()) { read_only_actions.insert(decl); std::cout << decl->getLocation().printToString(ci->getSourceManager()) << std::endl; - // CDT_WARN("codegen_warn", decl->getLocation(), "is read-only"); - } } else if (decl->isEosioNotify()) { @@ -387,13 +381,13 @@ namespace eosio { namespace cdt { visitor->set_main_name(main_fe->getName()); visitor->TraverseDecl(Context.getTranslationUnitDecl()); - for (auto const& fc : visitor->func_calls) { - std::cout << "key: " << fc.first->getQualifiedNameAsString() << " value: { "; - for (auto const& v : fc.second) { - std::cout << visitor->expr_to_str(v) << ", "; - } - std::cout << "}" << std::endl; - } + // for (auto const& fc : visitor->func_calls) { + // std::cout << "key: " << fc.first->getQualifiedNameAsString() << " value: { "; + // for (auto const& v : fc.second) { + // std::cout << visitor->expr_to_str(v) << ", "; + // } + // std::cout << "}" << std::endl; + // } for (auto const& ra : visitor->read_only_actions) { std::cout << ra->getQualifiedNameAsString() << std::endl; @@ -409,19 +403,18 @@ namespace eosio { namespace cdt { // std::cout << it->first->getQualifiedNameAsString() << std::endl; } if (ra->getLocation().isValid()) { - // CDT_ERROR("codegen_error", ra->getLocation(), "read only"); std::cout << " Caller: " << ra->getLocation().printToString(src_mgr) << std::endl; - } - for (auto val : it->second) { - if (val->getExprLoc().isValid()) { - // CDT_WARN("codegen_warn", it->second[0]->getExprLoc(), "read only"); - std::cout << " Callee: " << val->getExprLoc().printToString(src_mgr) << std::endl; + if (cg.warn_action_read_only) { + CDT_WARN("codegen_warning", ra->getLocation(), "read only"); + } else { + CDT_ERROR("codegen_error", ra->getLocation(), "read only"); } } - - // if (cg.warn_action_read_only == false) { - // // std::cout << "*** ERR***" << std::endl; - // return; + // for (auto val : it->second) { + // if (val->getExprLoc().isValid()) { + // CDT_WARN("codegen_warn", it->second[0]->getExprLoc(), "read only"); + // std::cout << " Callee: " << val->getExprLoc().printToString(src_mgr) << std::endl; + // } // } } } From 087fa9b861112e2094bf9899c044d8f7aca6244e Mon Sep 17 00:00:00 2001 From: Keke Li Date: Mon, 29 Mar 2021 18:22:30 -0700 Subject: [PATCH 070/204] Add two more chained indirect call test actions --- .../test_contracts/hf_indirect_call_tests.cpp | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/unit/test_contracts/hf_indirect_call_tests.cpp b/tests/unit/test_contracts/hf_indirect_call_tests.cpp index b6152c4239..65b96885d1 100644 --- a/tests/unit/test_contracts/hf_indirect_call_tests.cpp +++ b/tests/unit/test_contracts/hf_indirect_call_tests.cpp @@ -100,4 +100,24 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { combine(); return true; } + ACTION_TYPE + bool combinec(){ + auto set_rsc = [](){ + func _srl = set_resource_limit; + #define mysrl _srl + mysrl(0, 0, 0); + }; + set_rsc(); + return true; + } + ACTION_TYPE + bool combinecp(){ + auto set_rsc = [](int64_t a, int64_t b, int64_t c){ + func _srl = set_resource_limit; + #define mysrl _srl + mysrl(a, b, c); + }; + set_rsc(0,0,0); + return true; + } }; From 602b05721e40b93bdc0320853a0d3327a6ddbb9d Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Tue, 30 Mar 2021 12:51:53 -0400 Subject: [PATCH 071/204] set git branch for submodule eosio_llvm --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 9b0f8369c1..51368f352d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,6 +9,7 @@ [submodule "eosio_llvm"] path = eosio_llvm url = https://github.com/eosio/llvm + branch = qy-read-only-action [submodule "libraries/native/softfloat"] path = libraries/native/softfloat url = https://github.com/EOSIO/berkeley-softfloat-3.git From c99f002ea830b858bbe658a5f1c63eebabc6dff7 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Wed, 31 Mar 2021 08:53:47 -0400 Subject: [PATCH 072/204] add more checkings; clean up code --- tools/include/eosio/codegen.hpp | 98 +++++++-------------------------- tools/include/eosio/gen.hpp | 59 ++++++++++++++++---- 2 files changed, 69 insertions(+), 88 deletions(-) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 1bf892d593..4f05f84799 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -224,16 +224,11 @@ namespace eosio { namespace cdt { } virtual bool VisitCXXMethodDecl(CXXMethodDecl* decl) { - std::cout << "=VisitCXXMethodDecl=" << decl->getQualifiedNameAsString() << std::endl; std::string name = decl->getNameAsString(); static std::set _action_set; //used for validations static std::set _notify_set; //used for validations if (decl->isEosioAction()) { - std::cout << "==is eosio action==" << std::endl; - name = generation_utils::get_action_name(decl); - - validate_name(name, [&](auto s) { CDT_ERROR("codegen_error", decl->getLocation(), std::string("action name (")+s+") is not a valid eosio name"); }); @@ -252,13 +247,9 @@ namespace eosio { namespace cdt { if (decl->isEosioReadOnly()) { read_only_actions.insert(decl); - std::cout << decl->getLocation().printToString(ci->getSourceManager()) << std::endl; } } else if (decl->isEosioNotify()) { - - std::cout << "==is eosio notify==" << std::endl; - name = generation_utils::get_notify_pair(decl); auto first = name.substr(0, name.find("::")); if (first != "*") @@ -287,46 +278,26 @@ namespace eosio { namespace cdt { return true; } - std::string expr_to_str(Stmt *expr) - { - SourceRange expr_range = expr->getSourceRange(); - int range_size = get_rewriter().getRangeSize(expr_range); - if (range_size == -1) { - return ""; - } - - const char *str_start = get_rewriter().getSourceMgr().getCharacterData(expr_range.getBegin()); - std::string expr_str; - expr_str.assign(str_start, range_size); - return expr_str; - } - void process_function(FunctionDecl *func_decl) { if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { Stmt *stmts = func_decl->getBody(); - std::cout << "- Body: " << expr_to_str(stmts) << std::endl; for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { - std::cout << "\n- iter: " << expr_to_str(*it) << std::endl - << "- type: " << it->getStmtClassName() << std::endl; - if (CallExpr *call = dyn_cast(*it)) { - std::cout << "- Call: " << expr_to_str(*it) << std::endl; - if (FunctionDecl *fd = call->getDirectCallee()) { - std::cout << " - Function call: " << fd->getQualifiedNameAsString() - << "(" << fd->getID() << ")" << std::endl; - if (func_calls.count(fd) == 0) { - process_function(fd); - } - if (!func_calls[fd].empty()) { - func_calls[func_decl].push_back(call); - std::cout << "++key: " << func_decl->getQualifiedNameAsString() - << ", value: " << expr_to_str(*it) << std::endl; - if (func_decl->getLocation().isValid()) - // CDT_WARN("codegen_warn", func_decl->getLocation(), "add value"); - std::cout << func_decl->getLocation().printToString(ci->getSourceManager()) << std::endl; - if (fd->getLocation().isValid()) - // CDT_WARN("codegen_warn", fd->getLocation(), "add value"); - std::cout << fd->getLocation().printToString(ci->getSourceManager()) << std::endl; - break; + if (Stmt *s = *it) { + if (ExprWithCleanups *ec = dyn_cast(s)) { + s = ec->getSubExpr(); + while (ImplicitCastExpr *ice = dyn_cast(s)) + s = ice->getSubExpr(); + } + + if (CallExpr *call = dyn_cast(s)) { + if (FunctionDecl *fd = call->getDirectCallee()) { + if (func_calls.count(fd) == 0) { + process_function(fd); + } + if (!func_calls[fd].empty()) { + func_calls[func_decl].push_back(call); + break; + } } } } @@ -340,10 +311,9 @@ namespace eosio { namespace cdt { return true; } - std::string func_name = func_decl->getQualifiedNameAsString(); - if (func_calls.count(func_decl) == 0 && (is_write_host_func(func_name) || is_eosio_wasm_import_write_func(func_decl))) { + std::string fn = func_decl->getQualifiedNameAsString(); + if (func_calls.count(func_decl) == 0 && (is_write_host_func(fn) || is_eosio_wasm_import_write_func(func_decl))) { func_calls[func_decl] = {(CallExpr*)func_decl}; - std::cout << "++key: " << func_decl->getQualifiedNameAsString() << ", value: (itself)" << std::endl; } else { process_function(func_decl); } @@ -381,41 +351,15 @@ namespace eosio { namespace cdt { visitor->set_main_name(main_fe->getName()); visitor->TraverseDecl(Context.getTranslationUnitDecl()); - // for (auto const& fc : visitor->func_calls) { - // std::cout << "key: " << fc.first->getQualifiedNameAsString() << " value: { "; - // for (auto const& v : fc.second) { - // std::cout << visitor->expr_to_str(v) << ", "; - // } - // std::cout << "}" << std::endl; - // } - for (auto const& ra : visitor->read_only_actions) { - std::cout << ra->getQualifiedNameAsString() << std::endl; auto it = visitor->func_calls.find(ra); - // CDT_CHECK_WARN(it == visitor->func_calls.end(), "codegen_warn", ra->getLocation(), "read only"); - - if (it != visitor->func_calls.end()) { + std::string msg = "read-only action cannot call write host function"; if (cg.warn_action_read_only) { - std::cout << "WARNING: read-only action cannot call write host function" << std::endl; + CDT_WARN("codegen_warning", ra->getLocation(), msg); } else { - std::cout << "ERROR: read-only action cannot call write host function" << std::endl; - // std::cout << it->first->getQualifiedNameAsString() << std::endl; - } - if (ra->getLocation().isValid()) { - std::cout << " Caller: " << ra->getLocation().printToString(src_mgr) << std::endl; - if (cg.warn_action_read_only) { - CDT_WARN("codegen_warning", ra->getLocation(), "read only"); - } else { - CDT_ERROR("codegen_error", ra->getLocation(), "read only"); - } + CDT_ERROR("codegen_error", ra->getLocation(), msg); } - // for (auto val : it->second) { - // if (val->getExprLoc().isValid()) { - // CDT_WARN("codegen_warn", it->second[0]->getExprLoc(), "read only"); - // std::cout << " Callee: " << val->getExprLoc().printToString(src_mgr) << std::endl; - // } - // } } } diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 62570a48cd..8e3be7e063 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -689,14 +689,21 @@ struct generation_utils { static const std::set write_host_funcs = { "eosio::internal_use_do_not_use::set_resource_limits", - // "eosio::chain::webassembly::interface::set_wasm_parameters_packed", - // "eosio::chain::webassembly::interface::set_resource_limit", // ? - "eosio::chain::controller::set_proposed_producers", // ? + "eosio::chain::webassembly::interface::set_resource_limits", + "eosio::chain::webassembly::interface::set_wasm_parameters_packed", + "eosio::chain::webassembly::interface::set_resource_limit", + "eosio::chain::controller::set_proposed_producers", + "eosio::chain::webassembly::interface::set_proposed_producers", "eosio::internal_use_do_not_use::set_proposed_producers_ex", + "eosio::chain::webassembly::interface::set_proposed_producers_ex", "eosio::internal_use_do_not_use::set_blockchain_parameters_packed", - // "eosio::chain::webassembly::interface::set_parameters_packed", // ? + "eosio::chain::webassembly::interface::set_blockchain_parameters_packed" + "eosio::chain::webassembly::interface::set_parameters_packed", + "eosio::chain::webassembly::set_kv_parameters_packed", "eosio::internal_use_do_not_use::set_kv_parameters_packed", + "eosio::chain::webassembly::interface::set_kv_parameters_packed", "eosio::internal_use_do_not_use::set_privileged", + "eosio::chain::webassembly::interface::set_privileged", "eosio::internal_use_do_not_use::db_store_i64", "eosio::internal_use_do_not_use::db_update_i64", "eosio::internal_use_do_not_use::db_remove_i64", @@ -718,7 +725,9 @@ struct generation_utils { "eosio::kv::internal_use_do_not_use::kv_erase", "eosio::kv::internal_use_do_not_use::kv_set", // deferred transactions - "eosio::internal_use_do_not_use::send_deferred", + "eosio::chain::webassembly::interface::send_deferred", + "eosio::chain::webassembly::interface::send_deferred" + "eosio::send_deferred", // inline actions "eosio::internal_use_do_not_use::send_inline", "eosio::internal_use_do_not_use::send_context_free_inline" @@ -729,7 +738,7 @@ struct generation_utils { inline bool is_deferred_transaction_func( const std::string& t ) { static const std::set deferred_transaction_funcs = { - "eosio::internal_use_do_not_use::send_deferred", + "send_deferred", }; return deferred_transaction_funcs.count(t) >= 1; } @@ -737,8 +746,8 @@ struct generation_utils { inline bool is_inline_action_func( const std::string& t ) { static const std::set inline_action_funcs = { - "eosio::internal_use_do_not_use::send_inline", - "eosio::internal_use_do_not_use::send_context_free_inline" + "send_inline", + "send_context_free_inline" }; return inline_action_funcs.count(t) >= 1; } @@ -746,9 +755,38 @@ struct generation_utils { inline bool is_eosio_wasm_import_write_func( const clang::FunctionDecl *func_decl ) { static const std::set eosio_wasm_import_write_funcs = { - "set_resource_limit", + "set_resource_limits", "set_wasm_parameters_packed", - "set_parameters_packed" + "set_resource_limit", + "set_proposed_producers", + "set_proposed_producers_ex", + "set_blockchain_parameters_packed", + "set_parameters_packed", + "set_kv_parameters_packed", + "set_privileged", + "db_store_i64", + "db_update_i64", + "db_remove_i64", + "db_idx64_store", + "db_idx64_update", + "db_idx64_remove", + "db_idx128_store", + "db_idx128_update", + "db_idx128_remove", + "db_idx256_store", + "db_idx256_update", + "db_idx256_remove", + "db_idx_double_store", + "db_idx_double_update", + "db_idx_double_remove", + "db_idx_long_double_store", + "db_idx_long_double_update", + "db_idx_long_double_remove", + "kv_erase", + "kv_set", + "send_deferred", + "send_inline", + "send_context_free_inline" }; if (eosio_wasm_import_write_funcs.count(func_decl->getQualifiedNameAsString()) == 0) { @@ -758,7 +796,6 @@ struct generation_utils { if (func_decl->isInExternCContext()) { auto attrs = func_decl->getAttrs(); for (auto const &a : attrs) { - std::cout << "attr:" << a->getSpelling() << "," << a->getKind() << std::endl; if (a->getSpelling() == "eosio_wasm_import") { return true; } From 486c04e22d5ada1c4d1fbbdc20930f4776b283ca Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Wed, 31 Mar 2021 22:44:55 -0400 Subject: [PATCH 073/204] update commit hash for submodule eosio_llvm --- eosio_llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio_llvm b/eosio_llvm index 423a4ac7a7..a14a183af1 160000 --- a/eosio_llvm +++ b/eosio_llvm @@ -1 +1 @@ -Subproject commit 423a4ac7a7074e139c4f4c2f786d6b71d1b0965e +Subproject commit a14a183af1178567b76b78efabff8fbfe035b07a From 75447977dc7bd7e68536b58f276d48b19edfbe65 Mon Sep 17 00:00:00 2001 From: Keke Li Date: Thu, 1 Apr 2021 16:05:25 -0700 Subject: [PATCH 074/204] Move test contract files so as to easily used by team. --- .../compile-fail}/hf_indirect_call_tests.cpp | 2 +- .../compile-fail}/host_functions_tests.cpp | 2 +- tests/unit/test_contracts/CMakeLists.txt | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) rename tests/{unit/test_contracts => toolchain/compile-fail}/hf_indirect_call_tests.cpp (98%) rename tests/{unit/test_contracts => toolchain/compile-fail}/host_functions_tests.cpp (99%) diff --git a/tests/unit/test_contracts/hf_indirect_call_tests.cpp b/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp similarity index 98% rename from tests/unit/test_contracts/hf_indirect_call_tests.cpp rename to tests/toolchain/compile-fail/hf_indirect_call_tests.cpp index 65b96885d1..198e93b2e0 100644 --- a/tests/unit/test_contracts/hf_indirect_call_tests.cpp +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp @@ -25,7 +25,7 @@ extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); -#define ACTION_TYPE [[eosio::action]] +#define ACTION_TYPE [[eosio::action, eosio::read_only]] class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { public: diff --git a/tests/unit/test_contracts/host_functions_tests.cpp b/tests/toolchain/compile-fail/host_functions_tests.cpp similarity index 99% rename from tests/unit/test_contracts/host_functions_tests.cpp rename to tests/toolchain/compile-fail/host_functions_tests.cpp index bc58eb88b6..a8cad07a11 100644 --- a/tests/unit/test_contracts/host_functions_tests.cpp +++ b/tests/toolchain/compile-fail/host_functions_tests.cpp @@ -66,7 +66,7 @@ extern "C" __attribute__((eosio_wasm_import)) void set_parameters_packed( const extern "C" __attribute__((eosio_wasm_import)) void send_inline(char *serialized_action, size_t size); extern "C" __attribute__((eosio_wasm_import)) void send_context_free_inline(char *serialized_action, size_t size); -#define ACTION_TYPE [[eosio::action]] +#define ACTION_TYPE [[eosio::action, eosio::read_only]] class [[eosio::contract]] host_functions_tests : public eosio::contract { public: diff --git a/tests/unit/test_contracts/CMakeLists.txt b/tests/unit/test_contracts/CMakeLists.txt index 5cd54f1681..dfd75dce4a 100644 --- a/tests/unit/test_contracts/CMakeLists.txt +++ b/tests/unit/test_contracts/CMakeLists.txt @@ -7,8 +7,6 @@ add_contract(minimal_tests minimal_tests minimal_tests.cpp) add_contract(kv_single_index_tests kv_single_index_tests kv_single_index_tests.cpp) add_contract(kv_multiple_indices_tests kv_multiple_indices_tests kv_multiple_indices_tests.cpp) add_contract(read_only_query_tests read_only_query_tests read_only_query_tests.cpp) -add_contract(host_functions_tests host_functions_tests host_functions_tests.cpp) -add_contract(hf_indirect_call_tests hf_indirect_call_tests hf_indirect_call_tests.cpp) add_contract(kv_make_key_tests kv_make_key_tests kv_make_key_tests.cpp) add_contract(kv_map_tests kv_map_tests kv_map_tests.cpp) add_contract(capi_tests capi_tests capi/capi.c capi/action.c capi/chain.c capi/crypto.c capi/db.c capi/permission.c From ac2c16b5e4e4ca51df2ddf36212f4892ea1c62a8 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 2 Apr 2021 12:07:27 +0300 Subject: [PATCH 075/204] updates to match newest how to template --- .../01_compile-a-contract-via-cli.md | 49 +++++++---- .../10_compile/02_how-to-configure-cmake.md | 84 ++++++++++++------- .../03_compiling-contracts-with-cmake.md | 40 ++++++--- ...to_restrict_access_to_an_action_by_user.md | 31 +++++-- 4 files changed, 135 insertions(+), 69 deletions(-) diff --git a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md index 060efe3869..efd2773736 100644 --- a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md +++ b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md @@ -1,20 +1,35 @@ --- -content_title: How to compile a contract via CLI +content_title: How to compile a smart contract via CLI --- -## Preconditions -- You have the source of your contract saved in one of your local folders, e.g. `./examples/hello` -For details on how to create your first contract follow [this tutorial here](https://developers.eos.io/eosio-home/docs/your-first-contract) - -Follow these steps to compile your contract: - -1. Navigate to the hello folder in examples (./examples/hello), you should then see the ./src/hello.cpp file -2. Now run following commands: -```sh -$ mkdir build -$ cd build -$ eosio-cpp -abigen ../src/hello.cpp -o hello.wasm -I ../include/ -``` -3. This will generate two files: -- The compiled binary wasm, hello.wasm -- The generated ABI file, hello.abi +## Overview + +This how-to guide provides instructions how to compile a smart contract using the command line interface (CLI). + +## Before you begin + +* You have the source of the contract saved in a local folder, e.g. `./examples/hello/` +For details on how to create your first contract follow the [Hello World Contract](https://developers.eos.io/welcome/latest/smart-contract-guides/hello-world) guide. + +## Procedure + +Follow the following steps to compile your contract. + +1. Navigate to the hello folder in examples `./examples/hello`. You should see the `./src/hello.cpp` file. + +2. Run the following commands: + + ```sh + mkdir build + cd build + eosio-cpp -abigen ../src/hello.cpp -o hello.wasm -I ../include/ + ``` + +3. Verify the following two files were generated: + +* the compiled binary wasm: `hello.wasm`, +* and the generated ABI file: `hello.abi`. + +## Summary + +In conclusion, the above instructions show how to compile a smart contract using the command line interface (CLI). diff --git a/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md b/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md index 22549b473c..12b68f0ebb 100644 --- a/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md +++ b/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md @@ -2,53 +2,77 @@ content_title: How to configure CMake --- -## CMake Configuration +## Overview + +This how-to guide provides instructions how to configure CMake. + +## Before you begin + +* You have installed CMake, for detailed instructions consult the official [CMake installation page](https://CMake.org/install/). + +## Procedure + +The following steps show: + +* [Automatic generation of CMake configuration](#automatic-generation-of-CMake-configuration) +* [Manual generation of CMake configuration](#manual-generation-of-CMake-configuration) ### Automatic generation of CMake configuration -To compile an EOSIO smart contract with CMake, you'll need a CMake file. To use the new `eosio-init` tool to generate the directory structure stub .hpp/.cpp files and the cmake configuration files follow these steps: +To compile an EOSIO smart contract with CMake, you'll need a CMake file. To use the new `eosio-init` tool to generate the directory structure stub `.hpp/.cpp` files and the CMake configuration files follow these steps: -1. cd ~ -2. eosio-init --path=. --project=test_contract -3. cd test_contract -4. cd build -5. cmake .. -6. make -7. ls -al test_contract + ```sh + cd ~ + eosio-init --path=. --project=test_contract + cd test_contract + cd build + cmake .. + make + ls -al test_contract + ``` At this point, you'll have the `test_contract.abi` and `test_contract.wasm` files in `~/test_contract/test_contract`. These files are ready to be deployed. ### Manual generation of CMake configuration -To create manually the cmake configuration, the template `CMakeLists.txt` in the examples folder is a good boilerplate for manual usage. +To create manually the CMake configuration, the template `CMakeLists.txt` in the examples folder is a good boilerplate for manual usage. 1. In `CMakeLists.txt`: -``` -cmake_minimum_required(VERSION 3.5) -project(test_example VERSION 1.0.0) -find_package(eosio.cdt) + ```sh + cmake_minimum_required(VERSION 3.5) + project(test_example VERSION 1.0.0) + + find_package(eosio.cdt) -add_contract( test test test.cpp ) -``` + add_contract( test test test.cpp ) + ``` 2. In `test.cpp`: -``` -#include -using namespace eosio; -class [[eosio::contract]] test : public eosio::contract { -public: - using contract::contract; + ```c++ + #include + using namespace eosio; - [[eosio::action]] void testact( name test ) { - } -}; + class [[eosio::contract]] test : public eosio::contract { + public: + using contract::contract; -EOSIO_DISPATCH( test, (testact) ) -``` + [[eosio::action]] void testact( name test ) { + } + }; + + EOSIO_DISPATCH( test, (testact) ) + ``` 3. The following CMake macros are provided: -- `add_contract` is used to build your smart contract and generate an ABI. The first parameter is the contract name, the second is the cmake target name, and the rest are the CPP files needed to build the contract. -- `target_ricardian_directory` can be used to add the directory where your ricardian contracts live to a specific cmake target. -- `add_native_library` and `add_native_executable` are CMake macros for the native tester. They are drop in replacements for `add_library` and `add_executable`. + +* `add_contract` is used to build your smart contract and generate an ABI. The first parameter is the contract name, the second is the CMake target name, and the rest are the CPP files needed to build the contract. + +* `target_ricardian_directory` can be used to add the directory where your ricardian contracts live to a specific CMake target. + +* `add_native_library` and `add_native_executable` are CMake macros for the native tester. They are drop in replacements for `add_library` and `add_executable`. + +## Summary + +In conclusion, the above instructions show how to configure CMake . diff --git a/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md b/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md index 54bd0814d6..eb0314f097 100644 --- a/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md +++ b/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md @@ -2,20 +2,34 @@ content_title: How to compile a smart contract with CMake --- -## Preconditions -- You have the source of your contract saved in one of your local folders, e.g. `./examples/hello` -For details on how to create your first contract follow [this tutorial here](https://developers.eos.io/eosio-home/docs/your-first-contract) +## Overview -Follow these steps to compile your contract: +This how-to guide provides instructions on how to compile a smart contract with CMake. + +## Before you begin + +* You have the source of the contract saved in a local folder, e.g. `./examples/hello/` +For details on how to create your first contract follow the [Hello World Contract](https://developers.eos.io/welcome/latest/smart-contract-guides/hello-world) guide. + +## Procedure + +Follow the following steps to compile your contract. 1. Navigate to the hello folder in examples (./examples/hello), you should then see the ./src/hello.cpp file 2. Run following commands: -```sh -$ mkdir build -$ cd build -$ cmake .. -$ make -``` -3. This will generate two files: -- The compiled binary wasm, hello.wasm -- The generated ABI file, hello.abi + + ```sh + mkdir build + cd build + cmake .. + make + ``` + +3. Verify the following two files were generated: + +* the compiled binary wasm: `hello.wasm`, +* and the generated ABI file: `hello.abi`. + +## Summary + +In conclusion, the above instructions show how to compile a smart contract with CMake. diff --git a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md index d439981846..0305eb7f4b 100644 --- a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md +++ b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md @@ -3,22 +3,35 @@ content_title: How To Perform Authorization Checks link_text: How To Perform Authorization Checks --- -## Preconditions +## Overview -The following conditions are assumed: +This how-to guide provides instructions how to perform authorization checks in a smart contract. -1. You have the sources of a contract with `hi` action defined. +## Before you begin + +1. You have the sources of a contract with a `hi` action defined and implemented. 2. The `hi` action has defined one input parameter `user` of type `name`. -3. The `hi` action prints the name of the `user` account. -4. The `hi` action needs to authorize the `user` account. -## Authorization Methods +## Code Reference -To restrict access to the `hi` action, you can do it in three ways. +See the following code reference guides for functions which can be used to implement authorization checks in a smart contract: -### 1. Use eosio::check(eosio::has_auth(...)...) +* function [has_auth(name n)](https://developers.eos.io/manuals/eosio.cdt/latest/namespaceeosio#function-has_auth) +* function [require_auth(name n)](https://developers.eos.io/manuals/eosio.cdt/latest/namespaceeosio/#function-require_auth-12) +* function [require_auth2(capi_name name, capi_name permission)](https://developers.eos.io/manuals/eosio.cdt/v1.8/group__action__c#function-require_auth2) +* function [check(bool pred, ...)](https://developers.eos.io/manuals/eosio.cdt/latest/group__system/#function-check) -The below code enforces the action `hi` to be executed only by the account that is sent as parameter to the action, no matter what permission the account uses to sign the transaction (e.g. owner, active, code). +## Procedure + +The following steps show how to check authorization for `user` account for the `hi` action. There are three ways to accomplish an authorization check in a smart contract action implementation. You can use any of the methods provided below depending on your needs: + +* [Use check(...) in combination with has_auth(...)](#1-use-checkhas_auth) +* [Use require_auth(...)](#2-use-require_auth) +* [Use require_auth2(...)](#3-use-require_auth2) + +### 1. Use check(has_auth(...)...) + +The following code example enforces the action `hi` to be executed only by the account that is sent as parameter to the action, no matter what permission the account uses to sign the transaction (e.g. owner, active, code). [[info | Error message is custom]] | Observe that in this case the yielded error message is a custom one and thus it can be used to provide a better experience for the user. From 988fec947ef015499f385bfe9e915021052ac1a5 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 2 Apr 2021 12:15:50 +0300 Subject: [PATCH 076/204] add the forgotten summary section --- .../how_to_restrict_access_to_an_action_by_user.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md index 0305eb7f4b..9a171ee1fd 100644 --- a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md +++ b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md @@ -76,3 +76,7 @@ void hi( name user ) { [[info | Error message is not custom]] | Note that this time, as well as previous method, you can not customize the yielded error message, it will be a generic authorization error message. + +## Summary + +In conclusion, the above instructions show how to how to perform authorization checks in a smart contract. From b5e2872bdd0c784547b7301342ec25c4f07f787a Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 2 Apr 2021 13:07:05 +0300 Subject: [PATCH 077/204] updates -- take 3 --- .../kv_map/10_how-to-use-kv-map.md | 20 ++++++++++++------- .../kv_map/30_how-to-upsert-into-kv-map.md | 18 ++++++++++------- .../kv_map/40_how-to-delete-from-kv-map.md | 18 ++++++++++------- .../kv_map/50_how-to-iterate-kv-map.md | 18 ++++++++++------- .../kv_map/70_how-to-find-in-kv-map.md | 18 +++++++++++------ .../90_how-to-allow-users-to-pay-kv-map.md | 14 ++++++++----- .../kv_table/10_how-to-use-kv-table.md | 10 +++++----- .../20_how-to-create-indexes-kv-table.md | 14 ++++++------- .../30_how-to-upsert-into-kv-table.md | 12 +++++------ .../40_how-to-delete-from-kv-table.md | 14 ++++++------- .../kv_table/50_how-to-iterate-kv-table.md | 14 ++++++------- .../60_how-to-check-a-record-kv-table.md | 14 ++++++------- .../kv_table/70_how-to-find-in-kv-table.md | 14 ++++++------- .../80_how-to-query-range-in-kv-table.md | 14 ++++++------- .../90_how-to-allow-users-to-pay-kv-table.md | 12 +++++------ .../60_how-to-return-values-from-actions.md | 2 +- 16 files changed, 127 insertions(+), 99 deletions(-) diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md index ad792f4b5a..d3c93175f8 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md @@ -3,19 +3,21 @@ content_title: How-To Use Key-Value Map link_text: "How-To Use Key-Value Map" --- -## Summary +## Overview -This how-to procedure demonstrates how to define and use a `Key-Value Map` (`kv map`) in your smart contract. +This how-to demonstrates how to define and use a `Key-Value Map` (`kv map`) in a smart contract. To accomplish this task use `eosio::kv::map` template class, specify the name for the map object instantiated, the type of the key, and the type for the values stored for each key. The types used for the key and the values can be any standard type, or a user defined type. -## Prerequisites +## Before you begin + +Complete the following prerequisites: -* The EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide. -* A smart contract named `smrtcontract`. -* A user defined type named `person`, which defines the data stored in the map. +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) +* A smart contract named `smrtcontract` +* A user defined type named `person`, which defines the data stored in the map -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -63,6 +65,10 @@ class [[eosio::contract]] smartcontract : public eosio::contract { }; ``` +## Summary + +In conclusion, the above instructions show how to define and use a `Key-Value Map` (`kv map`) in a smart contract. + ## Next Steps The following option is available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md index 1c2f680917..cbb4eee55e 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md @@ -3,20 +3,20 @@ content_title: How-To Upsert Into Key-Value Map link_text: "How-To Upsert Into Key-Value Map" --- -## Summary +## Overview -This how-to procedure provides instructions to upsert into `Key-Value Map` (`kv map`). Upsert means insert when the item doesn't already exist, and update the item if it already exists in the map. +This how-to provides instructions to upsert into `Key-Value Map` (`kv map`). Upsert means insert when the item doesn't already exist, and update the item if it already exists in the map. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* Install EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map -* A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. +* A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -105,6 +105,10 @@ void smartcontract::upsert( } ``` +## Summary + +In conclusion, the above instructions show how to upsert into `Key-Value Map` (`kv map`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md index f472e63b2e..433fdf7bf1 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md @@ -3,20 +3,20 @@ content_title: How-To Delete from Key-Value Map link_text: "How-To Delete from Key-Value Map" --- -## Summary +## Overview -This how-to procedure provides instructions to delete from `Key-Value Map` (`kv map`) based on the unique key. +This how-to provides instructions to delete from `Key-Value Map` (`kv map`) based on the unique key. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map -* A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. +* A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -104,3 +104,7 @@ void kv_map::delete(int id) { } } ``` + +## Summary + +In conclusion, the above instructions show how to delete from `Key-Value Map` (`kv map`) based on the unique key. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md index 14028e56b8..296a2ea14c 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md @@ -3,20 +3,20 @@ content_title: How-To Iterate Through Key-Value Map link_text: "How-To Iterate Through Key-Value Map" --- -## Summary +## Overview -This how-to procedure provides instructions to iterate through a `Key-Value Map` (`kv map`) and read values from it. +This how-to provides instructions to iterate through a `Key-Value Map` (`kv map`) and read values from it. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -41,7 +41,7 @@ class [[eosio::contract]] smartcontract : public eosio::contract { }; ``` -## Procedures +## Procedure Complete the following steps to implement an action that is iterating through the first N `person` objects in `kv map` and prints their first and last names: @@ -100,3 +100,7 @@ void kv_map::iterate(int iterations_count) { } } }``` + +## Summary + +In conclusion, the above instructions show how to iterate through a `Key-Value Map` (`kv map`) and read values from it. \ No newline at end of file diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md index 5caabe27fd..32370d83ba 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md @@ -3,20 +3,20 @@ content_title: How-To Find in Key-Value Map link_text: "How-To Find in Key-Value Map" --- -## Summary +## Overview -This how-to procedure provides instructions to find an object in `Key-Value Map` (`kv map`) based on the unique key. +This how-to provides instructions to find an object in `Key-Value Map` (`kv map`) based on the unique key. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -100,6 +100,12 @@ void kv_map::find(int id) { } ``` +## Summary + +In conclusion, the above instructions show how to find an object in `Key-Value Map` (`kv map`) based on the unique key. + +## Next Steps + The following options are available when you complete the procedure: * [Update](30_how-to-upsert-into-kv-map.md) the `person` found. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md index 6e687611c0..ec6ef01cdf 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md @@ -3,18 +3,18 @@ content_title: How-To Allow Users to Pay for Key-Value Map Resources link_text: "How-To Allow Users to Pay for Key-Value Map Resources" --- -## Summary +## Overview -This how-to procedure provides instructions to allow users to pay for the resources needed to store data in a `Key-Value Map` (`kv map`). +This how-to provides instructions to allow users to pay for the resources needed to store data in a `Key-Value Map` (`kv map`). -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -102,6 +102,10 @@ void smartcontract::upsert( } ``` +## Summary + +In conclusion, the above instructions show how to allow users to pay for the resources needed to store data in a `Key-Value Map` (`kv map`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index 9aab1dadec..c87c35d734 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -3,22 +3,22 @@ content_title: How-To Use Key-Value Table link_text: "How-To Use Key-Value Table" --- -## Summary +## Overview -This how-to procedure demonstrates how to define and use a `Key-Value Table` (`kv table`) in your smart contract. +This how-to demonstrates how to define and use a `Key-Value Table` (`kv table`) in a smart contract. To accomplish this task, define the user type which will be stored in the `kv table`, and extend the `eosio::kv::table` template class with a specialized definition based on the user defined type. [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. -## Prerequisites +## Before you begin -* The EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide. +* The EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. * A user defined type named `person`, which defines the data stored in the table. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index 09852875e1..3a1e301101 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -3,9 +3,9 @@ content_title: How-To Create Indexes on a Key-Value Table link_text: "How-To Create Indexes on a Key-Value Table" --- -## Summary +## Overview -This how-to procedure provides instructions to create the following indexes on a `Key-Value Table` (`kv table`): +This how-to provides instructions to create the following indexes on a `Key-Value Table` (`kv table`): * A unique index using the macro `KV_NAMED_INDEX` * A unique index using the `eosio::kv::table::index` template class @@ -17,11 +17,11 @@ The `KV_NAMED_INDEX` macro and the `eosio::kv::table::index` template class are [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type which defines the data stored in the table, named `person` * A `kv table` type which stores objects of type `person`, named `address_table` @@ -31,7 +31,7 @@ Before you begin, complete the following prerequisites: * `last_name`, * `personal_id`. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -52,7 +52,7 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -## Procedures +## Procedure ### Define a unique index on property account_name using the macro KV_NAMED_INDEX diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index 73612a99d4..e57f51c009 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -3,25 +3,25 @@ content_title: How-To Upsert Into Key-Value Table link_text: "How-To Upsert Into Key-Value Table" --- -## Summary +## Overview -This how-to procedure provides instructions to upsert into `Key-Value Table` (`kv table`). +This how-to provides instructions to upsert into `Key-Value Table` (`kv table`). [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. Use the method `put` defined by the `eosio::kv::table` type to accomplish this task. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index dc97f8a876..307e5f79db 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -3,25 +3,25 @@ content_title: How-To Delete from Key-Value Table link_text: "How-To Delete from Key-Value Table" --- -## Summary +## Overview -This how-to procedure provides instructions to delete an object from a `Key-Value Table` (`kv table`). +This how-to provides instructions to delete an object from a `Key-Value Table` (`kv table`). [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. Use the method `erase` defined by the `eosio::kv::table` type to accomplish this task. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -53,7 +53,7 @@ class [[eosio::contract]] smrtcontract : public contract { Complete the following steps to delete a `person` object from `address_table`: -1. Create a new action `delete`, in your smart contract class, which takes as input parameters an account name, a first name, a last name and a personal id. +1. Create a new action `delete`, in a smart contract class, which takes as input parameters an account name, a first name, a last name and a personal id. 2. In the `delete` action access the instance of `address_table` by declaring a local variable of `address_table` type. 3. Call the `erase` method of the `address_table` and pass to it the primary key for the object which is deleted. If you try to erase an object which is not present in the `kv table` no error will be raised. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index c815d3693c..5064068468 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -3,20 +3,20 @@ content_title: How-To Iterate Through Key-Value Table link_text: "How-To Iterate Through Key-Value Table" --- -## Summary +## Overview -This how-to procedure provides instructions to iterate through a `Key-Value Table` (`kv table`) and read values from it. +This how-to provides instructions to iterate through a `Key-Value Table` (`kv table`) and read values from it. [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. Use the `iterator` defined by the `eosio::kv::table::index` class to accomplish this task. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide. +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. * A user defined type which defines the data stored in the table, named `person`. * A `kv table` type which stores objects of type `person`, named `address_table`. @@ -27,7 +27,7 @@ Before you begin, complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -55,7 +55,7 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -## Procedures +## Procedure Complete the following steps to implement an action that is iterating through the first N `person` objects in `address_table` and prints their first and last names: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index 2bf88337bf..32a7c78347 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -3,20 +3,20 @@ content_title: How-To Check a Record in a Key-Value Table link_text: "How-To Check a Record in a Key-Value Table" --- -## Summary +## Overview -This how-to procedure provides instructions to check if a specific object exists in a `Key-Value Table` (`kv table`). +This how-to provides instructions to check if a specific object exists in a `Key-Value Table` (`kv table`). [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. Use the method `exists` defined by the `eosio::kv::table::index` class to accomplish this task. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide. +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. * A user defined type which defines the data stored in the table, named `person`. * A `kv table` type which stores objects of type `person`, named `address_table`. @@ -27,7 +27,7 @@ Before you begin, complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -55,7 +55,7 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -## Procedures +## Procedure Complete the following steps to implement an action that is verifying whether a particular `person` identified by its `account_name` exists in the `address_table`: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index 479f98f65a..4268a8aeb3 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -3,20 +3,20 @@ content_title: How-To Find in Key-Value Table link_text: "How-To Find in Key-Value Table" --- -## Summary +## Overview -This how-to procedure provides instructions to find a specific object in a `Key-Value Table` (`kv table`). +This how-to provides instructions to find a specific object in a `Key-Value Table` (`kv table`). [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. Use the method `find()` defined by the `eosio::kv::table::index` class to accomplish this task. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide. +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. * A user defined type which defines the data stored in the table, named `person`. * A `kv table` type which stores objects of type `person`, named `address_table`. @@ -27,7 +27,7 @@ Before you begin, complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -55,7 +55,7 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -## Procedures +## Procedure Complete the following steps to implement an action to find a particular `person` identified by the `account_name` in the `address_table` and returns the person back to the caller: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index b348a441ca..b461fc101a 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -3,20 +3,20 @@ content_title: How-To Query Range in Key-Value Table link_text: "How-To Query Range in Key-Value Table" --- -## Summary +## Overview -This how-to procedure provides instructions to retrieve a list of values, from a `Key-Value Table` (`kv table`) index, which share a particular commonality. +This how-to provides instructions to retrieve a list of values, from a `Key-Value Table` (`kv table`) index, which share a particular commonality. [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. Use the method `range` defined by the `eosio::kv::table::index` class to accomplish this task. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide. +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. * A user defined type which defines the data stored in the table, named `person`. * A `kv table` type which stores objects of type `person`, named `address_table`. @@ -28,7 +28,7 @@ Before you begin, complete the following prerequisites: * A unique index, named `account_name_uidx`, defined on the `account_name` property.. * A non-unique index defined on the `last_name` property, named `last_name_idx`. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` @@ -60,7 +60,7 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -## Procedures +## Procedure Complete the following steps to implement an action to retrieve a list of persons with the same name from `address_table` and return it back to the caller: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index df7cb936a3..f101221769 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -3,25 +3,25 @@ content_title: How-To Allow Users to Pay for Key-Value Table Resources link_text: "How-To Allow Users to Pay for Key-Value Table Resources" --- -## Summary +## Overview -This how-to procedure provides instructions to allow users to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). +This how-to provides instructions to allow users to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. Use the method `put` defined by the `eosio::kv::table` type to accomplish this task and provide as the second parameter the account name which is the payer for the resources needed. -## Prerequisites +## Before you begin -Before you begin, complete the following prerequisites: +Complete the following prerequisites: -* An EOSIO development environment, for details consult the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation of your starting point. +Refer to the following possible implementation for your starting point. `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md index 04d15ebedb..e184a02d27 100644 --- a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md +++ b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md @@ -10,7 +10,7 @@ In order to accomplish this, use the `return` statement and pass the desired ret ## Prerequisites -* Set your EOSIO development environment. Refer to the [Get Started](https://developers.eos.io/welcome/latest/getting-started/development-environment/introduction) Guide. +* Set your EOSIO development environment. Refer to the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * You have a smart contract, let’s call it `smrtcontract`, and it builds without error. * You have an action, let’s call it `checkwithrv`, from which you want to return a value of a user defined type `action_response`. From c3eb5e1a34e75c60419aff3547f3f71f8bafa8b2 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 2 Apr 2021 13:22:19 +0300 Subject: [PATCH 078/204] updates take 3 --- .../30_key-value-api/kv_table/10_how-to-use-kv-table.md | 8 +++++++- .../kv_table/20_how-to-create-indexes-kv-table.md | 4 ++++ .../kv_table/30_how-to-upsert-into-kv-table.md | 4 ++++ .../kv_table/40_how-to-delete-from-kv-table.md | 4 ++++ .../kv_table/50_how-to-iterate-kv-table.md | 4 ++++ .../kv_table/60_how-to-check-a-record-kv-table.md | 4 ++++ .../kv_table/70_how-to-find-in-kv-table.md | 4 ++++ .../kv_table/80_how-to-query-range-in-kv-table.md | 4 ++++ .../kv_table/90_how-to-allow-users-to-pay-kv-table.md | 4 ++++ .../50_how-to-create-and-use-action-wrappers.md | 3 +++ 10 files changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index c87c35d734..ce25d82ec9 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -14,7 +14,9 @@ To accomplish this task, define the user type which will be stored in the `kv ta ## Before you begin -* The EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). +Complete the following prerequisites: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. * A user defined type named `person`, which defines the data stored in the table. @@ -72,6 +74,10 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` +## Summary + +In conclusion, the above instructions show how to define and use a `Key-Value Table` (`kv table`) in a smart contract. + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index 3a1e301101..882793c2b6 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -177,6 +177,10 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` +## Summary + +In conclusion, the above instructions show how to create indexes on a `Key-Value Table` (`kv table`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index e57f51c009..9dfde3096b 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -105,6 +105,10 @@ void smrtcontract::upsert( } ``` +## Summary + +In conclusion, the above instructions show how to upsert into `Key-Value Table` (`kv table`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index 307e5f79db..7c0a31d9de 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -96,6 +96,10 @@ void smrtcontract::delete(eosio::name account_name) { } ``` +## Summary + +In conclusion, the above instructions show how to delete an object from a `Key-Value Table` (`kv table`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index 5064068468..60b9e5b744 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -118,3 +118,7 @@ std::vector smrtcontract::iterate(int iterations_count) { } } ``` + +## Summary + +In conclusion, the above instructions show how to iterate through a `Key-Value Table` (`kv table`) and read values from it. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index 32a7c78347..048c7ceefe 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -102,6 +102,10 @@ bool smrtcontract::verify(string personal_id, string country) { } ``` +## Summary + +In conclusion, the above instructions show how to check if a specific object exists in a `Key-Value Table` (`kv table`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index 4268a8aeb3..243bdaac2f 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -119,6 +119,10 @@ person smrtcontract::find(name account_name) { } ``` +## Summary + +In conclusion, the above instructions show how to find a specific object in a `Key-Value Table` (`kv table`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index b461fc101a..c5d852b499 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -119,6 +119,10 @@ std::vector smrtcontract::getbylastname(string last_name) { } ``` +## Summary + +In conclusion, the above instructions show how to retrieve a list of values, from a `Key-Value Table` (`kv table`) index, which share a particular commonality. + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index f101221769..758ebe0e40 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -107,6 +107,10 @@ void smrtcontract::upsert( } ``` +## Summary + +In conclusion, the above instructions show how to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). + ## Next Steps The following options are available when you complete the procedure: diff --git a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md index 9692ff7b76..f00f6aceda 100644 --- a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md +++ b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md @@ -4,6 +4,7 @@ link_text: "How to create and use action wrappers" --- 1. Start with a contract `multi_index_example` which has an action `mod` defined like below in file `multi_index_example.hpp`; the action modifies the integer value `n` stored for row with key `user`. + ```cpp class [[eosio::contract]] multi_index_example : public contract { // ... @@ -11,7 +12,9 @@ class [[eosio::contract]] multi_index_example : public contract { // ... } ``` + 2. To define an action wrapper for the `mod` action, make use of the `eosio::action_wrapper` template, with the first parameter the action name as a `eosio::name` and second parameter as the reference to the action method + ```diff class [[eosio::contract]] multi_index_example : public contract { // ... From 9314f35120b394a00d201863c7057ba0ffbc8341 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 2 Apr 2021 16:56:14 -0400 Subject: [PATCH 079/204] add toolchain tests --- .../compile-fail/hf_indirect_call_tests.json | 10 ++++ .../compile-fail/host_functions_tests.json | 10 ++++ .../compile-pass/warn_action_read_only.cpp | 15 ++++++ .../compile-pass/warn_action_read_only.json | 12 +++++ tests/unit/test_contracts/read_only_tests.cpp | 48 ------------------- 5 files changed, 47 insertions(+), 48 deletions(-) create mode 100644 tests/toolchain/compile-fail/hf_indirect_call_tests.json create mode 100644 tests/toolchain/compile-fail/host_functions_tests.json create mode 100644 tests/toolchain/compile-pass/warn_action_read_only.cpp create mode 100644 tests/toolchain/compile-pass/warn_action_read_only.json delete mode 100644 tests/unit/test_contracts/read_only_tests.cpp diff --git a/tests/toolchain/compile-fail/hf_indirect_call_tests.json b/tests/toolchain/compile-fail/hf_indirect_call_tests.json new file mode 100644 index 0000000000..d3ec0acf8a --- /dev/null +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.json @@ -0,0 +1,10 @@ +{ + "tests" : [ + { + "compile_flags": [], + "expected" : { + "stderr": "codegen error" + } + } + ] +} diff --git a/tests/toolchain/compile-fail/host_functions_tests.json b/tests/toolchain/compile-fail/host_functions_tests.json new file mode 100644 index 0000000000..d1d45c5ebf --- /dev/null +++ b/tests/toolchain/compile-fail/host_functions_tests.json @@ -0,0 +1,10 @@ +{ + "tests" : [ + { + "compile_flags": [], + "expected" : { + "stderr": "codegen error" + } + } + ] +} diff --git a/tests/toolchain/compile-pass/warn_action_read_only.cpp b/tests/toolchain/compile-pass/warn_action_read_only.cpp new file mode 100644 index 0000000000..5cc31b607e --- /dev/null +++ b/tests/toolchain/compile-pass/warn_action_read_only.cpp @@ -0,0 +1,15 @@ +#include +#include + +using namespace eosio; +extern "C" __attribute__((weak)) __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); + +class [[eosio::contract]] warn_action_read_only : public contract { + public: + using contract::contract; + + [[eosio::action, eosio::read_only]] + void test1( name user ) { + set_resource_limit(user.value, 0, 0); + } +}; diff --git a/tests/toolchain/compile-pass/warn_action_read_only.json b/tests/toolchain/compile-pass/warn_action_read_only.json new file mode 100644 index 0000000000..60e098a091 --- /dev/null +++ b/tests/toolchain/compile-pass/warn_action_read_only.json @@ -0,0 +1,12 @@ +{ + "tests" : [ + { + "compile_flags": ["--warn-action-read-only"], + "expected" : { + "exit-code": 0, + "stderr": "codegen warning" + } + } + ] +} + \ No newline at end of file diff --git a/tests/unit/test_contracts/read_only_tests.cpp b/tests/unit/test_contracts/read_only_tests.cpp deleted file mode 100644 index 8c4448e6fd..0000000000 --- a/tests/unit/test_contracts/read_only_tests.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include - -using namespace eosio; -extern "C" __attribute__((weak)) __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); - -class [[eosio::contract]] read_only_tests : public contract { - public: - - [[eosio::action, eosio::read_only]] - void test1( name user, int64_t limit ) { - print( "Hello, ", user); - set_resource_limit(user.value, 0, 0); - } - - [[eosio::action]] - void test2( name user, int64_t limit ) { - internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); - } - - [[eosio::action, eosio::read_only]] - void test3( name user, int64_t limit ) { - internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); - } - - [[eosio::action, eosio::read_only]] - void test4( name user, int64_t limit ) { - foo1(user); - } - - [[eosio::action, eosio::read_only]] - void test5( name user, int64_t limit ) { - foo3(user); - } - - void foo1(name user) { - foo(user); - } - - void foo(name user) { - internal_use_do_not_use::set_resource_limits(user.value, 0, 0, 0); - } - - void foo3(name user) { - set_resource_limit(user.value, 0, 0); - } - -}; From 281807748d7169765afd8773d36b28868e1f0af9 Mon Sep 17 00:00:00 2001 From: Keke Li Date: Fri, 2 Apr 2021 14:04:09 -0700 Subject: [PATCH 080/204] Change flag to read_only for get() action --- tests/unit/test_contracts/read_only_query_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_contracts/read_only_query_tests.cpp b/tests/unit/test_contracts/read_only_query_tests.cpp index d2e6fd6237..03db734fbd 100644 --- a/tests/unit/test_contracts/read_only_query_tests.cpp +++ b/tests/unit/test_contracts/read_only_query_tests.cpp @@ -96,7 +96,7 @@ class [[eosio::contract]] read_only_query_tests : public eosio::contract { tf.put(s8, get_self()); } - [[eosio::action]] + [[eosio::action, eosio::read_only]] std::vector get() { my_table_m tm{"eosio"_n}; my_table_f tf{"eosio"_n}; From d214537ef6d094dae2fc0df278121d815c89c9dc Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 6 Apr 2021 16:12:55 +0300 Subject: [PATCH 081/204] how to action wrapper --- ...to_restrict_access_to_an_action_by_user.md | 2 +- ...0_how-to-create-and-use-action-wrappers.md | 58 +++++++++++++++++-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md index 9a171ee1fd..2910c27cfd 100644 --- a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md +++ b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md @@ -79,4 +79,4 @@ void hi( name user ) { ## Summary -In conclusion, the above instructions show how to how to perform authorization checks in a smart contract. +In conclusion, the above instructions show how to perform authorization checks in a smart contract. diff --git a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md index f00f6aceda..d02f11932d 100644 --- a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md +++ b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md @@ -3,7 +3,19 @@ content_title: How to create and use action wrappers link_text: "How to create and use action wrappers" --- -1. Start with a contract `multi_index_example` which has an action `mod` defined like below in file `multi_index_example.hpp`; the action modifies the integer value `n` stored for row with key `user`. +## Overview + +This how-to guide provides instructions on how to create and use an action wrapper in a smart contract. + +## Before you begin + +Complete the following prerequisites: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). +* A smart contract named `multi_index_example`, defined in file `multi_index_example.hpp`. +* An action `mod` which modifies the integer value `n` stored for row with key `user`. + +Refer to the following possible implementation for your starting point. ```cpp class [[eosio::contract]] multi_index_example : public contract { @@ -13,7 +25,25 @@ class [[eosio::contract]] multi_index_example : public contract { } ``` -2. To define an action wrapper for the `mod` action, make use of the `eosio::action_wrapper` template, with the first parameter the action name as a `eosio::name` and second parameter as the reference to the action method +## Code Reference + +See the following code reference guide for action wrapper: + +* [eosio::action_wrapper](../structeosio_1_1action__wrapper). + +## Procedure + +Complete the following steps to create and use action wrapper in the smart contract: + +1. [Define the action wrapper](#1-define-the-action-wrapper) +2. [Use the action wrapper](#2-use-the-action-wrapper) + * [2.1. Include Header File](#21-include-header-file) + * [2.2. Instantiate The Action Wrapper](#22-instantiate-the-action-wrapper) + * [2.3. Send The Action Using The Action Wrapper](#23-send-the-action-using-the-action-wrapper) + +### 1. Define The Action Wrapper + +To define an action wrapper for the `mod` action, make use of the `eosio::action_wrapper` template, with the first parameter the action name as a `eosio::name` and second parameter as the reference to the action method: ```diff class [[eosio::contract]] multi_index_example : public contract { @@ -24,17 +54,31 @@ class [[eosio::contract]] multi_index_example : public contract { // ... } ``` -3. To use the action wrapper, you have to include the header file where the action wrapper is defined + +### 2. Use The Action Wrapper + +#### 2.1. Include Header File + +To use the action wrapper, you have to include the header file where the action wrapper is defined: + ```cpp #include ``` -4. Then instantiate the `mod_action` defined above, specifying the contract to send the action to as the first argument. In this case, it is assumed the contract is deployed to `multiindexex` account, and a structure which is defined by two parameters: the self account, obtained by `get_self()` call, and the `active` permission (you can modify these two parameters based on your requirements). + +#### 2.2. Instantiate The Action Wrapper + +Instantiate the `mod_action` defined above, specifying the contract to send the action to as the first argument. In this case, it is assumed the contract is deployed to `multiindexex` account, and a structure which is defined by two parameters: the self account, obtained by `get_self()` call, and the `active` permission (you can modify these two parameters based on your requirements). + ```diff #include +multi_index_example::mod_action modaction("multiindexex"_n, {get_self(), "active"_n}); ``` -5. And finally call the `send` method of the action wrapper and pass in the `mod` action's parameters as positional arguments + +#### 2.3. Send The Action Using The Action Wrapper + +Call the `send` method of the action wrapper and pass in the `mod` action's parameters as positional arguments: + ```diff #include @@ -44,3 +88,7 @@ multi_index_example::mod_action modaction("multiindexex"_n, {get_self(), 1}); ``` For a full example see the [`multi_index` contract implementation](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to create and use action wrapper in a smart contract. From edb426b3129f032e0c5d4e7e75f65019b958f54a Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 6 Apr 2021 16:28:58 +0300 Subject: [PATCH 082/204] cosmetic updates --- .../kv_map/10_how-to-use-kv-map.md | 2 +- .../kv_map/30_how-to-upsert-into-kv-map.md | 2 +- .../kv_map/40_how-to-delete-from-kv-map.md | 2 +- .../kv_map/50_how-to-iterate-kv-map.md | 2 +- .../kv_map/70_how-to-find-in-kv-map.md | 2 +- .../90_how-to-allow-users-to-pay-kv-map.md | 2 +- .../kv_table/10_how-to-use-kv-table.md | 2 +- .../20_how-to-create-indexes-kv-table.md | 2 +- .../30_how-to-upsert-into-kv-table.md | 2 +- .../40_how-to-delete-from-kv-table.md | 2 +- .../kv_table/50_how-to-iterate-kv-table.md | 2 +- .../60_how-to-check-a-record-kv-table.md | 2 +- .../kv_table/70_how-to-find-in-kv-table.md | 2 +- .../80_how-to-query-range-in-kv-table.md | 2 +- .../90_how-to-allow-users-to-pay-kv-table.md | 2 +- ...0_how-to-create-and-use-action-wrappers.md | 2 +- .../60_how-to-return-values-from-actions.md | 25 +++++++++++++------ 17 files changed, 34 insertions(+), 23 deletions(-) diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md index d3c93175f8..470f7d2e22 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md @@ -17,7 +17,7 @@ Complete the following prerequisites: * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md index cbb4eee55e..be19c9554d 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md @@ -16,7 +16,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md index 433fdf7bf1..5cd727e298 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md @@ -16,7 +16,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md index 296a2ea14c..c9c5e31d8a 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md @@ -16,7 +16,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md index 32370d83ba..6d8b78fcef 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md @@ -16,7 +16,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md index ec6ef01cdf..fc2b5336c1 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md @@ -14,7 +14,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index ce25d82ec9..94ada5b62b 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -20,7 +20,7 @@ Complete the following prerequisites: * A smart contract named `smrtcontract`. * A user defined type named `person`, which defines the data stored in the table. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index 882793c2b6..b83ebe676b 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -31,7 +31,7 @@ Complete the following prerequisites: * `last_name`, * `personal_id`. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index 9dfde3096b..9e0bfe7ea3 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -21,7 +21,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index 7c0a31d9de..5f21c20ecf 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -21,7 +21,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index 60b9e5b744..38cb5ace6d 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -27,7 +27,7 @@ Complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index 048c7ceefe..6f4d33104f 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -27,7 +27,7 @@ Complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index 243bdaac2f..6192a387c6 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -27,7 +27,7 @@ Complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index c5d852b499..852797ad53 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -28,7 +28,7 @@ Complete the following prerequisites: * A unique index, named `account_name_uidx`, defined on the `account_name` property.. * A non-unique index defined on the `last_name` property, named `last_name_idx`. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index 758ebe0e40..3824fcb20e 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -21,7 +21,7 @@ Complete the following prerequisites: * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md index d02f11932d..8c337f83b8 100644 --- a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md +++ b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md @@ -15,7 +15,7 @@ Complete the following prerequisites: * A smart contract named `multi_index_example`, defined in file `multi_index_example.hpp`. * An action `mod` which modifies the integer value `n` stored for row with key `user`. -Refer to the following possible implementation for your starting point. +Refer to the following possible implementation for your starting point: ```cpp class [[eosio::contract]] multi_index_example : public contract { diff --git a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md index e184a02d27..40ae679320 100644 --- a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md +++ b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md @@ -2,19 +2,21 @@ content_title: How-To Return Values From Action --- -## Summary +## Overview This how-to demonstrates how a smart contract developer implements return values from an action. In order to accomplish this, use the `return` statement and pass the desired returned value, which can be of any C++ primitive type, a standard library type, or a user defined type. -## Prerequisites +## Before you begin + +Complete the following prerequisites: -* Set your EOSIO development environment. Refer to the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). -* You have a smart contract, let’s call it `smrtcontract`, and it builds without error. -* You have an action, let’s call it `checkwithrv`, from which you want to return a value of a user defined type `action_response`. +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). +* A smart contract, let’s call it `smrtcontract`, which builds without error. +* An action, let’s call it `checkwithrv`, from which you want to return a value of a user defined type `action_response`. -Refer to the following example. +Refer to the following possible implementation for your starting point: ```cpp struct action_response @@ -36,7 +38,7 @@ class [[eosio::contract]] smrtcontract : public contract { Complete the following steps to return an instance of `action_response` from the `checkwithrv` action: -1. Create an instance of the `action_response` C++ defined structure. +1. Create an instance of `action_response` C++ defined structure. 2. Initialize its data members based on the action’s business logic. 3. Use `return` statement and pass as a parameter the instance created and initialized in previous steps. @@ -45,7 +47,10 @@ Complete the following steps to return an instance of `action_response` from the action_response smrtcontract::checkwithrv( name nm ) { print_f("Name : %\n", nm); + // create instance of the action response structure action_response results; + + // initialize its data members results.id = 1; if (nm == "hello"_n) { results.status = {0, "Validation has passed."}; @@ -53,6 +58,8 @@ action_response smrtcontract::checkwithrv( name nm ) { else { results.status = {1, "Input param `name` not equal to `hello`."}; } + + // use return statement return results; // the `set_action_return_value` intrinsic is invoked automatically here } ``` @@ -69,3 +76,7 @@ The following options are available when you complete the procedure: [[info | Returned values from actions availability]] The returned values from actions are only available to the clients sending the action via the RPC API. Currently, there is no support for an inline action to be able to use the return value, because inline actions don't execute synchronously. + +## Summary + +In conclusion, the above instructions show how to return values from actions. From 4ff779217c54dccc8fb9a59463c0e1c6cb78e82b Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Tue, 6 Apr 2021 15:17:57 -0400 Subject: [PATCH 083/204] add regex support for toolchain tester; fix string compare --- tests/toolchain/compile-fail/hf_indirect_call_tests.json | 3 ++- tests/toolchain/compile-fail/host_functions_tests.json | 3 ++- tests/toolchain/compile-pass/warn_action_read_only.json | 1 - tools/include/compiler_options.hpp.in | 1 - tools/include/eosio/gen.hpp | 2 +- tools/toolchain-tester/tests.py | 3 ++- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/toolchain/compile-fail/hf_indirect_call_tests.json b/tests/toolchain/compile-fail/hf_indirect_call_tests.json index d3ec0acf8a..a5ed8bad19 100644 --- a/tests/toolchain/compile-fail/hf_indirect_call_tests.json +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.json @@ -3,7 +3,8 @@ { "compile_flags": [], "expected" : { - "stderr": "codegen error" + "exit-code": 255, + "stderr": "(codegen error.*){8}" } } ] diff --git a/tests/toolchain/compile-fail/host_functions_tests.json b/tests/toolchain/compile-fail/host_functions_tests.json index d1d45c5ebf..1d02388a63 100644 --- a/tests/toolchain/compile-fail/host_functions_tests.json +++ b/tests/toolchain/compile-fail/host_functions_tests.json @@ -3,7 +3,8 @@ { "compile_flags": [], "expected" : { - "stderr": "codegen error" + "exit-code": 255, + "stderr": "(codegen error.*){20}" } } ] diff --git a/tests/toolchain/compile-pass/warn_action_read_only.json b/tests/toolchain/compile-pass/warn_action_read_only.json index 60e098a091..0710b598c2 100644 --- a/tests/toolchain/compile-pass/warn_action_read_only.json +++ b/tests/toolchain/compile-pass/warn_action_read_only.json @@ -9,4 +9,3 @@ } ] } - \ No newline at end of file diff --git a/tools/include/compiler_options.hpp.in b/tools/include/compiler_options.hpp.in index 3953af2557..a335f887a3 100644 --- a/tools/include/compiler_options.hpp.in +++ b/tools/include/compiler_options.hpp.in @@ -911,7 +911,6 @@ static Options CreateOptions(bool add_defaults=true) { if (fuse_main_opt) ldopts.emplace_back("-fuse-main"); - /* TODO */ if(warn_action_read_only_opt) { warn_action_read_only = true; } else { diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 8e3be7e063..664203c873 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -796,7 +796,7 @@ struct generation_utils { if (func_decl->isInExternCContext()) { auto attrs = func_decl->getAttrs(); for (auto const &a : attrs) { - if (a->getSpelling() == "eosio_wasm_import") { + if (strcmp(a->getSpelling(), "eosio_wasm_import") == 0) { return true; } } diff --git a/tools/toolchain-tester/tests.py b/tools/toolchain-tester/tests.py index 0a21695363..2385dbe636 100644 --- a/tools/toolchain-tester/tests.py +++ b/tools/toolchain-tester/tests.py @@ -7,6 +7,7 @@ import json import os import subprocess +import re from printer import Printer as P from errors import TestFailure @@ -89,7 +90,7 @@ def handle_expecteds(self, res: subprocess.CompletedProcess): expected_stderr = expected["stderr"] actual_stderr = res.stderr.decode("utf-8") - if expected_stderr not in actual_stderr: + if expected_stderr not in actual_stderr and not re.search(expected_stderr, actual_stderr, flags=re.S): self.success = False raise TestFailure( f"expected {expected_stderr} stderr but got {actual_stderr}", From 9e2e8a6eee2bfa3166490203f23282b3c8899631 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Wed, 7 Apr 2021 10:10:14 -0400 Subject: [PATCH 084/204] break up name_tests into smaller tests, rename string_tests, remove static --- tests/unit/name_tests.cpp | 99 ++++++- tests/unit/string_tests1.cpp | 513 +++++++++++++++++----------------- tests/unit/string_tests2.cpp | 515 ++++++++++++++++++----------------- 3 files changed, 608 insertions(+), 519 deletions(-) diff --git a/tests/unit/name_tests.cpp b/tests/unit/name_tests.cpp index 464a9bf855..3f759deb27 100644 --- a/tests/unit/name_tests.cpp +++ b/tests/unit/name_tests.cpp @@ -14,11 +14,10 @@ using std::string; using eosio::name; -static constexpr uint64_t u64min = numeric_limits::min(); // 0ULL -static constexpr uint64_t u64max = numeric_limits::max(); // 18446744073709551615ULL +constexpr uint64_t u64max = numeric_limits::max(); // 18446744073709551615ULL // Definitions in `eosio.cdt/libraries/eosio/name.hpp` -EOSIO_TEST_BEGIN(name_type_test) +EOSIO_TEST_BEGIN(name_type_test_constructor_num) //// constexpr name() CHECK_EQUAL( name{}.value, 0ULL ) @@ -26,12 +25,13 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{0ULL}.value, 0ULL ) CHECK_EQUAL( name{1ULL}.value, 1ULL ) CHECK_EQUAL( name{u64max}.value, u64max ) - //// constexpr explicit name(name::raw) CHECK_EQUAL( name{name::raw{0ULL}}.value, 0ULL ) CHECK_EQUAL( name{name::raw{1ULL}}.value, 1ULL ) CHECK_EQUAL( name{name::raw{u64max}}.value, u64max ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_constructor_str_1) //// constexpr explicit name(string_view) // Note: // These are the exact `uint64_t` value representations of the given string @@ -42,13 +42,17 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"abc"}.value, 3589368903014285312ULL ) CHECK_EQUAL( name{"123"}.value, 614178399182651392ULL ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_3) CHECK_EQUAL( name{".abc"}.value, 112167778219196416ULL ) CHECK_EQUAL( name{".........abc"}.value, 102016ULL ) CHECK_EQUAL( name{"123."}.value, 614178399182651392ULL ) CHECK_EQUAL( name{"123........."}.value, 614178399182651392ULL ) CHECK_EQUAL( name{".a.b.c.1.2.3."}.value, 108209673814966320ULL ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_constructor_str_2) CHECK_EQUAL( name{"abc.123"}.value, 3589369488740450304ULL ) CHECK_EQUAL( name{"123.abc"}.value, 614181822271586304ULL ) @@ -60,14 +64,19 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"555555555555j"}.value, 2975281302211218015ULL ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"}.value, 3570337562653461615ULL ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"}.value, u64max ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_str_not_allowed) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name{"-1"};}) ) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name{"0"};}) ) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name{"6"};}) ) CHECK_ASSERT( "thirteenth character in name cannot be a letter that comes after j", ([]() {name{"111111111111k"};}) ) CHECK_ASSERT( "thirteenth character in name cannot be a letter that comes after j", ([]() {name{"zzzzzzzzzzzzk"};}) ) CHECK_ASSERT( "string is too long to be a valid name", ([]() {name{"12345abcdefghj"};}) ) +EOSIO_TEST_END + +EOSIO_TEST_BEGIN(name_type_test_char_to_value) // -------------------------------------------- // static constexpr uint8_t char_to_value(char) char c{'.'}; @@ -84,7 +93,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name::char_to_value(c), expected_value ) ++expected_value; } +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_allowed_chars) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name::char_to_value(char{'-'});}) ) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name::char_to_value(char{'/'});}) ) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name::char_to_value(char{'6'});}) ) @@ -92,7 +103,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name::char_to_value(char{'Z'});}) ) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name::char_to_value(char{'`'});}) ) CHECK_ASSERT( "character is not in allowed character set for names", ([]() {name::char_to_value(char{'{'});}) ); +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_str_len) // ------------------------------- // constexpr uint8_t length()cosnt CHECK_EQUAL( name{""}.length(), 0 ) @@ -109,9 +122,13 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"eosioaccoun"}.length(), 11 ) CHECK_EQUAL( name{"eosioaccount"}.length(), 12 ) CHECK_EQUAL( name{"eosioaccountj"}.length(), 13 ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_6) CHECK_ASSERT( "string is too long to be a valid name", ([]() {name{"12345abcdefghj"}.length();}) ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_suffix) // ---------------------------- // constexpr name suffix()const CHECK_EQUAL( name{".eosioaccounj"}.suffix(), name{"eosioaccounj"} ) @@ -129,7 +146,10 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"e.o.s.i.o.a.c"}.suffix(), name{"c"} ) CHECK_EQUAL( name{"eos.ioa.cco"}.suffix(), name{"cco"} ) +EOSIO_TEST_END + +EOSIO_TEST_BEGIN(name_type_test_prefix) // ---------------------------- // constexpr name prefix()const @@ -153,7 +173,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"a.my.account"}.prefix(), name{"a.my"} ) CHECK_EQUAL( name{"a.my.account"}.prefix().prefix(), name{"a"} ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_raw_1) // ----------------------------- // constexpr operator raw()const CHECK_EQUAL( name{"1"}.operator name::raw(), static_cast(576460752303423488ULL) ) @@ -169,7 +191,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"123."}.operator name::raw(), static_cast(614178399182651392ULL) ) CHECK_EQUAL( name{"123........."}.operator name::raw(), static_cast(614178399182651392ULL) ) CHECK_EQUAL( name{".a.b.c.1.2.3."}.operator name::raw(), static_cast(108209673814966320ULL) ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_raw_2) CHECK_EQUAL( name{"abc.123"}.operator name::raw(), static_cast(3589369488740450304ULL) ) CHECK_EQUAL( name{"123.abc"}.operator name::raw(), static_cast(614181822271586304ULL) ) @@ -181,7 +205,10 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"555555555555j"}.operator name::raw(), static_cast(2975281302211218015ULL) ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"}.operator name::raw(), static_cast(3570337562653461615ULL) ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"}.operator name::raw(), static_cast(u64max) ) +EOSIO_TEST_END + +EOSIO_TEST_BEGIN(name_type_test_op_bool) // --------------------------------------- // constexpr explicit operator bool()const // Note that I must be explicit about calling the operator because it is defined as `explicit` @@ -194,10 +221,12 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"1"}.operator bool(), true ) CHECK_EQUAL( !name{""}.operator bool(), true ) CHECK_EQUAL( !name{"1"}.operator bool(), false ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_memcmp_1) // ---------------------------------------- // char* write_as_string(char*, char*)const - static constexpr uint8_t buffer_size{32}; + constexpr uint8_t buffer_size{32}; char buffer[buffer_size]{}; string str{"1"}; @@ -214,6 +243,13 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) name{str = "123"}.write_as_string( buffer, buffer + sizeof(buffer) ); CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) +EOSIO_TEST_END + + +EOSIO_TEST_BEGIN(name_type_test_memcmp_2) + static constexpr uint8_t buffer_size{32}; + char buffer[buffer_size]{}; + string str{}; // Note: // Any '.' characters at the end of a name are ignored @@ -232,6 +268,12 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) name{str = "123.abc"}.write_as_string( buffer, buffer + sizeof(buffer) ); CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) +EOSIO_TEST_END + +EOSIO_TEST_BEGIN(name_type_test_memcmp_3) + static constexpr uint8_t buffer_size{32}; + char buffer[buffer_size]{}; + string str{}; name{str = "12345abcdefgj"}.write_as_string( buffer, buffer + sizeof(buffer) ); CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) @@ -248,7 +290,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) name{str = "zzzzzzzzzzzzj"}.write_as_string( buffer, buffer + sizeof(buffer) ); CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_to_str) // ----------------------- // string to_string()const CHECK_EQUAL( name{"1"}.to_string(), "1" ) @@ -276,7 +320,10 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"555555555555j"}.to_string(), "555555555555j" ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"}.to_string(), "aaaaaaaaaaaaj" ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"}.to_string(), "zzzzzzzzzzzzj" ) +EOSIO_TEST_END + +EOSIO_TEST_BEGIN(name_type_test_equal_1) // ---------------------------------------------------------- // friend constexpr bool operator==(const name&, const name&) CHECK_EQUAL( name{"1"} == name{"1"}, true ) @@ -292,7 +339,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"123."} == name{"123"}, true ) CHECK_EQUAL( name{"123........."} == name{"123"}, true ) CHECK_EQUAL( name{".a.b.c.1.2.3."} == name{".a.b.c.1.2.3"}, true ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_equal_2) CHECK_EQUAL( name{"abc.123"} == name{"abc.123"}, true ) CHECK_EQUAL( name{"123.abc"} == name{"123.abc"}, true ) @@ -304,7 +353,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"555555555555j"} == name{"555555555555j"}, true ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"} == name{"aaaaaaaaaaaaj"}, true ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} == name{"zzzzzzzzzzzzj"}, true ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_not_equal_1) // ----------------------------------------------------------- // friend constexpr bool operator!=(const name&, const name&) CHECK_EQUAL( name{"1"} != name{}, true ) @@ -320,7 +371,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"123."} != name{}, true ) CHECK_EQUAL( name{"123........."} != name{}, true ) CHECK_EQUAL( name{".a.b.c.1.2.3."} != name{}, true ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_not_equal_2) CHECK_EQUAL( name{"abc.123"} != name{}, true ) CHECK_EQUAL( name{"123.abc"} != name{}, true ) @@ -332,7 +385,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"555555555555j"} != name{}, true ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"} != name{}, true ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} != name{}, true ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_less_than_1) // --------------------------------------------------------- // friend constexpr bool operator<(const name&, const name&) CHECK_EQUAL( name{} < name{"1"}, true ) @@ -348,7 +403,10 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{} < name{"123."}, true ) CHECK_EQUAL( name{} < name{"123........."}, true ) CHECK_EQUAL( name{} < name{".a.b.c.1.2.3."}, true ) +EOSIO_TEST_END + +EOSIO_TEST_BEGIN(name_type_test_less_than_2) CHECK_EQUAL( name{} < name{"abc.123"}, true ) CHECK_EQUAL( name{} < name{"123.abc"}, true ) @@ -360,7 +418,10 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{} < name{"555555555555j"}, true ) CHECK_EQUAL( name{} < name{"aaaaaaaaaaaaj"}, true ) CHECK_EQUAL( name{} < name{"zzzzzzzzzzzzj"}, true ) +EOSIO_TEST_END + +EOSIO_TEST_BEGIN(name_type_test_op_n_1) // ------------------------------------ // inline constexpr name operator""_n() CHECK_EQUAL( name{}, ""_n ) @@ -378,7 +439,9 @@ EOSIO_TEST_BEGIN(name_type_test) CHECK_EQUAL( name{"123."}, "123."_n ) CHECK_EQUAL( name{"123........."}, "123........."_n ) CHECK_EQUAL( name{".a.b.c.1.2.3."}, ".a.b.c.1.2.3."_n ) +EOSIO_TEST_END +EOSIO_TEST_BEGIN(name_type_test_op_n_2) CHECK_EQUAL( name{"abc.123"}, "abc.123"_n ) CHECK_EQUAL( name{"123.abc"}, "123.abc"_n ) @@ -399,6 +462,30 @@ int main(int argc, char* argv[]) { } silence_output(!verbose); - EOSIO_TEST(name_type_test); + EOSIO_TEST(name_type_test_constructor_num) + EOSIO_TEST(name_type_test_constructor_str_1) + EOSIO_TEST(name_type_test_constructor_str_2) + EOSIO_TEST(name_type_test_str_not_allowed) + EOSIO_TEST(name_type_test_char_to_value) + EOSIO_TEST(name_type_test_allowed_chars) + EOSIO_TEST(name_type_test_str_len) + EOSIO_TEST(name_type_test_suffix) + EOSIO_TEST(name_type_test_prefix) + EOSIO_TEST(name_type_test_raw_1) + EOSIO_TEST(name_type_test_raw_2) + EOSIO_TEST(name_type_test_op_bool) + EOSIO_TEST(name_type_test_memcmp_1) + EOSIO_TEST(name_type_test_memcmp_2) + EOSIO_TEST(name_type_test_memcmp_3) + EOSIO_TEST(name_type_test_to_str) + EOSIO_TEST(name_type_test_equal_1) + EOSIO_TEST(name_type_test_equal_2) + EOSIO_TEST(name_type_test_not_equal_1) + EOSIO_TEST(name_type_test_not_equal_2) + EOSIO_TEST(name_type_test_less_than_1) + EOSIO_TEST(name_type_test_less_than_2) + EOSIO_TEST(name_type_test_op_n_1) + EOSIO_TEST(name_type_test_op_n_2) + return has_failed(); } diff --git a/tests/unit/string_tests1.cpp b/tests/unit/string_tests1.cpp index 351784e80c..4157e605eb 100644 --- a/tests/unit/string_tests1.cpp +++ b/tests/unit/string_tests1.cpp @@ -17,9 +17,9 @@ using eosio::string; //// template //// string(const char (&str)[N]) -EOSIO_TEST_BEGIN(string_test_1) - static const string eostr0{"a"}; - static const string eostr1{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_ctr_literal) + const string eostr0{"a"}; + const string eostr1{"abcdef"}; CHECK_EQUAL( eostr0.size(), 1 ) CHECK_EQUAL( eostr0.capacity(), 1 ) @@ -31,23 +31,23 @@ EOSIO_TEST_BEGIN(string_test_1) EOSIO_TEST_END //// string() -EOSIO_TEST_BEGIN(string_test_2) - static const string eostr{}; +EOSIO_TEST_BEGIN(string_test_ctr_default) + const string eostr{}; CHECK_EQUAL( eostr.size(), 0 ) CHECK_EQUAL( eostr.capacity(), 0 ) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0) EOSIO_TEST_END -//// constexpr string(const char* str, const size_t n) -EOSIO_TEST_BEGIN(string_test_3) - static const char* str0{""}; - static const char* str1{"abc"}; - static const char* str2{"abcdef"}; +//// const string(const char* str, const size_t n) +EOSIO_TEST_BEGIN(string_test_ctr_char_ptr) + const char* str0{""}; + const char* str1{"abc"}; + const char* str2{"abcdef"}; - static const string eostr0(str0, 0); - static const string eostr1(str1, 1); - static const string eostr2(str2, 6); + const string eostr0(str0, 0); + const string eostr1(str1, 1); + const string eostr2(str2, 6); CHECK_EQUAL( eostr0.size(), 0 ) CHECK_EQUAL( eostr0.capacity(), 0 ) @@ -63,10 +63,10 @@ EOSIO_TEST_BEGIN(string_test_3) EOSIO_TEST_END //// string(const size_t n, const char c) -EOSIO_TEST_BEGIN(string_test_4) - static const string eostr0(0, 'c'); - static const string eostr1(1, 'c'); - static const string eostr2(3, 'c'); +EOSIO_TEST_BEGIN(string_test_ctr_char_rep) + const string eostr0(0, 'c'); + const string eostr1(1, 'c'); + const string eostr2(3, 'c'); CHECK_EQUAL( eostr0.size(), 0 ) CHECK_EQUAL( eostr0.capacity(), 0 ) @@ -82,17 +82,17 @@ EOSIO_TEST_BEGIN(string_test_4) EOSIO_TEST_END //// string(const string& str, const size_t pos, const size_t n = string::npos) -EOSIO_TEST_BEGIN(string_test_5) - static const string eostr{"abcdef"}; - static const string eostr0_sub(eostr, 0, 0); - static const string eostr1_sub(eostr, 1, 0); - static const string eostr2_sub(eostr, 0, 1); - static const string eostr3_sub(eostr, 0, 3); - static const string eostr4_sub(eostr, 0, 8); - static const string eostr5_sub(eostr, 0, 7); - static const string eostr6_sub(eostr, 0, 6); - static const string eostr7_sub(eostr, 3, 3); - static const string eostr8_sub(eostr, 3, 2); +EOSIO_TEST_BEGIN(string_test_ctr_str_sub) + const string eostr{"abcdef"}; + const string eostr0_sub(eostr, 0, 0); + const string eostr1_sub(eostr, 1, 0); + const string eostr2_sub(eostr, 0, 1); + const string eostr3_sub(eostr, 0, 3); + const string eostr4_sub(eostr, 0, 8); + const string eostr5_sub(eostr, 0, 7); + const string eostr6_sub(eostr, 0, 6); + const string eostr7_sub(eostr, 3, 3); + const string eostr8_sub(eostr, 3, 2); CHECK_EQUAL( eostr0_sub.size(), 0 ) CHECK_EQUAL( eostr0_sub.capacity(), 0 ) @@ -131,14 +131,14 @@ EOSIO_TEST_BEGIN(string_test_5) CHECK_EQUAL( strcmp(eostr8_sub.c_str(), "de"), 0) EOSIO_TEST_END -//// constexpr string(const string& str) -EOSIO_TEST_BEGIN(string_test_6) - static const string eostr0{""}; - static const string eostr1{"a"}; - static const string eostr2{"abcdef"}; - static const string eostr0_cpy{eostr0}; - static const string eostr1_cpy{eostr1}; - static const string eostr2_cpy{eostr2}; +//// const string(const string& str) +EOSIO_TEST_BEGIN(string_test_ctr_cpy) + const string eostr0{""}; + const string eostr1{"a"}; + const string eostr2{"abcdef"}; + const string eostr0_cpy{eostr0}; + const string eostr1_cpy{eostr1}; + const string eostr2_cpy{eostr2}; CHECK_EQUAL( eostr0_cpy.size(), 0 ) CHECK_EQUAL( eostr0_cpy.capacity(), 0 ) @@ -153,7 +153,7 @@ EOSIO_TEST_BEGIN(string_test_6) CHECK_EQUAL( strcmp(eostr2_cpy.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_7) +EOSIO_TEST_BEGIN(string_test_op_plus) static string eostr0{""}; eostr0 += "a"; static string eostr1{"abc"}; @@ -170,14 +170,14 @@ EOSIO_TEST_BEGIN(string_test_7) CHECK_EQUAL( strcmp(eostr1_cpy.c_str(), "abcdef"), 0) EOSIO_TEST_END -//// constexpr string(const string&& str) -EOSIO_TEST_BEGIN(string_test_8) - static string eostr0{""}; - static string eostr1{"a"}; - static string eostr2{"abcdef"}; - static const string eostr0_mv{move(eostr0)}; - static const string eostr1_mv{move(eostr1)}; - static const string eostr2_mv{move(eostr2)}; +//// const string(const string&& str) +EOSIO_TEST_BEGIN(string_test_ctr_move) + const string eostr0{""}; + const string eostr1{"a"}; + const string eostr2{"abcdef"}; + const string eostr0_mv{move(eostr0)}; + const string eostr1_mv{move(eostr1)}; + const string eostr2_mv{move(eostr2)}; CHECK_EQUAL( eostr0_mv.size(), 0 ) CHECK_EQUAL( eostr0_mv.capacity(), 0 ) @@ -192,13 +192,13 @@ EOSIO_TEST_BEGIN(string_test_8) CHECK_EQUAL( strcmp(eostr2.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_9) - static string eostr0{""}; +EOSIO_TEST_BEGIN(string_test_op_plus_ctr_move) + string eostr0{""}; eostr0 += "a"; - static string eostr1{"abc"}; + string eostr1{"abc"}; eostr1 += "def"; - static string eostr0_cpy{move(eostr0)}; - static string eostr1_cpy{move(eostr1)}; + string eostr0_cpy{move(eostr0)}; + string eostr1_cpy{move(eostr1)}; CHECK_EQUAL( eostr0_cpy.size(), 1 ) CHECK_EQUAL( eostr0_cpy.capacity(), 2 ) @@ -210,13 +210,13 @@ EOSIO_TEST_BEGIN(string_test_9) EOSIO_TEST_END //// string& operator=(const string& str); -EOSIO_TEST_BEGIN(string_test_10) - static const string eostr0{""}; - static const string eostr1{"a"}; - static const string eostr2{"abcdef"}; - static string eostr0_cpy_assig{}; - static string eostr1_cpy_assig{}; - static string eostr2_cpy_assig{}; +EOSIO_TEST_BEGIN(string_test_op_assign_1) + const string eostr0{""}; + const string eostr1{"a"}; + const string eostr2{"abcdef"}; + string eostr0_cpy_assig{}; + string eostr1_cpy_assig{}; + string eostr2_cpy_assig{}; eostr0_cpy_assig = eostr0; eostr1_cpy_assig = eostr1; eostr2_cpy_assig = eostr2; @@ -234,13 +234,13 @@ EOSIO_TEST_BEGIN(string_test_10) CHECK_EQUAL( strcmp(eostr2_cpy_assig.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_11) - static string eostr0{""}; +EOSIO_TEST_BEGIN(string_test_op_plus_op_assign) + string eostr0{""}; eostr0 += "a"; - static string eostr1{"abc"}; + string eostr1{"abc"}; eostr1 += "def"; - static string eostr0_cpy_assig{}; - static string eostr1_cpy_assig{}; + string eostr0_cpy_assig{}; + string eostr1_cpy_assig{}; eostr0_cpy_assig = eostr0; eostr1_cpy_assig = eostr1; @@ -254,13 +254,13 @@ EOSIO_TEST_BEGIN(string_test_11) EOSIO_TEST_END //// string& operator=(string&& str) -EOSIO_TEST_BEGIN(string_test_12) - static string eostr0{""}; - static string eostr1{"a"}; - static string eostr2{"abcdef"}; - static string eostr0_mv_assig{}; - static string eostr1_mv_assig{}; - static string eostr2_mv_assig{}; +EOSIO_TEST_BEGIN(string_test_move_assign) + string eostr0{""}; + string eostr1{"a"}; + string eostr2{"abcdef"}; + string eostr0_mv_assig{}; + string eostr1_mv_assig{}; + string eostr2_mv_assig{}; eostr0_mv_assig = move(eostr0); eostr1_mv_assig = move(eostr1); eostr2_mv_assig = move(eostr2); @@ -278,13 +278,13 @@ EOSIO_TEST_BEGIN(string_test_12) CHECK_EQUAL( strcmp(eostr2_mv_assig.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_13) - static string eostr0{""}; +EOSIO_TEST_BEGIN(string_test_op_plus_move_assign) + string eostr0{""}; eostr0 += "a"; - static string eostr1{"abc"}; + string eostr1{"abc"}; eostr1 += "def"; - static string eostr0_mv_assig{}; - static string eostr1_mv_assig{}; + string eostr0_mv_assig{}; + string eostr1_mv_assig{}; eostr0_mv_assig = move(eostr0); eostr1_mv_assig = move(eostr1); @@ -298,8 +298,8 @@ EOSIO_TEST_BEGIN(string_test_13) EOSIO_TEST_END //// string& operator=(const char* str) -EOSIO_TEST_BEGIN(string_test_14) - static string eostr{}; +EOSIO_TEST_BEGIN(string_test_op_assign_2) + string eostr{}; eostr = "abcdef"; CHECK_EQUAL( eostr.size(), 6 ) @@ -312,8 +312,8 @@ EOSIO_TEST_BEGIN(string_test_14) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_15) - static string eostr{}; +EOSIO_TEST_BEGIN(string_test_op_assign_op_plus) + string eostr{}; eostr = ""; eostr += "abcdef"; @@ -328,46 +328,46 @@ EOSIO_TEST_BEGIN(string_test_15) EOSIO_TEST_END //// char& operator[](const size_t n) -EOSIO_TEST_BEGIN(string_test_16) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_pos_char_eq) + string eostr{"abcdef"}; CHECK_EQUAL( eostr[0], 'a' ) CHECK_EQUAL( eostr[5], 'f' ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_17) - static string eostr{"abc"}; +EOSIO_TEST_BEGIN(string_test_pos_char_eq_op_plus) + string eostr{"abc"}; eostr += "def"; CHECK_EQUAL( eostr[0], 'a' ) CHECK_EQUAL( eostr[5], 'f' ) EOSIO_TEST_END //// const char& operator[](const size_t n) const -EOSIO_TEST_BEGIN(string_test_18) - static const string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_pos_char_eq_ctr_literal) + const string eostr{"abcdef"}; CHECK_EQUAL( eostr[0], 'a' ) CHECK_EQUAL( eostr[5], 'f' ) EOSIO_TEST_END //// char& at(const size_t n) -EOSIO_TEST_BEGIN(string_test_19) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_1) + string eostr{"abcdef"}; CHECK_EQUAL( eostr.at(0), 'a' ) CHECK_EQUAL( eostr.at(5), 'f' ) - CHECK_ASSERT( "eosio::string::at", []() {eostr.at(6);} ) + CHECK_ASSERT( "eosio::string::at", [&]() {eostr.at(6);} ) EOSIO_TEST_END //// const char& at(const size_t n) const -EOSIO_TEST_BEGIN(string_test_20) - static const string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_2) + const string eostr{"abcdef"}; CHECK_EQUAL( eostr.at(0), 'a' ) CHECK_EQUAL( eostr.at(5), 'f' ) - CHECK_ASSERT( "eosio::string::at const", []() {eostr.at(6);} ) + CHECK_ASSERT( "eosio::string::at const", [&]() {eostr.at(6);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_21) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_3) + string eostr{""}; eostr += "abcdef"; const char c0{eostr.at(0)}; const char c1{eostr.at(5)}; @@ -376,35 +376,35 @@ EOSIO_TEST_BEGIN(string_test_21) EOSIO_TEST_END //// char& front() -EOSIO_TEST_BEGIN(string_test_22) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_front_1) + const string eostr{"abcdef"}; CHECK_EQUAL( eostr.front(), 'a' ) - static string empty_str; + const string empty_str; CHECK_EQUAL( eostr.front(), 'a' ) EOSIO_TEST_END //// const char& front() const -EOSIO_TEST_BEGIN(string_test_23) +EOSIO_TEST_BEGIN(string_test_front_2) static const string eostr{"abcdef"}; CHECK_EQUAL( eostr.front(), 'a' ) EOSIO_TEST_END //// char& back() -EOSIO_TEST_BEGIN(string_test_24) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_back_1) + const string eostr{"abcdef"}; CHECK_EQUAL( eostr.back(), 'f' ) EOSIO_TEST_END //// const char& back() const -EOSIO_TEST_BEGIN(string_test_25) - static const string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_back_2) + const string eostr{"abcdef"}; CHECK_EQUAL( eostr.back(), 'f' ) EOSIO_TEST_END //// char* data() -EOSIO_TEST_BEGIN(string_test_26) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_data_1) + string eostr{"abcdef"}; CHECK_EQUAL( strcmp(eostr.data(), "abcdef"), 0 ) eostr = "abc"; @@ -412,36 +412,36 @@ EOSIO_TEST_BEGIN(string_test_26) EOSIO_TEST_END //// const char* data() const -EOSIO_TEST_BEGIN(string_test_27) - static const string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_data_2) + const string eostr{"abcdef"}; CHECK_EQUAL( strcmp(eostr.data(), "abcdef"), 0 ) EOSIO_TEST_END //// const char* c_str() const -EOSIO_TEST_BEGIN(string_test_28) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_null_term_1) + const string eostr{"abcdef"}; CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) CHECK_EQUAL( eostr.c_str()[eostr.size()], '\0' ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_29) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_null_term_2) + string eostr{""}; eostr += "abcdef"; CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) CHECK_EQUAL( eostr.c_str()[eostr.size()], '\0' ) EOSIO_TEST_END //// char* begin() -EOSIO_TEST_BEGIN(string_test_30) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_iter_begin_1) + string eostr{"abcdef"}; char* iter{eostr.begin()}; CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) CHECK_EQUAL( strcmp(eostr.c_str(), iter), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_31) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_iter_begin_2) + string eostr{""}; eostr += "abcdef"; char* iter{eostr.begin()}; CHECK_EQUAL( eostr.size(), 6 ) @@ -450,8 +450,8 @@ EOSIO_TEST_BEGIN(string_test_31) EOSIO_TEST_END //// const char* cbegin() const -EOSIO_TEST_BEGIN(string_test_32) - static const string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_iter_cbegin) + string eostr{"abcdef"}; const char* iter{eostr.cbegin()}; CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 6 ) @@ -459,16 +459,16 @@ EOSIO_TEST_BEGIN(string_test_32) EOSIO_TEST_END //// char* end() -EOSIO_TEST_BEGIN(string_test_33) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_iter_end_1) + string eostr{"abcdef"}; char* iter{eostr.end()}; CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) CHECK_EQUAL( strcmp(eostr.c_str()+eostr.size(), iter), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_34) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_iter_end_2) + string eostr{""}; eostr += "abcdef"; char* iter{eostr.end()}; CHECK_EQUAL( eostr.size(), 6 ) @@ -477,8 +477,8 @@ EOSIO_TEST_BEGIN(string_test_34) EOSIO_TEST_END //// const char* cend() const -EOSIO_TEST_BEGIN(string_test_35) - static const string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_iter_cend) + string eostr{"abcdef"}; const char* iter{eostr.cend()}; CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 6 ) @@ -486,32 +486,32 @@ EOSIO_TEST_BEGIN(string_test_35) EOSIO_TEST_END //// bool string::empty() const -EOSIO_TEST_BEGIN(string_test_36) - static string eostr{}; +EOSIO_TEST_BEGIN(string_test_empty) + string eostr{}; CHECK_EQUAL( eostr.empty(), true ) eostr += 'c'; CHECK_EQUAL( eostr.empty(), false ) EOSIO_TEST_END //// size_t string::size() const -EOSIO_TEST_BEGIN(string_test_37) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_op_plus_char) + string eostr{"abcdef"}; CHECK_EQUAL( eostr.size(), 6 ) eostr += 'g'; CHECK_EQUAL( eostr.size(), 7 ) EOSIO_TEST_END //// size_t string::length() const -EOSIO_TEST_BEGIN(string_test_38) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_length) + string eostr{"abcdef"}; CHECK_EQUAL( eostr.length(), 6 ) eostr += 'g'; CHECK_EQUAL( eostr.length(), 7 ) EOSIO_TEST_END //// size_t string::capacity() const -EOSIO_TEST_BEGIN(string_test_39) - static string eostr{"abc"}; +EOSIO_TEST_BEGIN(string_test_capacity) + string eostr{"abc"}; CHECK_EQUAL( eostr.capacity(), 3 ) eostr += 'd', eostr += 'e', eostr += 'f'; CHECK_EQUAL( eostr.capacity(), 8 ) @@ -520,14 +520,14 @@ EOSIO_TEST_BEGIN(string_test_39) EOSIO_TEST_END //// size_t string::max_size() const -EOSIO_TEST_BEGIN(string_test_40) - static const string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_max_size) + const string eostr{"abcdef"}; CHECK_EQUAL( eostr.max_size(), string::npos ) EOSIO_TEST_END //// void reserve(const size_t n) -EOSIO_TEST_BEGIN(string_test_41) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_reserve_1) + string eostr{"abcdef"}; CHECK_EQUAL( eostr.capacity(), 6 ) eostr.reserve(10); CHECK_EQUAL( eostr.capacity(), 10 ) @@ -537,8 +537,8 @@ EOSIO_TEST_BEGIN(string_test_41) CHECK_EQUAL( eostr.capacity(), 24 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_42) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_reserve_2) + string eostr{""}; eostr += "abcdef"; CHECK_EQUAL( eostr.capacity(), 12 ) eostr.reserve(10); @@ -550,10 +550,10 @@ EOSIO_TEST_BEGIN(string_test_42) EOSIO_TEST_END //// void string::shrink_to_fit() const -EOSIO_TEST_BEGIN(string_test_43) - static string eostr0{}; - static string eostr1{"a"}; - static string eostr2{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_shrink_to_fit) + string eostr0{}; + string eostr1{"a"}; + string eostr2{"abcdef"}; CHECK_EQUAL( eostr0.capacity(), 0 ) eostr0.reserve(100); @@ -575,8 +575,8 @@ EOSIO_TEST_BEGIN(string_test_43) EOSIO_TEST_END //// void string::clear() -EOSIO_TEST_BEGIN(string_test_44) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_clear_1) + string eostr{"abcdef"}; CHECK_EQUAL( eostr.empty(), false ) eostr.clear(); CHECK_EQUAL( eostr.empty(), true ) @@ -584,8 +584,8 @@ EOSIO_TEST_BEGIN(string_test_44) CHECK_EQUAL( eostr.data()[0], '\0' ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_45) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_clear_2) + string eostr{""}; eostr += "abcdef"; CHECK_EQUAL( eostr.empty(), false ) eostr.clear(); @@ -595,8 +595,8 @@ EOSIO_TEST_BEGIN(string_test_45) EOSIO_TEST_END //// void resize(size_t n) -EOSIO_TEST_BEGIN(string_test_46) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_resize_1) + string eostr{"abcdef"}; eostr.resize(3); CHECK_EQUAL( eostr.size(), 3 ) @@ -614,8 +614,8 @@ EOSIO_TEST_BEGIN(string_test_46) CHECK_EQUAL( strcmp(eostr.c_str(), "abc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_47) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_resize_2) + string eostr{""}; eostr += "abcdef"; eostr.resize(3); @@ -635,9 +635,9 @@ EOSIO_TEST_BEGIN(string_test_47) EOSIO_TEST_END //// void swap(string& str) -EOSIO_TEST_BEGIN(string_test_48) - static string eostr_swap0{"abc"}; - static string eostr_swap1{"123456"}; +EOSIO_TEST_BEGIN(string_test_swap) + string eostr_swap0{"abc"}; + string eostr_swap1{"123456"}; eostr_swap0.swap(eostr_swap1); @@ -651,8 +651,8 @@ EOSIO_TEST_BEGIN(string_test_48) EOSIO_TEST_END //// void push_back(char c) -EOSIO_TEST_BEGIN(string_test_49) - static string eostr{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_push_back) + string eostr{"abcdef"}; CHECK_EQUAL( eostr.size(), 6 ) eostr.push_back('g'); CHECK_EQUAL( eostr.size(), 7 ) @@ -661,16 +661,16 @@ EOSIO_TEST_BEGIN(string_test_49) EOSIO_TEST_END //// void pop_back() -EOSIO_TEST_BEGIN(string_test_50) - static string eostr{"abcdefg"}; +EOSIO_TEST_BEGIN(string_test_pop_back_1) + string eostr{"abcdefg"}; CHECK_EQUAL( eostr.size(), 7 ) eostr.pop_back(); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_51) - static string eostr{"abc"}; +EOSIO_TEST_BEGIN(string_test_pop_back_2) + string eostr{"abc"}; CHECK_EQUAL( eostr.size(), 3 ) eostr.pop_back(); eostr.pop_back(); @@ -684,7 +684,7 @@ EOSIO_TEST_BEGIN(string_test_51) EOSIO_TEST_END //// string substr(size_t pos = 0, size_t len = npos) const -EOSIO_TEST_BEGIN(string_test_52) +EOSIO_TEST_BEGIN(string_test_substr_1) static const string eostr{"abcdef"}; CHECK_EQUAL( strcmp(eostr.substr(0).c_str(), "abcdef"), 0 ) CHECK_EQUAL( strcmp(eostr.substr(0,0).c_str(), ""), 0 ) @@ -704,8 +704,8 @@ EOSIO_TEST_BEGIN(string_test_52) CHECK_EQUAL( strcmp(eostr.substr(1,6).c_str(), "bcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_53) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_substr_2) + string eostr{""}; eostr += "abcdef"; CHECK_EQUAL( strcmp(eostr.substr(0).c_str(), "abcdef"), 0 ) CHECK_EQUAL( strcmp(eostr.substr(0,0).c_str(), ""), 0 ) @@ -726,9 +726,9 @@ EOSIO_TEST_BEGIN(string_test_53) EOSIO_TEST_END //// size_t copy(char* dest, size_t len, size_t pos = 0) const -EOSIO_TEST_BEGIN(string_test_54) - static const string eostr{"abcdef"}; - static char str[7]{}; +EOSIO_TEST_BEGIN(string_test_copy_1) + const string eostr{"abcdef"}; + char str[7]{}; CHECK_EQUAL( eostr.copy(str, 0), 0 ) CHECK_EQUAL( strcmp(str, ""), 0 ) @@ -758,10 +758,10 @@ EOSIO_TEST_BEGIN(string_test_54) CHECK_EQUAL( strcmp(str, ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_55) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_copy_2) + string eostr{""}; eostr += "abcdef"; - static char str[7]{}; + char str[7]{}; CHECK_EQUAL( eostr.copy(str, 0), 0 ) CHECK_EQUAL( strcmp(str, ""), 0 ) @@ -791,69 +791,69 @@ EOSIO_TEST_BEGIN(string_test_55) CHECK_EQUAL( strcmp(str, ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_56) - static const string eostr{"abcdef"}; - static char str[7]{}; - CHECK_ASSERT( "eosio::string::copy", []() {eostr.copy(str, 1, eostr.size()+1);} ) +EOSIO_TEST_BEGIN(string_test_copy_3) + const string eostr{"abcdef"}; + char str[7]{}; + CHECK_ASSERT( "eosio::string::copy", [&]() {eostr.copy(str, 1, eostr.size()+1);} ) EOSIO_TEST_END //// string& insert(const size_t pos, const char* str) -EOSIO_TEST_BEGIN(string_test_57) - static string eostr{"iii"}; - static const char* str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_1) + string eostr{"iii"}; + const char* str{"ooo"}; eostr.insert(0, str); CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_58) - static string eostr{"iii"}; - static const char* str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_2) + string eostr{"iii"}; + const char* str{"ooo"}; eostr.insert(1, str); CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_59) - static string eostr{"iii"}; - static const char* str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_3) + string eostr{"iii"}; + const char* str{"ooo"}; eostr.insert(2, str); CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_60) - static string eostr{"iii"}; - static const char* str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_4) + string eostr{"iii"}; + const char* str{"ooo"}; eostr.insert(3, str); CHECK_EQUAL( strcmp(eostr.c_str(), "iiiooo"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_61) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_5) + string eostr{""}; eostr += "iii"; - static const char* str{"ooo"}; + const char* str{"ooo"}; eostr.insert(0, str); CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_62) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_6) + string eostr{""}; eostr += "iii"; - static const char* str{"ooo"}; + const char* str{"ooo"}; eostr.insert(1, str); CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_63) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_7) + string eostr{""}; eostr += "iii"; - static const char* str{"ooo"}; + const char* str{"ooo"}; eostr.insert(2, str); CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_64) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_8) + string eostr{""}; eostr += "iii"; - static const char* str{"ooo"}; + const char* str{"ooo"}; eostr.insert(3, str); CHECK_EQUAL( strcmp(eostr.c_str(), "iiiooo"), 0 ) EOSIO_TEST_END @@ -865,69 +865,70 @@ int main(int argc, char* argv[]) { } silence_output(!verbose); - EOSIO_TEST(string_test_1) - EOSIO_TEST(string_test_2) - EOSIO_TEST(string_test_3) - EOSIO_TEST(string_test_4) - EOSIO_TEST(string_test_5) - EOSIO_TEST(string_test_6) - EOSIO_TEST(string_test_7) - EOSIO_TEST(string_test_8) - EOSIO_TEST(string_test_9) - EOSIO_TEST(string_test_10) - EOSIO_TEST(string_test_11) - EOSIO_TEST(string_test_12) - EOSIO_TEST(string_test_13) - EOSIO_TEST(string_test_14) - EOSIO_TEST(string_test_15) - EOSIO_TEST(string_test_16) - EOSIO_TEST(string_test_17) - EOSIO_TEST(string_test_18) - EOSIO_TEST(string_test_19) - EOSIO_TEST(string_test_20) - EOSIO_TEST(string_test_21) - EOSIO_TEST(string_test_22) - EOSIO_TEST(string_test_23) - EOSIO_TEST(string_test_24) - EOSIO_TEST(string_test_25) - EOSIO_TEST(string_test_26) - EOSIO_TEST(string_test_27) - EOSIO_TEST(string_test_28) - EOSIO_TEST(string_test_29) - EOSIO_TEST(string_test_30) - EOSIO_TEST(string_test_31) - EOSIO_TEST(string_test_32) - EOSIO_TEST(string_test_33) - EOSIO_TEST(string_test_34) - EOSIO_TEST(string_test_35) - EOSIO_TEST(string_test_36) - EOSIO_TEST(string_test_37) - EOSIO_TEST(string_test_38) - EOSIO_TEST(string_test_39) - EOSIO_TEST(string_test_40) - EOSIO_TEST(string_test_41) - EOSIO_TEST(string_test_42) - EOSIO_TEST(string_test_43) - EOSIO_TEST(string_test_44) - EOSIO_TEST(string_test_45) - EOSIO_TEST(string_test_46) - EOSIO_TEST(string_test_47) - EOSIO_TEST(string_test_48) - EOSIO_TEST(string_test_49) - EOSIO_TEST(string_test_50) - EOSIO_TEST(string_test_51) - EOSIO_TEST(string_test_52) - EOSIO_TEST(string_test_53) - EOSIO_TEST(string_test_54) - EOSIO_TEST(string_test_55) - EOSIO_TEST(string_test_56) - EOSIO_TEST(string_test_57) - EOSIO_TEST(string_test_58) - EOSIO_TEST(string_test_59) - EOSIO_TEST(string_test_60) - EOSIO_TEST(string_test_61) - EOSIO_TEST(string_test_62) - EOSIO_TEST(string_test_63) - EOSIO_TEST(string_test_64) + EOSIO_TEST(string_test_ctr_literal) + EOSIO_TEST(string_test_ctr_default) + EOSIO_TEST(string_test_ctr_char_ptr) + EOSIO_TEST(string_test_ctr_char_rep) + EOSIO_TEST(string_test_ctr_str_sub) + EOSIO_TEST(string_test_ctr_cpy) + EOSIO_TEST(string_test_op_plus) + EOSIO_TEST(string_test_ctr_move) + EOSIO_TEST(string_test_op_plus_ctr_move) + EOSIO_TEST(string_test_op_assign_1) + EOSIO_TEST(string_test_op_plus_op_assign) + EOSIO_TEST(string_test_move_assign) + EOSIO_TEST(string_test_op_plus_move_assign) + EOSIO_TEST(string_test_op_assign_2) + EOSIO_TEST(string_test_op_assign_op_plus) + EOSIO_TEST(string_test_pos_char_eq) + EOSIO_TEST(string_test_pos_char_eq_op_plus) + EOSIO_TEST(string_test_pos_char_eq_ctr_literal) + EOSIO_TEST(string_test_pos_char_eq_at_1) + EOSIO_TEST(string_test_pos_char_eq_at_2) + EOSIO_TEST(string_test_pos_char_eq_at_3) + EOSIO_TEST(string_test_front_1) + EOSIO_TEST(string_test_front_2) + EOSIO_TEST(string_test_back_1) + EOSIO_TEST(string_test_back_2) + EOSIO_TEST(string_test_data_1) + EOSIO_TEST(string_test_data_2) + EOSIO_TEST(string_test_null_term_1) + EOSIO_TEST(string_test_null_term_2) + EOSIO_TEST(string_test_iter_begin_1) + EOSIO_TEST(string_test_iter_begin_2) + EOSIO_TEST(string_test_iter_cbegin) + EOSIO_TEST(string_test_iter_end_1) + EOSIO_TEST(string_test_iter_end_2) + EOSIO_TEST(string_test_iter_cend) + EOSIO_TEST(string_test_empty) + EOSIO_TEST(string_test_op_plus_char) + EOSIO_TEST(string_test_length) + EOSIO_TEST(string_test_capacity) + EOSIO_TEST(string_test_max_size) + EOSIO_TEST(string_test_reserve_1) + EOSIO_TEST(string_test_reserve_2) + EOSIO_TEST(string_test_shrink_to_fit) + EOSIO_TEST(string_test_clear_1) + EOSIO_TEST(string_test_clear_2) + EOSIO_TEST(string_test_resize_1) + EOSIO_TEST(string_test_resize_2) + EOSIO_TEST(string_test_swap) + EOSIO_TEST(string_test_push_back) + EOSIO_TEST(string_test_pop_back_1) + EOSIO_TEST(string_test_pop_back_2) + EOSIO_TEST(string_test_substr_1) + EOSIO_TEST(string_test_substr_2) + EOSIO_TEST(string_test_copy_1) + EOSIO_TEST(string_test_copy_2) + EOSIO_TEST(string_test_copy_3) + EOSIO_TEST(string_test_insert_1) + EOSIO_TEST(string_test_insert_2) + EOSIO_TEST(string_test_insert_3) + EOSIO_TEST(string_test_insert_4) + EOSIO_TEST(string_test_insert_5) + EOSIO_TEST(string_test_insert_6) + EOSIO_TEST(string_test_insert_7) + EOSIO_TEST(string_test_insert_8) + return has_failed(); } diff --git a/tests/unit/string_tests2.cpp b/tests/unit/string_tests2.cpp index cd75b80b8d..ccb5369ff8 100644 --- a/tests/unit/string_tests2.cpp +++ b/tests/unit/string_tests2.cpp @@ -15,86 +15,86 @@ using eosio::string; // Definitions found in `eosio.cdt/libraries/eosiolib/core/eosio/string.hpp` -EOSIO_TEST_BEGIN(string_test_65) - static string eostr{"abcdefg"}; - static const char* null_man{nullptr}; - CHECK_ASSERT( "eosio::string::insert", []() {eostr.insert(0, null_man, 1);} ) - CHECK_ASSERT( "eosio::string::insert", []() {eostr.insert(-1, "ooo", 1);} ) +EOSIO_TEST_BEGIN(string_test_insert_null) + string eostr{"abcdefg"}; + const char* null_man{nullptr}; + CHECK_ASSERT( "eosio::string::insert", [&]() {eostr.insert(0, null_man, 1);} ) + CHECK_ASSERT( "eosio::string::insert", [&]() {eostr.insert(-1, "ooo", 1);} ) EOSIO_TEST_END //// string& insert(const size_t pos, const string& str) -EOSIO_TEST_BEGIN(string_test_66) - static string eostr{}; - static const string str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_to_blank) + string eostr{}; + const string str{"ooo"}; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 3 ) CHECK_EQUAL( eostr.capacity(), 6 ) CHECK_EQUAL( strcmp(eostr.c_str(), "ooo"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_67) - static string eostr{"abc"}; - static const string str{"d"}; +EOSIO_TEST_BEGIN(string_test_insert_at_beginning_single) + string eostr{"abc"}; + const string str{"d"}; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 4 ) CHECK_EQUAL( eostr.capacity(), 8 ) CHECK_EQUAL( strcmp(eostr.c_str(), "dabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_68) - static string eostr{"abc"}; - static const string str{"def"}; +EOSIO_TEST_BEGIN(string_test_insert_at_beginning_multiple_1) + string eostr{"abc"}; + const string str{"def"}; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) CHECK_EQUAL( strcmp(eostr.c_str(), "defabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_69) - static string eostr{"iii"}; - static const string str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_at_beginning_multiple_2) + string eostr{"iii"}; + const string str{"ooo"}; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_70) - static string eostr{"iii"}; - static const string str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_in_middle_1) + string eostr{"iii"}; + const string str{"ooo"}; eostr.insert(1, str); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_71) - static string eostr{"iii"}; - static const string str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_in_middle_2) + string eostr{"iii"}; + const string str{"ooo"}; eostr.insert(2, str); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_72) - static string eostr{"iii"}; - static const string str{"ooo"}; +EOSIO_TEST_BEGIN(string_test_insert_at_end) + string eostr{"iii"}; + const string str{"ooo"}; eostr.insert(3, str); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) CHECK_EQUAL( strcmp(eostr.c_str(), "iiiooo") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_73) - static string eostr{"abcdefg"}; - static const string str{"ooo"}; - CHECK_ASSERT( "eosio::string::insert", []() {eostr.insert(-1, str);} ) +EOSIO_TEST_BEGIN(string_test_insert_neg_index_1) + string eostr{"abcdefg"}; + const string str{"ooo"}; + CHECK_ASSERT( "eosio::string::insert", [&]() {eostr.insert(-1, str);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_74) - static string eostr{""}; - static string str{""}; +EOSIO_TEST_BEGIN(string_test_insert_op_plus_1) + string eostr{""}; + string str{""}; str += "ooo"; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 3 ) @@ -102,10 +102,10 @@ EOSIO_TEST_BEGIN(string_test_74) CHECK_EQUAL( strcmp(eostr.c_str(), "ooo"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_75) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_op_plus_2) + string eostr{""}; eostr += "abc"; - static string str{""}; + string str{""}; str += "d"; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 4 ) @@ -113,10 +113,10 @@ EOSIO_TEST_BEGIN(string_test_75) CHECK_EQUAL( strcmp(eostr.c_str(), "dabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_76) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_op_plus_3) + string eostr{""}; eostr += "abc"; - static string str{""}; + string str{""}; str += "def"; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 6 ) @@ -124,10 +124,10 @@ EOSIO_TEST_BEGIN(string_test_76) CHECK_EQUAL( strcmp(eostr.c_str(), "defabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_77) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_op_plus_4) + string eostr{""}; eostr += "iii"; - static string str{""}; + string str{""}; str += "ooo"; eostr.insert(0, str); CHECK_EQUAL( eostr.size(), 6 ) @@ -135,10 +135,10 @@ EOSIO_TEST_BEGIN(string_test_77) CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_78) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_op_plus_5) + string eostr{""}; eostr += "iii"; - static string str{""}; + string str{""}; str += "ooo"; eostr.insert(1, str); CHECK_EQUAL( eostr.size(), 6 ) @@ -146,10 +146,10 @@ EOSIO_TEST_BEGIN(string_test_78) CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_79) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_op_plus_6) + string eostr{""}; eostr += "iii"; - static string str{""}; + string str{""}; str += "ooo"; eostr.insert(2, str); CHECK_EQUAL( eostr.size(), 6 ) @@ -157,10 +157,10 @@ EOSIO_TEST_BEGIN(string_test_79) CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_80) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_insert_op_plus_7) + string eostr{""}; eostr += "iii"; - static string str{""}; + string str{""}; str += "ooo"; eostr.insert(3, str); CHECK_EQUAL( eostr.size(), 6 ) @@ -168,14 +168,14 @@ EOSIO_TEST_BEGIN(string_test_80) CHECK_EQUAL( strcmp(eostr.c_str(), "iiiooo") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_81) - static string eostr{"abcdefg"}; - static string str{"ooo"}; - CHECK_ASSERT( "eosio::string::insert", []() {eostr.insert(-1, str);} ) +EOSIO_TEST_BEGIN(string_test_insert_neg_index_2) + string eostr{"abcdefg"}; + string str{"ooo"}; + CHECK_ASSERT( "eosio::string::insert", [&]() {eostr.insert(-1, str);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_82) - static string eostr = "hello"; +EOSIO_TEST_BEGIN(string_test_insert_capacity) + string eostr = "hello"; eostr.insert(0, "0", 1); /// `_capacity` is now 12; `_begin` now holds `std::unique_ptr` CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( eostr.capacity(), 12 ) @@ -188,97 +188,97 @@ EOSIO_TEST_BEGIN(string_test_82) EOSIO_TEST_END //// string& erase(size_t pos = 0, size_t len = npos) -EOSIO_TEST_BEGIN(string_test_83) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase) + string eostr{"abcdefgh"}; eostr.erase(); CHECK_EQUAL( eostr.size(), 0 ) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_84) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_at_zero) + string eostr{"abcdefgh"}; eostr.erase(0); CHECK_EQUAL( eostr.size(), 0 ) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_85) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_to_npos) + string eostr{"abcdefgh"}; eostr.erase(0, string::npos); CHECK_EQUAL( eostr.size(), 0 ) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_86) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_1) + string eostr{"abcdefgh"}; eostr.erase(1, string::npos); CHECK_EQUAL( eostr.size(), 1 ) CHECK_EQUAL( strcmp(eostr.c_str(), "a"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_87) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_2) + string eostr{"abcdefgh"}; eostr.erase(2, string::npos); CHECK_EQUAL( eostr.size(), 2 ) CHECK_EQUAL( strcmp(eostr.c_str(), "ab"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_88) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_3) + string eostr{"abcdefgh"}; eostr.erase(3, string::npos); CHECK_EQUAL( eostr.size(), 3 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_89) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_4) + string eostr{"abcdefgh"}; eostr.erase(4, string::npos); CHECK_EQUAL( eostr.size(), 4 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcd"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_90) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_5) + string eostr{"abcdefgh"}; eostr.erase(5, string::npos); CHECK_EQUAL( eostr.size(), 5 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcde"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_91) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_6) + string eostr{"abcdefgh"}; eostr.erase(6, string::npos); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_92) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_7) + string eostr{"abcdefgh"}; eostr.erase(7, string::npos); CHECK_EQUAL( eostr.size(), 7 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefg"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_93) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_8) + string eostr{"abcdefgh"}; eostr.erase(8, string::npos); CHECK_EQUAL( eostr.size(), 8 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefgh"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_94) - static string eostr{"abcdefgh"}; +EOSIO_TEST_BEGIN(string_test_erase_from_8_len_0) + string eostr{"abcdefgh"}; eostr.erase(8, 0); CHECK_EQUAL( eostr.size(), 8 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefgh"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_95) - static string eostr{"abcdefg"}; - CHECK_ASSERT( "eosio::string::erase", []() {eostr.erase(-1, 1);} ) +EOSIO_TEST_BEGIN(string_test_erase_neg_index_1) + string eostr{"abcdefg"}; + CHECK_ASSERT( "eosio::string::erase", [&]() {eostr.erase(-1, 1);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_96) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(); @@ -286,8 +286,8 @@ EOSIO_TEST_BEGIN(string_test_96) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_97) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_at_zero_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(0); @@ -295,8 +295,8 @@ EOSIO_TEST_BEGIN(string_test_97) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_98) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_at_zero_op_plus_npos) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(0, string::npos); @@ -304,8 +304,8 @@ EOSIO_TEST_BEGIN(string_test_98) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_99) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_1_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(1, string::npos); @@ -313,8 +313,8 @@ EOSIO_TEST_BEGIN(string_test_99) CHECK_EQUAL( strcmp(eostr.c_str(), "a"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_100) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_2_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(2, string::npos); @@ -322,8 +322,8 @@ EOSIO_TEST_BEGIN(string_test_100) CHECK_EQUAL( strcmp(eostr.c_str(), "ab"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_101) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_3_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(3, string::npos); @@ -331,8 +331,8 @@ EOSIO_TEST_BEGIN(string_test_101) CHECK_EQUAL( strcmp(eostr.c_str(), "abc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_102) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_4_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(4, string::npos); @@ -340,8 +340,8 @@ EOSIO_TEST_BEGIN(string_test_102) CHECK_EQUAL( strcmp(eostr.c_str(), "abcd"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_103) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_5_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(5, string::npos); @@ -349,8 +349,8 @@ EOSIO_TEST_BEGIN(string_test_103) CHECK_EQUAL( strcmp(eostr.c_str(), "abcde"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_104) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_6_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(6, string::npos); @@ -358,8 +358,8 @@ EOSIO_TEST_BEGIN(string_test_104) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_105) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_7_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(7, string::npos); @@ -367,8 +367,8 @@ EOSIO_TEST_BEGIN(string_test_105) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefg"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_106) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_from_8_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(8, string::npos); @@ -376,8 +376,8 @@ EOSIO_TEST_BEGIN(string_test_106) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefgh"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_107) - static string eostr{""}; +EOSIO_TEST_BEGIN(string_test_erase_at_8_op_plus) + string eostr{""}; eostr += "abcdefgh"; eostr.erase(8, 0); @@ -385,49 +385,49 @@ EOSIO_TEST_BEGIN(string_test_107) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefgh"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_108) - static string eostr{"abcdefg"}; - CHECK_ASSERT( "eosio::string::erase", []() {eostr.erase(-1, 1);} ) +EOSIO_TEST_BEGIN(string_test_erase_neg_index_2) + string eostr{"abcdefg"}; + CHECK_ASSERT( "eosio::string::erase", [&]() {eostr.erase(-1, 1);} ) EOSIO_TEST_END //// string& append(const char* str) -EOSIO_TEST_BEGIN(string_test_109) - static string eostr{}; - static const char* str{"iii"}; +EOSIO_TEST_BEGIN(string_test_append_to_blank_1) + string eostr{}; + const char* str{"iii"}; eostr.append(str); CHECK_EQUAL( eostr.size(), 3 ) CHECK_EQUAL( eostr.capacity(), 6 ) CHECK_EQUAL( strcmp(eostr.c_str(), "iii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_110) - static string eostr{"abcdefg"}; - static const char* str{"iii"}; +EOSIO_TEST_BEGIN(string_test_append_1) + string eostr{"abcdefg"}; + const char* str{"iii"}; eostr.append(str); CHECK_EQUAL( eostr.size(), 10 ) CHECK_EQUAL( eostr.capacity(), 20 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefgiii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_111) - static string eostr{"abcdefg"}; - static const char* null_man{nullptr}; - CHECK_ASSERT( "eosio::string::append", []() {eostr.append(null_man);} ) +EOSIO_TEST_BEGIN(string_test_append_null) + string eostr{"abcdefg"}; + const char* null_man{nullptr}; + CHECK_ASSERT( "eosio::string::append", [&]() {eostr.append(null_man);} ) EOSIO_TEST_END //// string& append(const string& str) -EOSIO_TEST_BEGIN(string_test_112) - static string eostr{}; - static const string str{"iii"}; +EOSIO_TEST_BEGIN(string_test_append_to_blank_2) + string eostr{}; + const string str{"iii"}; eostr.append(str); CHECK_EQUAL( eostr.size(), 3 ) CHECK_EQUAL( eostr.capacity(), 6 ) CHECK_EQUAL( strcmp(eostr.c_str(), "iii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_113) - static string eostr{"abcdefg"}; - static const string str{"iii"}; +EOSIO_TEST_BEGIN(string_test_append_2) + string eostr{"abcdefg"}; + const string str{"iii"}; eostr.append(str); CHECK_EQUAL( eostr.size(), 10 ) CHECK_EQUAL( eostr.capacity(), 20 ) @@ -435,10 +435,10 @@ EOSIO_TEST_BEGIN(string_test_113) EOSIO_TEST_END //// string& operator+=(const char c) -EOSIO_TEST_BEGIN(string_test_114) - static string eostr0{}; - static string eostr1{"a"}; - static string eostr2{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_append_3) + string eostr0{}; + string eostr1{"a"}; + string eostr2{"abcdef"}; eostr0 += 'c'; CHECK_EQUAL( eostr0.size(), 1 ) @@ -458,11 +458,11 @@ EOSIO_TEST_BEGIN(string_test_114) EOSIO_TEST_END //// string& operator+=(const char* rhs) -EOSIO_TEST_BEGIN(string_test_115) - static string eostr0{}; - static string eostr1{"a"}; - static string eostr2{"abcdef"}; - static string eostr3{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_append_op_plus_1) + string eostr0{}; + string eostr1{"a"}; + string eostr2{"abcdef"}; + string eostr3{"abcdef"}; eostr0 += "c"; CHECK_EQUAL( eostr0.size(), 1 ) @@ -487,11 +487,11 @@ EOSIO_TEST_BEGIN(string_test_115) EOSIO_TEST_END //// string& operator+=(const string& rhs) -EOSIO_TEST_BEGIN(string_test_116) - static string eostr0{}; - static string eostr1{"a"}; - static string eostr2{"abcdef"}; - static string eostr3{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_append_op_plus_2) + string eostr0{}; + string eostr1{"a"}; + string eostr2{"abcdef"}; + string eostr3{"abcdef"}; eostr0 += string{"c"}; CHECK_EQUAL( eostr0.size(), 1 ) @@ -516,18 +516,18 @@ EOSIO_TEST_BEGIN(string_test_116) EOSIO_TEST_END //// string& operator+=(const string& s) -EOSIO_TEST_BEGIN(string_test_117) - static string eostr0{"a"}; - static string eostr1{"b"}; +EOSIO_TEST_BEGIN(string_test_append_op_plus_3) + string eostr0{"a"}; + string eostr1{"b"}; CHECK_EQUAL( eostr0.size(), 1 ) eostr0 += eostr1; CHECK_EQUAL( eostr0.size(), 2 ) CHECK_EQUAL( strcmp(eostr0.c_str(), "ab"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_118) - static string eostr0{"abc"}; - static string eostr1{"def"}; +EOSIO_TEST_BEGIN(string_test_append_op_plus_4) + string eostr0{"abc"}; + string eostr1{"def"}; CHECK_EQUAL( eostr0.size(), 3 ) eostr0 += eostr1; CHECK_EQUAL( eostr0.size(), 6 ) @@ -535,65 +535,65 @@ EOSIO_TEST_BEGIN(string_test_118) EOSIO_TEST_END //// inline void print(eosio::string str) -EOSIO_TEST_BEGIN(string_test_119) - static const string eostr0{""}; - static const string eostr1{"abc"}; - static const string eostr2{"abcdef"}; +EOSIO_TEST_BEGIN(string_test_print) + const string eostr0{""}; + const string eostr1{"abc"}; + const string eostr2{"abcdef"}; - CHECK_PRINT( "", [](){ print(eostr0); } ) - CHECK_PRINT( "abc", [](){ print(eostr1); } ) - CHECK_PRINT( "abcdef", [](){ print(eostr2); } ) + CHECK_PRINT( "", [&](){ print(eostr0); } ) + CHECK_PRINT( "abc", [&](){ print(eostr1); } ) + CHECK_PRINT( "abcdef", [&](){ print(eostr2); } ) EOSIO_TEST_END //// friend bool operator< (const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_120) - static const string eostr0{"abc"}; - static const string eostr1{"def"}; +EOSIO_TEST_BEGIN(string_test_less_than) + const string eostr0{"abc"}; + const string eostr1{"def"}; CHECK_EQUAL( (eostr0 < eostr0), false ) CHECK_EQUAL( (eostr1 < eostr1), false ) CHECK_EQUAL( (eostr0 < eostr1), true ) EOSIO_TEST_END //// friend bool operator> (const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_121) - static const string eostr0{"abc"}; - static const string eostr1{"def"}; +EOSIO_TEST_BEGIN(string_test_greater_than) + const string eostr0{"abc"}; + const string eostr1{"def"}; CHECK_EQUAL( (eostr0 > eostr0), false ) CHECK_EQUAL( (eostr1 > eostr1), false ) CHECK_EQUAL( (eostr0 > eostr1), false ) EOSIO_TEST_END //// friend bool operator<=(const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_122) - static const string eostr0{"abc"}; - static const string eostr1{"def"}; +EOSIO_TEST_BEGIN(string_test_less_than_or_equal) + const string eostr0{"abc"}; + const string eostr1{"def"}; CHECK_EQUAL( (eostr0 <= eostr0), true ) CHECK_EQUAL( (eostr1 <= eostr1), true ) CHECK_EQUAL( (eostr0 <= eostr1), true ) EOSIO_TEST_END //// friend bool operator>=(const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_123) - static const string eostr0{"abc"}; - static const string eostr1{"def"}; +EOSIO_TEST_BEGIN(string_test_greater_than_or_equal) + const string eostr0{"abc"}; + const string eostr1{"def"}; CHECK_EQUAL( (eostr0 >= eostr0), true ) CHECK_EQUAL( (eostr1 >= eostr1), true ) CHECK_EQUAL( (eostr0 >= eostr1), false ) EOSIO_TEST_END //// friend bool operator==(const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_124) - static const string eostr0{"abc"}; - static const string eostr1{"def"}; +EOSIO_TEST_BEGIN(string_test_equal) + const string eostr0{"abc"}; + const string eostr1{"def"}; CHECK_EQUAL( (eostr0 == eostr0), true ) CHECK_EQUAL( (eostr1 == eostr1), true ) CHECK_EQUAL( (eostr0 == eostr1), false ) EOSIO_TEST_END //// friend bool operator!=(const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_125) - static const string eostr0{"abc"}; - static const string eostr1{"def"}; +EOSIO_TEST_BEGIN(string_test_not_equal) + const string eostr0{"abc"}; + const string eostr1{"def"}; CHECK_EQUAL( (eostr0 != eostr0), false ) CHECK_EQUAL( (eostr1 != eostr1), false ) CHECK_EQUAL( (eostr0 != eostr1), true ) @@ -602,48 +602,48 @@ EOSIO_TEST_END //// template //// DataStream& operator<<(DataStream& ds, const string& str) //// DataStream& operator>>(DataStream& ds, string& str) -EOSIO_TEST_BEGIN(string_test_126) - static constexpr uint16_t buffer_size{256}; - static char datastream_buffer[buffer_size]{}; // Buffer for the datastream to point to - static char buffer[buffer_size]; // Buffer to compare `datastream_buffer` with - static datastream ds{datastream_buffer, buffer_size}; +EOSIO_TEST_BEGIN(string_test_stream_io_1) + constexpr uint16_t buffer_size{256}; + char datastream_buffer[buffer_size]{}; // Buffer for the datastream to point to + char buffer[buffer_size]; // Buffer to compare `datastream_buffer` with + datastream ds{datastream_buffer, buffer_size}; ds.seekp(0); fill(std::begin(datastream_buffer), std::end(datastream_buffer), 0); - static const string cstr {""}; - static string str{}; + const string cstr {""}; + string str{}; ds << cstr; ds.seekp(0); ds >> str; CHECK_EQUAL( cstr, str ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_127) - static constexpr uint16_t buffer_size{256}; - static char datastream_buffer[buffer_size]{}; - static char buffer[buffer_size]; - static datastream ds{datastream_buffer, buffer_size}; +EOSIO_TEST_BEGIN(string_test_stream_io_2) + constexpr uint16_t buffer_size{256}; + char datastream_buffer[buffer_size]{}; + char buffer[buffer_size]; + datastream ds{datastream_buffer, buffer_size}; ds.seekp(0); fill(std::begin(datastream_buffer), std::end(datastream_buffer), 0); - static const string cstr {"a"}; - static string str{}; + const string cstr {"a"}; + string str{}; ds << cstr; ds.seekp(0); ds >> str; CHECK_EQUAL( cstr, str ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_128) - static constexpr uint16_t buffer_size{256}; - static char datastream_buffer[buffer_size]{}; - static char buffer[buffer_size]; - static datastream ds{datastream_buffer, buffer_size}; +EOSIO_TEST_BEGIN(string_test_stream_io_3) + constexpr uint16_t buffer_size{256}; + char datastream_buffer[buffer_size]{}; + char buffer[buffer_size]; + datastream ds{datastream_buffer, buffer_size}; ds.seekp(0); fill(std::begin(datastream_buffer), std::end(datastream_buffer), 0); - static const string cstr {"abcdefghi"}; - static string str{}; + const string cstr {"abcdefghi"}; + string str{}; ds << cstr; ds.seekp(0); ds >> str; @@ -657,69 +657,70 @@ int main(int argc, char* argv[]) { } silence_output(!verbose); - EOSIO_TEST(string_test_65) - EOSIO_TEST(string_test_66) - EOSIO_TEST(string_test_67) - EOSIO_TEST(string_test_68) - EOSIO_TEST(string_test_69) - EOSIO_TEST(string_test_70) - EOSIO_TEST(string_test_71) - EOSIO_TEST(string_test_72) - EOSIO_TEST(string_test_73) - EOSIO_TEST(string_test_74) - EOSIO_TEST(string_test_75) - EOSIO_TEST(string_test_76) - EOSIO_TEST(string_test_77) - EOSIO_TEST(string_test_78) - EOSIO_TEST(string_test_79) - EOSIO_TEST(string_test_80) - EOSIO_TEST(string_test_81) - EOSIO_TEST(string_test_82) - EOSIO_TEST(string_test_83) - EOSIO_TEST(string_test_84) - EOSIO_TEST(string_test_85) - EOSIO_TEST(string_test_86) - EOSIO_TEST(string_test_87) - EOSIO_TEST(string_test_88) - EOSIO_TEST(string_test_89) - EOSIO_TEST(string_test_90) - EOSIO_TEST(string_test_91) - EOSIO_TEST(string_test_92) - EOSIO_TEST(string_test_93) - EOSIO_TEST(string_test_94) - EOSIO_TEST(string_test_95) - EOSIO_TEST(string_test_96) - EOSIO_TEST(string_test_97) - EOSIO_TEST(string_test_98) - EOSIO_TEST(string_test_99) - EOSIO_TEST(string_test_100) - EOSIO_TEST(string_test_101) - EOSIO_TEST(string_test_102) - EOSIO_TEST(string_test_103) - EOSIO_TEST(string_test_104) - EOSIO_TEST(string_test_105) - EOSIO_TEST(string_test_106) - EOSIO_TEST(string_test_107) - EOSIO_TEST(string_test_108) - EOSIO_TEST(string_test_109) - EOSIO_TEST(string_test_110) - EOSIO_TEST(string_test_111) - EOSIO_TEST(string_test_112) - EOSIO_TEST(string_test_113) - EOSIO_TEST(string_test_114) - EOSIO_TEST(string_test_115) - EOSIO_TEST(string_test_116) - EOSIO_TEST(string_test_117) - EOSIO_TEST(string_test_118) - EOSIO_TEST(string_test_119) - EOSIO_TEST(string_test_120) - EOSIO_TEST(string_test_121) - EOSIO_TEST(string_test_122) - EOSIO_TEST(string_test_123) - EOSIO_TEST(string_test_124) - EOSIO_TEST(string_test_125) - EOSIO_TEST(string_test_126) - EOSIO_TEST(string_test_127) - EOSIO_TEST(string_test_128) + EOSIO_TEST(string_test_insert_null) + EOSIO_TEST(string_test_insert_to_blank) + EOSIO_TEST(string_test_insert_at_beginning_single) + EOSIO_TEST(string_test_insert_at_beginning_multiple_1) + EOSIO_TEST(string_test_insert_at_beginning_multiple_2) + EOSIO_TEST(string_test_insert_in_middle_1) + EOSIO_TEST(string_test_insert_in_middle_2) + EOSIO_TEST(string_test_insert_at_end) + EOSIO_TEST(string_test_insert_neg_index_1) + EOSIO_TEST(string_test_insert_op_plus_1) + EOSIO_TEST(string_test_insert_op_plus_2) + EOSIO_TEST(string_test_insert_op_plus_3) + EOSIO_TEST(string_test_insert_op_plus_4) + EOSIO_TEST(string_test_insert_op_plus_5) + EOSIO_TEST(string_test_insert_op_plus_6) + EOSIO_TEST(string_test_insert_op_plus_7) + EOSIO_TEST(string_test_insert_neg_index_2) + EOSIO_TEST(string_test_insert_capacity) + EOSIO_TEST(string_test_erase) + EOSIO_TEST(string_test_erase_at_zero) + EOSIO_TEST(string_test_erase_to_npos) + EOSIO_TEST(string_test_erase_from_1) + EOSIO_TEST(string_test_erase_from_2) + EOSIO_TEST(string_test_erase_from_3) + EOSIO_TEST(string_test_erase_from_4) + EOSIO_TEST(string_test_erase_from_5) + EOSIO_TEST(string_test_erase_from_6) + EOSIO_TEST(string_test_erase_from_7) + EOSIO_TEST(string_test_erase_from_8) + EOSIO_TEST(string_test_erase_from_8_len_0) + EOSIO_TEST(string_test_erase_neg_index_1) + EOSIO_TEST(string_test_erase_op_plus) + EOSIO_TEST(string_test_erase_at_zero_op_plus) + EOSIO_TEST(string_test_erase_at_zero_op_plus_npos) + EOSIO_TEST(string_test_erase_from_1_op_plus) + EOSIO_TEST(string_test_erase_from_2_op_plus) + EOSIO_TEST(string_test_erase_from_3_op_plus) + EOSIO_TEST(string_test_erase_from_4_op_plus) + EOSIO_TEST(string_test_erase_from_5_op_plus) + EOSIO_TEST(string_test_erase_from_6_op_plus) + EOSIO_TEST(string_test_erase_from_7_op_plus) + EOSIO_TEST(string_test_erase_from_8_op_plus) + EOSIO_TEST(string_test_erase_at_8_op_plus) + EOSIO_TEST(string_test_erase_neg_index_2) + EOSIO_TEST(string_test_append_to_blank_1) + EOSIO_TEST(string_test_append_1) + EOSIO_TEST(string_test_append_null) + EOSIO_TEST(string_test_append_to_blank_2) + EOSIO_TEST(string_test_append_2) + EOSIO_TEST(string_test_append_3) + EOSIO_TEST(string_test_append_op_plus_1) + EOSIO_TEST(string_test_append_op_plus_2) + EOSIO_TEST(string_test_append_op_plus_3) + EOSIO_TEST(string_test_append_op_plus_4) + EOSIO_TEST(string_test_print) + EOSIO_TEST(string_test_less_than) + EOSIO_TEST(string_test_greater_than) + EOSIO_TEST(string_test_less_than_or_equal) + EOSIO_TEST(string_test_greater_than_or_equal) + EOSIO_TEST(string_test_equal) + EOSIO_TEST(string_test_not_equal) + EOSIO_TEST(string_test_stream_io_1) + EOSIO_TEST(string_test_stream_io_2) + EOSIO_TEST(string_test_stream_io_3) + return has_failed(); } From ec018c255d7f32446db6ad25074dc4bbda25e953 Mon Sep 17 00:00:00 2001 From: Keke Li Date: Wed, 7 Apr 2021 12:13:26 -0700 Subject: [PATCH 085/204] Using get_self instead of "eosio"_n so as to decouple tables with "eosio"_n, user can use other account then. --- tests/unit/test_contracts/read_only_query_tests.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/test_contracts/read_only_query_tests.cpp b/tests/unit/test_contracts/read_only_query_tests.cpp index 03db734fbd..ac8b736602 100644 --- a/tests/unit/test_contracts/read_only_query_tests.cpp +++ b/tests/unit/test_contracts/read_only_query_tests.cpp @@ -83,8 +83,8 @@ class [[eosio::contract]] read_only_query_tests : public eosio::contract { [[eosio::action]] void setup() { - my_table_m tm{"eosio"_n}; - my_table_f tf{"eosio"_n}; + my_table_m tm{get_self()}; + my_table_f tf{get_self()}; tm.put(s1, get_self()); tf.put(s2, get_self()); @@ -98,8 +98,8 @@ class [[eosio::contract]] read_only_query_tests : public eosio::contract { [[eosio::action, eosio::read_only]] std::vector get() { - my_table_m tm{"eosio"_n}; - my_table_f tf{"eosio"_n}; + my_table_m tm{get_self()}; + my_table_f tf{get_self()}; std::vector ret; auto itm = tm.id.begin(); @@ -135,8 +135,8 @@ class [[eosio::contract]] read_only_query_tests : public eosio::contract { [[eosio::action]] // usage: cleos -v push action eosio put '{"id":10,"name":"GULU","gender":1,"age":128}' -p eosio@active void put(uint32_t id, std::string name, uint32_t gender, uint32_t age ) { - my_table_m tm{"eosio"_n}; - my_table_f tf{"eosio"_n}; + my_table_m tm{get_self()}; + my_table_f tf{get_self()}; if(gender == 0){ tf.put({ .id = id, From 3d0cbbf8ff3fce72b1a95af4de79027b9db59f9a Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 8 Apr 2021 14:38:00 +0300 Subject: [PATCH 086/204] how to write an abi file it is actually a tutorial not a how to --- .../03_create-an-abi-file.md} | 5 ++++- docs/09_tutorials/index.md | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) rename docs/{06_how-to-guides/70_how-to-write-an-abi-file.md => 09_tutorials/03_create-an-abi-file.md} (99%) diff --git a/docs/06_how-to-guides/70_how-to-write-an-abi-file.md b/docs/09_tutorials/03_create-an-abi-file.md similarity index 99% rename from docs/06_how-to-guides/70_how-to-write-an-abi-file.md rename to docs/09_tutorials/03_create-an-abi-file.md index e2c12b3f63..42537a1ebc 100644 --- a/docs/06_how-to-guides/70_how-to-write-an-abi-file.md +++ b/docs/09_tutorials/03_create-an-abi-file.md @@ -1,7 +1,10 @@ --- -content_title: How to Write an ABI File +content_title: Create an ABI File --- +## Overview + +This tutorial provides instructions on how to create an ABI file. [[warning]] | As of v1.2.0, the eosio.wasmsdk was decoupled from the core repository. This change has introduced an eosio-cpp regression where the legacy eosio-abigen is no longer bundled with eosio-cpp. Until a new ABI generator is introduced, you will need to hand-write your ABI files. diff --git a/docs/09_tutorials/index.md b/docs/09_tutorials/index.md index 4d428089f4..95c7f23191 100644 --- a/docs/09_tutorials/index.md +++ b/docs/09_tutorials/index.md @@ -5,3 +5,4 @@ link_text: Tutorials - [Binary Extension](01_binary-extension.md) - [ABI Variants](02_abi-variants.md) +- [Create An ABI File](03_create-an-abi-file.md) From 0d210bda0d204426ab922d311fcf569f34d0de80 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Mon, 12 Apr 2021 09:39:09 -0400 Subject: [PATCH 087/204] fix bug in MacOS where string_tests1 failed --- tests/unit/string_tests1.cpp | 100 +++++++++---------- tests/unit/string_tests2.cpp | 184 +++++++++++++++++------------------ 2 files changed, 142 insertions(+), 142 deletions(-) diff --git a/tests/unit/string_tests1.cpp b/tests/unit/string_tests1.cpp index 4157e605eb..7bab9c2540 100644 --- a/tests/unit/string_tests1.cpp +++ b/tests/unit/string_tests1.cpp @@ -17,7 +17,7 @@ using eosio::string; //// template //// string(const char (&str)[N]) -EOSIO_TEST_BEGIN(string_test_ctr_literal) +EOSIO_TEST_BEGIN(string_test_ctr_lit) const string eostr0{"a"}; const string eostr1{"abcdef"}; @@ -31,7 +31,7 @@ EOSIO_TEST_BEGIN(string_test_ctr_literal) EOSIO_TEST_END //// string() -EOSIO_TEST_BEGIN(string_test_ctr_default) +EOSIO_TEST_BEGIN(string_test_ctr_def) const string eostr{}; CHECK_EQUAL( eostr.size(), 0 ) @@ -153,7 +153,7 @@ EOSIO_TEST_BEGIN(string_test_ctr_cpy) CHECK_EQUAL( strcmp(eostr2_cpy.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_op_plus) +EOSIO_TEST_BEGIN(string_test_op_pl) static string eostr0{""}; eostr0 += "a"; static string eostr1{"abc"}; @@ -171,7 +171,7 @@ EOSIO_TEST_BEGIN(string_test_op_plus) EOSIO_TEST_END //// const string(const string&& str) -EOSIO_TEST_BEGIN(string_test_ctr_move) +EOSIO_TEST_BEGIN(string_test_ctr_mv) const string eostr0{""}; const string eostr1{"a"}; const string eostr2{"abcdef"}; @@ -192,7 +192,7 @@ EOSIO_TEST_BEGIN(string_test_ctr_move) CHECK_EQUAL( strcmp(eostr2.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_op_plus_ctr_move) +EOSIO_TEST_BEGIN(string_test_op_pl_ctr_mv) string eostr0{""}; eostr0 += "a"; string eostr1{"abc"}; @@ -210,7 +210,7 @@ EOSIO_TEST_BEGIN(string_test_op_plus_ctr_move) EOSIO_TEST_END //// string& operator=(const string& str); -EOSIO_TEST_BEGIN(string_test_op_assign_1) +EOSIO_TEST_BEGIN(string_test_op_asgn_1) const string eostr0{""}; const string eostr1{"a"}; const string eostr2{"abcdef"}; @@ -234,7 +234,7 @@ EOSIO_TEST_BEGIN(string_test_op_assign_1) CHECK_EQUAL( strcmp(eostr2_cpy_assig.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_op_plus_op_assign) +EOSIO_TEST_BEGIN(string_test_op_pl_asgn) string eostr0{""}; eostr0 += "a"; string eostr1{"abc"}; @@ -254,7 +254,7 @@ EOSIO_TEST_BEGIN(string_test_op_plus_op_assign) EOSIO_TEST_END //// string& operator=(string&& str) -EOSIO_TEST_BEGIN(string_test_move_assign) +EOSIO_TEST_BEGIN(string_test_mv_asgn) string eostr0{""}; string eostr1{"a"}; string eostr2{"abcdef"}; @@ -278,7 +278,7 @@ EOSIO_TEST_BEGIN(string_test_move_assign) CHECK_EQUAL( strcmp(eostr2_mv_assig.c_str(), "abcdef"), 0) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_op_plus_move_assign) +EOSIO_TEST_BEGIN(string_test_op_pl_mv) string eostr0{""}; eostr0 += "a"; string eostr1{"abc"}; @@ -298,7 +298,7 @@ EOSIO_TEST_BEGIN(string_test_op_plus_move_assign) EOSIO_TEST_END //// string& operator=(const char* str) -EOSIO_TEST_BEGIN(string_test_op_assign_2) +EOSIO_TEST_BEGIN(string_test_op_asgn_2) string eostr{}; eostr = "abcdef"; @@ -312,7 +312,7 @@ EOSIO_TEST_BEGIN(string_test_op_assign_2) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_op_assign_op_plus) +EOSIO_TEST_BEGIN(string_test_op_asgn_pl) string eostr{}; eostr = ""; eostr += "abcdef"; @@ -328,13 +328,13 @@ EOSIO_TEST_BEGIN(string_test_op_assign_op_plus) EOSIO_TEST_END //// char& operator[](const size_t n) -EOSIO_TEST_BEGIN(string_test_pos_char_eq) +EOSIO_TEST_BEGIN(string_test_char_eq) string eostr{"abcdef"}; CHECK_EQUAL( eostr[0], 'a' ) CHECK_EQUAL( eostr[5], 'f' ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_pos_char_eq_op_plus) +EOSIO_TEST_BEGIN(string_test_char_eq_pl) string eostr{"abc"}; eostr += "def"; CHECK_EQUAL( eostr[0], 'a' ) @@ -342,14 +342,14 @@ EOSIO_TEST_BEGIN(string_test_pos_char_eq_op_plus) EOSIO_TEST_END //// const char& operator[](const size_t n) const -EOSIO_TEST_BEGIN(string_test_pos_char_eq_ctr_literal) +EOSIO_TEST_BEGIN(string_test_char_eq_ctr) const string eostr{"abcdef"}; CHECK_EQUAL( eostr[0], 'a' ) CHECK_EQUAL( eostr[5], 'f' ) EOSIO_TEST_END //// char& at(const size_t n) -EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_1) +EOSIO_TEST_BEGIN(string_test_char_eq_at_1) string eostr{"abcdef"}; CHECK_EQUAL( eostr.at(0), 'a' ) CHECK_EQUAL( eostr.at(5), 'f' ) @@ -358,7 +358,7 @@ EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_1) EOSIO_TEST_END //// const char& at(const size_t n) const -EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_2) +EOSIO_TEST_BEGIN(string_test_char_eq_at_2) const string eostr{"abcdef"}; CHECK_EQUAL( eostr.at(0), 'a' ) CHECK_EQUAL( eostr.at(5), 'f' ) @@ -366,7 +366,7 @@ EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_2) CHECK_ASSERT( "eosio::string::at const", [&]() {eostr.at(6);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_pos_char_eq_at_3) +EOSIO_TEST_BEGIN(string_test_char_eq_at_3) string eostr{""}; eostr += "abcdef"; const char c0{eostr.at(0)}; @@ -798,35 +798,35 @@ EOSIO_TEST_BEGIN(string_test_copy_3) EOSIO_TEST_END //// string& insert(const size_t pos, const char* str) -EOSIO_TEST_BEGIN(string_test_insert_1) +EOSIO_TEST_BEGIN(string_test_ins_1) string eostr{"iii"}; const char* str{"ooo"}; eostr.insert(0, str); CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_2) +EOSIO_TEST_BEGIN(string_test_ins_2) string eostr{"iii"}; const char* str{"ooo"}; eostr.insert(1, str); CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_3) +EOSIO_TEST_BEGIN(string_test_ins_3) string eostr{"iii"}; const char* str{"ooo"}; eostr.insert(2, str); CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_4) +EOSIO_TEST_BEGIN(string_test_ins_4) string eostr{"iii"}; const char* str{"ooo"}; eostr.insert(3, str); CHECK_EQUAL( strcmp(eostr.c_str(), "iiiooo"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_5) +EOSIO_TEST_BEGIN(string_test_ins_5) string eostr{""}; eostr += "iii"; const char* str{"ooo"}; @@ -834,7 +834,7 @@ EOSIO_TEST_BEGIN(string_test_insert_5) CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_6) +EOSIO_TEST_BEGIN(string_test_ins_6) string eostr{""}; eostr += "iii"; const char* str{"ooo"}; @@ -842,7 +842,7 @@ EOSIO_TEST_BEGIN(string_test_insert_6) CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_7) +EOSIO_TEST_BEGIN(string_test_ins_7) string eostr{""}; eostr += "iii"; const char* str{"ooo"}; @@ -850,7 +850,7 @@ EOSIO_TEST_BEGIN(string_test_insert_7) CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_8) +EOSIO_TEST_BEGIN(string_test_ins_8) string eostr{""}; eostr += "iii"; const char* str{"ooo"}; @@ -865,27 +865,27 @@ int main(int argc, char* argv[]) { } silence_output(!verbose); - EOSIO_TEST(string_test_ctr_literal) - EOSIO_TEST(string_test_ctr_default) + EOSIO_TEST(string_test_ctr_lit) + EOSIO_TEST(string_test_ctr_def) EOSIO_TEST(string_test_ctr_char_ptr) EOSIO_TEST(string_test_ctr_char_rep) EOSIO_TEST(string_test_ctr_str_sub) EOSIO_TEST(string_test_ctr_cpy) - EOSIO_TEST(string_test_op_plus) - EOSIO_TEST(string_test_ctr_move) - EOSIO_TEST(string_test_op_plus_ctr_move) - EOSIO_TEST(string_test_op_assign_1) - EOSIO_TEST(string_test_op_plus_op_assign) - EOSIO_TEST(string_test_move_assign) - EOSIO_TEST(string_test_op_plus_move_assign) - EOSIO_TEST(string_test_op_assign_2) - EOSIO_TEST(string_test_op_assign_op_plus) - EOSIO_TEST(string_test_pos_char_eq) - EOSIO_TEST(string_test_pos_char_eq_op_plus) - EOSIO_TEST(string_test_pos_char_eq_ctr_literal) - EOSIO_TEST(string_test_pos_char_eq_at_1) - EOSIO_TEST(string_test_pos_char_eq_at_2) - EOSIO_TEST(string_test_pos_char_eq_at_3) + EOSIO_TEST(string_test_op_pl) + EOSIO_TEST(string_test_ctr_mv) + EOSIO_TEST(string_test_op_pl_ctr_mv) + EOSIO_TEST(string_test_op_asgn_1) + EOSIO_TEST(string_test_op_pl_asgn) + EOSIO_TEST(string_test_mv_asgn) + EOSIO_TEST(string_test_op_pl_mv) + EOSIO_TEST(string_test_op_asgn_2) + EOSIO_TEST(string_test_op_asgn_pl) + EOSIO_TEST(string_test_char_eq) + EOSIO_TEST(string_test_char_eq_pl) + EOSIO_TEST(string_test_char_eq_ctr) + EOSIO_TEST(string_test_char_eq_at_1) + EOSIO_TEST(string_test_char_eq_at_2) + EOSIO_TEST(string_test_char_eq_at_3) EOSIO_TEST(string_test_front_1) EOSIO_TEST(string_test_front_2) EOSIO_TEST(string_test_back_1) @@ -921,14 +921,14 @@ int main(int argc, char* argv[]) { EOSIO_TEST(string_test_copy_1) EOSIO_TEST(string_test_copy_2) EOSIO_TEST(string_test_copy_3) - EOSIO_TEST(string_test_insert_1) - EOSIO_TEST(string_test_insert_2) - EOSIO_TEST(string_test_insert_3) - EOSIO_TEST(string_test_insert_4) - EOSIO_TEST(string_test_insert_5) - EOSIO_TEST(string_test_insert_6) - EOSIO_TEST(string_test_insert_7) - EOSIO_TEST(string_test_insert_8) + EOSIO_TEST(string_test_ins_1) + EOSIO_TEST(string_test_ins_2) + EOSIO_TEST(string_test_ins_3) + EOSIO_TEST(string_test_ins_4) + EOSIO_TEST(string_test_ins_5) + EOSIO_TEST(string_test_ins_6) + EOSIO_TEST(string_test_ins_7) + EOSIO_TEST(string_test_ins_8) return has_failed(); } diff --git a/tests/unit/string_tests2.cpp b/tests/unit/string_tests2.cpp index ccb5369ff8..a13fcd7cb3 100644 --- a/tests/unit/string_tests2.cpp +++ b/tests/unit/string_tests2.cpp @@ -15,7 +15,7 @@ using eosio::string; // Definitions found in `eosio.cdt/libraries/eosiolib/core/eosio/string.hpp` -EOSIO_TEST_BEGIN(string_test_insert_null) +EOSIO_TEST_BEGIN(string_test_ins_null) string eostr{"abcdefg"}; const char* null_man{nullptr}; CHECK_ASSERT( "eosio::string::insert", [&]() {eostr.insert(0, null_man, 1);} ) @@ -23,7 +23,7 @@ EOSIO_TEST_BEGIN(string_test_insert_null) EOSIO_TEST_END //// string& insert(const size_t pos, const string& str) -EOSIO_TEST_BEGIN(string_test_insert_to_blank) +EOSIO_TEST_BEGIN(string_test_ins_to_blank) string eostr{}; const string str{"ooo"}; eostr.insert(0, str); @@ -32,7 +32,7 @@ EOSIO_TEST_BEGIN(string_test_insert_to_blank) CHECK_EQUAL( strcmp(eostr.c_str(), "ooo"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_at_beginning_single) +EOSIO_TEST_BEGIN(string_test_ins_at_bgn_single) string eostr{"abc"}; const string str{"d"}; eostr.insert(0, str); @@ -41,7 +41,7 @@ EOSIO_TEST_BEGIN(string_test_insert_at_beginning_single) CHECK_EQUAL( strcmp(eostr.c_str(), "dabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_at_beginning_multiple_1) +EOSIO_TEST_BEGIN(string_test_ins_at_bgn_mul_1) string eostr{"abc"}; const string str{"def"}; eostr.insert(0, str); @@ -50,7 +50,7 @@ EOSIO_TEST_BEGIN(string_test_insert_at_beginning_multiple_1) CHECK_EQUAL( strcmp(eostr.c_str(), "defabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_at_beginning_multiple_2) +EOSIO_TEST_BEGIN(string_test_ins_at_bgn_mul_2) string eostr{"iii"}; const string str{"ooo"}; eostr.insert(0, str); @@ -59,7 +59,7 @@ EOSIO_TEST_BEGIN(string_test_insert_at_beginning_multiple_2) CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_in_middle_1) +EOSIO_TEST_BEGIN(string_test_ins_in_middle_1) string eostr{"iii"}; const string str{"ooo"}; eostr.insert(1, str); @@ -68,7 +68,7 @@ EOSIO_TEST_BEGIN(string_test_insert_in_middle_1) CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_in_middle_2) +EOSIO_TEST_BEGIN(string_test_ins_in_middle_2) string eostr{"iii"}; const string str{"ooo"}; eostr.insert(2, str); @@ -77,7 +77,7 @@ EOSIO_TEST_BEGIN(string_test_insert_in_middle_2) CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_at_end) +EOSIO_TEST_BEGIN(string_test_ins_at_end) string eostr{"iii"}; const string str{"ooo"}; eostr.insert(3, str); @@ -86,13 +86,13 @@ EOSIO_TEST_BEGIN(string_test_insert_at_end) CHECK_EQUAL( strcmp(eostr.c_str(), "iiiooo") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_neg_index_1) +EOSIO_TEST_BEGIN(string_test_ins_neg_index_1) string eostr{"abcdefg"}; const string str{"ooo"}; CHECK_ASSERT( "eosio::string::insert", [&]() {eostr.insert(-1, str);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_op_plus_1) +EOSIO_TEST_BEGIN(string_test_ins_op_pl_1) string eostr{""}; string str{""}; str += "ooo"; @@ -102,7 +102,7 @@ EOSIO_TEST_BEGIN(string_test_insert_op_plus_1) CHECK_EQUAL( strcmp(eostr.c_str(), "ooo"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_op_plus_2) +EOSIO_TEST_BEGIN(string_test_ins_op_pl_2) string eostr{""}; eostr += "abc"; string str{""}; @@ -113,7 +113,7 @@ EOSIO_TEST_BEGIN(string_test_insert_op_plus_2) CHECK_EQUAL( strcmp(eostr.c_str(), "dabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_op_plus_3) +EOSIO_TEST_BEGIN(string_test_ins_op_pl_3) string eostr{""}; eostr += "abc"; string str{""}; @@ -124,7 +124,7 @@ EOSIO_TEST_BEGIN(string_test_insert_op_plus_3) CHECK_EQUAL( strcmp(eostr.c_str(), "defabc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_op_plus_4) +EOSIO_TEST_BEGIN(string_test_ins_op_pl_4) string eostr{""}; eostr += "iii"; string str{""}; @@ -135,7 +135,7 @@ EOSIO_TEST_BEGIN(string_test_insert_op_plus_4) CHECK_EQUAL( strcmp(eostr.c_str(), "oooiii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_op_plus_5) +EOSIO_TEST_BEGIN(string_test_ins_op_pl_5) string eostr{""}; eostr += "iii"; string str{""}; @@ -146,7 +146,7 @@ EOSIO_TEST_BEGIN(string_test_insert_op_plus_5) CHECK_EQUAL( strcmp(eostr.c_str(), "ioooii") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_op_plus_6) +EOSIO_TEST_BEGIN(string_test_ins_op_pl_6) string eostr{""}; eostr += "iii"; string str{""}; @@ -157,7 +157,7 @@ EOSIO_TEST_BEGIN(string_test_insert_op_plus_6) CHECK_EQUAL( strcmp(eostr.c_str(), "iioooi") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_op_plus_7) +EOSIO_TEST_BEGIN(string_test_ins_op_pl_7) string eostr{""}; eostr += "iii"; string str{""}; @@ -168,13 +168,13 @@ EOSIO_TEST_BEGIN(string_test_insert_op_plus_7) CHECK_EQUAL( strcmp(eostr.c_str(), "iiiooo") , 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_neg_index_2) +EOSIO_TEST_BEGIN(string_test_ins_neg_index_2) string eostr{"abcdefg"}; string str{"ooo"}; CHECK_ASSERT( "eosio::string::insert", [&]() {eostr.insert(-1, str);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_insert_capacity) +EOSIO_TEST_BEGIN(string_test_ins_capacity) string eostr = "hello"; eostr.insert(0, "0", 1); /// `_capacity` is now 12; `_begin` now holds `std::unique_ptr` CHECK_EQUAL( eostr.size(), 6 ) @@ -209,63 +209,63 @@ EOSIO_TEST_BEGIN(string_test_erase_to_npos) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_1) +EOSIO_TEST_BEGIN(string_test_erase_1) string eostr{"abcdefgh"}; eostr.erase(1, string::npos); CHECK_EQUAL( eostr.size(), 1 ) CHECK_EQUAL( strcmp(eostr.c_str(), "a"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_2) +EOSIO_TEST_BEGIN(string_test_erase_2) string eostr{"abcdefgh"}; eostr.erase(2, string::npos); CHECK_EQUAL( eostr.size(), 2 ) CHECK_EQUAL( strcmp(eostr.c_str(), "ab"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_3) +EOSIO_TEST_BEGIN(string_test_erase_3) string eostr{"abcdefgh"}; eostr.erase(3, string::npos); CHECK_EQUAL( eostr.size(), 3 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_4) +EOSIO_TEST_BEGIN(string_test_erase_4) string eostr{"abcdefgh"}; eostr.erase(4, string::npos); CHECK_EQUAL( eostr.size(), 4 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcd"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_5) +EOSIO_TEST_BEGIN(string_test_erase_5) string eostr{"abcdefgh"}; eostr.erase(5, string::npos); CHECK_EQUAL( eostr.size(), 5 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcde"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_6) +EOSIO_TEST_BEGIN(string_test_erase_6) string eostr{"abcdefgh"}; eostr.erase(6, string::npos); CHECK_EQUAL( eostr.size(), 6 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_7) +EOSIO_TEST_BEGIN(string_test_erase_7) string eostr{"abcdefgh"}; eostr.erase(7, string::npos); CHECK_EQUAL( eostr.size(), 7 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefg"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_8) +EOSIO_TEST_BEGIN(string_test_erase_8) string eostr{"abcdefgh"}; eostr.erase(8, string::npos); CHECK_EQUAL( eostr.size(), 8 ) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefgh"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_8_len_0) +EOSIO_TEST_BEGIN(string_test_erase_8_len_0) string eostr{"abcdefgh"}; eostr.erase(8, 0); CHECK_EQUAL( eostr.size(), 8 ) @@ -277,7 +277,7 @@ EOSIO_TEST_BEGIN(string_test_erase_neg_index_1) CHECK_ASSERT( "eosio::string::erase", [&]() {eostr.erase(-1, 1);} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -286,7 +286,7 @@ EOSIO_TEST_BEGIN(string_test_erase_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_at_zero_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_at_0_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -295,7 +295,7 @@ EOSIO_TEST_BEGIN(string_test_erase_at_zero_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_at_zero_op_plus_npos) +EOSIO_TEST_BEGIN(string_test_erase_at_0_op_pl_npos) string eostr{""}; eostr += "abcdefgh"; @@ -304,7 +304,7 @@ EOSIO_TEST_BEGIN(string_test_erase_at_zero_op_plus_npos) CHECK_EQUAL( strcmp(eostr.c_str(), ""), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_1_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_1_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -313,7 +313,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_1_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "a"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_2_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_2_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -322,7 +322,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_2_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "ab"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_3_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_3_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -331,7 +331,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_3_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "abc"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_4_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_4_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -340,7 +340,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_4_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "abcd"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_5_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_5_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -349,7 +349,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_5_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "abcde"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_6_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_6_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -358,7 +358,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_6_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdef"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_7_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_7_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -367,7 +367,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_7_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefg"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_from_8_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_8_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -376,7 +376,7 @@ EOSIO_TEST_BEGIN(string_test_erase_from_8_op_plus) CHECK_EQUAL( strcmp(eostr.c_str(), "abcdefgh"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_erase_at_8_op_plus) +EOSIO_TEST_BEGIN(string_test_erase_at_8_op_pl) string eostr{""}; eostr += "abcdefgh"; @@ -458,7 +458,7 @@ EOSIO_TEST_BEGIN(string_test_append_3) EOSIO_TEST_END //// string& operator+=(const char* rhs) -EOSIO_TEST_BEGIN(string_test_append_op_plus_1) +EOSIO_TEST_BEGIN(string_test_append_op_pl_1) string eostr0{}; string eostr1{"a"}; string eostr2{"abcdef"}; @@ -487,7 +487,7 @@ EOSIO_TEST_BEGIN(string_test_append_op_plus_1) EOSIO_TEST_END //// string& operator+=(const string& rhs) -EOSIO_TEST_BEGIN(string_test_append_op_plus_2) +EOSIO_TEST_BEGIN(string_test_append_op_pl_2) string eostr0{}; string eostr1{"a"}; string eostr2{"abcdef"}; @@ -516,7 +516,7 @@ EOSIO_TEST_BEGIN(string_test_append_op_plus_2) EOSIO_TEST_END //// string& operator+=(const string& s) -EOSIO_TEST_BEGIN(string_test_append_op_plus_3) +EOSIO_TEST_BEGIN(string_test_append_op_pl_3) string eostr0{"a"}; string eostr1{"b"}; CHECK_EQUAL( eostr0.size(), 1 ) @@ -525,7 +525,7 @@ EOSIO_TEST_BEGIN(string_test_append_op_plus_3) CHECK_EQUAL( strcmp(eostr0.c_str(), "ab"), 0 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(string_test_append_op_plus_4) +EOSIO_TEST_BEGIN(string_test_append_op_pl_4) string eostr0{"abc"}; string eostr1{"def"}; CHECK_EQUAL( eostr0.size(), 3 ) @@ -555,7 +555,7 @@ EOSIO_TEST_BEGIN(string_test_less_than) EOSIO_TEST_END //// friend bool operator> (const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_greater_than) +EOSIO_TEST_BEGIN(string_test_gt) const string eostr0{"abc"}; const string eostr1{"def"}; CHECK_EQUAL( (eostr0 > eostr0), false ) @@ -564,7 +564,7 @@ EOSIO_TEST_BEGIN(string_test_greater_than) EOSIO_TEST_END //// friend bool operator<=(const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_less_than_or_equal) +EOSIO_TEST_BEGIN(string_test_lt_or_eq) const string eostr0{"abc"}; const string eostr1{"def"}; CHECK_EQUAL( (eostr0 <= eostr0), true ) @@ -573,7 +573,7 @@ EOSIO_TEST_BEGIN(string_test_less_than_or_equal) EOSIO_TEST_END //// friend bool operator>=(const string& lhs, const string& rhs) -EOSIO_TEST_BEGIN(string_test_greater_than_or_equal) +EOSIO_TEST_BEGIN(string_test_gt_or_eq) const string eostr0{"abc"}; const string eostr1{"def"}; CHECK_EQUAL( (eostr0 >= eostr0), true ) @@ -657,49 +657,49 @@ int main(int argc, char* argv[]) { } silence_output(!verbose); - EOSIO_TEST(string_test_insert_null) - EOSIO_TEST(string_test_insert_to_blank) - EOSIO_TEST(string_test_insert_at_beginning_single) - EOSIO_TEST(string_test_insert_at_beginning_multiple_1) - EOSIO_TEST(string_test_insert_at_beginning_multiple_2) - EOSIO_TEST(string_test_insert_in_middle_1) - EOSIO_TEST(string_test_insert_in_middle_2) - EOSIO_TEST(string_test_insert_at_end) - EOSIO_TEST(string_test_insert_neg_index_1) - EOSIO_TEST(string_test_insert_op_plus_1) - EOSIO_TEST(string_test_insert_op_plus_2) - EOSIO_TEST(string_test_insert_op_plus_3) - EOSIO_TEST(string_test_insert_op_plus_4) - EOSIO_TEST(string_test_insert_op_plus_5) - EOSIO_TEST(string_test_insert_op_plus_6) - EOSIO_TEST(string_test_insert_op_plus_7) - EOSIO_TEST(string_test_insert_neg_index_2) - EOSIO_TEST(string_test_insert_capacity) + EOSIO_TEST(string_test_ins_null) + EOSIO_TEST(string_test_ins_to_blank) + EOSIO_TEST(string_test_ins_at_bgn_single) + EOSIO_TEST(string_test_ins_at_bgn_mul_1) + EOSIO_TEST(string_test_ins_at_bgn_mul_2) + EOSIO_TEST(string_test_ins_in_middle_1) + EOSIO_TEST(string_test_ins_in_middle_2) + EOSIO_TEST(string_test_ins_at_end) + EOSIO_TEST(string_test_ins_neg_index_1) + EOSIO_TEST(string_test_ins_op_pl_1) + EOSIO_TEST(string_test_ins_op_pl_2) + EOSIO_TEST(string_test_ins_op_pl_3) + EOSIO_TEST(string_test_ins_op_pl_4) + EOSIO_TEST(string_test_ins_op_pl_5) + EOSIO_TEST(string_test_ins_op_pl_6) + EOSIO_TEST(string_test_ins_op_pl_7) + EOSIO_TEST(string_test_ins_neg_index_2) + EOSIO_TEST(string_test_ins_capacity) EOSIO_TEST(string_test_erase) EOSIO_TEST(string_test_erase_at_zero) EOSIO_TEST(string_test_erase_to_npos) - EOSIO_TEST(string_test_erase_from_1) - EOSIO_TEST(string_test_erase_from_2) - EOSIO_TEST(string_test_erase_from_3) - EOSIO_TEST(string_test_erase_from_4) - EOSIO_TEST(string_test_erase_from_5) - EOSIO_TEST(string_test_erase_from_6) - EOSIO_TEST(string_test_erase_from_7) - EOSIO_TEST(string_test_erase_from_8) - EOSIO_TEST(string_test_erase_from_8_len_0) + EOSIO_TEST(string_test_erase_1) + EOSIO_TEST(string_test_erase_2) + EOSIO_TEST(string_test_erase_3) + EOSIO_TEST(string_test_erase_4) + EOSIO_TEST(string_test_erase_5) + EOSIO_TEST(string_test_erase_6) + EOSIO_TEST(string_test_erase_7) + EOSIO_TEST(string_test_erase_8) + EOSIO_TEST(string_test_erase_8_len_0) EOSIO_TEST(string_test_erase_neg_index_1) - EOSIO_TEST(string_test_erase_op_plus) - EOSIO_TEST(string_test_erase_at_zero_op_plus) - EOSIO_TEST(string_test_erase_at_zero_op_plus_npos) - EOSIO_TEST(string_test_erase_from_1_op_plus) - EOSIO_TEST(string_test_erase_from_2_op_plus) - EOSIO_TEST(string_test_erase_from_3_op_plus) - EOSIO_TEST(string_test_erase_from_4_op_plus) - EOSIO_TEST(string_test_erase_from_5_op_plus) - EOSIO_TEST(string_test_erase_from_6_op_plus) - EOSIO_TEST(string_test_erase_from_7_op_plus) - EOSIO_TEST(string_test_erase_from_8_op_plus) - EOSIO_TEST(string_test_erase_at_8_op_plus) + EOSIO_TEST(string_test_erase_op_pl) + EOSIO_TEST(string_test_erase_at_0_op_pl) + EOSIO_TEST(string_test_erase_at_0_op_pl_npos) + EOSIO_TEST(string_test_erase_1_op_pl) + EOSIO_TEST(string_test_erase_2_op_pl) + EOSIO_TEST(string_test_erase_3_op_pl) + EOSIO_TEST(string_test_erase_4_op_pl) + EOSIO_TEST(string_test_erase_5_op_pl) + EOSIO_TEST(string_test_erase_6_op_pl) + EOSIO_TEST(string_test_erase_7_op_pl) + EOSIO_TEST(string_test_erase_8_op_pl) + EOSIO_TEST(string_test_erase_at_8_op_pl) EOSIO_TEST(string_test_erase_neg_index_2) EOSIO_TEST(string_test_append_to_blank_1) EOSIO_TEST(string_test_append_1) @@ -707,15 +707,15 @@ int main(int argc, char* argv[]) { EOSIO_TEST(string_test_append_to_blank_2) EOSIO_TEST(string_test_append_2) EOSIO_TEST(string_test_append_3) - EOSIO_TEST(string_test_append_op_plus_1) - EOSIO_TEST(string_test_append_op_plus_2) - EOSIO_TEST(string_test_append_op_plus_3) - EOSIO_TEST(string_test_append_op_plus_4) + EOSIO_TEST(string_test_append_op_pl_1) + EOSIO_TEST(string_test_append_op_pl_2) + EOSIO_TEST(string_test_append_op_pl_3) + EOSIO_TEST(string_test_append_op_pl_4) EOSIO_TEST(string_test_print) EOSIO_TEST(string_test_less_than) - EOSIO_TEST(string_test_greater_than) - EOSIO_TEST(string_test_less_than_or_equal) - EOSIO_TEST(string_test_greater_than_or_equal) + EOSIO_TEST(string_test_gt) + EOSIO_TEST(string_test_lt_or_eq) + EOSIO_TEST(string_test_gt_or_eq) EOSIO_TEST(string_test_equal) EOSIO_TEST(string_test_not_equal) EOSIO_TEST(string_test_stream_io_1) From 33556b832a6c9b017fc68ecbbc9ff172176d08d6 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Mon, 12 Apr 2021 13:04:34 -0400 Subject: [PATCH 088/204] Brew upstream package provider changed. We need to run an update before the upgrade to get packages properly now. --- .cicd/pipeline.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 812e7aadb3..c0df6e5efc 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -70,7 +70,7 @@ steps: - label: ":darwin: macOS 10.14 - Build" command: - - "brew upgrade" + - "brew update && brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -96,7 +96,7 @@ steps: - label: ":darwin: macOS 10.15 - Build" command: - - "brew upgrade" + - "brew update && brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -189,7 +189,7 @@ steps: - label: ":darwin: macOS 10.14 - Unit Tests" command: - - "brew upgrade" + - "brew update && brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -215,7 +215,7 @@ steps: - label: ":darwin: macOS 10.15 - Unit Tests" command: - - "brew upgrade" + - "brew update && brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -305,7 +305,7 @@ steps: - label: ":darwin: macOS 10.14 - Toolchain Tests" command: - - "brew upgrade" + - "brew update && brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" @@ -331,7 +331,7 @@ steps: - label: ":darwin: macOS 10.15 - Toolchain Tests" command: - - "brew upgrade" + - "brew update && brew upgrade" - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" From 075228d1cb80c856759297ba2e7b41b9f8b06b67 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Tue, 13 Apr 2021 18:32:17 -0400 Subject: [PATCH 089/204] condensed name_tests --- tests/unit/name_tests.cpp | 67 ++++++++++----------------------------- 1 file changed, 16 insertions(+), 51 deletions(-) diff --git a/tests/unit/name_tests.cpp b/tests/unit/name_tests.cpp index 3f759deb27..89e67ee2d6 100644 --- a/tests/unit/name_tests.cpp +++ b/tests/unit/name_tests.cpp @@ -17,7 +17,7 @@ using eosio::name; constexpr uint64_t u64max = numeric_limits::max(); // 18446744073709551615ULL // Definitions in `eosio.cdt/libraries/eosio/name.hpp` -EOSIO_TEST_BEGIN(name_type_test_constructor_num) +EOSIO_TEST_BEGIN(name_type_test_ctr_num) //// constexpr name() CHECK_EQUAL( name{}.value, 0ULL ) @@ -31,7 +31,7 @@ EOSIO_TEST_BEGIN(name_type_test_constructor_num) CHECK_EQUAL( name{name::raw{u64max}}.value, u64max ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_constructor_str_1) +EOSIO_TEST_BEGIN(name_type_test_ctr_str_lit) //// constexpr explicit name(string_view) // Note: // These are the exact `uint64_t` value representations of the given string @@ -42,17 +42,12 @@ EOSIO_TEST_BEGIN(name_type_test_constructor_str_1) CHECK_EQUAL( name{"abc"}.value, 3589368903014285312ULL ) CHECK_EQUAL( name{"123"}.value, 614178399182651392ULL ) -EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_3) CHECK_EQUAL( name{".abc"}.value, 112167778219196416ULL ) CHECK_EQUAL( name{".........abc"}.value, 102016ULL ) CHECK_EQUAL( name{"123."}.value, 614178399182651392ULL ) CHECK_EQUAL( name{"123........."}.value, 614178399182651392ULL ) CHECK_EQUAL( name{".a.b.c.1.2.3."}.value, 108209673814966320ULL ) -EOSIO_TEST_END - -EOSIO_TEST_BEGIN(name_type_test_constructor_str_2) CHECK_EQUAL( name{"abc.123"}.value, 3589369488740450304ULL ) CHECK_EQUAL( name{"123.abc"}.value, 614181822271586304ULL ) @@ -175,7 +170,7 @@ EOSIO_TEST_BEGIN(name_type_test_prefix) CHECK_EQUAL( name{"a.my.account"}.prefix().prefix(), name{"a"} ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_raw_1) +EOSIO_TEST_BEGIN(name_type_test_raw) // ----------------------------- // constexpr operator raw()const CHECK_EQUAL( name{"1"}.operator name::raw(), static_cast(576460752303423488ULL) ) @@ -191,9 +186,7 @@ EOSIO_TEST_BEGIN(name_type_test_raw_1) CHECK_EQUAL( name{"123."}.operator name::raw(), static_cast(614178399182651392ULL) ) CHECK_EQUAL( name{"123........."}.operator name::raw(), static_cast(614178399182651392ULL) ) CHECK_EQUAL( name{".a.b.c.1.2.3."}.operator name::raw(), static_cast(108209673814966320ULL) ) -EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_raw_2) CHECK_EQUAL( name{"abc.123"}.operator name::raw(), static_cast(3589369488740450304ULL) ) CHECK_EQUAL( name{"123.abc"}.operator name::raw(), static_cast(614181822271586304ULL) ) @@ -223,7 +216,7 @@ EOSIO_TEST_BEGIN(name_type_test_op_bool) CHECK_EQUAL( !name{"1"}.operator bool(), false ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_memcmp_1) +EOSIO_TEST_BEGIN(name_type_test_memcmp) // ---------------------------------------- // char* write_as_string(char*, char*)const constexpr uint8_t buffer_size{32}; @@ -243,13 +236,7 @@ EOSIO_TEST_BEGIN(name_type_test_memcmp_1) CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) name{str = "123"}.write_as_string( buffer, buffer + sizeof(buffer) ); CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) -EOSIO_TEST_END - -EOSIO_TEST_BEGIN(name_type_test_memcmp_2) - static constexpr uint8_t buffer_size{32}; - char buffer[buffer_size]{}; - string str{}; // Note: // Any '.' characters at the end of a name are ignored @@ -268,12 +255,7 @@ EOSIO_TEST_BEGIN(name_type_test_memcmp_2) CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) name{str = "123.abc"}.write_as_string( buffer, buffer + sizeof(buffer) ); CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) -EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_memcmp_3) - static constexpr uint8_t buffer_size{32}; - char buffer[buffer_size]{}; - string str{}; name{str = "12345abcdefgj"}.write_as_string( buffer, buffer + sizeof(buffer) ); CHECK_EQUAL( memcmp(str.c_str(), buffer, strlen(str.c_str())), 0 ) @@ -323,7 +305,7 @@ EOSIO_TEST_BEGIN(name_type_test_to_str) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_equal_1) +EOSIO_TEST_BEGIN(name_type_test_equal) // ---------------------------------------------------------- // friend constexpr bool operator==(const name&, const name&) CHECK_EQUAL( name{"1"} == name{"1"}, true ) @@ -339,9 +321,7 @@ EOSIO_TEST_BEGIN(name_type_test_equal_1) CHECK_EQUAL( name{"123."} == name{"123"}, true ) CHECK_EQUAL( name{"123........."} == name{"123"}, true ) CHECK_EQUAL( name{".a.b.c.1.2.3."} == name{".a.b.c.1.2.3"}, true ) -EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_equal_2) CHECK_EQUAL( name{"abc.123"} == name{"abc.123"}, true ) CHECK_EQUAL( name{"123.abc"} == name{"123.abc"}, true ) @@ -355,7 +335,7 @@ EOSIO_TEST_BEGIN(name_type_test_equal_2) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} == name{"zzzzzzzzzzzzj"}, true ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_not_equal_1) +EOSIO_TEST_BEGIN(name_type_test_not_equal) // ----------------------------------------------------------- // friend constexpr bool operator!=(const name&, const name&) CHECK_EQUAL( name{"1"} != name{}, true ) @@ -371,9 +351,7 @@ EOSIO_TEST_BEGIN(name_type_test_not_equal_1) CHECK_EQUAL( name{"123."} != name{}, true ) CHECK_EQUAL( name{"123........."} != name{}, true ) CHECK_EQUAL( name{".a.b.c.1.2.3."} != name{}, true ) -EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_not_equal_2) CHECK_EQUAL( name{"abc.123"} != name{}, true ) CHECK_EQUAL( name{"123.abc"} != name{}, true ) @@ -387,7 +365,7 @@ EOSIO_TEST_BEGIN(name_type_test_not_equal_2) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} != name{}, true ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_less_than_1) +EOSIO_TEST_BEGIN(name_type_test_less_than) // --------------------------------------------------------- // friend constexpr bool operator<(const name&, const name&) CHECK_EQUAL( name{} < name{"1"}, true ) @@ -403,10 +381,7 @@ EOSIO_TEST_BEGIN(name_type_test_less_than_1) CHECK_EQUAL( name{} < name{"123."}, true ) CHECK_EQUAL( name{} < name{"123........."}, true ) CHECK_EQUAL( name{} < name{".a.b.c.1.2.3."}, true ) -EOSIO_TEST_END - -EOSIO_TEST_BEGIN(name_type_test_less_than_2) CHECK_EQUAL( name{} < name{"abc.123"}, true ) CHECK_EQUAL( name{} < name{"123.abc"}, true ) @@ -421,7 +396,7 @@ EOSIO_TEST_BEGIN(name_type_test_less_than_2) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_op_n_1) +EOSIO_TEST_BEGIN(name_type_test_op_n) // ------------------------------------ // inline constexpr name operator""_n() CHECK_EQUAL( name{}, ""_n ) @@ -439,9 +414,7 @@ EOSIO_TEST_BEGIN(name_type_test_op_n_1) CHECK_EQUAL( name{"123."}, "123."_n ) CHECK_EQUAL( name{"123........."}, "123........."_n ) CHECK_EQUAL( name{".a.b.c.1.2.3."}, ".a.b.c.1.2.3."_n ) -EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_op_n_2) CHECK_EQUAL( name{"abc.123"}, "abc.123"_n ) CHECK_EQUAL( name{"123.abc"}, "123.abc"_n ) @@ -462,30 +435,22 @@ int main(int argc, char* argv[]) { } silence_output(!verbose); - EOSIO_TEST(name_type_test_constructor_num) - EOSIO_TEST(name_type_test_constructor_str_1) - EOSIO_TEST(name_type_test_constructor_str_2) + EOSIO_TEST(name_type_test_ctr_num) + EOSIO_TEST(name_type_test_ctr_str_lit) EOSIO_TEST(name_type_test_str_not_allowed) EOSIO_TEST(name_type_test_char_to_value) EOSIO_TEST(name_type_test_allowed_chars) EOSIO_TEST(name_type_test_str_len) EOSIO_TEST(name_type_test_suffix) EOSIO_TEST(name_type_test_prefix) - EOSIO_TEST(name_type_test_raw_1) - EOSIO_TEST(name_type_test_raw_2) + EOSIO_TEST(name_type_test_raw) EOSIO_TEST(name_type_test_op_bool) - EOSIO_TEST(name_type_test_memcmp_1) - EOSIO_TEST(name_type_test_memcmp_2) - EOSIO_TEST(name_type_test_memcmp_3) + EOSIO_TEST(name_type_test_memcmp) EOSIO_TEST(name_type_test_to_str) - EOSIO_TEST(name_type_test_equal_1) - EOSIO_TEST(name_type_test_equal_2) - EOSIO_TEST(name_type_test_not_equal_1) - EOSIO_TEST(name_type_test_not_equal_2) - EOSIO_TEST(name_type_test_less_than_1) - EOSIO_TEST(name_type_test_less_than_2) - EOSIO_TEST(name_type_test_op_n_1) - EOSIO_TEST(name_type_test_op_n_2) + EOSIO_TEST(name_type_test_equal) + EOSIO_TEST(name_type_test_not_equal) + EOSIO_TEST(name_type_test_less_than) + EOSIO_TEST(name_type_test_op_n) return has_failed(); } From 5436303d605d1c1f31115cc523780e326f0ac904 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Tue, 13 Apr 2021 18:38:05 -0400 Subject: [PATCH 090/204] removed static keyword --- tests/unit/string_tests1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/string_tests1.cpp b/tests/unit/string_tests1.cpp index 7bab9c2540..e62014622b 100644 --- a/tests/unit/string_tests1.cpp +++ b/tests/unit/string_tests1.cpp @@ -386,7 +386,7 @@ EOSIO_TEST_END //// const char& front() const EOSIO_TEST_BEGIN(string_test_front_2) - static const string eostr{"abcdef"}; + const string eostr{"abcdef"}; CHECK_EQUAL( eostr.front(), 'a' ) EOSIO_TEST_END From 57084945b64698cd9ef020acfeaba343c0750bd6 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 14 Apr 2021 14:12:43 +0300 Subject: [PATCH 091/204] updates based on code review --- .../01_compile-a-contract-via-cli.md | 2 +- .../10_compile/02_how-to-configure-cmake.md | 2 +- .../03_compiling-contracts-with-cmake.md | 2 +- ...to_restrict_access_to_an_action_by_user.md | 2 +- .../kv_map/10_how-to-use-kv-map.md | 20 +++++++++++++++---- .../kv_map/30_how-to-upsert-into-kv-map.md | 8 ++++---- .../kv_map/40_how-to-delete-from-kv-map.md | 6 +++--- .../kv_map/50_how-to-iterate-kv-map.md | 10 ++++------ .../kv_map/70_how-to-find-in-kv-map.md | 6 +++--- .../90_how-to-allow-users-to-pay-kv-map.md | 16 +++++++-------- .../kv_table/10_how-to-use-kv-table.md | 4 ++-- .../20_how-to-create-indexes-kv-table.md | 12 +++++------ .../30_how-to-upsert-into-kv-table.md | 6 +++--- .../40_how-to-delete-from-kv-table.md | 6 +++--- .../kv_table/50_how-to-iterate-kv-table.md | 8 ++++---- .../60_how-to-check-a-record-kv-table.md | 6 +++--- .../kv_table/70_how-to-find-in-kv-table.md | 6 +++--- .../80_how-to-query-range-in-kv-table.md | 6 +++--- .../90_how-to-allow-users-to-pay-kv-table.md | 8 ++++---- ...0_how-to-create-and-use-action-wrappers.md | 20 +++++++++---------- .../60_how-to-return-values-from-actions.md | 8 ++++---- 21 files changed, 87 insertions(+), 77 deletions(-) diff --git a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md index efd2773736..2014a1c326 100644 --- a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md +++ b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md @@ -4,7 +4,7 @@ content_title: How to compile a smart contract via CLI ## Overview -This how-to guide provides instructions how to compile a smart contract using the command line interface (CLI). +This guide provides instructions how to compile a smart contract using the command line interface (CLI). ## Before you begin diff --git a/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md b/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md index 12b68f0ebb..db9511dc1b 100644 --- a/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md +++ b/docs/06_how-to-guides/10_compile/02_how-to-configure-cmake.md @@ -4,7 +4,7 @@ content_title: How to configure CMake ## Overview -This how-to guide provides instructions how to configure CMake. +This guide provides instructions how to configure CMake. ## Before you begin diff --git a/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md b/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md index eb0314f097..612c0e3425 100644 --- a/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md +++ b/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md @@ -4,7 +4,7 @@ content_title: How to compile a smart contract with CMake ## Overview -This how-to guide provides instructions on how to compile a smart contract with CMake. +This guide provides instructions on how to compile a smart contract with CMake. ## Before you begin diff --git a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md index 2910c27cfd..e26e72f46d 100644 --- a/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md +++ b/docs/06_how-to-guides/20_authorization/how_to_restrict_access_to_an_action_by_user.md @@ -5,7 +5,7 @@ link_text: How To Perform Authorization Checks ## Overview -This how-to guide provides instructions how to perform authorization checks in a smart contract. +This guide provides instructions how to perform authorization checks in a smart contract. ## Before you begin diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md index 470f7d2e22..616ebc3d09 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md @@ -7,17 +7,29 @@ link_text: "How-To Use Key-Value Map" This how-to demonstrates how to define and use a `Key-Value Map` (`kv map`) in a smart contract. -To accomplish this task use `eosio::kv::map` template class, specify the name for the map object instantiated, the type of the key, and the type for the values stored for each key. The types used for the key and the values can be any standard type, or a user defined type. +To accomplish this task do the following: + +1. Instantiate an object of type `eosio::kv::map`. +2. Specify the name for the instantiated `eosio::kv::map` object. +3. Specify the type for the map's key. +4. Specify the type for the values stored for each key. +5. The key and the values types can be of any standard type or a user defined type. + +## Reference + +See the following code reference: + +* The [`kv::map`](https://developers.eos.io/manuals/eosio.cdt/latest/classeosio_1_1kv_1_1map) class. ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -41,7 +53,7 @@ class [[eosio::contract]] smartcontract : public eosio::contract { Complete the following steps to define the `my_map_t` type, based on the `eosio::kv::map`, which stores objects of type `person` with unique keys of type `int` and instantiate a map object of type `my_map_t`: * Define the `my_map_t` type based on `eosio::kv::map`. -* Specify `"kvmap"_n`, which is an `eosio::name`, as the first parameter, to name for the map object. +* Specify `"kvmap"_n`, which is an `eosio::name`, as the first parameter, to name the map object. * Specify `int` as the second parameter to give the type of the unique keys. * Specify `person` as the third parameter to give the type of the values stored in the map with each key. * Declare and instantiate, as a private data member, an instance of the type `my_map_t`, and name it `my_map`. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md index be19c9554d..87447effd0 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md @@ -9,14 +9,14 @@ This how-to provides instructions to upsert into `Key-Value Map` (`kv map`). Ups ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: -* Install EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -49,7 +49,7 @@ Complete the following steps to insert a new `person` object with a given ID, if 2. Create an instance of the `person` class, named `person_upsert`, based on the input parameters: `account_name`, `first_name` and `last_name`. 3. Use the `[]` operator defined for the `kv::map` type, and set the newly created `person_upsert` object as the value for the `id` key. -Refer to the following possible implementation to insert a new `person` object, and then update it, in the `kv map`: +Refer to the following reference implementation to insert a new `person` object, and then update it, in the `kv map`: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md index 5cd727e298..aeb31cc58a 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md @@ -9,14 +9,14 @@ This how-to provides instructions to delete from `Key-Value Map` (`kv map`) base ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -50,7 +50,7 @@ Complete the following steps to delete a `person` object with a given ID from th 3. If the `person` with the give ID is found use the `erase()` function defined for the `kv::map`, with the given ID as parameter, to erase the person object from the map. 4. If the `person` with the given ID is not found print an informative error message. -Refer to the following possible implementation to delete a `person` object from the `kv map`: +Refer to the following reference implementation to delete a `person` object from the `kv map`: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md index c9c5e31d8a..48a6307da9 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md @@ -9,14 +9,14 @@ This how-to provides instructions to iterate through a `Key-Value Map` (`kv map` ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -43,12 +43,10 @@ class [[eosio::contract]] smartcontract : public eosio::contract { ## Procedure -Complete the following steps to implement an action that is iterating through the first N `person` objects in `kv map` and prints their first and last names: +Complete the following steps to implement an action which iterates through the first N `person` objects in the `kv map` and prints their first and last names: 1. Create a new action `iterate`, which takes as an input parameter the number of iterations to be executed. -2. - -Refer to the following possible implementation to implement an action that is iterating through the first `iterations_count` objects in `my_map` and prints their first and last names: +2. Refer to the following reference implementation to implement an action which iterates through the first `iterations_count` objects in `my_map` and prints their first and last names: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md index 6d8b78fcef..ad3ffc4cd6 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md @@ -9,14 +9,14 @@ This how-to provides instructions to find an object in `Key-Value Map` (`kv map` ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -48,7 +48,7 @@ Complete the following steps to find a `person` object with a given ID: 1. Create a new action in your contract, named `delete`, which takes as input parameters the person ID. 2. Use the `find()` function defined for the `kv::map` type, with the give ID as parameter, to find the `person` with the given ID as unique key. -Refer to the following possible implementation to find `person` object with a given ID as unique key: +Refer to the following reference implementation to find `person` object with a given ID as unique key: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md index fc2b5336c1..ba5943fa1e 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md @@ -1,20 +1,20 @@ --- -content_title: How-To Allow Users to Pay for Key-Value Map Resources -link_text: "How-To Allow Users to Pay for Key-Value Map Resources" +content_title: How-To Create An Action Which Requires The User To Pay +link_text: "How-To Create An Action Which Requires The User To Pay" --- ## Overview -This how-to provides instructions to allow users to pay for the resources needed to store data in a `Key-Value Map` (`kv map`). +This guide provides instructions which show you how to create an action which requires the user to pay for the resources needed to store data in a `Key-Value Map` (`kv map`). -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the map * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -41,13 +41,13 @@ class [[eosio::contract]] smartcontract : public eosio::contract { ## Procedure -Complete the following steps to allow the payer for the resources needed to store the `person` object in the `my_map` object, to be the person account which is stored. +Complete the following steps to create an action which requires the `person`'s account, which is stored in the map, to pay for the resources needed to store the `person` object in the `my_map` object. 1. Create a new action in your contract, named `upsert`, which takes as input parameters the person `id`, an `account_name`, a `first_name` and a `last_name`. 2. Create an instance of the `person` class, named `person_upsert`, based on the input parameters: `account_name`, `first_name` and `last_name`. 3. Use the `[]` operator defined for the `kv::map` type. Pass as the input parameter for the `[]` operator an `std::pair` instance with its first parameter the unique `id` and the second parameter the account which is paying for the resources `account_name`. -Refer to the following possible implementation to insert a new `person` object, and then update it, in the `kv map`: +Refer to the following reference implementation to insert a new `person` object, and then update it, in the `kv map`: `smartcontract.hpp file` @@ -104,7 +104,7 @@ void smartcontract::upsert( ## Summary -In conclusion, the above instructions show how to allow users to pay for the resources needed to store data in a `Key-Value Map` (`kv map`). +In conclusion, the above instructions show how to require the user to pay for the resources needed to store data in a `Key-Value Map` (`kv map`). ## Next Steps diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index 94ada5b62b..60516007aa 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -14,13 +14,13 @@ To accomplish this task, define the user type which will be stored in the `kv ta ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. * A user defined type named `person`, which defines the data stored in the table. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index b83ebe676b..1da41d3cb0 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -19,7 +19,7 @@ The `KV_NAMED_INDEX` macro and the `eosio::kv::table::index` template class are ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` @@ -31,7 +31,7 @@ Complete the following prerequisites: * `last_name`, * `personal_id`. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -61,7 +61,7 @@ class [[eosio::contract]] smrtcontract : public contract { 3. Pass the name of the property for which the index is defined as the second parameter. 4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and the primary index defined previously as the second parameter. -Refer to the following possible implementation of a unique index on property `account_name` using macro `KV_NAMED_INDEX`: +Refer to the following reference implementation of a unique index on property `account_name` using macro `KV_NAMED_INDEX`: `smartcontract.hpp file` @@ -86,7 +86,7 @@ class [[eosio::contract]] smrtcontract : public contract { 2. Pass the name of the index as the first parameter. The parameter must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. Pass the reference to the property for which the index is defined, `&person::personal_id`, as the second parameter. -Refer to the following possible implementation of a unique index on property `personal_id` using `eosio::kv::table::index` template class: +Refer to the following reference implementation of a unique index on property `personal_id` using `eosio::kv::table::index` template class: `smartcontract.hpp file` @@ -115,7 +115,7 @@ class [[eosio::contract]] smrtcontract : public contract { The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameters types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. -Refer to the following possible implementation of a non-unique index on property `account_name` using macro `KV_NAMED_INDEX`: +Refer to the following reference implementation of a non-unique index on property `account_name` using macro `KV_NAMED_INDEX`: `smartcontract.hpp file` @@ -149,7 +149,7 @@ class [[eosio::contract]] smrtcontract : public contract { The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameters types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. -Refer to the following possible implementation of a non-unique index on property `last_name` using `eosio::kv::table::index` template class: +Refer to the following reference implementation of a non-unique index on property `last_name` using `eosio::kv::table::index` template class: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index 9e0bfe7ea3..f9cda5a238 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -14,14 +14,14 @@ Use the method `put` defined by the `eosio::kv::table` type to accomplish this t ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -57,7 +57,7 @@ Complete the following steps to insert a new `person` object, and then update it 2. In the `upsert` action access the instance of `address_table` by declaring a local variable of `address_table` type. 3. And then call the `put` method of the `address_table` and pass to it a newly created `person` object based on the action’s input parameters. -Refer to the following possible implementation to insert a new `person` object, and then update it, in the `kv table`: +Refer to the following reference implementation to insert a new `person` object, and then update it, in the `kv table`: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index 5f21c20ecf..37f9e37f58 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -14,14 +14,14 @@ Use the method `erase` defined by the `eosio::kv::table` type to accomplish this ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -57,7 +57,7 @@ Complete the following steps to delete a `person` object from `address_table`: 2. In the `delete` action access the instance of `address_table` by declaring a local variable of `address_table` type. 3. Call the `erase` method of the `address_table` and pass to it the primary key for the object which is deleted. If you try to erase an object which is not present in the `kv table` no error will be raised. -Refer to the following possible implementation to delete a `person` object from `address_table`: +Refer to the following reference implementation to delete a `person` object from `address_table`: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index 38cb5ace6d..0e4575def4 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -14,7 +14,7 @@ Use the `iterator` defined by the `eosio::kv::table::index` class to accomplish ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. @@ -27,7 +27,7 @@ Complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -57,7 +57,7 @@ class [[eosio::contract]] smrtcontract : public contract { ## Procedure -Complete the following steps to implement an action that is iterating through the first N `person` objects in `address_table` and prints their first and last names: +Complete the following steps to implement an action which iterates through the first N `person` objects in `address_table` and prints their first and last names: 1. Create a new action `iterate`, which takes as an input parameter the number of iterations to be executed. 2. In the `iterate` action access the instance of `address_table` by declaring a local variable of `address_table` type. @@ -65,7 +65,7 @@ Complete the following steps to implement an action that is iterating through th 4. Use the iterator `value` to access the current value of the iterator. 5. And then increment the iterator until the first N `person` objects stored in `address_table` are visited. -Refer to the following possible implementation to implement an action that is iterating through the first N `person` objects in `address_table` and prints their first and last names: +Refer to the following reference implementation to implement an action which iterates through the first N `person` objects in `address_table` and prints their first and last names: `smartcontract.hpp` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index 6f4d33104f..58da59df1a 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -14,7 +14,7 @@ Use the method `exists` defined by the `eosio::kv::table::index` class to accom ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. @@ -27,7 +27,7 @@ Complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -63,7 +63,7 @@ Complete the following steps to implement an action that is verifying whether a 2. In the `verify` action access the instance of `address_table` by declaring a local variable of `address_table` type. 3. Call the `exists()` method of the `account_name` index defined in the `kv table` class and pass the account name of the person to be verified. -Refer to the following possible implementation to implement an action that is verifying whether a particular `person` identified by its `account_name` exists in the `address_table`: +Refer to the following reference implementation to implement an action that is verifying whether a particular `person` identified by its `account_name` exists in the `address_table`: `smartcontract.hpp` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index 6192a387c6..d365c73cb8 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -14,7 +14,7 @@ Use the method `find()` defined by the `eosio::kv::table::index` class to accom ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. @@ -27,7 +27,7 @@ Complete the following prerequisites: * `personal_id`. * A unique index, named `account_name_uidx`, defined on the `account_name` property.. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -64,7 +64,7 @@ Complete the following steps to implement an action to find a particular `person 3. Call the `find` method of the `account_name` index defined in the table and pass the account name of the person to be verified. 4. Check if the `person` was found and return it back to the caller; if person was not found return an empty `person` object. -Refer to the following possible implementation to implement an action to find a particular `person` identified by the `account_name` in the `address_table` and returns the person back to the caller: +Refer to the following reference implementation to implement an action to find a particular `person` identified by the `account_name` in the `address_table` and returns the person back to the caller: `smartcontract.hpp` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index 852797ad53..d7f632b276 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -14,7 +14,7 @@ Use the method `range` defined by the `eosio::kv::table::index` class to accompl ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `smrtcontract`. @@ -28,7 +28,7 @@ Complete the following prerequisites: * A unique index, named `account_name_uidx`, defined on the `account_name` property.. * A non-unique index defined on the `last_name` property, named `last_name_idx`. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -70,7 +70,7 @@ Complete the following steps to implement an action to retrieve a list of person 2. The second parameter is a person object with its account name equal to `the maximum possible value for an account name` and its last name the same value to filter by the persons in the `address_table`. 3. Return back to the caller the list of persons the `range()` function returns. -Refer to the following possible implementation to implement an action to retrieve a list of persons with the same name from `address_table` and return it back to the caller: +Refer to the following reference implementation to implement an action to retrieve a list of persons with the same name from `address_table` and return it back to the caller: `smartcontract.hpp` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index 3824fcb20e..448c5d039e 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -5,7 +5,7 @@ link_text: "How-To Allow Users to Pay for Key-Value Table Resources" ## Overview -This how-to provides instructions to allow users to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). +This guide provides instructions which show you how to allow users to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. @@ -14,14 +14,14 @@ Use the method `put` defined by the `eosio::kv::table` type to accomplish this t ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table * A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: `smartcontract.hpp file` @@ -57,7 +57,7 @@ Complete the following steps to allow a specific account name to be the payer fo 2. In the `upsert` action access the instance of `address_table` belonging to this contract by declaring a local variable of `address_table` type and pass the contract name as paramter. 3. And then call the `put` method of the `address_table` and pass to it a newly created `person` object based on the action’s input parameters and the payer account name. -Refer to the following possible implementation to allow a specific account name to be the payer for the resources needed to store a person object in the `kv table`: +Refer to the following reference implementation to allow a specific account name to be the payer for the resources needed to store a person object in the `kv table`: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md index 8c337f83b8..cce2bca91c 100644 --- a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md +++ b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md @@ -5,17 +5,23 @@ link_text: "How to create and use action wrappers" ## Overview -This how-to guide provides instructions on how to create and use an action wrapper in a smart contract. +This guide provides instructions on how to create and use an action wrapper in a smart contract. + +## Code Reference + +See the following code reference guide for action wrapper: + +* [eosio::action_wrapper](../structeosio_1_1action__wrapper). ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract named `multi_index_example`, defined in file `multi_index_example.hpp`. * An action `mod` which modifies the integer value `n` stored for row with key `user`. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: ```cpp class [[eosio::contract]] multi_index_example : public contract { @@ -25,15 +31,9 @@ class [[eosio::contract]] multi_index_example : public contract { } ``` -## Code Reference - -See the following code reference guide for action wrapper: - -* [eosio::action_wrapper](../structeosio_1_1action__wrapper). - ## Procedure -Complete the following steps to create and use action wrapper in the smart contract: +Complete the following steps to create and use `mod_action` action wrapper for the existing `mod` action in the smart contract: 1. [Define the action wrapper](#1-define-the-action-wrapper) 2. [Use the action wrapper](#2-use-the-action-wrapper) diff --git a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md index 40ae679320..6a5c60cf4a 100644 --- a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md +++ b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md @@ -10,13 +10,13 @@ In order to accomplish this, use the `return` statement and pass the desired ret ## Before you begin -Complete the following prerequisites: +Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). * A smart contract, let’s call it `smrtcontract`, which builds without error. * An action, let’s call it `checkwithrv`, from which you want to return a value of a user defined type `action_response`. -Refer to the following possible implementation for your starting point: +Refer to the following reference implementation for your starting point: ```cpp struct action_response @@ -38,7 +38,7 @@ class [[eosio::contract]] smrtcontract : public contract { Complete the following steps to return an instance of `action_response` from the `checkwithrv` action: -1. Create an instance of `action_response` C++ defined structure. +1. Create an instance of the `action_response` C++ user defined structure. 2. Initialize its data members based on the action’s business logic. 3. Use `return` statement and pass as a parameter the instance created and initialized in previous steps. @@ -75,7 +75,7 @@ The following options are available when you complete the procedure: * Use other means (e.g. programmatically) to send the `checkwithrv` action to the smart contract and observe the returned value in the action trace. [[info | Returned values from actions availability]] -The returned values from actions are only available to the clients sending the action via the RPC API. Currently, there is no support for an inline action to be able to use the return value, because inline actions don't execute synchronously. +The action return values are only available to clients sending the action via the RPC API. Currently, there is no support for an inline action to be able to use the return value, because inline actions don't execute synchronously. ## Summary From 6ed716efae7127697c372a1178f716b390ee2458 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 14 Apr 2021 14:16:31 +0300 Subject: [PATCH 092/204] updates on the payer how to --- .../kv_table/90_how-to-allow-users-to-pay-kv-table.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index 448c5d039e..bfe8d133f6 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -1,11 +1,11 @@ --- -content_title: How-To Allow Users to Pay for Key-Value Table Resources -link_text: "How-To Allow Users to Pay for Key-Value Table Resources" +content_title: How-To Create An Action Which Requires The User To Pay +link_text: "How-To Create An Action Which Requires The User To Pay" --- ## Overview -This guide provides instructions which show you how to allow users to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). +This guide provides instructions which show you how to create an action which requires the user to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. @@ -51,7 +51,7 @@ class [[eosio::contract]] smrtcontract : public contract { ## Procedure -Complete the following steps to allow a specific account name to be the payer for the resources needed to store a person object in the `kv table`: +Complete the following steps to allow the `payer` account, to be the payer for the resources needed to store a person object in the `kv table`: 1. Create a new action `upsert` in your smart contact class, which takes as input parameters an `account name, a first name, a last name, a personal id` which define a person data, and an `account name` for the payer. 2. In the `upsert` action access the instance of `address_table` belonging to this contract by declaring a local variable of `address_table` type and pass the contract name as paramter. @@ -109,7 +109,7 @@ void smrtcontract::upsert( ## Summary -In conclusion, the above instructions show how to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). +In conclusion, the above instructions show how to create an action which requires the user to pay for the resources needed to store data in a `Key-Value Table` (`kv table`). ## Next Steps From eb3d84ca84452083a27d03c1bec5f6667bd4db46 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 15 Apr 2021 14:40:10 +0300 Subject: [PATCH 093/204] adding improvementes based on code review --- .../10_compile/01_compile-a-contract-via-cli.md | 13 +++++++++++++ .../kv_table/20_how-to-create-indexes-kv-table.md | 12 ++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md index 2014a1c326..ce8d2d62e2 100644 --- a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md +++ b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md @@ -6,6 +6,12 @@ content_title: How to compile a smart contract via CLI This guide provides instructions how to compile a smart contract using the command line interface (CLI). +## Reference + +See the following code reference: + +* The [`eosio-cpp`](https://developers.eos.io/manuals/eosio.cdt/v1.8/command-reference/eosio-cpp) tool. + ## Before you begin * You have the source of the contract saved in a local folder, e.g. `./examples/hello/` @@ -25,6 +31,13 @@ Follow the following steps to compile your contract. eosio-cpp -abigen ../src/hello.cpp -o hello.wasm -I ../include/ ``` + Where: + - `eosio-cpp` = Is the [`eosio-cpp`](https://developers.eos.io/manuals/eosio.cdt/v1.8/command-reference/eosio-cpp) tool. + - `-abigen` = It instructs the `eosio-cpp` tool to generate ABI file. + - `../src/hello.cpp` = Is the input cpp source file to be compiled. + - `-o hello.wasm` = It instructs the `eosio-cpp` tool who to name the output wasm file. + - `-I ../include/` = It tells `eosio-cpp` tool what the include folder path is, in this particular case it is relative path. + 3. Verify the following two files were generated: * the compiled binary wasm: `hello.wasm`, diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index 1da41d3cb0..4e5867bcf8 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -59,7 +59,7 @@ class [[eosio::contract]] smrtcontract : public contract { 1. Use the `KV_NAMED_INDEX` macro with two parameters. 2. Pass the name of the index as the first parameter. The parameter must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. Pass the name of the property for which the index is defined as the second parameter. -4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and the primary index defined previously as the second parameter. +4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and `account_name` index defined previously, by the KV_NAMED_INDEX macro, as the second parameter. Refer to the following reference implementation of a unique index on property `account_name` using macro `KV_NAMED_INDEX`: @@ -85,6 +85,7 @@ class [[eosio::contract]] smrtcontract : public contract { 1. Use the `eosio::kv::table::index` template class with two parameters. 2. Pass the name of the index as the first parameter. The parameter must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. Pass the reference to the property for which the index is defined, `&person::personal_id`, as the second parameter. +4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and the `personal_id_idx` index defined previously as the second parameter. Refer to the following reference implementation of a unique index on property `personal_id` using `eosio::kv::table::index` template class: @@ -112,8 +113,9 @@ class [[eosio::contract]] smrtcontract : public contract { 1. Use the `KV_NAMED_INDEX` with two parameters. 2. Pass the name of the index as the first parameter. The parameter must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. Pass the name of the property for which the index is defined as the second parameter. +4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and `first_name` index defined previously, by the KV_NAMED_INDEX macro, as the second parameter. -The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameters types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. +The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. Refer to the following reference implementation of a non-unique index on property `account_name` using macro `KV_NAMED_INDEX`: @@ -146,8 +148,10 @@ class [[eosio::contract]] smrtcontract : public contract { 1. Use the `eosio::kv::table::index` template class. 2. Pass as the first parameter the name of the index. It must be a qualified `eosio:name`, see documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. Pass the reference to the property for which the index is defined, `&person::last_name`, as the second parameter. +4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and the `last_name_idx` index defined previously as the second parameter. -The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameters types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. + +The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. Refer to the following reference implementation of a non-unique index on property `last_name` using `eosio::kv::table::index` template class: @@ -169,7 +173,7 @@ class [[eosio::contract]] smrtcontract : public contract { &person::last_name}; address_table(eosio::name contract_name) { - init(contract_name, last_name) + init(contract_name, last_name_idx) } }; public: From b84758e8318fea13765ce5d1db2edc7bf15c8e64 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Thu, 15 Apr 2021 09:54:01 -0400 Subject: [PATCH 094/204] add static_asser to test constexpr --- tests/unit/name_tests.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/unit/name_tests.cpp b/tests/unit/name_tests.cpp index 89e67ee2d6..decfeee42f 100644 --- a/tests/unit/name_tests.cpp +++ b/tests/unit/name_tests.cpp @@ -29,6 +29,10 @@ EOSIO_TEST_BEGIN(name_type_test_ctr_num) CHECK_EQUAL( name{name::raw{0ULL}}.value, 0ULL ) CHECK_EQUAL( name{name::raw{1ULL}}.value, 1ULL ) CHECK_EQUAL( name{name::raw{u64max}}.value, u64max ) + + // test that constexpr constructor is evaluated at compile time + static_assert(name{0ULL}.value == 0ULL); + static_assert( name{name::raw{1ULL}}.value == 1ULL ); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_ctr_str_lit) @@ -59,6 +63,9 @@ EOSIO_TEST_BEGIN(name_type_test_ctr_str_lit) CHECK_EQUAL( name{"555555555555j"}.value, 2975281302211218015ULL ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"}.value, 3570337562653461615ULL ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"}.value, u64max ) + + // test that constexpr constructor is evaluated at compile time + static_assert(name{"1"}.value == 576460752303423488ULL); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_str_not_allowed) @@ -119,7 +126,7 @@ EOSIO_TEST_BEGIN(name_type_test_str_len) CHECK_EQUAL( name{"eosioaccountj"}.length(), 13 ) EOSIO_TEST_END -EOSIO_TEST_BEGIN(name_type_test_6) +EOSIO_TEST_BEGIN(name_type_test_str_too_long) CHECK_ASSERT( "string is too long to be a valid name", ([]() {name{"12345abcdefghj"}.length();}) ) EOSIO_TEST_END @@ -168,6 +175,8 @@ EOSIO_TEST_BEGIN(name_type_test_prefix) CHECK_EQUAL( name{"a.my.account"}.prefix(), name{"a.my"} ) CHECK_EQUAL( name{"a.my.account"}.prefix().prefix(), name{"a"} ) + + static_assert(name{"e.osioaccounj"}.prefix() == name{"e"}); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_raw) @@ -214,6 +223,8 @@ EOSIO_TEST_BEGIN(name_type_test_op_bool) CHECK_EQUAL( name{"1"}.operator bool(), true ) CHECK_EQUAL( !name{""}.operator bool(), true ) CHECK_EQUAL( !name{"1"}.operator bool(), false ) + + static_assert(name{0}.operator bool() == false); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_memcmp) @@ -333,6 +344,9 @@ EOSIO_TEST_BEGIN(name_type_test_equal) CHECK_EQUAL( name{"555555555555j"} == name{"555555555555j"}, true ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"} == name{"aaaaaaaaaaaaj"}, true ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} == name{"zzzzzzzzzzzzj"}, true ) + + // test constexpr + static_assert(name{"1"} == name{"1"}); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_not_equal) @@ -363,6 +377,9 @@ EOSIO_TEST_BEGIN(name_type_test_not_equal) CHECK_EQUAL( name{"555555555555j"} != name{}, true ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"} != name{}, true ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} != name{}, true ) + + // test constexpr + static_assert(name{"1"} != name{"2"}); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_less_than) @@ -393,6 +410,9 @@ EOSIO_TEST_BEGIN(name_type_test_less_than) CHECK_EQUAL( name{} < name{"555555555555j"}, true ) CHECK_EQUAL( name{} < name{"aaaaaaaaaaaaj"}, true ) CHECK_EQUAL( name{} < name{"zzzzzzzzzzzzj"}, true ) + + // test constexpr + static_assert(name{} < name{"1"}); EOSIO_TEST_END @@ -426,6 +446,9 @@ EOSIO_TEST_BEGIN(name_type_test_op_n) CHECK_EQUAL( name{"555555555555j"}, "555555555555j"_n ) CHECK_EQUAL( name{"aaaaaaaaaaaaj"}, "aaaaaaaaaaaaj"_n ) CHECK_EQUAL( name{"zzzzzzzzzzzzj"}, "zzzzzzzzzzzzj"_n ) + + // test constexpr + static_assert(name{"1"} == "1"_n ); EOSIO_TEST_END int main(int argc, char* argv[]) { From e0380932699fed60c6ccd905d1746685d0ca58e3 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Thu, 15 Apr 2021 15:26:11 -0400 Subject: [PATCH 095/204] fixed formatting in static_assert --- tests/unit/name_tests.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/unit/name_tests.cpp b/tests/unit/name_tests.cpp index decfeee42f..09b23b06e6 100644 --- a/tests/unit/name_tests.cpp +++ b/tests/unit/name_tests.cpp @@ -31,7 +31,7 @@ EOSIO_TEST_BEGIN(name_type_test_ctr_num) CHECK_EQUAL( name{name::raw{u64max}}.value, u64max ) // test that constexpr constructor is evaluated at compile time - static_assert(name{0ULL}.value == 0ULL); + static_assert( name{0ULL}.value == 0ULL ); static_assert( name{name::raw{1ULL}}.value == 1ULL ); EOSIO_TEST_END @@ -65,7 +65,7 @@ EOSIO_TEST_BEGIN(name_type_test_ctr_str_lit) CHECK_EQUAL( name{"zzzzzzzzzzzzj"}.value, u64max ) // test that constexpr constructor is evaluated at compile time - static_assert(name{"1"}.value == 576460752303423488ULL); + static_assert( name{"1"}.value == 576460752303423488ULL ); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_str_not_allowed) @@ -176,7 +176,7 @@ EOSIO_TEST_BEGIN(name_type_test_prefix) CHECK_EQUAL( name{"a.my.account"}.prefix(), name{"a.my"} ) CHECK_EQUAL( name{"a.my.account"}.prefix().prefix(), name{"a"} ) - static_assert(name{"e.osioaccounj"}.prefix() == name{"e"}); + static_assert( name{"e.osioaccounj"}.prefix() == name{"e"} ); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_raw) @@ -224,7 +224,7 @@ EOSIO_TEST_BEGIN(name_type_test_op_bool) CHECK_EQUAL( !name{""}.operator bool(), true ) CHECK_EQUAL( !name{"1"}.operator bool(), false ) - static_assert(name{0}.operator bool() == false); + static_assert( name{0}.operator bool() == false ); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_memcmp) @@ -346,7 +346,7 @@ EOSIO_TEST_BEGIN(name_type_test_equal) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} == name{"zzzzzzzzzzzzj"}, true ) // test constexpr - static_assert(name{"1"} == name{"1"}); + static_assert( name{"1"} == name{"1"} ); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_not_equal) @@ -379,7 +379,7 @@ EOSIO_TEST_BEGIN(name_type_test_not_equal) CHECK_EQUAL( name{"zzzzzzzzzzzzj"} != name{}, true ) // test constexpr - static_assert(name{"1"} != name{"2"}); + static_assert( name{"1"} != name{"2"} ); EOSIO_TEST_END EOSIO_TEST_BEGIN(name_type_test_less_than) @@ -412,7 +412,7 @@ EOSIO_TEST_BEGIN(name_type_test_less_than) CHECK_EQUAL( name{} < name{"zzzzzzzzzzzzj"}, true ) // test constexpr - static_assert(name{} < name{"1"}); + static_assert( name{} < name{"1"} ); EOSIO_TEST_END @@ -448,7 +448,7 @@ EOSIO_TEST_BEGIN(name_type_test_op_n) CHECK_EQUAL( name{"zzzzzzzzzzzzj"}, "zzzzzzzzzzzzj"_n ) // test constexpr - static_assert(name{"1"} == "1"_n ); + static_assert( name{"1"} == "1"_n ); EOSIO_TEST_END int main(int argc, char* argv[]) { From 3bcf551ecef8edf7bb172f88508ca414aade6be1 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 19 Apr 2021 10:37:20 -0400 Subject: [PATCH 096/204] check local function pointers --- .../compile-fail/hf_indirect_call_tests.json | 2 +- tools/include/eosio/codegen.hpp | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/tests/toolchain/compile-fail/hf_indirect_call_tests.json b/tests/toolchain/compile-fail/hf_indirect_call_tests.json index a5ed8bad19..e8a59a88a0 100644 --- a/tests/toolchain/compile-fail/hf_indirect_call_tests.json +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.json @@ -4,7 +4,7 @@ "compile_flags": [], "expected" : { "exit-code": 255, - "stderr": "(codegen error.*){8}" + "stderr": "(codegen error.*){11}" } } ] diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 4f05f84799..a25724e65c 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -94,11 +94,13 @@ namespace eosio { namespace cdt { public: using call_map_t = std::map>; + using indirect_func_map_t = std::map; std::vector action_decls; std::vector notify_decls; std::set read_only_actions; call_map_t func_calls; + indirect_func_map_t indi_func_map; explicit eosio_codegen_visitor(CompilerInstance *CI) : generation_utils(), ci(CI) { @@ -247,6 +249,7 @@ namespace eosio { namespace cdt { if (decl->isEosioReadOnly()) { read_only_actions.insert(decl); + func_calls[decl] = {(CallExpr*)decl}; } } else if (decl->isEosioNotify()) { @@ -298,6 +301,51 @@ namespace eosio { namespace cdt { func_calls[func_decl].push_back(call); break; } + } else { + if (Expr *expr = call->getCallee()) { + while (ImplicitCastExpr *ice = dyn_cast(expr)) { + expr = ice->getSubExpr(); + } + if (DeclRefExpr *dre = dyn_cast(expr)) { + if (indi_func_map.count(dre->getFoundDecl()) != 0) { + func_calls[func_decl].push_back(call); + } + } + } + } + } else if (DeclStmt *ds = dyn_cast(s)) { + if (ds->isSingleDecl()) { + if (VarDecl *vd = dyn_cast(ds->getSingleDecl())) { + if (Expr *init = vd->getInit()) { + while (ImplicitCastExpr *ice = dyn_cast(init)) { + init = ice->getSubExpr(); + } + if (DeclRefExpr *dre = dyn_cast(init)) { + if (FunctionDecl *fd = dyn_cast(dre->getFoundDecl())) { + if (func_calls.count(fd) != 0) { + indi_func_map[vd] = fd; + } + } + } + } + } + } + } else if (BinaryOperator *bo = dyn_cast(s)) { + if (Expr *lhs = bo->getLHS()) { + if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { + if (Expr *rhs = bo->getRHS()) { + while (ImplicitCastExpr *ice = dyn_cast(rhs)) { + rhs = ice->getSubExpr(); + } + if (DeclRefExpr *rhs_dre = dyn_cast(rhs)) { + if (FunctionDecl *fd = dyn_cast(rhs_dre->getFoundDecl())) { + if (func_calls.count(fd) != 0) { + indi_func_map[lhs_dre->getFoundDecl()] = fd; + } + } + } + } + } } } } From 61a24c0b9f17906eed0a9517d18492ae906f63dc Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 19 Apr 2021 15:38:07 -0400 Subject: [PATCH 097/204] fix read-only action calling issue --- .../compile-fail/hf_indirect_call_tests.json | 2 +- tools/include/eosio/codegen.hpp | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/tests/toolchain/compile-fail/hf_indirect_call_tests.json b/tests/toolchain/compile-fail/hf_indirect_call_tests.json index e8a59a88a0..49d3b84555 100644 --- a/tests/toolchain/compile-fail/hf_indirect_call_tests.json +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.json @@ -4,7 +4,7 @@ "compile_flags": [], "expected" : { "exit-code": 255, - "stderr": "(codegen error.*){11}" + "stderr": "(codegen error.*){12}" } } ] diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index a25724e65c..d661598f97 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -249,7 +249,6 @@ namespace eosio { namespace cdt { if (decl->isEosioReadOnly()) { read_only_actions.insert(decl); - func_calls[decl] = {(CallExpr*)decl}; } } else if (decl->isEosioNotify()) { @@ -301,15 +300,13 @@ namespace eosio { namespace cdt { func_calls[func_decl].push_back(call); break; } - } else { - if (Expr *expr = call->getCallee()) { - while (ImplicitCastExpr *ice = dyn_cast(expr)) { - expr = ice->getSubExpr(); - } - if (DeclRefExpr *dre = dyn_cast(expr)) { - if (indi_func_map.count(dre->getFoundDecl()) != 0) { - func_calls[func_decl].push_back(call); - } + } else if (Expr *expr = call->getCallee()) { + while (ImplicitCastExpr *ice = dyn_cast(expr)) { + expr = ice->getSubExpr(); + } + if (DeclRefExpr *dre = dyn_cast(expr)) { + if (indi_func_map.count(dre->getFoundDecl()) != 0) { + func_calls[func_decl].push_back(call); } } } From 17a0a297a03a5425d9603b4193fd6d266e7cc518 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Thu, 22 Apr 2021 10:08:36 -0400 Subject: [PATCH 098/204] check global function pointer for write function --- tools/include/eosio/codegen.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index d661598f97..f3013b7090 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -350,6 +350,10 @@ namespace eosio { namespace cdt { } } + void process_class() { + // TODO(handel member variables) + } + virtual bool VisitFunctionDecl(FunctionDecl* func_decl) { SourceManager &sm = get_rewriter().getSourceMgr(); if (sm.isInSystemHeader(func_decl->getLocation()) || sm.isInExternCSystemHeader(func_decl->getLocation())) { @@ -369,6 +373,21 @@ namespace eosio { namespace cdt { if (auto* fd = dyn_cast(decl)) { if (fd->getNameInfo().getAsString() == "apply") apply_was_found = true; + } else if (auto* vd = dyn_cast(decl)) { + if (vd->hasGlobalStorage()) { + if (Expr *init = vd->getInit()) { + while (ImplicitCastExpr *ice = dyn_cast(init)) { + init = ice->getSubExpr(); + } + if (DeclRefExpr *dre = dyn_cast(init)) { + if (FunctionDecl *fd = dyn_cast(dre->getFoundDecl())) { + if (func_calls.count(fd) != 0) { + indi_func_map[vd] = fd; + } + } + } + } + } } return true; } From e4beb61b7b28fe7360394a2821b63469d245d559 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 26 Apr 2021 10:39:29 -0400 Subject: [PATCH 099/204] check class data members for write funciton --- tools/include/eosio/codegen.hpp | 79 +++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index f3013b7090..6ff54b0137 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -280,7 +280,19 @@ namespace eosio { namespace cdt { return true; } - void process_function(FunctionDecl *func_decl) { + FunctionDecl* get_rhs_fd(Expr *rhs) const { + while (ImplicitCastExpr *ice = dyn_cast(rhs)) { + rhs = ice->getSubExpr(); + } + if (DeclRefExpr *rhs_dre = dyn_cast(rhs)) { + if (FunctionDecl *fd = dyn_cast(rhs_dre->getFoundDecl())) { + return fd; + } + } + return nullptr; + } + + void process_function(FunctionDecl* func_decl) { if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { Stmt *stmts = func_decl->getBody(); for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { @@ -308,20 +320,19 @@ namespace eosio { namespace cdt { if (indi_func_map.count(dre->getFoundDecl()) != 0) { func_calls[func_decl].push_back(call); } + } else if (MemberExpr *me = dyn_cast(expr)) { + if (indi_func_map.count(me->getMemberDecl()) != 0) { + func_calls[func_decl].push_back(call); + } } } } else if (DeclStmt *ds = dyn_cast(s)) { if (ds->isSingleDecl()) { if (VarDecl *vd = dyn_cast(ds->getSingleDecl())) { if (Expr *init = vd->getInit()) { - while (ImplicitCastExpr *ice = dyn_cast(init)) { - init = ice->getSubExpr(); - } - if (DeclRefExpr *dre = dyn_cast(init)) { - if (FunctionDecl *fd = dyn_cast(dre->getFoundDecl())) { - if (func_calls.count(fd) != 0) { - indi_func_map[vd] = fd; - } + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[vd] = fd; } } } @@ -329,16 +340,13 @@ namespace eosio { namespace cdt { } } else if (BinaryOperator *bo = dyn_cast(s)) { if (Expr *lhs = bo->getLHS()) { - if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { - if (Expr *rhs = bo->getRHS()) { - while (ImplicitCastExpr *ice = dyn_cast(rhs)) { - rhs = ice->getSubExpr(); - } - if (DeclRefExpr *rhs_dre = dyn_cast(rhs)) { - if (FunctionDecl *fd = dyn_cast(rhs_dre->getFoundDecl())) { - if (func_calls.count(fd) != 0) { - indi_func_map[lhs_dre->getFoundDecl()] = fd; - } + if (Expr *rhs = bo->getRHS()) { + if (FunctionDecl *fd = get_rhs_fd(rhs)) { + if (func_calls.count(fd) != 0) { + if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { + indi_func_map[lhs_dre->getFoundDecl()] = fd; + } else if (MemberExpr *lhs_me = dyn_cast(lhs)) { + indi_func_map[lhs_me->getMemberDecl()] = fd; } } } @@ -350,8 +358,18 @@ namespace eosio { namespace cdt { } } - void process_class() { - // TODO(handel member variables) + void process_class(CXXRecordDecl* decl) { + for(auto it = decl->decls_begin(); it != decl->decls_end(); ++it) { + if(FieldDecl *f = dyn_cast(*it) ) { + if (Expr *init = f->getInClassInitializer()) { + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[f] = fd; + } + } + } + } + } } virtual bool VisitFunctionDecl(FunctionDecl* func_decl) { @@ -376,14 +394,9 @@ namespace eosio { namespace cdt { } else if (auto* vd = dyn_cast(decl)) { if (vd->hasGlobalStorage()) { if (Expr *init = vd->getInit()) { - while (ImplicitCastExpr *ice = dyn_cast(init)) { - init = ice->getSubExpr(); - } - if (DeclRefExpr *dre = dyn_cast(init)) { - if (FunctionDecl *fd = dyn_cast(dre->getFoundDecl())) { - if (func_calls.count(fd) != 0) { - indi_func_map[vd] = fd; - } + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[vd] = fd; } } } @@ -391,6 +404,14 @@ namespace eosio { namespace cdt { } return true; } + + virtual bool VisitCXXRecordDecl(CXXRecordDecl* decl) { + codegen& cg = codegen::get(); + if (decl->isEosioContract()) { + process_class(decl); + } + return true; + } }; class eosio_codegen_consumer : public ASTConsumer, public generation_utils { From add76f9845568940cad557e8e1ee81b4e8c61a76 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 26 Apr 2021 18:13:15 -0400 Subject: [PATCH 100/204] fix function pointer reassignment --- .../compile-fail/hf_indirect_call_tests.cpp | 132 +++++++++++++++++- .../compile-fail/hf_indirect_call_tests.json | 2 +- tools/cc/eosio-cpp.cpp.in | 2 +- tools/include/eosio/codegen.hpp | 25 ++-- tools/include/eosio/gen.hpp | 1 - 5 files changed, 144 insertions(+), 18 deletions(-) diff --git a/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp b/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp index 198e93b2e0..76c7b547b9 100644 --- a/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp @@ -23,13 +23,24 @@ */ extern "C" __attribute__((eosio_wasm_import)) void set_resource_limit(int64_t, int64_t, int64_t); - +extern "C" __attribute__((eosio_wasm_import)) void foo_bar(int64_t, int64_t, int64_t); #define ACTION_TYPE [[eosio::action, eosio::read_only]] +using func = void (*)(int64_t, int64_t, int64_t); + +func srl_g1 = set_resource_limit; +func srl_g2 = set_resource_limit; +func srl_g3; +func fb_g = foo_bar; + class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { public: using contract::contract; + func srl_m1 = set_resource_limit; + func srl_m2 = set_resource_limit; + func srl_m3; + func fb_m = foo_bar; ACTION_TYPE bool tlambda() { @@ -39,6 +50,7 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { set_rsc(); return true; } + ACTION_TYPE bool tlambdap() { auto set_rsc = [](int64_t a, int64_t b, int64_t c){ @@ -47,6 +59,7 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { set_rsc(0, 0, 0); return true; } + ACTION_TYPE bool tlambdap2(int64_t a, int64_t b, int64_t c) { auto set_rsc = [=](int64_t x, int64_t y, int64_t z){ @@ -55,31 +68,137 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { set_rsc(a, b, c); return true; } - using func = void (*)(int64_t, int64_t, int64_t); + ACTION_TYPE bool talias () { func srl = set_resource_limit; srl(0,0,0); return true; } - #define setfun set_resource_limit + + ACTION_TYPE + bool taliasg1() { + srl_g1(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasg2 () { + srl_g2 = foo_bar; + srl_g2(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasg3 () { + srl_g3 = set_resource_limit; + srl_g3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasg3re1 () { + srl_g3 = foo_bar; + srl_g3(0,0,0); + srl_g3 = set_resource_limit; + srl_g3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasg3re2 () { + srl_g3 = set_resource_limit; + srl_g3 = foo_bar; + srl_g3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasg3re3 () { + srl_g3 = foo_bar; + srl_g3 = set_resource_limit; + srl_g3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasgr () { + fb_g(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasm1 () { + srl_m1(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasm2 () { + srl_m2 = foo_bar; + srl_m2(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasm3 () { + srl_m3 = set_resource_limit; + srl_m3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasm3re1 () { + srl_m3 = foo_bar; + srl_m3(0,0,0); + srl_m3 = set_resource_limit; + srl_m3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasm3re2 () { + srl_m3 = set_resource_limit; + srl_m3 = foo_bar; + srl_m3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasm3re3 () { + srl_m3 = foo_bar; + srl_m3 = set_resource_limit; + srl_m3(0,0,0); + return true; + } + + ACTION_TYPE + bool taliasmr () { + fb_m(0,0,0); + return true; + } + + #define setfun set_resource_limit ACTION_TYPE bool tdefine(){ setfun(0,0,0); return true; } - #define setfunp() set_resource_limit(0,0,0) + + #define setfunp() set_resource_limit(0,0,0) ACTION_TYPE bool tdefinep(){ setfunp(); return true; } - #define setfunpi(a, b, c) set_resource_limit(a,b,c) + + #define setfunpi(a, b, c) set_resource_limit(a,b,c) ACTION_TYPE bool tdefinepi(){ setfunpi(0,0,0); return true; } + ACTION_TYPE bool combine(){ func srl = set_resource_limit; @@ -89,6 +208,7 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { setfunpi(0,0,0); return true; } + ACTION_TYPE bool combinea(){ tlambdap(); @@ -100,6 +220,7 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { combine(); return true; } + ACTION_TYPE bool combinec(){ auto set_rsc = [](){ @@ -110,6 +231,7 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { set_rsc(); return true; } + ACTION_TYPE bool combinecp(){ auto set_rsc = [](int64_t a, int64_t b, int64_t c){ diff --git a/tests/toolchain/compile-fail/hf_indirect_call_tests.json b/tests/toolchain/compile-fail/hf_indirect_call_tests.json index 49d3b84555..eb74c58a93 100644 --- a/tests/toolchain/compile-fail/hf_indirect_call_tests.json +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.json @@ -4,7 +4,7 @@ "compile_flags": [], "expected" : { "exit-code": 255, - "stderr": "(codegen error.*){12}" + "stderr": "(codegen error.*){20}" } } ] diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index 3d268d602b..5e730bb3a4 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -74,7 +74,7 @@ void generate(const std::vector& base_options, std::string input, s if (tool_run != 0) { throw std::runtime_error("abigen error"); } - + if (!abigen::get().is_empty()) { std::string abi_s; abigen::get().to_json().dump(abi_s); diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 6ff54b0137..4d818f91ce 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -292,6 +292,14 @@ namespace eosio { namespace cdt { return nullptr; } + void update_indi_func_map(NamedDecl *nd, FunctionDecl *fd) { + if (func_calls.count(fd) != 0) { + indi_func_map[nd] = fd; + } else if (indi_func_map.count(nd)){ + indi_func_map.erase(nd); + } + } + void process_function(FunctionDecl* func_decl) { if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { Stmt *stmts = func_decl->getBody(); @@ -339,16 +347,13 @@ namespace eosio { namespace cdt { } } } else if (BinaryOperator *bo = dyn_cast(s)) { - if (Expr *lhs = bo->getLHS()) { - if (Expr *rhs = bo->getRHS()) { - if (FunctionDecl *fd = get_rhs_fd(rhs)) { - if (func_calls.count(fd) != 0) { - if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { - indi_func_map[lhs_dre->getFoundDecl()] = fd; - } else if (MemberExpr *lhs_me = dyn_cast(lhs)) { - indi_func_map[lhs_me->getMemberDecl()] = fd; - } - } + Expr *lhs = nullptr, *rhs = nullptr; + if ((lhs = bo->getLHS()) && (rhs = bo->getRHS())) { + if (FunctionDecl *fd = get_rhs_fd(rhs)) { + if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { + update_indi_func_map(lhs_dre->getFoundDecl(), fd); + } else if (MemberExpr *lhs_me = dyn_cast(lhs)) { + update_indi_func_map(lhs_me->getMemberDecl(), fd); } } } diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index 664203c873..e67ea3a044 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -726,7 +726,6 @@ struct generation_utils { "eosio::kv::internal_use_do_not_use::kv_set", // deferred transactions "eosio::chain::webassembly::interface::send_deferred", - "eosio::chain::webassembly::interface::send_deferred" "eosio::send_deferred", // inline actions "eosio::internal_use_do_not_use::send_inline", From f83a8e3caaf26f695f8e7d38ab41d926796c49ef Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 29 Apr 2021 01:03:45 +0300 Subject: [PATCH 101/204] [docs] update Info->info Info->info --- .../40_multi-index/how-to-instantiate-a-multi-index-table.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index 607508dae5..b2b828c00a 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -129,5 +129,5 @@ class [[eosio::contract]] multi_index_example : public contract { }; ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). From f5cef84aa0bc6fb766a81df20ca6e76816267d5e Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Thu, 29 Apr 2021 10:15:34 -0400 Subject: [PATCH 102/204] code clean-up for different statement types --- tools/include/eosio/codegen.hpp | 131 ++++++++++++++++++-------------- 1 file changed, 75 insertions(+), 56 deletions(-) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index 4d818f91ce..d993dcaba4 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -93,11 +93,12 @@ namespace eosio { namespace cdt { bool apply_was_found = false; public: + std::vector action_decls; + std::vector notify_decls; + using call_map_t = std::map>; using indirect_func_map_t = std::map; - std::vector action_decls; - std::vector notify_decls; std::set read_only_actions; call_map_t func_calls; indirect_func_map_t indi_func_map; @@ -280,6 +281,23 @@ namespace eosio { namespace cdt { return true; } + void process_indi_callee(FunctionDecl* fd, CallExpr *call) { + if (Expr *expr = call->getCallee()) { + while (auto* ice = dyn_cast(expr)) { + expr = ice->getSubExpr(); + } + if (auto* dre = dyn_cast(expr)) { + if (indi_func_map.count(dre->getFoundDecl()) != 0) { + func_calls[fd].push_back(call); + } + } else if (auto* me = dyn_cast(expr)) { + if (indi_func_map.count(me->getMemberDecl()) != 0) { + func_calls[fd].push_back(call); + } + } + } + } + FunctionDecl* get_rhs_fd(Expr *rhs) const { while (ImplicitCastExpr *ice = dyn_cast(rhs)) { rhs = ice->getSubExpr(); @@ -292,26 +310,53 @@ namespace eosio { namespace cdt { return nullptr; } + void process_func_decl(DeclStmt *ds) { + if (ds->isSingleDecl()) { + if (auto* vd = dyn_cast(ds->getSingleDecl())) { + if (Expr *init = vd->getInit()) { + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[vd] = fd; + } + } + } + } + } + } + void update_indi_func_map(NamedDecl *nd, FunctionDecl *fd) { if (func_calls.count(fd) != 0) { indi_func_map[nd] = fd; - } else if (indi_func_map.count(nd)){ + } else if (indi_func_map.count(nd)) { indi_func_map.erase(nd); } } + void process_assignment(BinaryOperator *bo) { + Expr *lhs = nullptr, *rhs = nullptr; + if ((lhs = bo->getLHS()) && (rhs = bo->getRHS())) { + if (FunctionDecl *fd = get_rhs_fd(rhs)) { + if (auto* lhs_dre = dyn_cast(lhs)) { + update_indi_func_map(lhs_dre->getFoundDecl(), fd); + } else if (auto* lhs_me = dyn_cast(lhs)) { + update_indi_func_map(lhs_me->getMemberDecl(), fd); + } + } + } + } + void process_function(FunctionDecl* func_decl) { if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { Stmt *stmts = func_decl->getBody(); for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { if (Stmt *s = *it) { - if (ExprWithCleanups *ec = dyn_cast(s)) { + if (auto* ec = dyn_cast(s)) { s = ec->getSubExpr(); - while (ImplicitCastExpr *ice = dyn_cast(s)) + while (auto* ice = dyn_cast(s)) s = ice->getSubExpr(); } - if (CallExpr *call = dyn_cast(s)) { + if (auto* call = dyn_cast(s)) { if (FunctionDecl *fd = call->getDirectCallee()) { if (func_calls.count(fd) == 0) { process_function(fd); @@ -320,43 +365,13 @@ namespace eosio { namespace cdt { func_calls[func_decl].push_back(call); break; } - } else if (Expr *expr = call->getCallee()) { - while (ImplicitCastExpr *ice = dyn_cast(expr)) { - expr = ice->getSubExpr(); - } - if (DeclRefExpr *dre = dyn_cast(expr)) { - if (indi_func_map.count(dre->getFoundDecl()) != 0) { - func_calls[func_decl].push_back(call); - } - } else if (MemberExpr *me = dyn_cast(expr)) { - if (indi_func_map.count(me->getMemberDecl()) != 0) { - func_calls[func_decl].push_back(call); - } - } - } - } else if (DeclStmt *ds = dyn_cast(s)) { - if (ds->isSingleDecl()) { - if (VarDecl *vd = dyn_cast(ds->getSingleDecl())) { - if (Expr *init = vd->getInit()) { - if (FunctionDecl *fd = get_rhs_fd(init)) { - if (func_calls.count(fd) != 0) { - indi_func_map[vd] = fd; - } - } - } - } - } - } else if (BinaryOperator *bo = dyn_cast(s)) { - Expr *lhs = nullptr, *rhs = nullptr; - if ((lhs = bo->getLHS()) && (rhs = bo->getRHS())) { - if (FunctionDecl *fd = get_rhs_fd(rhs)) { - if (DeclRefExpr *lhs_dre = dyn_cast(lhs)) { - update_indi_func_map(lhs_dre->getFoundDecl(), fd); - } else if (MemberExpr *lhs_me = dyn_cast(lhs)) { - update_indi_func_map(lhs_me->getMemberDecl(), fd); - } - } + } else { + process_indi_callee(func_decl, call); } + } else if (auto* ds = dyn_cast(s)) { + process_func_decl(ds); + } else if (auto* bo = dyn_cast(s)) { + process_assignment(bo); } } } @@ -365,7 +380,7 @@ namespace eosio { namespace cdt { void process_class(CXXRecordDecl* decl) { for(auto it = decl->decls_begin(); it != decl->decls_end(); ++it) { - if(FieldDecl *f = dyn_cast(*it) ) { + if(auto* f = dyn_cast(*it) ) { if (Expr *init = f->getInClassInitializer()) { if (FunctionDecl *fd = get_rhs_fd(init)) { if (func_calls.count(fd) != 0) { @@ -411,12 +426,27 @@ namespace eosio { namespace cdt { } virtual bool VisitCXXRecordDecl(CXXRecordDecl* decl) { - codegen& cg = codegen::get(); if (decl->isEosioContract()) { process_class(decl); } return true; } + + void process_read_only_actions() const { + codegen& cg = codegen::get(); + for (auto const& ra : read_only_actions) { + auto it = func_calls.find(ra); + if (it != func_calls.end()) { + std::string msg = "read-only action cannot call write host function"; + if (cg.warn_action_read_only) { + CDT_WARN("codegen_warning", ra->getLocation(), msg); + } else { + CDT_ERROR("codegen_error", ra->getLocation(), msg); + } + } + } + } + }; class eosio_codegen_consumer : public ASTConsumer, public generation_utils { @@ -440,18 +470,7 @@ namespace eosio { namespace cdt { visitor->set_main_fid(fid); visitor->set_main_name(main_fe->getName()); visitor->TraverseDecl(Context.getTranslationUnitDecl()); - - for (auto const& ra : visitor->read_only_actions) { - auto it = visitor->func_calls.find(ra); - if (it != visitor->func_calls.end()) { - std::string msg = "read-only action cannot call write host function"; - if (cg.warn_action_read_only) { - CDT_WARN("codegen_warning", ra->getLocation(), msg); - } else { - CDT_ERROR("codegen_error", ra->getLocation(), msg); - } - } - } + visitor->process_read_only_actions(); for (auto ad : visitor->action_decls) visitor->create_action_dispatch(ad); From 9333e1099ba3ee44a50fb0764b199412aaef1910 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 30 Apr 2021 19:11:20 -0400 Subject: [PATCH 103/204] initial fix for nested std::map --- .../abigen-pass/nested_container.abi | 61 +++++++++++++++++++ .../abigen-pass/nested_container.cpp | 13 ++++ .../abigen-pass/nested_container.json | 9 +++ tools/include/eosio/abigen.hpp | 9 ++- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 tests/toolchain/abigen-pass/nested_container.abi create mode 100644 tests/toolchain/abigen-pass/nested_container.cpp create mode 100644 tests/toolchain/abigen-pass/nested_container.json diff --git a/tests/toolchain/abigen-pass/nested_container.abi b/tests/toolchain/abigen-pass/nested_container.abi new file mode 100644 index 0000000000..e837d154cc --- /dev/null +++ b/tests/toolchain/abigen-pass/nested_container.abi @@ -0,0 +1,61 @@ +{ + "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", + "version": "eosio::abi/1.2", + "types": [], + "structs": [ + { + "name": "map2map", + "base": "", + "fields": [ + { + "name": "m", + "type": "pair_string_string[]" + }, + { + "name": "m2m", + "type": "pair_string_pair_string_string[][]" + } + ] + }, + { + "name": "pair_string_pair_string_string", + "base": "", + "fields": [ + { + "name": "key", + "type": "string" + }, + { + "name": "value", + "type": "pair_string_string[]" + } + ] + }, + { + "name": "pair_string_string", + "base": "", + "fields": [ + { + "name": "key", + "type": "string" + }, + { + "name": "value", + "type": "string" + } + ] + } + ], + "actions": [ + { + "name": "map2map", + "type": "map2map", + "ricardian_contract": "" + } + ], + "tables": [], + "kv_tables": {}, + "ricardian_clauses": [], + "variants": [], + "action_results": [] +} \ No newline at end of file diff --git a/tests/toolchain/abigen-pass/nested_container.cpp b/tests/toolchain/abigen-pass/nested_container.cpp new file mode 100644 index 0000000000..c4111f65c6 --- /dev/null +++ b/tests/toolchain/abigen-pass/nested_container.cpp @@ -0,0 +1,13 @@ +#include + +using namespace eosio; +using std::map; +using std::string; + +class [[eosio::contract]] nested_container : public contract { +public: + using contract::contract; + + [[eosio::action]] + void map2map(map m, map> m2m) {} +}; \ No newline at end of file diff --git a/tests/toolchain/abigen-pass/nested_container.json b/tests/toolchain/abigen-pass/nested_container.json new file mode 100644 index 0000000000..08fd0d38f3 --- /dev/null +++ b/tests/toolchain/abigen-pass/nested_container.json @@ -0,0 +1,9 @@ +{ + "tests" : [ + { + "expected" : { + "abi-file" : "nested_container.abi" + } + } + ] + } \ No newline at end of file diff --git a/tools/include/eosio/abigen.hpp b/tools/include/eosio/abigen.hpp index e27ac94a19..d671c8af9f 100644 --- a/tools/include/eosio/abigen.hpp +++ b/tools/include/eosio/abigen.hpp @@ -169,7 +169,14 @@ namespace eosio { namespace cdt { } abi_struct kv; std::string name = get_type(type); - kv.name = name.substr(0, name.length() - 2); + auto remove_ending_brackets = [&]( std::string name ) { + int i = name.length()-1; + for (; i >= 0; i--) + if ( name[i] != '[' && name[i] != ']' ) + break; + return name.substr(0,i+1); + }; + kv.name = remove_ending_brackets(name); kv.fields.push_back( {"key", get_template_argument_as_string(type)} ); kv.fields.push_back( {"value", get_template_argument_as_string(type, 1)} ); add_type(std::get(get_template_argument(type))); From 545dcc37d562e8012064d519b7f81de4c22a4756 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 5 May 2021 16:09:38 +0300 Subject: [PATCH 104/204] correct informational callouts --- .../40_multi-index/how-to-define-a-primary-index.md | 4 ++-- .../40_multi-index/how-to-define-a-secondary-index.md | 2 +- .../40_multi-index/how-to-define-a-singleton.md | 2 +- .../how-to-delete-data-from-a-multi-index-table.md | 2 +- .../how-to-insert-data-into-a-multi-index-table.md | 2 +- .../40_multi-index/how-to-instantiate-a-multi-index-table.md | 2 +- ...d-retrieve-a-multi_index-table-based-on-secondary-index.md | 2 +- .../how-to-iterate-and-retrieve-a-multi_index-table.md | 2 +- .../how-to-modify-data-in-a-multi-index-table.md | 2 +- docs/09_tutorials/02_abi-variants.md | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index edebe2c726..7bf18d8491 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -37,7 +37,7 @@ using namespace eosio; }; ``` -[[Info | Secondary indexes information]] +[[info | Secondary indexes information]] | Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double. 5. For ease of use, define a type alias `test_tables` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above @@ -73,5 +73,5 @@ Declare the multi index table as a data member of type `test_tables`, as defined Now you have instantiated the `testtab` as a multi index table which has a primary index defined for its `test_primary` data member. -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index a0aaae5329..c6a36082d5 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -88,5 +88,5 @@ class [[eosio::contract]] multi_index_example : public contract { }; ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index 2409314af3..f8ee5b51a2 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -110,5 +110,5 @@ __singleton_example.cpp__ } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of singleton can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/singleton_example). diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index f1079c7aec..3f2fbc5050 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -29,5 +29,5 @@ To delete data from a multi index table follow the steps below: } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index 81df3702d9..37254edb51 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -32,5 +32,5 @@ To insert data into a multi index table follow the following steps } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index b2b828c00a..742917f092 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -35,7 +35,7 @@ using namespace eosio; }; ``` -[[Info | Additional indexes information]] +[[info | Additional indexes information]] | Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double. 5. For ease of use, define a type alias `test_tables` based on the multi_index template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index f2363f4477..939abbd7e8 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -171,5 +171,5 @@ __multi_index_example.cpp__ } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 188f50e1f7..3654701d8a 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -153,5 +153,5 @@ __multi_index_example.cpp__ } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index 174e6026d3..62a0250811 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -37,5 +37,5 @@ To modify data in the multi index table defined in the above tutorial, you will } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). diff --git a/docs/09_tutorials/02_abi-variants.md b/docs/09_tutorials/02_abi-variants.md index cc2448b0ab..2d286c4d39 100644 --- a/docs/09_tutorials/02_abi-variants.md +++ b/docs/09_tutorials/02_abi-variants.md @@ -156,5 +156,5 @@ class [[eosio::contract]] multi_index_example : public contract { [[warning | Not recommended warning]] | Be aware, it is not recommend to use `eosio::binary_extension` inside variant definition, this can lead to data corruption unless one is very careful in understanding how these two templates work and how the ABI gets generated! -[[Info | Implementation location]] +[[info | Implementation location]] | The implementation for ABI `variants` can be found [here](https://github.com/EOSIO/eos/pull/5652). From eec73ccb9e7cb5d3c0fbf6f76692960809c2a7dd Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Sun, 9 May 2021 13:24:16 -0400 Subject: [PATCH 105/204] fix ending newline --- tests/toolchain/abigen-pass/nested_container.abi | 2 +- tests/toolchain/abigen-pass/nested_container.cpp | 2 +- tests/toolchain/abigen-pass/nested_container.json | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/toolchain/abigen-pass/nested_container.abi b/tests/toolchain/abigen-pass/nested_container.abi index e837d154cc..ba0f5698ec 100644 --- a/tests/toolchain/abigen-pass/nested_container.abi +++ b/tests/toolchain/abigen-pass/nested_container.abi @@ -58,4 +58,4 @@ "ricardian_clauses": [], "variants": [], "action_results": [] -} \ No newline at end of file +} diff --git a/tests/toolchain/abigen-pass/nested_container.cpp b/tests/toolchain/abigen-pass/nested_container.cpp index c4111f65c6..4c0a16c75a 100644 --- a/tests/toolchain/abigen-pass/nested_container.cpp +++ b/tests/toolchain/abigen-pass/nested_container.cpp @@ -10,4 +10,4 @@ class [[eosio::contract]] nested_container : public contract { [[eosio::action]] void map2map(map m, map> m2m) {} -}; \ No newline at end of file +}; diff --git a/tests/toolchain/abigen-pass/nested_container.json b/tests/toolchain/abigen-pass/nested_container.json index 08fd0d38f3..752f4688ec 100644 --- a/tests/toolchain/abigen-pass/nested_container.json +++ b/tests/toolchain/abigen-pass/nested_container.json @@ -6,4 +6,5 @@ } } ] - } \ No newline at end of file + } + \ No newline at end of file From 0edea8774af09c7b673d719fa8746b7f3088d48b Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 10 May 2021 09:55:29 -0400 Subject: [PATCH 106/204] add support for multiple declarations; clean up code --- .../compile-fail/hf_indirect_call_tests.cpp | 6 ++ tools/include/eosio/codegen.hpp | 98 +++++++++---------- 2 files changed, 54 insertions(+), 50 deletions(-) diff --git a/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp b/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp index 76c7b547b9..befb8c98b6 100644 --- a/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp +++ b/tests/toolchain/compile-fail/hf_indirect_call_tests.cpp @@ -178,6 +178,12 @@ class [[eosio::contract]] hf_indirect_call_tests : public eosio::contract { return true; } + ACTION_TYPE + bool taliasma () { + func srl_a1, srl_a2 = set_resource_limit; + srl_a2(0,0,0); + } + #define setfun set_resource_limit ACTION_TYPE bool tdefine(){ diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index d993dcaba4..d24db794b6 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -299,31 +299,17 @@ namespace eosio { namespace cdt { } FunctionDecl* get_rhs_fd(Expr *rhs) const { - while (ImplicitCastExpr *ice = dyn_cast(rhs)) { + while (auto* ice = dyn_cast(rhs)) { rhs = ice->getSubExpr(); } - if (DeclRefExpr *rhs_dre = dyn_cast(rhs)) { - if (FunctionDecl *fd = dyn_cast(rhs_dre->getFoundDecl())) { + if (auto* rhs_dre = dyn_cast(rhs)) { + if (auto* fd = dyn_cast(rhs_dre->getFoundDecl())) { return fd; } } return nullptr; } - void process_func_decl(DeclStmt *ds) { - if (ds->isSingleDecl()) { - if (auto* vd = dyn_cast(ds->getSingleDecl())) { - if (Expr *init = vd->getInit()) { - if (FunctionDecl *fd = get_rhs_fd(init)) { - if (func_calls.count(fd) != 0) { - indi_func_map[vd] = fd; - } - } - } - } - } - } - void update_indi_func_map(NamedDecl *nd, FunctionDecl *fd) { if (func_calls.count(fd) != 0) { indi_func_map[nd] = fd; @@ -332,15 +318,10 @@ namespace eosio { namespace cdt { } } - void process_assignment(BinaryOperator *bo) { - Expr *lhs = nullptr, *rhs = nullptr; - if ((lhs = bo->getLHS()) && (rhs = bo->getRHS())) { - if (FunctionDecl *fd = get_rhs_fd(rhs)) { - if (auto* lhs_dre = dyn_cast(lhs)) { - update_indi_func_map(lhs_dre->getFoundDecl(), fd); - } else if (auto* lhs_me = dyn_cast(lhs)) { - update_indi_func_map(lhs_me->getMemberDecl(), fd); - } + void process_decl_init(NamedDecl *nd, Expr *init) { + if (FunctionDecl *fd = get_rhs_fd(init)) { + if (func_calls.count(fd) != 0) { + indi_func_map[nd] = fd; } } } @@ -348,7 +329,7 @@ namespace eosio { namespace cdt { void process_function(FunctionDecl* func_decl) { if (func_decl->isThisDeclarationADefinition() && func_decl->hasBody()) { Stmt *stmts = func_decl->getBody(); - for (auto it = stmts->child_begin(); it != stmts->child_end(); it++) { + for (auto it = stmts->child_begin(); it != stmts->child_end(); ++it) { if (Stmt *s = *it) { if (auto* ec = dyn_cast(s)) { s = ec->getSubExpr(); @@ -369,8 +350,29 @@ namespace eosio { namespace cdt { process_indi_callee(func_decl, call); } } else if (auto* ds = dyn_cast(s)) { - process_func_decl(ds); + auto process_decl = [this]( DeclStmt *s ) { + for (auto it = s->decl_begin(); it != s->decl_end(); ++it) { + if (auto* vd = dyn_cast(*it)) { + if (Expr *init = vd->getInit()) { + process_decl_init(vd, init); + } + } + } + }; + process_decl(ds); } else if (auto* bo = dyn_cast(s)) { + auto process_assignment = [this]( BinaryOperator *b ) { + Expr *lhs = nullptr, *rhs = nullptr; + if ((lhs = b->getLHS()) && (rhs = b->getRHS())) { + if (FunctionDecl *fd = get_rhs_fd(rhs)) { + if (auto* lhs_dre = dyn_cast(lhs)) { + update_indi_func_map(lhs_dre->getFoundDecl(), fd); + } else if (auto* lhs_me = dyn_cast(lhs)) { + update_indi_func_map(lhs_me->getMemberDecl(), fd); + } + } + } + }; process_assignment(bo); } } @@ -378,20 +380,6 @@ namespace eosio { namespace cdt { } } - void process_class(CXXRecordDecl* decl) { - for(auto it = decl->decls_begin(); it != decl->decls_end(); ++it) { - if(auto* f = dyn_cast(*it) ) { - if (Expr *init = f->getInClassInitializer()) { - if (FunctionDecl *fd = get_rhs_fd(init)) { - if (func_calls.count(fd) != 0) { - indi_func_map[f] = fd; - } - } - } - } - } - } - virtual bool VisitFunctionDecl(FunctionDecl* func_decl) { SourceManager &sm = get_rewriter().getSourceMgr(); if (sm.isInSystemHeader(func_decl->getLocation()) || sm.isInExternCSystemHeader(func_decl->getLocation())) { @@ -411,23 +399,33 @@ namespace eosio { namespace cdt { if (auto* fd = dyn_cast(decl)) { if (fd->getNameInfo().getAsString() == "apply") apply_was_found = true; - } else if (auto* vd = dyn_cast(decl)) { - if (vd->hasGlobalStorage()) { - if (Expr *init = vd->getInit()) { - if (FunctionDecl *fd = get_rhs_fd(init)) { - if (func_calls.count(fd) != 0) { - indi_func_map[vd] = fd; + } else { + auto process_global_var = [this]( clang::Decl* d ) { + if (auto* vd = dyn_cast(d)) { + if (vd->hasGlobalStorage()) { + if (Expr *init = vd->getInit()) { + process_decl_init(vd, init); } } } - } + }; + process_global_var(decl); } return true; } virtual bool VisitCXXRecordDecl(CXXRecordDecl* decl) { if (decl->isEosioContract()) { - process_class(decl); + auto process_data_member = [this]( CXXRecordDecl* rd ) { + for (auto it = rd->decls_begin(); it != rd->decls_end(); ++it) { + if (auto* f = dyn_cast(*it) ) { + if (Expr *init = f->getInClassInitializer()) { + process_decl_init(f, init); + } + } + } + }; + process_data_member(decl); } return true; } From ba55063196b7c817c7c08bdc3932abd0d1df2465 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 10 May 2021 13:18:35 -0400 Subject: [PATCH 107/204] fix json format --- tests/toolchain/abigen-pass/nested_container.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/toolchain/abigen-pass/nested_container.json b/tests/toolchain/abigen-pass/nested_container.json index 752f4688ec..4f2c8aae7f 100644 --- a/tests/toolchain/abigen-pass/nested_container.json +++ b/tests/toolchain/abigen-pass/nested_container.json @@ -6,5 +6,4 @@ } } ] - } - \ No newline at end of file +} From 41c5b48a2dc9c75bdc119f05c1a4c29bdeb5ef80 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Wed, 12 May 2021 16:41:26 -0400 Subject: [PATCH 108/204] change -v option to call clang-9 --- tools/cc/eosio-cc.cpp.in | 2 +- tools/cc/eosio-cpp.cpp.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/cc/eosio-cc.cpp.in b/tools/cc/eosio-cc.cpp.in index b1ee3e152b..81be71cb4e 100644 --- a/tools/cc/eosio-cc.cpp.in +++ b/tools/cc/eosio-cc.cpp.in @@ -22,7 +22,7 @@ int main(int argc, const char **argv) { // fix to show version info without having to have any other arguments for (int i=0; i < argc; i++) { if (argv[i] == std::string("-v")) { - eosio::cdt::environment::exec_subprogram("clang-7", {"-v"}); + eosio::cdt::environment::exec_subprogram("clang-9", {"-v"}); return 0; } } diff --git a/tools/cc/eosio-cpp.cpp.in b/tools/cc/eosio-cpp.cpp.in index 85f7b4c1d7..2c7f7eaafa 100644 --- a/tools/cc/eosio-cpp.cpp.in +++ b/tools/cc/eosio-cpp.cpp.in @@ -110,7 +110,7 @@ int main(int argc, const char **argv) { // fix to show version info without having to have any other arguments for (int i=0; i < argc; i++) { if (argv[i] == std::string("-v")) { - eosio::cdt::environment::exec_subprogram("clang-7", {"-v"}); + eosio::cdt::environment::exec_subprogram("clang-9", {"-v"}); return 0; } } From ef00c9d035fcea306131884724691398189be4a3 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 21 May 2021 16:17:49 -0400 Subject: [PATCH 109/204] remove system header checking; use C name to find write host function --- tools/include/eosio/codegen.hpp | 8 +-- tools/include/eosio/gen.hpp | 96 ++++++--------------------------- 2 files changed, 18 insertions(+), 86 deletions(-) diff --git a/tools/include/eosio/codegen.hpp b/tools/include/eosio/codegen.hpp index d24db794b6..54c0c4d3d8 100644 --- a/tools/include/eosio/codegen.hpp +++ b/tools/include/eosio/codegen.hpp @@ -381,13 +381,7 @@ namespace eosio { namespace cdt { } virtual bool VisitFunctionDecl(FunctionDecl* func_decl) { - SourceManager &sm = get_rewriter().getSourceMgr(); - if (sm.isInSystemHeader(func_decl->getLocation()) || sm.isInExternCSystemHeader(func_decl->getLocation())) { - return true; - } - - std::string fn = func_decl->getQualifiedNameAsString(); - if (func_calls.count(func_decl) == 0 && (is_write_host_func(fn) || is_eosio_wasm_import_write_func(func_decl))) { + if (func_calls.count(func_decl) == 0 && is_write_host_func(func_decl)) { func_calls[func_decl] = {(CallExpr*)func_decl}; } else { process_function(func_decl); diff --git a/tools/include/eosio/gen.hpp b/tools/include/eosio/gen.hpp index e67ea3a044..2e16cff282 100644 --- a/tools/include/eosio/gen.hpp +++ b/tools/include/eosio/gen.hpp @@ -685,74 +685,8 @@ struct generation_utils { return in_kv_namespace && is_internal; } - inline bool is_write_host_func( const std::string& t ) { + inline bool is_write_host_func( const clang::FunctionDecl *func_decl ) { static const std::set write_host_funcs = - { - "eosio::internal_use_do_not_use::set_resource_limits", - "eosio::chain::webassembly::interface::set_resource_limits", - "eosio::chain::webassembly::interface::set_wasm_parameters_packed", - "eosio::chain::webassembly::interface::set_resource_limit", - "eosio::chain::controller::set_proposed_producers", - "eosio::chain::webassembly::interface::set_proposed_producers", - "eosio::internal_use_do_not_use::set_proposed_producers_ex", - "eosio::chain::webassembly::interface::set_proposed_producers_ex", - "eosio::internal_use_do_not_use::set_blockchain_parameters_packed", - "eosio::chain::webassembly::interface::set_blockchain_parameters_packed" - "eosio::chain::webassembly::interface::set_parameters_packed", - "eosio::chain::webassembly::set_kv_parameters_packed", - "eosio::internal_use_do_not_use::set_kv_parameters_packed", - "eosio::chain::webassembly::interface::set_kv_parameters_packed", - "eosio::internal_use_do_not_use::set_privileged", - "eosio::chain::webassembly::interface::set_privileged", - "eosio::internal_use_do_not_use::db_store_i64", - "eosio::internal_use_do_not_use::db_update_i64", - "eosio::internal_use_do_not_use::db_remove_i64", - "eosio::internal_use_do_not_use::db_idx64_store", - "eosio::internal_use_do_not_use::db_idx64_update", - "eosio::internal_use_do_not_use::db_idx64_remove", - "eosio::internal_use_do_not_use::db_idx128_store", - "eosio::internal_use_do_not_use::db_idx128_update", - "eosio::internal_use_do_not_use::db_idx128_remove", - "eosio::internal_use_do_not_use::db_idx256_store", - "eosio::internal_use_do_not_use::db_idx256_update", - "eosio::internal_use_do_not_use::db_idx256_remove", - "eosio::internal_use_do_not_use::db_idx_double_store", - "eosio::internal_use_do_not_use::db_idx_double_update", - "eosio::internal_use_do_not_use::db_idx_double_remove", - "eosio::internal_use_do_not_use::db_idx_long_double_store", - "eosio::internal_use_do_not_use::db_idx_long_double_update", - "eosio::internal_use_do_not_use::db_idx_long_double_remove", - "eosio::kv::internal_use_do_not_use::kv_erase", - "eosio::kv::internal_use_do_not_use::kv_set", - // deferred transactions - "eosio::chain::webassembly::interface::send_deferred", - "eosio::send_deferred", - // inline actions - "eosio::internal_use_do_not_use::send_inline", - "eosio::internal_use_do_not_use::send_context_free_inline" - }; - return write_host_funcs.count(t) >= 1; - } - - inline bool is_deferred_transaction_func( const std::string& t ) { - static const std::set deferred_transaction_funcs = - { - "send_deferred", - }; - return deferred_transaction_funcs.count(t) >= 1; - } - - inline bool is_inline_action_func( const std::string& t ) { - static const std::set inline_action_funcs = - { - "send_inline", - "send_context_free_inline" - }; - return inline_action_funcs.count(t) >= 1; - } - - inline bool is_eosio_wasm_import_write_func( const clang::FunctionDecl *func_decl ) { - static const std::set eosio_wasm_import_write_funcs = { "set_resource_limits", "set_wasm_parameters_packed", @@ -788,20 +722,24 @@ struct generation_utils { "send_context_free_inline" }; - if (eosio_wasm_import_write_funcs.count(func_decl->getQualifiedNameAsString()) == 0) { - return false; - } + return write_host_funcs.count(func_decl->getNameInfo().getAsString()) >= 1; + } - if (func_decl->isInExternCContext()) { - auto attrs = func_decl->getAttrs(); - for (auto const &a : attrs) { - if (strcmp(a->getSpelling(), "eosio_wasm_import") == 0) { - return true; - } - } - } + inline bool is_deferred_transaction_func( const std::string& t ) { + static const std::set deferred_transaction_funcs = + { + "send_deferred", + }; + return deferred_transaction_funcs.count(t) >= 1; + } - return false; + inline bool is_inline_action_func( const std::string& t ) { + static const std::set inline_action_funcs = + { + "send_inline", + "send_context_free_inline" + }; + return inline_action_funcs.count(t) >= 1; } }; }} // ns eosio::cdt From bf9c37adec64ea1aa92b471f512e8923552f440d Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Mon, 24 May 2021 15:44:05 -0400 Subject: [PATCH 110/204] change llvm branch to eosio --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 51368f352d..d4d6791da8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,7 +9,7 @@ [submodule "eosio_llvm"] path = eosio_llvm url = https://github.com/eosio/llvm - branch = qy-read-only-action + branch = eosio [submodule "libraries/native/softfloat"] path = libraries/native/softfloat url = https://github.com/EOSIO/berkeley-softfloat-3.git From 3b3dd18a68c09606636f54ea1af4425827fdb27a Mon Sep 17 00:00:00 2001 From: ovi Date: Tue, 25 May 2021 21:24:26 +0300 Subject: [PATCH 111/204] [docs] dummy to trigger a doc build [docs] dummy to trigger a doc build --- docs/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.md b/docs/index.md index 57d2dcbd1d..560cca49cd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,3 +23,4 @@ There's been a round of braking changes, if you are upgrading from older version ## Important See LICENSE for copyright and license terms. Block.one makes its contribution on a voluntary basis as a member of the EOSIO community and is not responsible for ensuring the overall performance of the software or any related applications. We make no representation, warranty, guarantee or undertaking in respect of the software or any related documentation, whether expressed or implied, including but not limited to the warranties or merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or documentation or the use or other dealings in the software or documentation. Any test results or performance figures are indicative and will not reflect performance under all conditions. Any reference to any third party or third-party product, service or other resource is not an endorsement or recommendation by Block.one. We are not responsible, and disclaim any and all responsibility and liability, for your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so the information here may be out of date or inaccurate. + From 53cee3a1cf1fc6e7ec6b8e8aa5e5877c66a36f38 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 12:38:57 +0300 Subject: [PATCH 112/204] take 1 --- .../how-to-define-a-primary-index.md | 181 +++++++++++------- 1 file changed, 115 insertions(+), 66 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index edebe2c726..fd34bb07d9 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -2,76 +2,125 @@ content_title: How to define a primary index --- -A primary key is required when defining a multi index table structure. See the following example: - -1. Include the `eosio.hpp` header and declare the `eosio` namespace usage -``` -#include -using namespace eosio; -``` -2. Define the data structure for the multi index table -```cpp - struct [[eosio::table]] test_table { - }; -``` -3. Add to the data structure the fields which define the multi index table -```diff - // the data structure which defines each row of the table - struct [[eosio::table]] test_table { -+ // this field stores a name for each row of the multi index table -+ name test_primary; -+ // additional data stored in table row, e.g. an uint64_t type data -+ uint64_t datum; - }; -``` -4. Add the definition of the primary index for the multi index table. The primary index type must be uint64_t and must be unique -```diff - // the data structure which defines each row of the table - struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table - name test_primary; - // additional data stored in table row - uint64_t datum; -+ // mandatory definition for primary key getter -+ uint64_t primary_key( ) const { return test_primary.value; } - }; -``` - -[[Info | Secondary indexes information]] +## Overview + +This guide provides instructions on how to define a primary index in a multi-index table. + +## Reference + +See the following code reference: + +* The [`multi-index`](../../classeosio_1_1multi__index) class. + +## Before you begin + +Make sure you have the following prerequisites in place: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), +* A multi-index table named `test_table`, +* A primary key is required when defining a multi-index table structure, therefore you need to know which is the property that is the primary key for your multi-index table structure. That property must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. + +## Procedure + +Complete the following steps to define a primary index for the multi-index table named `test_table` based on its `test_primary` data member. + +### 1. Preparation And Initialization + +Include the `eosio.hpp` header and declare the `eosio` namespace usage + + ```cpp + #include + using namespace eosio; + ``` + +### 2. Defines The Table Data Structure + +Define the data structure for the multi index table + + ```cpp + struct [[eosio::table]] test_table { + }; + ``` + +Add to the data structure the fields which define the multi index table + + ```diff + // the data structure which defines each row of the table + struct [[eosio::table]] test_table { + + // this field stores a name for each row of the multi index table + + name test_primary; + + // additional data stored in table row, e.g. an uint64_t type data + + uint64_t datum; + }; + ``` + +### 3. Define The Primary Index + +Add the definition of the primary index for the multi index table. The primary index type must be uint64_t and must be unique + + ```diff + // the data structure which defines each row of the table + struct [[eosio::table]] test_table { + // this field stores a name for each row of the multi index table + name test_primary; + // additional data stored in table row + uint64_t datum; + + // mandatory definition for primary key getter + + uint64_t primary_key( ) const { return test_primary.value; } + }; + ``` + +[[info | Secondary indexes information]] | Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double. -5. For ease of use, define a type alias `test_tables` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above -```diff - // the data structure which defines each row of the table - struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table - name test_primary; - // additional data stored in table row - uint64_t datum; - // mandatory definition for primary key getter - uint64_t primary_key( ) const { return test_primary.value; } - }; - -+ typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; -``` +### 4. Define A Multi-Index Type Alias + +For ease of use, define a type alias `test_tables` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above + + ```diff + // the data structure which defines each row of the table + struct [[eosio::table]] test_table { + // this field stores a name for each row of the multi index table + name test_primary; + // additional data stored in table row + uint64_t datum; + // mandatory definition for primary key getter + uint64_t primary_key( ) const { return test_primary.value; } + }; + + + typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; + ``` + +### 5. Instantiate The Multi-Index Table Declare the multi index table as a data member of type `test_tables`, as defined above. -```diff - // the data structure which defines each row of the table - struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table - name test_primary; - // additional data stored in table row - uint64_t datum; - // mandatory definition for primary key getter - uint64_t primary_key( ) const { return test_primary.value; } - }; - - typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; -+ test_tables testtab; -``` + + ```diff + // the data structure which defines each row of the table + struct [[eosio::table]] test_table { + // this field stores a name for each row of the multi index table + name test_primary; + // additional data stored in table row + uint64_t datum; + // mandatory definition for primary key getter + uint64_t primary_key( ) const { return test_primary.value; } + }; + + typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; + + test_tables testtab; + ``` Now you have instantiated the `testtab` as a multi index table which has a primary index defined for its `test_primary` data member. -[[Info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +[[info | Full example location]] +| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to define a primary index in a multi-index table. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the multi-index table. From 51d91e059fa4fd90bb062dd1253e2b8d9da2e0b2 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 12:40:09 +0300 Subject: [PATCH 113/204] [[Info -> [[info --- .../40_multi-index/how-to-define-a-secondary-index.md | 2 +- .../40_multi-index/how-to-define-a-singleton.md | 2 +- .../how-to-delete-data-from-a-multi-index-table.md | 2 +- .../how-to-insert-data-into-a-multi-index-table.md | 2 +- .../40_multi-index/how-to-instantiate-a-multi-index-table.md | 4 ++-- ...d-retrieve-a-multi_index-table-based-on-secondary-index.md | 2 +- .../how-to-iterate-and-retrieve-a-multi_index-table.md | 3 ++- .../how-to-modify-data-in-a-multi-index-table.md | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index a0aaae5329..c6a36082d5 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -88,5 +88,5 @@ class [[eosio::contract]] multi_index_example : public contract { }; ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index 2409314af3..f8ee5b51a2 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -110,5 +110,5 @@ __singleton_example.cpp__ } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of singleton can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/singleton_example). diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index f1079c7aec..3f2fbc5050 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -29,5 +29,5 @@ To delete data from a multi index table follow the steps below: } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index 81df3702d9..37254edb51 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -32,5 +32,5 @@ To insert data into a multi index table follow the following steps } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index 9ab286ef0a..d115a675f6 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -35,7 +35,7 @@ using namespace eosio; }; ``` -[[Info | Additional indexes information]] +[[info | Additional indexes information]] | Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double. 5. For ease of use, define a type alias `test_tables` based on the multi_index template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above @@ -129,5 +129,5 @@ class [[eosio::contract]] multi_index_example : public contract { }; ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index f2363f4477..939abbd7e8 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -171,5 +171,5 @@ __multi_index_example.cpp__ } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 188f50e1f7..21abaa94b5 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -3,6 +3,7 @@ content_title: How to iterate and retrieve a multi index table --- ## Preconditions + - It is assumed you already have a multi index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi index table](./how-to-instantiate-a-multi-index-table.md). For exemplification define the multi index contract definition like below: @@ -153,5 +154,5 @@ __multi_index_example.cpp__ } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index 174e6026d3..62a0250811 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -37,5 +37,5 @@ To modify data in the multi index table defined in the above tutorial, you will } ``` -[[Info | Full example location]] +[[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). From c2a45aa3cace6956df5f326b288b2abcaf1378a3 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 12:42:44 +0300 Subject: [PATCH 114/204] multi index -> multi-index --- .../04_data-design-and-migration.md | 8 ++-- .../how-to-define-a-primary-index.md | 20 +++++----- .../how-to-define-a-secondary-index.md | 20 +++++----- .../how-to-define-a-singleton.md | 2 +- ...to-delete-data-from-a-multi-index-table.md | 10 ++--- ...to-insert-data-into-a-multi-index-table.md | 10 ++--- .../how-to-instantiate-a-multi-index-table.md | 40 +++++++++---------- ...ti_index-table-based-on-secondary-index.md | 38 +++++++++--------- ...terate-and-retrieve-a-multi_index-table.md | 38 +++++++++--------- ...w-to-modify-data-in-a-multi-index-table.md | 12 +++--- docs/08_troubleshooting.md | 2 +- docs/09_tutorials/02_abi-variants.md | 8 ++-- 12 files changed, 104 insertions(+), 104 deletions(-) diff --git a/docs/05_best-practices/04_data-design-and-migration.md b/docs/05_best-practices/04_data-design-and-migration.md index 5d847064a9..2806444f9d 100644 --- a/docs/05_best-practices/04_data-design-and-migration.md +++ b/docs/05_best-practices/04_data-design-and-migration.md @@ -2,9 +2,9 @@ content_title: Data design and migration --- -EOSIO based blockchains allow developers to easily update their smart contract code. However, a few things need to be considered when it comes to data update and/or migration. The main structure for storing data in EOSIO based blockchains is the multi index table. Once a multi index table has been created with a first version of a smart contract, it has some limitations when it comes to changing its structure. Below you will find a few possible approaches which you can consider when you design your smart contract data and its migration. +EOSIO based blockchains allow developers to easily update their smart contract code. However, a few things need to be considered when it comes to data update and/or migration. The main structure for storing data in EOSIO based blockchains is the multi-index table. Once a multi-index table has been created with a first version of a smart contract, it has some limitations when it comes to changing its structure. Below you will find a few possible approaches which you can consider when you design your smart contract data and its migration. -# How to modify the structure of a multi index table +# How to modify the structure of a multi-index table Modifying a multi-index table structure that has already been deployed to an EOSIO-based blockchain may be done by selecting one of the different strategies outlined below, depending on your requirements: @@ -28,9 +28,9 @@ To learn how to modify the structure using ABI variants read this [tutorial](../ #### 2.3.1. Migration without downtime, but slower -1. Create the new version of your multi index table alongside the old one; +1. Create the new version of your multi-index table alongside the old one; 2. Transfer data from the old table to the new one. You may do so as part of your normal access pattern, first checking the new table to see if the entry you seek is present and if not, check the original table, and if it's present, migrate it while adding the data for the new field, then remove it from the original table to save RAM costs. -3. You must retain both versions of your multi index table until you have completed this migration, at which point you may update your contract to remove the original version of your multi index table. +3. You must retain both versions of your multi-index table until you have completed this migration, at which point you may update your contract to remove the original version of your multi-index table. #### 2.3.2. Migration with downtime, but faster diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index fd34bb07d9..a984a3a2b9 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -35,19 +35,19 @@ Include the `eosio.hpp` header and declare the `eosio` namespace usage ### 2. Defines The Table Data Structure -Define the data structure for the multi index table +Define the data structure for the multi-index table ```cpp struct [[eosio::table]] test_table { }; ``` -Add to the data structure the fields which define the multi index table +Add to the data structure the fields which define the multi-index table ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - + // this field stores a name for each row of the multi index table + + // this field stores a name for each row of the multi-index table + name test_primary; + // additional data stored in table row, e.g. an uint64_t type data + uint64_t datum; @@ -56,12 +56,12 @@ Add to the data structure the fields which define the multi index table ### 3. Define The Primary Index -Add the definition of the primary index for the multi index table. The primary index type must be uint64_t and must be unique +Add the definition of the primary index for the multi-index table. The primary index type must be uint64_t and must be unique ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -80,7 +80,7 @@ For ease of use, define a type alias `test_tables` based on the `eosio::multi_in ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -93,12 +93,12 @@ For ease of use, define a type alias `test_tables` based on the `eosio::multi_in ### 5. Instantiate The Multi-Index Table -Declare the multi index table as a data member of type `test_tables`, as defined above. +Declare the multi-index table as a data member of type `test_tables`, as defined above. ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -110,10 +110,10 @@ Declare the multi index table as a data member of type `test_tables`, as defined + test_tables testtab; ``` -Now you have instantiated the `testtab` as a multi index table which has a primary index defined for its `test_primary` data member. +Now you have instantiated the `testtab` as a multi-index table which has a primary index defined for its `test_primary` data member. [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). ## Summary diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index c6a36082d5..fa5672c2f8 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -3,14 +3,14 @@ content_title: How to define a secondary index --- ## Preconditions -- It is assumed you already have a multi index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi index table](./how-to-instantiate-a-multi-index-table.md). +- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). -The steps below show how to add a secondary index to the existing multi index table. +The steps below show how to add a secondary index to the existing multi-index table. 1. Add a second field, `secondary`, to the data structure that defines the row of the table, in your case `test_table` ```diff struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; + name secondary; // additional data stored in table row @@ -23,7 +23,7 @@ The steps below show how to add a secondary index to the existing multi index ta 2. Add `by_secondary( )` method, which is the index accessor method to the new field value added. The secondary index, that will be added in step 3, will index this new data structure field. ```diff struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row @@ -48,7 +48,7 @@ __multi_index_example.hpp__ #include using namespace eosio; -// multi index example contract class +// multi-index example contract class class [[eosio::contract]] multi_index_example : public contract { public: using contract::contract; @@ -57,12 +57,12 @@ class [[eosio::contract]] multi_index_example : public contract { multi_index_example( name receiver, name code, datastream ds ) : // contract base class contructor contract(receiver, code, ds), - // instantiate multi index instance as data member (find it defined below) + // instantiate multi-index instance as data member (find it defined below) testtab(receiver, receiver.value) { } struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row @@ -72,12 +72,12 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t by_secondary( ) const { return secondary.value; } }; - // the multi index type definition, for ease of use a type alias `test_tables` is defined, + // the multi-index type definition, for ease of use a type alias `test_tables` is defined, // based on the multi_index template type, parametarized with a random name, the // test_table data structure, and the secondary index typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; - // the multi index table instance declared as a data member of type test_tables + // the multi-index table instance declared as a data member of type test_tables test_tables testtab; [[eosio::action]] void set( name user ); @@ -89,4 +89,4 @@ class [[eosio::contract]] multi_index_example : public contract { ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index f8ee5b51a2..737a46341f 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -11,7 +11,7 @@ To define a simple singleton, which is storing an account name as primary value using namespace eosio; ``` -2. Define the data structure for the multi index table +2. Define the data structure for the multi-index table ```cpp struct [[eosio::table]] testtable { name primary_value; diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index 3f2fbc5050..2b37678585 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -1,13 +1,13 @@ --- -content_title: How to delete data from a multi index table +content_title: How to delete data from a multi-index table --- ## Preconditions -- It is assumed you already have a multi index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi index table](./how-to-instantiate-a-multi-index-table.md). +- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). -To delete data from a multi index table follow the steps below: +To delete data from a multi-index table follow the steps below: -1. Make use of the multi index table iterator to find out if the data exists +1. Make use of the multi-index table iterator to find out if the data exists ```cpp [[eosio::action]] void multi_index_example::del( name user ) { // check if the user already exists @@ -30,4 +30,4 @@ To delete data from a multi index table follow the steps below: ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index 37254edb51..eae3503bf2 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -1,13 +1,13 @@ --- -content_title: How to insert data into a multi index table +content_title: How to insert data into a multi-index table --- ## Preconditions -- It is assumed you already have a multi index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi index table](./how-to-instantiate-a-multi-index-table.md). +- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). -To insert data into a multi index table follow the following steps +To insert data into a multi-index table follow the following steps -1. Make use of the multi index table iterator to find out if the data doesn't already exist +1. Make use of the multi-index table iterator to find out if the data doesn't already exist ```cpp [[eosio::action]] void multi_index_example::set( name user ) { // check if the user already exists @@ -33,4 +33,4 @@ To insert data into a multi index table follow the following steps ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index d115a675f6..a4c4d0cd66 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -1,5 +1,5 @@ --- -content_title: How to instantiate a multi index table +content_title: How to instantiate a multi-index table --- 1. Include the `eosio.hpp` header and declare the `eosio` namespace usage @@ -7,26 +7,26 @@ content_title: How to instantiate a multi index table #include using namespace eosio; ``` -2. Define the data structure for the multi index table +2. Define the data structure for the multi-index table ```cpp struct [[eosio::table]] test_table { }; ``` -3. Add to the data structure the fields which define the multi index table +3. Add to the data structure the fields which define the multi-index table ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { -+ // this field stores a name for each row of the multi index table ++ // this field stores a name for each row of the multi-index table + name test_primary; + // additional data stored in table row, e.g. an uint64_t type data + uint64_t datum; }; ``` -4. Add definition of the primary index for the multi index table. The primary index type must be uint64_t, it must be unique and it must be named `primary_key()`, if you don't have this the compiler (eosio-cpp) will generate an error saying it can't find the field to use as the primary key: +4. Add definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and it must be named `primary_key()`, if you don't have this the compiler (eosio-cpp) will generate an error saying it can't find the field to use as the primary key: ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -42,7 +42,7 @@ using namespace eosio; ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -53,11 +53,11 @@ using namespace eosio; + typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; ``` -6. Define the multi index table data member of type `test_tables` defined in the privious step +6. Define the multi-index table data member of type `test_tables` defined in the privious step ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -69,27 +69,27 @@ using namespace eosio; + test_tables testtab; ``` -7. Instantiate the data member `testtab` by passing to its constructor the `scope` (in this case `receiver`) and the `code` parameters, these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi index table, in this example you will initialize the `testtab` data member in the smart contract constructor +7. Instantiate the data member `testtab` by passing to its constructor the `scope` (in this case `receiver`) and the `code` parameters, these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor ```diff // contract class constructor multi_index_example( name receiver, name code, datastream ds ) : // contract base class contructor contract(receiver, code, ds), - // instantiate multi index instance as data member (find it defined below) + // instantiate multi-index instance as data member (find it defined below) + testtab(receiver, receiver.value) { } ``` -Now you have instantiated the `testtab` variable as a multi index table which has a primary index defined for its `test_primary` data member. +Now you have instantiated the `testtab` variable as a multi-index table which has a primary index defined for its `test_primary` data member. -Here is how the definition of a `multi_index_example` contract containing a multi index table could look like after following all the steps above. +Here is how the definition of a `multi_index_example` contract containing a multi-index table could look like after following all the steps above. __multi_index_example.hpp__ ```cpp #include using namespace eosio; -// multi index example contract class +// multi-index example contract class class [[eosio::contract]] multi_index_example : public contract { public: using contract::contract; @@ -98,14 +98,14 @@ class [[eosio::contract]] multi_index_example : public contract { multi_index_example( name receiver, name code, datastream ds ) : // contract base class contructor contract(receiver, code, ds), - // instantiate multi index instance as data member (find it defined below) + // instantiate multi-index instance as data member (find it defined below) testtab(receiver, receiver.value) { } - // the row structure of the multi index table, that is, each row of the table + // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -113,12 +113,12 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t primary_key( ) const { return test_primary.value; } }; - // the multi index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_tables`, // based on the multi_index template type, parametarized with a random name and // the test_table data structure typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; - // the multi index table instance declared as a data member of type test_tables + // the multi-index table instance declared as a data member of type test_tables test_tables testtab; [[eosio::action]] void set( name user ); @@ -130,4 +130,4 @@ class [[eosio::contract]] multi_index_example : public contract { ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index 939abbd7e8..bdd92e6fe8 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -1,17 +1,17 @@ --- -content_title: How to iterate and retrieve a multi index table based on secondary index +content_title: How to iterate and retrieve a multi-index table based on secondary index --- ## Preconditions -- It is assumed you already have a multi index table defined with a primary index and a secondary index, if not you can find an example [here](./how-to-define-a-secondary-index.md). +- It is assumed you already have a multi-index table defined with a primary index and a secondary index, if not you can find an example [here](./how-to-define-a-secondary-index.md). -You'll start with this example below which shows the definition of a `multi_index_example` contract class which has defined a multi index table with two indexes, a mandatory primary one and a secondary one: +You'll start with this example below which shows the definition of a `multi_index_example` contract class which has defined a multi-index table with two indexes, a mandatory primary one and a secondary one: ```cpp #include using namespace eosio; -// multi index example contract class +// multi-index example contract class class [[eosio::contract]] multi_index_example : public contract { public: using contract::contract; @@ -20,14 +20,14 @@ class [[eosio::contract]] multi_index_example : public contract { multi_index_example( name receiver, name code, datastream ds ) : // contract base class contructor contract(receiver, code, ds), - // instantiate multi index instance as data member (find it defined below) + // instantiate multi-index instance as data member (find it defined below) testtab(receiver, receiver.value) { } - // the row structure of the multi index table, that is, each row of the table + // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row @@ -37,12 +37,12 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t by_secondary( ) const { return secondary.value; } }; - // the multi index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_tables`, // based on the multi_index template type, parametarized with a random name, the // test_table data structure, and the secondary index typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; - // the multi index table instance declared as a data member of type test_tables + // the multi-index table instance declared as a data member of type test_tables test_tables testtab; [[eosio::action]] void set( name user ); @@ -53,7 +53,7 @@ class [[eosio::contract]] multi_index_example : public contract { }; ``` -To iterate and retreive the multi index table `testtab` defined in `multi_index_example` contract based on secondary index `by_secondary`, define a third action `bysec` which will do exactly that. +To iterate and retreive the multi-index table `testtab` defined in `multi_index_example` contract based on secondary index `by_secondary`, define a third action `bysec` which will do exactly that. 1. In the contract definition, add the new action definition, using the `[[eosio::action]] void` and the `eosio::action_wrapper` template like this: @@ -66,7 +66,7 @@ To iterate and retreive the multi index table `testtab` defined in `multi_index_ 2. In the contract implementation add the new action implementation like this: ```cpp -// iterates the multi index table rows using the secondary index and prints the row's values +// iterates the multi-index table rows using the secondary index and prints the row's values [[eosio::action]] void multi_index_example::bysec( name secid ) { // access the secondary index auto idx = testtab.get_index<"secid"_n>(); @@ -85,7 +85,7 @@ __multi_index_example.hpp__ #include using namespace eosio; -// multi index example contract class +// multi-index example contract class class [[eosio::contract]] multi_index_example : public contract { public: using contract::contract; @@ -94,14 +94,14 @@ class [[eosio::contract]] multi_index_example : public contract { multi_index_example( name receiver, name code, datastream ds ) : // contract base class contructor contract(receiver, code, ds), - // instantiate multi index instance as data member (find it defined below) + // instantiate multi-index instance as data member (find it defined below) testtab(receiver, receiver.value) { } - // the row structure of the multi index table, that is, each row of the table + // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row @@ -111,12 +111,12 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t by_secondary( ) const { return secondary.value; } }; - // the multi index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_tables`, // based on the multi_index template type, parametarized with a random name, the // test_table data structure, and the secondary index typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; - // the multi index table instance declared as a data member of type test_tables + // the multi-index table instance declared as a data member of type test_tables test_tables testtab; [[eosio::action]] void set( name user ); @@ -158,7 +158,7 @@ __multi_index_example.cpp__ eosio::print_f("Test Table : {%, %}\n", itr->test_primary, itr->datum); } -// iterates the multi index table rows using the secondary index and prints the row's values +// iterates the multi-index table rows using the secondary index and prints the row's values [[eosio::action]] void multi_index_example::bysec( name secid ) { // access the secondary index auto idx = testtab.get_index<"secid"_n>(); @@ -172,4 +172,4 @@ __multi_index_example.cpp__ ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 21abaa94b5..6e86e66297 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -1,19 +1,19 @@ --- -content_title: How to iterate and retrieve a multi index table +content_title: How to iterate and retrieve a multi-index table --- ## Preconditions -- It is assumed you already have a multi index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi index table](./how-to-instantiate-a-multi-index-table.md). +- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). -For exemplification define the multi index contract definition like below: +For exemplification define the multi-index contract definition like below: __multi_index_example.hpp__ ```cpp #include using namespace eosio; -// multi index example contract class +// multi-index example contract class class [[eosio::contract]] multi_index_example : public contract { public: using contract::contract; @@ -22,14 +22,14 @@ class [[eosio::contract]] multi_index_example : public contract { multi_index_example( name receiver, name code, datastream ds ) : // contract base class contructor contract(receiver, code, ds), - // instantiate multi index instance as data member (find it defined below) + // instantiate multi-index instance as data member (find it defined below) testtab(receiver, receiver.value) { } - // the row structure of the multi index table, that is, each row of the table + // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -37,12 +37,12 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t primary_key( ) const { return test_primary.value; } }; - // the multi index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_tables`, // based on the multi_index template type, parametarized with a random name and // the test_table data structure typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; - // the multi index table instance declared as a data member of type test_tables + // the multi-index table instance declared as a data member of type test_tables test_tables testtab; [[eosio::action]] void set( name user ); @@ -51,9 +51,9 @@ class [[eosio::contract]] multi_index_example : public contract { }; ``` -The steps below show how to iterate and retrieve a multi index table. +The steps below show how to iterate and retrieve a multi-index table. -1. Add to the above multi index example contract an action `print` which gets as parameter an acount name +1. Add to the above multi-index example contract an action `print` which gets as parameter an acount name ```cpp [[eosio::action]] void print( name user ); @@ -64,7 +64,7 @@ The steps below show how to iterate and retrieve a multi index table. +using print_action = action_wrapper<"print"_n, &multi_index_example::print>; ``` -3. Implement the action code, by searching for the `user` name in the multi index table using the primary index. If found, print out the value stored in that row for field `datum`. Otherwise asserts with a custom message. In the contract definition add the following implementation for `print` action: +3. Implement the action code, by searching for the `user` name in the multi-index table using the primary index. If found, print out the value stored in that row for field `datum`. Otherwise asserts with a custom message. In the contract definition add the following implementation for `print` action: ```cpp [[eosio::action]] void multi_index_example::print( name user ) { // searches for the row that corresponds to the user parameter @@ -84,7 +84,7 @@ __multi_index_example.hpp__ #include using namespace eosio; -// multi index example contract class +// multi-index example contract class class [[eosio::contract]] multi_index_example : public contract { public: using contract::contract; @@ -93,14 +93,14 @@ class [[eosio::contract]] multi_index_example : public contract { multi_index_example( name receiver, name code, datastream ds ) : // contract base class contructor contract(receiver, code, ds), - // instantiate multi index instance as data member (find it defined below) + // instantiate multi-index instance as data member (find it defined below) testtab(receiver, receiver.value) { } - // the row structure of the multi index table, that is, each row of the table + // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi index table + // this field stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -108,12 +108,12 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t primary_key( ) const { return test_primary.value; } }; - // the multi index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_tables`, // based on the multi_index template type, parametarized with a random name and // the test_table data structure typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; - // the multi index table instance declared as a data member of type test_tables + // the multi-index table instance declared as a data member of type test_tables test_tables testtab; [[eosio::action]] void set( name user ); @@ -155,4 +155,4 @@ __multi_index_example.cpp__ ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index 62a0250811..0d9b13cf74 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -1,13 +1,13 @@ --- -content_title: How to modify data in a multi index table +content_title: How to modify data in a multi-index table --- ## Preconditions -- It is assumed you already have a multi index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi index table](./how-to-instantiate-a-multi-index-table.md). +- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). -To modify data in the multi index table defined in the above tutorial, you will implement an action `mod` which it will receive as parameter the `user` which is the key of the row you want to modify and the `value` param which is the value to update with the row. +To modify data in the multi-index table defined in the above tutorial, you will implement an action `mod` which it will receive as parameter the `user` which is the key of the row you want to modify and the `value` param which is the value to update with the row. -1. Make use of the multi index table iterator to find out if the data exists +1. Make use of the multi-index table iterator to find out if the data exists ```cpp [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { auto itr = testtab.find(user.value); @@ -22,7 +22,7 @@ To modify data in the multi index table defined in the above tutorial, you will } ``` -3. If the row you want to update is found, the `check` method will do nothing and the iterator `itr` will be pointing at the row which you want to update, so then use the multi index `modify` method to make the update like below +3. If the row you want to update is found, the `check` method will do nothing and the iterator `itr` will be pointing at the row which you want to update, so then use the multi-index `modify` method to make the update like below ```diff [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -38,4 +38,4 @@ To modify data in the multi index table defined in the above tutorial, you will ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting.md index e8da1593a9..52e592dd59 100644 --- a/docs/08_troubleshooting.md +++ b/docs/08_troubleshooting.md @@ -63,7 +63,7 @@ __Possible solution__: Verify that `abi` and `wasm` files exist in the directory ## Action triggers ram charge which cannot be initiated from a notification. -__Possible solution__: The reason for this error is because the notification action doesn't have authorization to buy the needed RAM. In the context of multi index tables, there’s a table payer and a row payer. Only the contract can modify rows. The contract can create rows with a payer that didn’t authorize the action if the total amount of ram charged that payer doesn’t increase (e.g. delete a row and add another with the same payer). The table payer can’t change until the last row is deleted. For the purposes of billing, a table is identified by the tuple `contract, scope, table`. When you create a row for a `contract, scope, table` tuple that doesn’t exist, you create a table with the same payer. This can outlive the original row which created it, if other rows were created with that combination and this prevents the original payer from getting their ram back. Secondary indexes throw in more complexity since they use the lower 4 bits of the table name, producing additional `contract, scope, table` tuples combinations. Key takeaway: payer is about billing, not access control +__Possible solution__: The reason for this error is because the notification action doesn't have authorization to buy the needed RAM. In the context of multi-index tables, there’s a table payer and a row payer. Only the contract can modify rows. The contract can create rows with a payer that didn’t authorize the action if the total amount of ram charged that payer doesn’t increase (e.g. delete a row and add another with the same payer). The table payer can’t change until the last row is deleted. For the purposes of billing, a table is identified by the tuple `contract, scope, table`. When you create a row for a `contract, scope, table` tuple that doesn’t exist, you create a table with the same payer. This can outlive the original row which created it, if other rows were created with that combination and this prevents the original payer from getting their ram back. Secondary indexes throw in more complexity since they use the lower 4 bits of the table name, producing additional `contract, scope, table` tuples combinations. Key takeaway: payer is about billing, not access control ## You successfully re-deployed the contract code, but when you query the table you get the custom message that you coded when the table is not initialized (doesn't exist), or the system error message below in case you do not have code that checks first if table exist diff --git a/docs/09_tutorials/02_abi-variants.md b/docs/09_tutorials/02_abi-variants.md index cc2448b0ab..34c3ae2b55 100644 --- a/docs/09_tutorials/02_abi-variants.md +++ b/docs/09_tutorials/02_abi-variants.md @@ -4,9 +4,9 @@ link_text: ABI variants --- ABI variants give the flexibility of using more than one type for a defined variable or data member. -In EOSIO, the variants make use of the standard template library `variant` which was introduced in C++ 17. An instance of `std::variant` at any given time either holds a value of one of its alternative types, or in the case of error - no value. Because of this trait, variants can be used to build the multi index table structure with flexibility. Used in conjunction with ABI extensions, it allows for modification of the structure of an exiting multi index table, a.k.a. table. +In EOSIO, the variants make use of the standard template library `variant` which was introduced in C++ 17. An instance of `std::variant` at any given time either holds a value of one of its alternative types, or in the case of error - no value. Because of this trait, variants can be used to build the multi-index table structure with flexibility. Used in conjunction with ABI extensions, it allows for modification of the structure of an exiting multi-index table, a.k.a. table. -## Use variant when building the multi index table the first time +## Use variant when building the multi-index table the first time To define a `variant` for your table structure one example is shown below @@ -101,9 +101,9 @@ class [[eosio::contract]] multi_index_example : public contract { }; ``` -Now you can deploy the contract and it will be backwards compatible with the previous existing multi index table. +Now you can deploy the contract and it will be backwards compatible with the previous existing multi-index table. -## Use variant when changing an already deployed multi index table +## Use variant when changing an already deployed multi-index table ### Preconditions - It is assumed you deployed the contract defined in [this section](../06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md) and now you are going to change its table structure. From 81e9eb01021546d5962df9357ce6486705d79898 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 12:43:45 +0300 Subject: [PATCH 115/204] [[Info -> [[info take 2 --- docs/09_tutorials/02_abi-variants.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/09_tutorials/02_abi-variants.md b/docs/09_tutorials/02_abi-variants.md index 34c3ae2b55..310c3df8ac 100644 --- a/docs/09_tutorials/02_abi-variants.md +++ b/docs/09_tutorials/02_abi-variants.md @@ -156,5 +156,5 @@ class [[eosio::contract]] multi_index_example : public contract { [[warning | Not recommended warning]] | Be aware, it is not recommend to use `eosio::binary_extension` inside variant definition, this can lead to data corruption unless one is very careful in understanding how these two templates work and how the ABI gets generated! -[[Info | Implementation location]] +[[info | Implementation location]] | The implementation for ABI `variants` can be found [here](https://github.com/EOSIO/eos/pull/5652). From 9c0df1b77d7c68ce23090e56e9c86be23dca720e Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 13:07:06 +0300 Subject: [PATCH 116/204] take 2 --- .../how-to-define-a-primary-index.md | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index a984a3a2b9..3c15d4a958 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -4,7 +4,7 @@ content_title: How to define a primary index ## Overview -This guide provides instructions on how to define a primary index in a multi-index table. +This guide provides instructions on how to define a primary index for a multi-index table. ## Reference @@ -17,12 +17,10 @@ See the following code reference: Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), -* A multi-index table named `test_table`, -* A primary key is required when defining a multi-index table structure, therefore you need to know which is the property that is the primary key for your multi-index table structure. That property must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. ## Procedure -Complete the following steps to define a primary index for the multi-index table named `test_table` based on its `test_primary` data member. +Complete the following steps to define a primary index for the multi-index table named `testtab`. ### 1. Preparation And Initialization @@ -42,7 +40,7 @@ Define the data structure for the multi-index table }; ``` -Add to the data structure the fields which define the multi-index table +Add to the data structure the properties which define it. Each property corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the field that is the primary key for your multi-index table structure. The corresponding property for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. ```diff // the data structure which defines each row of the table @@ -56,7 +54,7 @@ Add to the data structure the fields which define the multi-index table ### 3. Define The Primary Index -Add the definition of the primary index for the multi-index table. The primary index type must be uint64_t and must be unique +Add the definition of the primary index for the multi-index table. The primary index type must be uint64_t and must be unique. ```diff // the data structure which defines each row of the table @@ -75,7 +73,7 @@ Add the definition of the primary index for the multi-index table. The primary i ### 4. Define A Multi-Index Type Alias -For ease of use, define a type alias `test_tables` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above +For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above ```diff // the data structure which defines each row of the table @@ -88,12 +86,12 @@ For ease of use, define a type alias `test_tables` based on the `eosio::multi_in uint64_t primary_key( ) const { return test_primary.value; } }; - + typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; + + typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; ``` ### 5. Instantiate The Multi-Index Table -Declare the multi-index table as a data member of type `test_tables`, as defined above. +Declare the `testtab` multi-index table as a data member of type `test_table_t`. ```diff // the data structure which defines each row of the table @@ -106,8 +104,8 @@ Declare the multi-index table as a data member of type `test_tables`, as defined uint64_t primary_key( ) const { return test_primary.value; } }; - typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; - + test_tables testtab; + typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; + + test_table_t testtab; ``` Now you have instantiated the `testtab` as a multi-index table which has a primary index defined for its `test_primary` data member. From e0495f126fb32c9566dfca1b136acc3d6495a67d Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 13:47:50 +0300 Subject: [PATCH 117/204] take 4 --- .../how-to-define-a-primary-index.md | 16 +- .../how-to-define-a-secondary-index.md | 199 +++++++++++------- 2 files changed, 126 insertions(+), 89 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index 3c15d4a958..16747c7d1c 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -20,7 +20,7 @@ Make sure you have the following prerequisites in place: ## Procedure -Complete the following steps to define a primary index for the multi-index table named `testtab`. +Complete the following steps to define a primary index for the multi-index table `testtab`. ### 1. Preparation And Initialization @@ -40,12 +40,12 @@ Define the data structure for the multi-index table }; ``` -Add to the data structure the properties which define it. Each property corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the field that is the primary key for your multi-index table structure. The corresponding property for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. +Add to the data structure the properties which define it. Each property corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding property for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - + // this field stores a name for each row of the multi-index table + + // this property stores a name for each row of the multi-index table + name test_primary; + // additional data stored in table row, e.g. an uint64_t type data + uint64_t datum; @@ -59,7 +59,7 @@ Add the definition of the primary index for the multi-index table. The primary i ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -69,7 +69,7 @@ Add the definition of the primary index for the multi-index table. The primary i ``` [[info | Secondary indexes information]] -| Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double. +| Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the corresponding property types can be uint64_t, uint128_t, uint256_t, double or long double. ### 4. Define A Multi-Index Type Alias @@ -78,7 +78,7 @@ For ease of use, define a type alias `test_table_t` based on the `eosio::multi_i ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -96,7 +96,7 @@ Declare the `testtab` multi-index table as a data member of type `test_table_t`. ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -115,7 +115,7 @@ Now you have instantiated the `testtab` as a multi-index table which has a prima ## Summary -In conclusion, the above instructions show how to define a primary index in a multi-index table. +In conclusion, the above instructions show how to define a primary index for a multi-index table. ## Next Steps diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index fa5672c2f8..e5b16284a6 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -2,91 +2,128 @@ content_title: How to define a secondary index --- -## Preconditions -- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). - -The steps below show how to add a secondary index to the existing multi-index table. - -1. Add a second field, `secondary`, to the data structure that defines the row of the table, in your case `test_table` -```diff - struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table - name test_primary; -+ name secondary; - // additional data stored in table row - uint64_t datum; - // mandatory definition for primary key getter - uint64_t primary_key( ) const { return test_primary.value; } - }; -``` - -2. Add `by_secondary( )` method, which is the index accessor method to the new field value added. The secondary index, that will be added in step 3, will index this new data structure field. -```diff - struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table - name test_primary; - name secondary; - // additional data stored in table row - uint64_t datum; - // mandatory definition for primary key getter - uint64_t primary_key( ) const { return test_primary.value; } -+ uint64_t by_secondary( ) const { return secondary.value; } - }; -``` +## Overview + +This guide provides instructions on how to define a secondary index for a multi-index table. + +## Reference + +See the following code reference: + +* The [`multi-index`](../../classeosio_1_1multi__index) class. + +## Before you begin + +Make sure you have the following prerequisites in place: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), +* A multi-index table `testtab` along with its `test_table` data structure, its mandatory primary index, and the type alias definition `test_table_t`. Please see [How To Define A Primary Index](./how-to-define-a-primary-index) to set up these prerequisites. + +## Procedure + +Complete the following steps to define a secondary index for the multi-index table `testtab`. + +### 1. Extend The Multi-Index Data Structure + +Add a second property `secondary`, of type `eosio::name`, to the `test_table` data structure that defines the `testtab` data. -3. In the `test_table` alias definition (typedef), add the definition of the secondary index by making use of the `eosio::indexed_by` template. `eosio::index_by` needs two parameters: the name of the index, `"secid"_n`, and a function call operator which extracts the value from the secondary data member as an index key. The function call operator is achieved by employing the `eosio::const_mem_fun` template which receives two parameters: the data structure `test_table` and the reference to the getter function member `by_secondary`. + ```diff + struct [[eosio::table]] test_table { + // this property stores a name for each row of the multi-index table + name test_primary; + + name secondary; + // additional data stored in table row + uint64_t datum; + // mandatory definition for primary key getter + uint64_t primary_key( ) const { return test_primary.value; } + }; + ``` -```diff -- typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; -+ typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; -``` +### 2. Add The Secondary Index Accessor Method -The full contract definition code with all the changes described above could look like this: +Add `by_secondary()` method, which is the index accessor method to the new property added. The secondary index, that will be added in the next step, will index this new data structure property. + + ```diff + struct [[eosio::table]] test_table { + // this property stores a name for each row of the multi-index table + name test_primary; + name secondary; + // additional data stored in table row + uint64_t datum; + // mandatory definition for primary key getter + uint64_t primary_key( ) const { return test_primary.value; } + + uint64_t by_secondary( ) const { return secondary.value; } + }; + ``` + +### 3. Define The Secondary Index + +In the `test_table_t` type definition, add the definition of the secondary index with the use of the `eosio::indexed_by` template. `eosio::index_by` needs two parameters: the name of the index, `"secid"_n`, and a function call operator which extracts the value from the secondary data member as an index key. The function call operator is defined with the use of `eosio::const_mem_fun` template which receives two parameters: the data structure `test_table` and the reference to the getter function member `by_secondary`. + + ```diff + - typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; + + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; + ``` + +For reference see below the full contract definition code with all the changes described above: __multi_index_example.hpp__ -```cpp -#include -using namespace eosio; - -// multi-index example contract class -class [[eosio::contract]] multi_index_example : public contract { - public: - using contract::contract; - - // contract class constructor - multi_index_example( name receiver, name code, datastream ds ) : - // contract base class contructor - contract(receiver, code, ds), - // instantiate multi-index instance as data member (find it defined below) - testtab(receiver, receiver.value) - { } - - struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table - name test_primary; - name secondary; - // additional data stored in table row - uint64_t datum; - // mandatory definition for primary key getter - uint64_t primary_key( ) const { return test_primary.value; } - uint64_t by_secondary( ) const { return secondary.value; } - }; - - // the multi-index type definition, for ease of use a type alias `test_tables` is defined, - // based on the multi_index template type, parametarized with a random name, the - // test_table data structure, and the secondary index - typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; - - // the multi-index table instance declared as a data member of type test_tables - test_tables testtab; - - [[eosio::action]] void set( name user ); - [[eosio::action]] void print( name user ); - - using set_action = action_wrapper<"set"_n, &multi_index_example::set>; - using print_action = action_wrapper<"print"_n, &multi_index_example::print>; -}; -``` + + ```cpp + #include + using namespace eosio; + + // multi-index example contract class + class [[eosio::contract]] multi_index_example : public contract { + public: + using contract::contract; + + // contract class constructor + multi_index_example( name receiver, name code, datastream ds ) : + // contract base class contructor + contract(receiver, code, ds), + // instantiate multi-index instance as data member (find it defined below) + testtab(receiver, receiver.value) + { } + + struct [[eosio::table]] test_table { + // this property stores a name for each row of the multi-index table + name test_primary; + name secondary; + // additional data stored in table row + uint64_t datum; + // mandatory definition for primary key getter + uint64_t primary_key( ) const { return test_primary.value; } + uint64_t by_secondary( ) const { return secondary.value; } + }; + + // the multi-index type definition, for ease of use a type alias `test_table_t` is defined, + // based on the multi_index template type, parametarized with a random name, the + // test_table data structure, and the secondary index + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; + + // the multi-index table instance declared as a data member of type test_table_t + test_table_t testtab; + + [[eosio::action]] void set( name user ); + [[eosio::action]] void print( name user ); + + using set_action = action_wrapper<"set"_n, &multi_index_example::set>; + using print_action = action_wrapper<"print"_n, &multi_index_example::print>; + }; + ``` + +Now you have instantiated the `testtab` as a multi-index table which has a primary index defined for its `test_primary` data member and a secondary index for its `secondary` data member. [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to define a secondary index for a multi-index table. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [iterate and retrieve data using the secondary index](./how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index) from the multi-index table. From 4cfa19cb9fdf2d86fe064695c2efc3bb8b645cf5 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 13:48:26 +0300 Subject: [PATCH 118/204] cosmetics: renames --- .../how-to-instantiate-a-multi-index-table.md | 28 +++++++++---------- ...ti_index-table-based-on-secondary-index.md | 20 ++++++------- ...terate-and-retrieve-a-multi_index-table.md | 20 ++++++------- docs/09_tutorials/02_abi-variants.md | 12 ++++---- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index a4c4d0cd66..d57a840a98 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -16,7 +16,7 @@ using namespace eosio; ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { -+ // this field stores a name for each row of the multi-index table ++ // this property stores a name for each row of the multi-index table + name test_primary; + // additional data stored in table row, e.g. an uint64_t type data + uint64_t datum; @@ -26,7 +26,7 @@ using namespace eosio; ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -38,11 +38,11 @@ using namespace eosio; [[info | Additional indexes information]] | Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double. -5. For ease of use, define a type alias `test_tables` based on the multi_index template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above +5. For ease of use, define a type alias `test_table_t` based on the multi_index template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -50,14 +50,14 @@ using namespace eosio; uint64_t primary_key( ) const { return test_primary.value; } }; -+ typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; ++ typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; ``` -6. Define the multi-index table data member of type `test_tables` defined in the privious step +6. Define the multi-index table data member of type `test_table_t` defined in the privious step ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -65,8 +65,8 @@ using namespace eosio; uint64_t primary_key( ) const { return test_primary.value; } }; - typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; -+ test_tables testtab; + typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; ++ test_table_t testtab; ``` 7. Instantiate the data member `testtab` by passing to its constructor the `scope` (in this case `receiver`) and the `code` parameters, these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor @@ -105,7 +105,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -113,13 +113,13 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t primary_key( ) const { return test_primary.value; } }; - // the multi-index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_table_t`, // based on the multi_index template type, parametarized with a random name and // the test_table data structure - typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; - // the multi-index table instance declared as a data member of type test_tables - test_tables testtab; + // the multi-index table instance declared as a data member of type test_table_t + test_table_t testtab; [[eosio::action]] void set( name user ); [[eosio::action]] void print( name user ); diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index bdd92e6fe8..48150cd69c 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -27,7 +27,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row @@ -37,13 +37,13 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t by_secondary( ) const { return secondary.value; } }; - // the multi-index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_table_t`, // based on the multi_index template type, parametarized with a random name, the // test_table data structure, and the secondary index - typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; - // the multi-index table instance declared as a data member of type test_tables - test_tables testtab; + // the multi-index table instance declared as a data member of type test_table_t + test_table_t testtab; [[eosio::action]] void set( name user ); [[eosio::action]] void print( name user ); @@ -101,7 +101,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row @@ -111,13 +111,13 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t by_secondary( ) const { return secondary.value; } }; - // the multi-index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_table_t`, // based on the multi_index template type, parametarized with a random name, the // test_table data structure, and the secondary index - typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; - // the multi-index table instance declared as a data member of type test_tables - test_tables testtab; + // the multi-index table instance declared as a data member of type test_table_t + test_table_t testtab; [[eosio::action]] void set( name user ); [[eosio::action]] void print( name user ); diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 6e86e66297..c67122d53d 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -29,7 +29,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -37,13 +37,13 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t primary_key( ) const { return test_primary.value; } }; - // the multi-index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_table_t`, // based on the multi_index template type, parametarized with a random name and // the test_table data structure - typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; - // the multi-index table instance declared as a data member of type test_tables - test_tables testtab; + // the multi-index table instance declared as a data member of type test_table_t + test_table_t testtab; [[eosio::action]] void set( name user ); @@ -100,7 +100,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this field stores a name for each row of the multi-index table + // this property stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -108,13 +108,13 @@ class [[eosio::contract]] multi_index_example : public contract { uint64_t primary_key( ) const { return test_primary.value; } }; - // the multi-index type definition, for ease of use define a type alias `test_tables`, + // the multi-index type definition, for ease of use define a type alias `test_table_t`, // based on the multi_index template type, parametarized with a random name and // the test_table data structure - typedef eosio::multi_index<"testtaba"_n, test_table> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; - // the multi-index table instance declared as a data member of type test_tables - test_tables testtab; + // the multi-index table instance declared as a data member of type test_table_t + test_table_t testtab; [[eosio::action]] void set( name user ); [[eosio::action]] void print( name user ); diff --git a/docs/09_tutorials/02_abi-variants.md b/docs/09_tutorials/02_abi-variants.md index 310c3df8ac..558630b0dc 100644 --- a/docs/09_tutorials/02_abi-variants.md +++ b/docs/09_tutorials/02_abi-variants.md @@ -45,9 +45,9 @@ class [[eosio::contract]] multi_index_example : public contract { } }; - typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; - test_tables testtab; + test_table_t testtab; [[eosio::action]] void set(name user); [[eosio::action]] void print( name user ); @@ -89,9 +89,9 @@ class [[eosio::contract]] multi_index_example : public contract { } }; - typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; - test_tables testtab; + test_table_t testtab; [[eosio::action]] void set(name user); [[eosio::action]] void print( name user ); @@ -141,9 +141,9 @@ class [[eosio::contract]] multi_index_example : public contract { + } }; - typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_tables; + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; - test_tables testtab; + test_table_t testtab; [[eosio::action]] void set(name user); [[eosio::action]] void print( name user ); From e02ff1b1c3a1119af89b3322e7be2b272a09fed0 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 15:48:54 +0300 Subject: [PATCH 119/204] take 5 --- .../how-to-define-a-primary-index.md | 6 +- .../how-to-define-a-secondary-index.md | 2 +- .../how-to-define-a-singleton.md | 127 ++++++++++++------ 3 files changed, 90 insertions(+), 45 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index 16747c7d1c..b628a4dbdd 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -24,7 +24,7 @@ Complete the following steps to define a primary index for the multi-index table ### 1. Preparation And Initialization -Include the `eosio.hpp` header and declare the `eosio` namespace usage +Include the `eosio.hpp` header and declare the `eosio` namespace usage. ```cpp #include @@ -33,7 +33,7 @@ Include the `eosio.hpp` header and declare the `eosio` namespace usage ### 2. Defines The Table Data Structure -Define the data structure for the multi-index table +Define the data structure for the multi-index table. ```cpp struct [[eosio::table]] test_table { @@ -73,7 +73,7 @@ Add the definition of the primary index for the multi-index table. The primary i ### 4. Define A Multi-Index Type Alias -For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above +For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above. ```diff // the data structure which defines each row of the table diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index e5b16284a6..a4149bc112 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -65,7 +65,7 @@ In the `test_table_t` type definition, add the definition of the secondary index + typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; ``` -For reference see below the full contract definition code with all the changes described above: +For reference see below the full contract definition code with all the changes described above. __multi_index_example.hpp__ diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index 737a46341f..e53b9f0149 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -2,56 +2,90 @@ content_title: How to define a singleton --- -To define a simple singleton, which is storing an account name as primary value and a uint64_t as secondary value in structure `testtable`, follow the steps below: +## Overview -1. Include the `eosio.hpp` and `singleton.hpp` headers and declare the `eosio` namespace usage -``` -#include -#include -using namespace eosio; -``` +This guide provides instructions on how to define a singleton. -2. Define the data structure for the multi-index table -```cpp -struct [[eosio::table]] testtable { - name primary_value; - uint64_t secondary_value; -}; -``` +## Reference -3. For ease of use, define a type alias `singleton_type` based on the `eosio::singleton` template type, parametarized with a random name `"testtable"`, which has to respect the EOSIO account name restrictions, and the `testtable` data structure defined above -```diff -struct [[eosio::table]] testtable { - name primary_value; - uint64_t secondary_value; -}; -+using singleton_type = eosio::singleton<"testtable"_n, testtable>; -``` +See the following code reference: -4. Define the singleton table instance declared as a data member of type `singleton_type` defined in the privious step -```diff -struct [[eosio::table]] testtable { - name primary_value; - uint64_t secondary_value; -}; +* The [`singleton`](../../classeosio_1_1singleton) class. -using singleton_type = eosio::singleton<"testtable"_n, testtable>; -+singleton_type singleton_instance; -``` +## Before you begin -5. Instantiate the data member `singleton_instance` by passing to its constructor the `receiver` and the `code` (in this case `receiver.value`) parameters; these two combined with "testtable" provide access to the partition of the RAM cache used by this singleton. In this example you will initialize the `singleton_instance` data member in the smart contract constructor, see below: -```diff -// singleton contract constructor -singleton_example( name receiver, name code, datastream ds ) : - contract(receiver, code, ds), -+ singleton_instance(receiver, receiver.value) - { } -} -``` +Make sure you have the following prerequisites in place: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), + +## Procedure + +A singleton uses a single multi-index table to store named objects of various types. To define a simple singleton, which is storing an account name as primary value and a uint64_t as secondary value in structure `testtable`, follow the steps below: + +### 1. Preparation And Initialization + +Include the `eosio.hpp` and `singleton.hpp` headers and declare the `eosio` namespace usage + + ```cpp + #include + #include + using namespace eosio; + ``` -Now you have defined and instantiated a singleton. Below you can find a possible implementation for the full class singleton example contract. +### 2. Defines The Table Data Structure + +Define the data structure for the multi-index table the singleton will use: + + ```cpp + struct [[eosio::table]] testtable { + name primary_value; + uint64_t secondary_value; + }; + ``` + +### 3. Define A Singleton Type Alias + +For ease of use, define a type alias `singleton_type` based on the `eosio::singleton` template type, parametarized with a random name `"testtable"`, which has to respect the EOSIO account name restrictions, and the `testtable` data structure defined above + + ```diff + struct [[eosio::table]] testtable { + name primary_value; + uint64_t secondary_value; + }; + +using singleton_type = eosio::singleton<"testtable"_n, testtable>; + ``` + +### 4. Define The Singleton Instance + +Define the singleton table instance as a data member of type `singleton_type` defined in the previous step. + + ```diff + struct [[eosio::table]] testtable { + name primary_value; + uint64_t secondary_value; + }; + + using singleton_type = eosio::singleton<"testtable"_n, testtable>; + +singleton_type singleton_instance; + ``` + +### 5. Initialize And Use The Singleton Instance + +Initialize `singleton_instance` defined previously by passing to its constructor the `receiver` and the `code` (in this case `receiver.value`) parameters; these two combined with "testtable" provide access to the partition of the RAM cache used by this singleton. In this example you will initialize the `singleton_instance` data member in the smart contract constructor, see below: + + ```diff + // singleton contract constructor + singleton_example( name receiver, name code, datastream ds ) : + contract(receiver, code, ds), + + singleton_instance(receiver, receiver.value) + { } + } + ``` + +Now you have defined and initialized a singleton as a data member for the smart contract class. You can access it from any of the smart contract methods via `singleton_instance` data member. Below you can find a possible implementation for the full class singleton example contract. __singleton_example.hpp__ + ```cpp #include #include @@ -87,6 +121,7 @@ class [[eosio::contract]] singleton_example : public contract { And below is a possible implementation for the two `get` and `set` actions defined above. It also demonstrates the usage of a couple of singleton methods. Note that the `set` action makes use of the singleton's `set` method, for which parameter is the account to pay for the new value stored. In this case, the same account name that is stored in the primary value is the payer. However, it can be a different account if so required. __singleton_example.cpp__ + ```cpp #include @@ -112,3 +147,13 @@ __singleton_example.cpp__ [[info | Full example location]] | A full example project demonstrating the instantiation and usage of singleton can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/singleton_example). + +## Summary + +In conclusion, the above instructions show how to define a singleton. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the singleton. From 5fe54bb08f91d937375f27351d7d611177f93acd Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 27 May 2021 15:51:22 +0300 Subject: [PATCH 120/204] take 6 --- .../40_multi-index/how-to-define-a-singleton.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index e53b9f0149..2811372557 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -20,7 +20,7 @@ Make sure you have the following prerequisites in place: ## Procedure -A singleton uses a single multi-index table to store named objects of various types. To define a simple singleton, which is storing an account name as primary value and a uint64_t as secondary value in structure `testtable`, follow the steps below: +A singleton uses a single multi-index table to store named objects of various types. To define a simple singleton, which is storing an account `name` as primary value and a `uint64_t` as secondary value in structure `testtable`, follow the steps below: ### 1. Preparation And Initialization @@ -156,4 +156,4 @@ In conclusion, the above instructions show how to define a singleton. The following option is available when you complete the procedure: -* You can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the singleton. +* Because a singleton is using a multi-index table, you can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the singleton. From cd6593bd837c0206f468a833016ef89130c36088 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Mon, 31 May 2021 16:32:57 +0300 Subject: [PATCH 121/204] take 6 --- .../how-to-define-a-primary-index.md | 5 +- .../how-to-define-a-singleton.md | 2 +- ...to-delete-data-from-a-multi-index-table.md | 59 ++++++++++-- ...to-insert-data-into-a-multi-index-table.md | 50 +++++++++-- .../how-to-instantiate-a-multi-index-table.md | 90 +++++++++++++++---- 5 files changed, 171 insertions(+), 35 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index b628a4dbdd..4f6bad6016 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -31,7 +31,7 @@ Include the `eosio.hpp` header and declare the `eosio` namespace usage. using namespace eosio; ``` -### 2. Defines The Table Data Structure +### 2. Define The Table Data Structure Define the data structure for the multi-index table. @@ -54,7 +54,7 @@ Add to the data structure the properties which define it. Each property correspo ### 3. Define The Primary Index -Add the definition of the primary index for the multi-index table. The primary index type must be uint64_t and must be unique. +Add definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and it must be named `primary_key()`, otherwise the compiler (eosio-cpp) will generate an error saying it can not find the field to use as the primary key: ```diff // the data structure which defines each row of the table @@ -121,4 +121,5 @@ In conclusion, the above instructions show how to define a primary index for a m The following option is available when you complete the procedure: +* You can [insert data in the multi-index table](./how-to-insert-data-into-a-multi-index-table). * You can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index 2811372557..5b9d554544 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -156,4 +156,4 @@ In conclusion, the above instructions show how to define a singleton. The following option is available when you complete the procedure: -* Because a singleton is using a multi-index table, you can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the singleton. +* Because a singleton is using as underlying structure a multi-index table, you can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the singleton same as you would with a multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index 2b37678585..759419ce11 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -2,12 +2,33 @@ content_title: How to delete data from a multi-index table --- -## Preconditions -- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). +## Overview -To delete data from a multi-index table follow the steps below: +This guide provides instructions on how to to delete data from a multi-index table. + +## Reference + +See the following code reference: + +* The [`multi-index`](../../classeosio_1_1multi__index) class. +* The [`find(...)`](../../group__multiindex#function-find) function. +* The [`erase(...)`](../../group__multiindex/#function-erase) method. + +## Before you begin + +Make sure you have the following prerequisites in place: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), +* A multi-index `testab` table instance which stores `user` objects indexed by the primary key which is of type `eosio::name`. Consult the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md) to learn how to set it up. + +## Procedure + +Complete the following steps to implement a `del` action which deletes an user object, identified by its account name, from the multi-index table. + +### 1. Find The User You Want To Delete + +Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to delete based on its account name: -1. Make use of the multi-index table iterator to find out if the data exists ```cpp [[eosio::action]] void multi_index_example::del( name user ) { // check if the user already exists @@ -15,13 +36,16 @@ To delete data from a multi-index table follow the steps below: } ``` -2. If the data exists use the `delete` method to delete the row from table +### 2. Delete The User If Found + +If the user exists use the [`erase`(...)](../../group__multiindex/#function-erase) method to delete the row from table. Otherwise print an informational message and return. + ```diff [[eosio::action]] void multi_index_example::del( name user ) { // check if the user already exists auto itr = testtab.find(user.value); + if ( itr == testtab.end() ) { -+ printf("user does not exist in table, nothing to delete" ); ++ printf("User does not exist in table, nothing to delete"); + return; + } @@ -30,4 +54,25 @@ To delete data from a multi-index table follow the steps below: ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to delete data from a multi-index table. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can verify if the user object was deleted from the multi-index table. . + +```cpp + // check if the user was deleted + auto itr = testtab.find(user.value); + if ( itr == testtab.end() ) { + printf("User was deleted successfully."); + } + else { + printf("User was NOT deleted!"); + } +``` diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index eae3503bf2..66444450c7 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -2,21 +2,44 @@ content_title: How to insert data into a multi-index table --- -## Preconditions -- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). +## Overview -To insert data into a multi-index table follow the following steps +This guide provides instructions on how to insert data into a multi-index table. + +## Reference + +See the following code reference: + +* The [`multi-index`](../../classeosio_1_1multi__index) class. +* The [`find(...)`](../../group__multiindex#function-find) function. +* The [`emplace`](../../group__multiindex/#function-emplace) method. + +## Before you begin + +Make sure you have the following prerequisites in place: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), +* A multi-index `testab` table instance which stores `user` objects indexed by the primary key which is of type `eosio::name`. Consult the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md) to learn how to set it up. + +## Procedure + +Complete the following steps to insert an user object in the `testtab` multi-index table: + +### 1. Verify If The User Already Exists + +Make use of the multi-index table iterator to find out if the user object already exists. -1. Make use of the multi-index table iterator to find out if the data doesn't already exist ```cpp [[eosio::action]] void multi_index_example::set( name user ) { // check if the user already exists auto itr = testtab.find(user.value); - } ``` -2. Use the `emplace` method to make the insertion if the user is not already in table +### 2. Insert The User If Not Found In Table + +Use the [`emplace`](../../group__multiindex/#function-emplace) method to make the insertion if the user object is not already in the multi-index table. Otherwise print an informational message. + ```diff [[eosio::action]] void multi_index_example::set( name user ) { // check if the user already exists @@ -29,8 +52,21 @@ To insert data into a multi-index table follow the following steps + u.datum = 0; + }); + } ++ else { ++ printf("User already exists."); ++ } } ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to insert data in a multi-index table. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [iterate and retrieve newly inserted data](./how-to-iterate-and-retrieve-a-multi_index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index d57a840a98..7a92530dad 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -2,27 +2,60 @@ content_title: How to instantiate a multi-index table --- -1. Include the `eosio.hpp` header and declare the `eosio` namespace usage -``` +## Overview + +This guide provides instructions on how to instantiate a multi-index table. + +## Reference + +See the following code reference: + +* The [`multi-index`](../../classeosio_1_1multi__index) class. + +## Before you begin + +Make sure you have the following prerequisites in place: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), + +## Procedure + +Complete the following steps to instantiate a multi-index table `testtab`. + +### 1. Preparation And Initialization + +Include the `eosio.hpp` header and declare the `eosio` namespace usage. + +```cpp #include using namespace eosio; ``` -2. Define the data structure for the multi-index table + +### 2. Define The Table Data Structure + +Define the data structure for the multi-index table. + ```cpp struct [[eosio::table]] test_table { }; ``` -3. Add to the data structure the fields which define the multi-index table -```diff - // the data structure which defines each row of the table - struct [[eosio::table]] test_table { -+ // this property stores a name for each row of the multi-index table -+ name test_primary; -+ // additional data stored in table row, e.g. an uint64_t type data -+ uint64_t datum; - }; -``` -4. Add definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and it must be named `primary_key()`, if you don't have this the compiler (eosio-cpp) will generate an error saying it can't find the field to use as the primary key: + +Add to the data structure the properties which define it. Each property corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding property for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. + + ```diff + // the data structure which defines each row of the table + struct [[eosio::table]] test_table { + + // this property stores a name for each row of the multi-index table + + name test_primary; + + // additional data stored in table row, e.g. an uint64_t type data + + uint64_t datum; + }; + ``` + +### 3. Define The Primary Index + +Add definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and it must be named `primary_key()`, otherwise the compiler (eosio-cpp) will generate an error saying it can not find the field to use as the primary key: + ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { @@ -38,7 +71,10 @@ using namespace eosio; [[info | Additional indexes information]] | Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the field types can be uint64_t, uint128_t, uint256_t, double or long double. -5. For ease of use, define a type alias `test_table_t` based on the multi_index template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above +### 4. Define A Multi-Index Type Alias + +For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above. + ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { @@ -53,7 +89,10 @@ using namespace eosio; + typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; ``` -6. Define the multi-index table data member of type `test_table_t` defined in the privious step +### 5. Instantiate The Multi-Index Table + +Declare the `testtab` multi-index table as a data member of type `test_table_t`. + ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { @@ -69,7 +108,9 @@ using namespace eosio; + test_table_t testtab; ``` -7. Instantiate the data member `testtab` by passing to its constructor the `scope` (in this case `receiver`) and the `code` parameters, these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor +# 6. Initialize The Multi-Index Table Instance + +Initialize the data member `testtab` by passing to its constructor the `scope` (in this case `receiver`) and the `code` parameters, these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor ```diff // contract class constructor @@ -80,11 +121,13 @@ multi_index_example( name receiver, name code, datastream ds ) : + testtab(receiver, receiver.value) { } ``` + Now you have instantiated the `testtab` variable as a multi-index table which has a primary index defined for its `test_primary` data member. Here is how the definition of a `multi_index_example` contract containing a multi-index table could look like after following all the steps above. __multi_index_example.hpp__ + ```cpp #include using namespace eosio; @@ -130,4 +173,15 @@ class [[eosio::contract]] multi_index_example : public contract { ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to define and instantiate a multi-index table instance. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [insert data in the multi-index table](./how-to-insert-data-into-a-multi-index-table). +* You can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the multi-index table. From fcd12b6b043f87b85a59b9f48626d1ae6801873b Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 1 Jun 2021 14:10:14 +0300 Subject: [PATCH 122/204] almost done, a few more touch ups needed --- ...to-delete-data-from-a-multi-index-table.md | 4 +- ...to-insert-data-into-a-multi-index-table.md | 4 +- ...ti_index-table-based-on-secondary-index.md | 90 +++++++++---------- ...terate-and-retrieve-a-multi_index-table.md | 87 +++++++++--------- ...w-to-modify-data-in-a-multi-index-table.md | 65 ++++++++++++-- 5 files changed, 145 insertions(+), 105 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index 759419ce11..445d263370 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -11,8 +11,8 @@ This guide provides instructions on how to to delete data from a multi-index tab See the following code reference: * The [`multi-index`](../../classeosio_1_1multi__index) class. -* The [`find(...)`](../../group__multiindex#function-find) function. -* The [`erase(...)`](../../group__multiindex/#function-erase) method. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. +* The [`multi-index::erase(...)`](../../group__multiindex/#function-erase) method. ## Before you begin diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index 66444450c7..c636cd1f64 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -11,8 +11,8 @@ This guide provides instructions on how to insert data into a multi-index table. See the following code reference: * The [`multi-index`](../../classeosio_1_1multi__index) class. -* The [`find(...)`](../../group__multiindex#function-find) function. -* The [`emplace`](../../group__multiindex/#function-emplace) method. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. +* The [`multi-index::emplace(...)`](../../group__multiindex/#function-emplace) method. ## Before you begin diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index 48150cd69c..495107b4ac 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -1,69 +1,48 @@ --- -content_title: How to iterate and retrieve a multi-index table based on secondary index +content_title: How to iterate and retrieve from multi-index table based on secondary index --- -## Preconditions -- It is assumed you already have a multi-index table defined with a primary index and a secondary index, if not you can find an example [here](./how-to-define-a-secondary-index.md). +## Overview -You'll start with this example below which shows the definition of a `multi_index_example` contract class which has defined a multi-index table with two indexes, a mandatory primary one and a secondary one: +This guide provides instructions on how iterate and retrieve data from a multi-index table based on a secondary index defined in the multi-index table. -```cpp -#include -using namespace eosio; +## Reference -// multi-index example contract class -class [[eosio::contract]] multi_index_example : public contract { - public: - using contract::contract; +See the following code reference: - // contract class constructor - multi_index_example( name receiver, name code, datastream ds ) : - // contract base class contructor - contract(receiver, code, ds), - // instantiate multi-index instance as data member (find it defined below) - testtab(receiver, receiver.value) - { } +* The [`multi-index`](../../classeosio_1_1multi__index) class. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. - // the row structure of the multi-index table, that is, each row of the table - // will contain an instance of this type of structure - struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table - name test_primary; - name secondary; - // additional data stored in table row - uint64_t datum; - // mandatory definition for primary key getter - uint64_t primary_key( ) const { return test_primary.value; } - uint64_t by_secondary( ) const { return secondary.value; } - }; +## Before you begin - // the multi-index type definition, for ease of use define a type alias `test_table_t`, - // based on the multi_index template type, parametarized with a random name, the - // test_table data structure, and the secondary index - typedef eosio::multi_index<"testtaba"_n, test_table, eosio::indexed_by<"secid"_n, eosio::const_mem_fun>> test_table_t; +Make sure you have the following prerequisites in place: - // the multi-index table instance declared as a data member of type test_table_t - test_table_t testtab; +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), +* A multi-index `testab` table instance which stores `user` objects indexed by the primary key which is of type `eosio::name` and a secondary index for property `secondary` of type `eosio::name` accessible through `by_secondary()` method. Consult the section [How to define a secondary index](./how-to-define-a-secondary-index) to learn how to set it up. - [[eosio::action]] void set( name user ); - [[eosio::action]] void print( name user ); +## Procedure - using set_action = action_wrapper<"set"_n, &multi_index_example::set>; - using print_action = action_wrapper<"print"_n, &multi_index_example::print>; -}; -``` +Complete the following steps to iterate, retrieve and print data from the `testtab` multi-index table using the secondary index. -To iterate and retreive the multi-index table `testtab` defined in `multi_index_example` contract based on secondary index `by_secondary`, define a third action `bysec` which will do exactly that. +### 1. Define The `bysec(...)` Action -1. In the contract definition, add the new action definition, using the `[[eosio::action]] void` and the `eosio::action_wrapper` template like this: +Add to the definition of the multi-index table the `bysec` action which gets as parameter an account name. This will be the action which will retrieve the user object stored in the multi-index based on the name input parameter using the secondary index. ```cpp [[eosio::action]] void bysec( name secid ); +``` - using bysec_action = action_wrapper<"bysec"_n, &multi_index_example::bysec>; +For ease of use add the action wrapper definition as well + +```diff + [[eosio::action]] void bysec( name secid ); + + +using bysec_action = action_wrapper<"bysec"_n, &multi_index_example::bysec>; ``` -2. In the contract implementation add the new action implementation like this: +### 2. Implement The `bysec(...)` Action + +Search the `user` name in the multi-index table using the secondary index. If found, print out the value of field `datum`. Otherwise assert with a custom message. In the contract definition add the following implementation for `print` action: ```cpp // iterates the multi-index table rows using the secondary index and prints the row's values @@ -78,9 +57,12 @@ To iterate and retreive the multi-index table `testtab` defined in `multi_index_ } ``` -3. The full code for both the contract definition and contract implementation follow: +### 3. Put It All Together + +The full definition and implementation files for the contract should look like this: __multi_index_example.hpp__ + ```cpp #include using namespace eosio; @@ -130,6 +112,7 @@ class [[eosio::contract]] multi_index_example : public contract { ``` __multi_index_example.cpp__ + ```cpp #include @@ -172,4 +155,15 @@ __multi_index_example.cpp__ ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to iterate and retrieve a multi-index table based on secondary index. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [insert data](./how-to-insert-data-into-a-multi-index-table) into the multi-index table. +* You can [delete data](./how-to-delete-data-from-a-multi-index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index c67122d53d..959d5edbc9 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -1,70 +1,49 @@ --- -content_title: How to iterate and retrieve a multi-index table +content_title: How to iterate and retrieve from multi-index table --- -## Preconditions +## Overview -- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). +This guide provides instructions on how to iterate and retrieve data from a multi-index table. -For exemplification define the multi-index contract definition like below: +## Reference -__multi_index_example.hpp__ -```cpp -#include -using namespace eosio; +See the following code reference: -// multi-index example contract class -class [[eosio::contract]] multi_index_example : public contract { - public: - using contract::contract; +* The [`multi-index`](../../classeosio_1_1multi__index) class. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. - // contract class constructor - multi_index_example( name receiver, name code, datastream ds ) : - // contract base class contructor - contract(receiver, code, ds), - // instantiate multi-index instance as data member (find it defined below) - testtab(receiver, receiver.value) - { } - - // the row structure of the multi-index table, that is, each row of the table - // will contain an instance of this type of structure - struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table - name test_primary; - // additional data stored in table row - uint64_t datum; - // mandatory definition for primary key getter - uint64_t primary_key( ) const { return test_primary.value; } - }; +## Before you begin - // the multi-index type definition, for ease of use define a type alias `test_table_t`, - // based on the multi_index template type, parametarized with a random name and - // the test_table data structure - typedef eosio::multi_index<"testtaba"_n, test_table> test_table_t; +Make sure you have the following prerequisites in place: - // the multi-index table instance declared as a data member of type test_table_t - test_table_t testtab; +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), +* A multi-index `testab` table instance which stores `user` objects indexed by the primary key which is of type `eosio::name`. Consult the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table) to learn how to set it up. - [[eosio::action]] void set( name user ); +## Procedure - using set_action = action_wrapper<"set"_n, &multi_index_example::set>; -}; -``` +Complete the following steps to iterate, retrieve and print data from the `testtab` multi-index table. -The steps below show how to iterate and retrieve a multi-index table. +### 1. Define The `print(...)` Action -1. Add to the above multi-index example contract an action `print` which gets as parameter an acount name +Add to the definition of the `testtab` multi-index table the `print` action which gets as parameter an account name: ```cpp [[eosio::action]] void print( name user ); ``` -2. For ease of use add the action wrapper defition as well + +For ease of use add the action wrapper definition as well + ```diff [[eosio::action]] void print( name user ); +using print_action = action_wrapper<"print"_n, &multi_index_example::print>; ``` -3. Implement the action code, by searching for the `user` name in the multi-index table using the primary index. If found, print out the value stored in that row for field `datum`. Otherwise asserts with a custom message. In the contract definition add the following implementation for `print` action: + +### 2. Implement The `print(...)` Action + +Search the `user` name in the multi-index table using the primary index. If found, print out the value of field `datum`. Otherwise assert with a custom message. In the contract definition add the following implementation for `print` action: + ```cpp [[eosio::action]] void multi_index_example::print( name user ) { // searches for the row that corresponds to the user parameter @@ -77,9 +56,13 @@ The steps below show how to iterate and retrieve a multi-index table. eosio::print_f("Test Table : {%, %}\n", itr->test_primary, itr->datum); } ``` -4. Finally the whole definition and implementation files for the contract should look like this: + +### 3. Put It All Together + +The full definition and implementation files for the contract should look like this: __multi_index_example.hpp__ + ```cpp #include using namespace eosio; @@ -125,6 +108,7 @@ class [[eosio::contract]] multi_index_example : public contract { ``` __multi_index_example.cpp__ + ```cpp #include @@ -155,4 +139,15 @@ __multi_index_example.cpp__ ``` [[info | Full example location]] -| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). \ No newline at end of file +| A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to iterate and retrieve a multi-index table. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [insert data](./how-to-insert-data-into-a-multi-index-table) into the multi-index table. +* You can [delete data](./how-to-delete-data-from-a-multi-index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index 0d9b13cf74..06f720d422 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -2,19 +2,58 @@ content_title: How to modify data in a multi-index table --- -## Preconditions -- It is assumed you already have a multi-index table instance defined along with its mandatory primary index, otherwise take a look at the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table.md). +## Overview -To modify data in the multi-index table defined in the above tutorial, you will implement an action `mod` which it will receive as parameter the `user` which is the key of the row you want to modify and the `value` param which is the value to update with the row. +This guide provides instructions on how to modify data in a multi-index table. + +## Reference + +See the following code reference: + +* The [`multi-index`](../../classeosio_1_1multi__index) class. +* The [`multi-index::modify(...)`](../../group__multiindex/#function-modify) function. + +## Before you begin + +Make sure you have the following prerequisites in place: + +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), +* A multi-index `testab` table instance which stores `user` objects indexed by the primary key which is of type `eosio::name`. Consult the section [How to instantiate a multi-index table](./how-to-instantiate-a-multi-index-table) to learn how to set it up. + +## Procedure + +Complete the following steps to modify data in the `testtab` multi-index table. + +### 1. Define The `mod(...)` Action + +Add to the definition of the `testtab` multi-index table the `mod` action which gets as input parameters a `user` of type `eosio::name` and a `value` of type `uint32_t`. The `mod` action will update the `user` object `datum` property with the `uint32_t` value. + +```cpp +[[eosio::action]] void mod( name user, uint32_t value ); +``` + +For ease of use add the action wrapper definition as well + +```diff +[[eosio::action]] void mod( name user, uint32_t value ); + ++using mod_action = action_wrapper<"mod"_n, &multi_index_example::mod>; +``` + +### 2. Find The User You Want To Modify + +Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to modify based on its account name. -1. Make use of the multi-index table iterator to find out if the data exists ```cpp [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { auto itr = testtab.find(user.value); } ``` -2. If the row you want to update is not found, then assert by using the `check` method and yield an error message +### 3. Yield Error Is User Not Found + +If the `user` object you want to update is not found, then assert by using the `check` method and yield an error message. + ```diff [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { auto itr = testtab.find(user.value); @@ -22,7 +61,9 @@ To modify data in the multi-index table defined in the above tutorial, you will } ``` -3. If the row you want to update is found, the `check` method will do nothing and the iterator `itr` will be pointing at the row which you want to update, so then use the multi-index `modify` method to make the update like below +### 4. Update The User If Found + +If the `user` object you want to update is found, the `check` method will do nothing and the iterator `itr` will be pointing at the object which you want to update, so then use the multi-index `modify` method to make the update like below ```diff [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -31,7 +72,6 @@ To modify data in the multi-index table defined in the above tutorial, you will check( itr != testtab.end(), "user does not exist in table" ); + testtab.modify( itr, _self, [&]( auto& row ) { -+ row.secondary = user; + row.datum = value; + }); } @@ -39,3 +79,14 @@ To modify data in the multi-index table defined in the above tutorial, you will [[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). + +## Summary + +In conclusion, the above instructions show how to modify data in a multi-index table. + +## Next Steps + +The following option is available when you complete the procedure: + +* You can [insert data](./how-to-insert-data-into-a-multi-index-table) into the multi-index table. +* You can [delete data](./how-to-delete-data-from-a-multi-index-table) from the multi-index table. From c688de4ba45e91bf640c814c259a5253211865c8 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 1 Jun 2021 14:20:43 +0300 Subject: [PATCH 123/204] touchups. --- .../how-to-delete-data-from-a-multi-index-table.md | 2 +- .../how-to-insert-data-into-a-multi-index-table.md | 2 +- ...eve-a-multi_index-table-based-on-secondary-index.md | 2 +- .../how-to-iterate-and-retrieve-a-multi_index-table.md | 2 +- .../how-to-modify-data-in-a-multi-index-table.md | 10 ++++++---- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index 445d263370..f111e1f7ca 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -27,7 +27,7 @@ Complete the following steps to implement a `del` action which deletes an user o ### 1. Find The User You Want To Delete -Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to delete based on its account name: +Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to delete. The targeted user is searched based on its account name. ```cpp [[eosio::action]] void multi_index_example::del( name user ) { diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index c636cd1f64..253f347d5c 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -27,7 +27,7 @@ Complete the following steps to insert an user object in the `testtab` multi-ind ### 1. Verify If The User Already Exists -Make use of the multi-index table iterator to find out if the user object already exists. +Make use of the multi-index table iterator to find out if the user object already exists. The targeted user is searched based on its account name. ```cpp [[eosio::action]] void multi_index_example::set( name user ) { diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index 495107b4ac..5ed7c6cce7 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -32,7 +32,7 @@ Add to the definition of the multi-index table the `bysec` action which gets as [[eosio::action]] void bysec( name secid ); ``` -For ease of use add the action wrapper definition as well +Optionally, for ease of use add the action wrapper definition as well. ```diff [[eosio::action]] void bysec( name secid ); diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 959d5edbc9..314ce0b90c 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -32,7 +32,7 @@ Add to the definition of the `testtab` multi-index table the `print` action whic [[eosio::action]] void print( name user ); ``` -For ease of use add the action wrapper definition as well +Optionally, for ease of use add the action wrapper definition as well. ```diff [[eosio::action]] void print( name user ); diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index 06f720d422..cd98c182aa 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -32,7 +32,7 @@ Add to the definition of the `testtab` multi-index table the `mod` action which [[eosio::action]] void mod( name user, uint32_t value ); ``` -For ease of use add the action wrapper definition as well +Optionally, for ease of use add the action wrapper definition as well. ```diff [[eosio::action]] void mod( name user, uint32_t value ); @@ -42,7 +42,7 @@ For ease of use add the action wrapper definition as well ### 2. Find The User You Want To Modify -Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to modify based on its account name. +Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to modify. The targeted user is searched based on its account name. ```cpp [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -50,7 +50,7 @@ Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) } ``` -### 3. Yield Error Is User Not Found +### 3. Yield Error If User Not Found If the `user` object you want to update is not found, then assert by using the `check` method and yield an error message. @@ -63,7 +63,7 @@ If the `user` object you want to update is not found, then assert by using the ` ### 4. Update The User If Found -If the `user` object you want to update is found, the `check` method will do nothing and the iterator `itr` will be pointing at the object which you want to update, so then use the multi-index `modify` method to make the update like below +If the `user` object you want to update is found, the `check` method will do nothing and the iterator `itr` will be pointing at the object which you want to update. Use the `modify` method to update the user object `datum` property with the `value` parameter. ```diff [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -77,6 +77,8 @@ If the `user` object you want to update is found, the `check` method will do not } ``` +Now you have implemented a new action `mod`, which when sent to the blockchain will update the `datum` propety for user object identified by `user` name with the `value` sent as parameter. + [[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). From 654adf055d0e56d39eb6218d3fb0c3bd22b5395c Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 1 Jun 2021 14:37:39 +0300 Subject: [PATCH 124/204] final touchups --- .../40_multi-index/how-to-define-a-singleton.md | 2 +- .../how-to-delete-data-from-a-multi-index-table.md | 2 +- .../how-to-insert-data-into-a-multi-index-table.md | 2 +- ...eve-a-multi_index-table-based-on-secondary-index.md | 6 +++--- .../how-to-iterate-and-retrieve-a-multi_index-table.md | 8 ++++---- .../how-to-modify-data-in-a-multi-index-table.md | 10 +++++----- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index 5b9d554544..604bae6ad6 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -32,7 +32,7 @@ Include the `eosio.hpp` and `singleton.hpp` headers and declare the `eosio` name using namespace eosio; ``` -### 2. Defines The Table Data Structure +### 2. Define The Table Data Structure Define the data structure for the multi-index table the singleton will use: diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index f111e1f7ca..b4a0264db0 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -11,7 +11,7 @@ This guide provides instructions on how to to delete data from a multi-index tab See the following code reference: * The [`multi-index`](../../classeosio_1_1multi__index) class. -* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) method. * The [`multi-index::erase(...)`](../../group__multiindex/#function-erase) method. ## Before you begin diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index 253f347d5c..e1b7c8e042 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -11,7 +11,7 @@ This guide provides instructions on how to insert data into a multi-index table. See the following code reference: * The [`multi-index`](../../classeosio_1_1multi__index) class. -* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) method. * The [`multi-index::emplace(...)`](../../group__multiindex/#function-emplace) method. ## Before you begin diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index 5ed7c6cce7..60984aa0be 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -11,7 +11,7 @@ This guide provides instructions on how iterate and retrieve data from a multi-i See the following code reference: * The [`multi-index`](../../classeosio_1_1multi__index) class. -* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) method. ## Before you begin @@ -24,7 +24,7 @@ Make sure you have the following prerequisites in place: Complete the following steps to iterate, retrieve and print data from the `testtab` multi-index table using the secondary index. -### 1. Define The `bysec(...)` Action +### 1. Define The bysec(...) Action Add to the definition of the multi-index table the `bysec` action which gets as parameter an account name. This will be the action which will retrieve the user object stored in the multi-index based on the name input parameter using the secondary index. @@ -42,7 +42,7 @@ Optionally, for ease of use add the action wrapper definition as well. ### 2. Implement The `bysec(...)` Action -Search the `user` name in the multi-index table using the secondary index. If found, print out the value of field `datum`. Otherwise assert with a custom message. In the contract definition add the following implementation for `print` action: +Search the `user` name in the multi-index table using the secondary index. If found, print out the value of field `datum`. Otherwise raise and error with a custom message. In the contract definition add the following implementation for `print` action: ```cpp // iterates the multi-index table rows using the secondary index and prints the row's values diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 314ce0b90c..b5c16c069d 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -11,7 +11,7 @@ This guide provides instructions on how to iterate and retrieve data from a mult See the following code reference: * The [`multi-index`](../../classeosio_1_1multi__index) class. -* The [`multi-index::find(...)`](../../group__multiindex#function-find) function. +* The [`multi-index::find(...)`](../../group__multiindex#function-find) method. ## Before you begin @@ -24,9 +24,9 @@ Make sure you have the following prerequisites in place: Complete the following steps to iterate, retrieve and print data from the `testtab` multi-index table. -### 1. Define The `print(...)` Action +### 1. Define The print(...) Action -Add to the definition of the `testtab` multi-index table the `print` action which gets as parameter an account name: +Add to the definition of the `testtab` multi-index table the `print` action which gets as parameter an account name. ```cpp [[eosio::action]] void print( name user ); @@ -42,7 +42,7 @@ Optionally, for ease of use add the action wrapper definition as well. ### 2. Implement The `print(...)` Action -Search the `user` name in the multi-index table using the primary index. If found, print out the value of field `datum`. Otherwise assert with a custom message. In the contract definition add the following implementation for `print` action: +Search the `user` name in the multi-index table using the primary index. If found, print out the value of field `datum`. Otherwise raise an error with a custom message. In the contract definition add the following implementation for `print` action: ```cpp [[eosio::action]] void multi_index_example::print( name user ) { diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index cd98c182aa..f7d644f021 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -11,7 +11,7 @@ This guide provides instructions on how to modify data in a multi-index table. See the following code reference: * The [`multi-index`](../../classeosio_1_1multi__index) class. -* The [`multi-index::modify(...)`](../../group__multiindex/#function-modify) function. +* The [`multi-index::modify(...)`](../../group__multiindex/#function-modify) method. ## Before you begin @@ -24,7 +24,7 @@ Make sure you have the following prerequisites in place: Complete the following steps to modify data in the `testtab` multi-index table. -### 1. Define The `mod(...)` Action +### 1. Define The mod(...) Action Add to the definition of the `testtab` multi-index table the `mod` action which gets as input parameters a `user` of type `eosio::name` and a `value` of type `uint32_t`. The `mod` action will update the `user` object `datum` property with the `uint32_t` value. @@ -52,7 +52,7 @@ Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) ### 3. Yield Error If User Not Found -If the `user` object you want to update is not found, then assert by using the `check` method and yield an error message. +If the `user` object you want to update is not found then raise an error message by using the [`eosio::check`](../../namespaceeosio/#function-check-17) method. ```diff [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -63,7 +63,7 @@ If the `user` object you want to update is not found, then assert by using the ` ### 4. Update The User If Found -If the `user` object you want to update is found, the `check` method will do nothing and the iterator `itr` will be pointing at the object which you want to update. Use the `modify` method to update the user object `datum` property with the `value` parameter. +If the `user` object you want to update is found, the [`eosio::check`](../../namespaceeosio/#function-check-17) method will do nothing and the iterator `itr` will be pointing at the object which you want to update. Use the [`multi-index::modify(...)`](../../group__multiindex/#function-modify) method to update the user object `datum` property with the `value` parameter. ```diff [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -77,7 +77,7 @@ If the `user` object you want to update is found, the `check` method will do not } ``` -Now you have implemented a new action `mod`, which when sent to the blockchain will update the `datum` propety for user object identified by `user` name with the `value` sent as parameter. +Now you have implemented a new action `mod`, which when sent to the blockchain will update the `datum` property for user object identified by `user` name with the `value` sent as parameter. [[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). From ad16f4f9c914cad964bc6cc7dcfb4062e4844457 Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Tue, 1 Jun 2021 15:13:49 -0400 Subject: [PATCH 125/204] fix broken links on docs root folder files --- docs/{02_installation.md => 02_installation/index.md} | 0 docs/{08_troubleshooting.md => 08_troubleshooting/index.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename docs/{02_installation.md => 02_installation/index.md} (100%) rename docs/{08_troubleshooting.md => 08_troubleshooting/index.md} (100%) diff --git a/docs/02_installation.md b/docs/02_installation/index.md similarity index 100% rename from docs/02_installation.md rename to docs/02_installation/index.md diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting/index.md similarity index 100% rename from docs/08_troubleshooting.md rename to docs/08_troubleshooting/index.md From 8ba0c80fdd5cc6f0b5f270ac812f4f47e8f4db79 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 2 Jun 2021 16:23:55 -0400 Subject: [PATCH 126/204] Create sanitize.sh from eos:a7b5566/.cicd/helpers/general.sh --- .cicd/helpers/sanitize.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 .cicd/helpers/sanitize.sh diff --git a/.cicd/helpers/sanitize.sh b/.cicd/helpers/sanitize.sh new file mode 100755 index 0000000000..43e0858efe --- /dev/null +++ b/.cicd/helpers/sanitize.sh @@ -0,0 +1,13 @@ +#!/bin/bash + + ##### sanitize branch names for use in URIs (docker containers) ##### +# tr '/' '_' # convert forward-slashes '/' to underscores '_' +# sed -E 's/[^-_.a-zA-Z0-9]+/-/g' # convert invalid docker chars to '-' +# sed -E 's/-+/-/g' # replace multiple dashes in a series "----" with a single dash '-' +# sed -E 's/-*_+-*/_/g' # replace dashes '-' and underscores '_' in-series with a single underscore '_' +# sed -E 's/_+/_/g' # replace multiple underscores in a row "___" with a single underscore '_' +# sed -E 's/(^[-_.]+|[-_.]+$)//g' # ensure tags do not begin or end with separator characters [-_.] +function sanitize() +{ + echo "$1" | tr '/' '_' | sed -E 's/[^-_.a-zA-Z0-9]+/-/g' | sed -E 's/-+/-/g' | sed -E 's/-*_+-*/_/g' | sed -E 's/_+/_/g' | sed -E 's/(^[-_.]+|[-_.]+$)//g' +} From 077bac770341e4b0d71be3f477dfaddf9c74ec40 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 2 Jun 2021 16:32:48 -0400 Subject: [PATCH 127/204] Copy-pasta from eos:a7b5566/.cicd/create-docker-from-binary.sh --- .cicd/create-docker-from-binary.sh | 97 +++++++++++++++++------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index 98fa89dabb..ed527255dd 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -1,53 +1,66 @@ #!/bin/bash echo '--- :evergreen_tree: Configuring Environment' set -euo pipefail - +. ./.cicd/helpers/sanitize.sh buildkite-agent artifact download '*.deb' --step ':ubuntu: Ubuntu 18.04 - Package Builder' . -echo ":done: download successful" - -SANITIZED_BRANCH=$(echo "$BUILDKITE_BRANCH" | sed 's.^/..' | sed 's/[:/]/_/g') -SANITIZED_TAG=$(echo "$BUILDKITE_TAG" | sed 's.^/..' | tr '/' '_') -echo "$SANITIZED_BRANCH" -echo "$SANITIZED_TAG" - -# do docker build -echo '+++ :docker: Building Container' -echo ":docker::build: Building image..." +SANITIZED_BRANCH="$(sanitize "$BUILDKITE_BRANCH")" +echo "Branch '$BUILDKITE_BRANCH' sanitized as '$SANITIZED_BRANCH'." +SANITIZED_TAG="$(sanitize "$BUILDKITE_TAG")" +[[ -z "$SANITIZED_TAG" ]] || echo "Branch '$BUILDKITE_TAG' sanitized as '$SANITIZED_TAG'." +# docker build +echo '+++ :docker: Build Docker Container' DOCKERHUB_REGISTRY="docker.io/eosio/eosio.cdt" - -BUILD_TAG=${BUILDKITE_BUILD_NUMBER:-latest} -DOCKER_BUILD_GEN="docker build -t eosio_cdt_image:$BUILD_TAG -f ./docker/dockerfile ." -echo "$ $DOCKER_BUILD_GEN" -eval $DOCKER_BUILD_GEN - -#tag and push on each destination AWS & DOCKERHUB -echo '+++ :arrow_up: Pushing Container' +IMAGE="${DOCKERHUB_REGISTRY}:${BUILDKITE_COMMIT:-latest}" +DOCKER_BUILD="docker build -t '$IMAGE' -f ./docker/dockerfile ." +echo "$ $DOCKER_BUILD" +eval $DOCKER_BUILD +# docker tag +echo '--- :label: Tag Container' EOSIO_REGS=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") -for REG in ${EOSIO_REGS[@]}; do - DOCKER_TAG_COMMIT="docker tag eosio_cdt_image:$BUILD_TAG $REG:$BUILDKITE_COMMIT" - DOCKER_TAG_BRANCH="docker tag eosio_cdt_image:$BUILD_TAG $REG:$SANITIZED_BRANCH" - echo -e "$ Tagging Images: \n$DOCKER_TAG_COMMIT \n$DOCKER_TAG_BRANCH" - eval $DOCKER_TAG_COMMIT +for REG in ${REGISTRIES[@]}; do + DOCKER_TAG_BRANCH="docker tag '$IMAGE' '$REG:$SANITIZED_BRANCH'" + echo "$ $DOCKER_TAG_BRANCH" eval $DOCKER_TAG_BRANCH - DOCKER_PUSH_COMMIT="docker push $REG:$BUILDKITE_COMMIT" - DOCKER_PUSH_BRANCH="docker push $REG:$SANITIZED_BRANCH" - echo -e "$ Pushing Images: \n$DOCKER_PUSH_COMMIT \n$DOCKER_PUSH_BRANCH" - eval $DOCKER_PUSH_COMMIT + DOCKER_TAG_COMMIT="docker tag '$IMAGE' '$REG:$BUILDKITE_COMMIT'" + echo "$ $DOCKER_TAG_COMMIT" + eval $DOCKER_TAG_COMMIT + if [[ ! -z "$SANITIZED_TAG" && "$SANITIZED_BRANCH" != "$SANITIZED_TAG" ]]; then + DOCKER_TAG="docker tag '$IMAGE' '$REG:$SANITIZED_TAG'" + echo "$ $DOCKER_TAG" + eval $DOCKER_TAG + fi +done +# docker push +echo '--- :arrow_up: Push Container' +for REG in ${REGISTRIES[@]}; do + DOCKER_PUSH_BRANCH="docker push '$REG:$SANITIZED_BRANCH'" + echo "$ $DOCKER_PUSH_BRANCH" eval $DOCKER_PUSH_BRANCH - CLEAN_IMAGE_COMMIT="docker rmi $REG:$BUILDKITE_COMMIT" - CLEAN_IMAGE_BRANCH="docker rmi $REG:$SANITIZED_BRANCH" - echo -e "Cleaning Up: \n$CLEAN_IMAGE_COMMIT \n$CLEAN_IMAGE_BRANCH$" - eval $CLEAN_IMAGE_COMMIT + DOCKER_PUSH_COMMIT="docker push '$REG:$BUILDKITE_COMMIT'" + echo "$ $DOCKER_PUSH_COMMIT" + eval $DOCKER_PUSH_COMMIT + if [[ ! -z "$SANITIZED_TAG" && "$SANITIZED_BRANCH" != "$SANITIZED_TAG" ]]; then + DOCKER_PUSH_TAG="docker push '$REG:$SANITIZED_TAG'" + echo "$ $DOCKER_PUSH_TAG" + eval $DOCKER_PUSH_TAG + fi +done +# docker rmi +echo '--- :put_litter_in_its_place: Cleanup' +for REG in ${REGISTRIES[@]}; do + CLEAN_IMAGE_BRANCH="docker rmi '$REG:$SANITIZED_BRANCH' || :" + echo "$ $CLEAN_IMAGE_BRANCH" eval $CLEAN_IMAGE_BRANCH - if [[ ! -z "$SANITIZED_TAG" ]]; then - DOCKER_TAG="docker tag eosio_cdt_image $REG:$SANITIZED_TAG" - DOCKER_REM="docker rmi $REG:$SANITIZED_TAG" - echo -e "$ \n Tagging Image: \n$DOCKER_TAG \n Cleaning Up: \n$DOCKER_REM" - eval $DOCKER_TAG - eval $DOCKER_REM + CLEAN_IMAGE_COMMIT="docker rmi '$REG:$BUILDKITE_COMMIT' || :" + echo "$ $CLEAN_IMAGE_COMMIT" + eval $CLEAN_IMAGE_COMMIT + if [[ ! -z "$SANITIZED_TAG" && "$SANITIZED_BRANCH" != "$SANITIZED_TAG" ]]; then + DOCKER_RMI="docker rmi '$REG:$SANITIZED_TAG' || :" + echo "$ $DOCKER_RMI" + eval $DOCKER_RMI fi done - -DOCKER_GEN="docker rmi eosio_cdt_image:$BUILD_TAG" -echo "Clean up base image" -eval $DOCKER_GEN +DOCKER_RMI="docker rmi '$IMAGE' || :" +echo "$ $DOCKER_RMI" +eval $DOCKER_RMI +echo 'Done.' From 03d4bb3fe2f0e53bf24cd2ce9f299d50b4d845c2 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 2 Jun 2021 16:23:55 -0400 Subject: [PATCH 128/204] Create sanitize.sh from eos:a7b5566/.cicd/helpers/general.sh --- .cicd/helpers/sanitize.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 .cicd/helpers/sanitize.sh diff --git a/.cicd/helpers/sanitize.sh b/.cicd/helpers/sanitize.sh new file mode 100755 index 0000000000..43e0858efe --- /dev/null +++ b/.cicd/helpers/sanitize.sh @@ -0,0 +1,13 @@ +#!/bin/bash + + ##### sanitize branch names for use in URIs (docker containers) ##### +# tr '/' '_' # convert forward-slashes '/' to underscores '_' +# sed -E 's/[^-_.a-zA-Z0-9]+/-/g' # convert invalid docker chars to '-' +# sed -E 's/-+/-/g' # replace multiple dashes in a series "----" with a single dash '-' +# sed -E 's/-*_+-*/_/g' # replace dashes '-' and underscores '_' in-series with a single underscore '_' +# sed -E 's/_+/_/g' # replace multiple underscores in a row "___" with a single underscore '_' +# sed -E 's/(^[-_.]+|[-_.]+$)//g' # ensure tags do not begin or end with separator characters [-_.] +function sanitize() +{ + echo "$1" | tr '/' '_' | sed -E 's/[^-_.a-zA-Z0-9]+/-/g' | sed -E 's/-+/-/g' | sed -E 's/-*_+-*/_/g' | sed -E 's/_+/_/g' | sed -E 's/(^[-_.]+|[-_.]+$)//g' +} From 69df5a80ceb8f6dd8a62008f7b37101b8e84fa5b Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 2 Jun 2021 16:32:48 -0400 Subject: [PATCH 129/204] Copy-pasta from eos:a7b5566/.cicd/create-docker-from-binary.sh --- .cicd/create-docker-from-binary.sh | 97 +++++++++++++++++------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index 98fa89dabb..ed527255dd 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -1,53 +1,66 @@ #!/bin/bash echo '--- :evergreen_tree: Configuring Environment' set -euo pipefail - +. ./.cicd/helpers/sanitize.sh buildkite-agent artifact download '*.deb' --step ':ubuntu: Ubuntu 18.04 - Package Builder' . -echo ":done: download successful" - -SANITIZED_BRANCH=$(echo "$BUILDKITE_BRANCH" | sed 's.^/..' | sed 's/[:/]/_/g') -SANITIZED_TAG=$(echo "$BUILDKITE_TAG" | sed 's.^/..' | tr '/' '_') -echo "$SANITIZED_BRANCH" -echo "$SANITIZED_TAG" - -# do docker build -echo '+++ :docker: Building Container' -echo ":docker::build: Building image..." +SANITIZED_BRANCH="$(sanitize "$BUILDKITE_BRANCH")" +echo "Branch '$BUILDKITE_BRANCH' sanitized as '$SANITIZED_BRANCH'." +SANITIZED_TAG="$(sanitize "$BUILDKITE_TAG")" +[[ -z "$SANITIZED_TAG" ]] || echo "Branch '$BUILDKITE_TAG' sanitized as '$SANITIZED_TAG'." +# docker build +echo '+++ :docker: Build Docker Container' DOCKERHUB_REGISTRY="docker.io/eosio/eosio.cdt" - -BUILD_TAG=${BUILDKITE_BUILD_NUMBER:-latest} -DOCKER_BUILD_GEN="docker build -t eosio_cdt_image:$BUILD_TAG -f ./docker/dockerfile ." -echo "$ $DOCKER_BUILD_GEN" -eval $DOCKER_BUILD_GEN - -#tag and push on each destination AWS & DOCKERHUB -echo '+++ :arrow_up: Pushing Container' +IMAGE="${DOCKERHUB_REGISTRY}:${BUILDKITE_COMMIT:-latest}" +DOCKER_BUILD="docker build -t '$IMAGE' -f ./docker/dockerfile ." +echo "$ $DOCKER_BUILD" +eval $DOCKER_BUILD +# docker tag +echo '--- :label: Tag Container' EOSIO_REGS=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") -for REG in ${EOSIO_REGS[@]}; do - DOCKER_TAG_COMMIT="docker tag eosio_cdt_image:$BUILD_TAG $REG:$BUILDKITE_COMMIT" - DOCKER_TAG_BRANCH="docker tag eosio_cdt_image:$BUILD_TAG $REG:$SANITIZED_BRANCH" - echo -e "$ Tagging Images: \n$DOCKER_TAG_COMMIT \n$DOCKER_TAG_BRANCH" - eval $DOCKER_TAG_COMMIT +for REG in ${REGISTRIES[@]}; do + DOCKER_TAG_BRANCH="docker tag '$IMAGE' '$REG:$SANITIZED_BRANCH'" + echo "$ $DOCKER_TAG_BRANCH" eval $DOCKER_TAG_BRANCH - DOCKER_PUSH_COMMIT="docker push $REG:$BUILDKITE_COMMIT" - DOCKER_PUSH_BRANCH="docker push $REG:$SANITIZED_BRANCH" - echo -e "$ Pushing Images: \n$DOCKER_PUSH_COMMIT \n$DOCKER_PUSH_BRANCH" - eval $DOCKER_PUSH_COMMIT + DOCKER_TAG_COMMIT="docker tag '$IMAGE' '$REG:$BUILDKITE_COMMIT'" + echo "$ $DOCKER_TAG_COMMIT" + eval $DOCKER_TAG_COMMIT + if [[ ! -z "$SANITIZED_TAG" && "$SANITIZED_BRANCH" != "$SANITIZED_TAG" ]]; then + DOCKER_TAG="docker tag '$IMAGE' '$REG:$SANITIZED_TAG'" + echo "$ $DOCKER_TAG" + eval $DOCKER_TAG + fi +done +# docker push +echo '--- :arrow_up: Push Container' +for REG in ${REGISTRIES[@]}; do + DOCKER_PUSH_BRANCH="docker push '$REG:$SANITIZED_BRANCH'" + echo "$ $DOCKER_PUSH_BRANCH" eval $DOCKER_PUSH_BRANCH - CLEAN_IMAGE_COMMIT="docker rmi $REG:$BUILDKITE_COMMIT" - CLEAN_IMAGE_BRANCH="docker rmi $REG:$SANITIZED_BRANCH" - echo -e "Cleaning Up: \n$CLEAN_IMAGE_COMMIT \n$CLEAN_IMAGE_BRANCH$" - eval $CLEAN_IMAGE_COMMIT + DOCKER_PUSH_COMMIT="docker push '$REG:$BUILDKITE_COMMIT'" + echo "$ $DOCKER_PUSH_COMMIT" + eval $DOCKER_PUSH_COMMIT + if [[ ! -z "$SANITIZED_TAG" && "$SANITIZED_BRANCH" != "$SANITIZED_TAG" ]]; then + DOCKER_PUSH_TAG="docker push '$REG:$SANITIZED_TAG'" + echo "$ $DOCKER_PUSH_TAG" + eval $DOCKER_PUSH_TAG + fi +done +# docker rmi +echo '--- :put_litter_in_its_place: Cleanup' +for REG in ${REGISTRIES[@]}; do + CLEAN_IMAGE_BRANCH="docker rmi '$REG:$SANITIZED_BRANCH' || :" + echo "$ $CLEAN_IMAGE_BRANCH" eval $CLEAN_IMAGE_BRANCH - if [[ ! -z "$SANITIZED_TAG" ]]; then - DOCKER_TAG="docker tag eosio_cdt_image $REG:$SANITIZED_TAG" - DOCKER_REM="docker rmi $REG:$SANITIZED_TAG" - echo -e "$ \n Tagging Image: \n$DOCKER_TAG \n Cleaning Up: \n$DOCKER_REM" - eval $DOCKER_TAG - eval $DOCKER_REM + CLEAN_IMAGE_COMMIT="docker rmi '$REG:$BUILDKITE_COMMIT' || :" + echo "$ $CLEAN_IMAGE_COMMIT" + eval $CLEAN_IMAGE_COMMIT + if [[ ! -z "$SANITIZED_TAG" && "$SANITIZED_BRANCH" != "$SANITIZED_TAG" ]]; then + DOCKER_RMI="docker rmi '$REG:$SANITIZED_TAG' || :" + echo "$ $DOCKER_RMI" + eval $DOCKER_RMI fi done - -DOCKER_GEN="docker rmi eosio_cdt_image:$BUILD_TAG" -echo "Clean up base image" -eval $DOCKER_GEN +DOCKER_RMI="docker rmi '$IMAGE' || :" +echo "$ $DOCKER_RMI" +eval $DOCKER_RMI +echo 'Done.' From e09d7b662a16d16454d4659b75b15fd23c0050ff Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 2 Jun 2021 17:26:06 -0400 Subject: [PATCH 130/204] Fix copy-pasta mistake --- .cicd/create-docker-from-binary.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index ed527255dd..eac0ec34b8 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -16,7 +16,7 @@ echo "$ $DOCKER_BUILD" eval $DOCKER_BUILD # docker tag echo '--- :label: Tag Container' -EOSIO_REGS=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") +REGISTRIES=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") for REG in ${REGISTRIES[@]}; do DOCKER_TAG_BRANCH="docker tag '$IMAGE' '$REG:$SANITIZED_BRANCH'" echo "$ $DOCKER_TAG_BRANCH" From 56ee415503f8e375d4c4788fa0ba3753977b9813 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 2 Jun 2021 17:26:06 -0400 Subject: [PATCH 131/204] Fix copy-pasta mistake --- .cicd/create-docker-from-binary.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index ed527255dd..eac0ec34b8 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -16,7 +16,7 @@ echo "$ $DOCKER_BUILD" eval $DOCKER_BUILD # docker tag echo '--- :label: Tag Container' -EOSIO_REGS=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") +REGISTRIES=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") for REG in ${REGISTRIES[@]}; do DOCKER_TAG_BRANCH="docker tag '$IMAGE' '$REG:$SANITIZED_BRANCH'" echo "$ $DOCKER_TAG_BRANCH" From 9a674c531cfb29004fc721caf0764ec953537cb9 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 3 Jun 2021 15:40:50 +0300 Subject: [PATCH 132/204] [docs] dev: update eosio-cpp with -no-missing-ricardian-clause update eosio-cpp with -no-missing-ricardian-clause --- docs/03_command-reference/eosio-cpp.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/03_command-reference/eosio-cpp.md b/docs/03_command-reference/eosio-cpp.md index 27b9053abd..f8c86402ad 100644 --- a/docs/03_command-reference/eosio-cpp.md +++ b/docs/03_command-reference/eosio-cpp.md @@ -71,4 +71,9 @@ compiler options: -sysroot= - Set the system root directory -v - Show commands to run and use verbose output -w - Suppress all warnings + -no-missing-ricardian-clause - Default false, disables warnings for missing Ricardian clauses ``` + +## Notes + +* -no-missing-ricardian-clause: Defaulting to false, if enabled, it suppresses warnings concerning missing Ricardian clauses on contracts and contract actions, including warnings generated when there is also no independent Ricardian clause file. From c4cf7de72daab0d3513b4301c8110d2eaacbbe7d Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 3 Jun 2021 15:45:41 +0300 Subject: [PATCH 133/204] small corrections small corrections --- docs/03_command-reference/eosio-cpp.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/03_command-reference/eosio-cpp.md b/docs/03_command-reference/eosio-cpp.md index f8c86402ad..2437208f33 100644 --- a/docs/03_command-reference/eosio-cpp.md +++ b/docs/03_command-reference/eosio-cpp.md @@ -71,9 +71,9 @@ compiler options: -sysroot= - Set the system root directory -v - Show commands to run and use verbose output -w - Suppress all warnings - -no-missing-ricardian-clause - Default false, disables warnings for missing Ricardian clauses + -no-missing-ricardian-clause - Defaults to false, disables warnings for missing Ricardian clauses ``` ## Notes -* -no-missing-ricardian-clause: Defaulting to false, if enabled, it suppresses warnings concerning missing Ricardian clauses on contracts and contract actions, including warnings generated when there is also no independent Ricardian clause file. +* -no-missing-ricardian-clause: Defaults to false, if enabled, it suppresses warnings for missing Ricardian clauses on contracts and contract actions. That includes the warnings generated when there is also no independent Ricardian clause file. From 3881702801e0ee94b4c5ed2370f2d0507c58109b Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 3 Jun 2021 15:47:01 +0300 Subject: [PATCH 134/204] [docs] 1.8.x - eosio-cpp add new option 1.8.x - eosio-cpp add new option sister PR: https://github.com/EOSIO/eosio.cdt/pull/1118 --- docs/03_command-reference/eosio-cpp.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/03_command-reference/eosio-cpp.md b/docs/03_command-reference/eosio-cpp.md index 27b9053abd..2437208f33 100644 --- a/docs/03_command-reference/eosio-cpp.md +++ b/docs/03_command-reference/eosio-cpp.md @@ -71,4 +71,9 @@ compiler options: -sysroot= - Set the system root directory -v - Show commands to run and use verbose output -w - Suppress all warnings + -no-missing-ricardian-clause - Defaults to false, disables warnings for missing Ricardian clauses ``` + +## Notes + +* -no-missing-ricardian-clause: Defaults to false, if enabled, it suppresses warnings for missing Ricardian clauses on contracts and contract actions. That includes the warnings generated when there is also no independent Ricardian clause file. From a928b1a28624f7911a945d14be1eafb3ea1fb5c0 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 9 Jun 2021 11:55:09 +0300 Subject: [PATCH 135/204] updates based on feedback from peer review (Philip) --- .../04_data-design-and-migration.md | 4 +-- docs/05_best-practices/13_binary-extension.md | 2 +- .../03_compiling-contracts-with-cmake.md | 2 +- .../kv_map/10_how-to-use-kv-map.md | 2 -- .../kv_map/30_how-to-upsert-into-kv-map.md | 2 -- .../kv_map/70_how-to-find-in-kv-map.md | 2 -- .../90_how-to-allow-users-to-pay-kv-map.md | 2 -- .../kv_table/10_how-to-use-kv-table.md | 2 -- .../20_how-to-create-indexes-kv-table.md | 31 +++++++++---------- .../30_how-to-upsert-into-kv-table.md | 4 +-- .../40_how-to-delete-from-kv-table.md | 1 - .../kv_table/50_how-to-iterate-kv-table.md | 2 +- .../60_how-to-check-a-record-kv-table.md | 2 -- .../kv_table/70_how-to-find-in-kv-table.md | 2 -- .../80_how-to-query-range-in-kv-table.md | 2 -- .../90_how-to-allow-users-to-pay-kv-table.md | 4 +-- .../how-to-define-a-primary-index.md | 6 ++-- .../how-to-define-a-secondary-index.md | 4 +-- .../how-to-define-a-singleton.md | 12 +++---- ...to-delete-data-from-a-multi-index-table.md | 4 +-- ...to-insert-data-into-a-multi-index-table.md | 4 +-- .../how-to-instantiate-a-multi-index-table.md | 6 ++-- ...ti_index-table-based-on-secondary-index.md | 2 -- ...terate-and-retrieve-a-multi_index-table.md | 4 +-- ...w-to-modify-data-in-a-multi-index-table.md | 4 +-- ...0_how-to-create-and-use-action-wrappers.md | 2 +- .../60_how-to-return-values-from-actions.md | 2 -- docs/09_tutorials/01_binary-extension.md | 2 +- docs/09_tutorials/03_create-an-abi-file.md | 4 +-- 29 files changed, 39 insertions(+), 83 deletions(-) diff --git a/docs/05_best-practices/04_data-design-and-migration.md b/docs/05_best-practices/04_data-design-and-migration.md index 2806444f9d..5df43da26a 100644 --- a/docs/05_best-practices/04_data-design-and-migration.md +++ b/docs/05_best-practices/04_data-design-and-migration.md @@ -2,9 +2,9 @@ content_title: Data design and migration --- -EOSIO based blockchains allow developers to easily update their smart contract code. However, a few things need to be considered when it comes to data update and/or migration. The main structure for storing data in EOSIO based blockchains is the multi-index table. Once a multi-index table has been created with a first version of a smart contract, it has some limitations when it comes to changing its structure. Below you will find a few possible approaches which you can consider when you design your smart contract data and its migration. +EOSIO based blockchains allow developers to easily update their smart contract code. However, a few things need to be considered when it comes to data updates and/or migration. The multi-index table API is one of the mechanisms (Key-Value API being the other) for storing and updating blockchain state. The multi-index table API creates and uses data structures in RAM. Once created and deployed on the blockchian, changing these structures, i.e. adding new fields, it has some limitations. Below you will find a few possible approaches which you can consider when you design your smart contract data and its migration. -# How to modify the structure of a multi-index table +# How to modify a data structure defined using multi-index table API Modifying a multi-index table structure that has already been deployed to an EOSIO-based blockchain may be done by selecting one of the different strategies outlined below, depending on your requirements: diff --git a/docs/05_best-practices/13_binary-extension.md b/docs/05_best-practices/13_binary-extension.md index c7783641ac..e500ae06d1 100644 --- a/docs/05_best-practices/13_binary-extension.md +++ b/docs/05_best-practices/13_binary-extension.md @@ -327,7 +327,7 @@ struct [[eosio::table]] structure { } ``` -And their corresponding sections in the `.abi` files: +Find below their corresponding sections in the `.abi` files: **binary_extension_contract.abi** diff --git a/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md b/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md index 612c0e3425..4ed3cf6593 100644 --- a/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md +++ b/docs/06_how-to-guides/10_compile/03_compiling-contracts-with-cmake.md @@ -4,7 +4,7 @@ content_title: How to compile a smart contract with CMake ## Overview -This guide provides instructions on how to compile a smart contract with CMake. +This guide provides instructions to compile a smart contract with CMake. ## Before you begin diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md index 616ebc3d09..4ed6a6e98e 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md @@ -83,6 +83,4 @@ In conclusion, the above instructions show how to define and use a `Key-Value Ma ## Next Steps -The following option is available when you complete the procedure: - * You [can add values](30_how-to-upsert-into-kv-map.md) in the map object created. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md index 87447effd0..31e5f5053f 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md @@ -111,7 +111,5 @@ In conclusion, the above instructions show how to upsert into `Key-Value Map` (` ## Next Steps -The following options are available when you complete the procedure: - * [Verify](70_how-to-find-in-kv-map.md) if the newly inserted `person` actually exists in the map. To accomplish this task use the `find()` function of the `kv_map`. * [Delete](40_how-to-delete-from-kv-map.md) the newly created or updated `person` from the map. To accomplish this task, use the `erase()` function of the `kv map`. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md index ad3ffc4cd6..2515459ad1 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md @@ -106,7 +106,5 @@ In conclusion, the above instructions show how to find an object in `Key-Value M ## Next Steps -The following options are available when you complete the procedure: - * [Update](30_how-to-upsert-into-kv-map.md) the `person` found. * [Delete](40_how-to-delete-from-kv-map.md) the `person` found. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md index ba5943fa1e..b13cefb3ca 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md @@ -108,7 +108,5 @@ In conclusion, the above instructions show how to require the user to pay for th ## Next Steps -The following options are available when you complete the procedure: - * [Verify](70_how-to-find-in-kv-map.md) if the newly inserted `person` actually exists in the map. To accomplish this task use the `find()` function of the `kv_map`. * [Delete](40_how-to-delete-from-kv-map.md) the newly created or updated `person` from the map. To accomplish this task, use the `erase()` function of the `kv map`. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index 60516007aa..46115aa91d 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -80,8 +80,6 @@ In conclusion, the above instructions show how to define and use a `Key-Value Ta ## Next Steps -The following options are available when you complete the procedure: - * You can [create one or more unique indexes](20_how-to-create-indexes-kv-table.md) using the `KV_NAMED_INDEX` macro or the `eosio::kv::table::index` template class. * You can [create one or more non-unique indexes](20_how-to-create-indexes-kv-table.md) using the `KV_NAMED_INDEX` macro or the `eosio::kv::table::index` template class. * You can access the defined `kv table` and perform operations on it and its defined indexes: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index 4e5867bcf8..04a7c66cec 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -57,9 +57,9 @@ class [[eosio::contract]] smrtcontract : public contract { ### Define a unique index on property account_name using the macro KV_NAMED_INDEX 1. Use the `KV_NAMED_INDEX` macro with two parameters. -2. Pass the name of the index as the first parameter. The parameter must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. Pass the name of the property for which the index is defined as the second parameter. -4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and `account_name` index defined previously, by the KV_NAMED_INDEX macro, as the second parameter. +2. The first parameter is the name of the index and it must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +3. The second parameter is the name of the property the index is defined for. +4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and `account_name` index, by the KV_NAMED_INDEX macro, as the second parameter. Refer to the following reference implementation of a unique index on property `account_name` using macro `KV_NAMED_INDEX`: @@ -83,9 +83,9 @@ class [[eosio::contract]] smrtcontract : public contract { ### Define a unique index on property personal_id using the eosio::kv::table::index template class 1. Use the `eosio::kv::table::index` template class with two parameters. -2. Pass the name of the index as the first parameter. The parameter must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. Pass the reference to the property for which the index is defined, `&person::personal_id`, as the second parameter. -4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and the `personal_id_idx` index defined previously as the second parameter. +2. The first parameter is the name of the index and it must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +3. The second parameter is the reference to the property for which the index is defined, `&person::personal_id`. +4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `personal_id_idx` index as the second parameter. Refer to the following reference implementation of a unique index on property `personal_id` using `eosio::kv::table::index` template class: @@ -111,11 +111,11 @@ class [[eosio::contract]] smrtcontract : public contract { ### Define a non-unique index on property first_name using the macro KV_NAMED_INDEX 1. Use the `KV_NAMED_INDEX` with two parameters. -2. Pass the name of the index as the first parameter. The parameter must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. Pass the name of the property for which the index is defined as the second parameter. -4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and `first_name` index defined previously, by the KV_NAMED_INDEX macro, as the second parameter. +2. The first parameter is the name of the index and it must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +3. The second parameter is the name of the property the index is defined for. +4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and `first_name` index, by the KV_NAMED_INDEX macro, as the second parameter. -The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. +The second parameter is the name of the property the index is defined for and the type of this property must be `std::tuple<>`. The first parameter of the tuple must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. The last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a property name which is unique. Refer to the following reference implementation of a non-unique index on property `account_name` using macro `KV_NAMED_INDEX`: @@ -146,12 +146,11 @@ class [[eosio::contract]] smrtcontract : public contract { ### Define a non-unique index on property last_name using the eosio::kv::table::index template class 1. Use the `eosio::kv::table::index` template class. -2. Pass as the first parameter the name of the index. It must be a qualified `eosio:name`, see documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. Pass the reference to the property for which the index is defined, `&person::last_name`, as the second parameter. -4. Call `init()` of the base class in the constructor of `address_table` type and pass the contract name as the first parameter and the `last_name_idx` index defined previously as the second parameter. +2. The first parameter is the name of the index and it must be a qualified `eosio:name`, see documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +3. The second parameter is the name of the property the index is defined for, `&person::last_name`. +4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `last_name_idx` index as the second parameter. - -The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. And the last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. And, as previously already mentioned, the last parameter correspond to the type of a property name which is unique. +The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. The last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a property name which is unique. Refer to the following reference implementation of a non-unique index on property `last_name` using `eosio::kv::table::index` template class: @@ -187,7 +186,5 @@ In conclusion, the above instructions show how to create indexes on a `Key-Value ## Next Steps -The following options are available when you complete the procedure: - * [Search](70_how-to-find-in-kv-table.md) by index key for values or range of values in the defined `kv table`. * [Check](60_how-to-check-a-record-kv-table.md) if a particular key exists in an index. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index f9cda5a238..deb6f77efe 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -55,7 +55,7 @@ Complete the following steps to insert a new `person` object, and then update it 1. Create a new action `upsert` in your smart contact class, which takes as input parameters an account name, a first name, a last name and a personal id. 2. In the `upsert` action access the instance of `address_table` by declaring a local variable of `address_table` type. -3. And then call the `put` method of the `address_table` and pass to it a newly created `person` object based on the action’s input parameters. +3. Call the `put` method of the `address_table` and pass to it a newly created `person` object based on the action’s input parameters. Refer to the following reference implementation to insert a new `person` object, and then update it, in the `kv table`: @@ -111,8 +111,6 @@ In conclusion, the above instructions show how to upsert into `Key-Value Table` ## Next Steps -The following options are available when you complete the procedure: - * [Check](60_how-to-check-a-record-kv-table.md) if the newly inserted `person` actually exists in the table. To accomplish this task, use the `exists()` function of any index defined for the table. * [Retrieve](70_how-to-find-in-kv-table.md) the newly inserted or updated `person` from the table. To accomplish this task, use the `find()` function of any index defined for the table. * [Delete](40_how-to-delete-from-kv-table.md) the newly created or updated `person` from the table. To accomplish this task, use the `erase()` function of the `kv table`. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index 37f9e37f58..f4e5041623 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -102,6 +102,5 @@ In conclusion, the above instructions show how to delete an object from a `Key-V ## Next Steps -The following options are available when you complete the procedure: * [Check](60_how-to-check-a-record-kv-table.md) if the newly inserted `person` was actually deleted from the table. To accomplish this task, use the `exists()` function of any index defined for the table. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index 0e4575def4..2313dea610 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -63,7 +63,7 @@ Complete the following steps to implement an action which iterates through the f 2. In the `iterate` action access the instance of `address_table` by declaring a local variable of `address_table` type. 3. Capture the `begin` and the `end` of the `account_name_uidx` index defined. 4. Use the iterator `value` to access the current value of the iterator. -5. And then increment the iterator until the first N `person` objects stored in `address_table` are visited. +5. Increment the iterator until the first N `person` objects stored in `address_table` are visited. Refer to the following reference implementation to implement an action which iterates through the first N `person` objects in `address_table` and prints their first and last names: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index 58da59df1a..91b9716dd3 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -108,6 +108,4 @@ In conclusion, the above instructions show how to check if a specific object exi ## Next Steps -The following options are available when you complete the procedure: - * Implement business logic and rely on the information that the `person` object exists in the table. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index d365c73cb8..8818a8eca3 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -125,7 +125,5 @@ In conclusion, the above instructions show how to find a specific object in a `K ## Next Steps -The following options are available when you complete the procedure: - * [Update](30_how-to-upsert-into-kv-table.md) the `person` found and returned. * [Delete](40_how-to-delete-from-kv-table.md) the `person` found and returned. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index d7f632b276..79b64c568c 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -125,6 +125,4 @@ In conclusion, the above instructions show how to retrieve a list of values, fro ## Next Steps -The following options are available when you complete the procedure: - * Access the list of objects returned by the `getbylastname` action. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index bfe8d133f6..e3d665bf32 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -55,7 +55,7 @@ Complete the following steps to allow the `payer` account, to be the payer for t 1. Create a new action `upsert` in your smart contact class, which takes as input parameters an `account name, a first name, a last name, a personal id` which define a person data, and an `account name` for the payer. 2. In the `upsert` action access the instance of `address_table` belonging to this contract by declaring a local variable of `address_table` type and pass the contract name as paramter. -3. And then call the `put` method of the `address_table` and pass to it a newly created `person` object based on the action’s input parameters and the payer account name. +3. Call the `put` method of the `address_table` and pass to it a newly created `person` object based on the action’s input parameters and the payer account name. Refer to the following reference implementation to allow a specific account name to be the payer for the resources needed to store a person object in the `kv table`: @@ -113,8 +113,6 @@ In conclusion, the above instructions show how to create an action which require ## Next Steps -The following options are available when you complete the procedure: - * [Check](60_how-to-check-a-record-kv-table.md) if the newly inserted `person` actually exists in the table. To accomplish this task, use the `exists()` function of any index defined for the table. * [Retrieve](70_how-to-find-in-kv-table.md) the newly inserted or updated `person` from the table. To accomplish this task, use the `find()` function of any index defined for the table. * [Delete](40_how-to-delete-from-kv-table.md) the newly created or updated `person` from the table. To accomplish this task, use the `erase()` function of the `kv table`. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index 4f6bad6016..4e97c8de74 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -4,7 +4,7 @@ content_title: How to define a primary index ## Overview -This guide provides instructions on how to define a primary index for a multi-index table. +This guide provides instructions to define a primary index for a multi-index table. ## Reference @@ -24,7 +24,7 @@ Complete the following steps to define a primary index for the multi-index table ### 1. Preparation And Initialization -Include the `eosio.hpp` header and declare the `eosio` namespace usage. +Include the `eosio.hpp` header and use the `using` directive to access the `eosio` namespace. ```cpp #include @@ -119,7 +119,5 @@ In conclusion, the above instructions show how to define a primary index for a m ## Next Steps -The following option is available when you complete the procedure: - * You can [insert data in the multi-index table](./how-to-insert-data-into-a-multi-index-table). * You can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index a4149bc112..96fcbaa14a 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -4,7 +4,7 @@ content_title: How to define a secondary index ## Overview -This guide provides instructions on how to define a secondary index for a multi-index table. +This guide provides instructions to define a secondary index for a multi-index table. ## Reference @@ -124,6 +124,4 @@ In conclusion, the above instructions show how to define a secondary index for a ## Next Steps -The following option is available when you complete the procedure: - * You can [iterate and retrieve data using the secondary index](./how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index 604bae6ad6..56c9456c34 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -4,7 +4,7 @@ content_title: How to define a singleton ## Overview -This guide provides instructions on how to define a singleton. +This guide provides instructions to define a singleton. ## Reference @@ -57,7 +57,7 @@ For ease of use, define a type alias `singleton_type` based on the `eosio::singl ### 4. Define The Singleton Instance -Define the singleton table instance as a data member of type `singleton_type` defined in the previous step. +Define the singleton table instance as a data member of type `singleton_type`. ```diff struct [[eosio::table]] testtable { @@ -71,7 +71,7 @@ Define the singleton table instance as a data member of type `singleton_type` de ### 5. Initialize And Use The Singleton Instance -Initialize `singleton_instance` defined previously by passing to its constructor the `receiver` and the `code` (in this case `receiver.value`) parameters; these two combined with "testtable" provide access to the partition of the RAM cache used by this singleton. In this example you will initialize the `singleton_instance` data member in the smart contract constructor, see below: +Initialize the `singleton_instance` using the constructor with the parameters `receiver` and `code` (the last one in in this case is `receiver.value`). These parameters, combined with `testtable`, provide access to the partition of the RAM cache used by this singleton. In our example you initialize the `singleton_instance` data member in the smart contract constructor, see below: ```diff // singleton contract constructor @@ -118,7 +118,7 @@ class [[eosio::contract]] singleton_example : public contract { }; ``` -And below is a possible implementation for the two `get` and `set` actions defined above. It also demonstrates the usage of a couple of singleton methods. Note that the `set` action makes use of the singleton's `set` method, for which parameter is the account to pay for the new value stored. In this case, the same account name that is stored in the primary value is the payer. However, it can be a different account if so required. +Find below a possible implementation for the two `get` and `set` actions defined above. It also demonstrates the usage of the `get` and `set` singleton methods. Note that the `set` action makes use of the singleton's `set` method, for which the second parameter is the payer account for the RAM needed to store the new value. __singleton_example.cpp__ @@ -154,6 +154,4 @@ In conclusion, the above instructions show how to define a singleton. ## Next Steps -The following option is available when you complete the procedure: - -* Because a singleton is using as underlying structure a multi-index table, you can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the singleton same as you would with a multi-index table. +* Singleton uses as underlying structure a multi-index table therefore you can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the singleton the same way you would with a multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index b4a0264db0..f3cecb6cf6 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -4,7 +4,7 @@ content_title: How to delete data from a multi-index table ## Overview -This guide provides instructions on how to to delete data from a multi-index table. +This guide provides instructions to to delete data from a multi-index table. ## Reference @@ -62,8 +62,6 @@ In conclusion, the above instructions show how to delete data from a multi-index ## Next Steps -The following option is available when you complete the procedure: - * You can verify if the user object was deleted from the multi-index table. . ```cpp diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index e1b7c8e042..c12a7e17ec 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -4,7 +4,7 @@ content_title: How to insert data into a multi-index table ## Overview -This guide provides instructions on how to insert data into a multi-index table. +This guide provides instructions to insert data into a multi-index table. ## Reference @@ -67,6 +67,4 @@ In conclusion, the above instructions show how to insert data in a multi-index t ## Next Steps -The following option is available when you complete the procedure: - * You can [iterate and retrieve newly inserted data](./how-to-iterate-and-retrieve-a-multi_index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index 7a92530dad..2de2b5d426 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -4,7 +4,7 @@ content_title: How to instantiate a multi-index table ## Overview -This guide provides instructions on how to instantiate a multi-index table. +This guide provides instructions to instantiate a multi-index table. ## Reference @@ -24,7 +24,7 @@ Complete the following steps to instantiate a multi-index table `testtab`. ### 1. Preparation And Initialization -Include the `eosio.hpp` header and declare the `eosio` namespace usage. +Include the `eosio.hpp` header and use the `using` directive to access the `eosio` namespace. ```cpp #include @@ -181,7 +181,5 @@ In conclusion, the above instructions show how to define and instantiate a multi ## Next Steps -The following option is available when you complete the procedure: - * You can [insert data in the multi-index table](./how-to-insert-data-into-a-multi-index-table). * You can [iterate and retrieve data](./how-to-iterate-and-retrieve-a-multi_index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index 60984aa0be..d77c6d104c 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -163,7 +163,5 @@ In conclusion, the above instructions show how to iterate and retrieve a multi-i ## Next Steps -The following option is available when you complete the procedure: - * You can [insert data](./how-to-insert-data-into-a-multi-index-table) into the multi-index table. * You can [delete data](./how-to-delete-data-from-a-multi-index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index b5c16c069d..87cbdf4b53 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -4,7 +4,7 @@ content_title: How to iterate and retrieve from multi-index table ## Overview -This guide provides instructions on how to iterate and retrieve data from a multi-index table. +This guide provides instructions to iterate and retrieve data from a multi-index table. ## Reference @@ -147,7 +147,5 @@ In conclusion, the above instructions show how to iterate and retrieve a multi-i ## Next Steps -The following option is available when you complete the procedure: - * You can [insert data](./how-to-insert-data-into-a-multi-index-table) into the multi-index table. * You can [delete data](./how-to-delete-data-from-a-multi-index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index f7d644f021..7d07154d8b 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -4,7 +4,7 @@ content_title: How to modify data in a multi-index table ## Overview -This guide provides instructions on how to modify data in a multi-index table. +This guide provides instructions to modify data in a multi-index table. ## Reference @@ -88,7 +88,5 @@ In conclusion, the above instructions show how to modify data in a multi-index t ## Next Steps -The following option is available when you complete the procedure: - * You can [insert data](./how-to-insert-data-into-a-multi-index-table) into the multi-index table. * You can [delete data](./how-to-delete-data-from-a-multi-index-table) from the multi-index table. diff --git a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md index cce2bca91c..94ebd59691 100644 --- a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md +++ b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md @@ -5,7 +5,7 @@ link_text: "How to create and use action wrappers" ## Overview -This guide provides instructions on how to create and use an action wrapper in a smart contract. +This guide provides instructions to create and use an action wrapper in a smart contract. ## Code Reference diff --git a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md index 6a5c60cf4a..eaf7c8c805 100644 --- a/docs/06_how-to-guides/60_how-to-return-values-from-actions.md +++ b/docs/06_how-to-guides/60_how-to-return-values-from-actions.md @@ -68,8 +68,6 @@ For a complete example of a smart contract that implements an action which retur ## Next Steps -The following options are available when you complete the procedure: - * Compile the smart contract and deploy it to the EOSIO testnet or any EOSIO based blockchain. * Use the `cleos` command to send the `checkwithrv` action to the smart contract and observe the returned value in the `cleos` output. * Use other means (e.g. programmatically) to send the `checkwithrv` action to the smart contract and observe the returned value in the action trace. diff --git a/docs/09_tutorials/01_binary-extension.md b/docs/09_tutorials/01_binary-extension.md index c149089790..5c7b291794 100644 --- a/docs/09_tutorials/01_binary-extension.md +++ b/docs/09_tutorials/01_binary-extension.md @@ -323,7 +323,7 @@ struct [[eosio::table]] structure { } ``` -And their corresponding sections in the `.abi` files: +Find below their corresponding sections in the `.abi` files: **binary_extension_contract.abi** diff --git a/docs/09_tutorials/03_create-an-abi-file.md b/docs/09_tutorials/03_create-an-abi-file.md index 42537a1ebc..92820e1540 100644 --- a/docs/09_tutorials/03_create-an-abi-file.md +++ b/docs/09_tutorials/03_create-an-abi-file.md @@ -4,14 +4,14 @@ content_title: Create an ABI File ## Overview -This tutorial provides instructions on how to create an ABI file. +This tutorial provides instructions to create an ABI file. [[warning]] | As of v1.2.0, the eosio.wasmsdk was decoupled from the core repository. This change has introduced an eosio-cpp regression where the legacy eosio-abigen is no longer bundled with eosio-cpp. Until a new ABI generator is introduced, you will need to hand-write your ABI files. ## Introduction -The Application Binary Interface (ABI) is a JSON-based description on how to convert user actions between their JSON and Binary representations. The ABI also describes how to convert the database state to/from JSON. Once you have described your contract via an ABI then developers and users will be able to interact with your contract seamlessly via JSON. +The Application Binary Interface (ABI) is a JSON-based description to convert user actions between their JSON and Binary representations. The ABI also describes how to convert the database state to/from JSON. Once you have described your contract via an ABI then developers and users will be able to interact with your contract seamlessly via JSON. This tutorial will use the [eosio.token](https://github.com/EOSIO/eosio.contracts/tree/master/eosio.token) contract as an example. *eosio.token contract does not cover every possible permutation of an ABI definition. From 4eabc2a0fe642beb64b52a2c6f17640133ade146 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 9 Jun 2021 12:08:50 +0300 Subject: [PATCH 136/204] property was used wrongly in many cases, for these cases the correct terminology for c++ is data member or data variable --- .../kv_table/10_how-to-use-kv-table.md | 2 +- .../20_how-to-create-indexes-kv-table.md | 28 +++++++++---------- .../30_how-to-upsert-into-kv-table.md | 2 +- .../40_how-to-delete-from-kv-table.md | 2 +- .../kv_table/50_how-to-iterate-kv-table.md | 2 +- .../60_how-to-check-a-record-kv-table.md | 2 +- .../kv_table/70_how-to-find-in-kv-table.md | 2 +- .../80_how-to-query-range-in-kv-table.md | 4 +-- .../90_how-to-allow-users-to-pay-kv-table.md | 2 +- .../30_key-value-api/kv_table/index.md | 10 +++---- .../how-to-define-a-primary-index.md | 12 ++++---- .../how-to-define-a-secondary-index.md | 10 +++---- .../how-to-instantiate-a-multi-index-table.md | 12 ++++---- ...ti_index-table-based-on-secondary-index.md | 4 +-- ...terate-and-retrieve-a-multi_index-table.md | 2 +- ...w-to-modify-data-in-a-multi-index-table.md | 6 ++-- 16 files changed, 51 insertions(+), 51 deletions(-) diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index 46115aa91d..f432ce617f 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -48,7 +48,7 @@ Complete the following steps to define the `address_table` type, based on the `e 1. Define the structure or class `address_table` in the scope of your smart contract class, for the abi generation to find it and place it into the abi file. 2. Derive `address_table` from `eosio::`kv::table` class template. Pass the `person` user defined type as the type parameter for `eosio::`kv::table` base class and the name of the `kv table`, let’s say `kvaddrbook`. 3. Annotate `address_table` type with `[[eosio::table]]`, and make sure it is placed after the `struct` keyword but before the name of the type. -4. Define a primary index `first_name_idx` based on the property `person::first_name`. Every `kv table` requires a primary index to be defined based on a property that stores unique values. +4. Define a primary index `first_name_idx` based on the data member `person::first_name`. Every `kv table` requires a primary index to be defined based on a data member that stores unique values. 5. In the `address_table` constructor, call the `init(...)` base class method with the two parameters: 1. The first parameter, of type `eosio::name`, is the contract that owns the table. 2. The second parameter is the `account_name_uidx` primary index. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index 04a7c66cec..c663cafbb2 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -54,14 +54,14 @@ class [[eosio::contract]] smrtcontract : public contract { ## Procedure -### Define a unique index on property account_name using the macro KV_NAMED_INDEX +### Define a unique index on data member account_name using the macro KV_NAMED_INDEX 1. Use the `KV_NAMED_INDEX` macro with two parameters. 2. The first parameter is the name of the index and it must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the name of the property the index is defined for. +3. The second parameter is the name of the data member the index is defined for. 4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and `account_name` index, by the KV_NAMED_INDEX macro, as the second parameter. -Refer to the following reference implementation of a unique index on property `account_name` using macro `KV_NAMED_INDEX`: +Refer to the following reference implementation of a unique index on data member `account_name` using macro `KV_NAMED_INDEX`: `smartcontract.hpp file` @@ -80,14 +80,14 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -### Define a unique index on property personal_id using the eosio::kv::table::index template class +### Define a unique index on data member personal_id using the eosio::kv::table::index template class 1. Use the `eosio::kv::table::index` template class with two parameters. 2. The first parameter is the name of the index and it must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the reference to the property for which the index is defined, `&person::personal_id`. +3. The second parameter is the reference to the data member for which the index is defined, `&person::personal_id`. 4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `personal_id_idx` index as the second parameter. -Refer to the following reference implementation of a unique index on property `personal_id` using `eosio::kv::table::index` template class: +Refer to the following reference implementation of a unique index on data member `personal_id` using `eosio::kv::table::index` template class: `smartcontract.hpp file` @@ -108,16 +108,16 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -### Define a non-unique index on property first_name using the macro KV_NAMED_INDEX +### Define a non-unique index on data member first_name using the macro KV_NAMED_INDEX 1. Use the `KV_NAMED_INDEX` with two parameters. 2. The first parameter is the name of the index and it must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the name of the property the index is defined for. +3. The second parameter is the name of the data member the index is defined for. 4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and `first_name` index, by the KV_NAMED_INDEX macro, as the second parameter. -The second parameter is the name of the property the index is defined for and the type of this property must be `std::tuple<>`. The first parameter of the tuple must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. The last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a property name which is unique. +The second parameter is the name of the data member the index is defined for and the type of this data member must be `std::tuple<>`. The first parameter of the tuple must be the type of the data member indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple type must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. -Refer to the following reference implementation of a non-unique index on property `account_name` using macro `KV_NAMED_INDEX`: +Refer to the following reference implementation of a non-unique index on data member `account_name` using macro `KV_NAMED_INDEX`: `smartcontract.hpp file` @@ -143,16 +143,16 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -### Define a non-unique index on property last_name using the eosio::kv::table::index template class +### Define a non-unique index on data member last_name using the eosio::kv::table::index template class 1. Use the `eosio::kv::table::index` template class. 2. The first parameter is the name of the index and it must be a qualified `eosio:name`, see documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the name of the property the index is defined for, `&person::last_name`. +3. The second parameter is the name of the data member the index is defined for, `&person::last_name`. 4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `last_name_idx` index as the second parameter. -The property used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the property indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the property indexed non-uniquely. The last parameter of the tuple type must be the type of a property name which is unique. In our case the type `eosio::name` is used because property `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a property name which is unique. +The data member used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the data member indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple type must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. -Refer to the following reference implementation of a non-unique index on property `last_name` using `eosio::kv::table::index` template class: +Refer to the following reference implementation of a non-unique index on data member `last_name` using `eosio::kv::table::index` template class: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index deb6f77efe..79ecc404a4 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -19,7 +19,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. +* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` darta member. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index f4e5041623..a6810bb9c6 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -19,7 +19,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. +* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` darta member. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index 2313dea610..edf0bb9a42 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -25,7 +25,7 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` property.. +* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index 91b9716dd3..c709fed1e3 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -25,7 +25,7 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` property.. +* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index 8818a8eca3..0f90a16873 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -25,7 +25,7 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` property.. +* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index 79b64c568c..4dbb31e095 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -25,8 +25,8 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` property.. -* A non-unique index defined on the `last_name` property, named `last_name_idx`. +* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. +* A non-unique index defined on the `last_name` darta member, named `last_name_idx`. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index e3d665bf32..a4c4427dd7 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -19,7 +19,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` property. +* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` darta member. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/index.md b/docs/06_how-to-guides/30_key-value-api/kv_table/index.md index 2c8dfcea36..666596e59a 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/index.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/index.md @@ -10,7 +10,7 @@ A `datastore key value table on-chain`, or a `KV Table`, serves as a storage loc [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. -The `object definition` consists of a list of `properties` and each property is stored on the corresponding row in the table. The properties of the objects are also referred to as `fields`. +The `object definition` consists of a list of `properties` and each data member is stored on the corresponding row in the table. The properties of the objects are also referred to as `fields`. A `KV Table` requires one unique index, of any type, that can be serialized to a binary representation. @@ -18,12 +18,12 @@ A `KV Table` supports zero or more secondary indexes, of any type, that can be s Two types of indexes can be defined, unique or non-unique. -A unique index can be defined just for one property, and it will sort the objects stored in the `KV Table` based on the `specified property`. The unique index also ensures only one instance of an object is stored with a particular value for the `specified property`, and thus ensures the uniqueness of the property for which it is defined. +A unique index can be defined just for one darta member, and it will sort the objects stored in the `KV Table` based on the `specified darta member`. The unique index also ensures only one instance of an object is stored with a particular value for the `specified darta member`, and thus ensures the uniqueness of the data member for which it is defined. -A non-unique index can be defined for one or multiple properties, and it will sort the objects stored in the `KV Table` based on the `specified property` or the combination of the `specified properties`. Very important though, a non-unique index requires as the last property of its definition a property which has unique values. Therefore although the non-unique index is intended for just one property, its definition will have two properties specified: +A non-unique index can be defined for one or multiple properties, and it will sort the objects stored in the `KV Table` based on the `specified darta member` or the combination of the `specified properties`. Very important though, a non-unique index requires as the last data member of its definition a data member which has unique values. Therefore although the non-unique index is intended for just one darta member, its definition will have two properties specified: -1. the first property, the one for which the non-unique index is built, -2. and the last property which must have unique values. +1. the first darta member, the one for which the non-unique index is built, +2. and the last data member which must have unique values. The main operations provided by the KV API are the following: diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index 4e97c8de74..7480da6686 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -40,12 +40,12 @@ Define the data structure for the multi-index table. }; ``` -Add to the data structure the properties which define it. Each property corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding property for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. +Add to the data structure the properties which define it. Each data member corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding data member for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - + // this property stores a name for each row of the multi-index table + + // this data member stores a name for each row of the multi-index table + name test_primary; + // additional data stored in table row, e.g. an uint64_t type data + uint64_t datum; @@ -59,7 +59,7 @@ Add definition of the primary index for the multi-index table. The primary index ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -69,7 +69,7 @@ Add definition of the primary index for the multi-index table. The primary index ``` [[info | Secondary indexes information]] -| Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the corresponding property types can be uint64_t, uint128_t, uint256_t, double or long double. +| Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the corresponding data member types can be uint64_t, uint128_t, uint256_t, double or long double. ### 4. Define A Multi-Index Type Alias @@ -78,7 +78,7 @@ For ease of use, define a type alias `test_table_t` based on the `eosio::multi_i ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -96,7 +96,7 @@ Declare the `testtab` multi-index table as a data member of type `test_table_t`. ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index 96fcbaa14a..24d4fbf734 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -25,11 +25,11 @@ Complete the following steps to define a secondary index for the multi-index tab ### 1. Extend The Multi-Index Data Structure -Add a second property `secondary`, of type `eosio::name`, to the `test_table` data structure that defines the `testtab` data. +Add a second data member `secondary`, of type `eosio::name`, to the `test_table` data structure that defines the `testtab` data. ```diff struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; + name secondary; // additional data stored in table row @@ -41,11 +41,11 @@ Add a second property `secondary`, of type `eosio::name`, to the `test_table` da ### 2. Add The Secondary Index Accessor Method -Add `by_secondary()` method, which is the index accessor method to the new property added. The secondary index, that will be added in the next step, will index this new data structure property. +Add `by_secondary()` method, which is the index accessor method to the new data member added. The secondary index, that will be added in the next step, will index this new data structure darta member. ```diff struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row @@ -87,7 +87,7 @@ __multi_index_example.hpp__ { } struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index 2de2b5d426..f5d4fb0a1f 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -40,12 +40,12 @@ Define the data structure for the multi-index table. }; ``` -Add to the data structure the properties which define it. Each property corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding property for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. +Add to the data structure the properties which define it. Each data member corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding data member for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - + // this property stores a name for each row of the multi-index table + + // this data member stores a name for each row of the multi-index table + name test_primary; + // additional data stored in table row, e.g. an uint64_t type data + uint64_t datum; @@ -59,7 +59,7 @@ Add definition of the primary index for the multi-index table. The primary index ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -78,7 +78,7 @@ For ease of use, define a type alias `test_table_t` based on the `eosio::multi_i ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -96,7 +96,7 @@ Declare the `testtab` multi-index table as a data member of type `test_table_t`. ```diff // the data structure which defines each row of the table struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; @@ -148,7 +148,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index d77c6d104c..fbf9916e54 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -18,7 +18,7 @@ See the following code reference: Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index), -* A multi-index `testab` table instance which stores `user` objects indexed by the primary key which is of type `eosio::name` and a secondary index for property `secondary` of type `eosio::name` accessible through `by_secondary()` method. Consult the section [How to define a secondary index](./how-to-define-a-secondary-index) to learn how to set it up. +* A multi-index `testab` table instance which stores `user` objects indexed by the primary key which is of type `eosio::name` and a secondary index for data member `secondary` of type `eosio::name` accessible through `by_secondary()` method. Consult the section [How to define a secondary index](./how-to-define-a-secondary-index) to learn how to set it up. ## Procedure @@ -83,7 +83,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; name secondary; // additional data stored in table row diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 87cbdf4b53..2f277101b7 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -83,7 +83,7 @@ class [[eosio::contract]] multi_index_example : public contract { // the row structure of the multi-index table, that is, each row of the table // will contain an instance of this type of structure struct [[eosio::table]] test_table { - // this property stores a name for each row of the multi-index table + // this data member stores a name for each row of the multi-index table name test_primary; // additional data stored in table row uint64_t datum; diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index 7d07154d8b..5ffe27b514 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -26,7 +26,7 @@ Complete the following steps to modify data in the `testtab` multi-index table. ### 1. Define The mod(...) Action -Add to the definition of the `testtab` multi-index table the `mod` action which gets as input parameters a `user` of type `eosio::name` and a `value` of type `uint32_t`. The `mod` action will update the `user` object `datum` property with the `uint32_t` value. +Add to the definition of the `testtab` multi-index table the `mod` action which gets as input parameters a `user` of type `eosio::name` and a `value` of type `uint32_t`. The `mod` action will update the `user` object `datum` data member with the `uint32_t` value. ```cpp [[eosio::action]] void mod( name user, uint32_t value ); @@ -63,7 +63,7 @@ If the `user` object you want to update is not found then raise an error message ### 4. Update The User If Found -If the `user` object you want to update is found, the [`eosio::check`](../../namespaceeosio/#function-check-17) method will do nothing and the iterator `itr` will be pointing at the object which you want to update. Use the [`multi-index::modify(...)`](../../group__multiindex/#function-modify) method to update the user object `datum` property with the `value` parameter. +If the `user` object you want to update is found, the [`eosio::check`](../../namespaceeosio/#function-check-17) method will do nothing and the iterator `itr` will be pointing at the object which you want to update. Use the [`multi-index::modify(...)`](../../group__multiindex/#function-modify) method to update the user object `datum` data member with the `value` parameter. ```diff [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -77,7 +77,7 @@ If the `user` object you want to update is found, the [`eosio::check`](../../nam } ``` -Now you have implemented a new action `mod`, which when sent to the blockchain will update the `datum` property for user object identified by `user` name with the `value` sent as parameter. +Now you have implemented a new action `mod`, which when sent to the blockchain will update the `datum` data member for user object identified by `user` name with the `value` sent as parameter. [[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). From d6573e5b8988cc2ab4d24da6e8dbf818198a9ac3 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 9 Jun 2021 12:21:37 +0300 Subject: [PATCH 137/204] updates based on peer review (Philip) -- take 2 --- .../40_multi-index/how-to-define-a-primary-index.md | 9 +++++++-- .../40_multi-index/how-to-define-a-singleton.md | 6 +++--- .../how-to-instantiate-a-multi-index-table.md | 2 +- .../50_how-to-create-and-use-action-wrappers.md | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index 7480da6686..26d28a10d1 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -69,11 +69,16 @@ Add definition of the primary index for the multi-index table. The primary index ``` [[info | Secondary indexes information]] -| Other, secondary, indexes if they will be defined can have duplicates. You can have up to 16 additional indexes and the corresponding data member types can be uint64_t, uint128_t, uint256_t, double or long double. +| Secondary indexes may be defined which are not unique. There can be up to 16 secondary indexes. Secondary indices support the following types: +* uint64_t +* uint128_t +* uint256_t +* double +* long double ### 4. Define A Multi-Index Type Alias -For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above. +For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure. The names must adhere to `EOSIO` account name restrictions. ```diff // the data structure which defines each row of the table diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index 56c9456c34..de19477f3e 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -34,7 +34,7 @@ Include the `eosio.hpp` and `singleton.hpp` headers and declare the `eosio` name ### 2. Define The Table Data Structure -Define the data structure for the multi-index table the singleton will use: +Define the data structure for the multi-index table: ```cpp struct [[eosio::table]] testtable { @@ -45,7 +45,7 @@ Define the data structure for the multi-index table the singleton will use: ### 3. Define A Singleton Type Alias -For ease of use, define a type alias `singleton_type` based on the `eosio::singleton` template type, parametarized with a random name `"testtable"`, which has to respect the EOSIO account name restrictions, and the `testtable` data structure defined above +For ease of use, define a type alias `singleton_type` based on the `eosio::singleton` template type, parametarized with a random name `"testtable"` and the `testtable` data structure. The names must adhere to `EOSIO` account name restrictions. ```diff struct [[eosio::table]] testtable { @@ -118,7 +118,7 @@ class [[eosio::contract]] singleton_example : public contract { }; ``` -Find below a possible implementation for the two `get` and `set` actions defined above. It also demonstrates the usage of the `get` and `set` singleton methods. Note that the `set` action makes use of the singleton's `set` method, for which the second parameter is the payer account for the RAM needed to store the new value. +Find below a possible implementation for the two `get` and `set` actions. It also demonstrates the usage of the `get` and `set` singleton methods. Note that the `set` action makes use of the singleton's `set` method, for which the second parameter is the payer account for the RAM needed to store the new value. __singleton_example.cpp__ diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index f5d4fb0a1f..ea04fbcf7e 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -73,7 +73,7 @@ Add definition of the primary index for the multi-index table. The primary index ### 4. Define A Multi-Index Type Alias -For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure defined above. +For ease of use, define a type alias `test_table_t` based on the `eosio::multi_index` template type, parametarized with a random name `"testtaba"` and the `test_table` data structure. The names must adhere to `EOSIO` account name restrictions. ```diff // the data structure which defines each row of the table diff --git a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md index 94ebd59691..915d3c5f64 100644 --- a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md +++ b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md @@ -67,7 +67,7 @@ To use the action wrapper, you have to include the header file where the action #### 2.2. Instantiate The Action Wrapper -Instantiate the `mod_action` defined above, specifying the contract to send the action to as the first argument. In this case, it is assumed the contract is deployed to `multiindexex` account, and a structure which is defined by two parameters: the self account, obtained by `get_self()` call, and the `active` permission (you can modify these two parameters based on your requirements). +Instantiate the `mod_action`, specifying the contract to send the action to as the first argument. In this case, it is assumed the contract is deployed to `multiindexex` account, and a structure which is defined by two parameters: the self account, obtained by `get_self()` call, and the `active` permission (you can modify these two parameters based on your requirements). ```diff #include From 6ad099bb30d829a1cb356d1f5480f73d522c5102 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 9 Jun 2021 12:34:54 +0300 Subject: [PATCH 138/204] introduce Features menu item and under it the Transaction Sponsorship --- docs/05_features/10_trx_sponsorship.md | 41 ++++++++++++++++++ .../02_naming-conventions.md | 0 .../03_resource-planning.md | 0 .../04_data-design-and-migration.md | 0 .../05_securing_your_contract.md | 0 .../07_error_handling.md | 0 .../08_abi/00_understanding-abi-files.md | 0 ...abi-code-generator-attributes-explained.md | 0 ...02_manually_write_an_ABI_file_explained.md | 0 .../08_abi/index.md | 0 .../09_deferred_transactions.md | 0 .../10_native-tester-compilation.md | 0 .../11_debugging_a_smart_contract.md | 0 .../12_return_values_from_actions.md | 0 .../13_binary-extension.md | 0 .../naming-conventions-format.png | Bin docs/08_troubleshooting.md | 6 +-- 17 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 docs/05_features/10_trx_sponsorship.md rename docs/{05_best-practices => 07_best-practices}/02_naming-conventions.md (100%) rename docs/{05_best-practices => 07_best-practices}/03_resource-planning.md (100%) rename docs/{05_best-practices => 07_best-practices}/04_data-design-and-migration.md (100%) rename docs/{05_best-practices => 07_best-practices}/05_securing_your_contract.md (100%) rename docs/{05_best-practices => 07_best-practices}/07_error_handling.md (100%) rename docs/{05_best-practices => 07_best-practices}/08_abi/00_understanding-abi-files.md (100%) rename docs/{05_best-practices => 07_best-practices}/08_abi/01_abi-code-generator-attributes-explained.md (100%) rename docs/{05_best-practices => 07_best-practices}/08_abi/02_manually_write_an_ABI_file_explained.md (100%) rename docs/{05_best-practices => 07_best-practices}/08_abi/index.md (100%) rename docs/{05_best-practices => 07_best-practices}/09_deferred_transactions.md (100%) rename docs/{05_best-practices => 07_best-practices}/10_native-tester-compilation.md (100%) rename docs/{05_best-practices => 07_best-practices}/11_debugging_a_smart_contract.md (100%) rename docs/{05_best-practices => 07_best-practices}/12_return_values_from_actions.md (100%) rename docs/{05_best-practices => 07_best-practices}/13_binary-extension.md (100%) rename docs/{05_best-practices => 07_best-practices}/naming-conventions-format.png (100%) diff --git a/docs/05_features/10_trx_sponsorship.md b/docs/05_features/10_trx_sponsorship.md new file mode 100644 index 0000000000..4d00e7fec4 --- /dev/null +++ b/docs/05_features/10_trx_sponsorship.md @@ -0,0 +1,41 @@ +--- +content_title: Transaction Sponsorship +--- + +## Overview + +The `Transaction Sponsorship` feature, also known as Resource Payer, allows a simple and secure way for application developers to sponsor, or decline to sponsor, transactions on behalf of their users. + +## Concept + +Before the `EOSIO 2.2` version, the CPU and NET resource costs for transactions on EOSIO-based blockchains were paid by the end users of the application. This fact made attracting and onboarding new users difficult. + +The `Transaction Sponsorship` feature makes it easier for both smart contract and full stack developers on EOSIO-based blockchains to allow their users to transact without having to pay for CPU and NET resource costs in a simple and secure manner. This new feature makes the process of onboarding new users straightforward. + +Blockchain application developers can use the `Transaction Sponsorship` on any EOSIO-based blockchain that enables it via the newly introduced `RESOURCE_PAYER` upgrade protocol feature. + +### Related Terminology/Concepts + +A [transaction](https://developers.eos.io/welcome/latest/glossary/index/#transaction) consists of one or more actions executed atomically on the blockchain which alter the state of the blockchain. + +You need system resources, [CPU](https://developers.eos.io/welcome/latest/glossary/index/#cpu) and [NET](https://developers.eos.io/welcome/latest/glossary/index/#net), to be able to execute transactions. + +The `Transaction Sponsorship` feature allows the application developers to designate the payer of the CPU and NET resources cost to a random blockchain [account](https://developers.eos.io/welcome/latest/glossary/index/#account). + +The `Transaction Sponsorship` feature is not available by default. To enable the feature, the `RESOURCE_PAYER` upgrade protocol feature must be enabled. For more information about upgrading protocol features, read the [Consensus Protocol Upgrade Process](https://developers.eos.io/manuals/eos/latest/nodeos/upgrade-guides/1.8-upgrade-guide/#upgrade-process-for-all-eosio-networks-including-test-networks) documentation. + +When you send the transaction to the blockchain, if you want to designate the transaction sponsor, you must specify in the transaction definition the sponsorship information which consists of the following: + +* The sponsor’s account name, +* The maximum CPU limit amount the sponsor supports expressed in microseconds, +* The maximum NET limit amount the sponsor supports expressed in bytes. + +The sponsorship information must be defined as a transaction extension and placed in the transaction’s extension list. For more details please see the examples provided in the following section. + +## Examples + +Below are two examples that illustrate how to send a sponsored transaction to the blockchain. + +* To send a transaction to the blockchain using `cleos` tool, follow the [How To Send A Sponsored Transaction](https://developers.eos.io/manuals/eosjs/latest/how-to-guides/how-to-submit-a-sponsored-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. \ + +* To send a transaction to the blockchain using javascript via the `eosjs` library, follow the [How To Send A Transaction](https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-submit-a-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. diff --git a/docs/05_best-practices/02_naming-conventions.md b/docs/07_best-practices/02_naming-conventions.md similarity index 100% rename from docs/05_best-practices/02_naming-conventions.md rename to docs/07_best-practices/02_naming-conventions.md diff --git a/docs/05_best-practices/03_resource-planning.md b/docs/07_best-practices/03_resource-planning.md similarity index 100% rename from docs/05_best-practices/03_resource-planning.md rename to docs/07_best-practices/03_resource-planning.md diff --git a/docs/05_best-practices/04_data-design-and-migration.md b/docs/07_best-practices/04_data-design-and-migration.md similarity index 100% rename from docs/05_best-practices/04_data-design-and-migration.md rename to docs/07_best-practices/04_data-design-and-migration.md diff --git a/docs/05_best-practices/05_securing_your_contract.md b/docs/07_best-practices/05_securing_your_contract.md similarity index 100% rename from docs/05_best-practices/05_securing_your_contract.md rename to docs/07_best-practices/05_securing_your_contract.md diff --git a/docs/05_best-practices/07_error_handling.md b/docs/07_best-practices/07_error_handling.md similarity index 100% rename from docs/05_best-practices/07_error_handling.md rename to docs/07_best-practices/07_error_handling.md diff --git a/docs/05_best-practices/08_abi/00_understanding-abi-files.md b/docs/07_best-practices/08_abi/00_understanding-abi-files.md similarity index 100% rename from docs/05_best-practices/08_abi/00_understanding-abi-files.md rename to docs/07_best-practices/08_abi/00_understanding-abi-files.md diff --git a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md b/docs/07_best-practices/08_abi/01_abi-code-generator-attributes-explained.md similarity index 100% rename from docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md rename to docs/07_best-practices/08_abi/01_abi-code-generator-attributes-explained.md diff --git a/docs/05_best-practices/08_abi/02_manually_write_an_ABI_file_explained.md b/docs/07_best-practices/08_abi/02_manually_write_an_ABI_file_explained.md similarity index 100% rename from docs/05_best-practices/08_abi/02_manually_write_an_ABI_file_explained.md rename to docs/07_best-practices/08_abi/02_manually_write_an_ABI_file_explained.md diff --git a/docs/05_best-practices/08_abi/index.md b/docs/07_best-practices/08_abi/index.md similarity index 100% rename from docs/05_best-practices/08_abi/index.md rename to docs/07_best-practices/08_abi/index.md diff --git a/docs/05_best-practices/09_deferred_transactions.md b/docs/07_best-practices/09_deferred_transactions.md similarity index 100% rename from docs/05_best-practices/09_deferred_transactions.md rename to docs/07_best-practices/09_deferred_transactions.md diff --git a/docs/05_best-practices/10_native-tester-compilation.md b/docs/07_best-practices/10_native-tester-compilation.md similarity index 100% rename from docs/05_best-practices/10_native-tester-compilation.md rename to docs/07_best-practices/10_native-tester-compilation.md diff --git a/docs/05_best-practices/11_debugging_a_smart_contract.md b/docs/07_best-practices/11_debugging_a_smart_contract.md similarity index 100% rename from docs/05_best-practices/11_debugging_a_smart_contract.md rename to docs/07_best-practices/11_debugging_a_smart_contract.md diff --git a/docs/05_best-practices/12_return_values_from_actions.md b/docs/07_best-practices/12_return_values_from_actions.md similarity index 100% rename from docs/05_best-practices/12_return_values_from_actions.md rename to docs/07_best-practices/12_return_values_from_actions.md diff --git a/docs/05_best-practices/13_binary-extension.md b/docs/07_best-practices/13_binary-extension.md similarity index 100% rename from docs/05_best-practices/13_binary-extension.md rename to docs/07_best-practices/13_binary-extension.md diff --git a/docs/05_best-practices/naming-conventions-format.png b/docs/07_best-practices/naming-conventions-format.png similarity index 100% rename from docs/05_best-practices/naming-conventions-format.png rename to docs/07_best-practices/naming-conventions-format.png diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting.md index e8da1593a9..8d17947015 100644 --- a/docs/08_troubleshooting.md +++ b/docs/08_troubleshooting.md @@ -74,11 +74,11 @@ assertion failure with message: singleton does not exist pending console output: ``` -__Possible solution__: It is possible that you changed the table name? That is the first, of `eosio::name` type, parameter which you passed to the `eosio::template` type alias definition. Or did you change the table structure definition at all? If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./05_best-practices/04_data-design-and-migration.md) section. +__Possible solution__: It is possible that you changed the table name? That is the first, of `eosio::name` type, parameter which you passed to the `eosio::template` type alias definition. Or did you change the table structure definition at all? If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./07_best-practices/04_data-design-and-migration.md) section. ## You successfully re-deployed the contract code, but when you query the table you get the fields of the row values swapped, that is, it appears the values stored in table rows are the same only that they are swapped between fields/columns -__Possible solution__: It is possible that you changed the order of the fields the table struct definition? If you change the order of the table struct definition, if the swapped fields have the same type you will see the data in the fields correctly, however if the types of the fields are different the results could be of something undefined. If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./05_best-practices/04_data-design-and-migration.md) section. +__Possible solution__: It is possible that you changed the order of the fields the table struct definition? If you change the order of the table struct definition, if the swapped fields have the same type you will see the data in the fields correctly, however if the types of the fields are different the results could be of something undefined. If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./07_best-practices/04_data-design-and-migration.md) section. ## You successfully re-deployed the contract code, but when you query the table you get a parse error, like the one below, or the returned data seems to be garbage @@ -87,7 +87,7 @@ error 2019-09-26T07:05:54.825 thread-0 main.cpp:3449 main Couldn't parse type_name ``` -__Possible solution__: It is possible that you changed the type of the fields for the table struct definition? If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./05_best-practices/04_data-design-and-migration.md) section. +__Possible solution__: It is possible that you changed the type of the fields for the table struct definition? If you need to change the table structure definition there are some limitations and a couple of ways to do it which are explained in the [Data Design and Migration](./07_best-practices/04_data-design-and-migration.md) section. ## eosio-cpp process never completes From a2619dde703d71067836b28a8be4459d3d8419bc Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 9 Jun 2021 13:32:50 +0300 Subject: [PATCH 139/204] updates based on peer review updates based on peer review --- docs/03_command-reference/eosio-cpp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03_command-reference/eosio-cpp.md b/docs/03_command-reference/eosio-cpp.md index 2437208f33..c424b03bc3 100644 --- a/docs/03_command-reference/eosio-cpp.md +++ b/docs/03_command-reference/eosio-cpp.md @@ -76,4 +76,4 @@ compiler options: ## Notes -* -no-missing-ricardian-clause: Defaults to false, if enabled, it suppresses warnings for missing Ricardian clauses on contracts and contract actions. That includes the warnings generated when there is also no independent Ricardian clause file. +* `-no-missing-ricardian-clause`: Defaults to false, if enabled, it suppresses warnings for missing Ricardian clauses on contracts and contract actions. That includes the warnings generated when there is no independent Ricardian clause file. From 3cff6291cd4739ca581223939d5c089068f64492 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 9 Jun 2021 13:44:57 +0300 Subject: [PATCH 140/204] add callout for secondary indexes when table already exists. --- .../40_multi-index/how-to-define-a-secondary-index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index 24d4fbf734..99e3834d3b 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -118,6 +118,10 @@ Now you have instantiated the `testtab` as a multi-index table which has a prima [[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). +[[warning | Do not add a secondary index to an existing table]] +| Adding a secondary index to an existing multi-index table it will have unpredictable outcome. Consult the [Data design and migration](../best-practices/data-design-and-migration) documentation for more details. + + ## Summary In conclusion, the above instructions show how to define a secondary index for a multi-index table. From 4742be8f94dd365f6a48e58d8208d42f296eb264 Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 9 Jun 2021 14:46:39 +0300 Subject: [PATCH 141/204] Update eosio-cpp.md --- docs/03_command-reference/eosio-cpp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03_command-reference/eosio-cpp.md b/docs/03_command-reference/eosio-cpp.md index 2437208f33..c424b03bc3 100644 --- a/docs/03_command-reference/eosio-cpp.md +++ b/docs/03_command-reference/eosio-cpp.md @@ -76,4 +76,4 @@ compiler options: ## Notes -* -no-missing-ricardian-clause: Defaults to false, if enabled, it suppresses warnings for missing Ricardian clauses on contracts and contract actions. That includes the warnings generated when there is also no independent Ricardian clause file. +* `-no-missing-ricardian-clause`: Defaults to false, if enabled, it suppresses warnings for missing Ricardian clauses on contracts and contract actions. That includes the warnings generated when there is no independent Ricardian clause file. From 5ce3c2a75f9ef16b9093055c04c421d3a29830db Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 16 Jun 2021 10:37:58 +0300 Subject: [PATCH 142/204] updates based on peer review feedback --- .../04_data-design-and-migration.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/05_best-practices/04_data-design-and-migration.md b/docs/05_best-practices/04_data-design-and-migration.md index 5df43da26a..3f443073db 100644 --- a/docs/05_best-practices/04_data-design-and-migration.md +++ b/docs/05_best-practices/04_data-design-and-migration.md @@ -2,15 +2,16 @@ content_title: Data design and migration --- -EOSIO based blockchains allow developers to easily update their smart contract code. However, a few things need to be considered when it comes to data updates and/or migration. The multi-index table API is one of the mechanisms (Key-Value API being the other) for storing and updating blockchain state. The multi-index table API creates and uses data structures in RAM. Once created and deployed on the blockchian, changing these structures, i.e. adding new fields, it has some limitations. Below you will find a few possible approaches which you can consider when you design your smart contract data and its migration. +EOSIO based blockchains allow developers to easily update their smart contract code. However, a few things need to be considered when it comes to data updates and/or migration. The multi-index table API is one of the mechanisms (Key-Value API being the other) for storing and updating blockchain state. The multi-index table API creates and uses data structures in RAM. Once created and deployed on the blockchain there are limitations if you want to update these structures. Below you will find a few approaches to your smart contract data design, updates to this design, and for data migration. # How to modify a data structure defined using multi-index table API -Modifying a multi-index table structure that has already been deployed to an EOSIO-based blockchain may be done by selecting one of the different strategies outlined below, depending on your requirements: +Modifying a deployed multi-index table structure may be done by selecting one of the different strategies outlined below: ## 1. If you don't mind losing the existing data If you don't mind losing the data from the initial table you can follow these two steps: + 1. Erase all records from first table 2. Deploy a new contract with modified table structure @@ -18,17 +19,19 @@ If you don't mind losing the data from the initial table you can follow these tw If you want to keep the existing data there are two ways to do it: -### 2.1. Using binary extentions +### 2.1. Using binary extensions + To learn how to modify the structure using binary extensions read this [tutorial](../09_tutorials/01_binary-extension.md). ### 2.2. Using ABI variants + To learn how to modify the structure using ABI variants read this [tutorial](../09_tutorials/02_abi-variants.md). ### 2.3. Migrate the existing data to a second table #### 2.3.1. Migration without downtime, but slower -1. Create the new version of your multi-index table alongside the old one; +1. Create the new version of your multi-index table alongside the old one. 2. Transfer data from the old table to the new one. You may do so as part of your normal access pattern, first checking the new table to see if the entry you seek is present and if not, check the original table, and if it's present, migrate it while adding the data for the new field, then remove it from the original table to save RAM costs. 3. You must retain both versions of your multi-index table until you have completed this migration, at which point you may update your contract to remove the original version of your multi-index table. @@ -36,7 +39,7 @@ To learn how to modify the structure using ABI variants read this [tutorial](../ If you prefer less code complexity and can accept downtime for your application: -1. Deploy a version of your contract solely for migration purposes, and run migration transactions on every row of your table until complete. If the first table is big, e.g. has a large number of rows, the transaction time limit could be reached while running the migration transactions. To mitigate this implement the migrate function to move a limited number of rows each time it runs; +1. Deploy a version of your contract solely for migration purposes, and run migration transactions on every row of your table until complete. If the first table is big, e.g. has a large number of rows, the transaction time limit could be reached while running the migration transactions. To mitigate this implement the migrate function to move a limited number of rows each time it runs. 2. Deploy a new contract using only the new version of the table, at which point, your migration and downtime is complete. [[caution]] From 4a7a7398b7d061829a261ef9ba7086def8906f54 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 17 Jun 2021 18:20:44 +0300 Subject: [PATCH 143/204] updates based on peer review (Philip) --- .../01_compile-a-contract-via-cli.md | 2 +- .../30_key-value-api/index.md | 2 +- .../kv_table/10_how-to-use-kv-table.md | 2 +- .../20_how-to-create-indexes-kv-table.md | 30 +++++++++---------- .../30_how-to-upsert-into-kv-table.md | 2 +- .../40_how-to-delete-from-kv-table.md | 2 +- .../kv_table/50_how-to-iterate-kv-table.md | 2 +- .../60_how-to-check-a-record-kv-table.md | 2 +- .../kv_table/70_how-to-find-in-kv-table.md | 2 +- .../80_how-to-query-range-in-kv-table.md | 4 +-- .../90_how-to-allow-users-to-pay-kv-table.md | 2 +- .../30_key-value-api/kv_table/index.md | 10 +++---- .../how-to-define-a-primary-index.md | 6 ++-- .../how-to-define-a-secondary-index.md | 2 +- .../how-to-define-a-singleton.md | 2 +- ...to-delete-data-from-a-multi-index-table.md | 4 +-- ...to-insert-data-into-a-multi-index-table.md | 2 +- .../how-to-instantiate-a-multi-index-table.md | 6 ++-- ...ti_index-table-based-on-secondary-index.md | 4 +-- ...terate-and-retrieve-a-multi_index-table.md | 4 +-- ...w-to-modify-data-in-a-multi-index-table.md | 6 ++-- ...0_how-to-create-and-use-action-wrappers.md | 4 +-- docs/08_troubleshooting.md | 4 +-- docs/09_tutorials/02_abi-variants.md | 5 ++-- 24 files changed, 56 insertions(+), 55 deletions(-) diff --git a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md index ce8d2d62e2..f17b2693db 100644 --- a/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md +++ b/docs/06_how-to-guides/10_compile/01_compile-a-contract-via-cli.md @@ -36,7 +36,7 @@ Follow the following steps to compile your contract. - `-abigen` = It instructs the `eosio-cpp` tool to generate ABI file. - `../src/hello.cpp` = Is the input cpp source file to be compiled. - `-o hello.wasm` = It instructs the `eosio-cpp` tool who to name the output wasm file. - - `-I ../include/` = It tells `eosio-cpp` tool what the include folder path is, in this particular case it is relative path. + - `-I ../include/` = It tells `eosio-cpp` tool what the include folder path is, in this particular case it is a relative path. 3. Verify the following two files were generated: diff --git a/docs/06_how-to-guides/30_key-value-api/index.md b/docs/06_how-to-guides/30_key-value-api/index.md index ad16996214..561c0bf465 100644 --- a/docs/06_how-to-guides/30_key-value-api/index.md +++ b/docs/06_how-to-guides/30_key-value-api/index.md @@ -12,7 +12,7 @@ The Key-Value API provides a set of C++ classes and structures which facilitates ## Concept -The Key-Value API, or KV API, is a new option for developers to create datastore key value tables on-chain. KV API is more flexible than multi-index and allows developers to search the table in a more human-readable way, unlike multi-index tables where search is over 64-bit values. +The Key-Value API, or KV API, is a new option for developers to create datastore key value tables on-chain. KV API is more flexible than multi-index and allows developers to search for the table in a more human-readable way, unlike multi-index tables where search is over 64-bit values. On top of flexibility, this new API has a simpler interface and it helps the developer to avoid complex C++ templates constructs. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index f432ce617f..148293ec67 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -48,7 +48,7 @@ Complete the following steps to define the `address_table` type, based on the `e 1. Define the structure or class `address_table` in the scope of your smart contract class, for the abi generation to find it and place it into the abi file. 2. Derive `address_table` from `eosio::`kv::table` class template. Pass the `person` user defined type as the type parameter for `eosio::`kv::table` base class and the name of the `kv table`, let’s say `kvaddrbook`. 3. Annotate `address_table` type with `[[eosio::table]]`, and make sure it is placed after the `struct` keyword but before the name of the type. -4. Define a primary index `first_name_idx` based on the data member `person::first_name`. Every `kv table` requires a primary index to be defined based on a data member that stores unique values. +4. Define a primary index `first_name_idx` based on the data member `person::first_name`. Every `kv table` requires a primary index to be defined on a data member that stores unique values. 5. In the `address_table` constructor, call the `init(...)` base class method with the two parameters: 1. The first parameter, of type `eosio::name`, is the contract that owns the table. 2. The second parameter is the `account_name_uidx` primary index. diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index c663cafbb2..d31b839f3a 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -54,14 +54,14 @@ class [[eosio::contract]] smrtcontract : public contract { ## Procedure -### Define a unique index on data member account_name using the macro KV_NAMED_INDEX +### Define a unique index on the data member account_name using the macro KV_NAMED_INDEX 1. Use the `KV_NAMED_INDEX` macro with two parameters. -2. The first parameter is the name of the index and it must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +2. The first parameter is the name of the index and must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. The second parameter is the name of the data member the index is defined for. -4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and `account_name` index, by the KV_NAMED_INDEX macro, as the second parameter. +4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `account_name` index, using the KV_NAMED_INDEX macro, as the second parameter. -Refer to the following reference implementation of a unique index on data member `account_name` using macro `KV_NAMED_INDEX`: +Refer to the following reference implementation of a unique index on `account_name` data member using macro `KV_NAMED_INDEX`: `smartcontract.hpp file` @@ -80,14 +80,14 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -### Define a unique index on data member personal_id using the eosio::kv::table::index template class +### Define a unique index on the data member personal_id using the eosio::kv::table::index template class 1. Use the `eosio::kv::table::index` template class with two parameters. -2. The first parameter is the name of the index and it must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the reference to the data member for which the index is defined, `&person::personal_id`. +2. The first parameter is the name of the index and must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +3. The second parameter is the name of the data member the index is defined for. 4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `personal_id_idx` index as the second parameter. -Refer to the following reference implementation of a unique index on data member `personal_id` using `eosio::kv::table::index` template class: +Refer to the following reference implementation of a unique index on `personal_id` data member using `eosio::kv::table::index` template class: `smartcontract.hpp file` @@ -108,16 +108,16 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -### Define a non-unique index on data member first_name using the macro KV_NAMED_INDEX +### Define a non-unique index on the data member first_name using the macro KV_NAMED_INDEX 1. Use the `KV_NAMED_INDEX` with two parameters. -2. The first parameter is the name of the index and it must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +2. The first parameter is the name of the index and must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. The second parameter is the name of the data member the index is defined for. 4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and `first_name` index, by the KV_NAMED_INDEX macro, as the second parameter. The second parameter is the name of the data member the index is defined for and the type of this data member must be `std::tuple<>`. The first parameter of the tuple must be the type of the data member indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple type must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. -Refer to the following reference implementation of a non-unique index on data member `account_name` using macro `KV_NAMED_INDEX`: +Refer to the following reference implementation of a non-unique index on `account_name` data member using macro `KV_NAMED_INDEX`: `smartcontract.hpp file` @@ -143,16 +143,16 @@ class [[eosio::contract]] smrtcontract : public contract { }; ``` -### Define a non-unique index on data member last_name using the eosio::kv::table::index template class +### Define a non-unique index on the data member last_name using the eosio::kv::table::index template class 1. Use the `eosio::kv::table::index` template class. -2. The first parameter is the name of the index and it must be a qualified `eosio:name`, see documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the name of the data member the index is defined for, `&person::last_name`. +2. The first parameter is the name of the index and must be a qualified `eosio:name`, see documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). +3. The second parameter is the name of the data member the index is defined for. 4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `last_name_idx` index as the second parameter. The data member used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the data member indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple type must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. -Refer to the following reference implementation of a non-unique index on data member `last_name` using `eosio::kv::table::index` template class: +Refer to the following reference implementation of a non-unique index `last_name` data member using `eosio::kv::table::index` template class: `smartcontract.hpp file` diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index 79ecc404a4..b02c467df8 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -19,7 +19,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` darta member. +* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` data member. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index a6810bb9c6..8acb591de4 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -19,7 +19,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` darta member. +* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` data member. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index edf0bb9a42..71b38349db 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -25,7 +25,7 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index c709fed1e3..c081100c2e 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -25,7 +25,7 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index 0f90a16873..b3735825bb 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -25,7 +25,7 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index 4dbb31e095..68da4bafa6 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -25,8 +25,8 @@ Make sure you have the following prerequisites in place: * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` darta member.. -* A non-unique index defined on the `last_name` darta member, named `last_name_idx`. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. +* A non-unique index defined on the `last_name` data member, named `last_name_idx`. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index a4c4427dd7..0fc888c3f4 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -19,7 +19,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` * A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` darta member. +* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` data member. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/index.md b/docs/06_how-to-guides/30_key-value-api/kv_table/index.md index 666596e59a..58f41fd334 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/index.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/index.md @@ -5,12 +5,12 @@ link_text: "Key-Value Table" #### KV Table -A `datastore key value table on-chain`, or a `KV Table`, serves as a storage location which is organized as a table of rows where each row stores objects with the same definition. +A `datastore key value table on-chain`, or a `KV Table`, serves as a storage location which is organized as a table of rows and columns where each row stores objects with the same definition. [[caution | Alpha version]] | `Key-Value Table` is designated as `alpha` and should not be used in production code. -The `object definition` consists of a list of `properties` and each data member is stored on the corresponding row in the table. The properties of the objects are also referred to as `fields`. +The `object definition` consists of a list of `data members`. One object is stored on one row in the table, which each `data member` stored in one column. The data members of the objects are also referred to as `fields`. A `KV Table` requires one unique index, of any type, that can be serialized to a binary representation. @@ -18,11 +18,11 @@ A `KV Table` supports zero or more secondary indexes, of any type, that can be s Two types of indexes can be defined, unique or non-unique. -A unique index can be defined just for one darta member, and it will sort the objects stored in the `KV Table` based on the `specified darta member`. The unique index also ensures only one instance of an object is stored with a particular value for the `specified darta member`, and thus ensures the uniqueness of the data member for which it is defined. +A unique index can be defined just for one data member, and it will sort the objects stored in the `KV Table` based on the `specified data member`. The unique index also ensures only one instance of an object is stored with a particular value for the `specified data member`, and thus ensures the uniqueness of the data member for which it is defined. -A non-unique index can be defined for one or multiple properties, and it will sort the objects stored in the `KV Table` based on the `specified darta member` or the combination of the `specified properties`. Very important though, a non-unique index requires as the last data member of its definition a data member which has unique values. Therefore although the non-unique index is intended for just one darta member, its definition will have two properties specified: +A non-unique index can be defined for one or multiple data members, and it will sort the objects stored in the `KV Table` based on the `specified data member` or the combination of the `specified data members`. Very important though, a non-unique index requires as the last data member of its definition a data member which has unique values. Therefore although the non-unique index is intended for just one data member, its definition will have two properties specified: -1. the first darta member, the one for which the non-unique index is built, +1. the first data member, the one for which the non-unique index is built, 2. and the last data member which must have unique values. The main operations provided by the KV API are the following: diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md index 26d28a10d1..cc84cbbc05 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-primary-index.md @@ -40,7 +40,7 @@ Define the data structure for the multi-index table. }; ``` -Add to the data structure the properties which define it. Each data member corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding data member for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. +Add the data structure data members. Each data member corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding data member for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. ```diff // the data structure which defines each row of the table @@ -54,7 +54,7 @@ Add to the data structure the properties which define it. Each data member corre ### 3. Define The Primary Index -Add definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and it must be named `primary_key()`, otherwise the compiler (eosio-cpp) will generate an error saying it can not find the field to use as the primary key: +Add the definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and must be named `primary_key()`, otherwise the compiler (eosio-cpp) will generate an error saying it can not find the field to use as the primary key: ```diff // the data structure which defines each row of the table @@ -113,7 +113,7 @@ Declare the `testtab` multi-index table as a data member of type `test_table_t`. + test_table_t testtab; ``` -Now you have instantiated the `testtab` as a multi-index table which has a primary index defined for its `test_primary` data member. +Now you have instantiated a multi-index table, and assigned to `testtab` variable, which has a primary index defined for its `test_primary` data member. [[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md index 99e3834d3b..68dea63de0 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-secondary-index.md @@ -41,7 +41,7 @@ Add a second data member `secondary`, of type `eosio::name`, to the `test_table` ### 2. Add The Secondary Index Accessor Method -Add `by_secondary()` method, which is the index accessor method to the new data member added. The secondary index, that will be added in the next step, will index this new data structure darta member. +Add `by_secondary()` method, which is the index accessor method to the new data member added. The secondary index, that will be added in the next step, will index this new data structure data member. ```diff struct [[eosio::table]] test_table { diff --git a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md index de19477f3e..e57cebe0a0 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-define-a-singleton.md @@ -118,7 +118,7 @@ class [[eosio::contract]] singleton_example : public contract { }; ``` -Find below a possible implementation for the two `get` and `set` actions. It also demonstrates the usage of the `get` and `set` singleton methods. Note that the `set` action makes use of the singleton's `set` method, for which the second parameter is the payer account for the RAM needed to store the new value. +Below is an example for the `get` and `set` actions. It also demonstrates the usage of the `get` and `set` singleton methods. Note that the `set` action makes use of the singleton's `set` method, for which the second parameter is the payer account for the RAM needed to store the new value. __singleton_example.cpp__ diff --git a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md index f3cecb6cf6..80db74dcee 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-delete-data-from-a-multi-index-table.md @@ -27,7 +27,7 @@ Complete the following steps to implement a `del` action which deletes an user o ### 1. Find The User You Want To Delete -Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to delete. The targeted user is searched based on its account name. +Use the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to delete. The targeted user is searched based on its account name. ```cpp [[eosio::action]] void multi_index_example::del( name user ) { @@ -38,7 +38,7 @@ Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) ### 2. Delete The User If Found -If the user exists use the [`erase`(...)](../../group__multiindex/#function-erase) method to delete the row from table. Otherwise print an informational message and return. +Check to see if the user exists and use [`erase`(...)](../../group__multiindex/#function-erase) method to delete the row from table. Otherwise print an informational message and return. ```diff [[eosio::action]] void multi_index_example::del( name user ) { diff --git a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md index c12a7e17ec..f2c8537692 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-insert-data-into-a-multi-index-table.md @@ -27,7 +27,7 @@ Complete the following steps to insert an user object in the `testtab` multi-ind ### 1. Verify If The User Already Exists -Make use of the multi-index table iterator to find out if the user object already exists. The targeted user is searched based on its account name. +Use of the multi-index table iterator to find out if the user object already exists. The targeted user is searched based on its account name. ```cpp [[eosio::action]] void multi_index_example::set( name user ) { diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index ea04fbcf7e..6ef6751c98 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -40,7 +40,7 @@ Define the data structure for the multi-index table. }; ``` -Add to the data structure the properties which define it. Each data member corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding data member for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. +Add the data structure data members. Each data member corresponds to a field of the multi-index table. A primary key is required when defining a multi-index table structure, therefore you need to know which is the multi-index table field that is the primary key for your multi-index table. The corresponding data member for the primary key field must store unique values. In this case it is the `test_primary` data member of type `eosio::name`. ```diff // the data structure which defines each row of the table @@ -54,7 +54,7 @@ Add to the data structure the properties which define it. Each data member corre ### 3. Define The Primary Index -Add definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and it must be named `primary_key()`, otherwise the compiler (eosio-cpp) will generate an error saying it can not find the field to use as the primary key: +Add the definition of the primary index for the multi-index table. The primary index type must be uint64_t, it must be unique and must be named `primary_key()`, otherwise the compiler (eosio-cpp) will generate an error saying it can not find the field to use as the primary key: ```diff // the data structure which defines each row of the table @@ -122,7 +122,7 @@ multi_index_example( name receiver, name code, datastream ds ) : { } ``` -Now you have instantiated the `testtab` variable as a multi-index table which has a primary index defined for its `test_primary` data member. +Now you have instantiated a multi-index table, and assigned to `testtab` variable, which has a primary index defined for its `test_primary` data member. Here is how the definition of a `multi_index_example` contract containing a multi-index table could look like after following all the steps above. diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md index fbf9916e54..c4205a1cbe 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table-based-on-secondary-index.md @@ -26,7 +26,7 @@ Complete the following steps to iterate, retrieve and print data from the `testt ### 1. Define The bysec(...) Action -Add to the definition of the multi-index table the `bysec` action which gets as parameter an account name. This will be the action which will retrieve the user object stored in the multi-index based on the name input parameter using the secondary index. +Add an action to the definition of the multi-index table which takes as parameter an account name. This action will retrieve the user object stored in the multi-index based on the passed in account name parameter. The action will use the secondary index. ```cpp [[eosio::action]] void bysec( name secid ); @@ -42,7 +42,7 @@ Optionally, for ease of use add the action wrapper definition as well. ### 2. Implement The `bysec(...)` Action -Search the `user` name in the multi-index table using the secondary index. If found, print out the value of field `datum`. Otherwise raise and error with a custom message. In the contract definition add the following implementation for `print` action: +Search for the `user` name in the multi-index table using the secondary index. If found, print out the value of field `datum`. Otherwise raise and error with a custom message. In the contract definition add the following implementation for `print` action: ```cpp // iterates the multi-index table rows using the secondary index and prints the row's values diff --git a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md index 2f277101b7..e821261c42 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-iterate-and-retrieve-a-multi_index-table.md @@ -26,7 +26,7 @@ Complete the following steps to iterate, retrieve and print data from the `testt ### 1. Define The print(...) Action -Add to the definition of the `testtab` multi-index table the `print` action which gets as parameter an account name. +Add a `print` action to the `testtab` multi-index table. The `print` action takes an account name as a parameter. ```cpp [[eosio::action]] void print( name user ); @@ -42,7 +42,7 @@ Optionally, for ease of use add the action wrapper definition as well. ### 2. Implement The `print(...)` Action -Search the `user` name in the multi-index table using the primary index. If found, print out the value of field `datum`. Otherwise raise an error with a custom message. In the contract definition add the following implementation for `print` action: +Search for the `user` name in the multi-index table using the primary index. If found, print out the value of field `datum`. Otherwise raise an error with a custom message. In the contract definition add the following implementation for `print` action: ```cpp [[eosio::action]] void multi_index_example::print( name user ) { diff --git a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md index 5ffe27b514..496a841ec6 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-modify-data-in-a-multi-index-table.md @@ -26,7 +26,7 @@ Complete the following steps to modify data in the `testtab` multi-index table. ### 1. Define The mod(...) Action -Add to the definition of the `testtab` multi-index table the `mod` action which gets as input parameters a `user` of type `eosio::name` and a `value` of type `uint32_t`. The `mod` action will update the `user` object `datum` data member with the `uint32_t` value. +Add a `mod` action to the `testtab` multi-index table. The `mod` action takes as input parameters a `user` of type `eosio::name` and a `value` of type `uint32_t`. The `mod` action updates the `user` object `datum` data member with the `uint32_t` value. ```cpp [[eosio::action]] void mod( name user, uint32_t value ); @@ -42,7 +42,7 @@ Optionally, for ease of use add the action wrapper definition as well. ### 2. Find The User You Want To Modify -Make use of the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to modify. The targeted user is searched based on its account name. +Use the multi-index [`find(...)`](../../group__multiindex#function-find) method to locate the user object you want to modify. The targeted user is searched based on its account name. ```cpp [[eosio::action]] void multi_index_example::mod( name user, uint32_t value ) { @@ -77,7 +77,7 @@ If the `user` object you want to update is found, the [`eosio::check`](../../nam } ``` -Now you have implemented a new action `mod`, which when sent to the blockchain will update the `datum` data member for user object identified by `user` name with the `value` sent as parameter. +Now you have implemented a new action `mod`. Call `mod` to update the `datum` data member for the user object identified by the `user` name parameter. [[info | Full example location]] | A full example project demonstrating the instantiation and usage of multi-index table can be found [here](https://github.com/EOSIO/eosio.cdt/tree/master/examples/multi_index_example). diff --git a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md index 915d3c5f64..ddd97794b8 100644 --- a/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md +++ b/docs/06_how-to-guides/50_how-to-create-and-use-action-wrappers.md @@ -43,7 +43,7 @@ Complete the following steps to create and use `mod_action` action wrapper for t ### 1. Define The Action Wrapper -To define an action wrapper for the `mod` action, make use of the `eosio::action_wrapper` template, with the first parameter the action name as a `eosio::name` and second parameter as the reference to the action method: +To define an action wrapper for the `mod` action, use the `eosio::action_wrapper` template, with the first parameter the action name as a `eosio::name` and second parameter as the reference to the action method: ```diff class [[eosio::contract]] multi_index_example : public contract { @@ -67,7 +67,7 @@ To use the action wrapper, you have to include the header file where the action #### 2.2. Instantiate The Action Wrapper -Instantiate the `mod_action`, specifying the contract to send the action to as the first argument. In this case, it is assumed the contract is deployed to `multiindexex` account, and a structure which is defined by two parameters: the self account, obtained by `get_self()` call, and the `active` permission (you can modify these two parameters based on your requirements). +Instantiate the `mod_action`. Specify the contract to send the action to as the first argument. In this case, it is assumed the contract is deployed to `multiindexex` account. Specify a structure with two parameters: the self account, obtained by `get_self()` call, and the `active` permission (you can modify these two parameters based on your requirements). ```diff #include diff --git a/docs/08_troubleshooting.md b/docs/08_troubleshooting.md index 52e592dd59..42c0300eda 100644 --- a/docs/08_troubleshooting.md +++ b/docs/08_troubleshooting.md @@ -61,9 +61,9 @@ Error 3160009: No wasm file found __Possible solution__: Verify that `abi` and `wasm` files exist in the directory specified in the `cleos set contract` command, and that their names match the directory name. -## Action triggers ram charge which cannot be initiated from a notification. +## Action triggers a ram charge which cannot be initiated from a notification -__Possible solution__: The reason for this error is because the notification action doesn't have authorization to buy the needed RAM. In the context of multi-index tables, there’s a table payer and a row payer. Only the contract can modify rows. The contract can create rows with a payer that didn’t authorize the action if the total amount of ram charged that payer doesn’t increase (e.g. delete a row and add another with the same payer). The table payer can’t change until the last row is deleted. For the purposes of billing, a table is identified by the tuple `contract, scope, table`. When you create a row for a `contract, scope, table` tuple that doesn’t exist, you create a table with the same payer. This can outlive the original row which created it, if other rows were created with that combination and this prevents the original payer from getting their ram back. Secondary indexes throw in more complexity since they use the lower 4 bits of the table name, producing additional `contract, scope, table` tuples combinations. Key takeaway: payer is about billing, not access control +__Possible solution__: This error happens because the notification action has no authorization to buy the needed RAM. In the context of multi-index tables, there is a table payer and a row payer. Only the contract can modify rows. The contract can create rows with a payer that did not authorize the action if the total amount of ram charged does not increase (e.g. delete a row and add another with the same payer). The table payer can not change until the last row is deleted. For the purposes of billing, a table is identified by the tuple `contract, scope, table`. When you create a row for a `contract, scope, table` tuple that doesn’t exist, you create a table with the same payer. This can outlive the original row which created it, if other rows were created with that combination and this prevents the original payer from getting their ram back. Secondary indexes throw in more complexity since they use the lower 4 bits of the table name, producing additional `contract, scope, table` tuples combinations. Key takeaway: payer is about billing, not access control ## You successfully re-deployed the contract code, but when you query the table you get the custom message that you coded when the table is not initialized (doesn't exist), or the system error message below in case you do not have code that checks first if table exist diff --git a/docs/09_tutorials/02_abi-variants.md b/docs/09_tutorials/02_abi-variants.md index 558630b0dc..d085b2dcaf 100644 --- a/docs/09_tutorials/02_abi-variants.md +++ b/docs/09_tutorials/02_abi-variants.md @@ -3,8 +3,9 @@ content_title: ABI variants link_text: ABI variants --- -ABI variants give the flexibility of using more than one type for a defined variable or data member. -In EOSIO, the variants make use of the standard template library `variant` which was introduced in C++ 17. An instance of `std::variant` at any given time either holds a value of one of its alternative types, or in the case of error - no value. Because of this trait, variants can be used to build the multi-index table structure with flexibility. Used in conjunction with ABI extensions, it allows for modification of the structure of an exiting multi-index table, a.k.a. table. +ABI variants give the flexibility of using more than one type for a defined variable or data member. + +In EOSIO, the variants use the standard template library `variant` which was introduced in C++ 17. An instance of `std::variant` at any given time either holds a value of one of its alternative types, or in the case of error - no value. Because of this trait, variants can be used to build the multi-index table structure with flexibility. Used in conjunction with ABI extensions, it allows for modification of the structure of an existing multi-index table, a.k.a. table. ## Use variant when building the multi-index table the first time From 814ddecf3131a39e5c61a04147ae893ae3b446df Mon Sep 17 00:00:00 2001 From: Philip Halsall Date: Mon, 21 Jun 2021 10:58:06 +0800 Subject: [PATCH 144/204] adding read-only queries --- docs/03_command-reference/eosio-cc.md | 1 + docs/03_command-reference/eosio-cpp.md | 1 + ...abi-code-generator-attributes-explained.md | 21 +++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/docs/03_command-reference/eosio-cc.md b/docs/03_command-reference/eosio-cc.md index 11b08050d3..a1c35daea4 100644 --- a/docs/03_command-reference/eosio-cc.md +++ b/docs/03_command-reference/eosio-cc.md @@ -71,4 +71,5 @@ compiler options: -sysroot= - Set the system root directory -v - Show commands to run and use verbose output -w - Suppress all warnings + --warn-action-read-only - Issue a warning if a read-only action uses a write API and continue compilation ``` diff --git a/docs/03_command-reference/eosio-cpp.md b/docs/03_command-reference/eosio-cpp.md index c424b03bc3..5bac526d02 100644 --- a/docs/03_command-reference/eosio-cpp.md +++ b/docs/03_command-reference/eosio-cpp.md @@ -72,6 +72,7 @@ compiler options: -v - Show commands to run and use verbose output -w - Suppress all warnings -no-missing-ricardian-clause - Defaults to false, disables warnings for missing Ricardian clauses + --warn-action-read-only - Issue a warning if a read-only action uses a write API and continue compilation ``` ## Notes diff --git a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md index f4931df137..5d1e726b1f 100644 --- a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md +++ b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md @@ -93,3 +93,24 @@ extern "C" { The code above will mark a function declaration as being a WebAssembly import. This allows for other compilation modes to specify which functions are import only (i.e. do not link) without having to maintain a secondary file with duplicate declarations. +## [[eosio::action, eosio::read-only]] +The `read-only` attribute marks a method which has been defined as an action as a read-only action. + +Example: + +```cpp +[[eosio::action, eosio::read-only]] +std::vector get() { + std::vector ret; + // retrieve blockchain state and populate the ret vector + return ret; +} +``` + +Contract actions tagged read-only: +* Cannot call insert/update (write) functions on the `Multi-Index API`, nor the `Key Value API`. +* Cannot call `deferred transactions`. +* Cannot call `inline actions`. +* The returned data size is limited by the action return value sizes. By default these are set to 256 bytes by `default_max_action_return_value_size`. + +The `eosio-cpp` and `eosio-cc` tools will generate an error and terminate compilation if an action tagged read-only attempts to use a write API. However, if the command-line override option `--warn-action-read-only` is used, the `eosio-cpp` and `eosio-cc` tools will issue a warning and continue compilation. From 76ff5ccc96607cb5b7020f9077add8522da9565b Mon Sep 17 00:00:00 2001 From: ovi Date: Mon, 21 Jun 2021 13:07:52 +0300 Subject: [PATCH 145/204] update the cleos support update the cleos support which will be added in RC2 --- docs/05_features/10_trx_sponsorship.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/05_features/10_trx_sponsorship.md b/docs/05_features/10_trx_sponsorship.md index 4d00e7fec4..0e0cdc764c 100644 --- a/docs/05_features/10_trx_sponsorship.md +++ b/docs/05_features/10_trx_sponsorship.md @@ -36,6 +36,11 @@ The sponsorship information must be defined as a transaction extension and place Below are two examples that illustrate how to send a sponsored transaction to the blockchain. -* To send a transaction to the blockchain using `cleos` tool, follow the [How To Send A Sponsored Transaction](https://developers.eos.io/manuals/eosjs/latest/how-to-guides/how-to-submit-a-sponsored-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. \ +### EOSJS -* To send a transaction to the blockchain using javascript via the `eosjs` library, follow the [How To Send A Transaction](https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-submit-a-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. +To send a transaction to the blockchain using javascript via the `eosjs` library, follow the [How To Send A Transaction](https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-submit-a-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. + +### Cleos + +[[warning | Cleos Support Will Be Available Starting With v2.2 RC2 Onwards]] +| The ability to send transaction sponsorship information using `cleos` will be added in the next v2.2 RC2 release. From 02d5404b326702093e3928a8fe371943b8604d35 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Tue, 22 Jun 2021 15:58:52 -0400 Subject: [PATCH 146/204] Add brew updater step. --- .cicd/pipeline.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index c0df6e5efc..8c7155c792 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -518,6 +518,19 @@ steps: queue: "automation-eks-eos-tester-fleet" timeout: 10 + - label: ":beer: Brew Updater" + command: | + buildkite-agent artifact download eosio.cdt.rb . --step ':darwin: Mojave - Package Builder' + mv eosio.cdt.rb eosio_cdt_mojave.rb + buildkite-agent artifact upload eosio_cdt_mojave.rb + buildkite-agent artifact download eosio.cdt.rb . --step ':darwin: Catalina - Package Builder' + mv eosio.cdt.rb eosio_cdt_catalina.rb + buildkite-agent artifact upload eosio_cdt_catalina.rb + agents: + queue: "automation-basic-builder-fleet" + timeout: "${TIMEOUT:-5}" + skip: ${SKIP_MACOS_10_14}${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} + - label: ":git: Git Submodule Regression Check" command: - "./.cicd/submodule-regression-checker.sh" From 84d0eab5e73fd395a155f18b21fb061d64131744 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Tue, 22 Jun 2021 17:36:52 -0400 Subject: [PATCH 147/204] Add brew updater step. --- .cicd/pipeline.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index c0df6e5efc..8c7155c792 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -518,6 +518,19 @@ steps: queue: "automation-eks-eos-tester-fleet" timeout: 10 + - label: ":beer: Brew Updater" + command: | + buildkite-agent artifact download eosio.cdt.rb . --step ':darwin: Mojave - Package Builder' + mv eosio.cdt.rb eosio_cdt_mojave.rb + buildkite-agent artifact upload eosio_cdt_mojave.rb + buildkite-agent artifact download eosio.cdt.rb . --step ':darwin: Catalina - Package Builder' + mv eosio.cdt.rb eosio_cdt_catalina.rb + buildkite-agent artifact upload eosio_cdt_catalina.rb + agents: + queue: "automation-basic-builder-fleet" + timeout: "${TIMEOUT:-5}" + skip: ${SKIP_MACOS_10_14}${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} + - label: ":git: Git Submodule Regression Check" command: - "./.cicd/submodule-regression-checker.sh" From cd6cc1e1954b3c743dafc7ca980aa4f83dc8f84b Mon Sep 17 00:00:00 2001 From: William Blevins Date: Tue, 22 Jun 2021 18:05:30 -0400 Subject: [PATCH 148/204] Unit tests can run on lighter node pool. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 8c7155c792..a12340cb27 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -210,7 +210,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_14}${SKIP_UNIT_TESTS} - label: ":darwin: macOS 10.15 - Unit Tests" @@ -234,7 +234,7 @@ steps: debug: true wait-network: true agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_15}${SKIP_UNIT_TESTS} - label: ":aws: Amazon_Linux 2 - Toolchain Tests" From af4ef2b42f4ce3cd2a7355d255ab5a9eb8038c8d Mon Sep 17 00:00:00 2001 From: William Blevins Date: Tue, 22 Jun 2021 18:08:07 -0400 Subject: [PATCH 149/204] Toolchain tests can likely run on lighter node pool. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index a12340cb27..fced5c396a 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -326,7 +326,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} - label: ":darwin: macOS 10.15 - Toolchain Tests" @@ -352,7 +352,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Integration Tests" From 0b7b43a6fdbec924d9fcca191f28eb75d5fcf8a4 Mon Sep 17 00:00:00 2001 From: Philip Halsall Date: Wed, 23 Jun 2021 11:30:19 +0800 Subject: [PATCH 150/204] updates after pr review --- .../08_abi/01_abi-code-generator-attributes-explained.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md index 5d1e726b1f..ef32de7dfd 100644 --- a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md +++ b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md @@ -111,6 +111,6 @@ Contract actions tagged read-only: * Cannot call insert/update (write) functions on the `Multi-Index API`, nor the `Key Value API`. * Cannot call `deferred transactions`. * Cannot call `inline actions`. -* The returned data size is limited by the action return value sizes. By default these are set to 256 bytes by `default_max_action_return_value_size`. +* The amount of data returned by read-only queries is limited by the action return value size. By default these are set to 256 bytes by `default_max_action_return_value_size`. -The `eosio-cpp` and `eosio-cc` tools will generate an error and terminate compilation if an action tagged read-only attempts to use a write API. However, if the command-line override option `--warn-action-read-only` is used, the `eosio-cpp` and `eosio-cc` tools will issue a warning and continue compilation. +The `eosio-cpp` and `eosio-cc` tools will generate an error and terminate compilation if an action tagged read-only attempts to call insert/update (write) functions. However, if the command-line override option `--warn-action-read-only` is used, the `eosio-cpp` and `eosio-cc` tools will issue a warning and continue compilation when write functions are used. From dd5544e89d42f9dbee635f6b4d26df78eea9f61c Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 23 Jun 2021 13:01:09 +0300 Subject: [PATCH 151/204] last changed based on review from Philip --- .../kv_map/10_how-to-use-kv-map.md | 2 +- .../kv_map/30_how-to-upsert-into-kv-map.md | 2 +- .../kv_map/40_how-to-delete-from-kv-map.md | 2 +- .../kv_map/50_how-to-iterate-kv-map.md | 2 +- .../kv_map/70_how-to-find-in-kv-map.md | 2 +- .../90_how-to-allow-users-to-pay-kv-map.md | 2 +- .../kv_table/10_how-to-use-kv-table.md | 4 +-- .../20_how-to-create-indexes-kv-table.md | 31 ++++++++++--------- .../30_how-to-upsert-into-kv-table.md | 5 +-- .../40_how-to-delete-from-kv-table.md | 5 +-- .../kv_table/50_how-to-iterate-kv-table.md | 12 +++---- .../60_how-to-check-a-record-kv-table.md | 12 +++---- .../kv_table/70_how-to-find-in-kv-table.md | 12 +++---- .../80_how-to-query-range-in-kv-table.md | 14 ++++----- .../90_how-to-allow-users-to-pay-kv-table.md | 5 +-- .../how-to-instantiate-a-multi-index-table.md | 2 +- 16 files changed, 59 insertions(+), 55 deletions(-) diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md index 4ed6a6e98e..3b062c5e4c 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/10_how-to-use-kv-map.md @@ -27,7 +27,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the map +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md index 31e5f5053f..d041e22c90 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/30_how-to-upsert-into-kv-map.md @@ -13,7 +13,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the map +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md index aeb31cc58a..5c8faf29a9 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/40_how-to-delete-from-kv-map.md @@ -13,7 +13,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the map +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int` Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md index 48a6307da9..2b1a5b5284 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/50_how-to-iterate-kv-map.md @@ -13,7 +13,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the map +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md index 2515459ad1..2ecec70ad1 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/70_how-to-find-in-kv-map.md @@ -13,7 +13,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the map +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md index b13cefb3ca..d499ef1d56 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_map/90_how-to-allow-users-to-pay-kv-map.md @@ -11,7 +11,7 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the map +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` * A `kv map` object, name `my_map`, which stores objects of type `person`, with unique keys of type `int`. Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md index 148293ec67..adf20acfca 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/10_how-to-use-kv-table.md @@ -17,8 +17,8 @@ To accomplish this task, define the user type which will be stored in the `kv ta Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). -* A smart contract named `smrtcontract`. -* A user defined type named `person`, which defines the data stored in the table. +* A smart contract named `smrtcontract` +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md index d31b839f3a..9b40bf2216 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/20_how-to-create-indexes-kv-table.md @@ -23,9 +23,9 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type which defines the data stored in the table, named `person` -* A `kv table` type which stores objects of type `person`, named `address_table` -* Each `person` object has the following properties: +* A user defined data type, `struct` or `class`, which defines the data stored in the table, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* Each `person` instance has the following data members: * `account_name`, * `first_name`, * `last_name`, @@ -59,7 +59,8 @@ class [[eosio::contract]] smrtcontract : public contract { 1. Use the `KV_NAMED_INDEX` macro with two parameters. 2. The first parameter is the name of the index and must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. The second parameter is the name of the data member the index is defined for. -4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `account_name` index, using the KV_NAMED_INDEX macro, as the second parameter. +4. Define the constructor of the `address_table` structure. It must have as input parameter the name of the contract, `contract_name`, which owns this table. +5. In the constructor of `address_table` structure call the base class `kv::table::init(...)` method. Pass the `contract_name` as the first parameter and the `account_name` as the second parameter. The `account_name` is the data member for which the index was defined for using the `KV_NAMED_INDEX` macro. Refer to the following reference implementation of a unique index on `account_name` data member using macro `KV_NAMED_INDEX`: @@ -85,7 +86,8 @@ class [[eosio::contract]] smrtcontract : public contract { 1. Use the `eosio::kv::table::index` template class with two parameters. 2. The first parameter is the name of the index and must be a qualified `eosio:name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). 3. The second parameter is the name of the data member the index is defined for. -4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `personal_id_idx` index as the second parameter. +4. Define the constructor of the `address_table` structure. It must have as input parameter the name of the contract, `contract_name`, which owns this table. +5. In the constructor of `address_table` structure call the base class `kv::table::init(...)` method. Pass the `contract_name` as the first parameter and the `personal_id_idx` as the second parameter. The `personal_id_idx` is the index defined previously. Refer to the following reference implementation of a unique index on `personal_id` data member using `eosio::kv::table::index` template class: @@ -112,10 +114,9 @@ class [[eosio::contract]] smrtcontract : public contract { 1. Use the `KV_NAMED_INDEX` with two parameters. 2. The first parameter is the name of the index and must be a qualified `eosio::name`. See documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the name of the data member the index is defined for. -4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and `first_name` index, by the KV_NAMED_INDEX macro, as the second parameter. - -The second parameter is the name of the data member the index is defined for and the type of this data member must be `std::tuple<>`. The first parameter of the tuple must be the type of the data member indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple type must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. +3. The second parameter is the name of the data member the index is defined for. The type of this data member must be `std::tuple<>`. The first parameter of the tuple must be the type of the data member indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple type must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the multiple properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. +4. Define the constructor of the `address_table` structure. It must have as input parameter the name of the contract, `contract_name`, which owns this table. +5. In the constructor of `address_table` structure call the base class `kv::table::init(...)` method. Pass the `contract_name` as the first parameter and the `first_name` as the second parameter. The `first_name` is the data member for which the index was defined for using the `KV_NAMED_INDEX` macro. Refer to the following reference implementation of a non-unique index on `account_name` data member using macro `KV_NAMED_INDEX`: @@ -145,12 +146,11 @@ class [[eosio::contract]] smrtcontract : public contract { ### Define a non-unique index on the data member last_name using the eosio::kv::table::index template class -1. Use the `eosio::kv::table::index` template class. +1. Use the `eosio::kv::table::index` template class with two parameters. 2. The first parameter is the name of the index and must be a qualified `eosio:name`, see documentation for the [eosio name restrictions](https://developers.eos.io/welcome/latest/glossary/index#account-name). -3. The second parameter is the name of the data member the index is defined for. -4. Call the base class method `init()` in the constructor of `address_table` type and pass the contract name as the first parameter and the `last_name_idx` index as the second parameter. - -The data member used for the second parameter must be of template type `std::tuple`. The first parameter must be the type of the data member indexed non-uniquely, in our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple type must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. +3. The second parameter is the name of the data member the index is defined for. The data member used for the second parameter must be of template type `std::tuple`. The first parameter of the tuple must be the type of the data member indexed non-uniquely. In our case the type `std::string` is used because `first_name` is the data member indexed non-uniquely. The last parameter of the tuple must be the type of a data member name which is unique. In our case the type `eosio::name` is used because data member `account_name` is unique. Multiple properties can be indexed non-uniquely as well. In this case the first parameter types correspond to the multiple properties being indexed. As previously already mentioned, the last parameter correspond to the type of a data member name which is unique. +4. Define the constructor of the `address_table` structure. It must have as input parameter the name of the contract, `contract_name`, which owns this table. +5. In the constructor of `address_table` structure call the base class `kv::table::init(...)` method. Pass the `contract_name` as the first parameter and the `last_name_idx` as the second parameter. The `last_name_idx` is the index defined previously. Refer to the following reference implementation of a non-unique index `last_name` data member using `eosio::kv::table::index` template class: @@ -169,7 +169,8 @@ class [[eosio::contract]] smrtcontract : public contract { index> last_name_idx { name{"persid"_n}, - &person::last_name}; + &person::last_name + }; address_table(eosio::name contract_name) { init(contract_name, last_name_idx) diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md index b02c467df8..9a7a5ffdae 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/30_how-to-upsert-into-kv-table.md @@ -18,8 +18,9 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` data member. +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* A primary index is defined for the `kv table` for the `person::account_name` data member Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md index 8acb591de4..e8da1e0252 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/40_how-to-delete-from-kv-table.md @@ -18,8 +18,9 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` data member. +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* A primary index is defined for the `kv table` for the `person::account_name` data member Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md index 71b38349db..17f9c64294 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/50_how-to-iterate-kv-table.md @@ -16,16 +16,16 @@ Use the `iterator` defined by the `eosio::kv::table::index` class to accomplish Make sure you have the following prerequisites in place: -* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). -* A smart contract named `smrtcontract`. -* A user defined type which defines the data stored in the table, named `person`. -* A `kv table` type which stores objects of type `person`, named `address_table`. -* Each `person` object has the following properties: +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) +* A smart contract named `smrtcontract` +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* Each `person` object has the following data members: * `account_name`, * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md index c081100c2e..72b2cf8c22 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/60_how-to-check-a-record-kv-table.md @@ -16,16 +16,16 @@ Use the method `exists` defined by the `eosio::kv::table::index` class to accom Make sure you have the following prerequisites in place: -* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). -* A smart contract named `smrtcontract`. -* A user defined type which defines the data stored in the table, named `person`. -* A `kv table` type which stores objects of type `person`, named `address_table`. -* Each `person` object has the following properties: +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) +* A smart contract named `smrtcontract` +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* Each `person` object has the following data members: * `account_name`, * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md index b3735825bb..b55bf8127a 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/70_how-to-find-in-kv-table.md @@ -16,16 +16,16 @@ Use the method `find()` defined by the `eosio::kv::table::index` class to accom Make sure you have the following prerequisites in place: -* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). -* A smart contract named `smrtcontract`. -* A user defined type which defines the data stored in the table, named `person`. -* A `kv table` type which stores objects of type `person`, named `address_table`. -* Each `person` object has the following properties: +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) +* A smart contract named `smrtcontract` +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* Each `person` object has the following data members: * `account_name`, * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md index 68da4bafa6..df03e7553c 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/80_how-to-query-range-in-kv-table.md @@ -16,17 +16,17 @@ Use the method `range` defined by the `eosio::kv::table::index` class to accompl Make sure you have the following prerequisites in place: -* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index). -* A smart contract named `smrtcontract`. -* A user defined type which defines the data stored in the table, named `person`. -* A `kv table` type which stores objects of type `person`, named `address_table`. -* Each `person` object has the following properties: +* An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) +* A smart contract named `smrtcontract` +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* Each `person` object has the following data members: * `account_name`, * `first_name`, * `last_name`, * `personal_id`. -* A unique index, named `account_name_uidx`, defined on the `account_name` data member.. -* A non-unique index defined on the `last_name` data member, named `last_name_idx`. +* A unique index, named `account_name_uidx`, defined on the `account_name` data member +* A non-unique index defined on the `last_name` data member, named `last_name_idx` Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md index 0fc888c3f4..1fe391e2c9 100644 --- a/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md +++ b/docs/06_how-to-guides/30_key-value-api/kv_table/90_how-to-allow-users-to-pay-kv-table.md @@ -18,8 +18,9 @@ Make sure you have the following prerequisites in place: * An EOSIO development environment, for details consult the [Get Started Guide](https://developers.eos.io/welcome/latest/getting-started-guide/index) * A smart contract named `smrtcontract` -* A user defined type named `person`, which defines the data stored in the table -* A `kv table` type which stores objects of type `person`, named `address_table`. The primary index of the `kv table` is defined based on the `person::account_name` data member. +* A user defined type, `struct` or `class`, which defines the data stored in the map, named `person` +* A `kv table` data type, `struct` or `class`, which inherits `eosio::kv::table`, and stores objects of type `person`, named `address_table` +* A primary index is defined for the `kv table` for the `person::account_name` data member Refer to the following reference implementation for your starting point: diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index 6ef6751c98..fbfc1a5447 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -110,7 +110,7 @@ Declare the `testtab` multi-index table as a data member of type `test_table_t`. # 6. Initialize The Multi-Index Table Instance -Initialize the data member `testtab` by passing to its constructor the `scope` (in this case `receiver`) and the `code` parameters, these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor +Initialize the data member `testtab` by passing to its constructor the `code` (in this case `receiver`) and the `code` parameters (`receiver.value`), these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor ```diff // contract class constructor From 56290191b62e2433ccfe321dfdae6ef9c2167b63 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 23 Jun 2021 09:57:40 -0400 Subject: [PATCH 152/204] Tests can run on lighter node pool. --- .cicd/pipeline.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 8c7155c792..fced5c396a 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -210,7 +210,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_14}${SKIP_UNIT_TESTS} - label: ":darwin: macOS 10.15 - Unit Tests" @@ -234,7 +234,7 @@ steps: debug: true wait-network: true agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_15}${SKIP_UNIT_TESTS} - label: ":aws: Amazon_Linux 2 - Toolchain Tests" @@ -326,7 +326,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} - label: ":darwin: macOS 10.15 - Toolchain Tests" @@ -352,7 +352,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - - "queue=mac-anka-large-node-fleet" + - "queue=mac-anka-node-fleet" skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Integration Tests" From 708a5cae973c926b20b34e59506445f0a312cb2d Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 23 Jun 2021 18:20:10 -0400 Subject: [PATCH 153/204] Ensure timeout can be overridden for macos package building. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index fced5c396a..9b23082af5 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -486,7 +486,7 @@ steps: cd: ~ agents: - "queue=mac-anka-node-fleet" - timeout: 10 + timeout: ${TIMEOUT:-20} skip: ${SKIP_MACOS_10_14}${SKIP_PACKAGE_BUILDER} - label: ":darwin: Catalina - Package Builder" @@ -507,7 +507,7 @@ steps: wait-network: true agents: - "queue=mac-anka-node-fleet" - timeout: 20 + timeout: ${TIMEOUT:-20} skip: ${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} - wait From ff8ead9327fdba49547463d83b3eafa90427cf04 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 23 Jun 2021 18:21:34 -0400 Subject: [PATCH 154/204] Ensure timeout can be overridden for macos package builder. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index fced5c396a..9b23082af5 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -486,7 +486,7 @@ steps: cd: ~ agents: - "queue=mac-anka-node-fleet" - timeout: 10 + timeout: ${TIMEOUT:-20} skip: ${SKIP_MACOS_10_14}${SKIP_PACKAGE_BUILDER} - label: ":darwin: Catalina - Package Builder" @@ -507,7 +507,7 @@ steps: wait-network: true agents: - "queue=mac-anka-node-fleet" - timeout: 20 + timeout: ${TIMEOUT:-20} skip: ${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} - wait From 7d2d5a14c9aa098b0170ca1ae0326da0372381a9 Mon Sep 17 00:00:00 2001 From: Philip Halsall Date: Thu, 24 Jun 2021 14:46:30 +0800 Subject: [PATCH 155/204] update after JG review --- .../08_abi/01_abi-code-generator-attributes-explained.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md index ef32de7dfd..737b9276ac 100644 --- a/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md +++ b/docs/05_best-practices/08_abi/01_abi-code-generator-attributes-explained.md @@ -113,4 +113,4 @@ Contract actions tagged read-only: * Cannot call `inline actions`. * The amount of data returned by read-only queries is limited by the action return value size. By default these are set to 256 bytes by `default_max_action_return_value_size`. -The `eosio-cpp` and `eosio-cc` tools will generate an error and terminate compilation if an action tagged read-only attempts to call insert/update (write) functions. However, if the command-line override option `--warn-action-read-only` is used, the `eosio-cpp` and `eosio-cc` tools will issue a warning and continue compilation when write functions are used. +The `eosio-cpp` and `eosio-cc` tools will generate an error and terminate compilation if an action tagged read-only attempts to call insert/update (write) functions, `deferred transactions` or `inline actions`. However, if the command-line override option `--warn-action-read-only` is used, the `eosio-cpp` and `eosio-cc` tools will issue a warning and continue compilation. From a7e73a6eda6c2eddfd6256aa7d4353d5db8d692a Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 24 Jun 2021 11:59:42 +0300 Subject: [PATCH 156/204] renaming it to resource payer as the main name --- docs/05_features/10_resource_payer.md | 46 ++++++++++++++++++++++++++ docs/05_features/10_trx_sponsorship.md | 46 -------------------------- 2 files changed, 46 insertions(+), 46 deletions(-) create mode 100644 docs/05_features/10_resource_payer.md delete mode 100644 docs/05_features/10_trx_sponsorship.md diff --git a/docs/05_features/10_resource_payer.md b/docs/05_features/10_resource_payer.md new file mode 100644 index 0000000000..c4967ab966 --- /dev/null +++ b/docs/05_features/10_resource_payer.md @@ -0,0 +1,46 @@ +--- +content_title: Resource Payer +--- + +## Overview + +The `Resource Payer` feature, also known as `Transaction Sponsorship`, allows to specify the resource payer for a transaction. As a direct consequence the application developers have a simple and secure way to sponsor, or decline to sponsor, transactions on behalf of their users. + +## Concept + +Before the `EOSIO 2.2` version, the CPU and NET resource costs for transactions on EOSIO-based blockchains were paid by the end users of the application. This fact made attracting and onboarding new users difficult. + +The `Resource Payer` feature makes it easier for both smart contract and full stack developers on EOSIO-based blockchains to allow their users to transact without having to pay for CPU and NET resource costs in a simple and secure manner. This new feature makes the process of onboarding new users straightforward. + +Blockchain application developers can use the `Resource Payer` on any EOSIO-based blockchain that enables it via the newly introduced `RESOURCE_PAYER` upgrade protocol feature. + +### Related Concepts + +A [transaction](https://developers.eos.io/welcome/latest/glossary/index/#transaction) consists of one or more actions executed atomically on the blockchain which alter the state of the blockchain. + +You need system resources, [CPU](https://developers.eos.io/welcome/latest/glossary/index/#cpu) and [NET](https://developers.eos.io/welcome/latest/glossary/index/#net), to be able to execute transactions. + +The `Resource Payer` feature allows the application developers to designate the payer of the CPU and NET resources cost to a random blockchain [account](https://developers.eos.io/welcome/latest/glossary/index/#account). + +The `Resource Payer` feature is not available by default. To enable the feature, the `RESOURCE_PAYER` upgrade protocol feature must be enabled. For more information about upgrading protocol features, read the [Consensus Protocol Upgrade Process](https://developers.eos.io/manuals/eos/latest/nodeos/upgrade-guides/1.8-upgrade-guide/#upgrade-process-for-all-eosio-networks-including-test-networks) documentation. + +When you send the transaction to the blockchain, if you want to designate the resource payer, you must specify in the transaction definition the payer information which consists of the following: + +* The payer account name, +* The maximum CPU limit amount the payer supports expressed in microseconds, +* The maximum NET limit amount the payer supports expressed in bytes. + +The sponsorship information must be defined as a transaction extension and placed in the transaction’s extension list. For more details please see the examples provided in the following section. + +## Examples + +Find below one example that illustrate how to send a sponsored transaction to the blockchain. + +### EOSJS + +To send a transaction to the blockchain using javascript via the `eosjs` library, follow the [How To Send A Transaction](https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-submit-a-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. + +### Cleos + +[[info | Cleos Support Will Be Available Starting With v2.2 RC2 Onwards]] +| The ability to send transaction sponsorship information using `cleos` will be added in the v2.2 RC2 release version. diff --git a/docs/05_features/10_trx_sponsorship.md b/docs/05_features/10_trx_sponsorship.md deleted file mode 100644 index 0e0cdc764c..0000000000 --- a/docs/05_features/10_trx_sponsorship.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -content_title: Transaction Sponsorship ---- - -## Overview - -The `Transaction Sponsorship` feature, also known as Resource Payer, allows a simple and secure way for application developers to sponsor, or decline to sponsor, transactions on behalf of their users. - -## Concept - -Before the `EOSIO 2.2` version, the CPU and NET resource costs for transactions on EOSIO-based blockchains were paid by the end users of the application. This fact made attracting and onboarding new users difficult. - -The `Transaction Sponsorship` feature makes it easier for both smart contract and full stack developers on EOSIO-based blockchains to allow their users to transact without having to pay for CPU and NET resource costs in a simple and secure manner. This new feature makes the process of onboarding new users straightforward. - -Blockchain application developers can use the `Transaction Sponsorship` on any EOSIO-based blockchain that enables it via the newly introduced `RESOURCE_PAYER` upgrade protocol feature. - -### Related Terminology/Concepts - -A [transaction](https://developers.eos.io/welcome/latest/glossary/index/#transaction) consists of one or more actions executed atomically on the blockchain which alter the state of the blockchain. - -You need system resources, [CPU](https://developers.eos.io/welcome/latest/glossary/index/#cpu) and [NET](https://developers.eos.io/welcome/latest/glossary/index/#net), to be able to execute transactions. - -The `Transaction Sponsorship` feature allows the application developers to designate the payer of the CPU and NET resources cost to a random blockchain [account](https://developers.eos.io/welcome/latest/glossary/index/#account). - -The `Transaction Sponsorship` feature is not available by default. To enable the feature, the `RESOURCE_PAYER` upgrade protocol feature must be enabled. For more information about upgrading protocol features, read the [Consensus Protocol Upgrade Process](https://developers.eos.io/manuals/eos/latest/nodeos/upgrade-guides/1.8-upgrade-guide/#upgrade-process-for-all-eosio-networks-including-test-networks) documentation. - -When you send the transaction to the blockchain, if you want to designate the transaction sponsor, you must specify in the transaction definition the sponsorship information which consists of the following: - -* The sponsor’s account name, -* The maximum CPU limit amount the sponsor supports expressed in microseconds, -* The maximum NET limit amount the sponsor supports expressed in bytes. - -The sponsorship information must be defined as a transaction extension and placed in the transaction’s extension list. For more details please see the examples provided in the following section. - -## Examples - -Below are two examples that illustrate how to send a sponsored transaction to the blockchain. - -### EOSJS - -To send a transaction to the blockchain using javascript via the `eosjs` library, follow the [How To Send A Transaction](https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-submit-a-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. - -### Cleos - -[[warning | Cleos Support Will Be Available Starting With v2.2 RC2 Onwards]] -| The ability to send transaction sponsorship information using `cleos` will be added in the next v2.2 RC2 release. From 99cf716562265936a8e99e731bd6b5ad58891bd3 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 24 Jun 2021 12:06:54 +0300 Subject: [PATCH 157/204] clean up --- docs/05_features/10_resource_payer.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/05_features/10_resource_payer.md b/docs/05_features/10_resource_payer.md index c4967ab966..ac34fe2cba 100644 --- a/docs/05_features/10_resource_payer.md +++ b/docs/05_features/10_resource_payer.md @@ -30,17 +30,17 @@ When you send the transaction to the blockchain, if you want to designate the re * The maximum CPU limit amount the payer supports expressed in microseconds, * The maximum NET limit amount the payer supports expressed in bytes. -The sponsorship information must be defined as a transaction extension and placed in the transaction’s extension list. For more details please see the examples provided in the following section. +The resource payer information must be defined as a transaction extension and placed in the transaction’s extension list. For more details please see the examples provided in the following section. ## Examples -Find below one example that illustrate how to send a sponsored transaction to the blockchain. +Find below one example that illustrate how to send transaction to the blockchain which contain resource payer information. ### EOSJS -To send a transaction to the blockchain using javascript via the `eosjs` library, follow the [How To Send A Transaction](https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-submit-a-transaction) steps and note in the json example the transaction sponsorship information set in the ``transaction_extensions`` field. +To send a transaction to the blockchain using javascript via the `eosjs` library, follow the [How To Send A Transaction](https://developers.eos.io/manuals/eos/latest/cleos/how-to-guides/how-to-submit-a-transaction) steps and note in the json example the resource payer information set in the ``transaction_extensions`` field. ### Cleos [[info | Cleos Support Will Be Available Starting With v2.2 RC2 Onwards]] -| The ability to send transaction sponsorship information using `cleos` will be added in the v2.2 RC2 release version. +| The ability to send transaction with resource payer information using `cleos` will be added in the v2.2 RC2 release version. From 9544bf206617f46a55f0af5f141b7637e13398c2 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 24 Jun 2021 15:21:09 +0300 Subject: [PATCH 158/204] correct the scope and code for multi-index table --- .../40_multi-index/how-to-instantiate-a-multi-index-table.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index fbfc1a5447..8cb528a30a 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -110,7 +110,7 @@ Declare the `testtab` multi-index table as a data member of type `test_table_t`. # 6. Initialize The Multi-Index Table Instance -Initialize the data member `testtab` by passing to its constructor the `code` (in this case `receiver`) and the `code` parameters (`receiver.value`), these two combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor +Initialize the data member `testtab` by passing to its constructor for the `code` parameter the `receiver` value and for the `scope` parameter the `receiver.value` value. These two parameters combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor ```diff // contract class constructor From 4c0fb68cf24c20146ee3045dd3631af5aea50555 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 24 Jun 2021 15:25:52 +0300 Subject: [PATCH 159/204] feature name should not be enclosed in ticks --- docs/05_features/10_resource_payer.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/05_features/10_resource_payer.md b/docs/05_features/10_resource_payer.md index ac34fe2cba..d4d3d2dc35 100644 --- a/docs/05_features/10_resource_payer.md +++ b/docs/05_features/10_resource_payer.md @@ -4,15 +4,15 @@ content_title: Resource Payer ## Overview -The `Resource Payer` feature, also known as `Transaction Sponsorship`, allows to specify the resource payer for a transaction. As a direct consequence the application developers have a simple and secure way to sponsor, or decline to sponsor, transactions on behalf of their users. +The Resource Payer feature, also known as Transaction Sponsorship, allows to specify the resource payer for a transaction. As a direct consequence the application developers have a simple and secure way to sponsor, or decline to sponsor, transactions on behalf of their users. ## Concept Before the `EOSIO 2.2` version, the CPU and NET resource costs for transactions on EOSIO-based blockchains were paid by the end users of the application. This fact made attracting and onboarding new users difficult. -The `Resource Payer` feature makes it easier for both smart contract and full stack developers on EOSIO-based blockchains to allow their users to transact without having to pay for CPU and NET resource costs in a simple and secure manner. This new feature makes the process of onboarding new users straightforward. +The Resource Payer feature makes it easier for both smart contract and full stack developers on EOSIO-based blockchains to allow their users to transact without having to pay for CPU and NET resource costs in a simple and secure manner. This new feature makes the process of onboarding new users straightforward. -Blockchain application developers can use the `Resource Payer` on any EOSIO-based blockchain that enables it via the newly introduced `RESOURCE_PAYER` upgrade protocol feature. +Blockchain application developers can use the Resource Payer on any EOSIO-based blockchain that enables it via the newly introduced `RESOURCE_PAYER` upgrade protocol feature. ### Related Concepts @@ -20,15 +20,15 @@ A [transaction](https://developers.eos.io/welcome/latest/glossary/index/#transac You need system resources, [CPU](https://developers.eos.io/welcome/latest/glossary/index/#cpu) and [NET](https://developers.eos.io/welcome/latest/glossary/index/#net), to be able to execute transactions. -The `Resource Payer` feature allows the application developers to designate the payer of the CPU and NET resources cost to a random blockchain [account](https://developers.eos.io/welcome/latest/glossary/index/#account). +The Resource Payer feature allows the application developers to designate the payer of the CPU and NET resources cost to a random blockchain [account](https://developers.eos.io/welcome/latest/glossary/index/#account). -The `Resource Payer` feature is not available by default. To enable the feature, the `RESOURCE_PAYER` upgrade protocol feature must be enabled. For more information about upgrading protocol features, read the [Consensus Protocol Upgrade Process](https://developers.eos.io/manuals/eos/latest/nodeos/upgrade-guides/1.8-upgrade-guide/#upgrade-process-for-all-eosio-networks-including-test-networks) documentation. +The Resource Payer feature is not available by default. To enable the feature, the `RESOURCE_PAYER` upgrade protocol feature must be enabled. For more information about upgrading protocol features, read the [Consensus Protocol Upgrade Process](https://developers.eos.io/manuals/eos/latest/nodeos/upgrade-guides/1.8-upgrade-guide/#upgrade-process-for-all-eosio-networks-including-test-networks) documentation. When you send the transaction to the blockchain, if you want to designate the resource payer, you must specify in the transaction definition the payer information which consists of the following: -* The payer account name, -* The maximum CPU limit amount the payer supports expressed in microseconds, -* The maximum NET limit amount the payer supports expressed in bytes. +* The payer account name +* The maximum CPU limit amount the payer supports expressed in microseconds +* The maximum NET limit amount the payer supports expressed in bytes The resource payer information must be defined as a transaction extension and placed in the transaction’s extension list. For more details please see the examples provided in the following section. From 3bb6f22201ba4e8013f0d0d5fdea340633e896f3 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 24 Jun 2021 15:31:41 +0300 Subject: [PATCH 160/204] use italics for feature name --- docs/05_features/10_resource_payer.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/05_features/10_resource_payer.md b/docs/05_features/10_resource_payer.md index d4d3d2dc35..e78756fae8 100644 --- a/docs/05_features/10_resource_payer.md +++ b/docs/05_features/10_resource_payer.md @@ -4,15 +4,15 @@ content_title: Resource Payer ## Overview -The Resource Payer feature, also known as Transaction Sponsorship, allows to specify the resource payer for a transaction. As a direct consequence the application developers have a simple and secure way to sponsor, or decline to sponsor, transactions on behalf of their users. +The *Resource Payer* feature, also known as *Transaction Sponsorship*, allows to specify the resource payer for a transaction. As a direct consequence the application developers have a simple and secure way to sponsor, or decline to sponsor, transactions on behalf of their users. ## Concept Before the `EOSIO 2.2` version, the CPU and NET resource costs for transactions on EOSIO-based blockchains were paid by the end users of the application. This fact made attracting and onboarding new users difficult. -The Resource Payer feature makes it easier for both smart contract and full stack developers on EOSIO-based blockchains to allow their users to transact without having to pay for CPU and NET resource costs in a simple and secure manner. This new feature makes the process of onboarding new users straightforward. +The *Resource Payer* feature makes it easier for both smart contract and full stack developers on EOSIO-based blockchains to allow their users to transact without having to pay for CPU and NET resource costs in a simple and secure manner. This new feature makes the process of onboarding new users straightforward. -Blockchain application developers can use the Resource Payer on any EOSIO-based blockchain that enables it via the newly introduced `RESOURCE_PAYER` upgrade protocol feature. +Blockchain application developers can use the *Resource Payer* on any EOSIO-based blockchain that enables it via the newly introduced `RESOURCE_PAYER` upgrade protocol feature. ### Related Concepts @@ -20,9 +20,9 @@ A [transaction](https://developers.eos.io/welcome/latest/glossary/index/#transac You need system resources, [CPU](https://developers.eos.io/welcome/latest/glossary/index/#cpu) and [NET](https://developers.eos.io/welcome/latest/glossary/index/#net), to be able to execute transactions. -The Resource Payer feature allows the application developers to designate the payer of the CPU and NET resources cost to a random blockchain [account](https://developers.eos.io/welcome/latest/glossary/index/#account). +The *Resource Payer* feature allows the application developers to designate the payer of the CPU and NET resources cost to a random blockchain [account](https://developers.eos.io/welcome/latest/glossary/index/#account). -The Resource Payer feature is not available by default. To enable the feature, the `RESOURCE_PAYER` upgrade protocol feature must be enabled. For more information about upgrading protocol features, read the [Consensus Protocol Upgrade Process](https://developers.eos.io/manuals/eos/latest/nodeos/upgrade-guides/1.8-upgrade-guide/#upgrade-process-for-all-eosio-networks-including-test-networks) documentation. +The *Resource Payer* feature is not available by default. To enable the feature, the `RESOURCE_PAYER` upgrade protocol feature must be enabled. For more information about upgrading protocol features, read the [Consensus Protocol Upgrade Process](https://developers.eos.io/manuals/eos/latest/nodeos/upgrade-guides/1.8-upgrade-guide/#upgrade-process-for-all-eosio-networks-including-test-networks) documentation. When you send the transaction to the blockchain, if you want to designate the resource payer, you must specify in the transaction definition the payer information which consists of the following: From 91ebdee64ed428ac60ff03da38a61db2ae459356 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 24 Jun 2021 16:12:47 -0400 Subject: [PATCH 161/204] Add version check test for eosio-cpp --version option. --- tests/CMakeLists.txt | 3 +++ tests/unit/version-label.sh | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100755 tests/unit/version-label.sh diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9b1e7fb946..ddba235860 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,6 +34,9 @@ add_unit_test( varint_tests ) add_test( NAME toolchain_tests COMMAND ${CMAKE_BINARY_DIR}/tools/toolchain-tester/toolchain-tester ${CMAKE_SOURCE_DIR}/tests/toolchain --cdt ${CMAKE_BINARY_DIR}/bin ) set_property(TEST toolchain_tests PROPERTY LABELS toolchain_tests) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unit/version-label.sh ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh COPYONLY) +add_test(NAME version-label-test COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh "eosio-cpp version ${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + if (eosio_FOUND) add_test(integration_tests ${CMAKE_BINARY_DIR}/tests/integration/integration_tests) set_property(TEST integration_tests PROPERTY LABELS integration_tests) diff --git a/tests/unit/version-label.sh b/tests/unit/version-label.sh new file mode 100755 index 0000000000..45698e9396 --- /dev/null +++ b/tests/unit/version-label.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -eo pipefail +# The purpose of this test is to ensure that the output of the "eosio-cpp --version" command matches the version string defined by our CMake files +echo '##### Eosio-cpp Version Label Test #####' +# orient ourselves +[[ -z "$BUILD_ROOT" ]] && export BUILD_ROOT="$(pwd)" +echo "Using BUILD_ROOT=\"$BUILD_ROOT\"." +# test expectations +if [[ -z "$EXPECTED" ]]; then + [[ -z "$BUILDKITE_TAG" ]] && export BUILDKITE_TAG="${GIT_TAG:-$1}" + export EXPECTED="$BUILDKITE_TAG" +fi +if [[ -z "$EXPECTED" ]]; then + echo "Missing version input." + exit 1 +fi +echo "Expecting \"$EXPECTED\"..." +# get eosio-cpp version +ACTUAL=$($BUILD_ROOT/bin/eosio-cpp --version) +EXIT_CODE=$? +# verify 0 exit code explicitly +if [[ $EXIT_CODE -ne 0 ]]; then + echo "Eosio-cpp produced non-zero exit code \"$EXIT_CODE\"." + exit $EXIT_CODE +fi +# test version +if [[ "$EXPECTED" == "$ACTUAL" ]]; then + echo "Passed with \"$ACTUAL\"." + exit 0 +fi +echo 'Failed!' +echo "\"$EXPECTED\" != \"$ACTUAL\"" +exit 1 From b070ae333c6f3735732ba5e720d571f1d6ee2546 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 24 Jun 2021 21:29:47 -0400 Subject: [PATCH 162/204] Test file naming consistency and add unit_tests label. --- tests/CMakeLists.txt | 5 +++-- tests/unit/{version-label.sh => version_tests.sh} | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename tests/unit/{version-label.sh => version_tests.sh} (100%) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ddba235860..eb2f4b0a18 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,8 +34,9 @@ add_unit_test( varint_tests ) add_test( NAME toolchain_tests COMMAND ${CMAKE_BINARY_DIR}/tools/toolchain-tester/toolchain-tester ${CMAKE_SOURCE_DIR}/tests/toolchain --cdt ${CMAKE_BINARY_DIR}/bin ) set_property(TEST toolchain_tests PROPERTY LABELS toolchain_tests) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unit/version-label.sh ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh COPYONLY) -add_test(NAME version-label-test COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh "eosio-cpp version ${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unit/version_tests.sh ${CMAKE_BINARY_DIR}/tests/unit/version_tests.sh COPYONLY) +add_test(NAME version_tests COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version_tests.sh "eosio-cpp version ${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST version_tests PROPERTY LABELS unit_tests) if (eosio_FOUND) add_test(integration_tests ${CMAKE_BINARY_DIR}/tests/integration/integration_tests) diff --git a/tests/unit/version-label.sh b/tests/unit/version_tests.sh similarity index 100% rename from tests/unit/version-label.sh rename to tests/unit/version_tests.sh From a34f23a26d92f3a9dcde37750ce1a1a3420537a3 Mon Sep 17 00:00:00 2001 From: ovi Date: Fri, 25 Jun 2021 12:28:47 +0300 Subject: [PATCH 163/204] small correction based on peer review small correction based on peer review - Bob --- .../40_multi-index/how-to-instantiate-a-multi-index-table.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md index 8cb528a30a..101f6169ef 100644 --- a/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md +++ b/docs/06_how-to-guides/40_multi-index/how-to-instantiate-a-multi-index-table.md @@ -110,7 +110,7 @@ Declare the `testtab` multi-index table as a data member of type `test_table_t`. # 6. Initialize The Multi-Index Table Instance -Initialize the data member `testtab` by passing to its constructor for the `code` parameter the `receiver` value and for the `scope` parameter the `receiver.value` value. These two parameters combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor +Initialize the data member `testtab` by passing to its constructor these two values: `receiver` for the `code` parameter and `receiver.value` for the `scope` parameter. These two parameters combined with table name `"testtaba"` provide access to the partition of the RAM cache used by this multi-index table, in this example you will initialize the `testtab` data member in the smart contract constructor ```diff // contract class constructor From d6ba5adaa6358aae39e6f587b6b6e438b2419bb4 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 24 Jun 2021 16:12:47 -0400 Subject: [PATCH 164/204] Add version check test for eosio-cpp --version option. --- tests/CMakeLists.txt | 3 +++ tests/unit/version-label.sh | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100755 tests/unit/version-label.sh diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9b1e7fb946..ddba235860 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,6 +34,9 @@ add_unit_test( varint_tests ) add_test( NAME toolchain_tests COMMAND ${CMAKE_BINARY_DIR}/tools/toolchain-tester/toolchain-tester ${CMAKE_SOURCE_DIR}/tests/toolchain --cdt ${CMAKE_BINARY_DIR}/bin ) set_property(TEST toolchain_tests PROPERTY LABELS toolchain_tests) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unit/version-label.sh ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh COPYONLY) +add_test(NAME version-label-test COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh "eosio-cpp version ${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + if (eosio_FOUND) add_test(integration_tests ${CMAKE_BINARY_DIR}/tests/integration/integration_tests) set_property(TEST integration_tests PROPERTY LABELS integration_tests) diff --git a/tests/unit/version-label.sh b/tests/unit/version-label.sh new file mode 100755 index 0000000000..45698e9396 --- /dev/null +++ b/tests/unit/version-label.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -eo pipefail +# The purpose of this test is to ensure that the output of the "eosio-cpp --version" command matches the version string defined by our CMake files +echo '##### Eosio-cpp Version Label Test #####' +# orient ourselves +[[ -z "$BUILD_ROOT" ]] && export BUILD_ROOT="$(pwd)" +echo "Using BUILD_ROOT=\"$BUILD_ROOT\"." +# test expectations +if [[ -z "$EXPECTED" ]]; then + [[ -z "$BUILDKITE_TAG" ]] && export BUILDKITE_TAG="${GIT_TAG:-$1}" + export EXPECTED="$BUILDKITE_TAG" +fi +if [[ -z "$EXPECTED" ]]; then + echo "Missing version input." + exit 1 +fi +echo "Expecting \"$EXPECTED\"..." +# get eosio-cpp version +ACTUAL=$($BUILD_ROOT/bin/eosio-cpp --version) +EXIT_CODE=$? +# verify 0 exit code explicitly +if [[ $EXIT_CODE -ne 0 ]]; then + echo "Eosio-cpp produced non-zero exit code \"$EXIT_CODE\"." + exit $EXIT_CODE +fi +# test version +if [[ "$EXPECTED" == "$ACTUAL" ]]; then + echo "Passed with \"$ACTUAL\"." + exit 0 +fi +echo 'Failed!' +echo "\"$EXPECTED\" != \"$ACTUAL\"" +exit 1 From 6ac7d48372115fd5c7529781356d06abca0bc358 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 24 Jun 2021 21:29:47 -0400 Subject: [PATCH 165/204] Test file naming consistency and add unit_tests label. --- tests/CMakeLists.txt | 5 +++-- tests/unit/{version-label.sh => version_tests.sh} | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename tests/unit/{version-label.sh => version_tests.sh} (100%) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ddba235860..eb2f4b0a18 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -34,8 +34,9 @@ add_unit_test( varint_tests ) add_test( NAME toolchain_tests COMMAND ${CMAKE_BINARY_DIR}/tools/toolchain-tester/toolchain-tester ${CMAKE_SOURCE_DIR}/tests/toolchain --cdt ${CMAKE_BINARY_DIR}/bin ) set_property(TEST toolchain_tests PROPERTY LABELS toolchain_tests) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unit/version-label.sh ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh COPYONLY) -add_test(NAME version-label-test COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version-label.sh "eosio-cpp version ${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unit/version_tests.sh ${CMAKE_BINARY_DIR}/tests/unit/version_tests.sh COPYONLY) +add_test(NAME version_tests COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version_tests.sh "eosio-cpp version ${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +set_property(TEST version_tests PROPERTY LABELS unit_tests) if (eosio_FOUND) add_test(integration_tests ${CMAKE_BINARY_DIR}/tests/integration/integration_tests) diff --git a/tests/unit/version-label.sh b/tests/unit/version_tests.sh similarity index 100% rename from tests/unit/version-label.sh rename to tests/unit/version_tests.sh From afe867acdac552d6b64a9d75f8f9f0f0eff4b8be Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 11:38:11 -0400 Subject: [PATCH 166/204] Backbone for ensure tag support in CDT. --- .cicd/docker/macos-10.14.sh | 7 +++ .cicd/docker/macos-10.15.sh | 7 +++ .cicd/pipeline.yml | 118 +++++++++++++++++++++++++----------- 3 files changed, 95 insertions(+), 37 deletions(-) create mode 100755 .cicd/docker/macos-10.14.sh create mode 100755 .cicd/docker/macos-10.15.sh diff --git a/.cicd/docker/macos-10.14.sh b/.cicd/docker/macos-10.14.sh new file mode 100755 index 0000000000..2e54b40c5f --- /dev/null +++ b/.cicd/docker/macos-10.14.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -eou pipefail +VERSION=1 + +brew update +brew upgrade +brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/docker/macos-10.15.sh b/.cicd/docker/macos-10.15.sh new file mode 100755 index 0000000000..2e54b40c5f --- /dev/null +++ b/.cicd/docker/macos-10.15.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -eou pipefail +VERSION=1 + +brew update +brew upgrade +brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 9b23082af5..d7cf56a6b3 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -1,5 +1,4 @@ steps: - - wait - label: ":aws: Amazon_Linux 2 - Build" @@ -70,8 +69,6 @@ steps: - label: ":darwin: macOS 10.14 - Build" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -82,22 +79,35 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" modify-cpu: 12 modify-ram: 24 always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + pre-commands: + - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" - EOSIO/skip-checkout#v0.1.1: cd: ~ + env: + PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} + REPO_COMMIT: $BUILDKITE_COMMIT + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TEMPLATE: 10.14.6_6C_14G_80G + TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent + timeout: ${TIMEOUT:-120} agents: - "queue=mac-anka-large-node-fleet" - skip: $SKIP_MACOS_10_14 + skip: ${SKIP_MACOS_10_14}${SKIP_MAC} - label: ":darwin: macOS 10.15 - Build" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -108,16 +118,32 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" modify-cpu: 12 modify-ram: 24 always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + pre-commands: + - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" + - EOSIO/skip-checkout#v0.1.1: + cd: ~ + env: + PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} + REPO_COMMIT: $BUILDKITE_COMMIT + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TEMPLATE: 10.14.6_6C_14G_80G + TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent + timeout: ${TIMEOUT:-120} agents: - "queue=mac-anka-large-node-fleet" - skip: $SKIP_MACOS_10_15 - + skip: ${SKIP_MACOS_10_15}${SKIP_MAC} - wait @@ -189,8 +215,6 @@ steps: - label: ":darwin: macOS 10.14 - Unit Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -201,22 +225,23 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_14}${SKIP_UNIT_TESTS} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_UNIT_TESTS} - label: ":darwin: macOS 10.15 - Unit Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -227,15 +252,20 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + - EOSIO/skip-checkout#v0.1.1: + cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_15}${SKIP_UNIT_TESTS} + skip: ${SKIP_MACOS_10_15}${SKIP_MAC}${SKIP_UNIT_TESTS} - label: ":aws: Amazon_Linux 2 - Toolchain Tests" command: @@ -305,8 +335,6 @@ steps: - label: ":darwin: macOS 10.14 - Toolchain Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -317,22 +345,23 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_TOOLCHAIN_TESTS} - label: ":darwin: macOS 10.15 - Toolchain Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -343,17 +372,20 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Integration Tests" command: @@ -482,12 +514,17 @@ steps: always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" timeout: ${TIMEOUT:-20} - skip: ${SKIP_MACOS_10_14}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_PACKAGE_BUILDER} - label: ":darwin: Catalina - Package Builder" command: @@ -505,10 +542,17 @@ steps: always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + - EOSIO/skip-checkout#v0.1.1: + cd: ~ agents: - "queue=mac-anka-node-fleet" timeout: ${TIMEOUT:-20} - skip: ${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_MACOS_10_15}${SKIP_MAC}${SKIP_PACKAGE_BUILDER} - wait @@ -529,7 +573,7 @@ steps: agents: queue: "automation-basic-builder-fleet" timeout: "${TIMEOUT:-5}" - skip: ${SKIP_MACOS_10_14}${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_MACOS_10_14}${SKIP_MACOS_10_15}${SKIP_MAC}${SKIP_PACKAGE_BUILDER} - label: ":git: Git Submodule Regression Check" command: From f7456b0ef273e7b72c86a17debe98afa13121f0e Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 12:07:03 -0400 Subject: [PATCH 167/204] Write macos script hashes and update pipeline file. --- .cicd/generate-pipeline.sh | 9 +++++++++ .cicd/pipeline.yml | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100755 .cicd/generate-pipeline.sh diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh new file mode 100755 index 0000000000..e00d441bf0 --- /dev/null +++ b/.cicd/generate-pipeline.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -eou pipefail + +export MACOS_10_14_FILE_HASH="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" +export MACOS_10_15_FILE_HASH="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" +export VARS='$MACOS_10_14_FILE_HASH:$MACOS_10_15_FILE_HASH' +envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" +buildkite-agent artifact upload pipeline.yml.out +buildkite-agent pipeline upload pipeline.yml.out diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index d7cf56a6b3..d7d3fb949e 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -79,7 +79,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -95,7 +95,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + PROJECT_TAG: ${MACOS_10_14_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -118,7 +118,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -134,7 +134,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + PROJECT_TAG: ${MACOS_10_15_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -225,7 +225,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" always-pull: true debug: true wait-network: true @@ -252,7 +252,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" always-pull: true debug: true wait-network: true @@ -345,7 +345,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" always-pull: true debug: true wait-network: true @@ -372,7 +372,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" always-pull: true debug: true wait-network: true From 6c5c7e3d97daf5ec7c78c2e135de900a4ad14c20 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 13:52:24 -0400 Subject: [PATCH 168/204] Fix path. --- .cicd/generate-pipeline.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh index e00d441bf0..3e75a5c926 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -5,5 +5,5 @@ export MACOS_10_14_FILE_HASH="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/mac export MACOS_10_15_FILE_HASH="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" export VARS='$MACOS_10_14_FILE_HASH:$MACOS_10_15_FILE_HASH' envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" -buildkite-agent artifact upload pipeline.yml.out -buildkite-agent pipeline upload pipeline.yml.out +buildkite-agent artifact upload ./.cicd/pipeline.yml.out +buildkite-agent pipeline upload ./.cicd/pipeline.yml.out From 386bfcb1841ab30bd453f5c5f4e94ba6646d3798 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 13:59:38 -0400 Subject: [PATCH 169/204] Try removing escapse characters. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index d7d3fb949e..09ed7cebef 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -98,7 +98,7 @@ steps: PROJECT_TAG: ${MACOS_10_14_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.14.6_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} @@ -137,7 +137,7 @@ steps: PROJECT_TAG: ${MACOS_10_15_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.14.6_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} From aa71bc6b5e46b666eb688572595508b137faa4f9 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 14:06:11 -0400 Subject: [PATCH 170/204] Correct ssh endpoint for mac-anka-fleet repo. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 09ed7cebef..e1766f06e1 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -91,7 +91,7 @@ steps: - 'registry-1' - 'registry-2' pre-commands: - - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" + - "rm -rf mac-anka-fleet; git clone git@github.com:EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" - EOSIO/skip-checkout#v0.1.1: cd: ~ env: @@ -130,7 +130,7 @@ steps: - 'registry-1' - 'registry-2' pre-commands: - - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" + - "rm -rf mac-anka-fleet; git clone git@github.com:EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" - EOSIO/skip-checkout#v0.1.1: cd: ~ env: From 3417c040aae6865f3a9ed33d7788a05d90e12a75 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 14:50:33 -0400 Subject: [PATCH 171/204] Fix bug with catalina VM. --- .cicd/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index e1766f06e1..28146502b7 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -138,7 +138,7 @@ steps: REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" - TEMPLATE: 10.14.6_6C_14G_80G + TEMPLATE: 10.15.5_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} agents: From bab811a5874e604a1b898de1c3d8103120939fb3 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:00:02 -0400 Subject: [PATCH 172/204] Better naming for platforms. --- .cicd/generate-base-images.sh | 2 +- .cicd/helpers/docker-hash.sh | 2 +- .cicd/{docker => platforms}/amazonlinux-2.dockerfile | 0 .cicd/{docker => platforms}/centos-7.7.dockerfile | 0 .cicd/{docker => platforms}/centos-8.dockerfile | 0 .cicd/{docker => platforms}/macos-10.14.sh | 3 +-- .cicd/{docker => platforms}/macos-10.15.sh | 3 +-- .cicd/{docker => platforms}/ubuntu-16.04.dockerfile | 0 .cicd/{docker => platforms}/ubuntu-18.04.dockerfile | 0 .cicd/{docker => platforms}/ubuntu-20.04.dockerfile | 0 10 files changed, 4 insertions(+), 6 deletions(-) rename .cicd/{docker => platforms}/amazonlinux-2.dockerfile (100%) rename .cicd/{docker => platforms}/centos-7.7.dockerfile (100%) rename .cicd/{docker => platforms}/centos-8.dockerfile (100%) rename .cicd/{docker => platforms}/macos-10.14.sh (82%) rename .cicd/{docker => platforms}/macos-10.15.sh (82%) rename .cicd/{docker => platforms}/ubuntu-16.04.dockerfile (100%) rename .cicd/{docker => platforms}/ubuntu-18.04.dockerfile (100%) rename .cicd/{docker => platforms}/ubuntu-20.04.dockerfile (100%) diff --git a/.cicd/generate-base-images.sh b/.cicd/generate-base-images.sh index 94abce495c..7a141640a9 100755 --- a/.cicd/generate-base-images.sh +++ b/.cicd/generate-base-images.sh @@ -9,7 +9,7 @@ TAG=$(echo $FULL_TAG | cut -d: -f2) EXISTS=$(curl -s -H "Authorization: Bearer $(curl -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${ORG_REPO}:pull" | jq --raw-output .token)" "https://registry.hub.docker.com/v2/${ORG_REPO}/manifests/$TAG") # build, if neccessary if [[ $EXISTS =~ '404 page not found' || $EXISTS =~ 'manifest unknown' ]]; then # if we cannot pull the image, we build and push it first - docker build -t $FULL_TAG -f $CICD_DIR/docker/${IMAGE_TAG}.dockerfile . + docker build -t $FULL_TAG -f $CICD_DIR/platforms/${IMAGE_TAG}.dockerfile . docker push $FULL_TAG else echo "$FULL_TAG already exists." diff --git a/.cicd/helpers/docker-hash.sh b/.cicd/helpers/docker-hash.sh index 6dcd24b3c2..de838e8e65 100644 --- a/.cicd/helpers/docker-hash.sh +++ b/.cicd/helpers/docker-hash.sh @@ -16,7 +16,7 @@ function determine-hash() { } if [[ ! -z $IMAGE_TAG ]]; then - determine-hash "$CICD_DIR/docker/${IMAGE_TAG}.dockerfile" + determine-hash "$CICD_DIR/platforms/${IMAGE_TAG}.dockerfile" export FULL_TAG="eosio/ci:eosio-cdt-$HASHED_IMAGE_TAG" else echo "Please set ENV::IMAGE_TAG to match the name of a platform dockerfile..." diff --git a/.cicd/docker/amazonlinux-2.dockerfile b/.cicd/platforms/amazonlinux-2.dockerfile similarity index 100% rename from .cicd/docker/amazonlinux-2.dockerfile rename to .cicd/platforms/amazonlinux-2.dockerfile diff --git a/.cicd/docker/centos-7.7.dockerfile b/.cicd/platforms/centos-7.7.dockerfile similarity index 100% rename from .cicd/docker/centos-7.7.dockerfile rename to .cicd/platforms/centos-7.7.dockerfile diff --git a/.cicd/docker/centos-8.dockerfile b/.cicd/platforms/centos-8.dockerfile similarity index 100% rename from .cicd/docker/centos-8.dockerfile rename to .cicd/platforms/centos-8.dockerfile diff --git a/.cicd/docker/macos-10.14.sh b/.cicd/platforms/macos-10.14.sh similarity index 82% rename from .cicd/docker/macos-10.14.sh rename to .cicd/platforms/macos-10.14.sh index 2e54b40c5f..3c91271a9c 100755 --- a/.cicd/docker/macos-10.14.sh +++ b/.cicd/platforms/macos-10.14.sh @@ -2,6 +2,5 @@ set -eou pipefail VERSION=1 -brew update -brew upgrade +brew update && brew upgrade brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/docker/macos-10.15.sh b/.cicd/platforms/macos-10.15.sh similarity index 82% rename from .cicd/docker/macos-10.15.sh rename to .cicd/platforms/macos-10.15.sh index 2e54b40c5f..3c91271a9c 100755 --- a/.cicd/docker/macos-10.15.sh +++ b/.cicd/platforms/macos-10.15.sh @@ -2,6 +2,5 @@ set -eou pipefail VERSION=1 -brew update -brew upgrade +brew update && brew upgrade brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/docker/ubuntu-16.04.dockerfile b/.cicd/platforms/ubuntu-16.04.dockerfile similarity index 100% rename from .cicd/docker/ubuntu-16.04.dockerfile rename to .cicd/platforms/ubuntu-16.04.dockerfile diff --git a/.cicd/docker/ubuntu-18.04.dockerfile b/.cicd/platforms/ubuntu-18.04.dockerfile similarity index 100% rename from .cicd/docker/ubuntu-18.04.dockerfile rename to .cicd/platforms/ubuntu-18.04.dockerfile diff --git a/.cicd/docker/ubuntu-20.04.dockerfile b/.cicd/platforms/ubuntu-20.04.dockerfile similarity index 100% rename from .cicd/docker/ubuntu-20.04.dockerfile rename to .cicd/platforms/ubuntu-20.04.dockerfile From 80552b4e24fd7d0ed0d74b744167e208067b5500 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:01:13 -0400 Subject: [PATCH 173/204] Use platforms in Mac steps. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 28146502b7..520cec5e83 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -98,7 +98,7 @@ steps: PROJECT_TAG: ${MACOS_10_14_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.14.6_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} @@ -137,7 +137,7 @@ steps: PROJECT_TAG: ${MACOS_10_15_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.15.5_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} From a8c08fa3ba8a6fb1ca4c4aeeec59bc8e1a7fac0b Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:02:45 -0400 Subject: [PATCH 174/204] More accurate variable naming. --- .cicd/generate-pipeline.sh | 6 +++--- .cicd/pipeline.yml | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh index 3e75a5c926..ba2e528851 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -1,9 +1,9 @@ #!/bin/bash set -eou pipefail -export MACOS_10_14_FILE_HASH="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" -export MACOS_10_15_FILE_HASH="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" -export VARS='$MACOS_10_14_FILE_HASH:$MACOS_10_15_FILE_HASH' +export MACOS_10_14_TAG="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" +export MACOS_10_15_TAG="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" +export VARS='$MACOS_10_14_TAG:$MACOS_10_15_TAG' envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" buildkite-agent artifact upload ./.cicd/pipeline.yml.out buildkite-agent pipeline upload ./.cicd/pipeline.yml.out diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 520cec5e83..7d5fd6e084 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -79,7 +79,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_TAG}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -95,7 +95,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MACOS_10_14_FILE_HASH} + PROJECT_TAG: ${MACOS_10_14_TAG} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -118,7 +118,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_TAG}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -134,7 +134,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MACOS_10_15_FILE_HASH} + PROJECT_TAG: ${MACOS_10_15_TAG} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -225,7 +225,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_TAG}" always-pull: true debug: true wait-network: true @@ -252,7 +252,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_TAG}" always-pull: true debug: true wait-network: true @@ -345,7 +345,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_TAG}" always-pull: true debug: true wait-network: true @@ -372,7 +372,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_TAG}" always-pull: true debug: true wait-network: true From f3d869a5a613e3a639659605ea0ee32d44609082 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:08:46 -0400 Subject: [PATCH 175/204] One more old docker dir instance updated. --- .cicd/generate-pipeline.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh index ba2e528851..202cefcec1 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -1,8 +1,8 @@ #!/bin/bash set -eou pipefail -export MACOS_10_14_TAG="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" -export MACOS_10_15_TAG="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" +export MACOS_10_14_TAG="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/platforms/macos-10.14.sh | awk '{print $1}')" +export MACOS_10_15_TAG="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/platforms/macos-10.15.sh | awk '{print $1}')" export VARS='$MACOS_10_14_TAG:$MACOS_10_15_TAG' envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" buildkite-agent artifact upload ./.cicd/pipeline.yml.out From 0f0aef0901b2b01caf5cdd23f039490aec2daf93 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 30 Jun 2021 09:48:40 -0400 Subject: [PATCH 176/204] Rename script. --- .cicd/{generate-pipeline.sh => pipeline-upload.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .cicd/{generate-pipeline.sh => pipeline-upload.sh} (100%) diff --git a/.cicd/generate-pipeline.sh b/.cicd/pipeline-upload.sh similarity index 100% rename from .cicd/generate-pipeline.sh rename to .cicd/pipeline-upload.sh From e0b92e1da3c7f5bc7fbd3c37d5f16d6d69e670d2 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 11:38:11 -0400 Subject: [PATCH 177/204] Backbone for ensure tag support in CDT. --- .cicd/docker/macos-10.14.sh | 7 +++ .cicd/docker/macos-10.15.sh | 7 +++ .cicd/pipeline.yml | 118 +++++++++++++++++++++++++----------- 3 files changed, 95 insertions(+), 37 deletions(-) create mode 100755 .cicd/docker/macos-10.14.sh create mode 100755 .cicd/docker/macos-10.15.sh diff --git a/.cicd/docker/macos-10.14.sh b/.cicd/docker/macos-10.14.sh new file mode 100755 index 0000000000..2e54b40c5f --- /dev/null +++ b/.cicd/docker/macos-10.14.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -eou pipefail +VERSION=1 + +brew update +brew upgrade +brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/docker/macos-10.15.sh b/.cicd/docker/macos-10.15.sh new file mode 100755 index 0000000000..2e54b40c5f --- /dev/null +++ b/.cicd/docker/macos-10.15.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -eou pipefail +VERSION=1 + +brew update +brew upgrade +brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 9b23082af5..d7cf56a6b3 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -1,5 +1,4 @@ steps: - - wait - label: ":aws: Amazon_Linux 2 - Build" @@ -70,8 +69,6 @@ steps: - label: ":darwin: macOS 10.14 - Build" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -82,22 +79,35 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" modify-cpu: 12 modify-ram: 24 always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + pre-commands: + - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" - EOSIO/skip-checkout#v0.1.1: cd: ~ + env: + PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} + REPO_COMMIT: $BUILDKITE_COMMIT + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TEMPLATE: 10.14.6_6C_14G_80G + TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent + timeout: ${TIMEOUT:-120} agents: - "queue=mac-anka-large-node-fleet" - skip: $SKIP_MACOS_10_14 + skip: ${SKIP_MACOS_10_14}${SKIP_MAC} - label: ":darwin: macOS 10.15 - Build" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -108,16 +118,32 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" modify-cpu: 12 modify-ram: 24 always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + pre-commands: + - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" + - EOSIO/skip-checkout#v0.1.1: + cd: ~ + env: + PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} + REPO_COMMIT: $BUILDKITE_COMMIT + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TEMPLATE: 10.14.6_6C_14G_80G + TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent + timeout: ${TIMEOUT:-120} agents: - "queue=mac-anka-large-node-fleet" - skip: $SKIP_MACOS_10_15 - + skip: ${SKIP_MACOS_10_15}${SKIP_MAC} - wait @@ -189,8 +215,6 @@ steps: - label: ":darwin: macOS 10.14 - Unit Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -201,22 +225,23 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_14}${SKIP_UNIT_TESTS} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_UNIT_TESTS} - label: ":darwin: macOS 10.15 - Unit Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -227,15 +252,20 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + - EOSIO/skip-checkout#v0.1.1: + cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_15}${SKIP_UNIT_TESTS} + skip: ${SKIP_MACOS_10_15}${SKIP_MAC}${SKIP_UNIT_TESTS} - label: ":aws: Amazon_Linux 2 - Toolchain Tests" command: @@ -305,8 +335,6 @@ steps: - label: ":darwin: macOS 10.14 - Toolchain Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -317,22 +345,23 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_TOOLCHAIN_TESTS} - label: ":darwin: macOS 10.15 - Toolchain Tests" command: - - "brew update && brew upgrade" - - "brew install git automake libtool wget cmake gmp gettext doxygen graphviz lcov python@3" - "git clone $BUILDKITE_REPO eosio.cdt" - "cd eosio.cdt && if [[ $BUILDKITE_BRANCH =~ ^pull/[0-9]+/head: ]]; then git fetch -v --prune origin refs/pull/$(echo $BUILDKITE_BRANCH | cut -d/ -f2)/head; fi" - "cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive" @@ -343,17 +372,20 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent" - modify-cpu: 12 - modify-ram: 24 + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" - skip: ${SKIP_MACOS_10_14}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Integration Tests" command: @@ -482,12 +514,17 @@ steps: always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' - EOSIO/skip-checkout#v0.1.1: cd: ~ agents: - "queue=mac-anka-node-fleet" timeout: ${TIMEOUT:-20} - skip: ${SKIP_MACOS_10_14}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_MACOS_10_14}${SKIP_MAC}${SKIP_PACKAGE_BUILDER} - label: ":darwin: Catalina - Package Builder" command: @@ -505,10 +542,17 @@ steps: always-pull: true debug: true wait-network: true + pre-execute-sleep: 5 + pre-execute-ping-sleep: github.com + failover-registries: + - 'registry-1' + - 'registry-2' + - EOSIO/skip-checkout#v0.1.1: + cd: ~ agents: - "queue=mac-anka-node-fleet" timeout: ${TIMEOUT:-20} - skip: ${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_MACOS_10_15}${SKIP_MAC}${SKIP_PACKAGE_BUILDER} - wait @@ -529,7 +573,7 @@ steps: agents: queue: "automation-basic-builder-fleet" timeout: "${TIMEOUT:-5}" - skip: ${SKIP_MACOS_10_14}${SKIP_MACOS_10_15}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_MACOS_10_14}${SKIP_MACOS_10_15}${SKIP_MAC}${SKIP_PACKAGE_BUILDER} - label: ":git: Git Submodule Regression Check" command: From 037b237d97d0c8ec553c677fc80f285f23eef3cb Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 12:07:03 -0400 Subject: [PATCH 178/204] Write macos script hashes and update pipeline file. --- .cicd/generate-pipeline.sh | 9 +++++++++ .cicd/pipeline.yml | 16 ++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100755 .cicd/generate-pipeline.sh diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh new file mode 100755 index 0000000000..e00d441bf0 --- /dev/null +++ b/.cicd/generate-pipeline.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -eou pipefail + +export MACOS_10_14_FILE_HASH="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" +export MACOS_10_15_FILE_HASH="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" +export VARS='$MACOS_10_14_FILE_HASH:$MACOS_10_15_FILE_HASH' +envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" +buildkite-agent artifact upload pipeline.yml.out +buildkite-agent pipeline upload pipeline.yml.out diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index d7cf56a6b3..d7d3fb949e 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -79,7 +79,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -95,7 +95,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + PROJECT_TAG: ${MACOS_10_14_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -118,7 +118,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -134,7 +134,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MAC_SCRIPT_HASH_GOES_HERE} + PROJECT_TAG: ${MACOS_10_15_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -225,7 +225,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" always-pull: true debug: true wait-network: true @@ -252,7 +252,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" always-pull: true debug: true wait-network: true @@ -345,7 +345,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" always-pull: true debug: true wait-network: true @@ -372,7 +372,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MAC_SCRIPT_HASH_GOES_HERE}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" always-pull: true debug: true wait-network: true From 615dd84efcdc572ddfec8a3f58493594f845688a Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 13:52:24 -0400 Subject: [PATCH 179/204] Fix path. --- .cicd/generate-pipeline.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh index e00d441bf0..3e75a5c926 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -5,5 +5,5 @@ export MACOS_10_14_FILE_HASH="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/mac export MACOS_10_15_FILE_HASH="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" export VARS='$MACOS_10_14_FILE_HASH:$MACOS_10_15_FILE_HASH' envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" -buildkite-agent artifact upload pipeline.yml.out -buildkite-agent pipeline upload pipeline.yml.out +buildkite-agent artifact upload ./.cicd/pipeline.yml.out +buildkite-agent pipeline upload ./.cicd/pipeline.yml.out From 139a6d984cbac07f92034c030df00d9bae72928f Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 13:59:38 -0400 Subject: [PATCH 180/204] Try removing escapse characters. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index d7d3fb949e..09ed7cebef 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -98,7 +98,7 @@ steps: PROJECT_TAG: ${MACOS_10_14_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.14.6_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} @@ -137,7 +137,7 @@ steps: PROJECT_TAG: ${MACOS_10_15_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f \$BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.14.6_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} From 3369d2e008c1990fb87d63b72be7705de627842e Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 14:06:11 -0400 Subject: [PATCH 181/204] Correct ssh endpoint for mac-anka-fleet repo. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 09ed7cebef..e1766f06e1 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -91,7 +91,7 @@ steps: - 'registry-1' - 'registry-2' pre-commands: - - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" + - "rm -rf mac-anka-fleet; git clone git@github.com:EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" - EOSIO/skip-checkout#v0.1.1: cd: ~ env: @@ -130,7 +130,7 @@ steps: - 'registry-1' - 'registry-2' pre-commands: - - "rm -rf mac-anka-fleet; git clone git@github.com/EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" + - "rm -rf mac-anka-fleet; git clone git@github.com:EOSIO/mac-anka-fleet.git && cd mac-anka-fleet && . ./ensure-tag.bash -u 12 -r 25G -a '-n'" - EOSIO/skip-checkout#v0.1.1: cd: ~ env: From 2ce6709ceffd5bdd840cdf6d7e9ec6c9212cf51b Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 14:50:33 -0400 Subject: [PATCH 182/204] Fix bug with catalina VM. --- .cicd/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index e1766f06e1..28146502b7 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -138,7 +138,7 @@ steps: REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" - TEMPLATE: 10.14.6_6C_14G_80G + TEMPLATE: 10.15.5_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} agents: From 6a95f6bb10b099776cab4d88c4f588d98a953b37 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:00:02 -0400 Subject: [PATCH 183/204] Better naming for platforms. --- .cicd/generate-base-images.sh | 2 +- .cicd/helpers/docker-hash.sh | 2 +- .cicd/{docker => platforms}/amazonlinux-2.dockerfile | 0 .cicd/{docker => platforms}/centos-7.7.dockerfile | 0 .cicd/{docker => platforms}/centos-8.dockerfile | 0 .cicd/{docker => platforms}/macos-10.14.sh | 3 +-- .cicd/{docker => platforms}/macos-10.15.sh | 3 +-- .cicd/{docker => platforms}/ubuntu-16.04.dockerfile | 0 .cicd/{docker => platforms}/ubuntu-18.04.dockerfile | 0 .cicd/{docker => platforms}/ubuntu-20.04.dockerfile | 0 10 files changed, 4 insertions(+), 6 deletions(-) rename .cicd/{docker => platforms}/amazonlinux-2.dockerfile (100%) rename .cicd/{docker => platforms}/centos-7.7.dockerfile (100%) rename .cicd/{docker => platforms}/centos-8.dockerfile (100%) rename .cicd/{docker => platforms}/macos-10.14.sh (82%) rename .cicd/{docker => platforms}/macos-10.15.sh (82%) rename .cicd/{docker => platforms}/ubuntu-16.04.dockerfile (100%) rename .cicd/{docker => platforms}/ubuntu-18.04.dockerfile (100%) rename .cicd/{docker => platforms}/ubuntu-20.04.dockerfile (100%) diff --git a/.cicd/generate-base-images.sh b/.cicd/generate-base-images.sh index 94abce495c..7a141640a9 100755 --- a/.cicd/generate-base-images.sh +++ b/.cicd/generate-base-images.sh @@ -9,7 +9,7 @@ TAG=$(echo $FULL_TAG | cut -d: -f2) EXISTS=$(curl -s -H "Authorization: Bearer $(curl -sSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${ORG_REPO}:pull" | jq --raw-output .token)" "https://registry.hub.docker.com/v2/${ORG_REPO}/manifests/$TAG") # build, if neccessary if [[ $EXISTS =~ '404 page not found' || $EXISTS =~ 'manifest unknown' ]]; then # if we cannot pull the image, we build and push it first - docker build -t $FULL_TAG -f $CICD_DIR/docker/${IMAGE_TAG}.dockerfile . + docker build -t $FULL_TAG -f $CICD_DIR/platforms/${IMAGE_TAG}.dockerfile . docker push $FULL_TAG else echo "$FULL_TAG already exists." diff --git a/.cicd/helpers/docker-hash.sh b/.cicd/helpers/docker-hash.sh index 6dcd24b3c2..de838e8e65 100644 --- a/.cicd/helpers/docker-hash.sh +++ b/.cicd/helpers/docker-hash.sh @@ -16,7 +16,7 @@ function determine-hash() { } if [[ ! -z $IMAGE_TAG ]]; then - determine-hash "$CICD_DIR/docker/${IMAGE_TAG}.dockerfile" + determine-hash "$CICD_DIR/platforms/${IMAGE_TAG}.dockerfile" export FULL_TAG="eosio/ci:eosio-cdt-$HASHED_IMAGE_TAG" else echo "Please set ENV::IMAGE_TAG to match the name of a platform dockerfile..." diff --git a/.cicd/docker/amazonlinux-2.dockerfile b/.cicd/platforms/amazonlinux-2.dockerfile similarity index 100% rename from .cicd/docker/amazonlinux-2.dockerfile rename to .cicd/platforms/amazonlinux-2.dockerfile diff --git a/.cicd/docker/centos-7.7.dockerfile b/.cicd/platforms/centos-7.7.dockerfile similarity index 100% rename from .cicd/docker/centos-7.7.dockerfile rename to .cicd/platforms/centos-7.7.dockerfile diff --git a/.cicd/docker/centos-8.dockerfile b/.cicd/platforms/centos-8.dockerfile similarity index 100% rename from .cicd/docker/centos-8.dockerfile rename to .cicd/platforms/centos-8.dockerfile diff --git a/.cicd/docker/macos-10.14.sh b/.cicd/platforms/macos-10.14.sh similarity index 82% rename from .cicd/docker/macos-10.14.sh rename to .cicd/platforms/macos-10.14.sh index 2e54b40c5f..3c91271a9c 100755 --- a/.cicd/docker/macos-10.14.sh +++ b/.cicd/platforms/macos-10.14.sh @@ -2,6 +2,5 @@ set -eou pipefail VERSION=1 -brew update -brew upgrade +brew update && brew upgrade brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/docker/macos-10.15.sh b/.cicd/platforms/macos-10.15.sh similarity index 82% rename from .cicd/docker/macos-10.15.sh rename to .cicd/platforms/macos-10.15.sh index 2e54b40c5f..3c91271a9c 100755 --- a/.cicd/docker/macos-10.15.sh +++ b/.cicd/platforms/macos-10.15.sh @@ -2,6 +2,5 @@ set -eou pipefail VERSION=1 -brew update -brew upgrade +brew update && brew upgrade brew install automake cmake doxygen gettext git gmp graphviz lcov libtool python@3 wget diff --git a/.cicd/docker/ubuntu-16.04.dockerfile b/.cicd/platforms/ubuntu-16.04.dockerfile similarity index 100% rename from .cicd/docker/ubuntu-16.04.dockerfile rename to .cicd/platforms/ubuntu-16.04.dockerfile diff --git a/.cicd/docker/ubuntu-18.04.dockerfile b/.cicd/platforms/ubuntu-18.04.dockerfile similarity index 100% rename from .cicd/docker/ubuntu-18.04.dockerfile rename to .cicd/platforms/ubuntu-18.04.dockerfile diff --git a/.cicd/docker/ubuntu-20.04.dockerfile b/.cicd/platforms/ubuntu-20.04.dockerfile similarity index 100% rename from .cicd/docker/ubuntu-20.04.dockerfile rename to .cicd/platforms/ubuntu-20.04.dockerfile From 31fe6b70b005630c5f3b4e60ee7583ac2af8f55e Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:01:13 -0400 Subject: [PATCH 184/204] Use platforms in Mac steps. --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 28146502b7..520cec5e83 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -98,7 +98,7 @@ steps: PROJECT_TAG: ${MACOS_10_14_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.14.6_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} @@ -137,7 +137,7 @@ steps: PROJECT_TAG: ${MACOS_10_15_FILE_HASH} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT - TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/docker/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" + TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" TEMPLATE: 10.15.5_6C_14G_80G TEMPLATE_TAG: clean::cicd::git-ssh::nas::brew::buildkite-agent timeout: ${TIMEOUT:-120} From 8fb5b47ec99d879e53888252836a14592ac00d8b Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:02:45 -0400 Subject: [PATCH 185/204] More accurate variable naming. --- .cicd/generate-pipeline.sh | 6 +++--- .cicd/pipeline.yml | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh index 3e75a5c926..ba2e528851 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -1,9 +1,9 @@ #!/bin/bash set -eou pipefail -export MACOS_10_14_FILE_HASH="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" -export MACOS_10_15_FILE_HASH="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" -export VARS='$MACOS_10_14_FILE_HASH:$MACOS_10_15_FILE_HASH' +export MACOS_10_14_TAG="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" +export MACOS_10_15_TAG="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" +export VARS='$MACOS_10_14_TAG:$MACOS_10_15_TAG' envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" buildkite-agent artifact upload ./.cicd/pipeline.yml.out buildkite-agent pipeline upload ./.cicd/pipeline.yml.out diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 520cec5e83..7d5fd6e084 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -79,7 +79,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_TAG}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -95,7 +95,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MACOS_10_14_FILE_HASH} + PROJECT_TAG: ${MACOS_10_14_TAG} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.14.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -118,7 +118,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_TAG}" modify-cpu: 12 modify-ram: 24 always-pull: true @@ -134,7 +134,7 @@ steps: - EOSIO/skip-checkout#v0.1.1: cd: ~ env: - PROJECT_TAG: ${MACOS_10_15_FILE_HASH} + PROJECT_TAG: ${MACOS_10_15_TAG} REPO: ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} REPO_COMMIT: $BUILDKITE_COMMIT TAG_COMMANDS: "git clone ${BUILDKITE_PULL_REQUEST_REPO:-$BUILDKITE_REPO} eosio.cdt && cd eosio.cdt && git checkout -f $BUILDKITE_COMMIT && git submodule update --init --recursive && . ./.cicd/platforms/macos-10.15.sh && cd ~/eosio.cdt && cd .. && rm -rf eosio.cdt" @@ -225,7 +225,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_TAG}" always-pull: true debug: true wait-network: true @@ -252,7 +252,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_TAG}" always-pull: true debug: true wait-network: true @@ -345,7 +345,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.14.6_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_14_TAG}" always-pull: true debug: true wait-network: true @@ -372,7 +372,7 @@ steps: no-volume: true inherit-environment-vars: true vm-name: 10.15.5_6C_14G_80G - vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_FILE_HASH}" + vm-registry-tag: "clean::cicd::git-ssh::nas::brew::buildkite-agent::${MACOS_10_15_TAG}" always-pull: true debug: true wait-network: true From cd139f12211de1f217d74ad355c073235316cae6 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 29 Jun 2021 15:08:46 -0400 Subject: [PATCH 186/204] One more old docker dir instance updated. --- .cicd/generate-pipeline.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/generate-pipeline.sh b/.cicd/generate-pipeline.sh index ba2e528851..202cefcec1 100755 --- a/.cicd/generate-pipeline.sh +++ b/.cicd/generate-pipeline.sh @@ -1,8 +1,8 @@ #!/bin/bash set -eou pipefail -export MACOS_10_14_TAG="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/docker/macos-10.14.sh | awk '{print $1}')" -export MACOS_10_15_TAG="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/docker/macos-10.15.sh | awk '{print $1}')" +export MACOS_10_14_TAG="eosio-cdt-macos-10.14-$(sha1sum ./.cicd/platforms/macos-10.14.sh | awk '{print $1}')" +export MACOS_10_15_TAG="eosio-cdt-macos-10.15-$(sha1sum ./.cicd/platforms/macos-10.15.sh | awk '{print $1}')" export VARS='$MACOS_10_14_TAG:$MACOS_10_15_TAG' envsubst "$VARS" < "./.cicd/pipeline.yml" > "./.cicd/pipeline.yml.out" buildkite-agent artifact upload ./.cicd/pipeline.yml.out From 9b070c04623505a88b6913c652c79636dc8c9c8a Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 30 Jun 2021 09:48:40 -0400 Subject: [PATCH 187/204] Rename script. --- .cicd/{generate-pipeline.sh => pipeline-upload.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .cicd/{generate-pipeline.sh => pipeline-upload.sh} (100%) diff --git a/.cicd/generate-pipeline.sh b/.cicd/pipeline-upload.sh similarity index 100% rename from .cicd/generate-pipeline.sh rename to .cicd/pipeline-upload.sh From 823239cbe6e239a741858535b24b1c99aaf21a10 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 11:01:02 -0400 Subject: [PATCH 188/204] Add package test steps and scripts. --- .cicd/pipeline.yml | 83 +++++++++++++++++++++++++++++++++++++++ .cicd/test-package.run.sh | 25 ++++++++++++ .cicd/test-package.sh | 7 ++++ 3 files changed, 115 insertions(+) create mode 100755 .cicd/test-package.run.sh create mode 100755 .cicd/test-package.sh diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 7d5fd6e084..de0daabc5a 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -425,9 +425,23 @@ steps: PKGTYPE: "rpm" agents: queue: "automation-eks-eos-tester-fleet" + key: "amazonlinux2pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER} + - label: ":aws: Amazon_Linux 2 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':aws: Amazon_Linux 2 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "amazonlinux:2" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "amazonlinux2pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":centos: Centos 7.7 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 7.7 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -439,9 +453,23 @@ steps: PKGTYPE: "rpm" agents: queue: "automation-eks-eos-tester-fleet" + key: "centos7pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER} + - label: ":centos: Centos 7.7 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':centos: Centos 7.7 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "centos:7" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "cento7pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":centos: Centos 8 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 8 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -453,9 +481,23 @@ steps: PKGTYPE: "rpm" agents: queue: "automation-eks-eos-tester-fleet" + key: "centos8pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER} + - label: ":centos: Centos 8 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':centos: Centos 8 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "centos:8" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "cento8pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":ubuntu: Ubuntu 16.04 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 16.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -470,6 +512,19 @@ steps: timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 16.04 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':ubuntu: Ubuntu 16.04 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "ubuntu:16.04" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "ubuntu1604pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":ubuntu: Ubuntu 18.04 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -481,9 +536,23 @@ steps: PKGTYPE: "deb" agents: queue: "automation-eks-eos-tester-fleet" + key: "ubuntu1804pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 18.04 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':ubuntu: Ubuntu 18.04 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "ubuntu:18.04" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "ubuntu1804pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":ubuntu: Ubuntu 20.04 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 20.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -495,9 +564,23 @@ steps: PKGTYPE: "deb" agents: queue: "automation-eks-eos-tester-fleet" + key: "ubuntu2004pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 20.04 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':ubuntu: Ubuntu 20.04 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "ubuntu:20.04" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "ubuntu2004pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":darwin: Mojave - Package Builder" command: - "git clone $BUILDKITE_REPO eosio.cdt" diff --git a/.cicd/test-package.run.sh b/.cicd/test-package.run.sh new file mode 100755 index 0000000000..1f571d2e02 --- /dev/null +++ b/.cicd/test-package.run.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -eu + +echo '+++ :minidisc: Installing EOSIO CDT' + +if [[ $(apt-get --version 2>/dev/null) ]]; then # debian family + UPDATE='apt-get update' + echo "$ $UPDATE" + eval $UPDATE + INSTALL="apt-get install -y /eos/*.deb" + echo "$ $INSTALL" + eval $INSTALL +elif [[ $(yum --version 2>/dev/null) ]]; then # RHEL family + UPDATE='yum check-update || :' + echo "$ $UPDATE" + eval $UPDATE + INSTALL="yum install -y /eos/*.rpm" + echo "$ $INSTALL" + eval $INSTALL +else + echo 'ERROR: Package manager not detected!' + exit 3 +fi + +eosio-cpp --version diff --git a/.cicd/test-package.sh b/.cicd/test-package.sh new file mode 100755 index 0000000000..039f939fa4 --- /dev/null +++ b/.cicd/test-package.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -eu + +echo '--- :docker: Selecting Container' + +docker pull $IMAGE +docker run --rm -v "$(pwd):/eos" -w '/eos' -it $IMAGE ./.cicd/test-package.run.sh From fd35c06e09c66f47c7d0d19a441596c2c7682e65 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 11:11:31 -0400 Subject: [PATCH 189/204] Add support for SKIP_LINUX variable. --- .cicd/pipeline.yml | 62 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index de0daabc5a..edbeecd0c7 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -10,7 +10,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_AMAZON_LINUX_2 + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX} - label: ":centos: CentOS 7.7 - Build" command: @@ -21,7 +21,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_CENTOS_7 + skip: ${SKIP_CENTOS_7}${SKIP_LINUX} - label: ":centos: CentOS 8 - Build" command: @@ -32,7 +32,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_CENTOS_8 + skip: ${SKIP_CENTOS_8}${SKIP_LINUX} - label: ":ubuntu: Ubuntu 16.04 - Build" command: @@ -43,7 +43,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_UBUNTU_16 + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX} - label: ":ubuntu: Ubuntu 18.04 - Build" command: @@ -54,7 +54,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_UBUNTU_18 + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX} - label: ":ubuntu: Ubuntu 20.04 - Build" command: @@ -65,7 +65,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_UBUNTU_20 + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX} - label: ":darwin: macOS 10.14 - Build" command: @@ -156,7 +156,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_UNIT_TESTS} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":centos: CentOS 7.7 - Unit Tests" command: @@ -167,7 +167,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_UNIT_TESTS} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":centos: CentOS 8 - Unit Tests" command: @@ -178,7 +178,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_UNIT_TESTS} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":ubuntu: Ubuntu 16.04 - Unit Tests" command: @@ -189,7 +189,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_UNIT_TESTS} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Unit Tests" command: @@ -200,7 +200,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_UNIT_TESTS} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":ubuntu: Ubuntu 20.04 - Unit Tests" command: @@ -211,7 +211,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_UNIT_TESTS} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":darwin: macOS 10.14 - Unit Tests" command: @@ -276,7 +276,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":centos: CentOS 7.7 - Toolchain Tests" command: @@ -287,7 +287,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":centos: CentOS 8 - Toolchain Tests" command: @@ -298,7 +298,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 16.04 - Toolchain Tests" command: @@ -309,7 +309,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Toolchain Tests" command: @@ -320,7 +320,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 20.04 - Toolchain Tests" command: @@ -331,7 +331,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":darwin: macOS 10.14 - Toolchain Tests" command: @@ -396,7 +396,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_INTEGRATION_TESTS} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_INTEGRATION_TESTS} - wait: continue_on_failure: true @@ -427,7 +427,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "amazonlinux2pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":aws: Amazon_Linux 2 - Test Package" command: | @@ -440,7 +440,7 @@ steps: depends_on: "amazonlinux2pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 7.7 - Package Builder" command: @@ -455,7 +455,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "centos7pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 7.7 - Test Package" command: | @@ -468,7 +468,7 @@ steps: depends_on: "cento7pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 8 - Package Builder" command: @@ -483,7 +483,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "centos8pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 8 - Test Package" command: | @@ -496,7 +496,7 @@ steps: depends_on: "cento8pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 16.04 - Package Builder" command: @@ -510,7 +510,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 16.04 - Test Package" command: | @@ -523,7 +523,7 @@ steps: depends_on: "ubuntu1604pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 18.04 - Package Builder" command: @@ -538,7 +538,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "ubuntu1804pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 18.04 - Test Package" command: | @@ -551,7 +551,7 @@ steps: depends_on: "ubuntu1804pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 20.04 - Package Builder" command: @@ -566,7 +566,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "ubuntu2004pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 20.04 - Test Package" command: | @@ -579,7 +579,7 @@ steps: depends_on: "ubuntu2004pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":darwin: Mojave - Package Builder" command: From cf9dabdbcee2aa5ac5471c950fd9b73f14db529e Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 13:49:10 -0400 Subject: [PATCH 190/204] BUILDKITE_TEST_AGENT_QUEUE variable from eos pipeline isn't used in CDT. --- .cicd/pipeline.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index edbeecd0c7..2d245049b3 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -436,7 +436,7 @@ steps: env: IMAGE: "amazonlinux:2" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "amazonlinux2pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -464,7 +464,7 @@ steps: env: IMAGE: "centos:7" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "cento7pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -492,7 +492,7 @@ steps: env: IMAGE: "centos:8" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "cento8pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -519,7 +519,7 @@ steps: env: IMAGE: "ubuntu:16.04" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "ubuntu1604pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -547,7 +547,7 @@ steps: env: IMAGE: "ubuntu:18.04" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "ubuntu1804pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -575,7 +575,7 @@ steps: env: IMAGE: "ubuntu:20.04" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "ubuntu2004pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} From 6d3ef72b7f5be14c0c7264df4116e318ee6b9586 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 15:29:54 -0400 Subject: [PATCH 191/204] Bugfix for dependency keys and artifact types. --- .cicd/pipeline.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 2d245049b3..049ecb3624 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -431,7 +431,7 @@ steps: - label: ":aws: Amazon_Linux 2 - Test Package" command: | - buildkite-agent artifact download '*.deb' . --step ':aws: Amazon_Linux 2 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + buildkite-agent artifact download '*.rpm' . --step ':aws: Amazon_Linux 2 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN ./.cicd/test-package.sh env: IMAGE: "amazonlinux:2" @@ -459,13 +459,13 @@ steps: - label: ":centos: Centos 7.7 - Test Package" command: | - buildkite-agent artifact download '*.deb' . --step ':centos: Centos 7.7 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + buildkite-agent artifact download '*.rpm' . --step ':centos: Centos 7.7 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN ./.cicd/test-package.sh env: IMAGE: "centos:7" agents: queue: "automation-eks-eos-tester-fleet" - depends_on: "cento7pb" + depends_on: "centos7pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} @@ -487,13 +487,13 @@ steps: - label: ":centos: Centos 8 - Test Package" command: | - buildkite-agent artifact download '*.deb' . --step ':centos: Centos 8 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + buildkite-agent artifact download '*.rpm' . --step ':centos: Centos 8 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN ./.cicd/test-package.sh env: IMAGE: "centos:8" agents: queue: "automation-eks-eos-tester-fleet" - depends_on: "cento8pb" + depends_on: "centos8pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} @@ -509,6 +509,7 @@ steps: PKGTYPE: "deb" agents: queue: "automation-eks-eos-tester-fleet" + key: "ubuntu1604pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} From d7ba805ec64c301f8bd4e98ad6d401ce759dbb6b Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 11:01:02 -0400 Subject: [PATCH 192/204] Add package test steps and scripts. --- .cicd/pipeline.yml | 83 +++++++++++++++++++++++++++++++++++++++ .cicd/test-package.run.sh | 25 ++++++++++++ .cicd/test-package.sh | 7 ++++ 3 files changed, 115 insertions(+) create mode 100755 .cicd/test-package.run.sh create mode 100755 .cicd/test-package.sh diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 7d5fd6e084..de0daabc5a 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -425,9 +425,23 @@ steps: PKGTYPE: "rpm" agents: queue: "automation-eks-eos-tester-fleet" + key: "amazonlinux2pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER} + - label: ":aws: Amazon_Linux 2 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':aws: Amazon_Linux 2 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "amazonlinux:2" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "amazonlinux2pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":centos: Centos 7.7 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 7.7 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -439,9 +453,23 @@ steps: PKGTYPE: "rpm" agents: queue: "automation-eks-eos-tester-fleet" + key: "centos7pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER} + - label: ":centos: Centos 7.7 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':centos: Centos 7.7 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "centos:7" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "cento7pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":centos: Centos 8 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':centos: CentOS 8 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -453,9 +481,23 @@ steps: PKGTYPE: "rpm" agents: queue: "automation-eks-eos-tester-fleet" + key: "centos8pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER} + - label: ":centos: Centos 8 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':centos: Centos 8 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "centos:8" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "cento8pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":ubuntu: Ubuntu 16.04 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 16.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -470,6 +512,19 @@ steps: timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 16.04 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':ubuntu: Ubuntu 16.04 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "ubuntu:16.04" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "ubuntu1604pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":ubuntu: Ubuntu 18.04 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -481,9 +536,23 @@ steps: PKGTYPE: "deb" agents: queue: "automation-eks-eos-tester-fleet" + key: "ubuntu1804pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 18.04 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':ubuntu: Ubuntu 18.04 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "ubuntu:18.04" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "ubuntu1804pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":ubuntu: Ubuntu 20.04 - Package Builder" command: - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 20.04 - Build' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN && tar -xzf build.tar.gz" @@ -495,9 +564,23 @@ steps: PKGTYPE: "deb" agents: queue: "automation-eks-eos-tester-fleet" + key: "ubuntu2004pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER} + - label: ":ubuntu: Ubuntu 20.04 - Test Package" + command: | + buildkite-agent artifact download '*.deb' . --step ':ubuntu: Ubuntu 20.04 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + ./.cicd/test-package.sh + env: + IMAGE: "ubuntu:20.04" + agents: + queue: "$BUILDKITE_TEST_AGENT_QUEUE" + depends_on: "ubuntu2004pb" + allow_dependency_failure: false + timeout: ${TIMEOUT:-10} + skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + - label: ":darwin: Mojave - Package Builder" command: - "git clone $BUILDKITE_REPO eosio.cdt" diff --git a/.cicd/test-package.run.sh b/.cicd/test-package.run.sh new file mode 100755 index 0000000000..1f571d2e02 --- /dev/null +++ b/.cicd/test-package.run.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -eu + +echo '+++ :minidisc: Installing EOSIO CDT' + +if [[ $(apt-get --version 2>/dev/null) ]]; then # debian family + UPDATE='apt-get update' + echo "$ $UPDATE" + eval $UPDATE + INSTALL="apt-get install -y /eos/*.deb" + echo "$ $INSTALL" + eval $INSTALL +elif [[ $(yum --version 2>/dev/null) ]]; then # RHEL family + UPDATE='yum check-update || :' + echo "$ $UPDATE" + eval $UPDATE + INSTALL="yum install -y /eos/*.rpm" + echo "$ $INSTALL" + eval $INSTALL +else + echo 'ERROR: Package manager not detected!' + exit 3 +fi + +eosio-cpp --version diff --git a/.cicd/test-package.sh b/.cicd/test-package.sh new file mode 100755 index 0000000000..039f939fa4 --- /dev/null +++ b/.cicd/test-package.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -eu + +echo '--- :docker: Selecting Container' + +docker pull $IMAGE +docker run --rm -v "$(pwd):/eos" -w '/eos' -it $IMAGE ./.cicd/test-package.run.sh From caf7a7faf52e780b576a0866625199d3d082d650 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 11:11:31 -0400 Subject: [PATCH 193/204] Add support for SKIP_LINUX variable. --- .cicd/pipeline.yml | 62 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index de0daabc5a..edbeecd0c7 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -10,7 +10,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_AMAZON_LINUX_2 + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX} - label: ":centos: CentOS 7.7 - Build" command: @@ -21,7 +21,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_CENTOS_7 + skip: ${SKIP_CENTOS_7}${SKIP_LINUX} - label: ":centos: CentOS 8 - Build" command: @@ -32,7 +32,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_CENTOS_8 + skip: ${SKIP_CENTOS_8}${SKIP_LINUX} - label: ":ubuntu: Ubuntu 16.04 - Build" command: @@ -43,7 +43,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_UBUNTU_16 + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX} - label: ":ubuntu: Ubuntu 18.04 - Build" command: @@ -54,7 +54,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_UBUNTU_18 + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX} - label: ":ubuntu: Ubuntu 20.04 - Build" command: @@ -65,7 +65,7 @@ steps: agents: queue: "automation-eks-eos-builder-fleet" timeout: ${TIMEOUT:-60} - skip: $SKIP_UBUNTU_20 + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX} - label: ":darwin: macOS 10.14 - Build" command: @@ -156,7 +156,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_UNIT_TESTS} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":centos: CentOS 7.7 - Unit Tests" command: @@ -167,7 +167,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_UNIT_TESTS} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":centos: CentOS 8 - Unit Tests" command: @@ -178,7 +178,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_UNIT_TESTS} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":ubuntu: Ubuntu 16.04 - Unit Tests" command: @@ -189,7 +189,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_UNIT_TESTS} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Unit Tests" command: @@ -200,7 +200,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_UNIT_TESTS} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":ubuntu: Ubuntu 20.04 - Unit Tests" command: @@ -211,7 +211,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_UNIT_TESTS} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_UNIT_TESTS} - label: ":darwin: macOS 10.14 - Unit Tests" command: @@ -276,7 +276,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":centos: CentOS 7.7 - Toolchain Tests" command: @@ -287,7 +287,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":centos: CentOS 8 - Toolchain Tests" command: @@ -298,7 +298,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 16.04 - Toolchain Tests" command: @@ -309,7 +309,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 18.04 - Toolchain Tests" command: @@ -320,7 +320,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":ubuntu: Ubuntu 20.04 - Toolchain Tests" command: @@ -331,7 +331,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_TOOLCHAIN_TESTS} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_TOOLCHAIN_TESTS} - label: ":darwin: macOS 10.14 - Toolchain Tests" command: @@ -396,7 +396,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_INTEGRATION_TESTS} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_INTEGRATION_TESTS} - wait: continue_on_failure: true @@ -427,7 +427,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "amazonlinux2pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":aws: Amazon_Linux 2 - Test Package" command: | @@ -440,7 +440,7 @@ steps: depends_on: "amazonlinux2pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_AMAZON_LINUX_2}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_AMAZON_LINUX_2}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 7.7 - Package Builder" command: @@ -455,7 +455,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "centos7pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 7.7 - Test Package" command: | @@ -468,7 +468,7 @@ steps: depends_on: "cento7pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_7}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 8 - Package Builder" command: @@ -483,7 +483,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "centos8pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":centos: Centos 8 - Test Package" command: | @@ -496,7 +496,7 @@ steps: depends_on: "cento8pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_CENTOS_8}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 16.04 - Package Builder" command: @@ -510,7 +510,7 @@ steps: agents: queue: "automation-eks-eos-tester-fleet" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 16.04 - Test Package" command: | @@ -523,7 +523,7 @@ steps: depends_on: "ubuntu1604pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_16}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 18.04 - Package Builder" command: @@ -538,7 +538,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "ubuntu1804pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 18.04 - Test Package" command: | @@ -551,7 +551,7 @@ steps: depends_on: "ubuntu1804pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_18}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_UBUNTU_18}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 20.04 - Package Builder" command: @@ -566,7 +566,7 @@ steps: queue: "automation-eks-eos-tester-fleet" key: "ubuntu2004pb" timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":ubuntu: Ubuntu 20.04 - Test Package" command: | @@ -579,7 +579,7 @@ steps: depends_on: "ubuntu2004pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} - skip: ${SKIP_UBUNTU_20}${SKIP_PACKAGE_BUILDER}${SKIP_LINUX} + skip: ${SKIP_UBUNTU_20}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} - label: ":darwin: Mojave - Package Builder" command: From 0e231c3132a510bcf349f7a1a8b2196f6626f4e9 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 13:49:10 -0400 Subject: [PATCH 194/204] BUILDKITE_TEST_AGENT_QUEUE variable from eos pipeline isn't used in CDT. --- .cicd/pipeline.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index edbeecd0c7..2d245049b3 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -436,7 +436,7 @@ steps: env: IMAGE: "amazonlinux:2" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "amazonlinux2pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -464,7 +464,7 @@ steps: env: IMAGE: "centos:7" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "cento7pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -492,7 +492,7 @@ steps: env: IMAGE: "centos:8" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "cento8pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -519,7 +519,7 @@ steps: env: IMAGE: "ubuntu:16.04" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "ubuntu1604pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -547,7 +547,7 @@ steps: env: IMAGE: "ubuntu:18.04" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "ubuntu1804pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} @@ -575,7 +575,7 @@ steps: env: IMAGE: "ubuntu:20.04" agents: - queue: "$BUILDKITE_TEST_AGENT_QUEUE" + queue: "automation-eks-eos-tester-fleet" depends_on: "ubuntu2004pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} From 74d90cdf39f50625cbf3edf8e9688059fad887c2 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Thu, 1 Jul 2021 15:29:54 -0400 Subject: [PATCH 195/204] Bugfix for dependency keys and artifact types. --- .cicd/pipeline.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 2d245049b3..049ecb3624 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -431,7 +431,7 @@ steps: - label: ":aws: Amazon_Linux 2 - Test Package" command: | - buildkite-agent artifact download '*.deb' . --step ':aws: Amazon_Linux 2 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + buildkite-agent artifact download '*.rpm' . --step ':aws: Amazon_Linux 2 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN ./.cicd/test-package.sh env: IMAGE: "amazonlinux:2" @@ -459,13 +459,13 @@ steps: - label: ":centos: Centos 7.7 - Test Package" command: | - buildkite-agent artifact download '*.deb' . --step ':centos: Centos 7.7 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + buildkite-agent artifact download '*.rpm' . --step ':centos: Centos 7.7 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN ./.cicd/test-package.sh env: IMAGE: "centos:7" agents: queue: "automation-eks-eos-tester-fleet" - depends_on: "cento7pb" + depends_on: "centos7pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_7}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} @@ -487,13 +487,13 @@ steps: - label: ":centos: Centos 8 - Test Package" command: | - buildkite-agent artifact download '*.deb' . --step ':centos: Centos 8 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN + buildkite-agent artifact download '*.rpm' . --step ':centos: Centos 8 - Package Builder' --agent-access-token $$BUILDKITE_AGENT_ACCESS_TOKEN ./.cicd/test-package.sh env: IMAGE: "centos:8" agents: queue: "automation-eks-eos-tester-fleet" - depends_on: "cento8pb" + depends_on: "centos8pb" allow_dependency_failure: false timeout: ${TIMEOUT:-10} skip: ${SKIP_CENTOS_8}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} @@ -509,6 +509,7 @@ steps: PKGTYPE: "deb" agents: queue: "automation-eks-eos-tester-fleet" + key: "ubuntu1604pb" timeout: ${TIMEOUT:-10} skip: ${SKIP_UBUNTU_16}${SKIP_LINUX}${SKIP_PACKAGE_BUILDER} From 2b5b429b04936023de52ae56448e791e979c2659 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Fri, 2 Jul 2021 10:14:46 -0400 Subject: [PATCH 196/204] bump eosio_llvm submodule commit to head --- eosio_llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio_llvm b/eosio_llvm index a14a183af1..d700c78db1 160000 --- a/eosio_llvm +++ b/eosio_llvm @@ -1 +1 @@ -Subproject commit a14a183af1178567b76b78efabff8fbfe035b07a +Subproject commit d700c78db1918c7a2783c37a97d42d6fcd223e4d From 60a5b9b4291127afccdaee735824f941609928fe Mon Sep 17 00:00:00 2001 From: iamveritas Date: Mon, 5 Jul 2021 15:23:02 +0300 Subject: [PATCH 197/204] re-org the best practices menu with the feaures one --- .../100_deferred_transactions.md} | 0 .../20_return_values_from_actions.md} | 0 .../13_binary-extension.md => 05_features/30_binary-extension.md} | 0 .../40_native-tester-compilation.md} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename docs/{07_best-practices/09_deferred_transactions.md => 05_features/100_deferred_transactions.md} (100%) rename docs/{07_best-practices/12_return_values_from_actions.md => 05_features/20_return_values_from_actions.md} (100%) rename docs/{07_best-practices/13_binary-extension.md => 05_features/30_binary-extension.md} (100%) rename docs/{07_best-practices/10_native-tester-compilation.md => 05_features/40_native-tester-compilation.md} (100%) diff --git a/docs/07_best-practices/09_deferred_transactions.md b/docs/05_features/100_deferred_transactions.md similarity index 100% rename from docs/07_best-practices/09_deferred_transactions.md rename to docs/05_features/100_deferred_transactions.md diff --git a/docs/07_best-practices/12_return_values_from_actions.md b/docs/05_features/20_return_values_from_actions.md similarity index 100% rename from docs/07_best-practices/12_return_values_from_actions.md rename to docs/05_features/20_return_values_from_actions.md diff --git a/docs/07_best-practices/13_binary-extension.md b/docs/05_features/30_binary-extension.md similarity index 100% rename from docs/07_best-practices/13_binary-extension.md rename to docs/05_features/30_binary-extension.md diff --git a/docs/07_best-practices/10_native-tester-compilation.md b/docs/05_features/40_native-tester-compilation.md similarity index 100% rename from docs/07_best-practices/10_native-tester-compilation.md rename to docs/05_features/40_native-tester-compilation.md From 67b8a91621fcaa89c79e7daaf4956ae9998a5210 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Mon, 5 Jul 2021 15:28:47 +0300 Subject: [PATCH 198/204] updates --- docs/05_features/30_binary-extension.md | 2 +- docs/05_features/40_native-tester-compilation.md | 2 +- ...100_deferred_transactions.md => 99_deferred_transactions.md} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename docs/05_features/{100_deferred_transactions.md => 99_deferred_transactions.md} (97%) diff --git a/docs/05_features/30_binary-extension.md b/docs/05_features/30_binary-extension.md index e500ae06d1..d92e114d0e 100644 --- a/docs/05_features/30_binary-extension.md +++ b/docs/05_features/30_binary-extension.md @@ -1,5 +1,5 @@ --- -content_title: The eosio::binary_extension type +content_title: The eosio::binary_extension Type --- Let's fully explain what the `eosio::binary_extension` type is, what it does, and why we need it for contract upgrades in certain situations. diff --git a/docs/05_features/40_native-tester-compilation.md b/docs/05_features/40_native-tester-compilation.md index c1dc48e348..3391424991 100644 --- a/docs/05_features/40_native-tester-compilation.md +++ b/docs/05_features/40_native-tester-compilation.md @@ -1,5 +1,5 @@ --- -content_title: How to use native tester/compilation +content_title: Native Tester And Compilation --- As of v1.5.0 native compilation can be performed and a new set of libraries to facilitate native testing and native "scratch pad" compilation. [`eosio-cc`](../03_command-reference/eosio-cc.md), [`eosio-cpp`](../03_command-reference/eosio-cpp.md) and [`eosio-ld`](../03_command-reference/eosio-ld.md) now support building "smart contracts" and unit tests natively for quick tests to help facilitate faster development \(note the default implementations of eosio `intrinsics` are currently asserts that state they are unavailable, these are user definable.\) diff --git a/docs/05_features/100_deferred_transactions.md b/docs/05_features/99_deferred_transactions.md similarity index 97% rename from docs/05_features/100_deferred_transactions.md rename to docs/05_features/99_deferred_transactions.md index 82036a6734..12e5d82c5b 100644 --- a/docs/05_features/100_deferred_transactions.md +++ b/docs/05_features/99_deferred_transactions.md @@ -1,5 +1,5 @@ --- -content_title: Deferred transactions +content_title: Deferred Transactions --- Deferred communication conceptually takes the form of action notifications sent to a peer transaction. Deferred actions get scheduled to run, at best, at a later time, at the producer's discretion. There is no guarantee that a deferred action will be executed. From 2c0deed318c3dc1e2090d7d12a52f8fd75a6e6f4 Mon Sep 17 00:00:00 2001 From: Qing Yang Date: Tue, 6 Jul 2021 14:08:56 -0400 Subject: [PATCH 199/204] Revert "Merge pull request #1093 from EOSIO/qy-map-nest-epe811" This reverts commit 2d0bb4f5bbfd3c419466be3f403003d20207d2a5, reversing changes made to bef15f507447f334d3bf2435a8d2b91defefbe1c. --- .../abigen-pass/nested_container.abi | 61 ------------------- .../abigen-pass/nested_container.cpp | 13 ---- .../abigen-pass/nested_container.json | 9 --- tools/include/eosio/abigen.hpp | 9 +-- 4 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 tests/toolchain/abigen-pass/nested_container.abi delete mode 100644 tests/toolchain/abigen-pass/nested_container.cpp delete mode 100644 tests/toolchain/abigen-pass/nested_container.json diff --git a/tests/toolchain/abigen-pass/nested_container.abi b/tests/toolchain/abigen-pass/nested_container.abi deleted file mode 100644 index ba0f5698ec..0000000000 --- a/tests/toolchain/abigen-pass/nested_container.abi +++ /dev/null @@ -1,61 +0,0 @@ -{ - "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", - "version": "eosio::abi/1.2", - "types": [], - "structs": [ - { - "name": "map2map", - "base": "", - "fields": [ - { - "name": "m", - "type": "pair_string_string[]" - }, - { - "name": "m2m", - "type": "pair_string_pair_string_string[][]" - } - ] - }, - { - "name": "pair_string_pair_string_string", - "base": "", - "fields": [ - { - "name": "key", - "type": "string" - }, - { - "name": "value", - "type": "pair_string_string[]" - } - ] - }, - { - "name": "pair_string_string", - "base": "", - "fields": [ - { - "name": "key", - "type": "string" - }, - { - "name": "value", - "type": "string" - } - ] - } - ], - "actions": [ - { - "name": "map2map", - "type": "map2map", - "ricardian_contract": "" - } - ], - "tables": [], - "kv_tables": {}, - "ricardian_clauses": [], - "variants": [], - "action_results": [] -} diff --git a/tests/toolchain/abigen-pass/nested_container.cpp b/tests/toolchain/abigen-pass/nested_container.cpp deleted file mode 100644 index 4c0a16c75a..0000000000 --- a/tests/toolchain/abigen-pass/nested_container.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include - -using namespace eosio; -using std::map; -using std::string; - -class [[eosio::contract]] nested_container : public contract { -public: - using contract::contract; - - [[eosio::action]] - void map2map(map m, map> m2m) {} -}; diff --git a/tests/toolchain/abigen-pass/nested_container.json b/tests/toolchain/abigen-pass/nested_container.json deleted file mode 100644 index 4f2c8aae7f..0000000000 --- a/tests/toolchain/abigen-pass/nested_container.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "tests" : [ - { - "expected" : { - "abi-file" : "nested_container.abi" - } - } - ] -} diff --git a/tools/include/eosio/abigen.hpp b/tools/include/eosio/abigen.hpp index d671c8af9f..e27ac94a19 100644 --- a/tools/include/eosio/abigen.hpp +++ b/tools/include/eosio/abigen.hpp @@ -169,14 +169,7 @@ namespace eosio { namespace cdt { } abi_struct kv; std::string name = get_type(type); - auto remove_ending_brackets = [&]( std::string name ) { - int i = name.length()-1; - for (; i >= 0; i--) - if ( name[i] != '[' && name[i] != ']' ) - break; - return name.substr(0,i+1); - }; - kv.name = remove_ending_brackets(name); + kv.name = name.substr(0, name.length() - 2); kv.fields.push_back( {"key", get_template_argument_as_string(type)} ); kv.fields.push_back( {"value", get_template_argument_as_string(type, 1)} ); add_type(std::get(get_template_argument(type))); From 2cca5fcfa54df67884d9cc2c8debe2f4000a27a9 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 7 Jul 2021 14:14:59 -0400 Subject: [PATCH 200/204] Update version test to use raw version to make downstream cicd-isms easier. --- tests/CMakeLists.txt | 2 +- tests/unit/version_tests.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index eb2f4b0a18..c254fbbe64 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,7 +35,7 @@ add_test( NAME toolchain_tests COMMAND ${CMAKE_BINARY_DIR}/tools/toolchain-teste set_property(TEST toolchain_tests PROPERTY LABELS toolchain_tests) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unit/version_tests.sh ${CMAKE_BINARY_DIR}/tests/unit/version_tests.sh COPYONLY) -add_test(NAME version_tests COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version_tests.sh "eosio-cpp version ${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) +add_test(NAME version_tests COMMAND ${CMAKE_BINARY_DIR}/tests/unit/version_tests.sh "${VERSION_FULL}" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) set_property(TEST version_tests PROPERTY LABELS unit_tests) if (eosio_FOUND) diff --git a/tests/unit/version_tests.sh b/tests/unit/version_tests.sh index 45698e9396..e1c6723a41 100755 --- a/tests/unit/version_tests.sh +++ b/tests/unit/version_tests.sh @@ -8,7 +8,7 @@ echo "Using BUILD_ROOT=\"$BUILD_ROOT\"." # test expectations if [[ -z "$EXPECTED" ]]; then [[ -z "$BUILDKITE_TAG" ]] && export BUILDKITE_TAG="${GIT_TAG:-$1}" - export EXPECTED="$BUILDKITE_TAG" + export EXPECTED="eosio-cpp version $BUILDKITE_TAG" fi if [[ -z "$EXPECTED" ]]; then echo "Missing version input." From 27cbde2bdf096910478a758614c3e4dbdfc70f89 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Wed, 7 Jul 2021 14:32:45 -0400 Subject: [PATCH 201/204] Update version test to trim leading 'v' from git tags. --- tests/unit/version_tests.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/unit/version_tests.sh b/tests/unit/version_tests.sh index e1c6723a41..2ff40cefc1 100755 --- a/tests/unit/version_tests.sh +++ b/tests/unit/version_tests.sh @@ -7,8 +7,12 @@ echo '##### Eosio-cpp Version Label Test #####' echo "Using BUILD_ROOT=\"$BUILD_ROOT\"." # test expectations if [[ -z "$EXPECTED" ]]; then - [[ -z "$BUILDKITE_TAG" ]] && export BUILDKITE_TAG="${GIT_TAG:-$1}" - export EXPECTED="eosio-cpp version $BUILDKITE_TAG" + if [[ -z "$1" ]]; then + export VERSION="$(echo ${BUILDKITE_TAG:-$GIT_TAG} | sed "s/^v//")" + else + export VERSION="$1" + fi + export EXPECTED="eosio-cpp version $VERSION" fi if [[ -z "$EXPECTED" ]]; then echo "Missing version input." From ba56eca80bb4e648de130181c5820af9c7744bb1 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Fri, 9 Jul 2021 11:31:20 -0400 Subject: [PATCH 202/204] Disable CI systems who may not want to push to DockerHub. --- .cicd/create-docker-from-binary.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.cicd/create-docker-from-binary.sh b/.cicd/create-docker-from-binary.sh index eac0ec34b8..465a4312ad 100755 --- a/.cicd/create-docker-from-binary.sh +++ b/.cicd/create-docker-from-binary.sh @@ -16,7 +16,11 @@ echo "$ $DOCKER_BUILD" eval $DOCKER_BUILD # docker tag echo '--- :label: Tag Container' -REGISTRIES=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") +if [[ "$BUILDKITE_PIPELINE_SLUG" =~ "-sec" ]] ; then + REGISTRIES=("$EOSIO_CDT_REGISTRY") +else + REGISTRIES=("$EOSIO_CDT_REGISTRY" "$DOCKERHUB_REGISTRY") +fi for REG in ${REGISTRIES[@]}; do DOCKER_TAG_BRANCH="docker tag '$IMAGE' '$REG:$SANITIZED_BRANCH'" echo "$ $DOCKER_TAG_BRANCH" From 922c7536f989fe6f9e47debe9b53154dff10fd6a Mon Sep 17 00:00:00 2001 From: Victor Camacho Date: Mon, 12 Jul 2021 10:34:49 -0400 Subject: [PATCH 203/204] Bump version to v1.8.1 --- CMakeLists.txt | 2 +- README.md | 10 +++++----- docs/02_installation/index.md | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 871bf33972..3c81ebdc07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ endif() set(VERSION_MAJOR 1) set(VERSION_MINOR 8) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) #set(VERSION_SUFFIX rc2) if (VERSION_SUFFIX) diff --git a/README.md b/README.md index 1dd41a3157..7e2c621260 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # EOSIO.CDT (Contract Development Toolkit) -## Version : 1.8.0 +## Version : 1.8.1 EOSIO.CDT is a toolchain for WebAssembly (WASM) and a set of tools to facilitate smart contract development for the EOSIO platform. In addition to being a general purpose WebAssembly toolchain, [EOSIO](https://github.com/eosio/eos) specific optimizations are available to support building EOSIO smart contracts. This new toolchain is built around [Clang 9](https://github.com/eosio/llvm), which means that EOSIO.CDT has the most currently available optimizations and analyses from LLVM, but as the WASM target is still considered experimental, some optimizations are incomplete or not available. @@ -28,8 +28,8 @@ brew remove eosio.cdt ### Debian Package Install ```sh -wget https://github.com/eosio/eosio.cdt/releases/download/v1.8.0/eosio.cdt_1.8.0-1-ubuntu-18.04_amd64.deb -sudo apt install ./eosio.cdt_1.8.0-1-ubuntu-18.04_amd64.deb +wget https://github.com/eosio/eosio.cdt/releases/download/v1.8.1/eosio.cdt_1.8.1-1-ubuntu-18.04_amd64.deb +sudo apt install ./eosio.cdt_1.8.1-1-ubuntu-18.04_amd64.deb ``` ### Debian Package Uninstall @@ -39,8 +39,8 @@ sudo apt remove eosio.cdt ### RPM Package Install ```sh -wget https://github.com/eosio/eosio.cdt/releases/download/v1.8.0/eosio.cdt-1.8.0-1.el7.x86_64.rpm -sudo yum install ./eosio.cdt-1.8.0-1.el7.x86_64.rpm +wget https://github.com/eosio/eosio.cdt/releases/download/v1.8.1/eosio.cdt-1.8.1-1.el7.x86_64.rpm +sudo yum install ./eosio.cdt-1.8.1-1.el7.x86_64.rpm ``` ### RPM Package Uninstall diff --git a/docs/02_installation/index.md b/docs/02_installation/index.md index a611c652a2..3b8fd6e2ff 100644 --- a/docs/02_installation/index.md +++ b/docs/02_installation/index.md @@ -22,8 +22,8 @@ brew remove eosio.cdt ## Debian Package Install ```sh -wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb -sudo apt install ./eosio.cdt_1.8.0-rc1-ubuntu-18.04_amd64.deb +wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.1/eosio.cdt_1.8.1-ubuntu-18.04_amd64.deb +sudo apt install ./eosio.cdt_1.8.1-ubuntu-18.04_amd64.deb ``` ## Debian Package Uninstall @@ -35,8 +35,8 @@ sudo apt remove eosio.cdt ## RPM Package Install ```sh -wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.0-rc1/eosio.cdt-1.8.0-rc1.el7.x86_64.rpm -sudo yum install ./eosio.cdt-1.8.0-rc1.el7.x86_64.rpm +wget https://github.com/EOSIO/eosio.cdt/releases/download/v1.8.1/eosio.cdt-1.8.1.el7.x86_64.rpm +sudo yum install ./eosio.cdt-1.8.1.el7.x86_64.rpm ``` ## RPM Package Uninstall From 35b3157fbcac0355c39bd89b795fa3a55c0d9ee5 Mon Sep 17 00:00:00 2001 From: Patrick Raphael Date: Mon, 12 Jul 2021 17:16:26 -0400 Subject: [PATCH 204/204] fix homebrew warnings --- scripts/generate_bottle.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/generate_bottle.sh b/scripts/generate_bottle.sh index 12a1db9b1f..343c6608d7 100644 --- a/scripts/generate_bottle.sh +++ b/scripts/generate_bottle.sh @@ -31,6 +31,8 @@ export SSUBPREFIX hash=`openssl dgst -sha256 ${NAME}.tar.gz | awk 'NF>1{print $NF}'` echo "class EosioCdt < Formula + # typed: false + # frozen_string_literal: true homepage \"${URL}\" revision 0 @@ -48,13 +50,13 @@ echo "class EosioCdt < Formula depends_on \"doxygen\" => :build depends_on \"graphviz\" => :build depends_on \"lcov\" => :build - depends_on :xcode => :build - depends_on :macos => :high_sierra - depends_on :arch => :intel + depends_on xcode: :build + depends_on macos: :mojave + depends_on arch: :intel bottle do root_url \"https://github.com/eosio/eosio.cdt/releases/download/v${VERSION}\" - sha256 \"${hash}\" => :${MAC_VERSION} + sha256 ${MAC_VERSION}: \"${hash}\" end def install raise \"Error, only supporting binary packages at this time\"