Skip to content

Commit 6683c9f

Browse files
authored
Merge pull request #75 from wojciechos/main
Add blueprint for starknet single node deployment
2 parents 2a56953 + c344474 commit 6683c9f

24 files changed

+2507
-0
lines changed

lib/starknet/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
*.js
2+
!jest.config.js
3+
*.d.ts
4+
node_modules
5+
6+
# CDK asset staging directory
7+
.cdk.staging
8+
cdk.out
9+
.idea
10+
11+
*-node.json

lib/starknet/.npmignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.ts
2+
!*.d.ts
3+
4+
# CDK asset staging directory
5+
.cdk.staging
6+
cdk.out

lib/starknet/README.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Sample AWS Blockchain Node Runner app for Starknet Nodes
2+
3+
| Contributed by |
4+
|:--------------------:|
5+
| [@wojciechos](https://github.com/wojciechos) |
6+
7+
[Starknet](https://docs.starknet.io/documentation/) is a "Layer 2" scaling solution for Ethereum leveraging zero knowledge proofs. This blueprint helps to deploy Starknet nodes (Juno) on AWS as RPC nodes. It is meant to be used for development, testing or Proof of Concept purposes.
8+
9+
## Overview of Deployment Architectures for Single Node setups
10+
11+
### Single node setup
12+
13+
![Single Node Deployment](./doc/assets/Architecture-SingleNode.png)
14+
15+
1. A Starknet node deployed in the [Default VPC](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html) continuously synchronizes with the [Sequencer](https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/starknet_architecture_overview/) through [Internet Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html).
16+
2. The Starknet node is used by dApps or development tools internally from within the Default VPC. JSON RPC API is not exposed to the Internet directly to protect nodes from unauthorized access.
17+
3. You will need access to a fully-synced Ethereum RPC endpoint before running Juno.
18+
4. The Starknet node sends various monitoring metrics for both EC2 and Starknet nodes to Amazon CloudWatch.
19+
20+
21+
## Hardware Requirements
22+
23+
**Minimum for Starknet node**
24+
25+
- Instance type [m6a.large](https://aws.amazon.com/ec2/instance-types/m6a/).
26+
- 250GB EBS gp3 storage with at least 3000 IOPS.
27+
28+
**Recommended for Starknet node**
29+
30+
- Instance type [m6a.2xlarge](https://aws.amazon.com/ec2/instance-types/m6a/).
31+
- 250GB EBS gp3 storage with at least 3000 IOPS.`
32+
33+
</details>
34+
35+
## Setup Instructions
36+
37+
### Setup Cloud9
38+
39+
We will use AWS Cloud9 to execute the subsequent commands. Follow the instructions in [Cloud9 Setup](../../docs/setup-cloud9.md)
40+
41+
### Clone this repository and install dependencies
42+
43+
```bash
44+
git clone https://github.com/aws-samples/aws-blockchain-node-runners.git
45+
cd aws-blockchain-node-runners
46+
npm install
47+
```
48+
49+
### Deploy Single Node
50+
51+
1. Make sure you are in the root directory of the cloned repository
52+
53+
2. If you have deleted or don't have the default VPC, create default VPC
54+
55+
```bash
56+
aws ec2 create-default-vpc
57+
```
58+
59+
> NOTE:
60+
> You may see the following error if the default VPC already exists: `An error occurred (DefaultVpcAlreadyExists) when calling the CreateDefaultVpc operation: A Default VPC already exists for this account in this region.`. That means you can just continue with the following steps.
61+
62+
3. Configure your setup
63+
64+
Create your own copy of `.env` file and edit it to update with your AWS Account ID and Region:
65+
```bash
66+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
67+
cd lib/starknet
68+
npm install
69+
pwd
70+
cp ./sample-configs/.env-sample-full .env
71+
nano .env
72+
```
73+
> NOTE:
74+
> Example configuration parameters are set in the local `.env-sample` file. You can find more examples inside `sample-configs` directory.
75+
76+
4. Deploy common components such as IAM role
77+
78+
```bash
79+
pwd
80+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
81+
npx cdk deploy starknet-common
82+
```
83+
84+
> IMPORTANT:
85+
> All AWS CDK v2 deployments use dedicated AWS resources to hold data during deployment. Therefore, your AWS account and Region must be [bootstrapped](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html) to create these resources before you can deploy. If you haven't already bootstrapped, issue the following command:
86+
> ```bash
87+
> cdk bootstrap aws://ACCOUNT-NUMBER/REGION
88+
> ```
89+
90+
91+
5. Deploy Starknet Full Node
92+
93+
```bash
94+
pwd
95+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
96+
npx cdk deploy starknet-single-node --json --outputs-file single-node-deploy.json
97+
```
98+
After starting the node you will need to wait for the initial synchronization process to finish. To see the progress, you may use SSM to connect into EC2 first and watch the log like this:
99+
100+
```bash
101+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
102+
echo "INSTANCE_ID="$INSTANCE_ID
103+
export AWS_REGION=us-east-1
104+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
105+
tail -f /var/log/starknet/error.log
106+
```
107+
108+
7. Test Starknet RPC API
109+
Use curl to query from within the node instance:
110+
```bash
111+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.node-instance-id? | select(. != null)')
112+
echo "INSTANCE_ID=" $INSTANCE_ID
113+
export AWS_REGION=us-east-1
114+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
115+
116+
curl --location 'http://localhost:6060' \
117+
--header 'Content-Type: application/json' \
118+
--data '{
119+
"jsonrpc":"2.0",
120+
"method":"starknet_chainId",
121+
"params":[],
122+
"id":1
123+
}'
124+
```
125+
126+
### Monitoring
127+
A script on the Starknet node publishes current block and blocks behind metrics to CloudWatch metrics every 5 minutes. When the node is fully synced the blocks behind metric should get to 0.To see the metrics:
128+
129+
- Navigate to CloudWatch service (make sure you are in the region you have specified for AWS_REGION)
130+
- Open Dashboards and select `starknet-single-node` from the list of dashboards.
131+
132+
## Clear up and undeploy everything
133+
134+
1. Undeploy all Nodes and Common stacks
135+
136+
```bash
137+
# Setting the AWS account id and region in case local .env file is lost
138+
export AWS_ACCOUNT_ID=<your_target_AWS_account_id>
139+
export AWS_REGION=<your_target_AWS_region>
140+
141+
pwd
142+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
143+
144+
# Undeploy Single Node
145+
npx cdk destroy starknet-single-node
146+
147+
148+
# Delete all common components like IAM role and Security Group
149+
npx cdk destroy starknet-common
150+
```
151+
152+
2. Follow steps to delete the Cloud9 instance in [Cloud9 Setup](../../doc/setup-cloud9.md)
153+
154+
## FAQ
155+
156+
1. How to check the logs of the clients running on my Starknet node?
157+
158+
**Note:** In this tutorial we chose not to use SSH and use Session Manager instead. That allows you to log all sessions in AWS CloudTrail to see who logged into the server and when. If you receive an error similar to `SessionManagerPlugin is not found`, [install Session Manager plugin for AWS CLI](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)
159+
160+
```bash
161+
pwd
162+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
163+
164+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
165+
echo "INSTANCE_ID=" $INSTANCE_ID
166+
export AWS_REGION=us-east-1
167+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
168+
sudo journalctl -o cat -fu starknet
169+
```
170+
2. How to check the logs from the EC2 user-data script?
171+
172+
```bash
173+
pwd
174+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
175+
176+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
177+
echo "INSTANCE_ID=" $INSTANCE_ID
178+
export AWS_REGION=us-east-1
179+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
180+
sudo cat /var/log/cloud-init-output.log
181+
```
182+
183+
3. How can I restart the Starknet service?
184+
185+
``` bash
186+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
187+
echo "INSTANCE_ID=" $INSTANCE_ID
188+
export AWS_REGION=us-east-1
189+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
190+
sudo systemctl status starknet.service
191+
sudo systemctl restart starknet.service
192+
```
193+
4. Where to find the key juno directories?
194+
195+
- The directory with binaries is `/home/ubuntu/juno-source`.
196+
- The data directory of juno agent is `/home/ubuntu/juno-source/juno-datadir`

lib/starknet/app.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env node
2+
import 'dotenv/config'
3+
import 'source-map-support/register';
4+
import * as cdk from 'aws-cdk-lib';
5+
import * as config from "./lib/config/starknetConfig";
6+
import {StarknetCommonStack} from "./lib/common-stack";
7+
import {StarknetSingleNodeStack} from "./lib/single-node-stack";
8+
9+
const app = new cdk.App();
10+
cdk.Tags.of(app).add("Project", "AWSStarknet");
11+
12+
new StarknetCommonStack(app, "starknet-common", {
13+
stackName: `starknet-nodes-common`,
14+
env: { account: config.baseConfig.accountId, region: config.baseConfig.region },
15+
});
16+
17+
new StarknetSingleNodeStack(app, "starknet-single-node", {
18+
stackName: `starknet-single-node`,
19+
env: { account: config.baseConfig.accountId, region: config.baseConfig.region },
20+
21+
instanceType: config.baseNodeConfig.instanceType,
22+
instanceCpuType: config.baseNodeConfig.instanceCpuType,
23+
dataVolume: config.baseNodeConfig.dataVolume,
24+
starknetNetworkId: config.baseNodeConfig.starknetNetworkId,
25+
starknetL1Endpoint: config.baseNodeConfig.starknetL1Endpoint,
26+
starknetNodeVersion: config.baseNodeConfig.starknetNodeVersion,
27+
});

lib/starknet/cdk.json

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"app": "npx ts-node --prefer-ts-exts app.ts",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"**/*.d.ts",
11+
"**/*.js",
12+
"tsconfig.json",
13+
"package*.json",
14+
"yarn.lock",
15+
"node_modules",
16+
"test"
17+
]
18+
},
19+
"context": {
20+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21+
"@aws-cdk/core:checkSecretUsage": true,
22+
"@aws-cdk/core:target-partitions": [
23+
"aws",
24+
"aws-cn"
25+
],
26+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
27+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
28+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
29+
"@aws-cdk/aws-iam:minimizePolicies": true,
30+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
31+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
32+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
33+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
34+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
35+
"@aws-cdk/core:enablePartitionLiterals": true,
36+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
37+
"@aws-cdk/aws-iam:standardizedServicePrincipals": true,
38+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
39+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
40+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
41+
"@aws-cdk/aws-route53-patters:useCertificate": true,
42+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
43+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
44+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
45+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
46+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
47+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
48+
"@aws-cdk/aws-redshift:columnId": true,
49+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
50+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
51+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
52+
"@aws-cdk/aws-kms:aliasNameRef": true,
53+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
54+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
55+
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true
56+
}
57+
}

0 commit comments

Comments
 (0)