Skip to content
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

feat: Block cheat codes in anvil #8277

Merged
merged 3 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions .github/workflows/devnet-deploys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
API_KEY: ${{ secrets.DEVNET_API_KEY }}
PUBLIC_API_KEY: ${{ secrets.DEVNET_API_KEY }}
FORK_MNEMONIC: ${{ secrets.FORK_MNEMONIC }}
CONTRACT_PUBLISHER_PRIVATE_KEY: ${{ secrets.CONTRACT_PUBLISHER_PRIVATE_KEY }}
CONTRACT_S3_BUCKET: s3://static.aztec.network
Expand Down Expand Up @@ -64,6 +65,7 @@ env:
# Anvil
TF_VAR_FORK_MNEMONIC: ${{ secrets.FORK_MNEMONIC }}
TF_VAR_INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }}
TF_VAR_PUBLIC_API_KEY: ${{ secrets.DEVNET_API_KEY }}

# Faucet
TF_VAR_FAUCET_ACCOUNT_INDEX: 9
Expand Down Expand Up @@ -105,6 +107,7 @@ jobs:
deploy_tag: ${{ steps.set_network_vars.outputs.deploy_tag }}
branch_name: ${{ steps.set_network_vars.outputs.branch_name }}
network_api_key: ${{ steps.set_network_vars.outputs.network_api_key }}
network_public_api_key: ${{ steps.set_network_vars.outputs.network_public_api_key }}
agents_per_prover: ${{ steps.set_network_vars.outputs.agents_per_prover }}
bot_interval: ${{ steps.set_network_vars.outputs.bot_interval }}
node_tcp_range_start: ${{ steps.set_network_vars.outputs.node_tcp_range_start }}
Expand All @@ -131,6 +134,7 @@ jobs:
echo "deploy_tag=devnet" >> $GITHUB_OUTPUT
echo "branch_name=devnet" >> $GITHUB_OUTPUT
echo "network_api_key=DEVNET_API_KEY" >> $GITHUB_OUTPUT
echo "network_public_api_key=DEVNET_API_KEY" >> $GITHUB_OUTPUT
echo "agents_per_prover=4" >> $GITHUB_OUTPUT
echo "bot_interval=180" >> $GITHUB_OUTPUT
echo "node_tcp_range_start=40100" >> $GITHUB_OUTPUT
Expand All @@ -151,6 +155,7 @@ jobs:
echo "deploy_tag=provernet" >> $GITHUB_OUTPUT
echo "branch_name=provernet" >> $GITHUB_OUTPUT
echo "network_api_key=PROVERNET_API_KEY" >> $GITHUB_OUTPUT
echo "network_public_api_key=PROVERNET_PUBLIC_API_KEY" >> $GITHUB_OUTPUT
echo "agents_per_prover=4" >> $GITHUB_OUTPUT
echo "bot_interval=300" >> $GITHUB_OUTPUT
echo "node_tcp_range_start=40200" >> $GITHUB_OUTPUT
Expand All @@ -171,6 +176,7 @@ jobs:
echo "deploy_tag=alphanet" >> $GITHUB_OUTPUT
echo "branch_name=alphanet" >> $GITHUB_OUTPUT
echo "network_api_key=ALPHANET_API_KEY" >> $GITHUB_OUTPUT
echo "network_public_api_key=ALPHANET_API_KEY" >> $GITHUB_OUTPUT
echo "agents_per_prover=1" >> $GITHUB_OUTPUT
echo "bot_interval=30" >> $GITHUB_OUTPUT
echo "node_tcp_range_start=40000" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -200,6 +206,8 @@ jobs:
TF_VAR_DEPLOY_TAG: ${{ needs.set-network.outputs.deploy_tag }}
API_KEY: ${{ secrets[needs.set-network.outputs.network_api_key] }}
TF_VAR_API_KEY: ${{ secrets[needs.set-network.outputs.network_api_key] }}
PUBLIC_API_KEY: ${{ secrets[needs.set-network.outputs.network_public_api_key] }}
TF_VAR_PUBLIC_API_KEY: ${{ secrets[needs.set-network.outputs.network_public_api_key] }}
API_KEY_NAME: ${{ needs.set-network.outputs.network_api_key }}
runs-on: ${{ github.actor }}-x86
steps:
Expand Down Expand Up @@ -443,6 +451,8 @@ jobs:
TF_VAR_DEPLOY_TAG: ${{ needs.set-network.outputs.deploy_tag }}
API_KEY: ${{ secrets[needs.set-network.outputs.network_api_key] }}
TF_VAR_API_KEY: ${{ secrets[needs.set-network.outputs.network_api_key] }}
PUBLIC_API_KEY: ${{ secrets[needs.set-network.outputs.network_public_api_key] }}
TF_VAR_PUBLIC_API_KEY: ${{ secrets[needs.set-network.outputs.network_public_api_key] }}
TF_VAR_AGENTS_PER_PROVER: ${{ needs.set-network.outputs.agents_per_prover }}
TF_VAR_BOT_TX_INTERVAL_SECONDS: ${{ needs.set-network.outputs.bot_interval }}
TF_VAR_NODE_LB_RULE_PRIORITY: ${{ needs.set-network.outputs.node_lb_priority_range_start }}
Expand Down
1 change: 1 addition & 0 deletions build-system/scripts/deploy_terraform
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export TF_VAR_DOCKERHUB_ACCOUNT=$DOCKERHUB_ACCOUNT
export TF_VAR_FORK_MNEMONIC=$FORK_MNEMONIC
export TF_VAR_INFURA_API_KEY=$INFURA_API_KEY
export TF_VAR_API_KEY=$FORK_API_KEY
export TF_VAR_PUBLIC_API_KEY=${PUBLIC_FORK_API_KEY:-$FORK_API_KEY}
export TF_VAR_L1_CHAIN_ID=$CHAIN_ID

# If given a repository name, use it to construct and set/override the backend key.
Expand Down
20 changes: 13 additions & 7 deletions iac/mainnet-fork/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,30 @@ build:
FROM ubuntu:focal

# Install nginx
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
RUN apt-get update && apt install -y git curl nginx

# Copy nginx config
COPY . .
COPY nginx/gateway.conf /etc/nginx/gateway.conf
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./scripts/install_nginx.sh ./scripts/install_nginx.sh
RUN ./scripts/install_nginx.sh

# Install foundry
COPY ./scripts/install_foundry.sh ./scripts/install_foundry.sh
RUN ./scripts/install_foundry.sh
ENV PATH="./foundry/bin:${PATH}"

# Copy nginx config
COPY ./scripts ./scripts
COPY ./redeploy ./redeploy
COPY ./nginx/ /etc/nginx/
COPY --chmod 640 ./etc/anvil.logrotate.conf /etc/logrotate.d/anvil

# Expose port 80
EXPOSE 80

# Set entrypoint.
ENTRYPOINT ["sh", "-c", "./scripts/run_nginx_anvil.sh"]

export-local:
FROM +build
SAVE IMAGE aztecprotocol/mainnet-fork

export-mainnet-fork:
FROM +build
ARG DIST_TAG="devnet"
Expand Down
9 changes: 9 additions & 0 deletions iac/mainnet-fork/etc/anvil.logrotate.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/var/log/anvil/*.log {
daily
missingok
rotate 14
size 50M
compress
notifempty
copytruncate
}
22 changes: 19 additions & 3 deletions iac/mainnet-fork/nginx/gateway.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,29 @@ server {
listen 80 default_server;
listen 8545;

location = /{{API_KEY}} {
location /{{ADMIN_API_KEY}} {
proxy_pass http://0.0.0.0:8544;
rewrite ^/{{API_KEY}}(.*) /$1 break;
rewrite ^/{{ADMIN_API_KEY}}(.*) /$1 break;
}

location /public-{{PUBLIC_API_KEY}} {
client_body_buffer_size 20M;
client_body_in_single_buffer on;
js_import main from njs/anvil_validation.js;
js_content main.authorize;
}

location @anvil {
proxy_pass http://0.0.0.0:8544;
rewrite ^/({{ADMIN_API_KEY}}|public-{{PUBLIC_API_KEY}})(.*) /$2 break;
}

# Error responses
error_page 404 = @400; # Treat invalid paths as bad requests
error_page 404 = @404;
location @404 {
return 404 '{"error":"Resource not found"}';
}

proxy_intercept_errors on; # Do not send backend errors to client
default_type application/json; # If no content-type, assume JSON
}
1 change: 1 addition & 0 deletions iac/mainnet-fork/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
load_module modules/ngx_http_js_module.so;

events {
worker_connections 768;
Expand Down
28 changes: 28 additions & 0 deletions iac/mainnet-fork/nginx/njs/anvil_validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Authorizes a request based on the method of the JSON-RPC request body, blocking all cheat codes.
// See https://github.com/nginx/njs-examples?tab=readme-ov-file#authorizing-requests-based-on-request-body-content-http-authorization-request-body
function authorize(r) {
try {
if (r.requestText) {
const body = JSON.parse(r.requestText);
if (body && body.method) {
const method = body.method.replace(/\s+/g).toLowerCase();
if (
method.startsWith("evm_") ||
method.startsWith("hardhat_") ||
method.startsWith("anvil_")
) {
const error = "Restricted method " + method;
r.error(error);
r.return(401, JSON.stringify({ error }));
return;
}
}
}
r.internalRedirect("@anvil");
} catch (e) {
r.error("JSON.parse exception: " + e);
r.return(400, JSON.stringify({ error: "Error parsing request" }));
}
}

export default { authorize };
2 changes: 1 addition & 1 deletion iac/mainnet-fork/redeploy
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3
4
19 changes: 19 additions & 0 deletions iac/mainnet-fork/scripts/install_nginx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/sh
set -eu

# See https://nginx.org/en/linux_packages.html#Ubuntu
echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections

apt-get update && apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring

curl -sS https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| tee /etc/apt/sources.list.d/nginx.list

echo "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
| tee /etc/apt/preferences.d/99nginx

apt-get update && apt install -y git curl nginx nginx-module-njs
14 changes: 9 additions & 5 deletions iac/mainnet-fork/scripts/run_nginx_anvil.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

set -eum pipefail

# Replace API_KEY in nginx config
echo "Replacing api key with $API_KEY in nginx config..."
sed -i 's/{{API_KEY}}/'$API_KEY'/' /etc/nginx/gateway.conf
# Replace API_KEYs in nginx config
echo "Replacing api keys in nginx config..."
sed -i 's/{{PUBLIC_API_KEY}}/'$PUBLIC_API_KEY'/g' /etc/nginx/gateway.conf
sed -i 's/{{ADMIN_API_KEY}}/'$API_KEY'/g' /etc/nginx/gateway.conf

# Run nginx and anvil alongside each other
trap 'kill $(jobs -p)' SIGTERM
Expand All @@ -21,8 +22,11 @@ echo "result: ${MNEMONIC_STRIPPED:0:10}..."
# Data directory for anvil state
mkdir -p /data

# Run anvil silently
.foundry/bin/anvil --silent --block-time 12 --host $HOST -p $PORT -m "$MNEMONIC_STRIPPED" -f=https://mainnet.infura.io/v3/$INFURA_API_KEY --chain-id=$L1_CHAIN_ID --fork-block-number=15918000 --block-base-fee-per-gas=10 -s=$SNAPSHOT_FREQUENCY --state=./data/state --balance=1000000000000000000 >/dev/null &
# Log directory for anvil
mkdir -p /var/log/anvil/

# Run anvil logging to /var/log/anvil
.foundry/bin/anvil --block-time 12 --host $HOST -p $PORT -m "$MNEMONIC_STRIPPED" -f=https://mainnet.infura.io/v3/$INFURA_API_KEY --chain-id=$L1_CHAIN_ID --fork-block-number=15918000 --block-base-fee-per-gas=10 -s=$SNAPSHOT_FREQUENCY --state=./data/state --balance=1000000000000000000 >>/var/log/anvil/anvil.log &

echo "Waiting for ethereum host at $ETHEREUM_HOST..."
while ! curl -s $ETHEREUM_HOST >/dev/null; do sleep 1; done
Expand Down
26 changes: 6 additions & 20 deletions iac/mainnet-fork/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,12 @@ resource "aws_ecs_task_definition" "aztec_mainnet_fork" {
image = "${var.DOCKERHUB_ACCOUNT}/mainnet-fork:${var.DEPLOY_TAG}"
essential = true
environment = [
{
name = "API_KEY"
value = "${var.API_KEY}"
},
{
name = "MNEMONIC"
value = "${var.FORK_MNEMONIC}"
},
{
name = "INFURA_API_KEY"
value = "${var.INFURA_API_KEY}"
},
{
name = "L1_CHAIN_ID"
value = "${var.L1_CHAIN_ID}"
},
{
name = "SNAPSHOT_FREQUENCY"
value = "15"
}
{ name = "API_KEY", value = "${var.API_KEY}" },
{ name = "PUBLIC_API_KEY", value = "${var.PUBLIC_API_KEY}" },
{ name = "MNEMONIC", value = "${var.FORK_MNEMONIC}" },
{ name = "INFURA_API_KEY", value = "${var.INFURA_API_KEY}" },
{ name = "L1_CHAIN_ID", value = "${var.L1_CHAIN_ID}" },
{ name = "SNAPSHOT_FREQUENCY", value = "15" }
]
mountPoints = [
{
Expand Down
4 changes: 4 additions & 0 deletions iac/mainnet-fork/terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ variable "API_KEY" {
type = string
}

variable "PUBLIC_API_KEY" {
type = string
}

variable "DOCKERHUB_ACCOUNT" {
type = string
}
Expand Down
Loading