Skip to content

Bitcoin Core Implementation #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 119 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
4ce981c
Bitcoin Core initial commit
Mar 28, 2025
4686b08
Update README.md
racket2000 Mar 28, 2025
12a990d
Update README.md
racket2000 Mar 28, 2025
99e33ce
Fix formatting
racket2000 Mar 28, 2025
c4b1782
Fix path
racket2000 Mar 28, 2025
bb00a03
Fix command
racket2000 Mar 28, 2025
7cf4620
Update README.md
racket2000 Mar 28, 2025
038e799
Update bitcoin.conf
racket2000 Mar 28, 2025
ec039e6
Update README.md
racket2000 Mar 31, 2025
210d050
Add clean up instructions
racket2000 Apr 1, 2025
e17e766
Add info about ALB cookie
racket2000 Apr 1, 2025
66ffdca
incorporate to website
Apr 1, 2025
fff4884
fix pre-commit errors
Apr 1, 2025
d82ade9
fix test and remove printed password from generateRPCAuth
Apr 1, 2025
f983100
fix pre-commit again
Apr 1, 2025
689a0cb
refresh package.json
Apr 1, 2025
f90c731
trying to fix website build error
Apr 1, 2025
97b375f
fix package-lock
Apr 1, 2025
8fe84a1
fix website build error
Apr 1, 2025
fc9b08a
fix website build error pt3
Apr 1, 2025
892b87d
Update README.md
racket2000 Apr 1, 2025
7322b92
fix website dependecy issues
Apr 1, 2025
a0d6b94
fix build dependecy issue
Apr 1, 2025
7a534ab
fix website build
Apr 1, 2025
a1b814c
fix website build pt2
Apr 1, 2025
689e531
fix website build pt3
Apr 1, 2025
57e092c
implement .env and remove local packages
Apr 3, 2025
8bc79d9
fix pre-commit
Apr 3, 2025
0795d9d
modify local package.json
Apr 3, 2025
79d8e70
fix file path
Apr 3, 2025
a707c89
update readme
Apr 3, 2025
2734a5a
fix precommit
Apr 3, 2025
a9c2482
update readme formatting
Apr 3, 2025
2e5662d
clarify credential rotation
Apr 3, 2025
0295682
Base. Upgrade and refactored to address common operational problems
vlasonfa Apr 8, 2025
eab895b
Merge pull request #189 from aws-samples/base
frbrkoala Apr 8, 2025
1444e67
increase EBS vol size
racket2000 Apr 8, 2025
ee9c460
Updated the default EBS vol size
racket2000 Apr 8, 2025
fc79b2d
Update README.md
anirudhmarc Apr 9, 2025
ca6e5c1
feedback incorp'd
Apr 10, 2025
7c62ebc
fix pre-commmit and add placeholder account ID
Apr 10, 2025
7f55a3e
update HA arch
Apr 10, 2025
ae0e262
fix path in readme
racket2000 Apr 10, 2025
d2cbe9f
update account id
racket2000 Apr 10, 2025
2b6f9b5
Remove .env file from repo
Apr 10, 2025
f83fdef
fix tests
Apr 10, 2025
1593a83
update readme regarding secrets manager
Apr 10, 2025
6a308a5
fix typo in env var
Apr 10, 2025
ba32139
clarify directory in command
Apr 10, 2025
7a5b647
add GP3_THROUGHPUT .env
Apr 10, 2025
f6ddf77
fix pre-commit
Apr 10, 2025
50dc0ac
update package.json
Apr 10, 2025
47d6254
fix precommit
Apr 10, 2025
480d7a6
add note regarding auth creds
Apr 10, 2025
47f188e
fix pre-commit
Apr 10, 2025
f749e51
add SSM note to payments
Apr 10, 2025
c62de10
fix typo
Apr 10, 2025
d23b858
Merge pull request #190 from anirudhmarc/patch-1
frbrkoala Apr 16, 2025
4eabb3d
BSC. Changes to snapshot download script
vlasonfa Apr 30, 2025
44cbb2e
Merge pull request #194 from aws-samples/bsc
frbrkoala Apr 30, 2025
772d8fb
Base. Fixed setup scripts to reflect recent updates in Base node setu…
vlasonfa May 2, 2025
d0bb870
Merge branch 'main' into base
frbrkoala May 2, 2025
f4f53aa
Merge pull request #195 from aws-samples/base
frbrkoala May 2, 2025
fd38dc4
Fantom. Deprecating the blueprint
vlasonfa May 5, 2025
6e85899
Website. Updated dependencies
vlasonfa May 5, 2025
918e683
Merge pull request #196 from aws-samples/website
frbrkoala May 5, 2025
d84f43b
Bitcoin Core initial commit
Mar 28, 2025
0d379bd
Update README.md
racket2000 Mar 28, 2025
831b93e
Update README.md
racket2000 Mar 28, 2025
721c662
Fix formatting
racket2000 Mar 28, 2025
0dbd577
Fix path
racket2000 Mar 28, 2025
2b20153
Fix command
racket2000 Mar 28, 2025
310788f
Update README.md
racket2000 Mar 28, 2025
97aa6b9
Update bitcoin.conf
racket2000 Mar 28, 2025
488dadc
Update README.md
racket2000 Mar 31, 2025
3952e83
Add clean up instructions
racket2000 Apr 1, 2025
0b630ad
Add info about ALB cookie
racket2000 Apr 1, 2025
b7db8a5
incorporate to website
Apr 1, 2025
217abed
fix pre-commit errors
Apr 1, 2025
9aa9338
fix test and remove printed password from generateRPCAuth
Apr 1, 2025
dbf962c
fix pre-commit again
Apr 1, 2025
d93b4d0
refresh package.json
Apr 1, 2025
e85b961
trying to fix website build error
Apr 1, 2025
5eb2383
fix package-lock
Apr 1, 2025
db32831
fix website build error
Apr 1, 2025
8e913bb
fix website build error pt3
Apr 1, 2025
5df7f6f
Update README.md
racket2000 Apr 1, 2025
d0e1953
fix website dependecy issues
Apr 1, 2025
996b489
fix build dependecy issue
Apr 1, 2025
ecc451d
fix website build
Apr 1, 2025
54e24b5
fix website build pt2
Apr 1, 2025
6f4513c
fix website build pt3
Apr 1, 2025
18cc33a
implement .env and remove local packages
Apr 3, 2025
377983d
fix pre-commit
Apr 3, 2025
ba71cdf
modify local package.json
Apr 3, 2025
b4c7bcd
fix file path
Apr 3, 2025
3c5375b
update readme
Apr 3, 2025
ae4acd9
fix precommit
Apr 3, 2025
936d19b
update readme formatting
Apr 3, 2025
a5f6f25
clarify credential rotation
Apr 3, 2025
96a736f
feedback incorp'd
Apr 10, 2025
41eb7e7
fix pre-commmit and add placeholder account ID
Apr 10, 2025
d7dbfcb
update HA arch
Apr 10, 2025
0bba922
fix path in readme
racket2000 Apr 10, 2025
b14fc5e
update account id
racket2000 Apr 10, 2025
a9912f7
Remove .env file from repo
Apr 10, 2025
3f3e660
fix tests
Apr 10, 2025
c066dfd
update readme regarding secrets manager
Apr 10, 2025
0a807db
fix typo in env var
Apr 10, 2025
197e302
clarify directory in command
Apr 10, 2025
75cccc8
add GP3_THROUGHPUT .env
Apr 10, 2025
6ed20a1
fix pre-commit
Apr 10, 2025
4b0ce37
update package.json
Apr 10, 2025
92a0d40
fix precommit
Apr 10, 2025
f70b0e5
add note regarding auth creds
Apr 10, 2025
5f2194b
fix pre-commit
Apr 10, 2025
74930b5
add SSM note to payments
Apr 10, 2025
1366ef8
fix typo
Apr 10, 2025
dcd7f69
Merge branch 'bitcoin-core' of https://github.com/aws-samples/aws-blo…
vlasonfa May 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
347 changes: 347 additions & 0 deletions lib/bitcoin-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
## Sample AWS Blockchain Node Runner app for Bitcoin Nodes

| Contributed by |
|:--------------------------------:|
| [Simon Goldberg](https://github.com/racket2000)|

### Overview

This guide walks you through deploying a Bitcoin Core mainnet node in a **Virtual Private Cloud (VPC)** using **Docker**, leveraging **AWS Secrets Manager** for secure credential handling. This configuration ensures robust security and performance while optimizing data transfer costs.

---

### Getting Started

#### Cloning the Repository

First, clone the repository from GitHub to get the necessary files and configurations:

```
git clone https://github.com/aws-samples/aws-blockchain-node-runners.git
cd aws-blockchain-node-runners/lib/bitcoin-core
```

#### Installing Dependencies

Make sure you have AWS CLI installed and configured. Run the following to install any additional dependencies:

```
npm install
```

### Configuration Management - Generating RPC Authentication

To interact with the Bitcoin Core RPC endpoint within your isolated VPC environment, run the following command before deploying the Bitcoin Node via CDK:

```
node generateRPCAuth.js
```

For a deeper dive and an overview of credential rotation, see [RPC Authentication -- Deep Dive](#rpc-authentication----deep-dive).


### Deploying the Node

To deploy a single node setup, use the following command:

```
npx cdk deploy SingleNodeBitcoinCoreStack
```

For High Availability (HA) node deployment, use:

```
npx cdk deploy HABitcoinCoreNodeStack
```

### Deployment Architectures for Bitcoin Nodes

#### Single Node Setup

- A **Bitcoin node** deployed in a **public subnet** continuously synchronizes with the Bitcoin network using outbound connections through a **NAT Gateway**.
- Outbound communication flows through an **Internet Gateway (IGW)**, but the node itself does not have a **public IP address** or **Elastic IP (EIP)**.
- The **NAT Gateway** translates the node's private IP into a public IP for outbound connections, but inbound connections are blocked. This ensures that the node functions as an **outbound-only node** (i.e., it does not accept inbound peer connections), increasing security and reducing data transfer costs.

#### High Availability (HA) Setup

- Deploying **multiple Bitcoin nodes** in an **Auto Scaling Group** enhances fault tolerance and availability.
- The nodes communicate internally through **private IP addresses** and synchronize through a shared **Application Load Balancer (ALB)**. The ALB implements session persistence using a "stickiness cookie". This ensures that subsequent requests from the same client are consistently routed to the same node, maintaining session continuity. The stickiness duration is set to 90 minutes but can be configured for up to 7 days.
Note: The Bitcoin Core nodes in the HA setup do not share state (e.g., wallet, mempool)
- HA nodes maintain synchronization through the **NAT Gateway** without exposing the RPC endpoint to the public internet.

---

### Optimizing Data Transfer Costs

By deploying as an **outbound-only node**, data transfer costs are significantly reduced since the node does not serve blockchain data to external peers. With its outbound connections, the node(s) are able to maintain full blockchain synchronization.

---
### Accessing and Using bitcoin-cli on a Bitcoin Core Instance

To interact with your Bitcoin Core instance, you'll need to use AWS Systems Manager, as direct SSH access is not available.

Bitcoin Core supports cookie-based authentication by default, so interacting with the `bitcoin-cli` from the node itself does not require credentials.

Follow these steps to make an RPC call:

1. **Access the Instance:**
- Open the AWS Console and navigate to EC2 Instances.
- Locate and select the instance named `SingleNodeBitcoinCoreStack/BitcoinSingleNode`.
- Click the "Connect" button.
- Choose "Session Manager" from the connection options.
- Select "Connect" to establish a session.

2. **Execute an RPC Call:**
Once connected, you can interact with the Bitcoin Core node using Docker commands.

To test the RPC interface, use the following command:

```
sudo docker exec -it bitcoind bitcoin-cli getblockchaininfo
```

This command executes the `getblockchaininfo` RPC method, which returns current state information about the blockchain.

3. **Interpreting Results:**
- The output will provide detailed information about the current state of the blockchain, including the current block height, difficulty, and other relevant data.
- You can use similar commands to execute other RPC methods supported by Bitcoin Core.

---
### Secure RPC Access with AWS Secrets Manager

For a client to securely interact with the Bitcoin Core RPC endpoint from a private subnet within your isolated VPC environment, AWS Secrets Manager is leveraged for credential storage and retrieval.

**Important**: Ensure that you execute the following commands from within a private subnet in the Bitcoin Core Node VPC. A VPC CloudShell environment is suitable for testing purposes.

#### Retrieving Credentials
First, retrieve the RPC credentials from AWS Secrets Manager:

```
export BTC_RPC_AUTH=$(aws secretsmanager get-secret-value --secret-id bitcoin_rpc_credentials --query SecretString --output text)
```

#### Single node RPC Call using credentials
To make an RPC call to a single Bitcoin node, use the following command. Replace <Bitcoin-Node-Private-IP> with the actual private IP address of your Bitcoin node: `<Bitcoin-Node-Private-IP>`.

```
curl --user "$BTC_RPC_AUTH" \
--data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockchaininfo", "params": []}' \
-H 'content-type: text/plain;' http://<Bitcoin-Node-Private-IP>:8332/
```

#### High Availability (HA) RPC Call using credentials

For high availability setups utilizing an Application Load Balancer (ALB), use the following command. Replace <Load-Balancer-DNS-Name> with your ALB's DNS name:

```
curl --user "$BTC_RPC_AUTH" \
--data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockchaininfo", "params": []}' \
-H 'content-type: text/plain;' \
<Load Balancer DNS Name>
```

---


### **Bitcoin Core: Creating an Encrypted Wallet for Payments**

This guide covers how to create an encrypted Bitcoin Core wallet specifically designed for receiving and managing payments in a secure and efficient way.

---

#### **1. Create an Encrypted Payment Wallet**

To create a wallet specifically for handling payments, use the following command:

```
sudo docker exec -it bitcoind bitcoin-cli createwallet "payments" false false "my_secure_passphrase"
```

- **payments:** The wallet name, indicating its purpose.
- **passphrase:** A secure, memorable phrase to protect your funds.

##### **Why Encrypt?**
- Protects against unauthorized access.
- Ensures funds are safe even if the server is compromised.

---

#### **2. Generate a Receiving Address**

To receive payments, generate a new address. You do not need to unlock the wallet for this step:

```
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" getnewaddress "customer1" "bech32"
```

- **customer1:** Label to identify payments from this customer.
- **bech32:** Generates a SegWit address for lower transaction fees.

**Example Output:**
```
bc1qxyzabc123... (Bech32 address)
```

---

#### **3. Monitor Incoming Payments**

To check the balance and verify received payments:

```
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" getbalance
```

- Displays the total balance held in the wallet.

To view detailed transactions:

```
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" listtransactions
```

---

#### **4. Sending Payments (Requires Unlocking)**

When making a payout or transferring funds, you need to unlock the wallet:

```
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" walletpassphrase "my_secure_passphrase" 600
```

- Unlocks the wallet for **600 seconds (10 minutes)**.

#### **Send Bitcoin to a specified address:**

```
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" sendtoaddress "bc1qrecipientaddress" 0.01 "Payment for service"
```

- Sends **0.01 BTC** with an optional label for record-keeping.


#### **5. Lock the Wallet After Use**

For enhanced security, immediately lock the wallet after transactions:

```
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" walletlock
```



#### **6. Backup the Wallet**

To protect your payment data, back up the encrypted wallet regularly:

```
sudo docker exec -it bitcoind bitcoin-cli -rpcwallet="payments" backupwallet "/path/to/backup/payments.dat"
```


#### **Security Tips for Payment Wallets**
- Use strong passphrases and store them securely offline.
- Regularly backup your wallet after creating new addresses or receiving payments.
- Consider setting up automated wallet backups to ensure data integrity.

---
### RPC Authentication -- Deep Dive

The `generateRPCAuth.js` script is responsible for generating secure authentication credentials for your Bitcoin node. This script creates a randomly generated **username** and **password** along with a **salt**. The password and salt are then combined and hashed using the **SHA256** algorithm to produce a secure **hash**. This hash is combined with the username to generate the final **rpcauth** parameter that is appended to the `bitcoin.conf` file.

The final `rpcauth` line in `bitcoin.conf` looks like this:

```
rpcauth=user_258:c220c5f38690bf880f0dd177547e55f7$77c6ec2dd90e792d60450b01a84cc8c2563a7fb1d0fbd73de49be818fde4b407
```

- The **rpcauth** part consists of a **username**, **salt**, and a **hashed password**, providing robust protection in the case that your `bitcoin.conf` is accessed by an unauthorized entity.
- The randomly generated **username** and **password** are securely stored in **AWS Secrets Manager**.

By using this script, it ensures that your node has unique and secure credentials.

### Rotating RPC Secrets

To maintain security, rotate RPC credentials periodically using the `generateRPCAuth.js` script:

```
node generateRPCAuth.js
```

This will update the value of your credentials in Secrets Manager.

**Replacing the Credentials and Restarting the Node to Apply Updates**

- Replace the old `rpcauth` value from the `bitcoin.conf` file with the new one:
```
sudo docker exec -it bitcoind sh -c "sed -i 's/^rpcauth=.*/rpcauth=<new rpcauth string with escape char>/' /root/.bitcoin/bitcoin.conf"
```
- Restart the Bitcoin node to apply changes:
```
sudo docker restart bitcoind
```

#### Verifying the Credential Rotation

Make an RPC call to ensure the new credentials are active:

```
curl --user "$BTC_RPC_AUTH" \
--data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockchaininfo", "params": []}' \
-H 'content-type: text/plain;' http://<Bitcoin-Node-Private-IP>:8332/
```

---

### Monitoring and Troubleshooting

Keep your node healthy by monitoring logs and configurations:

- Check recent Bitcoin logs:
```
sudo docker logs -f --tail 100 bitcoind
```

- Check first 100 Bitcoin logs:
```
sudo docker logs bitcoind | head -n 100
```

- View the configuration file:
```
sudo docker exec -it bitcoind cat /root/.bitcoin/bitcoin.conf
```
- View user data logs:
```
sudo cat /var/log/cloud-init-output.log
```


---

### Additional Tips and Best Practices

- Regularly rotate secrets and always remove old `rpcauth` entries before restarting the node.
- Use **CloudWatch** to monitor node performance and detect issues promptly.

---

### Cleaning up
To destroy the single node and HA configurations, you can run the following commands:

```
#Delete Single Node Infra
cdk destroy SingleNodeBitcoinCoreStack

#Delete HA Infra
cdk destroy HABitcoinCoreNodeStack
```


---

### Conclusion

Deploying and managing a Bitcoin node on AWS requires careful configuration to ensure security, cost efficiency, and high availability. By following the best practices outlined in this guide, you can maintain a robust and secure node while minimizing costs. Stay proactive with monitoring and regularly update credentials to keep your node running smoothly.

8 changes: 8 additions & 0 deletions lib/bitcoin-core/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env node
const cdk = require('aws-cdk-lib');
const { SingleNodeBitcoinCoreStack } = require('./lib/single-node-stack');
const { HABitcoinCoreNodeStack } = require('./lib/ha-node-stack');

const app = new cdk.App();
new SingleNodeBitcoinCoreStack(app, 'SingleNodeBitcoinCoreStack');
new HABitcoinCoreNodeStack(app, 'HABitcoinCoreNodeStack');
3 changes: 3 additions & 0 deletions lib/bitcoin-core/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"app": "node app.js"
}
Loading
Loading