mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Interface to read patch config from c contract lib. (#223)
This commit is contained in:
@@ -53,14 +53,29 @@ int main(int argc, char **argv)
|
||||
// printf("Received %.*s from %.*s", len, msg, HP_KEY_SIZE, sender);
|
||||
// free(msg);
|
||||
|
||||
// Patch file update.
|
||||
// struct patch_config patch = {};
|
||||
// patch.version = "2.0";
|
||||
// struct hp_unl_node unl[1] = {"ed65aac94e7287d461540523b8ce43b873fc97398bef1b42350feac72ad360b7f3"};
|
||||
// patch.unl.list = unl;
|
||||
// patch.unl.count = 1;
|
||||
// patch.roundtime = 1000;
|
||||
// hp_update_config(&patch);
|
||||
// // Test code segment - Config file will be updated with below values.
|
||||
// struct hp_config config = {};
|
||||
// config.version = "2.0";
|
||||
// config.consensus = "public";
|
||||
// config.npl = "public";
|
||||
// config.appbill.bin_args = "123";
|
||||
// struct hp_unl_node unl[1] = {"ed726f9f536904b125bdca10bbdd1e66591b274799b92ac8bcfc75bf45d7da4c0f"};
|
||||
// config.unl.list = unl;
|
||||
// config.unl.count = 1;
|
||||
// config.roundtime = 1000;
|
||||
// hp_update_config(&config);
|
||||
|
||||
// // Test code segment - Get current config file values.
|
||||
// struct hp_config *current_config = hp_get_config();
|
||||
// if (current_config != NULL)
|
||||
// {
|
||||
// printf("\"version\": \"%s\"\n", current_config->version);
|
||||
// printf("\"consensus\": \"%s\"\n", current_config->consensus);
|
||||
// printf("\"npl\": \"%s\"\n", current_config->npl);
|
||||
// printf("\"appbill_bin_args\": \"%s\"\n", current_config->appbill.bin_args);
|
||||
// }
|
||||
// // Returned hp_config struct memory should be freed after it's been used.
|
||||
// hp_free_config(current_config);
|
||||
|
||||
hp_deinit_user_input_mmap();
|
||||
hp_deinit_contract();
|
||||
@@ -69,13 +84,13 @@ int main(int argc, char **argv)
|
||||
|
||||
void store_timestamp(const uint64_t timestamp)
|
||||
{
|
||||
int fd = open("exects.txt", O_RDWR | O_CREAT | O_APPEND);
|
||||
int fd = open("exects.txt", O_RDWR | O_CREAT | O_APPEND, 0644);
|
||||
if (fd > 0)
|
||||
{
|
||||
char tsbuf[20];
|
||||
memset(tsbuf, 0, 20);
|
||||
sprintf(tsbuf, "%lu\n", timestamp);
|
||||
struct iovec vec[2] = {{(void *)"ts:", 4}, {(void *)tsbuf, 20}};
|
||||
struct iovec vec[2] = {{(void *)"ts:", 3}, {(void *)tsbuf, strlen(tsbuf)}};
|
||||
writev(fd, vec, 2);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -81,30 +81,26 @@
|
||||
ptr = NULL; \
|
||||
}
|
||||
|
||||
#define __HP_UPDATE_CONFIG_ERROR(msg) \
|
||||
{ \
|
||||
fprintf(stderr, "%s\n", msg); \
|
||||
if (fd) \
|
||||
close(fd); \
|
||||
\
|
||||
if (root) \
|
||||
__HP_FREE(root); \
|
||||
\
|
||||
if (config) \
|
||||
__hp_free_patch_config(&existing_patch); \
|
||||
\
|
||||
return -1; \
|
||||
#define __HP_UPDATE_CONFIG_ERROR(msg) \
|
||||
{ \
|
||||
fprintf(stderr, "%s\n", msg); \
|
||||
if (fd) \
|
||||
close(fd); \
|
||||
if (config) \
|
||||
__hp_free_patch_config(existing_patch); \
|
||||
\
|
||||
return -1; \
|
||||
}
|
||||
|
||||
/**
|
||||
* dest - Pointer to destination pointer.
|
||||
* dest - Destination pointer.
|
||||
* src - Source pointer.
|
||||
*/
|
||||
#define __HP_STRING_COPY(dest, src) \
|
||||
{ \
|
||||
__HP_FREE(*dest); \
|
||||
*dest = (char *)malloc(strlen(src) + 1); \
|
||||
memcpy(*dest, src, strlen(src) + 1); \
|
||||
__HP_FREE(dest); \
|
||||
dest = (char *)malloc(strlen(src) + 1); \
|
||||
memcpy(dest, src, strlen(src) + 1); \
|
||||
}
|
||||
|
||||
struct hp_user_input
|
||||
@@ -153,7 +149,7 @@ struct hp_appbill_config
|
||||
char *bin_args;
|
||||
};
|
||||
|
||||
struct patch_config
|
||||
struct hp_config
|
||||
{
|
||||
char *version;
|
||||
struct hp_unl_collection unl;
|
||||
@@ -195,13 +191,16 @@ int hp_writev_user_msg(const struct hp_user *user, const struct iovec *bufs, con
|
||||
int hp_write_npl_msg(const void *buf, const uint32_t len);
|
||||
int hp_writev_npl_msg(const struct iovec *bufs, const int buf_count);
|
||||
int hp_read_npl_msg(void *msg_buf, char *pubkey_buf, const int timeout);
|
||||
int hp_update_config(const struct patch_config *config);
|
||||
int hp_update_config(const struct hp_config *config);
|
||||
struct hp_config *hp_get_config();
|
||||
void hp_free_config(struct hp_config *config);
|
||||
|
||||
void __hp_parse_args_json(const struct json_object_s *object);
|
||||
int __hp_write_control_msg(const void *buf, const uint32_t len);
|
||||
void __hp_populate_patch_from_json_object(struct patch_config *config, struct json_object_s *object);
|
||||
int __hp_write_to_patch_file(const int fd, const struct patch_config *config);
|
||||
void __hp_free_patch_config(struct patch_config *patch_config);
|
||||
void __hp_populate_patch_from_json_object(struct hp_config *config, const struct json_object_s *object);
|
||||
int __hp_write_to_patch_file(const int fd, const struct hp_config *config);
|
||||
struct hp_config *__hp_read_from_patch_file(const int fd);
|
||||
void __hp_free_patch_config(struct hp_config *patch_config);
|
||||
|
||||
static struct __hp_contract __hpc = {};
|
||||
|
||||
@@ -438,18 +437,16 @@ int hp_read_npl_msg(void *msg_buf, char *pubkey_buf, const int timeout)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the params of the existing patch file.
|
||||
* @param config Pointer to the updated patch config struct.
|
||||
* Update the params of the existing config file.
|
||||
* @param config Pointer to the updated config struct.
|
||||
*/
|
||||
int hp_update_config(const struct patch_config *config)
|
||||
int hp_update_config(const struct hp_config *config)
|
||||
{
|
||||
struct hp_contract_context *cctx = __hpc.cctx;
|
||||
struct json_value_s *root = NULL;
|
||||
struct patch_config existing_patch = {};
|
||||
|
||||
if (cctx->readonly)
|
||||
{
|
||||
fprintf(stderr, "Config update not allowed in readonly mode.");
|
||||
fprintf(stderr, "Config update not allowed in readonly mode.\n");
|
||||
return -1;
|
||||
}
|
||||
const int fd = open(PATCH_FILE_PATH, O_RDWR);
|
||||
@@ -458,23 +455,15 @@ int hp_update_config(const struct patch_config *config)
|
||||
fprintf(stderr, "Error opening patch.cfg file.\n");
|
||||
return -1;
|
||||
}
|
||||
char buf[4096];
|
||||
const size_t len = read(fd, buf, sizeof(buf));
|
||||
if (len == -1)
|
||||
{
|
||||
__HP_UPDATE_CONFIG_ERROR("Error when reading stdin.");
|
||||
}
|
||||
|
||||
root = json_parse(buf, len);
|
||||
if (root && root->type == json_type_object)
|
||||
struct hp_config *existing_patch = __hp_read_from_patch_file(fd);
|
||||
if (existing_patch != NULL)
|
||||
{
|
||||
struct json_object_s *object = (struct json_object_s *)root->payload;
|
||||
__hp_populate_patch_from_json_object(&existing_patch, object);
|
||||
if (config->version)
|
||||
{
|
||||
if (strlen(config->version) != 0)
|
||||
{
|
||||
__HP_STRING_COPY(&existing_patch.version, config->version);
|
||||
__HP_STRING_COPY(existing_patch->version, config->version);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -511,20 +500,20 @@ int hp_update_config(const struct patch_config *config)
|
||||
}
|
||||
}
|
||||
}
|
||||
__HP_FREE(existing_patch.unl.list);
|
||||
existing_patch.unl.list = config->unl.count ? (struct hp_unl_node *)malloc(sizeof(struct hp_unl_node) * config->unl.count) : NULL;
|
||||
memcpy(existing_patch.unl.list, config->unl.list, sizeof(struct hp_unl_node) * config->unl.count);
|
||||
existing_patch.unl.count = config->unl.count;
|
||||
__HP_FREE(existing_patch->unl.list);
|
||||
existing_patch->unl.list = config->unl.count ? (struct hp_unl_node *)malloc(sizeof(struct hp_unl_node) * config->unl.count) : NULL;
|
||||
memcpy(existing_patch->unl.list, config->unl.list, sizeof(struct hp_unl_node) * config->unl.count);
|
||||
existing_patch->unl.count = config->unl.count;
|
||||
}
|
||||
|
||||
if (config->bin_path)
|
||||
__HP_STRING_COPY(&existing_patch.bin_path, config->bin_path);
|
||||
__HP_STRING_COPY(existing_patch->bin_path, config->bin_path);
|
||||
|
||||
if (config->bin_args)
|
||||
__HP_STRING_COPY(&existing_patch.bin_args, config->bin_args);
|
||||
__HP_STRING_COPY(existing_patch->bin_args, config->bin_args);
|
||||
|
||||
if (config->roundtime)
|
||||
existing_patch.roundtime = config->roundtime;
|
||||
// if (config->roundtime)
|
||||
// existing_patch->roundtime = config->roundtime;
|
||||
|
||||
if (config->consensus)
|
||||
{
|
||||
@@ -532,7 +521,7 @@ int hp_update_config(const struct patch_config *config)
|
||||
{
|
||||
__HP_UPDATE_CONFIG_ERROR("Invalid consensus flag. Valid values: public|private");
|
||||
}
|
||||
__HP_STRING_COPY(&existing_patch.consensus, config->consensus);
|
||||
__HP_STRING_COPY(existing_patch->consensus, config->consensus);
|
||||
}
|
||||
|
||||
if (config->npl)
|
||||
@@ -541,32 +530,97 @@ int hp_update_config(const struct patch_config *config)
|
||||
{
|
||||
__HP_UPDATE_CONFIG_ERROR("Invalid npl flag. Valid values: public|private");
|
||||
}
|
||||
__HP_STRING_COPY(&existing_patch.npl, config->npl);
|
||||
__HP_STRING_COPY(existing_patch->npl, config->npl);
|
||||
}
|
||||
|
||||
if (config->appbill.mode)
|
||||
__HP_STRING_COPY(&existing_patch.appbill.mode, config->appbill.mode);
|
||||
__HP_STRING_COPY(existing_patch->appbill.mode, config->appbill.mode);
|
||||
|
||||
if (config->appbill.bin_args)
|
||||
__HP_STRING_COPY(&existing_patch.appbill.bin_args, config->appbill.bin_args);
|
||||
__HP_STRING_COPY(existing_patch->appbill.bin_args, config->appbill.bin_args);
|
||||
|
||||
if (__hp_write_to_patch_file(fd, &existing_patch) == -1)
|
||||
if (__hp_write_to_patch_file(fd, existing_patch) == -1)
|
||||
__HP_UPDATE_CONFIG_ERROR("Error writing updated config to patch.cfg file.");
|
||||
|
||||
__hp_free_patch_config(&existing_patch);
|
||||
__hp_free_patch_config(existing_patch);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error reading patch.cfg file.\n");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
__HP_FREE(root);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the existing config file values.
|
||||
* @return returns a pointer to a config structure, returns NULL on error.
|
||||
*/
|
||||
struct hp_config *hp_get_config()
|
||||
{
|
||||
const int fd = open(PATCH_FILE_PATH, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
fprintf(stderr, "Error opening patch.cfg file.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hp_config *config = __hp_read_from_patch_file(fd);
|
||||
if (config == NULL)
|
||||
fprintf(stderr, "Error reading patch.cfg file.\n");
|
||||
|
||||
close(fd);
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the memory allocated for the config structure.
|
||||
* @param config Pointer to the config to be freed.
|
||||
*/
|
||||
void hp_free_config(struct hp_config *config)
|
||||
{
|
||||
__hp_free_patch_config(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the values from the existing patch file.
|
||||
* @param fd File discriptor of the patch.cfg file.
|
||||
* @return returns a pointer to a patch_config structure, returns NULL on error.
|
||||
*/
|
||||
struct hp_config *__hp_read_from_patch_file(const int fd)
|
||||
{
|
||||
char buf[4096];
|
||||
const size_t len = read(fd, buf, sizeof(buf));
|
||||
if (len == -1)
|
||||
return NULL;
|
||||
|
||||
struct json_value_s *root = json_parse(buf, len);
|
||||
if (root && root->type == json_type_object)
|
||||
{
|
||||
struct json_object_s *object = (struct json_object_s *)root->payload;
|
||||
// Create struct to populate json values.
|
||||
struct hp_config *config;
|
||||
// Allocate memory for the patch_config struct.
|
||||
config = (struct hp_config *)malloc(sizeof(struct hp_config));
|
||||
// malloc and populate values to the struct.
|
||||
__hp_populate_patch_from_json_object(config, object);
|
||||
__HP_FREE(root);
|
||||
return config;
|
||||
}
|
||||
|
||||
__HP_FREE(root);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write values of the given patch config struct to the file discriptor given.
|
||||
* @param fd File discriptor of the patch.cfg file.
|
||||
* @param config Patch config structure.
|
||||
*/
|
||||
int __hp_write_to_patch_file(const int fd, const struct patch_config *config)
|
||||
int __hp_write_to_patch_file(const int fd, const struct hp_config *config)
|
||||
{
|
||||
struct iovec iov_vec[4];
|
||||
// {version: + newline + 4 spaces => 21;
|
||||
@@ -630,7 +684,7 @@ int __hp_write_to_patch_file(const int fd, const struct patch_config *config)
|
||||
* @param config Pointer to the patch config sturct to be populated.
|
||||
* @param object Pointer to the json object.
|
||||
*/
|
||||
void __hp_populate_patch_from_json_object(struct patch_config *config, struct json_object_s *object)
|
||||
void __hp_populate_patch_from_json_object(struct hp_config *config, const struct json_object_s *object)
|
||||
{
|
||||
const struct json_object_element_s *elem = object->start;
|
||||
do
|
||||
@@ -832,7 +886,7 @@ int __hp_write_control_msg(const void *buf, const uint32_t len)
|
||||
* Free memory allocated for the given patch config struct.
|
||||
* @param patch_config Pointer of patch config struct to be freed.
|
||||
*/
|
||||
void __hp_free_patch_config(struct patch_config *patch_config)
|
||||
void __hp_free_patch_config(struct hp_config *patch_config)
|
||||
{
|
||||
__HP_FREE(patch_config->version);
|
||||
__HP_FREE(patch_config->unl.list);
|
||||
@@ -842,6 +896,7 @@ void __hp_free_patch_config(struct patch_config *patch_config)
|
||||
__HP_FREE(patch_config->npl);
|
||||
__HP_FREE(patch_config->appbill.mode);
|
||||
__HP_FREE(patch_config->appbill.bin_args);
|
||||
__HP_FREE(patch_config);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -48,6 +48,15 @@ const echoContract = async (ctx) => {
|
||||
// })
|
||||
// await ctx.unl.send("Hello");
|
||||
// }
|
||||
|
||||
// Update patch config
|
||||
// await ctx.updateConfig({
|
||||
// version: "2.0",
|
||||
// unl: [
|
||||
// "edf3f3bff36e22d0e1c7abf791ca4900e717754443b8e861dcfbf1cd2bbd0f6159"
|
||||
// ],
|
||||
// consensus: "private"
|
||||
// });
|
||||
}
|
||||
|
||||
const hpc = new HotPocket.Contract();
|
||||
|
||||
@@ -109,19 +109,11 @@ class PatchConfig {
|
||||
|
||||
let updatedUnl = [];
|
||||
for (let pubKey of unl) {
|
||||
// Pubkeys are validated against length, ed prefix and hex characters.
|
||||
if (!pubKey.length)
|
||||
throw "UNL pubKey not specified.";
|
||||
else if (pubKey.length != 66)
|
||||
throw "Invalid UNL pubKey specified. Invalid length.";
|
||||
else if (!pubKey.startsWith("ed"))
|
||||
throw "Invalid UNL pubKey specified. Invalid format.";
|
||||
|
||||
try {
|
||||
let pubKeyBin = hexToUint8Array(pubKey.substring(2));
|
||||
}
|
||||
catch {
|
||||
throw "Invalid UNL pubKey specified. Decode error.";
|
||||
}
|
||||
else if (!(/^(e|E)(d|D)[0-9a-fA-F]{64}$/g.test(pubKey)))
|
||||
throw "Invalid UNL pubKey specified.";
|
||||
|
||||
updatedUnl.push(pubKey);
|
||||
}
|
||||
@@ -166,14 +158,15 @@ class PatchConfig {
|
||||
|
||||
// Saves the config changes to tha patch config.
|
||||
saveChanges() {
|
||||
// Property order is simmilar to the property order of the patch.cfg created by HP at the startup.
|
||||
const config = {
|
||||
version: this.#version,
|
||||
unl: this.#unl,
|
||||
bin_path: this.#binPath,
|
||||
bin_args: this.#binArgs ? this.#binArgs : "",
|
||||
roundtime: this.#roundtime,
|
||||
consensus: this.#consensus,
|
||||
npl: this.#npl,
|
||||
unl: this.#unl,
|
||||
appbill: {
|
||||
mode: this.#appbillMode ? this.#appbillMode : "",
|
||||
bin_args: this.#appbillBinArgs ? this.#appbillBinArgs : ""
|
||||
@@ -181,7 +174,8 @@ class PatchConfig {
|
||||
};
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.writeFile(this.#patchConfigPath, JSON.stringify(config), (err) => {
|
||||
// Format json to match with the patch.cfg json format created by HP at the startup.
|
||||
fs.writeFile(this.#patchConfigPath, JSON.stringify(config, null, 4), (err) => {
|
||||
if (err) reject(err);
|
||||
else resolve();
|
||||
});
|
||||
@@ -538,10 +532,6 @@ const invokeCallback = async (callback, ...args) => {
|
||||
}
|
||||
}
|
||||
|
||||
const hexToUint8Array = (hexString) => {
|
||||
return new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
|
||||
}
|
||||
|
||||
const errHandler = (err) => console.log(err);
|
||||
|
||||
module.exports = {
|
||||
|
||||
Reference in New Issue
Block a user