diff --git a/include/in3/client.h b/include/in3/client.h
index 0ef39a726..4fa1144eb 100644
--- a/include/in3/client.h
+++ b/include/in3/client.h
@@ -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. */
@@ -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;
@@ -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;
@@ -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
diff --git a/src/api/eth1/rpc_api.c b/src/api/eth1/rpc_api.c
index 0394f8237..82542ffba 100644
--- a/src/api/eth1/rpc_api.c
+++ b/src/api/eth1/rpc_api.c
@@ -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];
@@ -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;
}
@@ -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;
diff --git a/src/cmd/in3/CMakeLists.txt b/src/cmd/in3/CMakeLists.txt
index 86338f6f0..0a0fb45b3 100644
--- a/src/cmd/in3/CMakeLists.txt
+++ b/src/cmd/in3/CMakeLists.txt
@@ -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
diff --git a/src/cmd/in3/in3_storage.c b/src/cmd/in3/in3_storage.c
index fcc0508c2..6f7d53b99 100644
--- a/src/cmd/in3/in3_storage.c
+++ b/src/cmd/in3/in3_storage.c
@@ -33,15 +33,19 @@
* with this program. If not, see .
*******************************************************************************/
+#include "in3_storage.h"
#include "../../core/client/client.h"
#include "../../core/util/mem.h"
+
#include
#include
#include
#if defined(_WIN32)
#include
+#include
#else
+#include
#include
#include
#endif
@@ -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();
+}
diff --git a/src/cmd/in3/in3_storage.h b/src/cmd/in3/in3_storage.h
index 633b52ba6..ecabc6f64 100644
--- a/src/cmd/in3/in3_storage.h
+++ b/src/cmd/in3/in3_storage.h
@@ -40,4 +40,6 @@
bytes_t* storage_get_item(void* cptr, char* key);
-void storage_set_item(void* cptr, char* key, bytes_t* content);
\ No newline at end of file
+void storage_set_item(void* cptr, char* key, bytes_t* content);
+
+void storage_clear(void* cptr);
\ No newline at end of file
diff --git a/src/cmd/in3/main.c b/src/cmd/in3/main.c
index 64d75d15e..ebc01ab19 100644
--- a/src/cmd/in3/main.c
+++ b/src/cmd/in3/main.c
@@ -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();
@@ -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)
@@ -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;
diff --git a/src/core/client/client.c b/src/core/client/client.c
index b16e7b4b3..fb5a0a208 100644
--- a/src/core/client/client.c
+++ b/src/core/client/client.c
@@ -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;
}
diff --git a/src/core/client/client.h b/src/core/client/client.h
index 5f2dc7d5e..181bba0f0 100644
--- a/src/core/client/client.h
+++ b/src/core/client/client.h
@@ -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. */
@@ -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;
@@ -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;
@@ -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
diff --git a/test/unit_tests/test_request.c b/test/unit_tests/test_request.c
index 652373ec0..f914bd2ae 100644
--- a/test/unit_tests/test_request.c
+++ b/test/unit_tests/test_request.c
@@ -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);
@@ -103,6 +103,10 @@ 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);
}
/*
@@ -110,7 +114,7 @@ void test_exec_req() {
*/
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);