diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..e6259f4e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.env +logs/ +bitcoin-data/ +node_modules/ diff --git a/.env-example b/.env-example index e62f6ff8..81fc0280 100644 --- a/.env-example +++ b/.env-example @@ -1,5 +1,8 @@ POWPEG_NODE_JAR_PATH=/Users//repos/powpeg-node/build/libs/federate-node-SNAPSHOT-all.jar + +# Change to ./config/regtest-key-files-and-hsms to also tests with the tcp signer CONFIG_FILE_PATH=./config/regtest-all-keyfiles + LOG_HOME=/Users//config/logs-config BITCOIND_BIN_PATH=/Users//bitcoind/bin/bitcoind JAVA_BIN_PATH=/Library/Java/JavaVirtualMachines/adoptopenjdk-17.jdk/Contents/Home/bin/java @@ -24,3 +27,9 @@ WAIT_FOR_BLOCK_ATTEMPT_TIME_MILLIS= # `80` recommended for most machines with enough resources. `160`, `250` or more for machine with limited resources. # Adjust as needed, starting with low values so the tests run as fast as they can. WAIT_FOR_BLOCK_MAX_ATTEMPTS= + +# Use to know how to execute the tcpsigner. So far these tests are designed to run on macOS or Ubuntu. If no option is specified, then the tcpsigner will be executed for Ubuntu. +EXEC_ENV=MACOS + +# Set it to false if you want to keep the container after the tests are executed. This is useful for debugging purposes. You can use the `docker exec` command to enter the container and check the logs or any other files. +DOCKER_REMOVE_CONTAINER_AFTER_EXECUTION=true diff --git a/.env.docker b/.env.docker new file mode 100644 index 00000000..acb71c24 --- /dev/null +++ b/.env.docker @@ -0,0 +1,8 @@ +POWPEG_NODE_JAR_PATH=/rits/federate-node.jar + +# Change to /rits/config/regtest-key-files-and-hsms to also tests with the tcp signer +CONFIG_FILE_PATH=/rits/config/regtest-all-keyfiles + +LOG_HOME=/rits/logs + +BITCOIN_DATA_DIR=/rits/bitcoin-data diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 943e8aa1..5c161c76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,10 +35,7 @@ jobs: - name: Checkout id: checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Prepare Docker build context - run: cp config/regtest-all-keyfiles.js container-action/rit-local-configs/ - + - name: Docker meta id: meta uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 diff --git a/.gitignore b/.gitignore index 490affa1..8c03fd39 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,13 @@ logs .env .DS_Store .idea/ +_internal/ +manager-tcp +bitcoin-data/ +key.json +tcpsigner-manager.log +tcpsigner.log +*.xml +!base-logback-config.xml +logs/ +federate-node.jar diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..b86bee0c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,86 @@ +FROM ubuntu:24.04@sha256:2e863c44b718727c860746568e1d54afd13b2fa71b160f5cd9058fc436217b30 AS builder + +LABEL Description="Custom RSK node image to execute Rootstock Integration Tests" + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + git \ + gnupg2 \ + mocha \ + wget \ + build-essential \ + python3 \ + && apt clean + +RUN apt-get update && apt-get install -y libc6 + +# -- nodeJs --------------------------------------------------------- +ENV NODE_VERSION v18.20.2 +RUN mkdir -p /usr/local/nvm +ENV NVM_DIR /usr/local/nvm + +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \ + && . $NVM_DIR/nvm.sh \ + && nvm install $NODE_VERSION \ + && nvm alias default $NODE_VERSION \ + && nvm use default + +ENV NODE_PATH $NVM_DIR/$NODE_VERSION/lib/node_modules +ENV PATH $NVM_DIR/versions/node/$NODE_VERSION/bin:$PATH + +# -- java --------------------------------------------------------- +ENV JAVA_VERSION 17 + +RUN apt-get update \ + && apt-get -y install "openjdk-$JAVA_VERSION-jdk" + +ENV JAVA_HOME="/usr/lib/jvm/java-$JAVA_VERSION-openjdk-amd64" + +# -- bitcoind --------------------------------------------------------- +ENV BITCOIN_VERSION 0.18.1 + +RUN cd /tmp \ + && wget https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${BITCOIN_VERSION}-x86_64-linux-gnu.tar.gz \ + && tar -xzvf bitcoin-${BITCOIN_VERSION}-x86_64-linux-gnu.tar.gz -C /opt \ + && mv /opt/bitcoin-${BITCOIN_VERSION} /opt/bitcoin \ + && rm -v /opt/bitcoin/bin/test_bitcoin /opt/bitcoin/bin/bitcoin-qt \ + && ln -sv /opt/bitcoin/bin/* /usr/local/bin + +RUN apt-get update && \ + apt-get install -y procps libsecp256k1-dev && \ + rm -rf /var/lib/apt/lists/* + +# Set work directory for Node.js +WORKDIR /rits + +RUN mkdir /rits/bitcoin-data + +# Copy Node.js dependencies and install +COPY package*.json ./ +RUN npm install + +# Copy the rest of the Node.js project +COPY . . + +# Overriding .env file with docker specific values +COPY .env.docker /rits/.env + +RUN chmod +x /rits/configure.sh +RUN /rits/configure.sh + +RUN chmod +x /rits/runWithDockerEntrypoint.sh + +RUN tar xzf /rits/tcpsigner/bin/manager-tcp.tgz -C /rits/tcpsigner/bin + +# tcp signer dependencies +RUN chmod +x /rits/tcpsigner/entrypoint.sh \ + && chmod +x /rits/tcpsigner/bin/tcpsigner \ + && chmod +x /rits/tcpsigner/bin/manager-tcp + +# Remove after debugging +RUN apt-get update && apt-get install -y iproute2 && apt-get clean +RUN apt update && apt install -y netcat-openbsd + +CMD [ "npm", "run", "test-fail-fast" ] diff --git a/README.md b/README.md index c4762af1..5defe489 100644 --- a/README.md +++ b/README.md @@ -51,30 +51,29 @@ There are more variables in the `.env-example` files, but they already have defa `POWPEG_NODE_JAR_PATH` should point to the absolute path of the powpeg-node .jar file in your system to be executed. -You can leave this value as the example or set `CONFIG_FILE_PATH` to the actual path of the configuration file you are going to use. If you don't provide a value, it will try to use `./config/regtest.js` instead. +You can leave this value as the example or set `CONFIG_FILE_PATH` to the actual path of the configuration file you are going to use. If you don't provide a value, it will try to use `./config/regtest-all-keyfiles.js` instead. Notice that there is a `regtest-all-keyfiles.js` file in the `config` directory. You can either use that one, rename it, modify it or use a new one. -At the moment, we are running the tests with `keyfiles` nodes. When we setup the tests to run with the `tcpsigner`, then we will update this guide to include that. -Optional. If you want to see the logs of the federators (recommended), then `LOG_HOME` should point the directory where the logback configurations files are. Keep in mind that these logback `.xml` files should be contained in another directory inside this `LOG_HOME` directory called `genesis-federation` and `second-federation` and each of these directories should contain a `fed1.xml`, `fed2.xml` and `fed3.xml` files. You can always modify this in the `regtest-all-keyfiles.js` file. +### Running the tests using the Tcp Signer -Example: +At the moment, we are running the tests with `keyfiles` nodes by default. If you want to run the tests with nodes using the tcp signer, then change the value of the `CONFIG_FILE_PATH` environment variable to `./config/regtest-key-files-and-hsms`. Using this configuration file will load one tcp signer instance for each federator that has an `hsm` type. -``` - - - genesis-federation/ - - fed1.xml - - fed2.xml - - fed3.xml - - second-federation/ - - fed1.xml - - fed2.xml - - fed3.xml -``` +### Logs + +There is one `base-logback-config.xml` file in the `config` directory. It serves as an example of how the logback configuration files should look. + +In the `restest...` files in `config/` directory, each federator node has a reference to a logback configuration file path. By default, if the file doesn't exist in that path, then the setup process will create it automatically. + +You can update the `LOG_HOME` environment variable to point to where you have your logback configuration files. If you don't, then they will be created for you automatically at the root directory of this project, in a new `logs/` directory. + +The environment variable `LOG_HOME` should point the directory where the logback configurations files are. -Use `container-action/rit-local-configs/logbacks` as an example. +### Bitcoind You you already have `bitcoind` installed in your system, you can leave `BITCOIND_BIN_PATH` empty, the tests will use the one available from the system. If you have the `bitcoind` binaries in a specific directory, you can specify that directory in this variable. This way you don't have to fully install `bitcoind` in your system. +### Java + If you already have the correct `java` version installed in your system, you can leave `JAVA_BIN_PATH` empty, the tests will use the one available from the system. If you have the java binaries in a specific directory, you can specify that directory in this variable. Set the directory where you want the bitcoin database to be located at here `BITCOIN_DATA_DIR`. @@ -211,3 +210,33 @@ The command `run-single-test-file` will execute the file `singleTestFileRunner.j 1 - It will assign the `01_02_51-post_wasabi_fed_pubkeys_fork.js` test file name to the `process.env.INCLUDE_CASES` variable. Since it will be the one in that `INCLUDE_CASES` variable, then only that test file will be run. 2 - It will setup a boolean `process.env.RUNNING_SINGLE_TEST_FILE` variable to `true` so the `fulfillRequirementsToRunAsSingleTestFile` function can check if it needs to manually take the blockchain to a state where the test file can run or not. + +### Running with docker + +You can simply run the `npm` command: + +> npm run run-with-docker + +Running it this way is important. It will read the `.env` variables first to locale the `POWPEG_NODE_JAR_PATH` and copy it here so `Dockerfile` can copy it along with the rest of the project. + +Using docker to run the tests you don't have to worry about installing the right version of Java or Bitcoind. + +It will also read the `DOCKER_REMOVE_CONTAINER_AFTER_EXECUTION` variable from the `.env` file. + +So make sure you have the `.env` file ready. Then, the `Dockerfile` will replace the `.env` file's content with the `.env.docker` file's content. + +#### Building the docker image and running the container directly + +Building + +To build the docker image directly, on the root directory, run: + +> docker buildx build --platform linux/amd64 -t rits . + +The `--platform linux/amd64` is necessary because the bitcoind binary depends on that platform, or it will fail to run. + +Running + +To run it, execute: + +> docker run --platform linux/amd64 -it rits diff --git a/cleanEnv.js b/cleanEnv.js index f3b46ed0..8209ae17 100644 --- a/cleanEnv.js +++ b/cleanEnv.js @@ -55,7 +55,7 @@ function clearBitcoinDataDirectory() { const cleanEnvironment = async () => { console.info('Cleaning environment...'); await clearBitcoinDataDirectory(); - await clearLogFiles(process.env.LOG_HOME); + await clearLogFiles(process.env.LOG_HOME || './logs'); shell.exec(killServicesCommand); console.info('Environment cleaned.'); }; diff --git a/logbacks/logback-fed1.xml.sample b/config/base-logback-config.xml similarity index 70% rename from logbacks/logback-fed1.xml.sample rename to config/base-logback-config.xml index aa8da269..4b646993 100644 --- a/logbacks/logback-fed1.xml.sample +++ b/config/base-logback-config.xml @@ -1,109 +1,101 @@ - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /PATH/TO/LOGS/fed1.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + System.out + + %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n + + + + + /path/to/logs/file.log + + + %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n + + + + /path/to/logs/rskj-%d{yyyy-MM-dd}.%i.log.gz + 100MB + 7 + 1GB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/node-configs/second-federation/fed2.conf b/config/node-configs/second-federation/fed2.conf index b3b2e2b8..96d401c8 100644 --- a/config/node-configs/second-federation/fed2.conf +++ b/config/node-configs/second-federation/fed2.conf @@ -10,6 +10,33 @@ federator { "127.0.0.1:18444" ] gasPrice = 1000 + signers { + BTC { + type = "hsm" + host = "127.0.0.1" + port = 9981 + keyId = "m/44'/1'/0'/0/0" + bookkeeping { + difficultyTarget = "3" + informerInterval = "8000" + maxAmountBlockHeaders = "50" + maxChunkSizeToHsm = "50" + }, + socketTimeout = 30000 + } + RSK { + type = "hsm" + host = "127.0.0.1" + port = 9981 + keyId = "m/44'/1'/1'/0/0" + } + MST { + type = "hsm" + host = "127.0.0.1" + port = 9981 + keyId = "m/44'/1'/2'/0/0" + } + } } rpc { diff --git a/config/node-configs/second-federation/fed3.conf b/config/node-configs/second-federation/fed3.conf index 6a2a5355..4b66fe18 100644 --- a/config/node-configs/second-federation/fed3.conf +++ b/config/node-configs/second-federation/fed3.conf @@ -10,6 +10,33 @@ federator { "127.0.0.1:18444" ] gasPrice = 1000 + signers { + BTC { + type = "hsm" + host = "127.0.0.1" + port = 9983 + keyId = "m/44'/1'/0'/0/0" + bookkeeping { + difficultyTarget = "3" + informerInterval = "8000" + maxAmountBlockHeaders = "50" + maxChunkSizeToHsm = "50" + }, + socketTimeout = 30000 + } + RSK { + type = "hsm" + host = "127.0.0.1" + port = 9983 + keyId = "m/44'/1'/1'/0/0" + } + MST { + type = "hsm" + host = "127.0.0.1" + port = 9983 + keyId = "m/44'/1'/2'/0/0" + } + } } rpc { diff --git a/config/node-configs/third-federation/fed2.conf b/config/node-configs/third-federation/fed2.conf index 2eefd0b6..a087f640 100644 --- a/config/node-configs/third-federation/fed2.conf +++ b/config/node-configs/third-federation/fed2.conf @@ -10,6 +10,33 @@ federator { "127.0.0.1:18444" ] gasPrice = 1000 + signers { + BTC { + type = "hsm" + host = "127.0.0.1" + port = 9987 + keyId = "m/44'/1'/0'/0/0" + bookkeeping { + difficultyTarget = "3" + informerInterval = "8000" + maxAmountBlockHeaders = "50" + maxChunkSizeToHsm = "50" + }, + socketTimeout = 30000 + } + RSK { + type = "hsm" + host = "127.0.0.1" + port = 9987 + keyId = "m/44'/1'/1'/0/0" + } + MST { + type = "hsm" + host = "127.0.0.1" + port = 9987 + keyId = "m/44'/1'/2'/0/0" + } + } } rpc { diff --git a/config/node-configs/third-federation/fed3.conf b/config/node-configs/third-federation/fed3.conf index 8098bd37..2fc8c5a6 100644 --- a/config/node-configs/third-federation/fed3.conf +++ b/config/node-configs/third-federation/fed3.conf @@ -10,6 +10,33 @@ federator { "127.0.0.1:18444" ] gasPrice = 1000 + signers { + BTC { + type = "hsm" + host = "127.0.0.1" + port = 9989 + keyId = "m/44'/1'/0'/0/0" + bookkeeping { + difficultyTarget = "3" + informerInterval = "8000" + maxAmountBlockHeaders = "50" + maxChunkSizeToHsm = "50" + }, + socketTimeout = 30000 + } + RSK { + type = "hsm" + host = "127.0.0.1" + port = 9989 + keyId = "m/44'/1'/1'/0/0" + } + MST { + type = "hsm" + host = "127.0.0.1" + port = 9989 + keyId = "m/44'/1'/2'/0/0" + } + } } rpc { diff --git a/config/regtest-all-keyfiles.js b/config/regtest-all-keyfiles.js index 18c3b8ad..9a73117e 100644 --- a/config/regtest-all-keyfiles.js +++ b/config/regtest-all-keyfiles.js @@ -2,12 +2,12 @@ const path = require('path'); const nodesConfigPath = 'config/node-configs'; const keysPathResolve = 'node-keys'; const powpegNodeJarPath = process.env.POWPEG_NODE_JAR_PATH; -const federatesLogbackPath = process.env.LOG_HOME; +const federatesLogbackPath = process.env.LOG_HOME || path.resolve(__dirname, '../logs'); const bookkeepingConfigurations = { - difficultyTarget: 3, - informerIntervalInMs: 2000, - blockHeadersToSend: 27 + difficultyTarget: "3", + informerInterval: "8000", + blockHeadersToSend: "50" }; module.exports = { @@ -18,7 +18,7 @@ module.exports = { btc: { rpcUser: 'test', rpcPassword: 'test', - dir: process.env.BITCOIN_DATA_DIR, + dir: process.env.BITCOIN_DATA_DIR || path.resolve(__dirname, '../bitcoin-data'), }, federations: { genesisFederation: { diff --git a/config/regtest-key-files-and-hsms.js b/config/regtest-key-files-and-hsms.js new file mode 100644 index 00000000..1ca5fbbb --- /dev/null +++ b/config/regtest-key-files-and-hsms.js @@ -0,0 +1,311 @@ +const path = require('path'); +const nodesConfigPath = 'config/node-configs'; +const keysPathResolve = 'node-keys'; +const powpegNodeJarPath = process.env.POWPEG_NODE_JAR_PATH; +const federatesLogbackPath = process.env.LOG_HOME || path.resolve(__dirname, '../logs'); + +const bookkeepingConfigurations = { + difficultyTarget: "3", + informerInterval: "8000", + maxAmountBlockHeaders: "50", + maxChunkSizeToHsm: "50" +}; + +module.exports = { + init: { + mineInitialBitcoin: true, + federatesLogbackFile: federatesLogbackPath + }, + btc: { + rpcUser: 'test', + rpcPassword: 'test', + dir: process.env.BITCOIN_DATA_DIR || path.resolve(__dirname, '../bitcoin-data'), + }, + federations: { + genesisFederation: { + federationId: 'genesis-federation', + members: [ + { + id: 'federator-1-genesis-federation', + federationId: 'genesis-federation', + logbackFile: `${federatesLogbackPath}/genesis-federation/fed1.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/genesis-federation/fed1.conf`, + publicKeys: { + btc: '0x0362634ab57dae9cb373a5d536e66a8c4f67468bbcfb063809bab643072d78a124', + rsk: '0x0362634ab57dae9cb373a5d536e66a8c4f67468bbcfb063809bab643072d78a124', + mst: '0x0362634ab57dae9cb373a5d536e66a8c4f67468bbcfb063809bab643072d78a124', + }, + customConfig: { + 'federator.signers.BTC.type': 'keyFile', + 'federator.signers.BTC.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed1.key`), + 'federator.signers.RSK.type': 'keyFile', + 'federator.signers.RSK.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed1.key`), + 'federator.signers.MST.type': 'keyFile', + 'federator.signers.MST.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed1.key`), + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 30002, + 'peer.active.0.nodeId': 'c5946b3fbae03a654237da863c9ed534e0878657175b132b8ca630f245df04dbb0bde4f3854613b16032fb214f9cc00f75363976ee078cc4409cdc543036ccfd', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 30004, + 'peer.active.1.nodeId': 'cd53fc53a07f211641a677d250f6de99caf620e8e77071e811a28b3bcddf0be19e9da12b897b83765fbaebe717fab74fcb1b57c82f7978b8be3296239909e626', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 30000, + rpcPort: 30001, + nodeId: '62634ab57dae9cb373a5d536e66a8c4f67468bbcfb063809bab643072d78a1243bd206c2c7a218d6ff4c9a185e71f066bd354e5267875b7683fbc70a1d455e87' + }, + { + id: 'federator-2-genesis-federation', + federationId: 'genesis-federation', + logbackFile: `${federatesLogbackPath}/genesis-federation/fed2.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/genesis-federation/fed2.conf`, + publicKeys: { + btc: '0x03c5946b3fbae03a654237da863c9ed534e0878657175b132b8ca630f245df04db', + rsk: '0x03c5946b3fbae03a654237da863c9ed534e0878657175b132b8ca630f245df04db', + mst: '0x03c5946b3fbae03a654237da863c9ed534e0878657175b132b8ca630f245df04db', + }, + customConfig: { + 'federator.signers.BTC.type': 'keyFile', + 'federator.signers.BTC.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed2.key`), + 'federator.signers.RSK.type': 'keyFile', + 'federator.signers.RSK.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed2.key`), + 'federator.signers.MST.type': 'keyFile', + 'federator.signers.MST.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed2.key`), + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 30000, + 'peer.active.0.nodeId': '62634ab57dae9cb373a5d536e66a8c4f67468bbcfb063809bab643072d78a1243bd206c2c7a218d6ff4c9a185e71f066bd354e5267875b7683fbc70a1d455e87', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 30004, + 'peer.active.1.nodeId': 'cd53fc53a07f211641a677d250f6de99caf620e8e77071e811a28b3bcddf0be19e9da12b897b83765fbaebe717fab74fcb1b57c82f7978b8be3296239909e626', + 'federator.amountOfHeadersToSend': 500, + + }, + bookkeepingConfigurations, + port: 30002, + rpcPort: 30003, + nodeId: 'c5946b3fbae03a654237da863c9ed534e0878657175b132b8ca630f245df04dbb0bde4f3854613b16032fb214f9cc00f75363976ee078cc4409cdc543036ccfd' + }, + { + id: 'federate-3-genesis-federation', + federationId: 'genesis-federation', + logbackFile: `${federatesLogbackPath}/genesis-federation/fed3.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/genesis-federation/fed3.conf`, + publicKeys: { + btc: '0x02cd53fc53a07f211641a677d250f6de99caf620e8e77071e811a28b3bcddf0be1', + rsk: '0x02cd53fc53a07f211641a677d250f6de99caf620e8e77071e811a28b3bcddf0be1', + mst: '0x02cd53fc53a07f211641a677d250f6de99caf620e8e77071e811a28b3bcddf0be1', + }, + customConfig: { + 'federator.signers.BTC.type': 'keyFile', + 'federator.signers.BTC.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed3.key`), + 'federator.signers.RSK.type': 'keyFile', + 'federator.signers.RSK.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed3.key`), + 'federator.signers.MST.type': 'keyFile', + 'federator.signers.MST.path': path.resolve(__dirname, `${keysPathResolve}/genesis-federation/fed3.key`), + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 30000, + 'peer.active.0.nodeId': '62634ab57dae9cb373a5d536e66a8c4f67468bbcfb063809bab643072d78a1243bd206c2c7a218d6ff4c9a185e71f066bd354e5267875b7683fbc70a1d455e87', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 30002, + 'peer.active.1.nodeId': 'c5946b3fbae03a654237da863c9ed534e0878657175b132b8ca630f245df04dbb0bde4f3854613b16032fb214f9cc00f75363976ee078cc4409cdc543036ccfd', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 30004, + rpcPort: 30005, + nodeId: 'cd53fc53a07f211641a677d250f6de99caf620e8e77071e811a28b3bcddf0be19e9da12b897b83765fbaebe717fab74fcb1b57c82f7978b8be3296239909e626' + } + ] + }, + secondFederation: { + federationId: 'second-federation', + members: [ + { + id: 'federator-1-second-federation', + federationId: 'second-federation', + type: 'keyfile', + logbackFile: `${federatesLogbackPath}/second-federation/fed1.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/second-federation/fed1.conf`, + publicKeys: { + btc: '0x03328105ab6744914e61bcfcb729d741f23528fd6eb1b42628120ab027d82c9c2d', + rsk: '0x03328105ab6744914e61bcfcb729d741f23528fd6eb1b42628120ab027d82c9c2d', + mst: '0x03328105ab6744914e61bcfcb729d741f23528fd6eb1b42628120ab027d82c9c2d', + }, + customConfig: { + 'federator.signers.BTC.type': 'keyFile', + 'federator.signers.BTC.path': path.resolve(__dirname, `${keysPathResolve}/second-federation/fed1.key`), + 'federator.signers.RSK.type': 'keyFile', + 'federator.signers.RSK.path': path.resolve(__dirname, `${keysPathResolve}/second-federation/fed1.key`), + 'federator.signers.MST.type': 'keyFile', + 'federator.signers.MST.path': path.resolve(__dirname, `${keysPathResolve}/second-federation/fed1.key`), + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 30000, + 'peer.active.0.nodeId': '62634ab57dae9cb373a5d536e66a8c4f67468bbcfb063809bab643072d78a1243bd206c2c7a218d6ff4c9a185e71f066bd354e5267875b7683fbc70a1d455e87', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 40002, + 'peer.active.1.nodeId': '8ac219dc7ac6bfe401892ddd26c63f14e7cd5b62c750162c0889eee19c1725c29e52c00bc91ee260241d2e4ddcf72ed69746b226fc7c1c63f906d19a7a31988a', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 40000, + rpcPort: 40001, + nodeId: '328105ab6744914e61bcfcb729d741f23528fd6eb1b42628120ab027d82c9c2d8c445f8c6727e291e1abcaa8398bf47d4cca6ea6600b137b875b8df22251e325' + }, + { + id: 'federate-2-second-federation', + federationId: 'second-federation', + type: 'hsm', + hsmPort: 9981, + hsmDifficultyTarget: '0x03', + logbackFile: `${federatesLogbackPath}/second-federation/fed2.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/second-federation/fed2.conf`, + publicKeys: { + btc: '0x028ac219dc7ac6bfe401892ddd26c63f14e7cd5b62c750162c0889eee19c1725c2', + rsk: '0x028ac219dc7ac6bfe401892ddd26c63f14e7cd5b62c750162c0889eee19c1725c2', + mst: '0x028ac219dc7ac6bfe401892ddd26c63f14e7cd5b62c750162c0889eee19c1725c2', + }, + customConfig: { + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 40000, + 'peer.active.0.nodeId': '328105ab6744914e61bcfcb729d741f23528fd6eb1b42628120ab027d82c9c2d8c445f8c6727e291e1abcaa8398bf47d4cca6ea6600b137b875b8df22251e325', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 40004, + 'peer.active.1.nodeId': '5ba2b832b97cfba1626eb264bd1ec2733a7ca02602153c57c0c95c9700030dccb0edb612fd01bd806c0202aa3380fb8dcbeddb7a1386259d4b9679c0003d04bc', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 40002, + rpcPort: 40003, + nodeId: '8ac219dc7ac6bfe401892ddd26c63f14e7cd5b62c750162c0889eee19c1725c29e52c00bc91ee260241d2e4ddcf72ed69746b226fc7c1c63f906d19a7a31988a' + }, + { + id: 'federate-3-second-federation', + federationId: 'second-federation', + type: 'hsm', + hsmPort: 9983, + hsmDifficultyTarget: '0x03', + logbackFile: `${federatesLogbackPath}/second-federation/fed3.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/second-federation/fed3.conf`, + publicKeys: { + btc: '0x025ba2b832b97cfba1626eb264bd1ec2733a7ca02602153c57c0c95c9700030dcc', + rsk: '0x025ba2b832b97cfba1626eb264bd1ec2733a7ca02602153c57c0c95c9700030dcc', + mst: '0x025ba2b832b97cfba1626eb264bd1ec2733a7ca02602153c57c0c95c9700030dcc', + }, + customConfig: { + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 40000, + 'peer.active.0.nodeId': '328105ab6744914e61bcfcb729d741f23528fd6eb1b42628120ab027d82c9c2d8c445f8c6727e291e1abcaa8398bf47d4cca6ea6600b137b875b8df22251e325', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 40002, + 'peer.active.1.nodeId': '8ac219dc7ac6bfe401892ddd26c63f14e7cd5b62c750162c0889eee19c1725c29e52c00bc91ee260241d2e4ddcf72ed69746b226fc7c1c63f906d19a7a31988a', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 40004, + rpcPort: 40005, + nodeId: '5ba2b832b97cfba1626eb264bd1ec2733a7ca02602153c57c0c95c9700030dccb0edb612fd01bd806c0202aa3380fb8dcbeddb7a1386259d4b9679c0003d04bc' + } + ] + }, + thirdFederation: { // First svp federation + federationId: 'third-federation', + members: [ + { + id: 'federate-1-third-federation', + federationId: 'third-federation', + type: 'keyfile', + logbackFile: `${federatesLogbackPath}/third-federation/fed1.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/third-federation/fed1.conf`, + publicKeys: { + btc: '0x034ba6ec42eab139697c3614653e130e76fc15d1d7e5c91b3df63d3c06195d4226', + rsk: '0x034ba6ec42eab139697c3614653e130e76fc15d1d7e5c91b3df63d3c06195d4226', + mst: '0x034ba6ec42eab139697c3614653e130e76fc15d1d7e5c91b3df63d3c06195d4226', + }, + customConfig: { + 'federator.signers.BTC.type': 'keyFile', + 'federator.signers.BTC.path': path.resolve(__dirname, `${keysPathResolve}/third-federation/fed1.key`), + 'federator.signers.RSK.type': 'keyFile', + 'federator.signers.RSK.path': path.resolve(__dirname, `${keysPathResolve}/third-federation/fed1.key`), + 'federator.signers.MST.type': 'keyFile', + 'federator.signers.MST.path': path.resolve(__dirname, `${keysPathResolve}/third-federation/fed1.key`), + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 40000, + 'peer.active.0.nodeId': '328105ab6744914e61bcfcb729d741f23528fd6eb1b42628120ab027d82c9c2d8c445f8c6727e291e1abcaa8398bf47d4cca6ea6600b137b875b8df22251e325', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 50002, + 'peer.active.1.nodeId': '0b1d25b03d041028326ac5b27af941524c31bf09df5fece7476d3940f9cd2394d3cd349b9b265b7427607736dcee323d9e4a893b1d15549c928278a4e6012c08', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 50000, + rpcPort: 50001, + nodeId: '4ba6ec42eab139697c3614653e130e76fc15d1d7e5c91b3df63d3c06195d42265a5550cda65aa54de279a79a55e5513598b183e64f351e790d6370a6c67b141d' + }, + { + id: 'federate-2-third-federation', + federationId: 'third-federation', + type: 'hsm', + hsmPort: 9987, + hsmDifficultyTarget: '0x03', + logbackFile: `${federatesLogbackPath}/third-federation/fed2.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/third-federation/fed2.conf`, + publicKeys: { + btc: '0x020b1d25b03d041028326ac5b27af941524c31bf09df5fece7476d3940f9cd2394', + rsk: '0x020b1d25b03d041028326ac5b27af941524c31bf09df5fece7476d3940f9cd2394', + mst: '0x020b1d25b03d041028326ac5b27af941524c31bf09df5fece7476d3940f9cd2394', + }, + customConfig: { + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 50000, + 'peer.active.0.nodeId': '4ba6ec42eab139697c3614653e130e76fc15d1d7e5c91b3df63d3c06195d42265a5550cda65aa54de279a79a55e5513598b183e64f351e790d6370a6c67b141d', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 50004, + 'peer.active.1.nodeId': '501878fb22fdf374921d168bb1ea02b324f00eb2c7610cb452167a9dcdab01646d8c1f285b44074c45255fc693f19486819256ef98a9be8b62e4e9af4b54542c', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 50002, + rpcPort: 50003, + nodeId: '0b1d25b03d041028326ac5b27af941524c31bf09df5fece7476d3940f9cd2394d3cd349b9b265b7427607736dcee323d9e4a893b1d15549c928278a4e6012c08' + }, + { + id: 'federate-3-third-federation', + federationId: 'third-federation', + type: 'hsm', + hsmPort: 9989, + hsmDifficultyTarget: '0x03', + logbackFile: `${federatesLogbackPath}/third-federation/fed3.xml`, + classpath: powpegNodeJarPath, + configFile: `${nodesConfigPath}/third-federation/fed3.conf`, + publicKeys: { + btc: '0x02501878fb22fdf374921d168bb1ea02b324f00eb2c7610cb452167a9dcdab0164', + rsk: '0x02501878fb22fdf374921d168bb1ea02b324f00eb2c7610cb452167a9dcdab0164', + mst: '0x02501878fb22fdf374921d168bb1ea02b324f00eb2c7610cb452167a9dcdab0164', + }, + customConfig: { + 'peer.active.0.ip': '127.0.0.1', + 'peer.active.0.port': 50000, + 'peer.active.0.nodeId': '4ba6ec42eab139697c3614653e130e76fc15d1d7e5c91b3df63d3c06195d42265a5550cda65aa54de279a79a55e5513598b183e64f351e790d6370a6c67b141d', + 'peer.active.1.ip': '127.0.0.1', + 'peer.active.1.port': 50002, + 'peer.active.1.nodeId': '0b1d25b03d041028326ac5b27af941524c31bf09df5fece7476d3940f9cd2394d3cd349b9b265b7427607736dcee323d9e4a893b1d15549c928278a4e6012c08', + 'federator.amountOfHeadersToSend': 500, + }, + bookkeepingConfigurations, + port: 50004, + rpcPort: 50005, + nodeId: '501878fb22fdf374921d168bb1ea02b324f00eb2c7610cb452167a9dcdab01646d8c1f285b44074c45255fc693f19486819256ef98a9be8b62e4e9af4b54542c' + } + ] + } + }, +} diff --git a/configure.sh b/configure.sh index e1fb4b01..3efe3a92 100755 --- a/configure.sh +++ b/configure.sh @@ -1,13 +1,13 @@ -cd config/node-keys +chmod 400 config/node-keys/genesis-federation/fed1.key +chmod 400 config/node-keys/genesis-federation/fed2.key +chmod 400 config/node-keys/genesis-federation/fed3.key -chmod 400 genesis-federation/fed1.key -chmod 400 genesis-federation/fed2.key -chmod 400 genesis-federation/fed3.key +chmod 400 config/node-keys/second-federation/fed1.key +chmod 400 config/node-keys/second-federation/fed2.key +chmod 400 config/node-keys/second-federation/fed3.key -chmod 400 second-federation/fed1.key -chmod 400 second-federation/fed2.key -chmod 400 second-federation/fed3.key +chmod 400 config/node-keys/third-federation/fed1.key +chmod 400 config/node-keys/third-federation/fed2.key +chmod 400 config/node-keys/third-federation/fed3.key -chmod 400 third-federation/fed1.key -chmod 400 third-federation/fed2.key -chmod 400 third-federation/fed3.key +chmod +x tcpsigner/entrypoint.sh diff --git a/container-action/Dockerfile b/container-action/Dockerfile index b1ef5e3c..251501aa 100644 --- a/container-action/Dockerfile +++ b/container-action/Dockerfile @@ -40,8 +40,6 @@ RUN cd /tmp \ # -- configure entrypoint to run RIT-------------------------------------------- -RUN mkdir -p /usr/src/logbacks - WORKDIR /usr/src COPY entrypoint.sh /usr/src/entrypoint.sh @@ -52,6 +50,11 @@ RUN chmod +x /usr/src/entrypoint.sh \ && mkdir -p /usr/src/bitcoindata \ && chmod -R 755 /usr/src/bitcoindata +# tpc signer dependencies +RUN apt-get update && \ + apt-get install -y procps libsecp256k1-dev && \ + rm -rf /var/lib/apt/lists/* + ENTRYPOINT ["/usr/src/entrypoint.sh"] EXPOSE 18332 diff --git a/container-action/entrypoint.sh b/container-action/entrypoint.sh index cb4accb9..b0e9c20c 100644 --- a/container-action/entrypoint.sh +++ b/container-action/entrypoint.sh @@ -58,7 +58,6 @@ cd rit echo -e "\n\n--------- Checking out the RIT branch: $RIT_BRANCH ---------\n\n" git checkout -f "$RIT_BRANCH" -mv container-action/rit-local-configs/logbacks/* /usr/src/logbacks/ mv container-action/scripts/configure_rit_locally.sh . echo -e "\n\n--------- Copying configuration files ---------\n\n" diff --git a/container-action/rit-local-configs/logbacks/genesis-federation/fed1.xml b/container-action/rit-local-configs/logbacks/genesis-federation/fed1.xml deleted file mode 100644 index 541d8ece..00000000 --- a/container-action/rit-local-configs/logbacks/genesis-federation/fed1.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed1-genesis-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/genesis-federation/fed2.xml b/container-action/rit-local-configs/logbacks/genesis-federation/fed2.xml deleted file mode 100644 index d9854f55..00000000 --- a/container-action/rit-local-configs/logbacks/genesis-federation/fed2.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed2-genesis-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/genesis-federation/fed3.xml b/container-action/rit-local-configs/logbacks/genesis-federation/fed3.xml deleted file mode 100644 index 19ed7e3c..00000000 --- a/container-action/rit-local-configs/logbacks/genesis-federation/fed3.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed3-genesis-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/second-federation/fed1.xml b/container-action/rit-local-configs/logbacks/second-federation/fed1.xml deleted file mode 100644 index f44b6841..00000000 --- a/container-action/rit-local-configs/logbacks/second-federation/fed1.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed1-second-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/second-federation/fed2.xml b/container-action/rit-local-configs/logbacks/second-federation/fed2.xml deleted file mode 100644 index 888d387d..00000000 --- a/container-action/rit-local-configs/logbacks/second-federation/fed2.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed2-second-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/second-federation/fed3.xml b/container-action/rit-local-configs/logbacks/second-federation/fed3.xml deleted file mode 100644 index e26e6eca..00000000 --- a/container-action/rit-local-configs/logbacks/second-federation/fed3.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed3-second-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/third-federation/fed1.xml b/container-action/rit-local-configs/logbacks/third-federation/fed1.xml deleted file mode 100644 index 0e70d278..00000000 --- a/container-action/rit-local-configs/logbacks/third-federation/fed1.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed1-third-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/third-federation/fed2.xml b/container-action/rit-local-configs/logbacks/third-federation/fed2.xml deleted file mode 100644 index 5ea24265..00000000 --- a/container-action/rit-local-configs/logbacks/third-federation/fed2.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed2-third-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ - - - - - - - - - - - - - diff --git a/container-action/rit-local-configs/logbacks/third-federation/fed3.xml b/container-action/rit-local-configs/logbacks/third-federation/fed3.xml deleted file mode 100644 index 38f2c509..00000000 --- a/container-action/rit-local-configs/logbacks/third-federation/fed3.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - System.out - - %date{yyyy-MM-dd-HH:mm:ss.SSSS} %p [%c{1}] %m%n - - - - - /usr/src/logs/fed3-third-federation.log - - - %date{yyyy-MM-dd-HH:mm:ss.SSS} %p [%c{1}] %m%n - - - - ./logs/rskj-%d{yyyy-MM-dd}.%i.log.gz - 100MB - 7 - 1GB - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ - - - - - - - - - - - - - diff --git a/container-action/scripts/configure_rit_locally.sh b/container-action/scripts/configure_rit_locally.sh index 029036f9..399fcb86 100755 --- a/container-action/scripts/configure_rit_locally.sh +++ b/container-action/scripts/configure_rit_locally.sh @@ -10,12 +10,13 @@ echo "POWPEG_VERSION received as parameter: $POWPEG_VERSION" read -r -d '' SETTINGS_RIT < f.bind(colors)); -var HSM_OUTPUT = 'hsm-{index}-{keyType}:'; -var HSM_COLORS = [ - colors.blue, - colors.cyan, - colors.magenta, - colors.red, - colors.yellow -].map(f => f.bind(colors)); - -const DEFAULT_SIGNER_PATHS = { - [KEY_TYPE_BTC]: "m/44'/1'/0'/0/0", - [KEY_TYPE_RSK]: "m/44'/1'/0'/0/1", - [KEY_TYPE_MST]: "m/44'/1'/0'/0/2", -}; const HOST = '127.0.0.1'; -const HSM_HOST = '127.0.0.1'; -var getFederateOutputPrefix = function(index, label) { - var color = FEDERATE_COLORS[(index) % FEDERATE_COLORS.length]; +const getFederateOutputPrefix = function(index, label) { + const color = FEDERATE_COLORS[(index) % FEDERATE_COLORS.length]; return color(FEDERATE_OUTPUT.replace('{index}', `${index}-${label}`)); }; -var getHsmOutputPrefix = function(index, keyType) { - var color = HSM_COLORS[(index) % HSM_COLORS.length]; - return colors.bold(color(`${HSM_OUTPUT.replace('{index}', index).replace('{keyType}', keyType)}`)); -}; - -const startHsm = async (config, hsmOutputPrefix, stderr, stdout, keyId, latestBlockHash, difficultyTarget) => { - var hsmStdout; - var hsmStderr; - if (config.printOutput) { - hsmStdout = new LineWrapper({ prefix: hsmOutputPrefix }); - hsmStdout.pipe(stdout); - hsmStderr = new LineWrapper({ prefix: hsmOutputPrefix }); - hsmStderr.pipe(stderr); - } - var hsmRunner = new HsmRunner({ - version: config.version, - useDocker: config.useDocker, - command: config.command, - serverPath: config.serverPath, - keyPath: config.keyPath, - seedPath: config.seedPath, - port: config.port, - stdout: hsmStdout, - stderr: hsmStderr, - keyId: keyId, - forks: Runners.common.forks, - latestBlockHash: latestBlockHash, - difficultyTarget: difficultyTarget, - useLogger: config.useLogger - }); - try { - await hsmRunner.start() - process.stdout.write(`${hsmOutputPrefix} HSM ${hsmRunner.options.version} started on port ${hsmRunner.port} (PID: ${hsmRunner.getPid()}) \n`); - return hsmRunner; - } catch(ex) { - process.stdout.write(`${hsmOutputPrefix} ${ex.stack} \n`); - throw new Error(ex.toString()); - } -}; - const parseActivations = (forks) => { activations = { activationHeights: {} }; for (let fork in forks) { @@ -85,28 +33,61 @@ const parseActivations = (forks) => { return activations; }; -const startFederate = async (index, config, latestBlockHash, bookkeepingConfigurations) => { - - bookkeepingConfigurations = config.bookkeepingConfigurations || bookkeepingConfigurations; +const createLogbackFileIfNotExists = (logbackConfigFilePath, index) => { + const logbackFileDir = path.dirname(logbackConfigFilePath); + const baseLogbackFilePath = path.resolve(__dirname, '../config/base-logback-config.xml'); + const logFileName = `fed${index}.log`; + const logFilePath = path.join(logbackFileDir, logFileName); + + try { + fs.mkdirSync(logbackFileDir, { recursive: true }); + + const fd = fs.openSync(logbackConfigFilePath, 'wx'); + + const baseContent = fs.readFileSync(baseLogbackFilePath, 'utf8'); + + const updatedContent = baseContent + .replace(/.*<\/file>/, `${logFilePath}`) + .replace( + /.*<\/fileNamePattern>/, + `${logbackConfigFilePath}/rskj-%d{yyyy-MM-dd}.%i.log.gz` + ); + + fs.writeSync(fd, updatedContent, null, 'utf8'); + fs.closeSync(fd); + + } catch (err) { + if (err.code === 'EEXIST') { + // File already exists, nothing to do + } else { + console.error('Error creating logback file:', err.message); + } + } + }; + +const startFederate = async (index, fedConfig, blockHashCheckpoint, bookkeepingConfigurations) => { + + bookkeepingConfigurations = fedConfig.bookkeepingConfigurations || bookkeepingConfigurations; - const federateOutputPrefix = getFederateOutputPrefix(index, config.federationId); - var fedStderr = new LineWrapper({ prefix: federateOutputPrefix }); + const federateOutputPrefix = getFederateOutputPrefix(index, fedConfig.federationId); + const fedStderr = new LineWrapper({ prefix: federateOutputPrefix }); fedStderr.pipe(process.stderr); - var federateConfig = Object.assign({}, config, { + const federateConfig = Object.assign({}, fedConfig, { stderr: fedStderr, - logbackFile: config.logbackFile, + logbackFile: fedConfig.logbackFile, forks: parseActivations(Runners.common.forks), }); federateConfig.customConfig['miner.client.enabled'] = false; federateConfig.customConfig['federator.updateBridgeTimerEnabled'] = false; - // Override bookkeeping config for all the feds regardless if they use HSM2 or not + // Override bookkeeping fedConfig for all the feds regardless if they use HSM2 or not federateConfig.customConfig['federator.signers.BTC.bookkeeping.difficultyTarget'] = bookkeepingConfigurations.difficultyTarget; - federateConfig.customConfig['federator.signers.BTC.bookkeeping.informerInterval'] = bookkeepingConfigurations.informerIntervalInMs; - federateConfig.customConfig['federator.signers.BTC.bookkeeping.maxAmountBlockHeaders'] = bookkeepingConfigurations.blockHeadersToSend; + federateConfig.customConfig['federator.signers.BTC.bookkeeping.informerInterval'] = bookkeepingConfigurations.informerInterval; + federateConfig.customConfig['federator.signers.BTC.bookkeeping.maxAmountBlockHeaders'] = bookkeepingConfigurations.maxAmountBlockHeaders; + federateConfig.customConfig['federator.signers.BTC.bookkeeping.maxChunkSizeToHsm'] = bookkeepingConfigurations.maxChunkSizeToHsm; - var fedStdout = new LineWrapper({ prefix: federateOutputPrefix }); + const fedStdout = new LineWrapper({ prefix: federateOutputPrefix }); fedStdout.pipe(process.stdout); if (federateConfig.printOutput) { federateConfig.stdout = fedStdout; @@ -115,73 +96,46 @@ const startFederate = async (index, config, latestBlockHash, bookkeepingConfigur federateConfig.bitcoinPeer = Runners.hosts.bitcoin.peerHost; + createLogbackFileIfNotExists(federateConfig.logbackFile, index); + try { - // Start an HSM instance for each key type specified - let hsms = {}; - let publicKeys = {}; - for (keyType of KEY_TYPES) { - if (config.hsmConfigs != null && config.hsmConfigs[keyType] != null) { - let hsm = await startHsm( - config.hsmConfigs[keyType], - getHsmOutputPrefix(index, keyType), - process.stderr, - process.stdout, - config.hsmConfigs[keyType].keyId || DEFAULT_SIGNER_PATHS[keyType], - latestBlockHash, - bookkeepingConfigurations.difficultyTarget - ); - var signerId = keyType.toUpperCase(); - - // Override signers config - federateConfig.customConfig[`federator.signers.${signerId}.type`] = 'hsm'; - federateConfig.customConfig[`federator.signers.${signerId}.host`] = HSM_HOST; - federateConfig.customConfig[`federator.signers.${signerId}.port`] = hsm.port; - - // Set the key id, which might be overriden by configuration - let keyId = hsm.getKeyId(); - federateConfig.customConfig[`federator.signers.${signerId}.keyId`] = keyId; - - // Gather the bitcoin public key from the hsm - try { - publicKeys[keyType] = await executeWithRetries( - () => hsm.getPublicKey(keyId), - 3, - 1000 - ); - } - catch (ex) { - let hsmGenericStdOut = new LineWrapper({ prefix: getHsmOutputPrefix(index, 'undetermined') }); - hsmGenericStdOut.pipe(process.stdout); - hsmGenericStdOut.write(`${ex.toString()} ${ex.stack ? ex.stack : ''} \n`); - throw new Error(ex.toString()); - } - - hsms[keyType] = hsm; - } else { - // Gather public key from configuration for now. - // TODO: actually read the node's configuration file, - // read the key file and compute the public key - publicKeys[keyType] = config.publicKeys[keyType]; - } + + const fedRunner = new FederateRunner(federateConfig); + Runners.hosts.federates = Runners.hosts.federates || []; + + fedRunner.hsm = null; + + if(fedConfig.type === 'hsm') { + const hsmPort = fedConfig.hsmPort; + const difficultyTarget = fedConfig.hsmDifficultyTarget; + const hsm = new TcpSignerRunner(fedConfig.id, hsmPort, [`-c${blockHashCheckpoint}`, `--difficulty=${difficultyTarget}`]); + await hsm.start(); + const publicKeysFromTcpSigner = await hsm.getPublicKeys(); + const compressedPublicKeys = publicKeysFromTcpSigner.map((pubKey) => { + return compressPublicKey(pubKey); + }); + expect(compressedPublicKeys).to.be.deep.equal(Object.values(fedConfig.publicKeys), `HSM ${fedConfig.id} public keys do not match the expected ones`); + fedRunner.hsm = hsm; } - var fedRunner = new FederateRunner(federateConfig); - fedRunner.hsms = hsms; Runners.fedRunners = Runners.fedRunners || []; Runners.fedRunners.push(fedRunner); await fedRunner.start({ - port: config.port, - rpcPort: config.rpcPort, + port: fedConfig.port, + rpcPort: fedConfig.rpcPort, }); + + if(Runners.hosts.federates.length > 1) { + await waitForSync(getRskTransactionHelpers(Runners.hosts.federates)); + } - var host = { - federationId: config.federationId, + const host = { + federationId: fedConfig.federationId, host: `${HOST}:${fedRunner.ports.rpc}`, - publicKeys: publicKeys, + publicKeys: fedConfig.publicKeys, } - Runners.hosts.federates = Runners.hosts.federates || []; Runners.hosts.federates.push(host); Runners.hosts.federate = Runners.hosts.federate || host; fedStdout.write( @@ -200,5 +154,6 @@ const startFederate = async (index, config, latestBlockHash, bookkeepingConfigur }; module.exports = { - startFederate: startFederate + startFederate: startFederate, + createLogbackFileIfNotExists, }; \ No newline at end of file diff --git a/lib/federation-utils.js b/lib/federation-utils.js index fb5240e1..f5266630 100644 --- a/lib/federation-utils.js +++ b/lib/federation-utils.js @@ -2,6 +2,7 @@ const { KEY_TYPE_BTC, KEY_TYPE_RSK, KEY_TYPE_MST } = require('./constants/federa const { ethToWeis } = require('@rsksmart/btc-eth-unit-converter'); const rskUtils = require('./rsk-utils'); const federateStarter = require('./federate-starter'); +const { wait } = require('./utils'); const comparePublicKeys = (publicKeyA, publicKeyB) => { if (publicKeyA < publicKeyB) { @@ -48,19 +49,31 @@ const stopPreviousFederators = async (newFederationConfig) => { Runners.fedRunners.forEach((fedRunner) => { if(fedRunner.options.federationId === previousFederationId) { fedRunner.stop(); + if(fedRunner.hsm) { + fedRunner.hsm.stop(); + fedRunner.hsm = null; + } } }); + await wait(2000); + Runners.fedRunners = Runners.fedRunners.filter(fedRunner => fedRunner.options.federationId !== previousFederationId); Runners.hosts.federates = Runners.hosts.federates.filter(fedHostInfo => fedHostInfo.federationId !== previousFederationId); Runners.hosts.federate = Runners.hosts.federates[0]; }; -const startNewFederationNodes = async (newFederationConfig) => { +const startNewFederationNodes = async (newFederationConfig, rskTxHelper) => { + const hasHsm = newFederationConfig.some(member => member.type === 'hsm'); + let blockHashCheckpoint; + if(hasHsm) { + const latestBlockNumber = await rskTxHelper.getBlockNumber(); + blockHashCheckpoint = (await rskTxHelper.getBlock(latestBlockNumber - 10)).hash; + } for(let i = 0; i < newFederationConfig.length; i++) { const fedConfig = newFederationConfig[i]; - await federateStarter.startFederate(i + 1, fedConfig); + await federateStarter.startFederate(i + 1, fedConfig, blockHashCheckpoint); } }; diff --git a/lib/hsm-client.js b/lib/hsm-client.js deleted file mode 100644 index 4b7b737a..00000000 --- a/lib/hsm-client.js +++ /dev/null @@ -1,31 +0,0 @@ -var jsonTcpClient = require('./json-tcp-client'); - -var Client = function(host, port) { - this.client = jsonTcpClient.getClient(host, port); -}; - -Client.prototype.getVersion = function() { - return this.client.send({ command: "version" }).then((response) => { - if (response.errorcode === 0) { - return response.version; - } - - return Promise.reject(response.errorcode); - }) -}; - -Client.prototype.getPublicKey = function(keyId) { - return this.getVersion().then((version) => { - return this.client.send({ command: "getPubKey", version: version, keyId: keyId }).then((response) => { - if (response.errorcode === 0) { - return response.pubKey; - } - - return Promise.reject(response.errorcode); - }); - }); -}; - -module.exports = { - getClient: (host, port) => new Client(host, port), -}; diff --git a/lib/hsm-runner.js b/lib/hsm-runner.js deleted file mode 100644 index 29fe5412..00000000 --- a/lib/hsm-runner.js +++ /dev/null @@ -1,293 +0,0 @@ -var childProcess = require('child_process'); -var devnull = require('dev-null'); -var portUtils = require('./port-utils'); -var path = require('path'); -let HsmClient = require('./hsm-client'); -let { executeWithRetries } = require('./utils'); - -const VERSIONS = { - V1: '1', - V2: '2', - V2_STATELESS: '2_stateless' -}; - -let HSM_IDENTIFIERS = 0; - -let DEFAULT_HOSTS = {}; -DEFAULT_HOSTS[VERSIONS.V1] = '127.0.0.1'; -DEFAULT_HOSTS[VERSIONS.V2] = '0.0.0.0'; - -var DEFAULT_OPTIONS = { - version: VERSIONS.V1, - keyId: undefined -}; - -const spawnProcessVersion1 = (serverPath, port, keyPath) => { - let args = [ - serverPath, - `-p${port}` - ]; - if (keyPath) { - args.push(`-k${path.resolve(keyPath)}`); - } - return childProcess.spawn('python', args); -}; - -const spawnProcessVersion2Docker = ( - serverPath, - port, - keyPath, - identifier, - forks, - latestBlockHash, - difficultyTarget, - stateful, - useLogger -) => { - let tmpKeyFile = `keys.${identifier}.json`; - let containerName = `hsm2_${identifier}`; - let networkUpgrades = parseNetworkUpgrades(forks); - if (!latestBlockHash) { - throw new Error('to use HSM we need a checkpoint!'); - } - let checkpoint = latestBlockHash; - let dockerCommand = - `docker run -i --rm --name ${containerName} ` + - `-p ${port}:${port} ` + - `-v "\`pwd\`:/hsm2" ` + - `-w "/hsm2" ` + - `-u "\`id -u\`:\`id ` + - `-g\`" hsm2 ./${path.basename(serverPath)} ` + - `-b 0.0.0.0 ` + - `-p ${port} `+ - `-k ${tmpKeyFile} ` + - `-n '${networkUpgrades}' `; - if (stateful) { - dockerCommand += - `-c '${checkpoint}' ` + - `-d '0x${difficultyTarget.toString(16)}' ` + - `-s 'state_${identifier}.json' ` + - `-S 20480 `; - } - if (useLogger) { - dockerCommand += `-l 'logging-custom.cfg'`; // enable to configure custom logging. File must exist in simulator directory - } - //TODO Allow parametrization of custom logging file - let args = [ - '-c', - dockerCommand - ]; - const processOptions = { - cwd: path.dirname(serverPath), - // stdio: 'inherit' //==> uncomment if you need to see what's going on in the spawned process - }; - if (keyPath) { - childProcess.execSync(`cp ${path.resolve(keyPath)} ${tmpKeyFile}`, processOptions); - - // Remove this tmp file after 10 seconds. If the hsm has not fetched the file at that time, it won't anyway - setTimeout(() => { - childProcess.execSync(`rm -f ${tmpKeyFile}`, processOptions); - }, 10000); - } - const command = '/bin/sh'; - let process = childProcess.spawn(command, args, processOptions); - process.containerName = containerName; - return process; -}; - -const spawnProcessVersion2NoDocker = ( - serverPath, - port, - keyPath, - identifier, - forks, - checkpoint, - difficultyTarget, - stateful -) => { - let tmpKeyFile = `keys.${identifier}.json`; - let containerName = `hsm2_${identifier}`; - let networkUpgrades = parseNetworkUpgrades(forks); - let args = [ - '-b127.0.0.1', - `-p${port}`, - `-k${tmpKeyFile}`, - `-n${networkUpgrades}`, - `-S20480`, - //`-l logging-custom.cfg`; // enable to configure custom logging. File must exist in simulator directory - //TODO Allow parametrization of custom logging file - ]; - if (stateful) { - args = args.concat([ - `-c${checkpoint}`, - `-d0x${difficultyTarget.toString(16)}`, - `-sstate_${identifier}.json` // Set a fake state file - ]); - } - - const processOptions = { - cwd: path.dirname(serverPath), - // stdio: 'inherit' //==> uncomment if you need to see what's going on in the spawned process - }; - if (keyPath) { - childProcess.execSync(`cp ${path.resolve(keyPath)} ${tmpKeyFile}`, processOptions); - - // Remove this tmp file after 10 seconds. If the hsm has not fetched the file at that time, it won't anyway - setTimeout(() => { - childProcess.execSync(`rm -f ${tmpKeyFile}`, processOptions); - }, 10000); - } - let process = childProcess.spawn(serverPath, args, processOptions); - process.containerName = containerName; - return process; -}; - -let parseNetworkUpgrades = (forks) => { - let upgrades = {}; - Object.entries(forks).forEach(entry => { - const forkName = entry[0]; - const forkHeight = entry[1]; - upgrades[forkName] = forkHeight; - }); - let networkUpgrades = {network_upgrades:upgrades} - return JSON.stringify(networkUpgrades); -}; - -var HSMRunner = function(options) { - this.options = Object.assign({}, options); - if (!this.options.version) { - this.options.version = DEFAULT_OPTIONS.version; - } - if (!this.options.host) { - this.options.host = DEFAULT_HOSTS[this.options.version]; - } - - this.identifier = (new Date()).getTime() + HSM_IDENTIFIERS; - HSM_IDENTIFIERS++; -} - - -HSMRunner.prototype.spawnProcess = function() { - switch (this.options.version) { - case VERSIONS.V1: - return spawnProcessVersion1(this.options.serverPath, this.port, this.options.keyPath); - case VERSIONS.V2: - case VERSIONS.V2_STATELESS: - if (this.options.useDocker) { - return spawnProcessVersion2Docker( - this.options.serverPath, - this.port, - this.options.keyPath, - this.identifier, - this.options.forks, - this.options.latestBlockHash, - this.options.difficultyTarget, - this.options.version == VERSIONS.V2, - this.options.useLogger - ); - } else { - return spawnProcessVersion2NoDocker( - this.options.serverPath, - this.port, - this.options.keyPath, - this.identifier, - this.options.forks, - this.options.latestBlockHash, - this.options.difficultyTarget, - this.options.version == VERSIONS.V2 - ); - } - default: - throw new Error(`invalid version ${this.options.version}`); - } -} - -HSMRunner.prototype.start = function() { - if (this.isRunning()) { - throw "HSM already started"; - } - - if (this.options.serverPath == null) { - throw "Must specify a path for the HSM server"; - } - this.options.serverPath = path.resolve(this.options.serverPath); - - var futurePort = Promise.resolve(); - if (!this.options.port) { - futurePort = portUtils.findFreePorts(40000, 40100, 1, this.options.host); - } - - return futurePort.then((selectedPorts) => { - this.port = this.options.port; - if (!this.port) { - this.port = selectedPorts[0]; - } - - this.process = this.spawnProcess(); - if (this.process.stdout) { - if (this.options.stdout != null) { - this.process.stdout.pipe(this.options.stdout); - } else { - this.process.stdout.pipe(devnull()); - } - } - - if (this.process.stderr) { - if (this.options.stderr != null) { - this.process.stderr.pipe(this.options.stderr); - } else { - this.process.stderr.pipe(devnull()); - } - } - - this.running = false; - - this.process.on('exit', () => { - this.running = false; - }); - - this.client = HsmClient.getClient(this.options.host, this.port); - - return executeWithRetries( - () => { - return this.getPublicKey(); - }, - 10, - 1000).then((r) => { - this.running = true; - return r; - }); - }); -}; - -HSMRunner.prototype.stop = function() { - if (this.process == null) { - throw "HSM server was not started"; - } - this.process.kill('SIGINT'); -}; - -HSMRunner.prototype.isRunning = function() { - return this.running; -}; - -HSMRunner.prototype.getPid = function() { - if (!this.isRunning()) { - return false; - } - - return this.process.pid; -} - -HSMRunner.prototype.getPublicKey = function(keyId) { - let keyIdArg = keyId || this.options.keyId; - return this.client.getPublicKey(keyIdArg); -} - -HSMRunner.prototype.getKeyId = function() { - return this.options.keyId; -} - -module.exports = { - Runner: HSMRunner -}; diff --git a/lib/json-tcp-client.js b/lib/json-tcp-client.js index 44f49ef9..99a068ef 100644 --- a/lib/json-tcp-client.js +++ b/lib/json-tcp-client.js @@ -9,7 +9,7 @@ var Client = function(host, port) { Client.prototype.send = function(command) { return new Promise((resolve, reject) => { var socket = new net.Socket(); - socket.setTimeout(5000, () => reject('cant connect to socket')); + socket.setTimeout(30000, () => reject('cant connect to socket')); socket.connect(this.port, this.host); socket.on('connect', () => { var socketRl = readline.createInterface({ @@ -19,8 +19,8 @@ Client.prototype.send = function(command) { let timeout = setTimeout(() => { socket.destroy(); - reject('didnt get response from socket'); - }, 5000); + reject('Didnt get response from socket for command: ' + JSON.stringify(command)); + }, 30000); socketRl.question(JSON.stringify(command) + "\n", (response) => { clearTimeout(timeout); diff --git a/lib/rsk-utils.js b/lib/rsk-utils.js index a6c319ed..0d46c6eb 100644 --- a/lib/rsk-utils.js +++ b/lib/rsk-utils.js @@ -67,6 +67,7 @@ const waitForBlock = (rskClient, blockNumber, waitTime = 500, maxAttempts = 500) return new Promise((resolve, reject) => { let attempts = 1; let latestBlockNumber = -1; + let maxAttemptsOnError = 5; const checkBlockNumber = () => { rskClient.eth.getBlockNumber().then(newLatestBlockNumber => { const expectedMinBlockHeightReached = newLatestBlockNumber >= blockNumber; @@ -85,7 +86,11 @@ const waitForBlock = (rskClient, blockNumber, waitTime = 500, maxAttempts = 500) } setTimeout(checkBlockNumber, waitTime); }).catch(error => { - reject('[waitForBlock] ' + error.stack); + console.log(`[waitForBlock] error attempts remaining: ${maxAttemptsOnError}`); + if (maxAttemptsOnError-- === 0) { + return reject(new Error(`[waitForBlock] Error getting block number from rsk client: ${error.message}`)); + } + setTimeout(checkBlockNumber, waitTime); }); }; checkBlockNumber(); @@ -302,7 +307,7 @@ const triggerRelease = async (rskTransactionHelpers, btcClient, callbacks = {}) await callbacks.pegoutConfirmedCallback(rskTxHelper); } - const MAX_ATTEMPTS = 20; + const MAX_ATTEMPTS = 50; const CHECK_EVERY_MILLISECONDS = 2000; // At this point, the pegout is in the `pegoutsWaitingForSignatures` structure in the bridge. @@ -314,11 +319,13 @@ const triggerRelease = async (rskTransactionHelpers, btcClient, callbacks = {}) const method = async () => { const currentBridgeState = await getBridgeState(rskTxHelper.getClient()); + if(currentBridgeState.pegoutsWaitingForSignatures.length === 0) { return true; // Returning true to stop the retryWithCheck loop early } await wait(1000); await mineAndSync(rskTransactionHelpers); + return false; // Returning false to make the retryWithCheck loop continue until this check returns true or it reaches the max attempts }; @@ -342,6 +349,8 @@ const triggerRelease = async (rskTransactionHelpers, btcClient, callbacks = {}) // After this point the bridge should already have the change uxto registered await waitAndUpdateBridge(rskTxHelper); + const finalBridgeState = await getBridgeState(rskTxHelper.getClient()); + }; /** @@ -574,6 +583,11 @@ const uncompressPublicKey = (compressedPublicKey) => { return uncompressedPublicKey.toHex(false); }; +const compressPublicKey = (uncompressedPublicKey) => { + const point = secp.ProjectivePoint.fromHex(removePrefix0x(uncompressedPublicKey)); + return '0x' + point.toHex(true); +}; + const keccak256 = (str) => { return Web3.utils.keccak256(str); } @@ -626,4 +640,5 @@ module.exports = { removeCompressionPrefix, getAddressFromUncompressedPublicKey, uncompressPublicKey, + compressPublicKey, }; diff --git a/lib/tcpsigner-runner.js b/lib/tcpsigner-runner.js new file mode 100644 index 00000000..e3d226fb --- /dev/null +++ b/lib/tcpsigner-runner.js @@ -0,0 +1,165 @@ +const { spawn, execSync } = require('child_process'); +const path = require('path'); +const fs = require('fs'); +const { wait } = require('./utils'); +const jsonTcpClient = require('./json-tcp-client'); + +const TCP_SIGNER_HOST = '127.0.0.1'; + +const keyIds = [ + "m/44'/1'/0'/0/0", // tBTC + "m/44'/1'/1'/0/0", // tRSK + "m/44'/1'/2'/0/0" // tMST +]; + +class TcpSignerRunner { + + constructor(id, port, extraArgs = []) { + this.id = id; + this.dockerContainerName = `${this.id}-hsm`; + this.port = port; + this.extraArgs = extraArgs; + this.process = null; + this.dockerImage = 'tcpsigner-bundle'; + this.execEnv = process.env.EXEC_ENV || 'UBUNTU'; + this.client = jsonTcpClient.getClient(TCP_SIGNER_HOST, this.port); + this.isRunning = false; + } + + async start() { + + if(this.isRunning) { + throw new Error(`TcpSignerRunner "${this.dockerContainerName}" is already running`); + } + + const args = [ + ...this.extraArgs, + `-p${this.port}`, + `--key=key.json`, + `-y0x01` // Difficulty cap + ]; + + const tcpSignerExecutionPath = path.resolve(__dirname, '../tcpsigner'); + const keyPath = path.resolve(tcpSignerExecutionPath, `keys/${this.id}-key.json`); + + const destination = path.join(tcpSignerExecutionPath, 'key.json'); + fs.copyFileSync(keyPath, destination); + + const runningInMacOS = this.execEnv === 'MACOS'; + + const scriptPath = runningInMacOS ? path.resolve(tcpSignerExecutionPath, 'run.sh') : path.resolve(tcpSignerExecutionPath, 'entrypoint.sh'); + + if(runningInMacOS) { + args.push(`--docker-container-name=${this.dockerContainerName}`); + } + + const processOptions = { cwd: tcpSignerExecutionPath, stdio: 'inherit' }; + this.process = spawn(scriptPath, args, processOptions); + + this.process.on('exit', () => { + this.isRunning = false; + }); + + this.isRunning = true; + + await this.waitForReady(); + + return this.process; + + } + + async waitForReady() { + + let attempts = 0; + const maxAttempts = 25; + const waitTime = 1000; + + while (attempts < maxAttempts) { + try { + const versionResponseFromTcpSigner = await this.getVersion(); + console.log('Tcp Signer is ready. Version: ', versionResponseFromTcpSigner); + break; + } catch (err) { + attempts++; + if (attempts === maxAttempts) { + const message = `Failed to connect to instance "${this.dockerContainerName}" after ${maxAttempts} attempts.`; + console.error(message); + throw new Error(message); + } + await wait(waitTime); + } + } + + } + + stop() { + if (!this.process) { + return; + } + try { + const runningInMacOS = this.execEnv === 'MACOS'; + if(runningInMacOS) { + execSync(`docker stop ${this.dockerContainerName}`, { stdio: 'inherit' }); + } + this.process.kill('SIGKILL'); + this.process = null; + this.isRunning = false; + } catch (err) { + console.error(`Failed to stop instance "${this.dockerContainerName}":`, err.message); + } + } + + async getVersion() { + if(!this.isRunning) { + return -1; + } + try { + const response = await this.client.send({ command: "version" }); + if (response.errorcode === 0) { + return response.version; + } + } catch (err) { + throw new Error(`Failed to get version from instance "${this.dockerContainerName}": ${err.message}`); + } + } + + async getPublicKey(keyId) { + if(!this.isRunning) { + return []; + } + try { + const version = await this.getVersion(); + const response = await this.client.send({ command: "getPubKey", version: version, keyId: keyId }); + if (response.errorcode === 0) { + return response.pubKey; + } + } catch(err) { + console.error('Error getting public key: ', err.message); + throw new Error(`Failed to get public key from instance "${this.dockerContainerName}": ${err.message}`); + } + } + + async getPublicKeys() { + const promises = keyIds.map(keyId => this.getPublicKey(keyId)); + return Promise.all(promises); + } + + async getBlockchainState() { + if(!this.isRunning) { + return null; + } + try { + const version = await this.getVersion(); + const response = await this.client.send({ command: "blockchainState", version: version }); + if (response.errorcode === 0) { + return response.state; + } + } catch (err) { + console.error('Error getting blockchain state: ', err.message); + } + return null; + } + +} + +module.exports = TcpSignerRunner; diff --git a/lib/tests/change-federation.js b/lib/tests/change-federation.js index 99d0800d..a7ee6b7f 100644 --- a/lib/tests/change-federation.js +++ b/lib/tests/change-federation.js @@ -1,8 +1,8 @@ const rskUtils = require('../rsk-utils'); const bitcoinJsLib = require('bitcoinjs-lib'); -const { parseRLPToPegoutWaitingSignatures, parseU } = require('@rsksmart/bridge-state-data-parser/pegout-waiting-signature'); +const { parseRLPToPegoutWaitingSignatures } = require('@rsksmart/bridge-state-data-parser/pegout-waiting-signature'); const { parseRLPToActiveFederationUtxos } = require('@rsksmart/bridge-state-data-parser/active-federation-utxos'); -const { getRskTransactionHelpers } = require('../rsk-tx-helper-provider'); +const { getRskTransactionHelper, getRskTransactionHelpers } = require('../rsk-tx-helper-provider'); const { getBridge } = require('../bridge-provider'); const { removePrefix0x, @@ -99,13 +99,14 @@ const execute = (description, newFederationConfig) => { before(async () => { - await startNewFederationNodes(newFederationConfig.members); + rskTxHelper = getRskTransactionHelper(); + await startNewFederationNodes(newFederationConfig.members, rskTxHelper); rskTxHelpers = getRskTransactionHelpers(); rskTxHelper = rskTxHelpers[0]; bridgeTxParser = new BridgeTransactionParser(rskTxHelper.getClient()); btcTxHelper = getBtcClient(); - + await fundNewFederators(rskTxHelper, newFederationConfig.members); await rskUtils.waitForSync(rskTxHelpers); @@ -371,7 +372,7 @@ const execute = (description, newFederationConfig) => { } // Mining to have enough confirmations for the SVP fund transaction and updating the bridge. - await rskTxHelper.mine(3); + await rskUtils.mineAndSync(rskTxHelpers, 3); await rskUtils.waitAndUpdateBridge(rskTxHelper); const initialBridgeState = await getBridgeState(rskTxHelper.getClient()); @@ -499,7 +500,7 @@ const execute = (description, newFederationConfig) => { const oldFederationUtxos = parseRLPToActiveFederationUtxos(oldUtxosRlpEncoded); // Mining to activate the migration age - await rskTxHelper.mine(FUNDS_MIGRATION_AGE_SINCE_ACTIVATION_BEGIN + 1); + await rskUtils.mineAndSync(rskTxHelpers, FUNDS_MIGRATION_AGE_SINCE_ACTIVATION_BEGIN + 1); // Start migration await rskUtils.waitAndUpdateBridge(rskTxHelper); @@ -508,7 +509,7 @@ const execute = (description, newFederationConfig) => { expect(bridgeStateAfterUpdatingCollections.pegoutsWaitingForConfirmations.length).to.be.greaterThan(0, 'There should be at least one pegout waiting for confirmations.'); await wait(1000); - await rskTxHelper.mine(BTC_TO_RSK_MINIMUM_CONFIRMATIONS); + await rskUtils.mineAndSync(rskTxHelpers, BTC_TO_RSK_MINIMUM_CONFIRMATIONS); await wait(1000); await rskUtils.waitAndUpdateBridge(rskTxHelper); const lastFederator = rskTxHelpers[rskTxHelpers.length - 1]; @@ -614,8 +615,7 @@ const waitForExpectedCountOfAddSignatureEventsToBeEmitted = async (rskTxHelpers, addSignatureEvents.push(event); } }); - await rskTxHelper.mine(); - await rskUtils.waitForSync(rskTxHelpers); + await rskUtils.mineAndSync(rskTxHelpers, 1); fromBlockNumber++; if(maxAttempts === 0) { diff --git a/package.json b/package.json index 1c8f35b0..9a7df61e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "test": "mocha --timeout 600000", "test-fail-fast": "mocha -b --timeout 600000", "run-tests-multiple-times": "node multipleTestExecutionsRunner.js", - "run-single-test-file": "node singleTestFileRunner.js" + "run-single-test-file": "node singleTestFileRunner.js", + "run-with-docker": "node runWithDocker.js" }, "author": "", "license": "GPL3", diff --git a/runWithDocker.js b/runWithDocker.js new file mode 100644 index 00000000..0e098939 --- /dev/null +++ b/runWithDocker.js @@ -0,0 +1,25 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); +require('dotenv').config(); + +const jarPath = process.env.POWPEG_NODE_JAR_PATH; +const removeContainerAfterExecution = process.env.DOCKER_REMOVE_CONTAINER_AFTER_EXECUTION === 'true'; + +const removeContainerAfterExecutionFlag = removeContainerAfterExecution ? '--rm' : ''; + +if (jarPath) { + const destPath = path.join(__dirname, 'federate-node.jar'); + console.log(`Copying JAR from ${jarPath} to ${destPath}`); + fs.copyFileSync(jarPath, destPath); +} else { + console.log("POWPEG_NODE_JAR_PATH is not set. Skipping file copy."); +} + +console.log("Building Docker image..."); + +execSync('docker buildx build --platform linux/amd64 -t rits .', { stdio: 'inherit' }); + +console.log("Running Docker container..."); + +execSync(`docker run --name rits --platform linux/amd64 -it ${removeContainerAfterExecutionFlag} rits`, { stdio: 'inherit' }); diff --git a/tcpsigner/Dockerfile b/tcpsigner/Dockerfile new file mode 100644 index 00000000..065d2253 --- /dev/null +++ b/tcpsigner/Dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:24.04 + +RUN apt-get update && \ + apt-get install -y procps libsecp256k1-dev && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR /tcpsigner-bundle + +COPY bin bin +COPY entrypoint.sh entrypoint.sh +COPY key.json key.json + +RUN tar xzf bin/manager-tcp.tgz -C bin/ + +RUN chmod +x entrypoint.sh \ + && chmod +x bin/tcpsigner \ + && chmod +x bin/manager-tcp + +CMD ["./entrypoint.sh"] diff --git a/tcpsigner/README.md b/tcpsigner/README.md new file mode 100644 index 00000000..a6f5bc04 --- /dev/null +++ b/tcpsigner/README.md @@ -0,0 +1,51 @@ +# Tcp signer bundle + +This tcp signer bundle includes the built tcpsigner and tcp signer manager binaries (built on and to be used on Ubuntu 24), ready to be included in a Docker container and run. + +The `Dockerfile` in this directory is to be used to run the tcp signer bundle manually for testing purposes. + +To run the tcp signer bundle with docker, first execute: + +> chmod +x run.sh + +To build and run, try: + +> ./run.sh -h + +The `-h` parameter is to print the tcp signer `help` menu. + +To run the tcp signer with some parameters, like the checkpoint (with `-c` flag), and port 9995 (or any other you need), try: + +> ./run.sh -c0xf98c614b921913a70d36a68512e1bf3717a6ede3e05b9d1ab1fd8ba7bd0e9842 --difficulty=0x03 -p9995 + +You can also run another instance with a different port number, like: + +> ./run.sh -c0xf98c614b921913a70d36a68512e1bf3717a6ede3e05b9d1ab1fd8ba7bd0e9842 --difficulty=0x03 -p9997 + +When running multiple instances of the tcp signer, make sure to change the port number, to at least 2 units more. If the first instance has port 9995, then the second should be something like 9997 or any other number that is at least 2 units away. This is because the tcp signer will run with port `port - 1` while the tcp signer manager will run with `port`. Check the `entrypoint.sh` line with `TCP_SIGNER_PORT=$((PORT - 1))`. + +This is to avoid ports collision when running multiple instances of the tcp signer directly from a docker container. + +You can also specify a `key.json` file. Just put one in the `tcpsigner/` base directory and run: + +> ./run.sh -c0xf98c614b921913a70d36a68512e1bf3717a6ede3e05b9d1ab1fd8ba7bd0e9842 --difficulty=0x03 -p9995 --key=key.json + +For the `key.json` file, you can paste something like this: + +```json +{ + "m/44'/0'/0'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/0'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/0'/0/1": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/0'/0/2": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/1'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/2'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/137'/0'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/137'/0'/0/1": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/137'/1'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4" +} +``` + +If you don't pass a `--key` parameter, then the tcp signer will create a key file with random private keys that it will create. + +You can call the `entrypoint.sh` file directly if you are running this project in Ubuntu. diff --git a/tcpsigner/bin/manager-tcp.tgz b/tcpsigner/bin/manager-tcp.tgz new file mode 100644 index 00000000..c72f042b Binary files /dev/null and b/tcpsigner/bin/manager-tcp.tgz differ diff --git a/tcpsigner/bin/tcpsigner b/tcpsigner/bin/tcpsigner new file mode 100755 index 00000000..76e66bd0 Binary files /dev/null and b/tcpsigner/bin/tcpsigner differ diff --git a/tcpsigner/entrypoint.sh b/tcpsigner/entrypoint.sh new file mode 100755 index 00000000..5ddc4f62 --- /dev/null +++ b/tcpsigner/entrypoint.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +help() { + "$DIR/bin/tcpsigner" --help + exit 1 +} + +stop() { + exit +} + +trap stop SIGTERM SIGINT SIGQUIT SIGHUP ERR + +# ========================================================== +# ========================================================== +while getopts ":p:h" opt; do + case "$opt" in + p) + PORT=$OPTARG + ;; + h) + help + ;; + esac +done +# ========================================================== +# ========================================================== + +TCP_SIGNER_PORT=$((PORT - 1)) + +# 🔵 Check if manager-tcp binary exists. Necessary when running without Docker. +if [ ! -f "$DIR/bin/manager-tcp" ]; then + tar xzf "$DIR/bin/manager-tcp.tgz" -C "$DIR/bin/" +fi + +chmod +x $DIR/bin/tcpsigner +chmod +x $DIR/bin/manager-tcp + +chmod 444 $DIR/key.json + +# Start the TCPSigner +"$DIR/bin/tcpsigner" $@ -p$TCP_SIGNER_PORT > $DIR/tcpsigner.log 2>&1 & + +# Wait for it to be up and running +sleep 2 + +# Start the manager for the TCPSigner +"$DIR/bin/manager-tcp" -b0.0.0.0 -p$PORT -tp $TCP_SIGNER_PORT > $DIR/tcpsigner-manager.log 2>&1 & + +# Wait for any process to exit +wait -n + +# Exit with status of process that exited first +exit $? diff --git a/tcpsigner/keys/federate-2-second-federation-key.json b/tcpsigner/keys/federate-2-second-federation-key.json new file mode 100644 index 00000000..001916d6 --- /dev/null +++ b/tcpsigner/keys/federate-2-second-federation-key.json @@ -0,0 +1,11 @@ +{ + "m/44'/0'/0'/0/0": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/1'/0'/0/0": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/1'/0'/0/1": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/1'/0'/0/2": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/1'/1'/0/0": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/1'/2'/0/0": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/137'/0'/0/0": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/137'/0'/0/1": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a", + "m/44'/137'/1'/0/0": "cb0878d04ae1d7d30df5866f845467b1d3ead5116b7732b894d69b89dc90f03a" +} diff --git a/tcpsigner/keys/federate-2-third-federation-key.json b/tcpsigner/keys/federate-2-third-federation-key.json new file mode 100644 index 00000000..a03f670d --- /dev/null +++ b/tcpsigner/keys/federate-2-third-federation-key.json @@ -0,0 +1,11 @@ +{ + "m/44'/0'/0'/0/0": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/1'/0'/0/0": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/1'/0'/0/1": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/1'/0'/0/2": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/1'/1'/0/0": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/1'/2'/0/0": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/137'/0'/0/0": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/137'/0'/0/1": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06", + "m/44'/137'/1'/0/0": "7e878d8199b6e7159aa79fa8077c5e8129b1bd6ce1cd5016dfd568d9944a0a06" +} diff --git a/tcpsigner/keys/federate-3-second-federation-key.json b/tcpsigner/keys/federate-3-second-federation-key.json new file mode 100644 index 00000000..666f5817 --- /dev/null +++ b/tcpsigner/keys/federate-3-second-federation-key.json @@ -0,0 +1,11 @@ +{ + "m/44'/0'/0'/0/0": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/1'/0'/0/0": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/1'/0'/0/1": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/1'/0'/0/2": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/1'/1'/0/0": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/1'/2'/0/0": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/137'/0'/0/0": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/137'/0'/0/1": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367", + "m/44'/137'/1'/0/0": "88f1707bedd8afc8314035b2a8334bc5d6e6644aaf9b94e89cb5e27e9dc34367" +} diff --git a/tcpsigner/keys/federate-3-third-federation-key.json b/tcpsigner/keys/federate-3-third-federation-key.json new file mode 100644 index 00000000..6e029392 --- /dev/null +++ b/tcpsigner/keys/federate-3-third-federation-key.json @@ -0,0 +1,11 @@ +{ + "m/44'/0'/0'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/0'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/0'/0/1": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/0'/0/2": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/1'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/1'/2'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/137'/0'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/137'/0'/0/1": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4", + "m/44'/137'/1'/0/0": "e7272a960b8b7ca61b815b63d44db8f0aebd418e1613108027007a82541ac2f4" +} diff --git a/tcpsigner/run.sh b/tcpsigner/run.sh new file mode 100755 index 00000000..581304a7 --- /dev/null +++ b/tcpsigner/run.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +PORT=9999 +while getopts ":p:" opt; do + case "$opt" in + p) + PORT=$OPTARG + ;; + esac +done + +DOCKER_CONTAINER_NAME="" +NEW_ARGS=() + +for arg in "$@"; do + if [[ "$arg" == --docker-container-name=* ]]; then + DOCKER_CONTAINER_NAME="${arg#--docker-container-name=}" + else + NEW_ARGS+=("$arg") + fi +done + +DOCKER_IMAGE_NAME=tcpsigner-bundle + +docker buildx build --platform linux/amd64 -t $DOCKER_IMAGE_NAME . + +docker run --name $DOCKER_CONTAINER_NAME --platform linux/amd64 -ti --rm -p $PORT:$PORT $DOCKER_IMAGE_NAME ./entrypoint.sh -p$PORT "${NEW_ARGS[@]}" diff --git a/test.js b/test.js index 8bf1ca66..aaea266c 100644 --- a/test.js +++ b/test.js @@ -20,7 +20,7 @@ if (global.describe == null || global.it == null) { } // Load the configuration, regtest by default -const configFileName = process.env.CONFIG_FILE_PATH || './config/regtest'; +const configFileName = process.env.CONFIG_FILE_PATH || './config/regtest-all-keyfiles'; const config = require(configFileName); @@ -37,9 +37,10 @@ const HOST = '127.0.0.1'; const BTC_HOST = '127.0.0.1'; const bookkeepingConfigurations = { - difficultyTarget: 3, - informerIntervalInMs: 2000, - blockHeadersToSend: 27 + difficultyTarget: "3", + informerInterval: "8000", + maxAmountBlockHeaders: "50", + maxChunkSizeToHsm: "50", }; /** @@ -93,7 +94,7 @@ global.Runners = { fingerroot500: createForkObject('fingerroot500', 1), arrowhead600: createForkObject('arrowhead600', 1), arrowhead631: createForkObject('arrowhead631', 1), - lovell700: createForkObject('lovell700', 1100), + lovell700: createForkObject('lovell700', 1750), }, additionalFederationAddresses: [] } @@ -238,7 +239,7 @@ before(async () => { } process.stdout.write(`\n Starting additional Federate nodes from block ${latestBlock.hash}. Height: ${latestBlock.number} \n\n`); - return startFederates( + return await startFederates( federatesToStart.length + 1, config.additionalFederateNodes.map(getConfigForFederateNodes), latestBlock.hash @@ -283,12 +284,9 @@ const shutdownHooks = () => { if (Runners.fedRunners != null) { Runners.fedRunners.forEach((fedRunner, index) => { fedRunner.stop(); - // process.stdout.write(`${getFederateOutputPrefix(index)} stopped\n`); - if (fedRunner.hsms) { - for (const hsm in fedRunner.hsms) { - fedRunner.hsms[hsm].stop(); - // process.stdout.write(`${getHsmOutputPrefix(index, hsm)} stopped\n`); - } + if (fedRunner.hsm) { + fedRunner.hsm.stop(); + fedRunner.hsm = null; } }); } diff --git a/tests/00_00_01-sync.js b/tests/00_00_01-sync.js index 1ea8d30e..73517935 100644 --- a/tests/00_00_01-sync.js +++ b/tests/00_00_01-sync.js @@ -14,7 +14,8 @@ describe('Federators sync', () => { expect(Runners.hosts.federates.length).to.be.greaterThan(0, 'Federates array cannot be empty'); const rskTransactionHelpers = getRskTransactionHelpers(); - const blocksToMine = 20; + // Mining 515 blocks so we are ready to start using the tcpsigner. + const blocksToMine = 515; // Should mine and sync all the fed nodes and return the latest block number for each fed const federatorsLatestBlocks = await rskUtils.mineAndSync(rskTransactionHelpers, blocksToMine);