Skip to content

Commit 1349141

Browse files
committed
Merge remote-tracking branch 'origin/develop' into fix-healthchecker-stale-cache
# Conflicts: # core/scripts/go.mod # deployment/go.mod # integration-tests/go.mod # integration-tests/load/go.mod # system-tests/lib/go.mod
2 parents dfe60d4 + 6eb6b84 commit 1349141

84 files changed

Lines changed: 2523 additions & 677 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-core.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,9 @@ jobs:
360360
GH_RUN_ID: ${{ github.run_id }}
361361
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
362362
run: |
363-
find race.* | xargs cat > race.txt
364-
if [[ -s race.txt ]]; then
365-
cat race.txt
363+
find race.* | xargs cat >> races.txt
364+
if [[ -s races.txt ]]; then
365+
cat races.txt
366366
echo "post_to_slack=true" | tee -a "$GITHUB_OUTPUT"
367367
else
368368
echo "post_to_slack=false" | tee -a "$GITHUB_OUTPUT"

.github/workflows/cre-local-env-tests.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
113113
with:
114114
aws-region: ${{ secrets.QA_AWS_REGION }}
115-
role-to-assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
115+
role-to-assume: ${{ secrets.AWS_CTF_READ_ACCESS_ROLE_ARN }}
116116
role-duration-seconds: 1800
117117
mask-aws-account-id: true
118118

@@ -151,7 +151,8 @@ jobs:
151151
env:
152152
DISABLE_DX_TRACKING: true
153153
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154-
AWS_ECR: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.us-west-2.amazonaws.com
154+
MAIN_AWS_ECR: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.us-west-2.amazonaws.com
155+
SDLC_AWS_ECR: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.us-west-2.amazonaws.com
155156
run: |
156157
# Remove chip_ingress/chip_config sections since CI role lacks ECR permissions for the Atlas repo
157158
awk '/^\[chip_ingress\.build_config\]/,/^$/{next} /^\[chip_ingress\.pull_config\]/,/^$/{next} /^\[chip_config\.build_config\]/,/^$/{next} /^\[chip_config\.pull_config\]/,/^$/{next} {print}' configs/setup.toml > configs/setup.toml.tmp && mv configs/setup.toml.tmp configs/setup.toml
@@ -165,6 +166,7 @@ jobs:
165166
CTF_CONFIGS: "./configs/workflow-gateway-don.toml"
166167
CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1"
167168
CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink:${{ github.event_name == 'pull_request' && format('nightly-{0}-plugins', steps.set-date.outputs.date) || inputs.chainlink_image_tag }}"
169+
CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
168170
DISABLE_DX_TRACKING: "true"
169171
CI: "true"
170172
run: |

.github/workflows/cre-regression-system-tests.yaml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ jobs:
117117
# Beholder stack will be started only for the Beholder tests
118118
CHIP_INGRESS_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f
119119
CHIP_CONFIG_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969
120+
CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
120121
BILLING_PLATFORM_SERVICE_IMAGE: ${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/billing-platform-service:v1.45.0
121122

122123
steps:
@@ -221,12 +222,9 @@ jobs:
221222
continue-on-error: ${{ env.ENABLE_AUTO_QUARANTINE == 'true' }}
222223
env:
223224
TEST_NAME: ${{ matrix.tests.test_name }}
224-
TEST_TIMEOUT: 30m
225+
TEST_TIMEOUT: 7m # let's leave 3 minutes for other steps (the whole job times out after 10 minutes)
225226
PARALLEL_COUNT: "10"
226-
# parallelisation flags for tests
227-
# fanout is necessary, because multiple tests would otherwise start chip test sinks at the same port, causing conflicts
228227
CRE_TEST_PARALLEL_ENABLED: "true"
229-
CRE_TEST_CHIP_SINK_FANOUT_ENABLED: "true"
230228
run: |
231229
echo "Starting test: '${TEST_NAME}'"
232230
echo "⚠️⚠️⚠️ Add 'skip-e2e-regression' label to skip this step if necessary ⚠️⚠️⚠️"
@@ -260,12 +258,12 @@ jobs:
260258
artifact-name: ${{ matrix.tests.test_id }}_test_logs
261259

262260
- name: Show Docker containers status
263-
if: failure()
261+
if: failure() || cancelled()
264262
shell: bash
265263
run: docker ps -a
266264

267265
- name: Save Regression tests Docker logs
268-
if: failure()
266+
if: failure() || cancelled()
269267
shell: bash
270268
working-directory: system-tests/tests/regression/cre
271269
run: |
@@ -275,7 +273,7 @@ jobs:
275273
done
276274
277275
- name: Upload all artifacts as single package
278-
if: failure()
276+
if: failure() || cancelled()
279277
uses: actions/upload-artifact@v7
280278
with:
281279
name: test-logs-${{ matrix.tests.test_name }}-${{ matrix.tests.topology }}

.github/workflows/cre-soak-memory-leak.yml

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ jobs:
4040
CTF_CHAINLINK_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/${{ inputs.ecr_name || 'chainlink' }}:${{ inputs.chainlink_image_tag }}"
4141
CHIP_INGRESS_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f"
4242
CHIP_CONFIG_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969"
43+
CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
4344

4445
steps:
4546
- name: Enable S3 Cache for Self-Hosted Runners
@@ -76,28 +77,12 @@ jobs:
7677
registries: ${{ format('{0},{1}', secrets.QA_AWS_ACCOUNT_NUMBER, secrets.AWS_ACCOUNT_ID_PROD) }}
7778
env:
7879
AWS_REGION: ${{ secrets.QA_AWS_REGION }}
79-
80-
- name: Install CTF binary
81-
shell: bash
82-
working-directory: core/scripts/cre/environment
83-
env:
84-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
85-
CTF_TAG: "framework/v0.15.2"
86-
run: |
87-
echo "::startgroup::Install CTF binary"
88-
mkdir -p bin
89-
gh release download "${CTF_TAG}" --pattern "framework-v*-linux-amd64.tar.gz" --clobber --repo smartcontractkit/chainlink-testing-framework -O ctf.tar.gz
90-
tar -xzf ctf.tar.gz
91-
mv ctf bin/ctf
92-
chmod +x bin/ctf
93-
echo "::endgroup::"
94-
9580
- name: Start observability stack
9681
shell: bash
9782
working-directory: core/scripts/cre/environment
9883
run: |
9984
echo "::startgroup::Starting observability stack (required by leak package)"
100-
./bin/ctf obs up -f
85+
go run . obs up -f
10186
echo "::endgroup::"
10287
10388
- name: Start local CRE

.github/workflows/cre-system-tests.yaml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ jobs:
248248
env:
249249
CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1"
250250
CTF_CHAINLINK_IMAGE: "${{ steps.resolve-chainlink-image.outputs.resolved_image }}"
251+
CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
251252
CTF_CONFIGS: ${{ matrix.tests.configs }}
252253
CRE_VERSION: ${{ matrix.tests.cre_version }}
253254
TEST_NAME: ${{ matrix.tests.test_name }}
@@ -327,15 +328,12 @@ jobs:
327328
continue-on-error: ${{ env.ENABLE_AUTO_QUARANTINE == 'true' }}
328329
env:
329330
TEST_NAME: ${{ matrix.tests.test_name }}
330-
TEST_TIMEOUT: 30m
331+
TEST_TIMEOUT: 7m # let's leave 3 minutes for other steps (the whole job times out after 10 minutes)
331332
RUN_QUARANTINED_TESTS: "true" # always run quarantined tests in CI
332333
TOPOLOGY_NAME: ${{ matrix.tests.topology }}
333334
GITHUB_TOKEN: ${{ steps.github-token.outputs.access-token || '' }} # to avoid rate limiting when downloading protobuf files from GitHub
334335
PARALLEL_COUNT: "10"
335-
# parallelisation flags for tests
336-
# fanout is necessary, because multiple tests would otherwise start chip test sinks at the same port, causing conflicts
337336
CRE_TEST_PARALLEL_ENABLED: "true"
338-
CRE_TEST_CHIP_SINK_FANOUT_ENABLED: "true"
339337
run: |
340338
echo "Starting test: '${TEST_NAME}'"
341339
gotestsum \
@@ -365,12 +363,12 @@ jobs:
365363
artifact-name: ${{ matrix.tests.test_id }}_test_logs
366364

367365
- name: Show Docker containers status
368-
if: failure()
366+
if: failure() || cancelled()
369367
shell: bash
370368
run: docker ps -a
371369

372370
- name: Save Smoke tests Docker logs
373-
if: failure()
371+
if: failure() || cancelled()
374372
shell: bash
375373
working-directory: system-tests/tests/smoke/cre
376374
run: |
@@ -383,7 +381,7 @@ jobs:
383381
done
384382
385383
- name: Upload all artifacts as single package
386-
if: failure()
384+
if: failure() || cancelled()
387385
uses: actions/upload-artifact@v7
388386
with:
389387
name: test-logs-${{ matrix.tests.test_name }}-${{ matrix.tests.topology }}

.github/workflows/devenv-compat.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ jobs:
9999
CTF_LOG_LEVEL: ${{ inputs.ctf-log-level }}
100100
# JD is required by the local CRE-based tests
101101
CTF_JD_IMAGE: "${{ secrets.AWS_ACCOUNT_ID_PROD }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/job-distributor:0.22.1"
102+
# ChIP Router is required by the local CRE-based tests
103+
CTF_CHIP_ROUTER_IMAGE: "${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/local-cre-chip-router:v1.0.1"
102104
steps:
103105
- name: Checkout code
104106
uses: actions/checkout@v5

core/capabilities/integration_tests/keystone/keystone_test.go

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,22 @@ import (
55
"crypto/rand"
66
"encoding/hex"
77
"math/big"
8+
"net/url"
9+
"os"
810
"sync"
11+
"sync/atomic"
912
"testing"
1013
"time"
1114

1215
"github.com/ethereum/go-ethereum/accounts/abi/bind"
16+
"github.com/ethereum/go-ethereum/common"
1317
"github.com/google/uuid"
1418
"github.com/stretchr/testify/assert"
1519
"github.com/stretchr/testify/require"
1620

1721
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/datastreams"
1822
"github.com/smartcontractkit/chainlink-common/pkg/logger"
23+
"github.com/smartcontractkit/chainlink-common/pkg/services/servicetest"
1924
feeds_consumer "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/feeds_consumer_1_0_0"
2025
reporttypes "github.com/smartcontractkit/chainlink-evm/pkg/mercury/v3/types"
2126
"github.com/smartcontractkit/chainlink-protos/cre/go/values"
@@ -31,6 +36,99 @@ func Test_OneAtATimeTransmissionSchedule(t *testing.T) {
3136
testTransmissionSchedule(t, "2s", "oneAtATime")
3237
}
3338

39+
func Test_AllAtOnceZeroDelta_SubmitsDuplicateForwarderTxs(t *testing.T) {
40+
rawDBURL, ok := os.LookupEnv("CL_DATABASE_URL")
41+
if !ok {
42+
t.Skip("CL_DATABASE_URL is required for this integration test")
43+
}
44+
parsedDBURL, err := url.Parse(rawDBURL)
45+
if err != nil || parsedDBURL.Path == "" {
46+
t.Skip("CL_DATABASE_URL must include a database path for this integration test")
47+
}
48+
49+
ctx := t.Context()
50+
lggr := logger.Test(t)
51+
52+
workflowDonConfiguration, err := framework.NewDonConfiguration(framework.NewDonConfigurationParams{
53+
Name: "Workflow",
54+
NumNodes: 7,
55+
F: 2,
56+
AcceptsWorkflows: true,
57+
})
58+
require.NoError(t, err)
59+
triggerDonConfiguration, err := framework.NewDonConfiguration(framework.NewDonConfigurationParams{
60+
Name: "Trigger",
61+
NumNodes: 7,
62+
F: 2,
63+
})
64+
require.NoError(t, err)
65+
targetDonConfiguration, err := framework.NewDonConfiguration(framework.NewDonConfigurationParams{
66+
Name: "Target",
67+
NumNodes: 7,
68+
F: 2,
69+
})
70+
require.NoError(t, err)
71+
72+
triggerSink := framework.NewTriggerSink(t, "streams-trigger", "1.0.0")
73+
donContext := framework.CreateDonContext(ctx, t)
74+
75+
workflowDon := createKeystoneWorkflowDon(ctx, t, lggr, workflowDonConfiguration, triggerDonConfiguration, targetDonConfiguration, donContext)
76+
forwarderAddr, _ := SetupForwarderContract(t, workflowDon, donContext.EthBlockchain)
77+
_, consumer := SetupConsumerContract(t, donContext.EthBlockchain, forwarderAddr, workflowOwnerID, workflowName)
78+
writeTargetDon := createKeystoneWriteTargetDon(ctx, t, lggr, targetDonConfiguration, donContext, forwarderAddr)
79+
triggerDon := createKeystoneTriggerDon(ctx, t, lggr, triggerDonConfiguration, donContext, triggerSink)
80+
81+
servicetest.Run(t, workflowDon)
82+
servicetest.Run(t, triggerDon)
83+
servicetest.Run(t, writeTargetDon)
84+
donContext.WaitForCapabilitiesToBeExposed(t, workflowDon, triggerDon, writeTargetDon)
85+
86+
feedID := newFeedID(t)
87+
job := createKeystoneWorkflowJob(
88+
t,
89+
workflowName,
90+
workflowOwnerID,
91+
[]string{feedID},
92+
consumer.Address(),
93+
"0s",
94+
"allAtOnce",
95+
)
96+
err = workflowDon.AddJob(ctx, &job)
97+
require.NoError(t, err)
98+
99+
report := createFeedReport(t, big.NewInt(1), 7, feedID, triggerDonConfiguration.KeyBundles)
100+
wrappedReports, err := wrapReports([]*datastreams.FeedReport{report}, 12, datastreams.Metadata{})
101+
require.NoError(t, err)
102+
103+
startBlock, err := donContext.EthBlockchain.Client().BlockNumber(ctx)
104+
require.NoError(t, err)
105+
106+
triggerSink.SendOutput(wrappedReports, uuid.New().String())
107+
waitForConsumerReports(t, consumer, newStreamsV1Handler([]*datastreams.FeedReport{report}))
108+
109+
var observedTxCount atomic.Uint64
110+
require.Eventually(t, func() bool {
111+
latestBlock, blockErr := donContext.EthBlockchain.Client().BlockNumber(ctx)
112+
if blockErr != nil || latestBlock <= startBlock {
113+
return false
114+
}
115+
txCount, countErr := countTransactionsToAddress(ctx, donContext.EthBlockchain, forwarderAddr, startBlock+1, latestBlock)
116+
if countErr != nil {
117+
return false
118+
}
119+
observedTxCount.Store(txCount)
120+
return txCount > 1
121+
}, 20*time.Second, 500*time.Millisecond, "expected duplicate forwarder tx submissions for one execution")
122+
123+
// TODO: @ilija42 Expected behavior after fix: exactly one forwarder transaction should be submitted for a single execution.
124+
// require.EqualValues(
125+
// t,
126+
// 1,
127+
// observedTxCount.Load(),
128+
// "TODO: enforce single forwarder submission per execution under allAtOnce + low deltaStage",
129+
// )
130+
}
131+
34132
func testTransmissionSchedule(t *testing.T, deltaStage string, schedule string) {
35133
ctx := t.Context()
36134

@@ -49,7 +147,7 @@ func testTransmissionSchedule(t *testing.T, deltaStage string, schedule string)
49147
targetDonConfiguration, triggerSink)
50148

51149
feedCount := 3
52-
var feedIDs []string
150+
feedIDs := make([]string, 0, feedCount)
53151
for range feedCount {
54152
feedIDs = append(feedIDs, newFeedID(t))
55153
}
@@ -161,3 +259,27 @@ func (h *streamsV1Handler) handleDone(t *testing.T) {
161259
defer h.mu.Unlock()
162260
t.Logf("found (%v) %d of %d", h.found, len(h.found), len(h.expected))
163261
}
262+
263+
func countTransactionsToAddress(
264+
ctx context.Context,
265+
chain *framework.EthBlockchain,
266+
target common.Address,
267+
fromBlock uint64,
268+
toBlock uint64,
269+
) (uint64, error) {
270+
var count uint64
271+
for blockNum := fromBlock; blockNum <= toBlock; blockNum++ {
272+
block, err := chain.Client().BlockByNumber(ctx, new(big.Int).SetUint64(blockNum))
273+
if err != nil {
274+
return 0, err
275+
}
276+
277+
for _, tx := range block.Transactions() {
278+
if tx.To() != nil && *tx.To() == target {
279+
count++
280+
}
281+
}
282+
}
283+
284+
return count, nil
285+
}

core/scripts/cre/environment/configs/setup.toml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,19 @@ local_image = "job-distributor:0.22.1"
1212

1313
[job_distributor.pull_config]
1414
local_image = "job-distributor:0.22.1"
15-
ecr_image = "{{.ECR}}/job-distributor:0.22.1"
15+
ecr_image = "{{.MAIN_ECR}}/job-distributor:0.22.1"
16+
17+
[chip_router.build_config]
18+
repository = "https://github.com/smartcontractkit/chainlink-testing-framework"
19+
branch = "main"
20+
commit = "dd420c0d953334e3fef9a109b6816de706f6be90"
21+
dockerfile = "framework/components/chiprouter/Dockerfile"
22+
docker_ctx = "framework/components/chiprouter"
23+
local_image = "local-cre-chip-router:v1.0.1"
24+
25+
[chip_router.pull_config]
26+
local_image = "local-cre-chip-router:v1.0.1"
27+
ecr_image = "{{.SDLC_ECR}}/local-cre-chip-router:v1.0.1"
1628

1729
[chip_ingress.build_config]
1830
repository = "https://github.com/smartcontractkit/atlas"
@@ -25,7 +37,7 @@ pre_run = "pushd chip-ingress && go mod vendor && popd"
2537

2638
[chip_ingress.pull_config]
2739
local_image = "chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f"
28-
ecr_image = "{{.ECR}}/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f"
40+
ecr_image = "{{.MAIN_ECR}}/atlas-chip-ingress:da84cb72d3a160e02896247d46ab4b9806ebee2f"
2941

3042
[chip_config.build_config]
3143
repository = "https://github.com/smartcontractkit/atlas"
@@ -38,7 +50,7 @@ pre_run = "pushd chip-config && go mod vendor && popd"
3850

3951
[chip_config.pull_config]
4052
local_image = "chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969"
41-
ecr_image = "{{.ECR}}/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969"
53+
ecr_image = "{{.MAIN_ECR}}/atlas-chip-config:7b4e9ee68fd1c737dd3480b5a3ced0188f29b969"
4254

4355
[billing_platform_service.build_config]
4456
repository = "https://github.com/smartcontractkit/billing-platform-service"
@@ -50,7 +62,7 @@ local_image = "billing-platform-service:local-cre"
5062

5163
[billing_platform_service.pull_config]
5264
local_image = "billing-platform-service:local-cre"
53-
ecr_image = "{{.ECR}}/billing-platform-service:1.36.1"
65+
ecr_image = "{{.MAIN_ECR}}/billing-platform-service:1.36.1"
5466

5567
[observability]
5668
repository = "https://github.com/smartcontractkit/chainlink-observability"

core/scripts/cre/environment/configs/workflow-don-solana.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11

2+
[chip_router]
3+
image = "local-cre-chip-router:v1.0.1"
4+
25
[[blockchains]]
36
type = "anvil"
47
chain_id = "1337"

0 commit comments

Comments
 (0)