Cluster script improvements and lib upgrades. (#73)

This commit is contained in:
Ravin Perera
2021-11-02 14:16:49 +05:30
committed by GitHub
parent e43abfface
commit ee232be9e1
9 changed files with 154 additions and 33 deletions

View File

@@ -1,6 +1,8 @@
#ifndef __HOTPOCKET_CONTRACT_LIB_C__
#define __HOTPOCKET_CONTRACT_LIB_C__
// Hot Pocket contract library version 0.5.0
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -21,8 +23,9 @@ const char *__HP_PATCH_FILE_PATH = "../patch.cfg";
// Public constants.
#define HP_NPL_MSG_MAX_SIZE __HP_SEQPKT_MAX_SIZE
#define HP_KEY_SIZE 66 // Hex pubkey size. (64 char key + 2 chars for key type prfix)
#define HP_HASH_SIZE 64 // Hex hash size.
#define HP_KEY_SIZE 66 // Hex pubkey size. (64 char key + 2 chars for key type prfix)
#define HP_HASH_SIZE 64 // Hex hash size.
#define HP_CONTRACT_ID_SIZE 36 // Contract Id UUIDv4 string length.
const char *HP_POST_EXEC_SCRIPT_NAME = "post_exec.sh";
#define __HP_ASSIGN_STRING(dest, elem) \
@@ -168,9 +171,10 @@ struct hp_contract_context
{
bool readonly;
uint64_t timestamp;
char pubkey[HP_KEY_SIZE + 1]; // +1 for null char.
uint64_t lcl_seq_no; // lcl sequence no.
char lcl_hash[HP_HASH_SIZE + 1]; // +1 for null char.
char contract_id[HP_CONTRACT_ID_SIZE + 1]; // +1 for null char.
char pubkey[HP_KEY_SIZE + 1]; // +1 for null char.
uint64_t lcl_seq_no; // lcl sequence no.
char lcl_hash[HP_HASH_SIZE + 1]; // +1 for null char.
struct hp_users_collection users;
struct hp_unl_collection unl;
};
@@ -195,6 +199,7 @@ 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);
struct hp_config *hp_get_config();
int hp_update_config(const struct hp_config *config);
int hp_update_peers(const char *add_peers[], const size_t add_peers_count, const char *remove_peers[], const size_t remove_peers_count);
void hp_set_config_string(char **config_str, const char *value, const size_t value_size);
void hp_set_config_unl(struct hp_config *config, const struct hp_unl_node *new_unl, const size_t new_unl_count);
void hp_free_config(struct hp_config *config);
@@ -204,6 +209,8 @@ int __hp_write_control_msg(const void *buf, const uint32_t len);
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);
size_t __hp_get_json_string_array_encoded_len(const char *elems[], const size_t count);
int __hp_encode_json_string_array(char *buf, const char *elems[], const size_t count);
static struct __hp_contract __hpc = {};
@@ -276,9 +283,10 @@ int hp_deinit_contract()
__HP_FREE(cctx);
// Send termination control message.
__hp_write_control_msg("{\"type\":\"contract_end\"}", 23);
const int ret = __hp_write_control_msg("{\"type\":\"contract_end\"}", 23);
close(__hpc.control_fd);
return 0;
return ret;
}
const struct hp_contract_context *hp_get_context()
@@ -355,7 +363,7 @@ int hp_write_npl_msg(const void *buf, const uint32_t len)
{
if (len > HP_NPL_MSG_MAX_SIZE)
{
fprintf(stderr, "NPL message exceeds max length %d.", HP_NPL_MSG_MAX_SIZE);
fprintf(stderr, "NPL message exceeds max length %d.\n", HP_NPL_MSG_MAX_SIZE);
return -1;
}
@@ -370,7 +378,7 @@ int hp_writev_npl_msg(const struct iovec *bufs, const int buf_count)
if (len > HP_NPL_MSG_MAX_SIZE)
{
fprintf(stderr, "NPL message exceeds max length %d.", HP_NPL_MSG_MAX_SIZE);
fprintf(stderr, "NPL message exceeds max length %d.\n", HP_NPL_MSG_MAX_SIZE);
return -1;
}
@@ -583,6 +591,83 @@ void hp_free_config(struct hp_config *config)
__HP_FREE(config);
}
/**
* Updates the known-peers this node must attempt connections to.
* @param add_peers Array of strings containing peers to be added. Each string must be in the format of "<ip>:<port>".
* @param add_peers_count No. of peers to be added.
* @param remove_peers Array of strings containing peers to be removed. Each string must be in the format of "<ip>:<port>".
* @param remove_peers_count No. of peers to be removed.
*/
int hp_update_peers(const char *add_peers[], const size_t add_peers_count, const char *remove_peers[], const size_t remove_peers_count)
{
const size_t add_json_len = __hp_get_json_string_array_encoded_len(add_peers, add_peers_count);
char add_json[add_json_len];
if (__hp_encode_json_string_array(add_json, add_peers, add_peers_count) == -1)
{
fprintf(stderr, "Error when encoding peer update changeset 'add'.\n");
return -1;
}
const size_t remove_json_len = __hp_get_json_string_array_encoded_len(remove_peers, remove_peers_count);
char remove_json[remove_json_len];
if (__hp_encode_json_string_array(remove_json, remove_peers, remove_peers_count) == -1)
{
fprintf(stderr, "Error when encoding peer update changeset 'remove'.\n");
return -1;
}
const size_t msg_len = 47 + (add_json_len - 1) + (remove_json_len - 1);
char msg[msg_len];
sprintf(msg, "{\"type\":\"peer_changeset\",\"add\":[%s],\"remove\":[%s]}", add_json, remove_json);
if (__hp_write_control_msg(msg, msg_len - 1) == -1)
return -1;
return 0;
}
/**
* Returns the null-terminated string length required to encode as a json string array without enclosing brackets.
* @param elems Array of strings.
* @param count No. of strings.
*/
size_t __hp_get_json_string_array_encoded_len(const char *elems[], const size_t count)
{
size_t len = 1; // +1 for null terminator.
for (size_t i = 0; i < count; i++)
{
len += (strlen(elems[i]) + 2); // Quoted string.
if (i < count - 1)
len += 1; // Comma
}
return len;
}
/**
* Formats a string array in JSON notation without enclosing brackets.
* @param buf Buffer to populate the encoded output.
* @param elems Array of strings.
* @param count No. of strings.
*/
int __hp_encode_json_string_array(char *buf, const char *elems[], const size_t count)
{
size_t pos = 0;
for (size_t i = 0; i < count; i++)
{
const char *elem = elems[i];
buf[pos++] = '\"';
strcpy((buf + pos), elem);
pos += strlen(elem);
buf[pos++] = '\"';
if (i < count - 1)
buf[pos++] = ',';
}
buf[pos] = '\0';
return 0;
}
/**
* Read the values from the existing patch file.
* @param fd File discriptor of the patch.cfg file.
@@ -846,7 +931,11 @@ void __hp_parse_args_json(const struct json_object_s *object)
{
const struct json_string_s *k = elem->name;
if (strcmp(k->string, "pubkey") == 0)
if (strcmp(k->string, "contract_id") == 0)
{
__HP_ASSIGN_STRING(cctx->contract_id, elem);
}
else if (strcmp(k->string, "pubkey") == 0)
{
__HP_ASSIGN_STRING(cctx->pubkey, elem);
}
@@ -957,7 +1046,7 @@ int __hp_write_control_msg(const void *buf, const uint32_t len)
{
if (len > __HP_SEQPKT_MAX_SIZE)
{
fprintf(stderr, "Control message exceeds max length %d.", __HP_SEQPKT_MAX_SIZE);
fprintf(stderr, "Control message exceeds max length %d.\n", __HP_SEQPKT_MAX_SIZE);
return -1;
}

View File

@@ -13,7 +13,7 @@ mb_xrpl_conf=$mb_xrpl_data/mb-xrpl.cfg
sashimono_service="sashimono-agent"
cgcreate_service="sashimono-cgcreate"
mb_xrpl_service="sashimono-mb-xrpl"
hook_address="rK4qxNScYAz6rw7rv3tbktMn4Qr2VBLCM9"
hook_address="rpTA2MtFV7L6hLzjSBYc1FBgYqTs6APVdz"
group="sashimonousers"
admin_group="sashiadmin"
cgroupsuffix="-cg"
@@ -81,10 +81,8 @@ cp "$script_dir"/sashi $user_bin
# Check whether docker installation dir is still empty.
[ -z "$(ls -A $docker_bin 2>/dev/null)" ] && echo "Rootless Docker installation failed." && rollback
# This will be commented and self ip will be hardcoded since the interface differs from machine to machine.
# This needs to be fixed later.
# selfip=$(ip -4 a l ens3 | awk '/inet/ {print $2}' | cut -d/ -f1)
selfip="127.0.0.1"
# Detect self host address
selfip=$(hostname -I)
# Install private docker registry.
# (Disabled until secure registry configuration)
@@ -148,7 +146,7 @@ if [ "$quiet"=="-q" ]; then
# (This is done for testing purposes during development)
xrpl_faucet_url="https://hooks-testnet.xrpl-labs.com/newcreds"
hook_secret="snVCiKRox58HokST4YBEETw6w57oW"
hook_secret="spAhiYQMb71CyEHU4zAA5Q2PSiUkN"
func_url="https://func-hotpocket.azurewebsites.net/api/evrfaucet?code=pPUyV1q838ryrihA5NVlobVXj8ZGgn9HsQjGGjl6Vhgxlfha4/xCgQ=="
# Generate new fauset account.

View File

@@ -35,7 +35,7 @@ if [ "$quiet" == "-q" ]; then
# We only perform this for our testing setup during development.
echo "Cleaning up host XRP account..."
hook_address="rK4qxNScYAz6rw7rv3tbktMn4Qr2VBLCM9"
hook_address="rpTA2MtFV7L6hLzjSBYc1FBgYqTs6APVdz"
func_url="https://func-hotpocket.azurewebsites.net/api/evrfaucet?code=pPUyV1q838ryrihA5NVlobVXj8ZGgn9HsQjGGjl6Vhgxlfha4/xCgQ=="
mb_xrpl_conf=$mb_xrpl_data/mb-xrpl.cfg

View File

@@ -490,9 +490,9 @@
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"evernode-js-client": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.2.2.tgz",
"integrity": "sha512-NX8gNJfOkYNFJfWyKOmRS8psf+Dr32KglLBT0Vh6vUyIfHDIEyclbhoVAqFb6ea/PIpVwKN274pWof8jux+RDw==",
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.2.5.tgz",
"integrity": "sha512-L0noX3uopHA4NGD5bMEiogqLZglxPaBknbwBwWWjWCAg7Vtf29CzArehd4aGEPPaBAzZnj6WmJ1L9qLYq4RVeg==",
"requires": {
"eccrypto": "1.1.6",
"ripple-address-codec": "4.1.3",

View File

@@ -4,7 +4,7 @@
"build": "ncc build mb-xrpl.js --minify -o dist"
},
"dependencies": {
"evernode-js-client": "0.2.2",
"evernode-js-client": "0.2.5",
"sqlite3": "5.0.2"
}
}

View File

@@ -42,14 +42,14 @@ PRINTFORMAT="Node %2s: %s\n"
mode=$1
if [ "$mode" == "select" ] || [ "$mode" == "reconfig" ] || [ "$mode" == "lcl" ] || [ "$mode" == "get-unl" ] || [ "$mode" == "docker-pull" ] ||
[ "$mode" == "create" ] || [ "$mode" == "createall" ] || [ "$mode" == "start" ] || [ "$mode" == "stop" ] || [ "$mode" == "destroy" ] ||
[ "$mode" == "create" ] || [ "$mode" == "createall" ] || [ "$mode" == "start" ] || [ "$mode" == "stop" ] || [ "$mode" == "destroy" ] || [ "$mode" == "destroy-all" ] ||
[ "$mode" == "ssh" ] || [ "$mode" == "sshu" ] || [ "$mode" == "attach" ] || [ "$mode" == "ip" ] || [ "$mode" == "updatecfg" ] ||
[ "$mode" == "statefile" ] || [ "$mode" == "umount" ] || [ "$mode" == "backup" ] || [ "$mode" == "restore" ] || [ "$mode" == "syncwith" ]; then
echo "mode: $mode"
else
echo "Invalid command."
echo " Expected: select <contract name> | reconfig [N] [R] | lcl [N] | get-unl | docker-pull [N] | create [N] | createall <peerport> | start [N] | stop [N] |"
echo " destroy [N] | ssh <N>or<command> | sshu <N> | attach <N> | ip [N] | updatecfg [N] | statefile [N] <file> | umount [N] | backup <N> | restore [N] | syncwith <N>"
echo " destroy [N] | destroy-all [N] | ssh <N>or<command> | sshu <N> | attach <N> | ip [N] | updatecfg [N] | statefile [N] <file> | umount [N] | backup <N> | restore [N] | syncwith <N>"
echo " [N]: Optional node no. <N>: Required node no. [R]: 'R' If sashimono needed to reinstall."
exit 1
fi
@@ -590,6 +590,36 @@ if [ $mode == "destroy" ]; then
exit 0
fi
if [ $mode == "destroy-all" ]; then
# Destroy all instances of given host.
function destroyallinstances() {
hostaddr=${hostaddrs[$1]}
nodeno=$(expr $1 + 1)
while :
do
containername=$(sshskp $sshuser@$hostaddr sashi list | tail +3 | head -1 | awk '{ print $1 }')
if [ "$containername" != "" ]; then
echo "Node$nodeno. Destroying $containername..."
result=$(sshskp $sshuser@$hostaddr sashi destroy -n $containername)
echo "Node$nodeno. $containername: $result"
else
break
fi
done
}
if [ $nodeid = -1 ]; then
for i in "${!hostaddrs[@]}"; do
destroyallinstances $i &
done
wait
else
destroyallinstances $nodeid
fi
exit 0
fi
if [ $mode = "ssh" ]; then
if [ $nodeid = -1 ]; then
if [ -n "$2" ]; then

View File

@@ -264,7 +264,11 @@ async function main() {
});
const mode = args[0];
if (mode === "create") {
if (mode === "init") {
await createEvernodeConnections();
await initHosts();
}
else if (mode === "create") {
if (args.length === 1) {
await createInstancesSequentially();
}
@@ -280,7 +284,7 @@ async function main() {
console.log("Specify peer port for 'createall'.");
}
else {
console.log("Specifiy args: create | createall <peerport>")
console.log("Specifiy args: init | create | createall <peerport>")
}
if (rippleAPI)

View File

@@ -9,9 +9,9 @@
"integrity": "sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ=="
},
"@types/node": {
"version": "16.11.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.2.tgz",
"integrity": "sha512-w34LtBB0OkDTs19FQHXy4Ig/TOXI4zqvXS2Kk1PAsRKZ0I+nik7LlMYxckW0tSNGtvWmzB+mrCTbuEjuB9DVsw=="
"version": "16.11.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
"integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w=="
},
"@types/ws": {
"version": "7.4.7",
@@ -285,9 +285,9 @@
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"evernode-js-client": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.2.1.tgz",
"integrity": "sha512-iKe0iRxiqUQdPkRZ4ZzwgZ/mALdu7cW9rbOuL88fu3aLDNc451uGasfokrx9jxSFYVK4Uif0oHQkefg+oVetSg==",
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/evernode-js-client/-/evernode-js-client-0.2.5.tgz",
"integrity": "sha512-L0noX3uopHA4NGD5bMEiogqLZglxPaBknbwBwWWjWCAg7Vtf29CzArehd4aGEPPaBAzZnj6WmJ1L9qLYq4RVeg==",
"requires": {
"eccrypto": "1.1.6",
"ripple-address-codec": "4.1.3",

View File

@@ -2,7 +2,7 @@
"name": "evcluster",
"type": "module",
"dependencies": {
"evernode-js-client": "0.2.2",
"evernode-js-client": "0.2.5",
"node-fetch": "3.0.0"
}
}