From 621c46eebf315c12ef916643864c9ed0b7a5292a Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 21 Jun 2019 11:41:40 +0800 Subject: [PATCH 01/24] Expand get_table_rows with more2 field when doing lookup with primary key --- plugins/chain_plugin/chain_plugin.cpp | 7 +++++++ .../include/eosio/chain_plugin/chain_plugin.hpp | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 085acbd9551..1a832ff1e2b 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1439,6 +1439,13 @@ double convert_to_type(const string& str, const string& desc) { return val; } +template +string convert_to_string(const Type& source, const string& key_type, const string& encode_type, const string& desc) { + try { + return fc::variant(source).as(); + } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} from '${source}' to string.", ("desc", desc)("source",source) ) +} + abi_def get_abi( const controller& db, const name& account ) { const auto &d = db.db(); const account_object *code_accnt = d.find(account); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index ed7c62b2751..25d134057c6 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -69,6 +69,9 @@ uint64_t convert_to_type(const string& str, const string& desc); template<> double convert_to_type(const string& str, const string& desc); +template +string convert_to_string(const Type& source, const string& key_type, const string& encode_type, const string& desc); + class read_only { const controller& db; const fc::microseconds abi_serializer_max_time; @@ -297,6 +300,7 @@ class read_only { struct get_table_rows_result { vector rows; ///< one row per item, either encoded as hex String or JSON object bool more = false; ///< true if last element in data is not the end and sizeof data() < limit + string more2; ///< fill lower_bound with this value to fetch more rows }; get_table_rows_result get_table_rows( const get_table_rows_params& params )const; @@ -559,6 +563,7 @@ class read_only { } if( itr != end_itr ) { result.more = true; + result.more2 = convert_to_string(itr->primary_key, p.key_type, p.encode_type, "more2 - next lower bound"); } }; @@ -739,7 +744,7 @@ FC_REFLECT(eosio::chain_apis::read_only::get_block_header_state_params, (block_n FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) ) FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_params, (json)(code)(scope)(table)(table_key)(lower_bound)(upper_bound)(limit)(key_type)(index_position)(encode_type)(reverse)(show_payer) ) -FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_result, (rows)(more) ); +FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_result, (rows)(more)(more2) ); FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_params, (code)(table)(lower_bound)(upper_bound)(limit)(reverse) ) FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_result_row, (code)(scope)(table)(payer)(count)); From 51582b2c048245f87a304f3091b1435916ccbe46 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 21 Jun 2019 11:42:04 +0800 Subject: [PATCH 02/24] Replace fixed_key with fixed_bytes from eosio.cdt --- .../chain/include/eosio/chain/fixed_bytes.hpp | 394 ++++++++++++++++++ .../chain/include/eosio/chain/fixed_key.hpp | 225 ---------- 2 files changed, 394 insertions(+), 225 deletions(-) create mode 100644 libraries/chain/include/eosio/chain/fixed_bytes.hpp delete mode 100644 libraries/chain/include/eosio/chain/fixed_key.hpp diff --git a/libraries/chain/include/eosio/chain/fixed_bytes.hpp b/libraries/chain/include/eosio/chain/fixed_bytes.hpp new file mode 100644 index 00000000000..d1a4099153a --- /dev/null +++ b/libraries/chain/include/eosio/chain/fixed_bytes.hpp @@ -0,0 +1,394 @@ +/** + * @file + * @copyright defined in eos/LICENSE + */ +#pragma once + +#include + +// #include + +#include +#include +#include +#include + +namespace eosio { + + /// @cond IMPLEMENTATIONS + + using chain::uint128_t; + + template + class fixed_bytes; + + template + bool operator ==(const fixed_bytes &c1, const fixed_bytes &c2); + + template + bool operator !=(const fixed_bytes &c1, const fixed_bytes &c2); + + template + bool operator >(const fixed_bytes &c1, const fixed_bytes &c2); + + template + bool operator <(const fixed_bytes &c1, const fixed_bytes &c2); + + template + bool operator >=(const fixed_bytes &c1, const fixed_bytes &c2); + + template + bool operator <=(const fixed_bytes &c1, const fixed_bytes &c2); + + /// @endcond + + /** + * @defgroup fixed_bytes Fixed Size Byte Array + * @ingroup core + * @ingroup types + * @brief Fixed size array of bytes sorted lexicographically + */ + + /** + * Fixed size byte array sorted lexicographically + * + * @ingroup fixed_bytes + * @tparam Size - Size of the fixed_bytes object + */ + template + class fixed_bytes { + private: + + template struct bool_pack; + template + using all_true = std::is_same< bool_pack, bool_pack >; + + template + static void set_from_word_sequence(const Word* arr_begin, const Word* arr_end, fixed_bytes& key) + { + auto itr = key._data.begin(); + word_t temp_word = 0; + const size_t sub_word_shift = 8 * sizeof(Word); + const size_t num_sub_words = sizeof(word_t) / sizeof(Word); + auto sub_words_left = num_sub_words; + for( auto w_itr = arr_begin; w_itr != arr_end; ++w_itr ) { + if( sub_words_left > 1 ) { + temp_word |= static_cast(*w_itr); + temp_word <<= sub_word_shift; + --sub_words_left; + continue; + } + + FC_ASSERT( sub_words_left == 1, "unexpected error in fixed_bytes constructor" ); + temp_word |= static_cast(*w_itr); + sub_words_left = num_sub_words; + + *itr = temp_word; + temp_word = 0; + ++itr; + } + if( sub_words_left != num_sub_words ) { + if( sub_words_left > 1 ) + temp_word <<= 8 * (sub_words_left-1); + *itr = temp_word; + } + } + + public: + typedef uint128_t word_t; + + /** + * Get number of words contained in this fixed_bytes object. A word is defined to be 16 bytes in size + */ + + static constexpr size_t num_words() { return (Size + sizeof(word_t) - 1) / sizeof(word_t); } + + /** + * Get number of padded bytes contained in this fixed_bytes object. Padded bytes are the remaining bytes + * inside the fixed_bytes object after all the words are allocated + */ + static constexpr size_t padded_bytes() { return num_words() * sizeof(word_t) - Size; } + + /** + * Default constructor to fixed_bytes object which initializes all bytes to zero + */ + constexpr fixed_bytes() : _data() {} + + /** + * Constructor to fixed_bytes object from std::array of num_words() word_t types + * + * @param arr data + */ + fixed_bytes(const std::array& arr) + { + std::copy(arr.begin(), arr.end(), _data.begin()); + } + + /** + * Constructor to fixed_bytes object from std::array of Word types smaller in size than word_t + * + * @param arr - Source data + */ + template::value && + std::is_unsigned::value && + !std::is_same::value && + std::less{}(sizeof(Word), sizeof(word_t))>::type > + fixed_bytes(const std::array& arr) + { + static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(Word)) * sizeof(Word), + "size of the backing word size is not divisible by the size of the array element" ); + static_assert( sizeof(Word) * NumWords <= Size, "too many words supplied to fixed_bytes constructor" ); + + set_from_word_sequence(arr.data(), arr.data() + arr.size(), *this); + } + + /** + * Constructor to fixed_bytes object from fixed-sized C array of Word types smaller in size than word_t + * + * @param arr - Source data + */ + template::value && + std::is_unsigned::value && + !std::is_same::value && + std::less{}(sizeof(Word), sizeof(word_t))>::type > + fixed_bytes(const Word(&arr)[NumWords]) + { + static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(Word)) * sizeof(Word), + "size of the backing word size is not divisible by the size of the array element" ); + static_assert( sizeof(Word) * NumWords <= Size, "too many words supplied to fixed_bytes constructor" ); + + set_from_word_sequence(arr, arr + NumWords, *this); + } + + /** + * Create a new fixed_bytes object from a sequence of words + * + * @tparam FirstWord - The type of the first word in the sequence + * @tparam Rest - The type of the remaining words in the sequence + * @param first_word - The first word in the sequence + * @param rest - The remaining words in the sequence + */ + template + static + fixed_bytes + make_from_word_sequence(typename std::enable_if::value && + std::is_unsigned::value && + !std::is_same::value && + sizeof(FirstWord) <= sizeof(word_t) && + all_true<(std::is_same::value)...>::value, + FirstWord>::type first_word, + Rest... rest) + { + static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(FirstWord)) * sizeof(FirstWord), + "size of the backing word size is not divisible by the size of the words supplied as arguments" ); + static_assert( sizeof(FirstWord) * (1 + sizeof...(Rest)) <= Size, "too many words supplied to make_from_word_sequence" ); + + fixed_bytes key; + std::array arr{{ first_word, rest... }}; + set_from_word_sequence(arr.data(), arr.data() + arr.size(), key); + return key; + } + + /** + * Get the contained std::array + */ + const auto& get_array()const { return _data; } + + /** + * Get the underlying data of the contained std::array + */ + auto data() { return _data.data(); } + + /// @cond INTERNAL + + /** + * Get the underlying data of the contained std::array + */ + auto data()const { return _data.data(); } + + /// @endcond + + /** + * Get the size of the contained std::array + */ + auto size()const { return _data.size(); } + + + /** + * Extract the contained data as an array of bytes + * + * @return - the extracted data as array of bytes + */ + std::array extract_as_byte_array()const { + std::array arr; + + const size_t num_sub_words = sizeof(word_t); + + auto arr_itr = arr.begin(); + auto data_itr = _data.begin(); + + for( size_t counter = _data.size(); counter > 0; --counter, ++data_itr ) { + size_t sub_words_left = num_sub_words; + + auto temp_word = *data_itr; + if( counter == 1 ) { // If last word in _data array... + sub_words_left -= padded_bytes(); + temp_word >>= 8*padded_bytes(); + } + for( ; sub_words_left > 0; --sub_words_left ) { + *(arr_itr + sub_words_left - 1) = static_cast(temp_word & 0xFF); + temp_word >>= 8; + } + arr_itr += num_sub_words; + } + + return arr; + } + + /** + * Prints fixed_bytes as a hexidecimal string + * + * @param val to be printed + */ + inline void print()const { + auto arr = extract_as_byte_array(); + printhex(static_cast(arr.data()), arr.size()); + } + + /// @cond OPERATORS + + friend bool operator == <>(const fixed_bytes &c1, const fixed_bytes &c2); + + friend bool operator != <>(const fixed_bytes &c1, const fixed_bytes &c2); + + friend bool operator > <>(const fixed_bytes &c1, const fixed_bytes &c2); + + friend bool operator < <>(const fixed_bytes &c1, const fixed_bytes &c2); + + friend bool operator >= <>(const fixed_bytes &c1, const fixed_bytes &c2); + + friend bool operator <= <>(const fixed_bytes &c1, const fixed_bytes &c2); + + /// @endcond + + private: + + std::array _data; + }; + + /// @cond IMPLEMENTATIONS + + /** + * Lexicographically compares two fixed_bytes variables c1 and c2 + * + * @param c1 - First fixed_bytes object to compare + * @param c2 - Second fixed_bytes object to compare + * @return if c1 == c2, return true, otherwise false + */ + template + bool operator ==(const fixed_bytes &c1, const fixed_bytes &c2) { + return c1._data == c2._data; + } + + /** + * Lexicographically compares two fixed_bytes variables c1 and c2 + * + * @param c1 - First fixed_bytes object to compare + * @param c2 - Second fixed_bytes object to compare + * @return if c1 != c2, return true, otherwise false + */ + template + bool operator !=(const fixed_bytes &c1, const fixed_bytes &c2) { + return c1._data != c2._data; + } + + /** + * Lexicographically compares two fixed_bytes variables c1 and c2 + * + * @param c1 - First fixed_bytes object to compare + * @param c2 - Second fixed_bytes object to compare + * @return if c1 > c2, return true, otherwise false + */ + template + bool operator >(const fixed_bytes& c1, const fixed_bytes& c2) { + return c1._data > c2._data; + } + + /** + * Lexicographically compares two fixed_bytes variables c1 and c2 + * + * @param c1 - First fixed_bytes object to compare + * @param c2 - Second fixed_bytes object to compare + * @return if c1 < c2, return true, otherwise false + */ + template + bool operator <(const fixed_bytes &c1, const fixed_bytes &c2) { + return c1._data < c2._data; + } + + /** + * Lexicographically compares two fixed_bytes variables c1 and c2 + * + * @param c1 - First fixed_bytes object to compare + * @param c2 - Second fixed_bytes object to compare + * @return if c1 >= c2, return true, otherwise false + */ + template + bool operator >=(const fixed_bytes& c1, const fixed_bytes& c2) { + return c1._data >= c2._data; + } + + /** + * Lexicographically compares two fixed_bytes variables c1 and c2 + * + * @param c1 - First fixed_bytes object to compare + * @param c2 - Second fixed_bytes object to compare + * @return if c1 <= c2, return true, otherwise false + */ + template + bool operator <=(const fixed_bytes &c1, const fixed_bytes &c2) { + return c1._data <= c2._data; + } + + + using checksum160 = fixed_bytes<20>; + using checksum256 = fixed_bytes<32>; + using checksum512 = fixed_bytes<64>; + + /** + * Serialize a fixed_bytes into a stream + * + * @brief Serialize a fixed_bytes + * @param ds - The stream to write + * @param d - The value to serialize + * @tparam DataStream - Type of datastream buffer + * @return DataStream& - Reference to the datastream + */ + template + inline DataStream& operator<<(DataStream& ds, const fixed_bytes& d) { + auto arr = d.extract_as_byte_array(); + ds.write( (const char*)arr.data(), arr.size() ); + return ds; + } + + /** + * Deserialize a fixed_bytes from a stream + * + * @brief Deserialize a fixed_bytes + * @param ds - The stream to read + * @param d - The destination for deserialized value + * @tparam DataStream - Type of datastream buffer + * @return DataStream& - Reference to the datastream + */ + template + inline DataStream& operator>>(DataStream& ds, fixed_bytes& d) { + std::array arr; + ds.read( (char*)arr.data(), arr.size() ); + d = fixed_bytes( arr ); + return ds; + } + + /// @endcond +} diff --git a/libraries/chain/include/eosio/chain/fixed_key.hpp b/libraries/chain/include/eosio/chain/fixed_key.hpp deleted file mode 100644 index 5dd90f901ad..00000000000 --- a/libraries/chain/include/eosio/chain/fixed_key.hpp +++ /dev/null @@ -1,225 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE - */ -#pragma once - -#include -#include -#include - -#include -#include -namespace eosio { - - using chain::uint128_t; - - template - class fixed_key; - - template - bool operator==(const fixed_key &c1, const fixed_key &c2); - - template - bool operator!=(const fixed_key &c1, const fixed_key &c2); - - template - bool operator>(const fixed_key &c1, const fixed_key &c2); - - template - bool operator<(const fixed_key &c1, const fixed_key &c2); - - /** - * @defgroup fixed_key fixed size key sorted lexicographically - * @ingroup types - * @{ - */ - template - class fixed_key { - private: - - template struct bool_pack; - template - using all_true = std::is_same< bool_pack, bool_pack >; - - template - static void set_from_word_sequence(const std::array& arr, fixed_key& key) - { - auto itr = key._data.begin(); - word_t temp_word = 0; - const size_t sub_word_shift = 8 * sizeof(Word); - const size_t num_sub_words = sizeof(word_t) / sizeof(Word); - auto sub_words_left = num_sub_words; - for( auto&& w : arr ) { - if( sub_words_left > 1 ) { - temp_word |= static_cast(w); - temp_word <<= sub_word_shift; - --sub_words_left; - continue; - } - - EOS_ASSERT( sub_words_left == 1, chain::fixed_key_type_exception, "unexpected error in fixed_key constructor" ); - temp_word |= static_cast(w); - sub_words_left = num_sub_words; - - *itr = temp_word; - temp_word = 0; - ++itr; - } - if( sub_words_left != num_sub_words ) { - if( sub_words_left > 1 ) - temp_word <<= 8 * (sub_words_left-1); - *itr = temp_word; - } - } - - public: - - typedef uint128_t word_t; - - static constexpr size_t num_words() { return (Size + sizeof(word_t) - 1) / sizeof(word_t); } - static constexpr size_t padded_bytes() { return num_words() * sizeof(word_t) - Size; } - - /** - * @brief Default constructor to fixed_key object - * - * @details Default constructor to fixed_key object which initializes all bytes to zero - */ - fixed_key() : _data() {} - - /** - * @brief Constructor to fixed_key object from std::array of num_words() words - * - * @details Constructor to fixed_key object from std::array of num_words() words - * @param arr data - */ - fixed_key(const std::array& arr) - { - std::copy(arr.begin(), arr.end(), _data.begin()); - } - - template::value && - !std::is_same::value && - sizeof(Word) < sizeof(word_t)>::type > - fixed_key(const std::array& arr) - { - static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(Word)) * sizeof(Word), - "size of the backing word size is not divisible by the size of the array element" ); - static_assert( sizeof(Word) * NumWords <= Size, "too many words supplied to fixed_key constructor" ); - - set_from_word_sequence(arr, *this); - } - - template - static - fixed_key - make_from_word_sequence(typename std::enable_if::value && - !std::is_same::value && - sizeof(FirstWord) <= sizeof(word_t) && - all_true<(std::is_same::value)...>::value, - FirstWord>::type first_word, - Rest... rest) - { - static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(FirstWord)) * sizeof(FirstWord), - "size of the backing word size is not divisible by the size of the words supplied as arguments" ); - static_assert( sizeof(FirstWord) * (1 + sizeof...(Rest)) <= Size, "too many words supplied to make_from_word_sequence" ); - - fixed_key key; - set_from_word_sequence(std::array{{ first_word, rest... }}, key); - return key; - } - - const auto& get_array()const { return _data; } - - auto data() { return _data.data(); } - auto data()const { return _data.data(); } - - auto size()const { return _data.size(); } - - std::array extract_as_byte_array()const { - std::array arr; - - const size_t num_sub_words = sizeof(word_t); - - auto arr_itr = arr.begin(); - auto data_itr = _data.begin(); - - for( size_t counter = _data.size(); counter > 0; --counter, ++data_itr ) { - size_t sub_words_left = num_sub_words; - - if( counter == 1 ) { // If last word in _data array... - sub_words_left -= padded_bytes(); - } - auto temp_word = *data_itr; - for( ; sub_words_left > 0; --sub_words_left ) { - *(arr_itr + sub_words_left - 1) = static_cast(temp_word & 0xFF); - temp_word >>= 8; - } - arr_itr += num_sub_words; - } - - return arr; - } - - // Comparison operators - friend bool operator== <>(const fixed_key &c1, const fixed_key &c2); - - friend bool operator!= <>(const fixed_key &c1, const fixed_key &c2); - - friend bool operator> <>(const fixed_key &c1, const fixed_key &c2); - - friend bool operator< <>(const fixed_key &c1, const fixed_key &c2); - - private: - - std::array _data; - }; - - /** - * @brief Compares two fixed_key variables c1 and c2 - * - * @details Lexicographically compares two fixed_key variables c1 and c2 - * @return if c1 == c2, return true, otherwise false - */ - template - bool operator==(const fixed_key &c1, const fixed_key &c2) { - return c1._data == c2._data; - } - - /** - * @brief Compares two fixed_key variables c1 and c2 - * - * @details Lexicographically compares two fixed_key variables c1 and c2 - * @return if c1 != c2, return true, otherwise false - */ - template - bool operator!=(const fixed_key &c1, const fixed_key &c2) { - return c1._data != c2._data; - } - - /** - * @brief Compares two fixed_key variables c1 and c2 - * - * @details Lexicographically compares two fixed_key variables c1 and c2 - * @return if c1 > c2, return true, otherwise false - */ - template - bool operator>(const fixed_key &c1, const fixed_key &c2) { - return c1._data > c2._data; - } - - /** - * @brief Compares two fixed_key variables c1 and c2 - * - * @details Lexicographically compares two fixed_key variables c1 and c2 - * @return if c1 < c2, return true, otherwise false - */ - template - bool operator<(const fixed_key &c1, const fixed_key &c2) { - return c1._data < c2._data; - } - /// @} fixed_key - - typedef fixed_key<32> key256; -} From 2c5c1586d6e2586cbd49dc3e83c6ee6fb22e4327 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 21 Jun 2019 11:43:15 +0800 Subject: [PATCH 03/24] Expand get_table_rows with more2 field when doing lookup with secondary index i64, i128, float64 --- plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 25d134057c6..42399c984aa 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -489,6 +489,7 @@ class read_only { } if( itr != end_itr ) { result.more = true; + result.more2 = convert_to_string(itr->secondary_key, p.key_type, p.encode_type, "more2 - next lower bound"); } }; From ca3f64ba87d92d571804f8245885696736178e17 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 21 Jun 2019 11:44:50 +0800 Subject: [PATCH 04/24] Expand get_table_rows with more2 field when doing lookup with secondary index i256, sha256, ripemd160 --- plugins/chain_plugin/chain_plugin.cpp | 22 +++++++++++++++++++ .../eosio/chain_plugin/chain_plugin.hpp | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 1a832ff1e2b..489cd755442 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1446,6 +1446,28 @@ string convert_to_string(const Type& source, const string& key_type, const strin } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} from '${source}' to string.", ("desc", desc)("source",source) ) } +template<> +string convert_to_string(const chain::key256_t& source, const string& key_type, const string& encode_type, const string& desc) { + try { + if (key_type == chain_apis::sha256 || (key_type == chain_apis::i256 && encode_type == chain_apis::hex)) { + auto byte_array = fixed_bytes<32>(source).extract_as_byte_array(); + fc::sha256 val(reinterpret_cast(byte_array.data()), byte_array.size()); + return std::string(val); + } else if (key_type == chain_apis::i256) { + auto byte_array = fixed_bytes<32>(source).extract_as_byte_array(); + fc::sha256 val(reinterpret_cast(byte_array.data()), byte_array.size()); + return std::string("0x") + std::string(val); + } else if (key_type == chain_apis::ripemd160) { + auto byte_array = fixed_bytes<20>(source).extract_as_byte_array(); + fc::ripemd160 val; + memcpy(val._hash, byte_array.data(), byte_array.size() ); + return std::string(val); + } + EOS_ASSERT( false, chain_type_exception, "Incompatible key_type and encode_type for key256_t more2" ); + + } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} source '${source}' to string.", ("desc", desc)("source",source) ) +} + abi_def get_abi( const controller& db, const name& account ) { const auto &d = db.db(); const account_object *code_accnt = d.find(account); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 42399c984aa..e8f2b7f8195 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -72,6 +73,9 @@ double convert_to_type(const string& str, const string& desc); template string convert_to_string(const Type& source, const string& key_type, const string& encode_type, const string& desc); +template<> +string convert_to_string(const chain::key256_t& source, const string& key_type, const string& encode_type, const string& desc); + class read_only { const controller& db; const fc::microseconds abi_serializer_max_time; From c72ca9e6ec3964df5235aa00b1bfa987bbaae0df Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 21 Jun 2019 11:46:42 +0800 Subject: [PATCH 05/24] Properly align the input for get_table_rows query with key type i256, sha256, ripemd160 --- .../eosio/chain_plugin/chain_plugin.hpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index e8f2b7f8195..484bc17a8ad 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -639,13 +639,8 @@ class read_write { using index_type = chain::index256_index; static auto function() { return [](const input_type& v) { - chain::key256_t k; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-aliasing" - k[0] = ((uint128_t *)&v._hash)[0]; //0-127 - k[1] = ((uint128_t *)&v._hash)[1]; //127-256 -#pragma GCC diagnostic pop - return k; + fixed_bytes<32> fb(*reinterpret_cast*>(v.data())); + return chain::key256_t(fb.get_array()); }; } }; @@ -657,10 +652,8 @@ class read_write { using index_type = chain::index256_index; static auto function() { return [](const input_type& v) { - chain::key256_t k; - memset(k.data(), 0, sizeof(k)); - memcpy(k.data(), v._hash, sizeof(v._hash)); - return k; + fixed_bytes<20> fb(*reinterpret_cast*>(v.data())); + return chain::key256_t(fb.get_array()); }; } }; @@ -672,8 +665,8 @@ class read_write { static auto function() { return [](const input_type v) { chain::key256_t k; - k[0] = ((uint128_t *)&v)[0]; //0-127 - k[1] = ((uint128_t *)&v)[1]; //127-256 + k[0] = ((uint128_t *)&v)[1]; //128-256 + k[1] = ((uint128_t *)&v)[0]; //0-127 return k; }; } From 89dbac63a3c1f95ae470024a7c33c6c50e240d77 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 21 Jun 2019 11:47:17 +0800 Subject: [PATCH 06/24] Expand get_table_rows with more2 field when doing lookup with secondary index float128 --- plugins/chain_plugin/chain_plugin.cpp | 8 ++++++++ .../include/eosio/chain_plugin/chain_plugin.hpp | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 489cd755442..c76b0b883c7 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1468,6 +1468,14 @@ string convert_to_string(const chain::key256_t& source, const string& key_type, } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} source '${source}' to string.", ("desc", desc)("source",source) ) } +template<> +string convert_to_string(const float128_t& source, const string& key_type, const string& encode_type, const string& desc) { + try { + const uint128_t val = *reinterpret_cast(&source); + return fc::variant(val).as(); + } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} from '${source}' to string.", ("desc", desc)("source",source) ) +} + abi_def get_abi( const controller& db, const name& account ) { const auto &d = db.db(); const account_object *code_accnt = d.find(account); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 484bc17a8ad..6978237a460 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -76,6 +76,10 @@ string convert_to_string(const Type& source, const string& key_type, const strin template<> string convert_to_string(const chain::key256_t& source, const string& key_type, const string& encode_type, const string& desc); +template<> +string convert_to_string(const float128_t& source, const string& key_type, const string& encode_type, const string& desc); + + class read_only { const controller& db; const fc::microseconds abi_serializer_max_time; From 2266398b4542cac48a262eebb1657b4f2cbf3d89 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 21 Jun 2019 11:48:35 +0800 Subject: [PATCH 07/24] Change the format of the input of get_table_rows query with key type float128 to match the returned value (represented as uint128_t) --- plugins/chain_plugin/chain_plugin.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index c76b0b883c7..d00d3b57bc1 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1535,11 +1535,8 @@ read_only::get_table_rows_result read_only::get_table_rows( const read_only::get }); } else if (p.key_type == chain_apis::float128) { - return get_table_rows_by_seckey(p, abi, [](double v)->float128_t{ - float64_t f = *(float64_t *)&v; - float128_t f128; - f64_to_f128M(f, &f128); - return f128; + return get_table_rows_by_seckey(p, abi, [](uint128_t v)->float128_t{ + return *reinterpret_cast(&v); }); } else if (p.key_type == chain_apis::sha256) { From c2e529956a1086cfdb2ad54d17f9ab18b6f8b988 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Tue, 25 Jun 2019 15:21:09 +0800 Subject: [PATCH 08/24] Add unit test for get table --- tests/chain_plugin_tests.cpp | 170 ++++++++++++++++++ unittests/contracts.hpp.in | 1 + unittests/test-contracts/CMakeLists.txt | 1 + .../get_table_test/CMakeLists.txt | 6 + .../get_table_test/get_table_test.abi | 105 +++++++++++ .../get_table_test/get_table_test.cpp | 26 +++ .../get_table_test/get_table_test.hpp | 63 +++++++ .../get_table_test/get_table_test.wasm | Bin 0 -> 13428 bytes 8 files changed, 372 insertions(+) create mode 100644 unittests/test-contracts/get_table_test/CMakeLists.txt create mode 100644 unittests/test-contracts/get_table_test/get_table_test.abi create mode 100644 unittests/test-contracts/get_table_test/get_table_test.cpp create mode 100644 unittests/test-contracts/get_table_test/get_table_test.hpp create mode 100755 unittests/test-contracts/get_table_test/get_table_test.wasm diff --git a/tests/chain_plugin_tests.cpp b/tests/chain_plugin_tests.cpp index a6e119a5b06..e506b224f3e 100644 --- a/tests/chain_plugin_tests.cpp +++ b/tests/chain_plugin_tests.cpp @@ -15,6 +15,7 @@ #include +#include #include #include @@ -122,4 +123,173 @@ BOOST_FIXTURE_TEST_CASE( get_block_with_invalid_abi, TESTER ) try { } FC_LOG_AND_RETHROW() /// get_block_with_invalid_abi +BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { + create_account(N(test)); + + // setup contract and abi + set_code( N(test), contracts::get_table_test_wasm() ); + set_abi( N(test), contracts::get_table_test_abi().data() ); + produce_block(); + + // Init some data + push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 2)); + push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 5)); + push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 7)); + push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "firstinput")); + push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "secondinput")); + push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "thirdinput")); + produce_block(); + + // The result of the init will populate + // For numobjs table (secondary index is on sec64, sec128, secdouble, secldouble) + // { + // "rows": [{ + // "key": 0, + // "sec64": 2, + // "sec128": "0x02000000000000000000000000000000", + // "secdouble": "2.00000000000000000", + // "secldouble": "0x00000000000000000000000000000040" + // },{ + // "key": 1, + // "sec64": 5, + // "sec128": "0x05000000000000000000000000000000", + // "secdouble": "5.00000000000000000", + // "secldouble": "0x00000000000000000000000000400140" + // },{ + // "key": 2, + // "sec64": 7, + // "sec128": "0x07000000000000000000000000000000", + // "secdouble": "7.00000000000000000", + // "secldouble": "0x00000000000000000000000000c00140" + // } + // "more": false, + // "more2": "" + // } + // For hashobjs table (secondary index is on sec256 and sec160): + // { + // "rows": [{ + // "key": 0, + // "hash_input": "firstinput", + // "sec256": "05f5aa6b6c5568c53e886591daa9d9f636fa8e77873581ba67ca46a0f96c226e", + // "sec160": "2a9baa59f1e376eda2e963c140d13c7e77c2f1fb" + // },{ + // "key": 1, + // "hash_input": "secondinput", + // "sec256": "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264", + // "sec160": "fb9d03d3012dc2a6c7b319f914542e3423550c2a" + // },{ + // "key": 2, + // "hash_input": "thirdinput", + // "sec256": "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5", + // "sec160": "ab4314638b573fdc39e5a7b107938ad1b5a16414" + // } + // ], + // "more": false, + // "more2": "" + // } + + + chain_apis::read_only plugin(*(this->control), fc::microseconds::maximum()); + chain_apis::read_only::get_table_rows_params params{ + .code=N(test), + .scope="test", + .limit=1, + .json=true + }; + + params.table = N(numobjs); + + // i64 primary key type + params.key_type = "i64"; + params.index_position = "1"; + params.lower_bound = "0"; + + auto res_1 = plugin.get_table_rows(params); + BOOST_TEST(res_1.rows[0].get_object()["key"].as() == 0); + BOOST_TEST(res_1.more2 == "1"); + + // i64 secondary key type + params.key_type = "i64"; + params.index_position = "2"; + params.lower_bound = "5"; + + auto res_2 = plugin.get_table_rows(params); + BOOST_TEST(res_2.rows[0].get_object()["sec64"].as() == 5); + BOOST_TEST(res_2.more2 == "7"); + + // i128 secondary key type + params.key_type = "i128"; + params.index_position = "3"; + params.lower_bound = "0x05000000000000000000000000000000"; + + auto res_3 = plugin.get_table_rows(params); + chain::uint128_t sec128_expected_value = 5; + BOOST_CHECK(res_3.rows[0].get_object()["sec128"].as() == sec128_expected_value); + BOOST_TEST(res_3.more2 == "0x07000000000000000000000000000000"); + + // float64 secondary key type + params.key_type = "float64"; + params.index_position = "4"; + params.lower_bound = "5.0"; + + auto res_4 = plugin.get_table_rows(params); + float64_t secdouble_expected_value = ui64_to_f64(5); + double secdouble_res_value = res_4.rows[0].get_object()["secdouble"].as(); + BOOST_CHECK(*reinterpret_cast(&secdouble_res_value) == secdouble_expected_value); + BOOST_TEST(res_4.more2 == "7.00000000000000000"); + + // float128 secondary key type + params.key_type = "float128"; + params.index_position = "5"; + params.lower_bound = "0x00000000000000000000000000400140"; + + auto res_5 = plugin.get_table_rows(params); + float128_t secldouble_expected_value = ui64_to_f128(5); + chain::uint128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); + BOOST_TEST(*reinterpret_cast(&secldouble_res_value) == secldouble_expected_value); + BOOST_TEST(res_5.more2 == "0x00000000000000000000000000c00140"); + + params.table = N(hashobjs); + + // sha256 secondary key type + params.key_type = "sha256"; + params.index_position = "2"; + params.lower_bound = "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; + + auto res_6 = plugin.get_table_rows(params); + + checksum256_type sec256_expected_value = checksum256_type::hash(std::string("thirdinput")); + + checksum256_type sec256_res_value = res_6.rows[0].get_object()["sec256"].as(); + BOOST_TEST(std::string(sec256_res_value) == std::string(sec256_expected_value)); + BOOST_TEST(res_6.rows[0].get_object()["hash_input"].as() == std::string("thirdinput")); + BOOST_TEST(res_6.more2 == "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); + + // i256 secondary key type + params.key_type = "i256"; + params.index_position = "2"; + params.lower_bound = "0x2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; + + auto res_7 = plugin.get_table_rows(params); + checksum256_type i256_expected_value = checksum256_type::hash(std::string("thirdinput")); + checksum256_type i256_res_value = res_7.rows[0].get_object()["sec256"].as(); + BOOST_CHECK(i256_res_value == i256_expected_value); + BOOST_TEST(res_7.rows[0].get_object()["hash_input"].as() == "thirdinput"); + BOOST_TEST(res_7.more2 == "0x3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); + + // ripemd160 secondary key type + params.key_type = "ripemd160"; + params.index_position = "3"; + params.lower_bound = "ab4314638b573fdc39e5a7b107938ad1b5a16414"; + + auto res_8 = plugin.get_table_rows(params); + ripemd160 sec160_expected_value = ripemd160::hash(std::string("thirdinput")); + ripemd160 sec160_res_value = res_8.rows[0].get_object()["sec160"].as(); + BOOST_CHECK(sec160_res_value == sec160_expected_value); + BOOST_TEST(res_8.rows[0].get_object()["hash_input"].as() == "thirdinput"); + BOOST_TEST(res_8.more2 == "fb9d03d3012dc2a6c7b319f914542e3423550c2a"); + + + +} FC_LOG_AND_RETHROW() /// get_table_test BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/contracts.hpp.in b/unittests/contracts.hpp.in index efafa1846c8..60de8096f25 100644 --- a/unittests/contracts.hpp.in +++ b/unittests/contracts.hpp.in @@ -42,6 +42,7 @@ namespace eosio { MAKE_READ_WASM_ABI(asserter, asserter, test-contracts) MAKE_READ_WASM_ABI(deferred_test, deferred_test, test-contracts) MAKE_READ_WASM_ABI(get_sender_test, get_sender_test, test-contracts) + MAKE_READ_WASM_ABI(get_table_test, get_table_test, test-contracts) MAKE_READ_WASM_ABI(noop, noop, test-contracts) MAKE_READ_WASM_ABI(payloadless, payloadless, test-contracts) MAKE_READ_WASM_ABI(proxy, proxy, test-contracts) diff --git a/unittests/test-contracts/CMakeLists.txt b/unittests/test-contracts/CMakeLists.txt index 1aded520712..7c48729a524 100644 --- a/unittests/test-contracts/CMakeLists.txt +++ b/unittests/test-contracts/CMakeLists.txt @@ -10,6 +10,7 @@ endif() add_subdirectory( asserter ) add_subdirectory( deferred_test ) add_subdirectory( get_sender_test ) +add_subdirectory( get_table_test ) add_subdirectory( integration_test ) add_subdirectory( noop ) add_subdirectory( payloadless ) diff --git a/unittests/test-contracts/get_table_test/CMakeLists.txt b/unittests/test-contracts/get_table_test/CMakeLists.txt new file mode 100644 index 00000000000..846bf453406 --- /dev/null +++ b/unittests/test-contracts/get_table_test/CMakeLists.txt @@ -0,0 +1,6 @@ +if( EOSIO_COMPILE_TEST_CONTRACTS ) + add_contract( get_table_test get_table_test get_table_test.cpp ) +else() + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/get_table_test.wasm ${CMAKE_CURRENT_BINARY_DIR}/get_table_test.wasm COPYONLY ) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/get_table_test.abi ${CMAKE_CURRENT_BINARY_DIR}/get_table_test.abi COPYONLY ) +endif() diff --git a/unittests/test-contracts/get_table_test/get_table_test.abi b/unittests/test-contracts/get_table_test/get_table_test.abi new file mode 100644 index 00000000000..1a7cdcc2137 --- /dev/null +++ b/unittests/test-contracts/get_table_test/get_table_test.abi @@ -0,0 +1,105 @@ +{ + "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", + "version": "eosio::abi/1.1", + "types": [], + "structs": [ + { + "name": "addhashobj", + "base": "", + "fields": [ + { + "name": "hashinput", + "type": "string" + } + ] + }, + { + "name": "addnumobj", + "base": "", + "fields": [ + { + "name": "input", + "type": "uint64" + } + ] + }, + { + "name": "hashobj", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint64" + }, + { + "name": "hash_input", + "type": "string" + }, + { + "name": "sec256", + "type": "checksum256" + }, + { + "name": "sec160", + "type": "checksum160" + } + ] + }, + { + "name": "numobj", + "base": "", + "fields": [ + { + "name": "key", + "type": "uint64" + }, + { + "name": "sec64", + "type": "uint64" + }, + { + "name": "sec128", + "type": "uint128" + }, + { + "name": "secdouble", + "type": "float64" + }, + { + "name": "secldouble", + "type": "float128" + } + ] + } + ], + "actions": [ + { + "name": "addhashobj", + "type": "addhashobj", + "ricardian_contract": "" + }, + { + "name": "addnumobj", + "type": "addnumobj", + "ricardian_contract": "" + } + ], + "tables": [ + { + "name": "hashobjs", + "type": "hashobj", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "numobjs", + "type": "numobj", + "index_type": "i64", + "key_names": [], + "key_types": [] + } + ], + "ricardian_clauses": [], + "variants": [] +} \ No newline at end of file diff --git a/unittests/test-contracts/get_table_test/get_table_test.cpp b/unittests/test-contracts/get_table_test/get_table_test.cpp new file mode 100644 index 00000000000..c35409f2ac2 --- /dev/null +++ b/unittests/test-contracts/get_table_test/get_table_test.cpp @@ -0,0 +1,26 @@ +/** + * @file + * @copyright defined in eos/LICENSE + */ +#include "get_table_test.hpp" + +void get_table_test::addnumobj(uint64_t input) { + numobjs numobjs_table( _self, _self.value ); + numobjs_table.emplace(_self, [&]( auto& obj ) { + obj.key = numobjs_table.available_primary_key(); + obj.sec64 = input; + obj.sec128 = input; + obj.secdouble = input; + obj.secldouble = input; + }); +} + +void get_table_test::addhashobj(std::string hashinput) { + hashobjs hashobjs_table( _self, _self.value ); + hashobjs_table.emplace(_self, [&]( auto& obj ) { + obj.key = hashobjs_table.available_primary_key(); + obj.hash_input = hashinput; + obj.sec256 = sha256(hashinput.data(), hashinput.size()); + obj.sec160 = ripemd160(hashinput.data(), hashinput.size()); + }); +} \ No newline at end of file diff --git a/unittests/test-contracts/get_table_test/get_table_test.hpp b/unittests/test-contracts/get_table_test/get_table_test.hpp new file mode 100644 index 00000000000..a777bfd63ee --- /dev/null +++ b/unittests/test-contracts/get_table_test/get_table_test.hpp @@ -0,0 +1,63 @@ +/** + * @file + * @copyright defined in eos/LICENSE + */ +#pragma once + +#include +#include + +using namespace eosio; + +class [[eosio::contract]] get_table_test : public eosio::contract { + public: + using eosio::contract::contract; + + // Number object + struct [[eosio::table]] numobj { + uint64_t key; + uint64_t sec64; + uint128_t sec128; + double secdouble; + long double secldouble; + + uint64_t primary_key() const { return key; } + uint64_t sec64_key() const { return sec64; } + uint128_t sec128_key() const { return sec128; } + double secdouble_key() const { return secdouble; } + long double secldouble_key() const { return secldouble; } + }; + + // Hash object + struct [[eosio::table]] hashobj { + uint64_t key; + std::string hash_input; + checksum256 sec256; + checksum160 sec160; + + uint64_t primary_key() const { return key; } + checksum256 sec256_key() const { return sec256; } + checksum256 sec160_key() const { return checksum256(sec160.get_array()); } + }; + + typedef eosio::multi_index< "numobjs"_n, numobj, + indexed_by<"bysec1"_n, const_mem_fun>, + indexed_by<"bysec2"_n, const_mem_fun>, + indexed_by<"bysec3"_n, const_mem_fun>, + indexed_by<"bysec4"_n, const_mem_fun> + > numobjs; + + typedef eosio::multi_index< "hashobjs"_n, hashobj, + indexed_by<"bysec1"_n, const_mem_fun>, + indexed_by<"bysec2"_n, const_mem_fun> + > hashobjs; + + [[eosio::action]] + void addnumobj(uint64_t input); + + + [[eosio::action]] + void addhashobj(std::string hashinput); + + +}; \ No newline at end of file diff --git a/unittests/test-contracts/get_table_test/get_table_test.wasm b/unittests/test-contracts/get_table_test/get_table_test.wasm new file mode 100755 index 0000000000000000000000000000000000000000..cc1b5399505b8370abfa52a7c264c2cbca1ba9e8 GIT binary patch literal 13428 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 literal 0 HcmV?d00001 From 99f45af9eb52d0b12b2aa272c400d06d84a6d1e4 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Tue, 25 Jun 2019 15:38:35 +0800 Subject: [PATCH 09/24] Add comments for get table test --- tests/chain_plugin_tests.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/chain_plugin_tests.cpp b/tests/chain_plugin_tests.cpp index e506b224f3e..b5821ab43f6 100644 --- a/tests/chain_plugin_tests.cpp +++ b/tests/chain_plugin_tests.cpp @@ -220,7 +220,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { // i128 secondary key type params.key_type = "i128"; params.index_position = "3"; - params.lower_bound = "0x05000000000000000000000000000000"; + params.lower_bound = "0x05000000000000000000000000000000"; // This is 5 in uint128 representation auto res_3 = plugin.get_table_rows(params); chain::uint128_t sec128_expected_value = 5; @@ -241,7 +241,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { // float128 secondary key type params.key_type = "float128"; params.index_position = "5"; - params.lower_bound = "0x00000000000000000000000000400140"; + params.lower_bound = "0x00000000000000000000000000400140"; // This is 5.0 in uint128 representation auto res_5 = plugin.get_table_rows(params); float128_t secldouble_expected_value = ui64_to_f128(5); @@ -254,7 +254,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { // sha256 secondary key type params.key_type = "sha256"; params.index_position = "2"; - params.lower_bound = "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; + params.lower_bound = "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; // This is hash of "thirdinput" auto res_6 = plugin.get_table_rows(params); @@ -268,7 +268,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { // i256 secondary key type params.key_type = "i256"; params.index_position = "2"; - params.lower_bound = "0x2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; + params.lower_bound = "0x2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; // This is sha256 hash of "thirdinput" as number auto res_7 = plugin.get_table_rows(params); checksum256_type i256_expected_value = checksum256_type::hash(std::string("thirdinput")); @@ -280,7 +280,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { // ripemd160 secondary key type params.key_type = "ripemd160"; params.index_position = "3"; - params.lower_bound = "ab4314638b573fdc39e5a7b107938ad1b5a16414"; + params.lower_bound = "ab4314638b573fdc39e5a7b107938ad1b5a16414"; // This is ripemd160 hash of "thirdinput" auto res_8 = plugin.get_table_rows(params); ripemd160 sec160_expected_value = ripemd160::hash(std::string("thirdinput")); From 73bb3af94ea89c7b04ad2c0661aaac9fa4f85d9c Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Tue, 25 Jun 2019 17:26:30 +0800 Subject: [PATCH 10/24] Update comments --- .../chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 6978237a460..e9a8ca00a59 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -669,7 +669,7 @@ class read_write { static auto function() { return [](const input_type v) { chain::key256_t k; - k[0] = ((uint128_t *)&v)[1]; //128-256 + k[0] = ((uint128_t *)&v)[1]; //128-255 k[1] = ((uint128_t *)&v)[0]; //0-127 return k; }; From 0657c5d1f1a284cef3aed010c7f22857bbfda6a8 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Thu, 27 Jun 2019 12:11:07 +0800 Subject: [PATCH 11/24] Move get_table_more2_test from chain_plugin_tests to get_table_tests --- tests/chain_plugin_tests.cpp | 169 ---------------------------- tests/get_table_tests.cpp | 206 +++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+), 169 deletions(-) diff --git a/tests/chain_plugin_tests.cpp b/tests/chain_plugin_tests.cpp index b5821ab43f6..edc6d2620da 100644 --- a/tests/chain_plugin_tests.cpp +++ b/tests/chain_plugin_tests.cpp @@ -123,173 +123,4 @@ BOOST_FIXTURE_TEST_CASE( get_block_with_invalid_abi, TESTER ) try { } FC_LOG_AND_RETHROW() /// get_block_with_invalid_abi -BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try { - create_account(N(test)); - - // setup contract and abi - set_code( N(test), contracts::get_table_test_wasm() ); - set_abi( N(test), contracts::get_table_test_abi().data() ); - produce_block(); - - // Init some data - push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 2)); - push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 5)); - push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 7)); - push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "firstinput")); - push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "secondinput")); - push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "thirdinput")); - produce_block(); - - // The result of the init will populate - // For numobjs table (secondary index is on sec64, sec128, secdouble, secldouble) - // { - // "rows": [{ - // "key": 0, - // "sec64": 2, - // "sec128": "0x02000000000000000000000000000000", - // "secdouble": "2.00000000000000000", - // "secldouble": "0x00000000000000000000000000000040" - // },{ - // "key": 1, - // "sec64": 5, - // "sec128": "0x05000000000000000000000000000000", - // "secdouble": "5.00000000000000000", - // "secldouble": "0x00000000000000000000000000400140" - // },{ - // "key": 2, - // "sec64": 7, - // "sec128": "0x07000000000000000000000000000000", - // "secdouble": "7.00000000000000000", - // "secldouble": "0x00000000000000000000000000c00140" - // } - // "more": false, - // "more2": "" - // } - // For hashobjs table (secondary index is on sec256 and sec160): - // { - // "rows": [{ - // "key": 0, - // "hash_input": "firstinput", - // "sec256": "05f5aa6b6c5568c53e886591daa9d9f636fa8e77873581ba67ca46a0f96c226e", - // "sec160": "2a9baa59f1e376eda2e963c140d13c7e77c2f1fb" - // },{ - // "key": 1, - // "hash_input": "secondinput", - // "sec256": "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264", - // "sec160": "fb9d03d3012dc2a6c7b319f914542e3423550c2a" - // },{ - // "key": 2, - // "hash_input": "thirdinput", - // "sec256": "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5", - // "sec160": "ab4314638b573fdc39e5a7b107938ad1b5a16414" - // } - // ], - // "more": false, - // "more2": "" - // } - - - chain_apis::read_only plugin(*(this->control), fc::microseconds::maximum()); - chain_apis::read_only::get_table_rows_params params{ - .code=N(test), - .scope="test", - .limit=1, - .json=true - }; - - params.table = N(numobjs); - - // i64 primary key type - params.key_type = "i64"; - params.index_position = "1"; - params.lower_bound = "0"; - - auto res_1 = plugin.get_table_rows(params); - BOOST_TEST(res_1.rows[0].get_object()["key"].as() == 0); - BOOST_TEST(res_1.more2 == "1"); - - // i64 secondary key type - params.key_type = "i64"; - params.index_position = "2"; - params.lower_bound = "5"; - - auto res_2 = plugin.get_table_rows(params); - BOOST_TEST(res_2.rows[0].get_object()["sec64"].as() == 5); - BOOST_TEST(res_2.more2 == "7"); - - // i128 secondary key type - params.key_type = "i128"; - params.index_position = "3"; - params.lower_bound = "0x05000000000000000000000000000000"; // This is 5 in uint128 representation - - auto res_3 = plugin.get_table_rows(params); - chain::uint128_t sec128_expected_value = 5; - BOOST_CHECK(res_3.rows[0].get_object()["sec128"].as() == sec128_expected_value); - BOOST_TEST(res_3.more2 == "0x07000000000000000000000000000000"); - - // float64 secondary key type - params.key_type = "float64"; - params.index_position = "4"; - params.lower_bound = "5.0"; - - auto res_4 = plugin.get_table_rows(params); - float64_t secdouble_expected_value = ui64_to_f64(5); - double secdouble_res_value = res_4.rows[0].get_object()["secdouble"].as(); - BOOST_CHECK(*reinterpret_cast(&secdouble_res_value) == secdouble_expected_value); - BOOST_TEST(res_4.more2 == "7.00000000000000000"); - - // float128 secondary key type - params.key_type = "float128"; - params.index_position = "5"; - params.lower_bound = "0x00000000000000000000000000400140"; // This is 5.0 in uint128 representation - - auto res_5 = plugin.get_table_rows(params); - float128_t secldouble_expected_value = ui64_to_f128(5); - chain::uint128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); - BOOST_TEST(*reinterpret_cast(&secldouble_res_value) == secldouble_expected_value); - BOOST_TEST(res_5.more2 == "0x00000000000000000000000000c00140"); - - params.table = N(hashobjs); - - // sha256 secondary key type - params.key_type = "sha256"; - params.index_position = "2"; - params.lower_bound = "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; // This is hash of "thirdinput" - - auto res_6 = plugin.get_table_rows(params); - - checksum256_type sec256_expected_value = checksum256_type::hash(std::string("thirdinput")); - - checksum256_type sec256_res_value = res_6.rows[0].get_object()["sec256"].as(); - BOOST_TEST(std::string(sec256_res_value) == std::string(sec256_expected_value)); - BOOST_TEST(res_6.rows[0].get_object()["hash_input"].as() == std::string("thirdinput")); - BOOST_TEST(res_6.more2 == "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); - - // i256 secondary key type - params.key_type = "i256"; - params.index_position = "2"; - params.lower_bound = "0x2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; // This is sha256 hash of "thirdinput" as number - - auto res_7 = plugin.get_table_rows(params); - checksum256_type i256_expected_value = checksum256_type::hash(std::string("thirdinput")); - checksum256_type i256_res_value = res_7.rows[0].get_object()["sec256"].as(); - BOOST_CHECK(i256_res_value == i256_expected_value); - BOOST_TEST(res_7.rows[0].get_object()["hash_input"].as() == "thirdinput"); - BOOST_TEST(res_7.more2 == "0x3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); - - // ripemd160 secondary key type - params.key_type = "ripemd160"; - params.index_position = "3"; - params.lower_bound = "ab4314638b573fdc39e5a7b107938ad1b5a16414"; // This is ripemd160 hash of "thirdinput" - - auto res_8 = plugin.get_table_rows(params); - ripemd160 sec160_expected_value = ripemd160::hash(std::string("thirdinput")); - ripemd160 sec160_res_value = res_8.rows[0].get_object()["sec160"].as(); - BOOST_CHECK(sec160_res_value == sec160_expected_value); - BOOST_TEST(res_8.rows[0].get_object()["hash_input"].as() == "thirdinput"); - BOOST_TEST(res_8.more2 == "fb9d03d3012dc2a6c7b319f914542e3423550c2a"); - - - -} FC_LOG_AND_RETHROW() /// get_table_test BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/get_table_tests.cpp b/tests/get_table_tests.cpp index 91fca59ef3b..34f4e10c04e 100644 --- a/tests/get_table_tests.cpp +++ b/tests/get_table_tests.cpp @@ -452,4 +452,210 @@ BOOST_FIXTURE_TEST_CASE( get_table_by_seckey_test, TESTER ) try { } FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { + create_account(N(test)); + + // setup contract and abi + set_code( N(test), contracts::get_table_test_wasm() ); + set_abi( N(test), contracts::get_table_test_abi().data() ); + produce_block(); + + // Init some data + push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 2)); + push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 5)); + push_action(N(test), N(addnumobj), N(test), mutable_variant_object()("input", 7)); + push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "firstinput")); + push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "secondinput")); + push_action(N(test), N(addhashobj), N(test), mutable_variant_object()("hashinput", "thirdinput")); + produce_block(); + + // The result of the init will populate + // For numobjs table (secondary index is on sec64, sec128, secdouble, secldouble) + // { + // "rows": [{ + // "key": 0, + // "sec64": 2, + // "sec128": "0x02000000000000000000000000000000", + // "secdouble": "2.00000000000000000", + // "secldouble": "0x00000000000000000000000000000040" + // },{ + // "key": 1, + // "sec64": 5, + // "sec128": "0x05000000000000000000000000000000", + // "secdouble": "5.00000000000000000", + // "secldouble": "0x00000000000000000000000000400140" + // },{ + // "key": 2, + // "sec64": 7, + // "sec128": "0x07000000000000000000000000000000", + // "secdouble": "7.00000000000000000", + // "secldouble": "0x00000000000000000000000000c00140" + // } + // "more": false, + // "more2": "" + // } + // For hashobjs table (secondary index is on sec256 and sec160): + // { + // "rows": [{ + // "key": 0, + // "hash_input": "firstinput", + // "sec256": "05f5aa6b6c5568c53e886591daa9d9f636fa8e77873581ba67ca46a0f96c226e", + // "sec160": "2a9baa59f1e376eda2e963c140d13c7e77c2f1fb" + // },{ + // "key": 1, + // "hash_input": "secondinput", + // "sec256": "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264", + // "sec160": "fb9d03d3012dc2a6c7b319f914542e3423550c2a" + // },{ + // "key": 2, + // "hash_input": "thirdinput", + // "sec256": "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5", + // "sec160": "ab4314638b573fdc39e5a7b107938ad1b5a16414" + // } + // ], + // "more": false, + // "more2": "" + // } + + + chain_apis::read_only plugin(*(this->control), fc::microseconds::maximum()); + chain_apis::read_only::get_table_rows_params params{ + .code=N(test), + .scope="test", + .limit=1, + .json=true + }; + + params.table = N(numobjs); + + // i64 primary key type + params.key_type = "i64"; + params.index_position = "1"; + params.lower_bound = "0"; + + auto res_1 = plugin.get_table_rows(params); + BOOST_TEST(res_1.rows[0].get_object()["key"].as() == 0); + BOOST_TEST(res_1.more2 == "1"); + params.lower_bound = res_1.more2; + auto more2_res_1 = plugin.get_table_rows(params); + BOOST_TEST(more2_res_1.rows[0].get_object()["key"].as() == 1); + + + // i64 secondary key type + params.key_type = "i64"; + params.index_position = "2"; + params.lower_bound = "5"; + + auto res_2 = plugin.get_table_rows(params); + BOOST_TEST(res_2.rows[0].get_object()["sec64"].as() == 5); + BOOST_TEST(res_2.more2 == "7"); + params.lower_bound = res_2.more2; + auto more2_res_2 = plugin.get_table_rows(params); + BOOST_TEST(more2_res_2.rows[0].get_object()["sec64"].as() == 7); + + // i128 secondary key type + params.key_type = "i128"; + params.index_position = "3"; + params.lower_bound = "0x05000000000000000000000000000000"; // This is 5 in uint128 representation + + auto res_3 = plugin.get_table_rows(params); + chain::uint128_t sec128_expected_value = 5; + BOOST_CHECK(res_3.rows[0].get_object()["sec128"].as() == sec128_expected_value); + BOOST_TEST(res_3.more2 == "0x07000000000000000000000000000000"); + params.lower_bound = res_3.more2; + auto more2_res_3 = plugin.get_table_rows(params); + chain::uint128_t more2_sec128_expected_value = 7; + BOOST_CHECK(more2_res_3.rows[0].get_object()["sec128"].as() == more2_sec128_expected_value); + + // float64 secondary key type + params.key_type = "float64"; + params.index_position = "4"; + params.lower_bound = "5.0"; + + auto res_4 = plugin.get_table_rows(params); + float64_t secdouble_expected_value = ui64_to_f64(5); + double secdouble_res_value = res_4.rows[0].get_object()["secdouble"].as(); + BOOST_CHECK(*reinterpret_cast(&secdouble_res_value) == secdouble_expected_value); + BOOST_TEST(res_4.more2 == "7.00000000000000000"); + params.lower_bound = res_4.more2; + auto more2_res_4 = plugin.get_table_rows(params); + float64_t more2_secdouble_expected_value = ui64_to_f64(7); + double more2_secdouble_res_value = more2_res_4.rows[0].get_object()["secdouble"].as(); + BOOST_CHECK(*reinterpret_cast(&more2_secdouble_res_value) == more2_secdouble_expected_value); + + // float128 secondary key type + params.key_type = "float128"; + params.index_position = "5"; + params.lower_bound = "0x00000000000000000000000000400140"; // This is 5.0 in uint128 representation + + auto res_5 = plugin.get_table_rows(params); + float128_t secldouble_expected_value = ui64_to_f128(5); + chain::uint128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); + BOOST_TEST(*reinterpret_cast(&secldouble_res_value) == secldouble_expected_value); + BOOST_TEST(res_5.more2 == "0x00000000000000000000000000c00140"); + params.lower_bound = res_5.more2; + auto more2_res_5 = plugin.get_table_rows(params); + float128_t more2_secldouble_expected_value = ui64_to_f128(7); + chain::uint128_t more2_secldouble_res_value = more2_res_5.rows[0].get_object()["secldouble"].as(); + BOOST_TEST(*reinterpret_cast(&more2_secldouble_res_value) == more2_secldouble_expected_value); + + params.table = N(hashobjs); + + // sha256 secondary key type + params.key_type = "sha256"; + params.index_position = "2"; + params.lower_bound = "2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; // This is hash of "thirdinput" + + auto res_6 = plugin.get_table_rows(params); + checksum256_type sec256_expected_value = checksum256_type::hash(std::string("thirdinput")); + checksum256_type sec256_res_value = res_6.rows[0].get_object()["sec256"].as(); + BOOST_TEST(sec256_res_value == sec256_expected_value); + BOOST_TEST(res_6.rows[0].get_object()["hash_input"].as() == std::string("thirdinput")); + BOOST_TEST(res_6.more2 == "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); + params.lower_bound = res_6.more2; + auto more2_res_6 = plugin.get_table_rows(params); + checksum256_type more2_sec256_expected_value = checksum256_type::hash(std::string("secondinput")); + checksum256_type more2_sec256_res_value = more2_res_6.rows[0].get_object()["sec256"].as(); + BOOST_TEST(more2_sec256_res_value == more2_sec256_expected_value); + BOOST_TEST(more2_res_6.rows[0].get_object()["hash_input"].as() == std::string("secondinput")); + + // i256 secondary key type + params.key_type = "i256"; + params.index_position = "2"; + params.lower_bound = "0x2652d68fbbf6000c703b35fdc607b09cd8218cbeea1d108b5c9e84842cdd5ea5"; // This is sha256 hash of "thirdinput" as number + + auto res_7 = plugin.get_table_rows(params); + checksum256_type i256_expected_value = checksum256_type::hash(std::string("thirdinput")); + checksum256_type i256_res_value = res_7.rows[0].get_object()["sec256"].as(); + BOOST_TEST(i256_res_value == i256_expected_value); + BOOST_TEST(res_7.rows[0].get_object()["hash_input"].as() == "thirdinput"); + BOOST_TEST(res_7.more2 == "0x3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); + params.lower_bound = res_7.more2; + auto more2_res_7 = plugin.get_table_rows(params); + checksum256_type more2_i256_expected_value = checksum256_type::hash(std::string("secondinput")); + checksum256_type more2_i256_res_value = more2_res_7.rows[0].get_object()["sec256"].as(); + BOOST_TEST(more2_i256_res_value == more2_i256_expected_value); + BOOST_TEST(more2_res_7.rows[0].get_object()["hash_input"].as() == "secondinput"); + + // ripemd160 secondary key type + params.key_type = "ripemd160"; + params.index_position = "3"; + params.lower_bound = "ab4314638b573fdc39e5a7b107938ad1b5a16414"; // This is ripemd160 hash of "thirdinput" + + auto res_8 = plugin.get_table_rows(params); + ripemd160 sec160_expected_value = ripemd160::hash(std::string("thirdinput")); + ripemd160 sec160_res_value = res_8.rows[0].get_object()["sec160"].as(); + BOOST_TEST(sec160_res_value == sec160_expected_value); + BOOST_TEST(res_8.rows[0].get_object()["hash_input"].as() == "thirdinput"); + BOOST_TEST(res_8.more2 == "fb9d03d3012dc2a6c7b319f914542e3423550c2a"); + params.lower_bound = res_8.more2; + auto more2_res_8 = plugin.get_table_rows(params); + ripemd160 more2_sec160_expected_value = ripemd160::hash(std::string("secondinput")); + ripemd160 more2_sec160_res_value = more2_res_8.rows[0].get_object()["sec160"].as(); + BOOST_TEST(more2_sec160_res_value == more2_sec160_expected_value); + BOOST_TEST(more2_res_8.rows[0].get_object()["hash_input"].as() == "secondinput"); + +} FC_LOG_AND_RETHROW() /// get_table_more2_test + BOOST_AUTO_TEST_SUITE_END() From 418c728292b914ff45419820624b9675434448cd Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Tue, 2 Jul 2019 10:41:36 +0800 Subject: [PATCH 12/24] Add comments --- .../include/eosio/chain_plugin/chain_plugin.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index e9a8ca00a59..ef9835a9907 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -643,6 +643,9 @@ class read_write { using index_type = chain::index256_index; static auto function() { return [](const input_type& v) { + // The input is in big endian, i.e. f58262c8005bb64b8f99ec6083faf050c502d099d9929ae37ffed2fe1bb954fb + // fixed_bytes will convert the input to array of 2 uint128_t in little endian, i.e. 50f0fa8360ec998f4bb65b00c86282f5 fb54b91bfed2fe7fe39a92d999d002c5 + // which is the format used by secondary index fixed_bytes<32> fb(*reinterpret_cast*>(v.data())); return chain::key256_t(fb.get_array()); }; @@ -656,6 +659,9 @@ class read_write { using index_type = chain::index256_index; static auto function() { return [](const input_type& v) { + // The input is in big endian, i.e. 83a83a3876c64c33f66f33c54f1869edef5b5d4a000000000000000000000000 + // fixed_bytes will convert the input to array of 2 uint128_t in little endian, i.e. ed69184fc5336ff6334cc676383aa883 0000000000000000000000004a5d5bef + // which is the format used by secondary index fixed_bytes<20> fb(*reinterpret_cast*>(v.data())); return chain::key256_t(fb.get_array()); }; @@ -668,6 +674,9 @@ class read_write { using index_type = chain::index256_index; static auto function() { return [](const input_type v) { + // The input is in little endian of uint256_t, i.e. fb54b91bfed2fe7fe39a92d999d002c550f0fa8360ec998f4bb65b00c86282f5 + // fixed_bytes will convert the input to array of 2 uint128_t in little endian, i.e. 50f0fa8360ec998f4bb65b00c86282f5 fb54b91bfed2fe7fe39a92d999d002c5 + // which is the format used by secondary index chain::key256_t k; k[0] = ((uint128_t *)&v)[1]; //128-255 k[1] = ((uint128_t *)&v)[0]; //0-127 From 09a9eed23a09c126e3f1c39814f8f9b393a015ae Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Thu, 1 Aug 2019 16:32:41 +0800 Subject: [PATCH 13/24] Remove redundant include --- libraries/chain/include/eosio/chain/fixed_bytes.hpp | 2 -- tests/chain_plugin_tests.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/libraries/chain/include/eosio/chain/fixed_bytes.hpp b/libraries/chain/include/eosio/chain/fixed_bytes.hpp index d1a4099153a..df659935bda 100644 --- a/libraries/chain/include/eosio/chain/fixed_bytes.hpp +++ b/libraries/chain/include/eosio/chain/fixed_bytes.hpp @@ -6,8 +6,6 @@ #include -// #include - #include #include #include diff --git a/tests/chain_plugin_tests.cpp b/tests/chain_plugin_tests.cpp index edc6d2620da..a6e119a5b06 100644 --- a/tests/chain_plugin_tests.cpp +++ b/tests/chain_plugin_tests.cpp @@ -15,7 +15,6 @@ #include -#include #include #include From 315fb1fa0edc3ca8ab59bad9c7dfb8ee97a52429 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Thu, 1 Aug 2019 16:33:09 +0800 Subject: [PATCH 14/24] more2 to next_key --- plugins/chain_plugin/chain_plugin.cpp | 2 +- .../eosio/chain_plugin/chain_plugin.hpp | 8 ++--- tests/get_table_tests.cpp | 36 +++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index e94d9f2203d..5672c97e660 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1480,7 +1480,7 @@ string convert_to_string(const chain::key256_t& source, const string& key_type, memcpy(val._hash, byte_array.data(), byte_array.size() ); return std::string(val); } - EOS_ASSERT( false, chain_type_exception, "Incompatible key_type and encode_type for key256_t more2" ); + EOS_ASSERT( false, chain_type_exception, "Incompatible key_type and encode_type for key256_t next_key" ); } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} source '${source}' to string.", ("desc", desc)("source",source) ) } diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 611c6591508..80006c0b347 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -308,7 +308,7 @@ class read_only { struct get_table_rows_result { vector rows; ///< one row per item, either encoded as hex String or JSON object bool more = false; ///< true if last element in data is not the end and sizeof data() < limit - string more2; ///< fill lower_bound with this value to fetch more rows + string next_key; ///< fill lower_bound with this value to fetch more rows }; get_table_rows_result get_table_rows( const get_table_rows_params& params )const; @@ -497,7 +497,7 @@ class read_only { } if( itr != end_itr ) { result.more = true; - result.more2 = convert_to_string(itr->secondary_key, p.key_type, p.encode_type, "more2 - next lower bound"); + result.next_key = convert_to_string(itr->secondary_key, p.key_type, p.encode_type, "next_key - next lower bound"); } }; @@ -572,7 +572,7 @@ class read_only { } if( itr != end_itr ) { result.more = true; - result.more2 = convert_to_string(itr->primary_key, p.key_type, p.encode_type, "more2 - next lower bound"); + result.next_key = convert_to_string(itr->primary_key, p.key_type, p.encode_type, "next_key - next lower bound"); } }; @@ -756,7 +756,7 @@ FC_REFLECT(eosio::chain_apis::read_only::get_block_header_state_params, (block_n FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) ) FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_params, (json)(code)(scope)(table)(table_key)(lower_bound)(upper_bound)(limit)(key_type)(index_position)(encode_type)(reverse)(show_payer) ) -FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_result, (rows)(more)(more2) ); +FC_REFLECT( eosio::chain_apis::read_only::get_table_rows_result, (rows)(more)(next_key) ); FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_params, (code)(table)(lower_bound)(upper_bound)(limit)(reverse) ) FC_REFLECT( eosio::chain_apis::read_only::get_table_by_scope_result_row, (code)(scope)(table)(payer)(count)); diff --git a/tests/get_table_tests.cpp b/tests/get_table_tests.cpp index 34f4e10c04e..bdacd23e4c2 100644 --- a/tests/get_table_tests.cpp +++ b/tests/get_table_tests.cpp @@ -493,7 +493,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { // "secldouble": "0x00000000000000000000000000c00140" // } // "more": false, - // "more2": "" + // "next_key": "" // } // For hashobjs table (secondary index is on sec256 and sec160): // { @@ -515,7 +515,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { // } // ], // "more": false, - // "more2": "" + // "next_key": "" // } @@ -536,8 +536,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_1 = plugin.get_table_rows(params); BOOST_TEST(res_1.rows[0].get_object()["key"].as() == 0); - BOOST_TEST(res_1.more2 == "1"); - params.lower_bound = res_1.more2; + BOOST_TEST(res_1.next_key == "1"); + params.lower_bound = res_1.next_key; auto more2_res_1 = plugin.get_table_rows(params); BOOST_TEST(more2_res_1.rows[0].get_object()["key"].as() == 1); @@ -549,8 +549,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_2 = plugin.get_table_rows(params); BOOST_TEST(res_2.rows[0].get_object()["sec64"].as() == 5); - BOOST_TEST(res_2.more2 == "7"); - params.lower_bound = res_2.more2; + BOOST_TEST(res_2.next_key == "7"); + params.lower_bound = res_2.next_key; auto more2_res_2 = plugin.get_table_rows(params); BOOST_TEST(more2_res_2.rows[0].get_object()["sec64"].as() == 7); @@ -562,8 +562,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_3 = plugin.get_table_rows(params); chain::uint128_t sec128_expected_value = 5; BOOST_CHECK(res_3.rows[0].get_object()["sec128"].as() == sec128_expected_value); - BOOST_TEST(res_3.more2 == "0x07000000000000000000000000000000"); - params.lower_bound = res_3.more2; + BOOST_TEST(res_3.next_key == "0x07000000000000000000000000000000"); + params.lower_bound = res_3.next_key; auto more2_res_3 = plugin.get_table_rows(params); chain::uint128_t more2_sec128_expected_value = 7; BOOST_CHECK(more2_res_3.rows[0].get_object()["sec128"].as() == more2_sec128_expected_value); @@ -577,8 +577,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { float64_t secdouble_expected_value = ui64_to_f64(5); double secdouble_res_value = res_4.rows[0].get_object()["secdouble"].as(); BOOST_CHECK(*reinterpret_cast(&secdouble_res_value) == secdouble_expected_value); - BOOST_TEST(res_4.more2 == "7.00000000000000000"); - params.lower_bound = res_4.more2; + BOOST_TEST(res_4.next_key == "7.00000000000000000"); + params.lower_bound = res_4.next_key; auto more2_res_4 = plugin.get_table_rows(params); float64_t more2_secdouble_expected_value = ui64_to_f64(7); double more2_secdouble_res_value = more2_res_4.rows[0].get_object()["secdouble"].as(); @@ -593,8 +593,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { float128_t secldouble_expected_value = ui64_to_f128(5); chain::uint128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); BOOST_TEST(*reinterpret_cast(&secldouble_res_value) == secldouble_expected_value); - BOOST_TEST(res_5.more2 == "0x00000000000000000000000000c00140"); - params.lower_bound = res_5.more2; + BOOST_TEST(res_5.next_key == "0x00000000000000000000000000c00140"); + params.lower_bound = res_5.next_key; auto more2_res_5 = plugin.get_table_rows(params); float128_t more2_secldouble_expected_value = ui64_to_f128(7); chain::uint128_t more2_secldouble_res_value = more2_res_5.rows[0].get_object()["secldouble"].as(); @@ -612,8 +612,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { checksum256_type sec256_res_value = res_6.rows[0].get_object()["sec256"].as(); BOOST_TEST(sec256_res_value == sec256_expected_value); BOOST_TEST(res_6.rows[0].get_object()["hash_input"].as() == std::string("thirdinput")); - BOOST_TEST(res_6.more2 == "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); - params.lower_bound = res_6.more2; + BOOST_TEST(res_6.next_key == "3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); + params.lower_bound = res_6.next_key; auto more2_res_6 = plugin.get_table_rows(params); checksum256_type more2_sec256_expected_value = checksum256_type::hash(std::string("secondinput")); checksum256_type more2_sec256_res_value = more2_res_6.rows[0].get_object()["sec256"].as(); @@ -630,8 +630,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { checksum256_type i256_res_value = res_7.rows[0].get_object()["sec256"].as(); BOOST_TEST(i256_res_value == i256_expected_value); BOOST_TEST(res_7.rows[0].get_object()["hash_input"].as() == "thirdinput"); - BOOST_TEST(res_7.more2 == "0x3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); - params.lower_bound = res_7.more2; + BOOST_TEST(res_7.next_key == "0x3cb93a80b47b9d70c5296be3817d34b48568893b31468e3a76337bb7d3d0c264"); + params.lower_bound = res_7.next_key; auto more2_res_7 = plugin.get_table_rows(params); checksum256_type more2_i256_expected_value = checksum256_type::hash(std::string("secondinput")); checksum256_type more2_i256_res_value = more2_res_7.rows[0].get_object()["sec256"].as(); @@ -648,8 +648,8 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { ripemd160 sec160_res_value = res_8.rows[0].get_object()["sec160"].as(); BOOST_TEST(sec160_res_value == sec160_expected_value); BOOST_TEST(res_8.rows[0].get_object()["hash_input"].as() == "thirdinput"); - BOOST_TEST(res_8.more2 == "fb9d03d3012dc2a6c7b319f914542e3423550c2a"); - params.lower_bound = res_8.more2; + BOOST_TEST(res_8.next_key == "fb9d03d3012dc2a6c7b319f914542e3423550c2a"); + params.lower_bound = res_8.next_key; auto more2_res_8 = plugin.get_table_rows(params); ripemd160 more2_sec160_expected_value = ripemd160::hash(std::string("secondinput")); ripemd160 more2_sec160_res_value = more2_res_8.rows[0].get_object()["sec160"].as(); From eb0922a16e20fd3694605c6ece03f85753561bfe Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 2 Aug 2019 11:17:06 +0800 Subject: [PATCH 15/24] Add row size check for get_table_tests --- tests/get_table_tests.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/get_table_tests.cpp b/tests/get_table_tests.cpp index bdacd23e4c2..d3bbf8b3e48 100644 --- a/tests/get_table_tests.cpp +++ b/tests/get_table_tests.cpp @@ -535,10 +535,12 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { params.lower_bound = "0"; auto res_1 = plugin.get_table_rows(params); + BOOST_REQUIRE(res_1.rows.size() > 0); BOOST_TEST(res_1.rows[0].get_object()["key"].as() == 0); BOOST_TEST(res_1.next_key == "1"); params.lower_bound = res_1.next_key; auto more2_res_1 = plugin.get_table_rows(params); + BOOST_REQUIRE(more2_res_1.rows.size() > 0); BOOST_TEST(more2_res_1.rows[0].get_object()["key"].as() == 1); @@ -548,10 +550,12 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { params.lower_bound = "5"; auto res_2 = plugin.get_table_rows(params); + BOOST_REQUIRE(res_2.rows.size() > 0); BOOST_TEST(res_2.rows[0].get_object()["sec64"].as() == 5); BOOST_TEST(res_2.next_key == "7"); params.lower_bound = res_2.next_key; auto more2_res_2 = plugin.get_table_rows(params); + BOOST_REQUIRE(more2_res_2.rows.size() > 0); BOOST_TEST(more2_res_2.rows[0].get_object()["sec64"].as() == 7); // i128 secondary key type @@ -561,11 +565,13 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_3 = plugin.get_table_rows(params); chain::uint128_t sec128_expected_value = 5; + BOOST_REQUIRE(res_3.rows.size() > 0); BOOST_CHECK(res_3.rows[0].get_object()["sec128"].as() == sec128_expected_value); BOOST_TEST(res_3.next_key == "0x07000000000000000000000000000000"); params.lower_bound = res_3.next_key; auto more2_res_3 = plugin.get_table_rows(params); chain::uint128_t more2_sec128_expected_value = 7; + BOOST_REQUIRE(more2_res_3.rows.size() > 0); BOOST_CHECK(more2_res_3.rows[0].get_object()["sec128"].as() == more2_sec128_expected_value); // float64 secondary key type @@ -575,12 +581,14 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_4 = plugin.get_table_rows(params); float64_t secdouble_expected_value = ui64_to_f64(5); + BOOST_REQUIRE(res_4.rows.size() > 0); double secdouble_res_value = res_4.rows[0].get_object()["secdouble"].as(); BOOST_CHECK(*reinterpret_cast(&secdouble_res_value) == secdouble_expected_value); BOOST_TEST(res_4.next_key == "7.00000000000000000"); params.lower_bound = res_4.next_key; auto more2_res_4 = plugin.get_table_rows(params); float64_t more2_secdouble_expected_value = ui64_to_f64(7); + BOOST_REQUIRE(more2_res_4.rows.size() > 0); double more2_secdouble_res_value = more2_res_4.rows[0].get_object()["secdouble"].as(); BOOST_CHECK(*reinterpret_cast(&more2_secdouble_res_value) == more2_secdouble_expected_value); @@ -591,12 +599,14 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_5 = plugin.get_table_rows(params); float128_t secldouble_expected_value = ui64_to_f128(5); + BOOST_REQUIRE(res_5.rows.size() > 0); chain::uint128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); BOOST_TEST(*reinterpret_cast(&secldouble_res_value) == secldouble_expected_value); BOOST_TEST(res_5.next_key == "0x00000000000000000000000000c00140"); params.lower_bound = res_5.next_key; auto more2_res_5 = plugin.get_table_rows(params); float128_t more2_secldouble_expected_value = ui64_to_f128(7); + BOOST_REQUIRE(more2_res_5.rows.size() > 0); chain::uint128_t more2_secldouble_res_value = more2_res_5.rows[0].get_object()["secldouble"].as(); BOOST_TEST(*reinterpret_cast(&more2_secldouble_res_value) == more2_secldouble_expected_value); @@ -609,6 +619,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_6 = plugin.get_table_rows(params); checksum256_type sec256_expected_value = checksum256_type::hash(std::string("thirdinput")); + BOOST_REQUIRE(res_6.rows.size() > 0); checksum256_type sec256_res_value = res_6.rows[0].get_object()["sec256"].as(); BOOST_TEST(sec256_res_value == sec256_expected_value); BOOST_TEST(res_6.rows[0].get_object()["hash_input"].as() == std::string("thirdinput")); @@ -616,6 +627,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { params.lower_bound = res_6.next_key; auto more2_res_6 = plugin.get_table_rows(params); checksum256_type more2_sec256_expected_value = checksum256_type::hash(std::string("secondinput")); + BOOST_REQUIRE(more2_res_6.rows.size() > 0); checksum256_type more2_sec256_res_value = more2_res_6.rows[0].get_object()["sec256"].as(); BOOST_TEST(more2_sec256_res_value == more2_sec256_expected_value); BOOST_TEST(more2_res_6.rows[0].get_object()["hash_input"].as() == std::string("secondinput")); @@ -627,6 +639,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_7 = plugin.get_table_rows(params); checksum256_type i256_expected_value = checksum256_type::hash(std::string("thirdinput")); + BOOST_REQUIRE(res_7.rows.size() > 0); checksum256_type i256_res_value = res_7.rows[0].get_object()["sec256"].as(); BOOST_TEST(i256_res_value == i256_expected_value); BOOST_TEST(res_7.rows[0].get_object()["hash_input"].as() == "thirdinput"); @@ -634,6 +647,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { params.lower_bound = res_7.next_key; auto more2_res_7 = plugin.get_table_rows(params); checksum256_type more2_i256_expected_value = checksum256_type::hash(std::string("secondinput")); + BOOST_REQUIRE(more2_res_7.rows.size() > 0); checksum256_type more2_i256_res_value = more2_res_7.rows[0].get_object()["sec256"].as(); BOOST_TEST(more2_i256_res_value == more2_i256_expected_value); BOOST_TEST(more2_res_7.rows[0].get_object()["hash_input"].as() == "secondinput"); @@ -645,6 +659,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { auto res_8 = plugin.get_table_rows(params); ripemd160 sec160_expected_value = ripemd160::hash(std::string("thirdinput")); + BOOST_REQUIRE(res_8.rows.size() > 0); ripemd160 sec160_res_value = res_8.rows[0].get_object()["sec160"].as(); BOOST_TEST(sec160_res_value == sec160_expected_value); BOOST_TEST(res_8.rows[0].get_object()["hash_input"].as() == "thirdinput"); @@ -652,6 +667,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { params.lower_bound = res_8.next_key; auto more2_res_8 = plugin.get_table_rows(params); ripemd160 more2_sec160_expected_value = ripemd160::hash(std::string("secondinput")); + BOOST_REQUIRE(more2_res_8.rows.size() > 0); ripemd160 more2_sec160_res_value = more2_res_8.rows[0].get_object()["sec160"].as(); BOOST_TEST(more2_sec160_res_value == more2_sec160_expected_value); BOOST_TEST(more2_res_8.rows[0].get_object()["hash_input"].as() == "secondinput"); From d410b2dd1818a9628f66bd7aa37f3130521270db Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 2 Aug 2019 11:17:50 +0800 Subject: [PATCH 16/24] Use boost multiprecision uint128_t to convert input --- plugins/chain_plugin/chain_plugin.cpp | 22 +++++++++++++++++-- .../eosio/chain_plugin/chain_plugin.hpp | 5 ++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 5672c97e660..2ad0c6eddd2 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1443,6 +1443,16 @@ uint64_t convert_to_type(const string& str, const string& desc) { } } +template<> +uint128_t convert_to_type(const string& str, const string& desc) { + uint128_t val; + try { + auto bmp = boost::multiprecision::uint128_t(str); + val = *reinterpret_cast(&bmp); + } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} string '${str}' to uint128_t type.", ("desc", desc)("str",str) ) + return val; +} + template<> double convert_to_type(const string& str, const string& desc) { double val{}; @@ -1552,8 +1562,16 @@ read_only::get_table_rows_result read_only::get_table_rows( const read_only::get }); } else if (p.key_type == chain_apis::float128) { - return get_table_rows_by_seckey(p, abi, [](uint128_t v)->float128_t{ - return *reinterpret_cast(&v); + if ( p.encode_type == chain_apis::hex) { + return get_table_rows_by_seckey(p, abi, [](uint128_t v)->float128_t{ + return *reinterpret_cast(&v); + }); + } + return get_table_rows_by_seckey(p, abi, [](double v)->float128_t{ + float64_t f = *(float64_t *)&v; + float128_t f128; + f64_to_f128M(f, &f128); + return f128; }); } else if (p.key_type == chain_apis::sha256) { diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 80006c0b347..7febdfd3d2a 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -56,7 +56,7 @@ struct permission { template struct resolver_factory; -// see specializations for uint64_t and double in source file +// see specializations for uint64_t, uint128_t and double in source file template Type convert_to_type(const string& str, const string& desc) { try { @@ -67,6 +67,9 @@ Type convert_to_type(const string& str, const string& desc) { template<> uint64_t convert_to_type(const string& str, const string& desc); +template<> +uint128_t convert_to_type(const string& str, const string& desc); + template<> double convert_to_type(const string& str, const string& desc); From 8cba938e238f7d2a0af8610afb7efe0019672411 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Tue, 17 Sep 2019 17:07:55 +0800 Subject: [PATCH 17/24] Modify from_variant and to_variant of uint128 and int128 to use boost multiprecision --- libraries/fc | 2 +- tests/get_table_tests.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/fc b/libraries/fc index c9e7389ba1f..2824a8caf6f 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit c9e7389ba1f0d8bd4fe4dbbfe97863c722f8e564 +Subproject commit 2824a8caf6f4f0422affe637987da9b366b55118 diff --git a/tests/get_table_tests.cpp b/tests/get_table_tests.cpp index 7cbad763f5c..8b6088f1722 100644 --- a/tests/get_table_tests.cpp +++ b/tests/get_table_tests.cpp @@ -557,13 +557,13 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { // i128 secondary key type params.key_type = "i128"; params.index_position = "3"; - params.lower_bound = "0x05000000000000000000000000000000"; // This is 5 in uint128 representation + params.lower_bound = "5"; auto res_3 = plugin.get_table_rows(params); chain::uint128_t sec128_expected_value = 5; BOOST_REQUIRE(res_3.rows.size() > 0); BOOST_CHECK(res_3.rows[0].get_object()["sec128"].as() == sec128_expected_value); - BOOST_TEST(res_3.next_key == "0x07000000000000000000000000000000"); + BOOST_TEST(res_3.next_key == "7"); params.lower_bound = res_3.next_key; auto more2_res_3 = plugin.get_table_rows(params); chain::uint128_t more2_sec128_expected_value = 7; From 1e6ecb0be8e27c3f31b33594768a54dab5d11dd3 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Tue, 17 Sep 2019 17:13:34 +0800 Subject: [PATCH 18/24] User lower precision floating point for float128 next_key --- plugins/chain_plugin/chain_plugin.cpp | 6 +++--- tests/get_table_tests.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index c16f87dfcbf..6d21c08a27c 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1530,9 +1530,9 @@ string convert_to_string(const chain::key256_t& source, const string& key_type, template<> string convert_to_string(const float128_t& source, const string& key_type, const string& encode_type, const string& desc) { - try { - const uint128_t val = *reinterpret_cast(&source); - return fc::variant(val).as(); + try { + float64_t f = f128_to_f64(source); + return fc::variant(f).as(); } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} from '${source}' to string.", ("desc", desc)("source",source) ) } diff --git a/tests/get_table_tests.cpp b/tests/get_table_tests.cpp index 8b6088f1722..d47f7e7f0c9 100644 --- a/tests/get_table_tests.cpp +++ b/tests/get_table_tests.cpp @@ -449,7 +449,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_by_seckey_test, TESTER ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { +BOOST_FIXTURE_TEST_CASE( get_table_next_key_test, TESTER ) try { create_account(N(test)); // setup contract and abi @@ -591,14 +591,14 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { // float128 secondary key type params.key_type = "float128"; params.index_position = "5"; - params.lower_bound = "0x00000000000000000000000000400140"; // This is 5.0 in uint128 representation + params.lower_bound = "5.0"; auto res_5 = plugin.get_table_rows(params); float128_t secldouble_expected_value = ui64_to_f128(5); BOOST_REQUIRE(res_5.rows.size() > 0); chain::uint128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); BOOST_TEST(*reinterpret_cast(&secldouble_res_value) == secldouble_expected_value); - BOOST_TEST(res_5.next_key == "0x00000000000000000000000000c00140"); + BOOST_TEST(res_5.next_key == "7.00000000000000000"); params.lower_bound = res_5.next_key; auto more2_res_5 = plugin.get_table_rows(params); float128_t more2_secldouble_expected_value = ui64_to_f128(7); @@ -668,6 +668,6 @@ BOOST_FIXTURE_TEST_CASE( get_table_more2_test, TESTER ) try { BOOST_TEST(more2_sec160_res_value == more2_sec160_expected_value); BOOST_TEST(more2_res_8.rows[0].get_object()["hash_input"].as() == "secondinput"); -} FC_LOG_AND_RETHROW() /// get_table_more2_test +} FC_LOG_AND_RETHROW() /// get_table_next_key_test BOOST_AUTO_TEST_SUITE_END() From 8d692b2abbd9cd1bbec79f7034f1b61ba4fdc8a8 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Wed, 18 Sep 2019 10:30:49 +0800 Subject: [PATCH 19/24] Update fc libraries --- libraries/fc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fc b/libraries/fc index 2824a8caf6f..3cd44bd5d98 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 2824a8caf6f4f0422affe637987da9b366b55118 +Subproject commit 3cd44bd5d984891bf16a71b277df2135adbe8cd6 From 95135f9aef606a2842a183aa1500ba26a3ec5d1e Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Thu, 19 Sep 2019 18:23:49 +0800 Subject: [PATCH 20/24] Maintain old behaviour of float128_t variant --- libraries/chain/abi_serializer.cpp | 3 ++- .../chain/include/eosio/chain/database_utils.hpp | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/chain/abi_serializer.cpp b/libraries/chain/abi_serializer.cpp index 4a029b193ea..bd3ac712c79 100644 --- a/libraries/chain/abi_serializer.cpp +++ b/libraries/chain/abi_serializer.cpp @@ -11,6 +11,7 @@ using namespace boost; + namespace eosio { namespace chain { const size_t abi_serializer::max_recursion_depth; @@ -75,7 +76,7 @@ namespace eosio { namespace chain { // TODO: Add proper support for floating point types. For now this is good enough. built_in_types.emplace("float32", pack_unpack()); built_in_types.emplace("float64", pack_unpack()); - built_in_types.emplace("float128", pack_unpack()); + built_in_types.emplace("float128", pack_unpack()); built_in_types.emplace("time_point", pack_unpack()); built_in_types.emplace("time_point_sec", pack_unpack()); diff --git a/libraries/chain/include/eosio/chain/database_utils.hpp b/libraries/chain/include/eosio/chain/database_utils.hpp index 52f8a42cd68..84c90842795 100644 --- a/libraries/chain/include/eosio/chain/database_utils.hpp +++ b/libraries/chain/include/eosio/chain/database_utils.hpp @@ -118,12 +118,23 @@ namespace fc { inline void to_variant( const float128_t& f, variant& v ) { - v = variant(*reinterpret_cast(&f)); + // Assumes platform is little endian and hex representation of 128-bit integer is in little endian order. + const eosio::chain::uint128_t as_bytes = *reinterpret_cast(&f); + std::string s = "0x"; + s.append( to_hex( reinterpret_cast(&as_bytes), sizeof(as_bytes) ) ); + v = s; } inline void from_variant( const variant& v, float128_t& f ) { - from_variant(v, *reinterpret_cast(&f)); + // Temporarily hold the binary in uint128_t before casting it to float128_t + eosio::chain::uint128_t temp = 0; + auto s = v.as_string(); + FC_ASSERT( s.size() == 2 + 2 * sizeof(temp) && s.find("0x") == 0, "Failure in converting hex data into a float128_t"); + auto sz = from_hex( s.substr(2), reinterpret_cast(&temp), sizeof(temp) ); + // Assumes platform is little endian and hex representation of 128-bit integer is in little endian order. + FC_ASSERT( sz == sizeof(temp), "Failure in converting hex data into a float128_t" ); + f = *reinterpret_cast(&temp); } inline From 7bb5b690f4fbee8e6b2c92de95fcf28001677ce2 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 19 Sep 2019 15:38:22 -0400 Subject: [PATCH 21/24] fix get_table_tests/get_table_next_key_test --- tests/get_table_tests.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/get_table_tests.cpp b/tests/get_table_tests.cpp index d47f7e7f0c9..081708059b2 100644 --- a/tests/get_table_tests.cpp +++ b/tests/get_table_tests.cpp @@ -538,7 +538,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_next_key_test, TESTER ) try { auto more2_res_1 = plugin.get_table_rows(params); BOOST_REQUIRE(more2_res_1.rows.size() > 0); BOOST_TEST(more2_res_1.rows[0].get_object()["key"].as() == 1); - + // i64 secondary key type params.key_type = "i64"; @@ -557,7 +557,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_next_key_test, TESTER ) try { // i128 secondary key type params.key_type = "i128"; params.index_position = "3"; - params.lower_bound = "5"; + params.lower_bound = "5"; auto res_3 = plugin.get_table_rows(params); chain::uint128_t sec128_expected_value = 5; @@ -596,15 +596,15 @@ BOOST_FIXTURE_TEST_CASE( get_table_next_key_test, TESTER ) try { auto res_5 = plugin.get_table_rows(params); float128_t secldouble_expected_value = ui64_to_f128(5); BOOST_REQUIRE(res_5.rows.size() > 0); - chain::uint128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); - BOOST_TEST(*reinterpret_cast(&secldouble_res_value) == secldouble_expected_value); + float128_t secldouble_res_value = res_5.rows[0].get_object()["secldouble"].as(); + BOOST_TEST(secldouble_res_value == secldouble_expected_value); BOOST_TEST(res_5.next_key == "7.00000000000000000"); params.lower_bound = res_5.next_key; auto more2_res_5 = plugin.get_table_rows(params); float128_t more2_secldouble_expected_value = ui64_to_f128(7); BOOST_REQUIRE(more2_res_5.rows.size() > 0); - chain::uint128_t more2_secldouble_res_value = more2_res_5.rows[0].get_object()["secldouble"].as(); - BOOST_TEST(*reinterpret_cast(&more2_secldouble_res_value) == more2_secldouble_expected_value); + float128_t more2_secldouble_res_value = more2_res_5.rows[0].get_object()["secldouble"].as(); + BOOST_TEST(more2_secldouble_res_value == more2_secldouble_expected_value); params.table = N(hashobjs); From 10e4a60e56d2343814b30b33631cf501bc9a29b3 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Mon, 23 Sep 2019 11:27:18 +0800 Subject: [PATCH 22/24] convert_to_type for uint128 is not needed anymore since fc variant is modified --- plugins/chain_plugin/chain_plugin.cpp | 10 ---------- .../include/eosio/chain_plugin/chain_plugin.hpp | 3 --- 2 files changed, 13 deletions(-) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 6d21c08a27c..8887c8156e9 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1476,16 +1476,6 @@ uint64_t convert_to_type(const string& str, const string& desc) { } } -template<> -uint128_t convert_to_type(const string& str, const string& desc) { - uint128_t val; - try { - auto bmp = boost::multiprecision::uint128_t(str); - val = *reinterpret_cast(&bmp); - } FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} string '${str}' to uint128_t type.", ("desc", desc)("str",str) ) - return val; -} - template<> double convert_to_type(const string& str, const string& desc) { double val{}; diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index b79395f542b..684cc1a2967 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -63,9 +63,6 @@ Type convert_to_type(const string& str, const string& desc) { template<> uint64_t convert_to_type(const string& str, const string& desc); -template<> -uint128_t convert_to_type(const string& str, const string& desc); - template<> double convert_to_type(const string& str, const string& desc); From 96d9f41031148e65172d81672f835dd52e86bef6 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Mon, 23 Sep 2019 11:27:35 +0800 Subject: [PATCH 23/24] Fix strict alias violation --- .../include/eosio/chain_plugin/chain_plugin.hpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 684cc1a2967..ceae80733a2 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -642,7 +642,9 @@ class read_write { // The input is in big endian, i.e. f58262c8005bb64b8f99ec6083faf050c502d099d9929ae37ffed2fe1bb954fb // fixed_bytes will convert the input to array of 2 uint128_t in little endian, i.e. 50f0fa8360ec998f4bb65b00c86282f5 fb54b91bfed2fe7fe39a92d999d002c5 // which is the format used by secondary index - fixed_bytes<32> fb(*reinterpret_cast*>(v.data())); + uint8_t buffer[32]; + memcpy(buffer, v.data(), 32); + fixed_bytes<32> fb(buffer); return chain::key256_t(fb.get_array()); }; } @@ -658,7 +660,9 @@ class read_write { // The input is in big endian, i.e. 83a83a3876c64c33f66f33c54f1869edef5b5d4a000000000000000000000000 // fixed_bytes will convert the input to array of 2 uint128_t in little endian, i.e. ed69184fc5336ff6334cc676383aa883 0000000000000000000000004a5d5bef // which is the format used by secondary index - fixed_bytes<20> fb(*reinterpret_cast*>(v.data())); + uint8_t buffer[20]; + memcpy(buffer, v.data(), 20); + fixed_bytes<20> fb(buffer); return chain::key256_t(fb.get_array()); }; } @@ -671,11 +675,13 @@ class read_write { static auto function() { return [](const input_type v) { // The input is in little endian of uint256_t, i.e. fb54b91bfed2fe7fe39a92d999d002c550f0fa8360ec998f4bb65b00c86282f5 - // fixed_bytes will convert the input to array of 2 uint128_t in little endian, i.e. 50f0fa8360ec998f4bb65b00c86282f5 fb54b91bfed2fe7fe39a92d999d002c5 + // the following will convert the input to array of 2 uint128_t in little endian, i.e. 50f0fa8360ec998f4bb65b00c86282f5 fb54b91bfed2fe7fe39a92d999d002c5 // which is the format used by secondary index chain::key256_t k; - k[0] = ((uint128_t *)&v)[1]; //128-255 - k[1] = ((uint128_t *)&v)[0]; //0-127 + uint8_t buffer[32]; + boost::multiprecision::export_bits(v, buffer, 8, false); + memcpy(&k[0], buffer + 16, 16); + memcpy(&k[1], buffer, 16); return k; }; } From 71a77ba3ee9ce3fb207bd494441b6e2128af6316 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Wed, 25 Sep 2019 09:13:04 +0800 Subject: [PATCH 24/24] Update fc to master --- libraries/fc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fc b/libraries/fc index 3cd44bd5d98..52e372f4cab 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 3cd44bd5d984891bf16a71b277df2135adbe8cd6 +Subproject commit 52e372f4cabc59d531a2bbf35bebbf244e4d9485