Skip to content

Commit

Permalink
Merge pull request #520 from eosnetworkfoundation/fix_get_table_rows_…
Browse files Browse the repository at this point in the history
…by_seckey

[3.2] Fix eosio::name conversion in get_table_rows_by_seckey
  • Loading branch information
linh2931 authored Jun 26, 2022
2 parents be7680b + 1f1754b commit 980fc79
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 6 deletions.
1 change: 1 addition & 0 deletions libraries/testing/contracts.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace eosio {
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(get_table_seckey_test, get_table_seckey_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)
Expand Down
4 changes: 4 additions & 0 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,10 @@ uint64_t read_only::get_table_index_name(const read_only::get_table_rows_params&
return index;
}

uint64_t convert_to_type(const eosio::name &n, const string &desc) {
return n.to_uint64_t();
}

template<>
uint64_t convert_to_type(const string& str, const string& desc) {

Expand Down
20 changes: 14 additions & 6 deletions plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Type convert_to_type(const string& str, const string& desc) {
} FC_RETHROW_EXCEPTIONS(warn, "Could not convert ${desc} string '${str}' to key type.", ("desc", desc)("str",str) )
}

uint64_t convert_to_type(const eosio::name &n, const string &desc);

template<>
uint64_t convert_to_type(const string& str, const string& desc);

Expand Down Expand Up @@ -518,9 +520,12 @@ class read_only {

if( p.lower_bound.size() ) {
if( p.key_type == "name" ) {
name s(p.lower_bound);
SecKeyType lv = convert_to_type<SecKeyType>( s.to_string(), "lower_bound name" ); // avoids compiler error
std::get<1>(lower_bound_lookup_tuple) = conv( lv );
if constexpr (std::is_same_v<uint64_t, SecKeyType>) {
SecKeyType lv = convert_to_type(name{p.lower_bound}, "lower_bound name");
std::get<1>(lower_bound_lookup_tuple) = conv(lv);
} else {
EOS_ASSERT(false, chain::contract_table_query_exception, "Invalid key type of eosio::name ${nm} for lower bound", ("nm", p.lower_bound));
}
} else {
SecKeyType lv = convert_to_type<SecKeyType>( p.lower_bound, "lower_bound" );
std::get<1>(lower_bound_lookup_tuple) = conv( lv );
Expand All @@ -529,9 +534,12 @@ class read_only {

if( p.upper_bound.size() ) {
if( p.key_type == "name" ) {
name s(p.upper_bound);
SecKeyType uv = convert_to_type<SecKeyType>( s.to_string(), "upper_bound name" );
std::get<1>(upper_bound_lookup_tuple) = conv( uv );
if constexpr (std::is_same_v<uint64_t, SecKeyType>) {
SecKeyType uv = convert_to_type(name{p.upper_bound}, "upper_bound name");
std::get<1>(upper_bound_lookup_tuple) = conv(uv);
} else {
EOS_ASSERT(false, chain::contract_table_query_exception, "Invalid key type of eosio::name ${nm} for upper bound", ("nm", p.upper_bound));
}
} else {
SecKeyType uv = convert_to_type<SecKeyType>( p.upper_bound, "upper_bound" );
std::get<1>(upper_bound_lookup_tuple) = conv( uv );
Expand Down
98 changes: 98 additions & 0 deletions tests/get_table_seckey_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string/predicate.hpp>

#include <eosio/testing/tester.hpp>
#include <eosio/chain/abi_serializer.hpp>
#include <eosio/chain/wasm_eosio_constraints.hpp>
#include <eosio/chain/resource_limits.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/wast_to_wasm.hpp>
#include <eosio/chain_plugin/chain_plugin.hpp>

#include <contracts.hpp>

#include <fc/io/fstream.hpp>

#include <Runtime/Runtime.h>

#include <fc/variant_object.hpp>
#include <fc/io/json.hpp>

#include <array>
#include <utility>

#ifdef NON_VALIDATING_TEST
#define TESTER tester
#else
#define TESTER validating_tester
#endif

using namespace eosio;
using namespace eosio::chain;
using namespace eosio::testing;
using namespace fc;

BOOST_AUTO_TEST_SUITE(get_table_seckey_tests)

BOOST_FIXTURE_TEST_CASE( get_table_next_key_test, TESTER ) try {
create_account("test"_n);

// setup contract and abi
set_code( "test"_n, contracts::get_table_seckey_test_wasm() );
set_abi( "test"_n, contracts::get_table_seckey_test_abi().data() );
produce_block();

chain_apis::read_only plugin(*(this->control), {}, fc::microseconds::maximum(), {}, {});
chain_apis::read_only::get_table_rows_params params = []{
chain_apis::read_only::get_table_rows_params params{};
params.json=true;
params.code="test"_n;
params.scope="test";
params.limit=1;
return params;
}();

params.table = "numobjs"_n;


// name secondary key type
push_action("test"_n, "addnumobj"_n, "test"_n, mutable_variant_object()("input", 2)("nm", "a"));
push_action("test"_n, "addnumobj"_n, "test"_n, mutable_variant_object()("input", 5)("nm", "b"));
push_action("test"_n, "addnumobj"_n, "test"_n, mutable_variant_object()("input", 7)("nm", "c"));

params.table = "numobjs"_n;
params.key_type = "name";
params.limit = 10;
params.index_position = "6";
params.lower_bound = "a";
params.upper_bound = "a";
auto res_nm = plugin.get_table_rows(params);
BOOST_REQUIRE(res_nm.rows.size() == 1);

params.lower_bound = "a";
params.upper_bound = "b";
res_nm = plugin.get_table_rows(params);
BOOST_REQUIRE(res_nm.rows.size() == 2);

params.lower_bound = "a";
params.upper_bound = "c";
res_nm = plugin.get_table_rows(params);
BOOST_REQUIRE(res_nm.rows.size() == 3);

push_action("test"_n, "addnumobj"_n, "test"_n, mutable_variant_object()("input", 8)("nm", "1111"));
push_action("test"_n, "addnumobj"_n, "test"_n, mutable_variant_object()("input", 9)("nm", "2222"));
push_action("test"_n, "addnumobj"_n, "test"_n, mutable_variant_object()("input", 10)("nm", "3333"));

params.lower_bound = "1111";
params.upper_bound = "3333";
res_nm = plugin.get_table_rows(params);
BOOST_REQUIRE(res_nm.rows.size() == 3);

params.lower_bound = "2222";
params.upper_bound = "3333";
res_nm = plugin.get_table_rows(params);
BOOST_REQUIRE(res_nm.rows.size() == 2);

} FC_LOG_AND_RETHROW() /// get_table_next_key_test

BOOST_AUTO_TEST_SUITE_END()
1 change: 1 addition & 0 deletions unittests/test-contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_subdirectory( asserter )
add_subdirectory( deferred_test )
add_subdirectory( get_sender_test )
add_subdirectory( get_table_test )
add_subdirectory( get_table_seckey_test )
add_subdirectory( integration_test )
add_subdirectory( noop )
add_subdirectory( payloadless )
Expand Down
6 changes: 6 additions & 0 deletions unittests/test-contracts/get_table_seckey_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
if( EOSIO_COMPILE_TEST_CONTRACTS )
add_contract( get_table_seckey_test get_table_seckey_test get_table_seckey_test.cpp )
else()
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/get_table_seckey_test.wasm ${CMAKE_CURRENT_BINARY_DIR}/get_table_seckey_test.wasm COPYONLY )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/get_table_seckey_test.abi ${CMAKE_CURRENT_BINARY_DIR}/get_table_seckey_test.abi COPYONLY )
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"____comment": "This file was generated with eosio-abigen. DO NOT EDIT ",
"version": "eosio::abi/1.2",
"types": [],
"structs": [
{
"name": "addnumobj",
"base": "",
"fields": [
{
"name": "input",
"type": "uint64"
},
{
"name": "nm",
"type": "string"
}
]
},
{
"name": "numobj",
"base": "",
"fields": [
{
"name": "key",
"type": "uint64"
},
{
"name": "sec64",
"type": "uint64"
},
{
"name": "sec128",
"type": "uint128"
},
{
"name": "secdouble",
"type": "float64"
},
{
"name": "secldouble",
"type": "float128"
},
{
"name": "nm",
"type": "name"
}
]
}
],
"actions": [
{
"name": "addnumobj",
"type": "addnumobj",
"ricardian_contract": ""
}
],
"tables": [
{
"name": "numobjs",
"type": "numobj",
"index_type": "i64",
"key_names": [],
"key_types": []
}
],
"kv_tables": {},
"ricardian_clauses": [],
"variants": [],
"action_results": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @file
* @copyright defined in eos/LICENSE
*/
#include "get_table_seckey_test.hpp"


void get_table_seckey_test::addnumobj(uint64_t input, std::string nm) {
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;
obj.nm = name(nm);
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @file
* @copyright defined in eos/LICENSE
*/
#pragma once

#include <eosio/eosio.hpp>
#include <eosio/crypto.hpp>

using namespace eosio;

class [[eosio::contract]] get_table_seckey_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;
name nm;

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; }
uint64_t name_key() const { return nm.value; }
};

typedef eosio::multi_index< "numobjs"_n, numobj,
indexed_by<"bysec1"_n, const_mem_fun<numobj, uint64_t, &numobj::sec64_key>>,
indexed_by<"bysec2"_n, const_mem_fun<numobj, uint128_t, &numobj::sec128_key>>,
indexed_by<"bysec3"_n, const_mem_fun<numobj, double, &numobj::secdouble_key>>,
indexed_by<"bysec4"_n, const_mem_fun<numobj, long double, &numobj::secldouble_key>>,
indexed_by<"byname"_n, const_mem_fun<numobj, uint64_t, &numobj::name_key>>
> numobjs;

[[eosio::action]]
void addnumobj(uint64_t input, std::string nm);
};
Binary file not shown.

0 comments on commit 980fc79

Please sign in to comment.