diff --git a/lib/base/README.md b/lib/base/README.md index 440ab484..acb11abb 100644 --- a/lib/base/README.md +++ b/lib/base/README.md @@ -258,9 +258,9 @@ aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION ```bash sudo su bcuser # Execution client logs: -docker logs --tail 50 node_execution_1 -f +docker logs --tail 50 node-execution-1 -f # Base client logs: -docker logs --tail 50 node_node_1 -f +docker logs --tail 50 node-node-1 -f ``` 2. How to check the logs from the EC2 user-data script? diff --git a/lib/base/app.ts b/lib/base/app.ts index f0e95baf..1e7e9899 100644 --- a/lib/base/app.ts +++ b/lib/base/app.ts @@ -17,12 +17,13 @@ new BaseCommonStack(app, "base-common", { }); new BaseSingleNodeStack(app, "base-single-node", { - stackName: `base-single-node-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, + stackName: `base-single-node-${config.baseNodeConfig.baseClient}-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, env: { account: config.baseConfig.accountId, region: config.baseConfig.region }, instanceType: config.baseNodeConfig.instanceType, instanceCpuType: config.baseNodeConfig.instanceCpuType, baseNetworkId: config.baseNodeConfig.baseNetworkId, + baseClient: config.baseNodeConfig.baseClient, baseNodeConfiguration: config.baseNodeConfig.baseNodeConfiguration, restoreFromSnapshot: config.baseNodeConfig.restoreFromSnapshot, l1ExecutionEndpoint: config.baseNodeConfig.l1ExecutionEndpoint, @@ -32,12 +33,13 @@ new BaseSingleNodeStack(app, "base-single-node", { }); new BaseHANodesStack(app, "base-ha-nodes", { - stackName: `base-ha-nodes-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, + stackName: `base-ha-nodes-${config.baseNodeConfig.baseClient}-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, env: { account: config.baseConfig.accountId, region: config.baseConfig.region }, instanceType: config.baseNodeConfig.instanceType, instanceCpuType: config.baseNodeConfig.instanceCpuType, baseNetworkId: config.baseNodeConfig.baseNetworkId, + baseClient: config.baseNodeConfig.baseClient, baseNodeConfiguration: config.baseNodeConfig.baseNodeConfiguration, restoreFromSnapshot: config.baseNodeConfig.restoreFromSnapshot, l1ExecutionEndpoint: config.baseNodeConfig.l1ExecutionEndpoint, diff --git a/lib/base/lib/assets/instance/storage/restore-from-snapshot-archive-s3.sh b/lib/base/lib/assets/instance/storage/restore-from-snapshot-archive-s3.sh deleted file mode 100644 index 5bd8aa17..00000000 --- a/lib/base/lib/assets/instance/storage/restore-from-snapshot-archive-s3.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -set +e - -source /etc/cdk_environment - -echo "Downloading Snapshot." - -cd /data - -SNAPSHOT_FILE_NAME=snapshot.tar.gz -SNAPSHOT_DIR=/data - -LATEST_SNAPSHOT_FILE_NAME=$(curl https://$NETWORK_ID-$NODE_CONFIG-snapshots.base.org/latest) && \ -s5cmd --log error cp s3://base-snapshots-$NETWORK_ID-archive/$LATEST_SNAPSHOT_FILE_NAME $SNAPSHOT_DIR/$SNAPSHOT_FILE_NAME && \ -echo "Downloading Snapshot script finished" && \ -sleep 60 &&\ -echo "Starting snapshot decompression ..." && \ -tar --use-compress-program=unzstd -xvf $SNAPSHOT_DIR/$SNAPSHOT_FILE_NAME -C /data 2>&1 | tee unzip.log && echo "decompresed successfully..." || echo "decompression failed..." >> snapshots-decompression.log - -echo "Decompresed snapshot, cleaning up..." - -mv /data/snapshots/$NETWORK_ID/download/* $SNAPSHOT_DIR && \ -rm -rf /data/snapshots && \ -rm -rf $SNAPSHOT_DIR/$SNAPSHOT_FILE_NAME - -echo "Snapshot is ready, starting the service.." - -chown -R bcuser:bcuser $SNAPSHOT_DIR - -sudo systemctl daemon-reload -sudo systemctl enable --now node diff --git a/lib/base/lib/assets/instance/storage/restore-from-snapshot-http.sh b/lib/base/lib/assets/instance/storage/restore-from-snapshot.sh similarity index 50% rename from lib/base/lib/assets/instance/storage/restore-from-snapshot-http.sh rename to lib/base/lib/assets/instance/storage/restore-from-snapshot.sh index c36a5af0..53c310e9 100644 --- a/lib/base/lib/assets/instance/storage/restore-from-snapshot-http.sh +++ b/lib/base/lib/assets/instance/storage/restore-from-snapshot.sh @@ -12,28 +12,42 @@ SNAPSHOT_DIR=/data SNAPSHOT_DOWNLOAD_STATUS=-1 if [ "$SNAPSHOT_URL" == "none" ] || [ -z "${SNAPSHOT_URL}" ]; then - LATEST_SNAPSHOT_FILE_NAME=$(curl https://$NETWORK_ID-$NODE_CONFIG-snapshots.base.org/latest) - SNAPSHOT_URL=https://$NETWORK_ID-$NODE_CONFIG-snapshots.base.org/$LATEST_SNAPSHOT_FILE_NAME + + case $BASE_CLIENT in + "geth") + LATEST_SNAPSHOT_FILE_NAME=$(curl https://$NETWORK_ID-full-snapshots.base.org/latest) + SNAPSHOT_URL=https://$NETWORK_ID-full-snapshots.base.org/$LATEST_SNAPSHOT_FILE_NAME + ;; + "reth") + LATEST_SNAPSHOT_FILE_NAME=$(curl https://$NETWORK_ID-reth-archive-snapshots.base.org/latest) + SNAPSHOT_URL=https://$NETWORK_ID-reth-archive-snapshots.base.org/$LATEST_SNAPSHOT_FILE_NAME + ;; + *) + # Geth + LATEST_SNAPSHOT_FILE_NAME=$(curl https://$NETWORK_ID-full-snapshots.base.org/latest) + SNAPSHOT_URL=https://$NETWORK_ID-full-snapshots.base.org/$LATEST_SNAPSHOT_FILE_NAME + ;; + esac fi while (( SNAPSHOT_DOWNLOAD_STATUS != 0 )) do - PIDS=$(pgrep aria2c) + PIDS=$(pgrep wget) if [ -z "$PIDS" ]; then - aria2c --max-connection-per-server=1 $SNAPSHOT_URL -d $SNAPSHOT_DIR -o $SNAPSHOT_FILE_NAME -l /data/download.log --log-level=notice --allow-overwrite=true --allow-piece-length-change=true + wget $SNAPSHOT_URL -P $SNAPSHOT_DIR -O $SNAPSHOT_FILE_NAME fi SNAPSHOT_DOWNLOAD_STATUS=$? - pid=$(pidof aria2c) + pid=$(pidof wget) wait $pid - echo "aria2c exit." + echo "wget exit." case $SNAPSHOT_DOWNLOAD_STATUS in - 3) - echo "File does not exist." - exit 3 + 8) + echo "Server error." + exit 8 ;; - 9) + 3) echo "No space left on device." - exit 9 + exit 3 ;; *) continue @@ -46,9 +60,9 @@ sleep 60 echo "Starting snapshot decompression ..." -tar --use-compress-program=unzstd -xvf $SNAPSHOT_DIR/$SNAPSHOT_FILE_NAME -C /data 2>&1 | tee unzip.log && echo "decompresed successfully..." || echo "decompression failed..." >> snapshots-decompression.log +tar --use-compress-program=unzstd -xvf $SNAPSHOT_DIR/$SNAPSHOT_FILE_NAME -C /data 2>&1 | tee unzip.log && echo "decompressed successfully..." || echo "decompression failed..." >> snapshots-decompression.log -echo "Decompresed snapshot, cleaning up..." +echo "Decompressed snapshot, cleaning up..." mv /data/snapshots/$NETWORK_ID/download/* /data && \ rm -rf /data/snapshots && \ diff --git a/lib/base/lib/assets/node/node-start.sh b/lib/base/lib/assets/node/node-start.sh index 63deb24e..372cd9f7 100644 --- a/lib/base/lib/assets/node/node-start.sh +++ b/lib/base/lib/assets/node/node-start.sh @@ -4,7 +4,8 @@ set -e source /etc/cdk_environment export NETWORK_ENV=".env.$NETWORK_ID" -export CLIENT=geth +export CLIENT="$BASE_CLIENT" +export HOST_DATA_DIR="/data" echo "Script is starting client $CLIENT on $NETWORK_ENV" # Start the node diff --git a/lib/base/lib/assets/user-data-alinux.sh b/lib/base/lib/assets/user-data-alinux.sh index 5553f1d8..27818b1d 100644 --- a/lib/base/lib/assets/user-data-alinux.sh +++ b/lib/base/lib/assets/user-data-alinux.sh @@ -1,37 +1,24 @@ #!/bin/bash set +e -# Set by generic single-node and ha-node CDK components -LIFECYCLE_HOOK_NAME=${_LIFECYCLE_HOOK_NAME_} -AUTOSCALING_GROUP_NAME=${_AUTOSCALING_GROUP_NAME_} RESOURCE_ID=${_NODE_CF_LOGICAL_ID_} -ASSETS_S3_PATH=${_ASSETS_S3_PATH_} -DATA_VOLUME_TYPE=${_DATA_VOLUME_TYPE_} -DATA_VOLUME_SIZE=${_DATA_VOLUME_SIZE_} - -# Set by Base-specic CDK components and stacks -AWS_REGION=${_AWS_REGION_} STACK_NAME=${_STACK_NAME_} RESTORE_FROM_SNAPSHOT=${_RESTORE_FROM_SNAPSHOT_} -NETWORK_ID=${_NETWORK_ID_} -NODE_CONFIG=${_NODE_CONFIG_} -L1_EXECUTION_ENDPOINT=${_L1_EXECUTION_ENDPOINT_} -L1_CONSENSUS_ENDPOINT=${_L1_CONSENSUS_ENDPOINT_} -SNAPSHOT_URL=${_SNAPSHOT_URL_} { - echo "LIFECYCLE_HOOK_NAME=$LIFECYCLE_HOOK_NAME" - echo "AUTOSCALING_GROUP_NAME=$AUTOSCALING_GROUP_NAME" - echo "ASSETS_S3_PATH=$ASSETS_S3_PATH" - echo "DATA_VOLUME_TYPE=$DATA_VOLUME_TYPE" - echo "DATA_VOLUME_SIZE=$DATA_VOLUME_SIZE" - - echo "AWS_REGION=$AWS_REGION" - echo "NETWORK_ID=$NETWORK_ID" - echo "NODE_CONFIG=$NODE_CONFIG" - echo "L1_EXECUTION_ENDPOINT=$L1_EXECUTION_ENDPOINT" - echo "L1_CONSENSUS_ENDPOINT=$L1_CONSENSUS_ENDPOINT" - echo "SNAPSHOT_URL=$SNAPSHOT_URL" + echo "LIFECYCLE_HOOK_NAME=${_LIFECYCLE_HOOK_NAME_}" + echo "AUTOSCALING_GROUP_NAME=${_AUTOSCALING_GROUP_NAME_}" + echo "ASSETS_S3_PATH=${_ASSETS_S3_PATH_}" + echo "DATA_VOLUME_TYPE=${_DATA_VOLUME_TYPE_}" + echo "DATA_VOLUME_SIZE=${_DATA_VOLUME_SIZE_}" + + echo "AWS_REGION=${_AWS_REGION_}" + echo "NETWORK_ID=${_NETWORK_ID_}" + echo "BASE_CLIENT=${_BASE_CLIENT_}" + echo "NODE_CONFIG=${_NODE_CONFIG_}" + echo "L1_EXECUTION_ENDPOINT=${_L1_EXECUTION_ENDPOINT_}" + echo "L1_CONSENSUS_ENDPOINT=${_L1_CONSENSUS_ENDPOINT_}" + echo "SNAPSHOT_URL=${_SNAPSHOT_URL_}" } >> /etc/cdk_environment source /etc/cdk_environment @@ -45,11 +32,9 @@ echo "Architecture detected: $arch" if [ "$arch" == "x86_64" ]; then SSM_AGENT_BINARY_URI=https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm - S5CMD_URI=https://github.com/peak/s5cmd/releases/download/v2.1.0/s5cmd_2.1.0_Linux-64bit.tar.gz YQ_URI=https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 else SSM_AGENT_BINARY_URI=https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_arm64/amazon-ssm-agent.rpm - S5CMD_URI=https://github.com/peak/s5cmd/releases/download/v2.1.0/s5cmd_2.1.0_Linux-arm64.tar.gz YQ_URI=https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 fi @@ -61,29 +46,6 @@ wget $YQ_URI -O /usr/bin/yq && chmod +x /usr/bin/yq sudo systemctl enable crond.service sudo systemctl start crond.service -echo " Installing aria2 a p2p downloader" -cd /tmp - -if [ "$arch" == "x86_64" ]; then - wget https://github.com/q3aql/aria2-static-builds/releases/download/v1.36.0/aria2-1.36.0-linux-gnu-64bit-build1.tar.bz2 - tar jxvf aria2-1.36.0-linux-gnu-64bit-build1.tar.bz2 - cd aria2-1.36.0-linux-gnu-64bit-build1/ - make install -else - wget https://github.com/q3aql/aria2-static-builds/releases/download/v1.36.0/aria2-1.36.0-linux-gnu-arm-rbpi-build1.tar.bz2 - tar jxvf aria2-1.36.0-linux-gnu-arm-rbpi-build1.tar.bz2 - cd aria2-1.36.0-linux-gnu-arm-rbpi-build1/ - make install -fi - -echo " Installing s5cmd" -cd /opt -wget -q $S5CMD_URI -O s5cmd.tar.gz -tar -xf s5cmd.tar.gz -chmod +x s5cmd -mv s5cmd /usr/bin -s5cmd version - cd /opt echo "Downloading assets zip file" @@ -116,7 +78,7 @@ echo "Starting docker" service docker start systemctl enable docker -echo "Clonning node repo" +echo "Cloning node repo" cd /home/bcuser GIT_URL=https://github.com/base-org/node.git git clone $GIT_URL @@ -150,28 +112,12 @@ case $NODE_CONFIG in ;; esac -case $NETWORK_ID in - "mainnet") - sed -i "s#OP_NODE_L1_ETH_RPC=https://1rpc.io/eth#OP_NODE_L1_ETH_RPC=$L1_EXECUTION_ENDPOINT#g" $OP_CONFIG_FILE_PATH - sed -i '/.env.mainnet/s/^#//g' /home/bcuser/node/docker-compose.yml - sed -i '/OP_NODE_L1_BEACON/s/^#//g' $OP_CONFIG_FILE_PATH - sed -i "s#OP_NODE_L1_BEACON=https://your.mainnet.beacon.node/endpoint-here#OP_NODE_L1_BEACON=$L1_CONSENSUS_ENDPOINT#g" $OP_CONFIG_FILE_PATH - ;; - "sepolia") - sed -i "s#OP_NODE_L1_ETH_RPC=https://rpc.sepolia.org#OP_NODE_L1_ETH_RPC=$L1_EXECUTION_ENDPOINT#g" $OP_CONFIG_FILE_PATH - sed -i "/.env.sepolia/s/^#//g" /home/bcuser/node/docker-compose.yml - sed -i '/OP_NODE_L1_BEACON/s/^#//g' $OP_CONFIG_FILE_PATH - sed -i "s#OP_NODE_L1_BEACON=https://your.sepolia.beacon.node/endpoint-here#OP_NODE_L1_BEACON=$L1_CONSENSUS_ENDPOINT#g" $OP_CONFIG_FILE_PATH - ;; - *) - echo "Network id is not valid." - exit 1 - ;; -esac - -echo "OP_NODE_L1_TRUST_RPC=true" >> $OP_CONFIG_FILE_PATH +sed -i "s##$L1_EXECUTION_ENDPOINT#g" $OP_CONFIG_FILE_PATH +sed -i "s##$L1_CONSENSUS_ENDPOINT#g" $OP_CONFIG_FILE_PATH +sed -i "s##$L1_CONSENSUS_ENDPOINT#g" $OP_CONFIG_FILE_PATH +sed -i "s#OP_NODE_L1_TRUST_RPC=\"false\"#OP_NODE_L1_TRUST_RPC=\"true\"#g" $OP_CONFIG_FILE_PATH -sed -i "s#GETH_HOST_DATA_DIR=./geth-data#GETH_HOST_DATA_DIR=/data/geth#g" /home/bcuser/node/.env +sed -i "s#HOST_DATA_DIR=./$BASE_CLIENT-data#HOST_DATA_DIR=/data#g" /home/bcuser/node/.env chown -R bcuser:bcuser /home/bcuser/node @@ -242,16 +188,6 @@ echo "Starting CloudWatch Agent" -a fetch-config -c file:/opt/aws/amazon-cloudwatch-agent/etc/custom-amazon-cloudwatch-agent.json -m ec2 -s systemctl restart amazon-cloudwatch-agent -if [ "$RESTORE_FROM_SNAPSHOT" == "false" ]; then - echo "Skipping restoration from snapshot. Starting node" - systemctl daemon-reload - systemctl enable --now node -else - echo "Restoring full node from snapshot over http" - chmod +x /opt/instance/storage/restore-from-snapshot-http.sh - echo "/opt/instance/storage/restore-from-snapshot-http.sh" | at now + 1 min -fi - if [[ "$LIFECYCLE_HOOK_NAME" != "none" ]]; then echo "Signaling ASG lifecycle hook to complete" TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") @@ -259,5 +195,15 @@ if [[ "$LIFECYCLE_HOOK_NAME" != "none" ]]; then aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE --instance-id $INSTANCE_ID --lifecycle-hook-name "$LIFECYCLE_HOOK_NAME" --auto-scaling-group-name "$AUTOSCALING_GROUP_NAME" --region $AWS_REGION fi +if [ "$RESTORE_FROM_SNAPSHOT" == "false" ]; then + echo "Skipping restoration from snapshot. Starting node" + systemctl daemon-reload + systemctl enable --now node +else + echo "Restoring full node from snapshot" + chmod +x /opt/instance/storage/restore-from-snapshot.sh + /opt/instance/storage/restore-from-snapshot.sh +fi + echo "All Done!!" set -e diff --git a/lib/base/lib/config/baseConfig.interface.ts b/lib/base/lib/config/baseConfig.interface.ts index b6d0fc3f..29f1f3f8 100644 --- a/lib/base/lib/config/baseConfig.interface.ts +++ b/lib/base/lib/config/baseConfig.interface.ts @@ -1,6 +1,7 @@ import * as configTypes from "../../../constructs/config.interface"; export type BaseNetworkId = "mainnet" | "sepolia"; +export type BaseClient = "geth" | "reth"; export type BaseNodeConfiguration = "full" | "archive"; export {AMBEthereumNodeNetworkId} from "../../../constructs/config.interface"; @@ -16,6 +17,7 @@ export interface BaseBaseConfig extends configTypes.BaseConfig { export interface BaseBaseNodeConfig extends configTypes.BaseNodeConfig { baseNetworkId: BaseNetworkId; + baseClient: BaseClient; baseNodeConfiguration: BaseNodeConfiguration; dataVolume: BaseDataVolumeConfig; restoreFromSnapshot: boolean; diff --git a/lib/base/lib/config/baseConfig.ts b/lib/base/lib/config/baseConfig.ts index 26727b08..557f3fc4 100644 --- a/lib/base/lib/config/baseConfig.ts +++ b/lib/base/lib/config/baseConfig.ts @@ -18,16 +18,28 @@ const parseDataVolumeType = (dataVolumeType: string) => { } } +const getClientConfiguration = (client: configTypes.BaseClient, nodeConfiguration: configTypes.BaseNodeConfiguration) => { + switch (client) { + case "reth": + return "archive"; + case "geth": + return "full"; + default: + return "full"; + } +} + export const baseConfig: configTypes.BaseBaseConfig = { accountId: process.env.AWS_ACCOUNT_ID || "xxxxxxxxxxx", - region: process.env.AWS_REGION || "us-east-2", + region: process.env.AWS_REGION || "us-east-1", } export const baseNodeConfig: configTypes.BaseBaseNodeConfig = { instanceType: new ec2.InstanceType(process.env.BASE_INSTANCE_TYPE ? process.env.BASE_INSTANCE_TYPE : "m7g.2xlarge"), instanceCpuType: process.env.BASE_CPU_TYPE?.toLowerCase() == "x86_64" ? ec2.AmazonLinuxCpuType.X86_64 : ec2.AmazonLinuxCpuType.ARM_64, baseNetworkId: process.env.BASE_NETWORK_ID || "mainnet", - baseNodeConfiguration: process.env.BASE_NODE_CONFIGURATION || "full", + baseClient: process.env.BASE_CLIENT || "geth", + baseNodeConfiguration: getClientConfiguration( process.env.BASE_CLIENT, process.env.BASE_NODE_CONFIGURATION), restoreFromSnapshot: process.env.BASE_RESTORE_FROM_SNAPSHOT?.toLowerCase() == "true" ? true : false, l1ExecutionEndpoint: process.env.BASE_L1_EXECUTION_ENDPOINT || constants.NoneValue, l1ConsensusEndpoint: process.env.BASE_L1_CONSENSUS_ENDPOINT || constants.NoneValue, diff --git a/lib/base/lib/ha-nodes-stack.ts b/lib/base/lib/ha-nodes-stack.ts index 86760725..3edbe53d 100644 --- a/lib/base/lib/ha-nodes-stack.ts +++ b/lib/base/lib/ha-nodes-stack.ts @@ -16,6 +16,7 @@ export interface BaseHANodesStackProps extends cdk.StackProps { instanceType: ec2.InstanceType; instanceCpuType: ec2.AmazonLinuxCpuType; baseNetworkId: configTypes.BaseNetworkId; + baseClient: configTypes.BaseClient, baseNodeConfiguration: configTypes.BaseNodeConfiguration; restoreFromSnapshot: boolean; l1ExecutionEndpoint: string, @@ -40,6 +41,7 @@ export class BaseHANodesStack extends cdk.Stack { instanceType, instanceCpuType, baseNetworkId, + baseClient, baseNodeConfiguration, restoreFromSnapshot, l1ExecutionEndpoint, @@ -80,6 +82,7 @@ export class BaseHANodesStack extends cdk.Stack { _DATA_VOLUME_TYPE_: dataVolume.type, _DATA_VOLUME_SIZE_: dataVolumeSizeBytes.toString(), _NETWORK_ID_: baseNetworkId, + _BASE_CLIENT_: baseClient, _NODE_CONFIG_: baseNodeConfiguration, _LIFECYCLE_HOOK_NAME_: lifecycleHookName, _AUTOSCALING_GROUP_NAME_: autoScalingGroupName, diff --git a/lib/base/lib/single-node-stack.ts b/lib/base/lib/single-node-stack.ts index 0e4f4cd7..c7115451 100644 --- a/lib/base/lib/single-node-stack.ts +++ b/lib/base/lib/single-node-stack.ts @@ -17,6 +17,7 @@ export interface BaseSingleNodeStackProps extends cdk.StackProps { instanceType: ec2.InstanceType; instanceCpuType: ec2.AmazonLinuxCpuType; baseNetworkId: configTypes.BaseNetworkId; + baseClient: configTypes.BaseClient, baseNodeConfiguration: configTypes.BaseNodeConfiguration; restoreFromSnapshot: boolean; l1ExecutionEndpoint: string, @@ -34,13 +35,14 @@ export class BaseSingleNodeStack extends cdk.Stack { const STACK_NAME = cdk.Stack.of(this).stackName; const STACK_ID = cdk.Stack.of(this).stackId; const availabilityZones = cdk.Stack.of(this).availabilityZones; - const chosenAvailabilityZone = availabilityZones.slice(0, 1)[0]; + const chosenAvailabilityZone = availabilityZones.slice(0, 2)[1]; // Getting our config from initialization properties const { instanceType, instanceCpuType, baseNetworkId, + baseClient, baseNodeConfiguration, restoreFromSnapshot, l1ExecutionEndpoint, @@ -107,6 +109,7 @@ export class BaseSingleNodeStack extends cdk.Stack { _DATA_VOLUME_TYPE_: dataVolume.type, _DATA_VOLUME_SIZE_: dataVolumeSizeBytes.toString(), _NETWORK_ID_: baseNetworkId, + _BASE_CLIENT_: baseClient, _NODE_CONFIG_: baseNodeConfiguration, _LIFECYCLE_HOOK_NAME_: constants.NoneValue, _AUTOSCALING_GROUP_NAME_: constants.NoneValue, diff --git a/lib/base/sample-configs/.env-sample-archive-mainet b/lib/base/sample-configs/.env-sample-archive-mainet new file mode 100644 index 00000000..a5795fbf --- /dev/null +++ b/lib/base/sample-configs/.env-sample-archive-mainet @@ -0,0 +1,37 @@ +############################################################# +# Example configuration for Base nodes runner app on AWS # +############################################################# + +## Set the AWS account is and region for your environment ## +AWS_ACCOUNT_ID="xxxxxxxx" +AWS_REGION="us-east-1" + +## Common configuration parameters ## +BASE_CLIENT="reth" # All options: "geth", "reth" +BASE_NETWORK_ID="mainnet" # All options: "mainnet", "sepolia" +BASE_NODE_CONFIGURATION="full" # All options: "full", "archive" +BASE_INSTANCE_TYPE="i8g.4xlarge" # Recommended for Insance Store: i8g.4xlarge, "ARM_64" +BASE_CPU_TYPE="ARM_64" # All options: "x86_64", "ARM_64". IMPORTANT: Make sure the CPU type matches the instance type used + +# Data volume configuration +BASE_DATA_VOL_TYPE="instance-store" # Other options: "io1" | "io2" | "gp3" | "instance-store" . IMPORTANT: Use "instance-store" option only with instance types that support that feature, like popular for node im4gn, d3, i3en, and i4i instance families +#BASE_DATA_VOL_SIZE="1000" # Current required data size in GB to keep both snapshot archive and unarchived version of it. For Sepolia 1000 will be sufficient. +#BASE_DATA_VOL_IOPS="5000" # Max IOPS for EBS volumes (not applicable for "instance-store") +#BASE_DATA_VOL_THROUGHPUT="700" # Max throughput for EBS gp3 volumes (not applicable for "io1" | "io2" | "instance-store") +BASE_L1_EXECUTION_ENDPOINT="https://ethereum-rpc.publicnode.com" # Set your own URL to Ethereum L1 node: https://docs.base.org/tools/node-providers +BASE_L1_CONSENSUS_ENDPOINT="https://ethereum-beacon-api.publicnode.com" + +BASE_RESTORE_FROM_SNAPSHOT="true" # Download snapshot to speed up statup time +BASE_SNAPSHOT_URL="none" # Optionally provide the URL to download snpashot: https://docs.base.org/tutorials/run-a-base-node/#snapshots + +# Example for Sepolia: +#BASE_L1_EXECUTION_ENDPOINT=https://ethereum-sepolia-rpc.publicnode.com +#BASE_L1_CONSENSUS_ENDPOINT=https://ethereum-sepolia-beacon-api.publicnode.com +# Example for Mainnet and with Ethereum Blueprint with Geth-Lighthouse client combination and private IP: +#BASE_L1_EXECUTION_ENDPOINT=http://172.31.15.220:8545 +#BASE_L1_CONSENSUS_ENDPOINT=http://172.31.15.220:5052 + +## HA nodes configuration ## +BASE_HA_NUMBER_OF_NODES="2" # Total number of RPC nodes to be provisioned. Default: 2 +BASE_HA_ALB_HEALTHCHECK_GRACE_PERIOD_MIN="500" # Time enough to initialize the instance +BASE_HA_NODES_HEARTBEAT_DELAY_MIN="120" # Time sufficient enough for a node do sync diff --git a/lib/base/sample-configs/.env-sample-archive-sepolia b/lib/base/sample-configs/.env-sample-archive-sepolia index b55c9d91..c94b9637 100644 --- a/lib/base/sample-configs/.env-sample-archive-sepolia +++ b/lib/base/sample-configs/.env-sample-archive-sepolia @@ -7,6 +7,7 @@ AWS_ACCOUNT_ID="xxxxxxxx" AWS_REGION="us-east-1" ## Common configuration parameters ## +BASE_CLIENT="reth" # All options: "geth", "reth" BASE_NETWORK_ID="sepolia" # All options: "mainnet", "sepolia" BASE_NODE_CONFIGURATION="archive" # All options: "full", "archive" BASE_INSTANCE_TYPE="m7g.2xlarge" # Reconneded for Insance Store: i3en.3xlarge, "x86_64" diff --git a/lib/base/sample-configs/.env-sample-full-ha-sepolia b/lib/base/sample-configs/.env-sample-full-ha-sepolia index 62a43370..7ca3cfcb 100644 --- a/lib/base/sample-configs/.env-sample-full-ha-sepolia +++ b/lib/base/sample-configs/.env-sample-full-ha-sepolia @@ -7,6 +7,7 @@ AWS_ACCOUNT_ID="xxxxxxxx" AWS_REGION="us-east-1" ## Common configuration parameters ## +BASE_CLIENT="geth" # All options: "geth", "reth" BASE_NETWORK_ID="sepolia" # All options: "mainnet", "sepolia" BASE_NODE_CONFIGURATION="full" # All options: "full", "archive" BASE_INSTANCE_TYPE="m7g.2xlarge" # Reconneded for Insance Store: i3en.3xlarge, "x86_64" diff --git a/lib/base/sample-configs/.env-sample-full-mainet b/lib/base/sample-configs/.env-sample-full-mainet new file mode 100644 index 00000000..5a15716d --- /dev/null +++ b/lib/base/sample-configs/.env-sample-full-mainet @@ -0,0 +1,37 @@ +############################################################# +# Example configuration for Base nodes runner app on AWS # +############################################################# + +## Set the AWS account is and region for your environment ## +AWS_ACCOUNT_ID="xxxxxxxx" +AWS_REGION="us-east-1" + +## Common configuration parameters ## +BASE_CLIENT="geth" # All options: "geth", "reth" +BASE_NETWORK_ID="mainnet" # All options: "mainnet", "sepolia" +BASE_NODE_CONFIGURATION="full" # All options: "full", "archive" +BASE_INSTANCE_TYPE="i8g.4xlarge" # Reconneded for Insance Store: i3en.3xlarge, "x86_64" +BASE_CPU_TYPE="ARM_64" # All options: "x86_64", "ARM_64". IMPORTANT: Make sure the CPU type matches the instance type used + +# Data volume configuration +BASE_DATA_VOL_TYPE="instance-store" # Other options: "io1" | "io2" | "gp3" | "instance-store" . IMPORTANT: Use "instance-store" option only with instance types that support that feature, like popular for node im4gn, d3, i3en, and i4i instance families +#BASE_DATA_VOL_SIZE="1000" # Current required data size in GB to keep both snapshot archive and unarchived version of it. For Sepolia 1000 will be sufficient. +#BASE_DATA_VOL_IOPS="5000" # Max IOPS for EBS volumes (not applicable for "instance-store") +#BASE_DATA_VOL_THROUGHPUT="700" # Max throughput for EBS gp3 volumes (not applicable for "io1" | "io2" | "instance-store") +BASE_L1_EXECUTION_ENDPOINT="https://ethereum-rpc.publicnode.com" # Set your own URL to Ethereum L1 node: https://docs.base.org/tools/node-providers +BASE_L1_CONSENSUS_ENDPOINT="https://ethereum-beacon-api.publicnode.com" + +BASE_RESTORE_FROM_SNAPSHOT="true" # Download snapshot to speed up statup time +BASE_SNAPSHOT_URL="none" # Optionally provide the URL to download snpashot: https://docs.base.org/tutorials/run-a-base-node/#snapshots + +# Example for Sepolia: +#BASE_L1_EXECUTION_ENDPOINT=https://ethereum-sepolia-rpc.publicnode.com +#BASE_L1_CONSENSUS_ENDPOINT=https://ethereum-sepolia-beacon-api.publicnode.com +# Example for Mainnet and with Ethereum Blueprint with Geth-Lighthouse client combination and private IP: +#BASE_L1_EXECUTION_ENDPOINT=http://172.31.15.220:8545 +#BASE_L1_CONSENSUS_ENDPOINT=http://172.31.15.220:5052 + +## HA nodes configuration ## +BASE_HA_NUMBER_OF_NODES="2" # Total number of RPC nodes to be provisioned. Default: 2 +BASE_HA_ALB_HEALTHCHECK_GRACE_PERIOD_MIN="500" # Time enough to initialize the instance +BASE_HA_NODES_HEARTBEAT_DELAY_MIN="120" # Time sufficient enough for a node do sync diff --git a/lib/base/sample-configs/.env-sample-full-sepolia b/lib/base/sample-configs/.env-sample-full-sepolia index 62a43370..7e55a10a 100644 --- a/lib/base/sample-configs/.env-sample-full-sepolia +++ b/lib/base/sample-configs/.env-sample-full-sepolia @@ -7,7 +7,7 @@ AWS_ACCOUNT_ID="xxxxxxxx" AWS_REGION="us-east-1" ## Common configuration parameters ## -BASE_NETWORK_ID="sepolia" # All options: "mainnet", "sepolia" +BASE_CLIENT="geth" # All options: "geth", "reth" BASE_NODE_CONFIGURATION="full" # All options: "full", "archive" BASE_INSTANCE_TYPE="m7g.2xlarge" # Reconneded for Insance Store: i3en.3xlarge, "x86_64" BASE_CPU_TYPE="ARM_64" # All options: "x86_64", "ARM_64". IMPORTANT: Make sure the CPU type matches the instance type used diff --git a/lib/base/test/.env-test b/lib/base/test/.env-test index 2796c5d3..830dcb72 100644 --- a/lib/base/test/.env-test +++ b/lib/base/test/.env-test @@ -7,6 +7,7 @@ AWS_ACCOUNT_ID="xxxxxxxxxxxx" AWS_REGION="us-east-1" # Regions supported by Amazon Managed Blockchain Access Ethereum: https://docs.aws.amazon.com/general/latest/gr/managedblockchain.html#managedblockchain-access ## Common configuration parameters ## +BASE_CLIENT="geth" # All options: "geth", "reth" BASE_NETWORK_ID="mainnet" # All options: "mainnet" BASE_NODE_CONFIGURATION="full" # All options: "full", "archive" BASE_INSTANCE_TYPE="m7g.4xlarge" diff --git a/lib/base/test/base-single-node.test.ts b/lib/base/test/base-single-node.test.ts index 809efc53..7dae18ba 100644 --- a/lib/base/test/base-single-node.test.ts +++ b/lib/base/test/base-single-node.test.ts @@ -15,18 +15,9 @@ describe("BaseSingleNodeStack", () => { // Create the BaseSingleNodeStack. baseSingleNodeStack = new BaseSingleNodeStack(app, "base-single-node", { - stackName: `base-single-node-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, + stackName: `base-single-node-${config.baseNodeConfig.baseClient}-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, env: { account: config.baseConfig.accountId, region: config.baseConfig.region }, - - instanceType: config.baseNodeConfig.instanceType, - instanceCpuType: config.baseNodeConfig.instanceCpuType, - baseNetworkId: config.baseNodeConfig.baseNetworkId, - baseNodeConfiguration: config.baseNodeConfig.baseNodeConfiguration, - restoreFromSnapshot: config.baseNodeConfig.restoreFromSnapshot, - l1ExecutionEndpoint: config.baseNodeConfig.l1ExecutionEndpoint, - l1ConsensusEndpoint: config.baseNodeConfig.l1ConsensusEndpoint, - snapshotUrl: config.baseNodeConfig.snapshotUrl, - dataVolume: config.baseNodeConfig.dataVolume, + ...config.baseNodeConfig }); template = Template.fromStack(baseSingleNodeStack); @@ -147,7 +138,7 @@ describe("BaseSingleNodeStack", () => { "Fn::Join": [ "", [ - "base-single-node-full-mainnet-", + "base-single-node-geth-full-mainnet-", { "Ref": Match.anyValue() } diff --git a/lib/base/test/ha-nodes-stack.test.ts b/lib/base/test/ha-nodes-stack.test.ts index 09a2473e..10344794 100644 --- a/lib/base/test/ha-nodes-stack.test.ts +++ b/lib/base/test/ha-nodes-stack.test.ts @@ -12,22 +12,11 @@ describe("BaseHANodesStack", () => { // Create the BaseHANodesStack. const baseHANodesStack = new BaseHANodesStack(app, "base-sync-node", { - stackName: `base-ha-nodes-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, + stackName: `base-ha-nodes-${config.baseNodeConfig.baseClient}-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, env: { account: config.baseConfig.accountId, region: config.baseConfig.region }, - instanceType: config.baseNodeConfig.instanceType, - instanceCpuType: config.baseNodeConfig.instanceCpuType, - baseNetworkId: config.baseNodeConfig.baseNetworkId, - baseNodeConfiguration: config.baseNodeConfig.baseNodeConfiguration, - restoreFromSnapshot: config.baseNodeConfig.restoreFromSnapshot, - l1ExecutionEndpoint: config.baseNodeConfig.l1ExecutionEndpoint, - l1ConsensusEndpoint: config.baseNodeConfig.l1ConsensusEndpoint, - snapshotUrl: config.baseNodeConfig.snapshotUrl, - dataVolume: config.baseNodeConfig.dataVolume, - - albHealthCheckGracePeriodMin: config.haNodeConfig.albHealthCheckGracePeriodMin, - heartBeatDelayMin: config.haNodeConfig.heartBeatDelayMin, - numberOfNodes: config.haNodeConfig.numberOfNodes + ...config.baseNodeConfig, + ...config.haNodeConfig }); // Prepare the stack for assertions. @@ -158,7 +147,7 @@ describe("BaseHANodesStack", () => { // Has Auto Scaling Group. template.hasResourceProperties("AWS::AutoScaling::AutoScalingGroup", { - AutoScalingGroupName: `base-ha-nodes-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, + AutoScalingGroupName: `base-ha-nodes-${config.baseNodeConfig.baseClient}-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, HealthCheckGracePeriod: config.haNodeConfig.albHealthCheckGracePeriodMin * 60, HealthCheckType: "ELB", DefaultInstanceWarmup: 60, @@ -173,7 +162,7 @@ describe("BaseHANodesStack", () => { template.hasResourceProperties("AWS::AutoScaling::LifecycleHook", { DefaultResult: "ABANDON", HeartbeatTimeout: config.haNodeConfig.heartBeatDelayMin * 60, - LifecycleHookName: `base-ha-nodes-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, + LifecycleHookName: `base-ha-nodes-${config.baseNodeConfig.baseClient}-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}`, LifecycleTransition: "autoscaling:EC2_INSTANCE_LAUNCHING", }); @@ -216,7 +205,7 @@ describe("BaseHANodesStack", () => { }, { Key: "access_logs.s3.prefix", - Value: `base-ha-nodes-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}` + Value: `base-ha-nodes-${config.baseNodeConfig.baseClient}-${config.baseNodeConfig.baseNodeConfiguration}-${config.baseNodeConfig.baseNetworkId}` } ], Scheme: "internal",