Skip to content

Commit

Permalink
Merge branch '227-feature-request-getconfig' into 'develop'
Browse files Browse the repository at this point in the history
Resolve "Feature request: GetConfig"

Closes #227

See merge request in3/c/in3-core!210
  • Loading branch information
simon-jentzsch committed Apr 17, 2020
2 parents 82b7f21 + fae81fc commit 9182c5c
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 2 deletions.
9 changes: 9 additions & 0 deletions c/include/in3/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,15 @@ char* in3_configure(
const char* config /**< JSON-string with the configuration to set. */
);

/**
* gets the current config as json.
*
* For details about the structure of ther config see https://in3.readthedocs.io/en/develop/api-ts.html#type-in3config
*/
char* in3_get_config(
in3_t* c /**< the incubed client */
);

/**
* defines a default transport which is used when creating a new client.
*/
Expand Down
10 changes: 10 additions & 0 deletions c/src/api/eth1/rpc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ static in3_ret_t in3_config(in3_ctx_t* ctx, d_token_t* params, in3_response_t**
RESPONSE_END();
return IN3_OK;
}
static in3_ret_t in3_getConfig(in3_ctx_t* ctx, in3_response_t** response) {
char* ret = in3_get_config(ctx->client);
RESPONSE_START();
sb_add_chars(&response[0]->result, ret);
RESPONSE_END();
_free(ret);
return IN3_OK;
}

static in3_ret_t in3_pk2address(in3_ctx_t* ctx, d_token_t* params, in3_response_t** response) {
bytes_t* pk = d_get_bytes_at(params, 0);
Expand Down Expand Up @@ -342,6 +350,7 @@ static in3_ret_t eth_handle_intern(in3_ctx_t* ctx, in3_response_t** response) {
if (strcmp(method, "in3_ens") == 0) return in3_ens(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_getConfig") == 0) return in3_getConfig(ctx, response);
if (strcmp(method, "in3_pk2address") == 0) return in3_pk2address(ctx, params, response);
if (strcmp(method, "in3_pk2public") == 0) return in3_pk2address(ctx, params, response);
if (strcmp(method, "in3_ecrecover") == 0) return in3_ecrecover(ctx, params, response);
Expand All @@ -362,6 +371,7 @@ static int verify(in3_vctx_t* v) {
strcmp(method, "web3_sha3") == 0 ||
strcmp(method, "in3_ens") == 0 ||
strcmp(method, "in3_config") == 0 ||
strcmp(method, "in3_getConfig") == 0 ||
strcmp(method, "in3_pk2address") == 0 ||
strcmp(method, "in3_ecrecover") == 0 ||
strcmp(method, "in3_signData") == 0 ||
Expand Down
9 changes: 9 additions & 0 deletions c/src/core/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,15 @@ char* in3_configure(
const char* config /**< JSON-string with the configuration to set. */
);

/**
* gets the current config as json.
*
* For details about the structure of ther config see https://in3.readthedocs.io/en/develop/api-ts.html#type-in3config
*/
char* in3_get_config(
in3_t* c /**< the incubed client */
);

/**
* defines a default transport which is used when creating a new client.
*/
Expand Down
95 changes: 95 additions & 0 deletions c/src/core/client/client_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,101 @@ static inline bool is_hex_str(const char* str) {
return str[strspn(str, "0123456789abcdefABCDEF")] == 0;
}

static void add_prop(sb_t* sb, char prefix, const char* property) {
sb_add_char(sb, prefix);
sb_add_char(sb, '"');
sb_add_chars(sb, property);
sb_add_chars(sb, "\":");
}
static void add_bool(sb_t* sb, char prefix, const char* property, bool value) {
add_prop(sb, prefix, property);
sb_add_chars(sb, value ? "true" : "false");
}
static void add_string(sb_t* sb, char prefix, const char* property, const char* value) {
add_prop(sb, prefix, property);
sb_add_char(sb, '"');
sb_add_chars(sb, value);
sb_add_char(sb, '"');
}

static void add_uint(sb_t* sb, char prefix, const char* property, uint64_t value) {
add_prop(sb, prefix, property);
char tmp[16];
sprintf(tmp, "%u", (uint32_t) value);
sb_add_chars(sb, tmp);
}

static void add_hex(sb_t* sb, char prefix, const char* property, bytes_t value) {
add_prop(sb, prefix, property);
sb_add_bytes(sb, NULL, &value, 1, false);
}

char* in3_get_config(in3_t* c) {
sb_t* sb = sb_new("");
in3_chain_t* chain = in3_find_chain(c, c->chain_id);
add_bool(sb, '{', "autoUpdateList", c->flags & FLAGS_AUTO_UPDATE_LIST);
add_uint(sb, ',', "chainId", c->chain_id);
add_uint(sb, ',', "signatureCount", c->signature_count);
add_uint(sb, ',', "finality", c->finality);
add_bool(sb, ',', "includeCode", c->flags & FLAGS_INCLUDE_CODE);
add_uint(sb, ',', "maxAttempts", c->max_attempts);
add_bool(sb, ',', "keepIn3", c->flags & FLAGS_KEEP_IN3);
add_bool(sb, ',', "stats", c->flags & FLAGS_STATS);
add_bool(sb, ',', "useBinary", c->flags & FLAGS_BINARY);
add_bool(sb, ',', "useHttp", c->flags & FLAGS_HTTP);
add_uint(sb, ',', "maxBlockCache", c->max_block_cache);
add_uint(sb, ',', "maxCodeCache", c->max_code_cache);
add_uint(sb, ',', "maxVerifiedHashes", c->max_verified_hashes);
add_uint(sb, ',', "timeout", c->timeout);
add_uint(sb, ',', "minDeposit", c->min_deposit);
add_uint(sb, ',', "nodeProps", c->node_props);
add_uint(sb, ',', "nodeLimit", c->node_limit);
add_string(sb, ',', "proof", (c->proof == PROOF_NONE) ? "none" : (c->proof == PROOF_STANDARD ? "standard" : "full"));
if (c->key)
add_hex(sb, ',', "key", bytes(c->key, 32));
if (c->replace_latest_block)
add_uint(sb, ',', "replaceLatestBlock", c->replace_latest_block);
add_uint(sb, ',', "requestCount", c->request_count);
if (c->chain_id == ETH_CHAIN_ID_LOCAL)
add_string(sb, ',', "rpc", chain->nodelist->url);

sb_add_chars(sb, ",\"nodes\":{");
for (int i = 0; i < c->chains_length; i++) {
chain = c->chains + i;
if (i) sb_add_char(sb, ',');
sb_add_char(sb, '"');
sb_add_hexuint(sb, chain->chain_id);
sb_add_chars(sb, "\":");
add_hex(sb, '{', "contract", *chain->contract);
if (chain->whitelist)
add_hex(sb, ',', "whiteListContract", bytes(chain->whitelist->contract, 20));
add_hex(sb, ',', "registryId", bytes(chain->registry_id, 32));
add_bool(sb, ',', "needsUpdate", chain->nodelist_upd8_params != NULL);
add_uint(sb, ',', "avgBlockTime", chain->avg_block_time);
sb_add_chars(sb, ",\"nodeList\":[");
for (int j = 0; j < chain->nodelist_length; j++) {
if ((chain->nodelist[j].attrs & ATTR_BOOT_NODE) == 0) continue;
if (sb->data[sb->len - 1] != '[') sb_add_char(sb, ',');
add_string(sb, '{', "url", chain->nodelist[j].url);
add_uint(sb, ',', "props", chain->nodelist[j].props);
add_hex(sb, ',', "address", *(chain->nodelist[j].address));
sb_add_char(sb, '}');
}
if (sb->data[sb->len - 1] == '[') {
sb->len -= 13;
sb_add_char(sb, '}');
} else
sb_add_chars(sb, "]}");
}
sb_add_chars(sb, "}}");

// TODO pay

char* r = sb->data;
_free(sb);
return r;
}

char* in3_configure(in3_t* c, const char* config) {
d_track_keynames(1);
d_clear_keynames();
Expand Down
2 changes: 1 addition & 1 deletion c/src/core/client/execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ static in3_ret_t find_valid_result(in3_ctx_t* ctx, int nodes_count, in3_response
}

// check auto update opts only if this node wasn't blacklisted (due to wrong result/proof)
if (!is_blacklisted(node) && d_get(ctx->responses[0], K_IN3))
if (!is_blacklisted(node) && ctx->responses && d_get(ctx->responses[0], K_IN3))
check_autoupdate(ctx, chain, d_get(ctx->responses[0], K_IN3), node);

// !node_weight is valid, because it means this is a internaly handled response
Expand Down
3 changes: 2 additions & 1 deletion c/src/core/util/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,8 @@ bool d_eq(const d_token_t* a, const d_token_t* b) {
}
return true;
}
return (a->data && b->data)
if (d_type(a) == T_STRING) return strcmp((char*) a->data, (char*) b->data) == 0;
return (a->data && b->data && d_type(a) == T_BYTES)
? b_cmp(d_bytes(a), d_bytes(b))
: a->data == NULL && b->data == NULL;
}
Expand Down
76 changes: 76 additions & 0 deletions c/test/unit_tests/test_config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*******************************************************************************
* This file is part of the Incubed project.
* Sources: https://github.com/slockit/in3-c
*
* Copyright (C) 2018-2020 slock.it GmbH, Blockchains LLC
*
*
* COMMERCIAL LICENSE USAGE
*
* Licensees holding a valid commercial license may use this file in accordance
* with the commercial license agreement provided with the Software or, alternatively,
* in accordance with the terms contained in a written agreement between you and
* slock.it GmbH/Blockchains LLC. For licensing terms and conditions or further
* information please contact slock.it at [email protected].
*
* Alternatively, this file may be used under the AGPL license as follows:
*
* AGPL LICENSE USAGE
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
* [Permissions of this strong copyleft license are conditioned on making available
* complete source code of licensed works and modifications, which include larger
* works using a licensed work, under the same license. Copyright and license notices
* must be preserved. Contributors provide an express grant of patent rights.]
* You should have received a copy of the GNU Affero General Public License along
* with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/

#ifndef TEST
#define TEST
#endif
#ifndef TEST
#define DEBUG
#endif

#include "../../src/api/eth1/eth_api.h"
#include "../../src/core/client/cache.h"
#include "../../src/core/client/context.h"
#include "../../src/core/client/nodelist.h"
#include "../../src/core/util/data.h"
#include "../../src/core/util/debug.h"
#include "../../src/core/util/utils.h"
#include "../../src/verifier/eth1/nano/eth_nano.h"
#include "../test_utils.h"
#include <stdio.h>
#include <unistd.h>

void test_get_config() {
in3_register_eth_nano();
in3_register_eth_api();
in3_t* c = in3_for_chain(ETH_CHAIN_ID_KOVAN);
char * result = NULL, *error = NULL;
in3_client_rpc(c, "in3_getConfig", "[]", &result, &error);
if (error) printf("ERROR: %s\n", error);
TEST_ASSERT_NULL(error);
TEST_ASSERT_EQUAL_STRING("{\"autoUpdateList\":true,\"chainId\":42,\"signatureCount\":0,\"finality\":0,\"includeCode\":false,\"maxAttempts\":7,\"keepIn3\":false,\"stats\":true,\"useBinary\":false,\"useHttp\":false,\"maxBlockCache\":0,\"maxCodeCache\":0,\"maxVerifiedHashes\":5,\"timeout\":10000,\"minDeposit\":0,\"nodeProps\":0,\"nodeLimit\":0,\"proof\":\"standard\",\"requestCount\":1,\"nodes\":{\"0x2a\":{\"contract\":\"0x4c396dcf50ac396e5fdea18163251699b5fcca25\",\"registryId\":\"0x92eb6ad5ed9068a24c1c85276cd7eb11eda1e8c50b17fbaffaf3e8396df4becf\",\"needsUpdate\":true,\"avgBlockTime\":6}}}", result);
_free(result);
in3_free(c);
}

/*
* Main
*/
int main() {
dbg_log("starting cor tests");

TESTS_BEGIN();
RUN_TEST(test_get_config);
return TESTS_END();
}

0 comments on commit 9182c5c

Please sign in to comment.