Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
aac0dfe
Copy from recall-deploy
sam701 May 8, 2025
a095609
Remove ipc ref
sam701 May 12, 2025
fcb6387
Fix ipc dir location
sam701 May 12, 2025
9efe1a8
Adjust nushell setup script
sam701 May 12, 2025
492150e
Add commit check
sam701 May 12, 2025
b2f9513
Remove onepass
sam701 May 14, 2025
a819b56
Add GH workflow
sam701 May 14, 2025
a59ae74
Remove unused workflow step
sam701 May 14, 2025
06f0a80
Fix branch name
sam701 May 14, 2025
29aa262
Disable QEMU
sam701 May 14, 2025
c0a23a8
Set PATH
sam701 May 14, 2025
45459ea
Fix image rebuild
sam701 May 15, 2025
2e1f0fc
Enable skipping of the commit match check
sam701 May 15, 2025
e337c57
Try to build without root
sam701 May 15, 2025
d33563c
Fix nu path
sam701 May 15, 2025
6b04461
Try to build an explicit image
sam701 May 15, 2025
e43f12e
Fix flags
sam701 May 15, 2025
51f623a
Fix permissions
sam701 May 15, 2025
7288485
Run anvil as local user
sam701 May 15, 2025
65c20b1
Fix reset flag
sam701 May 15, 2025
1e16c6b
Add group to docker run
sam701 May 15, 2025
247b14d
Build fendermint locally
sam701 May 15, 2025
bf2d96b
Fix local build
sam701 May 15, 2025
d445cc8
Tune multi-arch build
sam701 May 15, 2025
b93fe53
Fix script
sam701 May 15, 2025
2e1277c
Fix user ID in DIND image
sam701 May 16, 2025
c2707de
Inspect anvil state
sam701 May 16, 2025
7220908
Use a single anvil Dockerfile
sam701 May 16, 2025
328cbf8
Delete unused code
sam701 May 16, 2025
1d8a556
Fix anvil image
sam701 May 16, 2025
84f1365
Fix anvil termination
sam701 May 16, 2025
b723796
Debug 1
sam701 May 16, 2025
3c4f0b4
debug 2
sam701 May 16, 2025
8fe0b26
Enable full build
sam701 May 16, 2025
d5190ec
Test full build
sam701 May 19, 2025
deaa53d
Improve README
sam701 May 19, 2025
57618dc
Rename subcommand
sam701 May 19, 2025
d866181
Fix contract stack deployment
sam701 May 19, 2025
665065a
Fix build
sam701 May 19, 2025
7097dd2
Remove debug code
sam701 May 19, 2025
e556205
Improve docs
sam701 May 19, 2025
d16f87f
Enable running localnet after stop
sam701 May 21, 2025
70e0dd7
Make build-dind-image respect graceful-shutdown field
sam701 May 21, 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
11 changes: 11 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,14 @@ jobs:
- build
- unit-tests
- e2e-tests

build-localnet-image:
uses: ./.github/workflows/docker-build-localnet-image.yaml
secrets: inherit
# Dependencies are not strictly necessary, but if fendermint tests pass they publish docker too, so they better work.
# It is because of these needs that all the filters are allowed to run on `main` too, otherwise this would be disabled.
# It could be done in a more granular approach inside the workflows to allow the job to pass but opt-out of testing,
# but I guess it doesn't hurt to run a final round of unconditional tests, even though it takes longer to publish.
if: github.ref == 'refs/heads/main'
needs:
- docker-publish
39 changes: 39 additions & 0 deletions .github/workflows/docker-build-localnet-image.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Build Localnet Image
on:
# Runs on non-main branches where the fendermint image must be built locally
pull_request:

# runs on main branch after the fendermint image has been published
workflow_call:

jobs:
build-localnet-image:
runs-on: self-hosted
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}

- name: Install Nushell
run: ./deployment/set-up-nu.sh

- name: Build Localnet Image
working-directory: ./deployment
run: |
set -eux

source ./.nu/activate.sh

if [ "${{ github.ref }}" == "refs/heads/main" ]; then
hash=$(git rev-parse --short=7 HEAD)
flags="--fendermint-image textile/fendermint:sha-$hash --push-multi-arch-tags textile/recall-localnet:sha-$hash,textile/recall-localnet:latest"
else
flags="--rebuild-fendermint-image --local-image-tag recall-localnet"
fi

./localnet.nu build-docker-image $flags --node-count 2
19 changes: 0 additions & 19 deletions .github/workflows/docker-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,22 +78,3 @@ jobs:
export BUILDX_STORE="--push"
export BUILDX_FLAGS="--platform linux/amd64,linux/arm64"
cd fendermint && make docker-build

# Publish Localnet image using the Fendermint image built above
publish_localnet:
name: Publish Localnet image
runs-on: self-hosted
needs: publish
steps:
- name: Trigger localnet image publish in recall-deploy
run: |
echo "Using Fendermint commit hash: ${{ needs.publish.outputs.commit-hash }}"
curl -X POST --location "https://api.github.com/repos/recallnet/recall-deploy/dispatches" \
--header "Authorization: token ${{ secrets.PA_TOKEN }}" \
--header "Accept: application/vnd.github.v3+json" \
--data '{
"event_type": "remote-trigger",
"client_payload": {
"fendermint-sha": "${{ needs.publish.outputs.commit-hash }}"
}
}'
3 changes: 3 additions & 0 deletions deployment/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.nu/
/localnet-data*
/testnet-data-*
12 changes: 12 additions & 0 deletions deployment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Localnet Scripts

## Install nushell
If you do not have nushell installed, you can call `./set-up-nu.sh` that will download the required nushell version to `./.nu`.
You can add `nu` to your `PATH` with `source ./.nu/activate.sh`

## Usage
You can run the localnet in two ways:
* `./localnet.nu run` - runs all localnet services on the local docker. See `./localnet.nu run -h` for details.
* `./localnet.nu run-dind` - downloads the latest `textile/recall-localnet` docker image and runs all services inside a single container. This is faster than the previous option.

See `./localnet.nu -h` for details.
13 changes: 13 additions & 0 deletions deployment/docker/anvil.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM ubuntu:24.04

RUN set -x; \
arch=$(uname -m | sed -e s/aarch64/arm64/ -e s/x86_64/amd64/); \
apt update && apt install -y curl && \
curl -Lo /tmp/tt.tgz https://github.com/foundry-rs/foundry/releases/download/stable/foundry_stable_linux_${arch}.tar.gz && \
tar xvf /tmp/tt.tgz -C /usr/bin && \
rm /tmp/tt.tgz

RUN mkdir -p /workdir
WORKDIR /workdir

ENTRYPOINT ["anvil", "--host", "0.0.0.0", "--state", "/workdir/state"]
44 changes: 44 additions & 0 deletions deployment/docker/entrypoint-localnet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash

set -ex

# Setup signal handling for graceful shutdown
function cleanup() {
echo "Received termination signal. Shutting down containers..."
cd /workdir/localnet-data
for d in node-*; do
(
cd $d/workdir
docker compose down
)
done
docker stop localnet-anvil
docker network rm recall-localnet
pkill -TERM dockerd
exit 0
}

# Register the cleanup function for these signals
trap cleanup SIGTERM SIGINT

nohup dockerd &> /dev/null &
DOCKERD_PID=$!
while ! docker info > /dev/null; do
sleep 1
done

docker build -t anvil -f ./docker/anvil.Dockerfile ./docker
docker network create recall-localnet || true
docker run --rm --name localnet-anvil -u nobody -d --network recall-localnet -p 0.0.0.0:8545:8545 -v /workdir/localnet-data/anvil:/workdir anvil

cd localnet-data
for d in node-*; do
(
cd $d/workdir
docker compose up -d
)
done

# Keep container running until terminated
echo "All containers started. Waiting for termination signal..."
wait $DOCKERD_PID
17 changes: 17 additions & 0 deletions deployment/docker/localnet.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM docker

RUN apk add bash

RUN mkdir -p /workdir
WORKDIR /workdir

COPY docker /workdir/docker
COPY localnet-data /workdir/localnet-data
RUN chown -R nobody:nobody /workdir
ENV RECALL_NODE_USER=nobody
RUN ls -la /workdir/localnet-data/anvil/

# This is needed to expose DIND endpoints correctly from inside the localnet container
ENV LOCALNET_CLI_BIND_HOST=0.0.0.0

ENTRYPOINT ["./docker/entrypoint-localnet.sh"]
34 changes: 34 additions & 0 deletions deployment/docker/subnet-setup.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This image is used to set up a subnet.
# It contains the required ipc-cli and fendermint versions and the foundry tools.

ARG fendermint_image

FROM $fendermint_image

# Install foundry
RUN set -ex; \
arch=$(uname -m | sed -e s/aarch64/arm64/ -e s/x86_64/amd64/); \
curl -Lo /tmp/tt.tgz https://github.com/foundry-rs/foundry/releases/download/stable/foundry_stable_linux_${arch}.tar.gz && \
tar xvf /tmp/tt.tgz -C /bin && \
rm /tmp/tt.tgz


ARG NODE_VERSION=22.14.0

# Install build tools
RUN set -ex; \
apt update; \
apt install -y git make python3 build-essential; \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash;

RUN set -ex; \
\. $HOME/.nvm/nvm.sh; \
nvm install $NODE_VERSION; \
nvm use v$NODE_VERSION; \
nvm alias default v$NODE_VERSION;

ENV PATH="/fendermint/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"

RUN npm install -g pnpm

ENTRYPOINT ["/bin/bash"]
128 changes: 128 additions & 0 deletions deployment/lib/local-files.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@

export def add-subnet-to-ipc-config [] {
open $env.state.config.ipc_config_file |
update subnets { $in | append {
id: $env.state.subnet_id
config: {
network_type: "fevm"
provider_http: $env.state.config.subnet.rpc_url
gateway_addr: "0x77aa40b105843728088c0132e43fc44348881da8"
registry_addr: "0x74539671a1d2f1c8f200826baba665179f53a1b7"
}
}} |
to toml |
save -f $env.state.config.ipc_config_file
}

export def write-subnet-config [dest: string, --bootstrap] {
mut cfg = {
address_network: "testnet"
parent_chain: {
chain_id: $env.state.config.parent_chain.chain_id
addresses: {
gateway: $env.state.gateway_address
registry: $env.state.registry_address
supply_source: $env.state.supply_source_address
subnet_contract: $env.state.subnet_eth_address
validator_gater: $env.state.validator_gater_address
validator_rewarder: $env.state.validator_rewarder_address
}
}
subnet: {
subnet_id: $env.state.subnet_id
chain_id: $env.state.config.subnet.chain_id
}
endpoints: {
cometbft_rpc_servers: $env.state.config.subnet.cometbft_rpc_servers
cometbft_persistent_peers: ($env.state.peers?.cometbft | default [] | uniq)
fendermint_seeds: ($env.state.peers?.fendermint | default [] | uniq)
}
}

if not $bootstrap {
$cfg = ($cfg | merge deep {
subnet: {
addresses: {
credit_manager: $env.state.creditManager_contract_address
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sam701 we no longer need to deploy the wrapper / "manager" contracts. i just merged ad096f2 in the contracts repo, which removes them entirely.

i created issues in https://github.com/recallnet/recall-docker-compose/issues/60 and https://github.com/recallnet/recall-deploy/issues/308 to account for this elsewhere. (i should have gave you a heads up wrt the IaC...sorry about that.)

Copy link
Copy Markdown
Contributor

@dtbuchholz dtbuchholz May 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or, i suppose we could keep your existing logic in this PR. then, create a follow up PR that updates ipc's recall-contracts submodule to ad096f2, and align that with the two issues mentioned in the comment above.

if that makes sense to you, i created this ticket as a follow up: #621

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dtbuchholz cool, thank you! The scripts in recall-deploy will be removed once this PR is merged. I'll move your issue from recall-deploy to this repo.

bucket_manager: $env.state.bucketManager_contract_address
faucet_contract: $env.state.faucet_contract_address
blob_manager: $env.state.blobManager_contract_address
}
}
endpoints: {
evm_rpc_url: $env.state.config.subnet.rpc_url
}
})
}

$cfg | save -f $dest
}

export def build-setup-docker-image [] {
cd docker
docker build ...[
--build-arg $"fendermint_image=($env.state.config.fendermint_image)"
-t $env.state.config.setup_image
-f subnet-setup.Dockerfile .
]
}

export def build-fendermint-image [] {
if $env.state.config.fendermint_image == "fendermint" {
cd ../fendermint
make docker-build
}
}

export def set-fendermint-image [docker_compose_dir: string] {
cd $"($docker_compose_dir)/config"
let f = "node-default.toml"
open $f | update images.fendermint $env.state.config.fendermint_image | save -f $f
}

# Write network config suitable for recall CLI into workdir.
export def write-recall-cli-config [] {
let endpoints = match $env.state.config.network {
"localnet" => ({
subnet_config: {
rpc_url: "http://localhost:26657"
object_api_url: "http://localhost:8001"
evm_rpc_url: "http://localhost:8645"
}
parent_network_config: {
evm_rpc_url: "http://localhost:8545"
}
})
"testnet" => {
let base = $"($env.state.config.version).node-0.testnet.recall.network"
{
subnet_config: {
rpc_url: $"https://api.($base)"
object_api_url: $"https://objects.($base)"
evm_rpc_url: $"https://evm.($base)"
}
parent_network_config: {
evm_rpc_url: "https://api.calibration.node.glif.io"
}
}
}
}

let contracts = {
subnet_config: {
chain_id: $env.state.config.subnet.chain_id
subnet_id: $env.state.subnet_id
evm_gateway_address: "0x77aa40b105843728088c0132e43fc44348881da8"
evm_registry_address: "0x74539671a1d2f1c8f200826baba665179f53a1b7"
}
parent_network_config: {
evm_gateway_address: $env.state.gateway_address
evm_registry_address: $env.state.registry_address
evm_supply_source_address: $env.state.supply_source_address
}
}

let cfg = {} | insert $env.state.config.network ($endpoints | merge deep $contracts)

$cfg | save -f ($env.state.config.workdir | path join "networks.toml")
}
Loading
Loading