Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

fix get_table_rows_by_seckey conversion #9605

Merged
merged 8 commits into from
Nov 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions plugins/chain_plugin/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,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 @@ -63,6 +63,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 @@ -490,9 +492,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>) {
larryk85 marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -501,9 +506,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/contracts.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,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(kv_bios, kv_bios, test-contracts)
MAKE_READ_WASM_ABI(kv_test, kv_test, test-contracts)
MAKE_READ_WASM_ABI(noop, noop, test-contracts)
Expand Down
1 change: 1 addition & 0 deletions unittests/test-contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,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( kv_bios )
add_subdirectory( kv_test )
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.