Skip to content

Commit 9339dd0

Browse files
authored
Merge pull request #78 from aws-samples/starknet
Starknet
2 parents 2a56953 + 3192a92 commit 9339dd0

30 files changed

+1707
-3
lines changed

docs/pre-merge-tools.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ npm run install-pre-commit-mac
4242
npm run run-pre-commit
4343
```
4444

45-
4. Optionally, run [shellcheck](https://github.com/koalaman/shellcheck) to check for common problems in your shell scripts.
45+
4. Optionally, run [shellcheck](https://github.com/koalaman/shellcheck) to check for common problems in your shell scripts.

lib/constructs/amb-ethereum-single-node.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ export interface SingleNodeAMBEthereumConstructCustomProps {
1313
export class SingleNodeAMBEthereumConstruct extends cdkContructs.Construct {
1414
public nodeId: string;
1515
public rpcUrl: string;
16+
public wssRpcUrl: string;
1617
public billingToken: string;
1718
public rpcUrlWithBillingToken: string;
19+
public wssRpcUrlWithBillingToken: string;
1820

1921

2022
constructor(scope: cdkContructs.Construct, id: string, props: SingleNodeAMBEthereumConstructCustomProps) {
@@ -63,8 +65,10 @@ export class SingleNodeAMBEthereumConstruct extends cdkContructs.Construct {
6365

6466
this.nodeId = createNode.getResponseField('NodeId');
6567
this.rpcUrl = `https://${this.nodeId}.t.ethereum.managedblockchain.${REGION}.amazonaws.com`;
68+
this.wssRpcUrl = `wss://${this.nodeId}.wss.t.ethereum.managedblockchain.${REGION}.amazonaws.com`;
6669
this.billingToken=createAccessor.getResponseField('BillingToken');
67-
this.rpcUrlWithBillingToken = `${this.rpcUrl}?billingtoken=${this.billingToken}`;
70+
this.rpcUrlWithBillingToken = `${this.rpcUrl}/?billingtoken=${this.billingToken}`;
71+
this.wssRpcUrlWithBillingToken = `${this.wssRpcUrl}/?billingtoken=${this.billingToken}`;
6872

6973
const deleteAccessor = new cr.AwsCustomResource(this, 'deleteAccessor', {
7074
onDelete: {

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: 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/README.md

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
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+
## Additional Materials
21+
22+
<details>
23+
24+
<summary>Well-Architected Checklist</summary>
25+
26+
This is the Well-Architected checklist for Stacks nodes implementation of the AWS Blockchain Node Runner app. This checklist takes into account questions from the [AWS Well-Architected Framework](https://aws.amazon.com/architecture/well-architected/) which are relevant to this workload. Please feel free to add more checks from the framework if required for your workload.
27+
28+
| Pillar | Control | Question/Check | Remarks |
29+
|:------------------------|:----------------------------------|:---------------------------------------------------------------------------------|:-----------------|
30+
| Security | Network protection | Are there unnecessary open ports in security groups? | There are no ports open to public. RPC port 6060 is open only IP addresses from the same VPC. |
31+
| | | Traffic inspection | AWS WAF could be implemented for traffic inspection. Additional charges will apply. |
32+
| | Compute protection | Reduce attack surface | This solution uses Ubuntu Server 20.04 AMI. You may choose to run hardening scripts on it. |
33+
| | | Enable people to perform actions at a distance | This solution uses AWS Systems Manager for terminal session, not ssh ports. |
34+
| | Data protection at rest | Use encrypted Amazon Elastic Block Store (Amazon EBS) volumes | This solution uses encrypted Amazon EBS volumes. |
35+
| | | Use encrypted Amazon Simple Storage Service (Amazon S3) buckets | This solution uses Amazon S3 managed keys (SSE-S3) encryption. |
36+
| | Data protection in transit | Use TLS | TLS is not used in this solution. Port 6060 is the only open port, but you may create HTTPS listener with self signed certificate if TLS is desired. |
37+
| | Authorization and access control | Use instance profile with Amazon Elastic Compute Cloud (Amazon EC2) instances | This solution uses AWS Identity and Access Management (AWS IAM) role instead of IAM user. |
38+
| | | Following principle of least privilege access | In all node types, root user is not used (using special user "ubuntu" instead). |
39+
| | Application security | Security focused development practices | cdk-nag is being used with appropriate suppressions. |
40+
| Cost optimization | Service selection | Use cost effective resources | 1. AMD-based instances are used for Consensus and RPC node to save the costs. Consider compiling Graviton-based binaries to improve costs for compute.<br/>2. Cost-effective EBS gp3 are preferred instead of io2. |
41+
| | Cost awareness | Estimate costs | Single RPC node with `m6a.2xlarge` EBS gp3 volume about 600 GB with On-Demand pricing will cost around US$323.29 per month in the US East (N. Virginia) region not including network requests for follower nodes. More analysis needed. |
42+
| Reliability | Resiliency implementation | Withstand component failures | This solution ues only for a single-node deployment. If the running node failed, you will need to undeploy the existing stack and re-deploy the node again. |
43+
| | Data backup | How is data backed up? | Considering blockchain data is replicated by nodes automatically and Starknet nodes sync from start within an hour and a half, we don't use any additional mechanisms to backup the data. |
44+
| | Resource monitoring | How are workload resources monitored? | Resources are being monitored using Amazon CloudWatch dashboards. Amazon CloudWatch custom metrics are being pushed via CloudWatch Agent. |
45+
| Performance efficiency | Compute selection | How is compute solution selected? | Compute solution is selected based on best price-performance, i.e. AWS AMD-based Amazon EC2 instances. |
46+
| | Storage selection | How is storage solution selected? | Storage solution is selected based on best price-performance, i.e. gp3 Amazon EBS volumes with optimal IOPS and throughput. |
47+
| | Architecture selection | How is the best performance architecture selected? | We used a combination of recommendations from the Starknet community. |
48+
| Operational excellence | Workload health | How is health of workload determined? | We rely on metrics reported to CloudWatch by `/opt/syncchecker.sh` script. |
49+
| Sustainability | Hardware & services | Select most efficient hardware for your workload | The solution uses AMD-powered instances. There is a potential to use AWS Graviton-based Amazon EC2 instances which offer the best performance per watt of energy use in Amazon EC2. |
50+
</details>
51+
52+
### Hardware Requirements
53+
54+
**Minimum for Starknet node**
55+
56+
- Instance type [m6a.large](https://aws.amazon.com/ec2/instance-types/m6a/).
57+
- 250GB EBS gp3 storage with at least 3000 IOPS.
58+
59+
**Recommended for Starknet node**
60+
61+
- Instance type [m6a.2xlarge](https://aws.amazon.com/ec2/instance-types/m6a/).
62+
- 600GB EBS gp3 storage with at least 3000 IOPS to store and upzip snapshots.
63+
64+
## Setup Instructions
65+
66+
### Setup Cloud9
67+
68+
We will use AWS Cloud9 to execute the subsequent commands. Follow the instructions in [Cloud9 Setup](../../docs/setup-cloud9.md)
69+
70+
### Clone this repository and install dependencies
71+
72+
```bash
73+
git clone https://github.com/aws-samples/aws-blockchain-node-runners.git
74+
cd aws-blockchain-node-runners
75+
npm install
76+
```
77+
78+
### Deploy Single Node
79+
80+
1. Make sure you are in the root directory of the cloned repository
81+
82+
2. If you have deleted or don't have the default VPC, create default VPC
83+
84+
```bash
85+
aws ec2 create-default-vpc
86+
```
87+
88+
> NOTE:
89+
> 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.
90+
91+
3. Configure your setup
92+
93+
Create your own copy of `.env` file and edit it to update with your AWS Account ID and Region:
94+
```bash
95+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
96+
cd lib/starknet
97+
npm install
98+
pwd
99+
cp ./sample-configs/.env-sample-full .env
100+
nano .env
101+
```
102+
> NOTE:
103+
> Example configuration parameters are set in the local `.env-sample` file. You can find more examples inside `sample-configs` directory.
104+
105+
4. Deploy common components such as IAM role
106+
107+
```bash
108+
pwd
109+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
110+
npx cdk deploy starknet-common
111+
```
112+
113+
> IMPORTANT:
114+
> 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:
115+
> ```bash
116+
> cdk bootstrap aws://ACCOUNT-NUMBER/REGION
117+
> ```
118+
119+
5. [OPTIONAL] You can use Amazon Managed Blockchain (AMB) Access Ethereum node as L1 node. To do that, leave `STARKNET_L1_ENDPOINT` URL empty and, deploy Amazon Managed Blockchain (AMB) Access Ethereum node. Wait about 35-70 minutes for the node to sync.
120+
121+
```bash
122+
pwd
123+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
124+
npx cdk deploy starknet-ethereum-l1-node --json --outputs-file starknet-ethereum-l1-node.json
125+
```
126+
To watch the progress, open the [AMB Web UI](https://console.aws.amazon.com/managedblockchain/home), click the name of your target network from the list (Mainnet, Goerly, etc.) and watch the status of the node to change from `Creating` to `Available`.
127+
128+
6. Deploy Starknet Full Node
129+
130+
```bash
131+
pwd
132+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
133+
npx cdk deploy starknet-single-node --json --outputs-file single-node-deploy.json
134+
```
135+
After starting the node you will need to wait for the initial synchronization process to finish. When using snapshot, the node should become available within a couple of hours, but migh take about 3-4 days to sync it from block 0. To check the progress, you may use SSM to connect into EC2 first and watch the log like this:
136+
137+
```bash
138+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
139+
echo "INSTANCE_ID="$INSTANCE_ID
140+
export AWS_REGION=us-east-1
141+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
142+
tail -f /var/log/starknet/error.log
143+
```
144+
145+
146+
7. Test Starknet RPC API
147+
Use curl to query from within the node instance:
148+
```bash
149+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.node-instance-id? | select(. != null)')
150+
echo "INSTANCE_ID=" $INSTANCE_ID
151+
export AWS_REGION=us-east-1
152+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
153+
154+
curl --location 'http://localhost:6060' \
155+
--header 'Content-Type: application/json' \
156+
--data '{
157+
"jsonrpc":"2.0",
158+
"method":"starknet_chainId",
159+
"params":[],
160+
"id":1
161+
}'
162+
```
163+
164+
### Monitoring
165+
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:
166+
167+
- Navigate to CloudWatch service (make sure you are in the region you have specified for AWS_REGION)
168+
- Open Dashboards and select `starknet-single-node-<network_id>` from the list of dashboards.
169+
170+
## Clear up and undeploy everything
171+
172+
1. Undeploy all Nodes and Common stacks
173+
174+
```bash
175+
# Setting the AWS account id and region in case local .env file is lost
176+
export AWS_ACCOUNT_ID=<your_target_AWS_account_id>
177+
export AWS_REGION=<your_target_AWS_region>
178+
179+
pwd
180+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
181+
182+
# Undeploy Single Node
183+
npx cdk destroy starknet-single-node
184+
185+
# Undeploy AMB Etheruem node
186+
npx cdk destroy starknet-ethereum-l1-node
187+
188+
# Delete all common components like IAM role and Security Group
189+
npx cdk destroy starknet-common
190+
```
191+
192+
2. Follow steps to delete the Cloud9 instance in [Cloud9 Setup](../../doc/setup-cloud9.md)
193+
194+
## FAQ
195+
196+
1. How to check the logs of the clients running on my Starknet node?
197+
198+
**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)
199+
200+
```bash
201+
pwd
202+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
203+
204+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
205+
echo "INSTANCE_ID="$INSTANCE_ID
206+
export AWS_REGION=us-east-1
207+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
208+
tail -f /var/log/starknet/error.log
209+
```
210+
2. How to check the logs from the EC2 user-data script?
211+
212+
```bash
213+
pwd
214+
# Make sure you are in aws-blockchain-node-runners/lib/starknet
215+
216+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
217+
echo "INSTANCE_ID=" $INSTANCE_ID
218+
export AWS_REGION=us-east-1
219+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
220+
sudo cat /var/log/cloud-init-output.log
221+
```
222+
223+
3. How can I restart the Starknet service?
224+
225+
``` bash
226+
export INSTANCE_ID=$(cat single-node-deploy.json | jq -r '..|.nodeinstanceid? | select(. != null)')
227+
echo "INSTANCE_ID=" $INSTANCE_ID
228+
export AWS_REGION=us-east-1
229+
aws ssm start-session --target $INSTANCE_ID --region $AWS_REGION
230+
sudo systemctl status starknet.service
231+
sudo systemctl restart starknet.service
232+
```
233+
4. Where to find the key juno directories?
234+
235+
- The directory with binaries is `/home/ubuntu/juno-source`.
236+
- The data directory of juno agent is `/data`

lib/starknet/app.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 nag from "cdk-nag";
6+
import * as config from "./lib/config/starknetConfig";
7+
import {StarknetCommonStack} from "./lib/common-stack";
8+
import {StarknetAMBEthereumSingleNodeStack} from "./lib/amb-ethereum-single-node-stack";
9+
import {StarknetSingleNodeStack} from "./lib/single-node-stack";
10+
11+
const app = new cdk.App();
12+
cdk.Tags.of(app).add("Project", "AWSStarknet");
13+
14+
new StarknetCommonStack(app, "starknet-common", {
15+
stackName: `starknet-nodes-common`,
16+
env: { account: config.baseConfig.accountId, region: config.baseConfig.region },
17+
});
18+
19+
new StarknetAMBEthereumSingleNodeStack(app, "starknet-ethereum-l1-node", {
20+
stackName: `starknet-amb-ethereum-single-node-${config.baseNodeConfig.ambEntereumNodeNetworkId}`,
21+
env: { account: config.baseConfig.accountId, region: config.baseConfig.region },
22+
23+
ambEthereumNodeNetworkId: config.baseNodeConfig.ambEntereumNodeNetworkId,
24+
ambEthereumNodeInstanceType: config.baseNodeConfig.ambEntereumNodeInstanceType,
25+
});
26+
27+
new StarknetSingleNodeStack(app, "starknet-single-node", {
28+
stackName: `starknet-single-node-${config.baseNodeConfig.starknetNetworkId}`,
29+
env: { account: config.baseConfig.accountId, region: config.baseConfig.region },
30+
31+
instanceType: config.baseNodeConfig.instanceType,
32+
instanceCpuType: config.baseNodeConfig.instanceCpuType,
33+
dataVolume: config.baseNodeConfig.dataVolume,
34+
starknetNetworkId: config.baseNodeConfig.starknetNetworkId,
35+
starknetL1Endpoint: config.baseNodeConfig.starknetL1Endpoint,
36+
starknetNodeVersion: config.baseNodeConfig.starknetNodeVersion,
37+
snapshotUrl: config.baseNodeConfig.snapshotUrl
38+
});
39+
40+
// Security Check
41+
cdk.Aspects.of(app).add(
42+
new nag.AwsSolutionsChecks({
43+
verbose: false,
44+
reports: true,
45+
logIgnores: false,
46+
})
47+
);

0 commit comments

Comments
 (0)