Skip to content

Commit

Permalink
Merge branch '131-cli-hangs' into 'develop'
Browse files Browse the repository at this point in the history
Resolve "CLI hangs"

Closes #131

See merge request in3/c/in3-core!89
  • Loading branch information
simon-jentzsch committed Jan 8, 2020
2 parents 065c51d + b5d8003 commit 2b4302e
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 11 deletions.
15 changes: 13 additions & 2 deletions include/in3/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,21 @@ typedef void (*in3_storage_set_item)(
bytes_t* value /**< the value to store.*/
);

/**
* storage handler function for clearing the cache.
**/
typedef void (*in3_storage_clear)(
void* cptr /**< a custom pointer as set in the storage handler*/
);

/**
* storage handler to handle cache.
**/
typedef struct in3_storage_handler {
in3_storage_get_item get_item; /**< function pointer returning a stored value for the given key.*/
in3_storage_set_item set_item; /**< function pointer setting a stored value for the given key.*/
void* cptr; /**< custom pointer which will will be passed to functions */
in3_storage_clear clear; /**< function pointer clearing all contents of cache.*/
void* cptr; /**< custom pointer which will be passed to functions */
} in3_storage_handler_t;

#define IN3_SIGN_ERR_REJECTED -1 /**< return value used by the signer if the the signature-request was rejected. */
Expand Down Expand Up @@ -462,6 +470,7 @@ typedef struct in3_t_ {
* in3_storage_handler_t storage_handler;
* storage_handler.get_item = storage_get_item;
* storage_handler.set_item = storage_set_item;
* storage_handler.clear = storage_clear;
*
* // configure transport
* client->transport = send_curl;
Expand Down Expand Up @@ -499,6 +508,7 @@ in3_t* in3_new() __attribute__((deprecated("use in3_for_chain(ETH_CHAIN_ID_MULTI
* in3_storage_handler_t storage_handler;
* storage_handler.get_item = storage_get_item;
* storage_handler.set_item = storage_set_item;
* storage_handler.clear = storage_clear;
*
* // configure transport
* client->transport = send_curl;
Expand Down Expand Up @@ -644,9 +654,10 @@ in3_signer_t* in3_create_signer(
* create a new storage handler-object to be set on the client.
* the caller will need to free this pointer after usage.
*/
in3_storage_handler_t* in3_create_storeage_handler(
in3_storage_handler_t* in3_create_storage_handler(
in3_storage_get_item get_item, /**< function pointer returning a stored value for the given key.*/
in3_storage_set_item set_item, /**< function pointer setting a stored value for the given key.*/
in3_storage_clear clear, /**< function pointer clearing all contents of cache.*/
void* cptr /**< custom pointer which will will be passed to functions */
);
#endif
15 changes: 14 additions & 1 deletion src/api/eth1/rpc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ static in3_ret_t in3_config(in3_ctx_t* ctx, d_token_t* params, in3_response_t**
return IN3_OK;
}

static in3_ret_t in3_cacheClear(in3_ctx_t* ctx, in3_response_t** response) {
in3_storage_handler_t* cache = ctx->client->cache;
if (!cache || !cache->clear)
return ctx_set_error(ctx, "No storage set", IN3_ECONFIG);
cache->clear(cache->cptr);
RESPONSE_START();
sb_add_chars(&response[0]->result, "true");
RESPONSE_END();
return IN3_OK;
}

static in3_ret_t eth_handle_intern(in3_ctx_t* ctx, in3_response_t** response) {
if (ctx->len > 1) return IN3_ENOTSUP; // internal handling is only possible for single requests (at least for now)
d_token_t* r = ctx->requests[0];
Expand All @@ -150,6 +161,7 @@ static in3_ret_t eth_handle_intern(in3_ctx_t* ctx, in3_response_t** response) {
if (strcmp(method, "in3_checksumAddress") == 0) return in3_checkSumAddress(ctx, params, response);
if (strcmp(method, "web3_sha3") == 0) return in3_sha3(ctx, params, response);
if (strcmp(method, "in3_config") == 0) return in3_config(ctx, params, response);
if (strcmp(method, "in3_cacheClear") == 0) return in3_cacheClear(ctx, response);

return parent_handle ? parent_handle(ctx, response) : IN3_OK;
}
Expand All @@ -162,7 +174,8 @@ static int verify(in3_vctx_t* v) {
strcmp(method, "in3_abiDecode") == 0 ||
strcmp(method, "in3_checksumAddress") == 0 ||
strcmp(method, "web3_sha3") == 0 ||
strcmp(method, "in3_config") == 0)
strcmp(method, "in3_config") == 0 ||
strcmp(method, "in3_cacheClear") == 0)
return IN3_OK;

return parent_verify ? parent_verify(v) : IN3_ENOTSUP;
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/in3/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ ENDIF()


add_executable(in3 main.c in3_storage.c)

target_compile_definitions(in3 PRIVATE _XOPEN_SOURCE=600)
target_link_libraries(in3 ${LIBS} eth_full eth_api -lm)

install(TARGETS in3
Expand Down
50 changes: 50 additions & 0 deletions src/cmd/in3/in3_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,19 @@
* with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/

#include "in3_storage.h"
#include "../../core/client/client.h"
#include "../../core/util/mem.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_WIN32)
#include <direct.h>
#include <dirent.h>
#else
#include <ftw.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
Expand Down Expand Up @@ -113,3 +117,49 @@ void storage_set_item(void* cptr, char* key, bytes_t* content) {
}
_free(path);
}

#if defined(_WIN32)
static void rm_recurs(const char* path) {
struct dirent* entry = NULL;
DIR* dir = NULL;
dir = opendir(path);
while ((entry = readdir(dir))) {
DIR* sub_dir = NULL;
FILE* file = NULL;
char abs_path[270] = {0};
if (*(entry->d_name) != '.') {
sprintf(abs_path, "%s/%s", path, entry->d_name);
if ((sub_dir = opendir(abs_path))) {
closedir(sub_dir);
rm_recurs(abs_path);
} else {
if ((file = fopen(abs_path, "r"))) {
fclose(file);
remove(abs_path);
}
}
}
}
remove(path);
}
#else
static int unlink_cb(const char* fpath, const struct stat* sb, int typeflag, struct FTW *ftwbuf) {
UNUSED_VAR(sb);
UNUSED_VAR(typeflag);
UNUSED_VAR(ftwbuf);
return remove(fpath);
}

static void rm_recurs(const char* dir) {
nftw(dir, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
}
#endif

void storage_clear(void* cptr) {
UNUSED_VAR(cptr);
rm_recurs(get_storage_dir());
// recreate storage dir
free(_HOME_DIR);
_HOME_DIR = NULL;
get_storage_dir();
}
4 changes: 3 additions & 1 deletion src/cmd/in3/in3_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@

bytes_t* storage_get_item(void* cptr, char* key);

void storage_set_item(void* cptr, char* key, bytes_t* content);
void storage_set_item(void* cptr, char* key, bytes_t* content);

void storage_clear(void* cptr);
5 changes: 4 additions & 1 deletion src/cmd/in3/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,7 @@ int main(int argc, char* argv[]) {
in3_storage_handler_t storage_handler;
storage_handler.get_item = storage_get_item;
storage_handler.set_item = storage_set_item;
storage_handler.clear = storage_clear;

// we want to verify all
in3_register_eth_full();
Expand Down Expand Up @@ -609,6 +610,8 @@ int main(int argc, char* argv[]) {
pk_file = argv[++i];
} else if (strcmp(argv[i], "-chain") == 0 || strcmp(argv[i], "-c") == 0) // chain_id
set_chain_id(c, argv[++i]);
else if (strcmp(argv[i], "-ccache") == 0) // clear cache
c->cache->clear(c->cache->cptr);
else if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "-data") == 0) { // data
char* d = argv[++i];
if (strcmp(d, "-") == 0)
Expand Down Expand Up @@ -825,7 +828,7 @@ int main(int argc, char* argv[]) {

return 0;
} else if (strcmp(method, "autocompletelist") == 0) {
printf("send call abi_encode abi_decode ecrecover key -sigtype -st eth_sign raw hash sign createkey -ri -ro keystore unlock pk2address pk2public mainnet tobalaba kovan goerli local volta true false latest -np -debug -c -chain -p -version -proof -s -signs -b -block -to -d -data -gas_limit -value -w -wait -hex -json in3_nodeList in3_stats in3_sign web3_clientVersion web3_sha3 net_version net_peerCount net_listening eth_protocolVersion eth_syncing eth_coinbase eth_mining eth_hashrate eth_gasPrice eth_accounts eth_blockNumber eth_getBalance eth_getStorageAt eth_getTransactionCount eth_getBlockTransactionCountByHash eth_getBlockTransactionCountByNumber eth_getUncleCountByBlockHash eth_getUncleCountByBlockNumber eth_getCode eth_sign eth_sendTransaction eth_sendRawTransaction eth_call eth_estimateGas eth_getBlockByHash eth_getBlockByNumber eth_getTransactionByHash eth_getTransactionByBlockHashAndIndex eth_getTransactionByBlockNumberAndIndex eth_getTransactionReceipt eth_pendingTransactions eth_getUncleByBlockHashAndIndex eth_getUncleByBlockNumberAndIndex eth_getCompilers eth_compileLLL eth_compileSolidity eth_compileSerpent eth_newFilter eth_newBlockFilter eth_newPendingTransactionFilter eth_uninstallFilter eth_getFilterChanges eth_getFilterLogs eth_getLogs eth_getWork eth_submitWork eth_submitHashrate\n");
printf("send call abi_encode abi_decode ecrecover key -sigtype -st eth_sign raw hash sign createkey -ri -ro keystore unlock pk2address pk2public mainnet tobalaba kovan goerli local volta true false latest -np -debug -c -chain -p -version -proof -s -signs -b -block -to -d -data -gas_limit -value -w -wait -hex -json in3_nodeList in3_stats in3_sign web3_clientVersion web3_sha3 net_version net_peerCount net_listening eth_protocolVersion eth_syncing eth_coinbase eth_mining eth_hashrate eth_gasPrice eth_accounts eth_blockNumber eth_getBalance eth_getStorageAt eth_getTransactionCount eth_getBlockTransactionCountByHash eth_getBlockTransactionCountByNumber eth_getUncleCountByBlockHash eth_getUncleCountByBlockNumber eth_getCode eth_sign eth_sendTransaction eth_sendRawTransaction eth_call eth_estimateGas eth_getBlockByHash eth_getBlockByNumber eth_getTransactionByHash eth_getTransactionByBlockHashAndIndex eth_getTransactionByBlockNumberAndIndex eth_getTransactionReceipt eth_pendingTransactions eth_getUncleByBlockHashAndIndex eth_getUncleByBlockNumberAndIndex eth_getCompilers eth_compileLLL eth_compileSolidity eth_compileSerpent eth_newFilter eth_newBlockFilter eth_newPendingTransactionFilter eth_uninstallFilter eth_getFilterChanges eth_getFilterLogs eth_getLogs eth_getWork eth_submitWork eth_submitHashrate in3_cacheClear\n");
return 0;
} else if (strcmp(method, "createkey") == 0) {
time_t t;
Expand Down
4 changes: 3 additions & 1 deletion src/core/client/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,16 @@ in3_signer_t* in3_create_signer(
return signer;
}

in3_storage_handler_t* in3_create_storeage_handler(
in3_storage_handler_t* in3_create_storage_handler(
in3_storage_get_item get_item, /**< function pointer returning a stored value for the given key.*/
in3_storage_set_item set_item, /**< function pointer setting a stored value for the given key.*/
in3_storage_clear clear, /**< function pointer setting a stored value for the given key.*/
void* cptr /**< custom pointer which will will be passed to functions */
) {
in3_storage_handler_t* handler = _calloc(1, sizeof(in3_storage_handler_t));
handler->cptr = cptr;
handler->get_item = get_item;
handler->set_item = set_item;
handler->clear = clear;
return handler;
}
15 changes: 13 additions & 2 deletions src/core/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,21 @@ typedef void (*in3_storage_set_item)(
bytes_t* value /**< the value to store.*/
);

/**
* storage handler function for clearing the cache.
**/
typedef void (*in3_storage_clear)(
void* cptr /**< a custom pointer as set in the storage handler*/
);

/**
* storage handler to handle cache.
**/
typedef struct in3_storage_handler {
in3_storage_get_item get_item; /**< function pointer returning a stored value for the given key.*/
in3_storage_set_item set_item; /**< function pointer setting a stored value for the given key.*/
void* cptr; /**< custom pointer which will will be passed to functions */
in3_storage_clear clear; /**< function pointer clearing all contents of cache.*/
void* cptr; /**< custom pointer which will be passed to functions */
} in3_storage_handler_t;

#define IN3_SIGN_ERR_REJECTED -1 /**< return value used by the signer if the the signature-request was rejected. */
Expand Down Expand Up @@ -462,6 +470,7 @@ typedef struct in3_t_ {
* in3_storage_handler_t storage_handler;
* storage_handler.get_item = storage_get_item;
* storage_handler.set_item = storage_set_item;
* storage_handler.clear = storage_clear;
*
* // configure transport
* client->transport = send_curl;
Expand Down Expand Up @@ -499,6 +508,7 @@ in3_t* in3_new() __attribute__((deprecated("use in3_for_chain(ETH_CHAIN_ID_MULTI
* in3_storage_handler_t storage_handler;
* storage_handler.get_item = storage_get_item;
* storage_handler.set_item = storage_set_item;
* storage_handler.clear = storage_clear;
*
* // configure transport
* client->transport = send_curl;
Expand Down Expand Up @@ -644,9 +654,10 @@ in3_signer_t* in3_create_signer(
* create a new storage handler-object to be set on the client.
* the caller will need to free this pointer after usage.
*/
in3_storage_handler_t* in3_create_storeage_handler(
in3_storage_handler_t* in3_create_storage_handler(
in3_storage_get_item get_item, /**< function pointer returning a stored value for the given key.*/
in3_storage_set_item set_item, /**< function pointer setting a stored value for the given key.*/
in3_storage_clear clear, /**< function pointer clearing all contents of cache.*/
void* cptr /**< custom pointer which will will be passed to functions */
);
#endif
8 changes: 6 additions & 2 deletions test/unit_tests/test_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void test_exec_req() {
in3_register_eth_api();

in3_t* c = in3_for_chain(ETH_CHAIN_ID_MAINNET);
;

char* result = in3_client_exec_req(c, "{\"method\":\"web3_sha3\",\"params\":[\"0x1234\"]}");
TEST_ASSERT_EQUAL_STRING("{\"id\":1,\"jsonrpc\":\"2.0\",\"result\":\"0x56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432\"}", result);
_free(result);
Expand All @@ -103,14 +103,18 @@ void test_exec_req() {
TEST_ASSERT_EQUAL_STRING("{\"id\":0,\"jsonrpc\":\"2.0\",\"error\":{\"code\":-6,\"message\":\"No Method defined\"}}", result);
_free(result);

result = in3_client_exec_req(c, "{\"method\":\"in3_cacheClear\",\"params\":[]}");
TEST_ASSERT_EQUAL_STRING("{\"id\":0,\"jsonrpc\":\"2.0\",\"error\":{\"code\":-6,\"message\":\"The request could not be handled\nNo storage set\"}}", result);
_free(result);

in3_free(c);
}
/*
* Main
*/
int main() {
_free(in3_create_signer(NULL, NULL, NULL));
_free(in3_create_storeage_handler(NULL, NULL, NULL));
_free(in3_create_storage_handler(NULL, NULL, NULL, NULL));

TESTS_BEGIN();
RUN_TEST(test_configure_request);
Expand Down

0 comments on commit 2b4302e

Please sign in to comment.