mirror of
https://github.com/EvernodeXRPL/sashimono.git
synced 2026-04-29 15:38:00 +00:00
Cluster script improvements and lib upgrades. (#73)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
6
mb-xrpl/package-lock.json
generated
6
mb-xrpl/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
12
test/vm-cluster/package-lock.json
generated
12
test/vm-cluster/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user