diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db0616c18..70d4bbbcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -143,6 +143,9 @@ jobs: echo "GOMEMLIMIT=6GiB" >> "$GITHUB_ENV" echo "GOGC=80" >> "$GITHUB_ENV" + - name: Spinup eigenda-proxy test dependency + run: ./scripts/start-eigenda-proxy.sh + - name: run tests without race detection if: matrix.test-mode == 'defaults' run: | diff --git a/contracts b/contracts index eaa0aef42..13f4041ab 160000 --- a/contracts +++ b/contracts @@ -1 +1 @@ -Subproject commit eaa0aef42c5ef5e590025321c7d6c07a109dec67 +Subproject commit 13f4041ab59f697bd04aaadb3692b8ca8da2cbe1 diff --git a/deploy/deploy.go b/deploy/deploy.go index 358f44d52..bf17507ce 100644 --- a/deploy/deploy.go +++ b/deploy/deploy.go @@ -245,7 +245,7 @@ func DeployOnL1(ctx context.Context, parentChainReader *headerreader.HeaderReade if eigenDARollupManager == (common.Address{0x0}) { log.Warn("No EigenDA Rollup Manager contract address specified, deploying dummy rollup manager instead") - dummyRollupManager, tx, _, err := bridgegen.DeployEigenDADummyManager(deployAuth, parentChainReader.Client()) + dummyRollupManager, tx, _, err := bridgegen.DeployEigenDABlobVerifierL2(deployAuth, parentChainReader.Client()) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { return nil, fmt.Errorf("dummy manager deploy error: %w", err) diff --git a/scripts/start-eigenda-proxy.sh b/scripts/start-eigenda-proxy.sh new file mode 100755 index 000000000..0a921a04a --- /dev/null +++ b/scripts/start-eigenda-proxy.sh @@ -0,0 +1,19 @@ +echo "Pull eigenda-proxy container" +docker pull ghcr.io/layr-labs/eigenda-proxy@sha256:10a4762f5c43e9037835617e6ec0b03da34012df87048a363f43b969ab93679b + +echo "Tagging image" +docker tag ghcr.io/layr-labs/eigenda-proxy@sha256:10a4762f5c43e9037835617e6ec0b03da34012df87048a363f43b969ab93679b eigenda-proxy-nitro-test + +echo "Start eigenda-proxy container" + +docker run -d --name eigenda-proxy-nitro-test \ + -p 4242:6666 \ + -e EIGENDA_PROXY_ADDR=0.0.0.0 \ + -e EIGENDA_PROXY_PORT=6666 \ + -e MEMSTORE_ENABLED=true \ + -e MEMSTORE_EXPIRATION=1m \ + -e EIGENDA_PROXY_TARGET_URL=http://localhost:3000 \ + eigenda-proxy-nitro-test + +## TODO - support teardown or embed a docker client wrapper that spins up and tears down resource +# within system tests. Since this is only used by one system test, it's not a large priority atm. \ No newline at end of file diff --git a/system_tests/eigenda_test.go b/system_tests/eigenda_test.go new file mode 100644 index 000000000..266d1c55a --- /dev/null +++ b/system_tests/eigenda_test.go @@ -0,0 +1,109 @@ +// Copyright 2021-2022, Offchain Labs, Inc. +// For license information, see https://github.com/nitro/blob/master/LICENSE + +package arbtest + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/params" + + "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/execution/gethexec" +) + +const ( + proxyURL = "http://127.0.0.1:4242" +) + +func TestEigenDAProxyBatchPosting(t *testing.T) { + + initTest(t) + + ctx, cancel := context.WithCancel(context.Background()) + defer func() { + cancel() + }() + + // Setup L1 chain and contracts + chainConfig := params.ArbitrumDevTestEigenDAConfig() + l1info, l1client, _, l1stack := createTestL1BlockChain(t, nil) + defer requireClose(t, l1stack) + feedErrChan := make(chan error, 10) + addresses, initMessage := DeployOnTestL1(t, ctx, l1info, l1client, chainConfig) + + nodeDir := t.TempDir() + l2info := NewArbTestInfo(t, chainConfig.ChainID) + l1NodeConfigA := arbnode.ConfigDefaultL1Test() + l1NodeConfigB := arbnode.ConfigDefaultL1NonSequencerTest() + sequencerTxOpts := l1info.GetDefaultTransactOpts("Sequencer", ctx) + sequencerTxOptsPtr := &sequencerTxOpts + parentChainID := big.NewInt(1337) + { + + // Setup L2 chain + _, l2stackA, l2chainDb, l2arbDb, l2blockchain := createL2BlockChainWithStackConfig(t, l2info, nodeDir, chainConfig, initMessage, nil, nil) + l2info.GenerateAccount("User2") + + // Setup EigenDA config + l1NodeConfigA.EigenDA.Enable = true + l1NodeConfigA.EigenDA.Rpc = proxyURL + + execA, err := gethexec.CreateExecutionNode(ctx, l2stackA, l2chainDb, l2blockchain, l1client, gethexec.ConfigDefaultTest) + Require(t, err) + + l2Cfg := l2blockchain.Config() + l2Cfg.ArbitrumChainParams.DataAvailabilityCommittee = false + l2Cfg.ArbitrumChainParams.EigenDA = true + nodeA, err := arbnode.CreateNode(ctx, l2stackA, execA, l2arbDb, NewFetcherFromConfig(l1NodeConfigA), l2Cfg, l1client, addresses, sequencerTxOptsPtr, sequencerTxOptsPtr, nil, feedErrChan, parentChainID, nil) + Require(t, err) + Require(t, nodeA.Start(ctx)) + l2clientA := ClientForStack(t, l2stackA) + + l1NodeConfigB.BlockValidator.Enable = false + l1NodeConfigB.EigenDA.Enable = true + l1NodeConfigB.EigenDA.Rpc = proxyURL + + l2clientB, nodeB := Create2ndNodeWithConfig(t, ctx, nodeA, l1stack, l1info, &l2info.ArbInitData, l1NodeConfigB, nil, nil) + checkEigenDABatchPosting(t, ctx, l1client, l2clientA, l1info, l2info, big.NewInt(1e12), l2clientB) + nodeA.StopAndWait() + nodeB.StopAndWait() + } +} + +func checkEigenDABatchPosting(t *testing.T, ctx context.Context, l1client, l2clientA *ethclient.Client, l1info, l2info info, expectedBalance *big.Int, l2ClientsToCheck ...*ethclient.Client) { + tx := l2info.PrepareTx("Owner", "User2", l2info.TransferGas, big.NewInt(1e12), nil) + err := l2clientA.SendTransaction(ctx, tx) + Require(t, err) + + _, err = EnsureTxSucceeded(ctx, l2clientA, tx) + Require(t, err) + + // give the inbox reader a bit of time to pick up the delayed message + time.Sleep(time.Millisecond * 100) + + // sending l1 messages creates l1 blocks.. make enough to get that delayed inbox message in + for i := 0; i < 100; i++ { + SendWaitTestTransactions(t, ctx, l1client, []*types.Transaction{ + l1info.PrepareTx("Faucet", "User", 30000, big.NewInt(1e12), nil), + }) + } + + for _, client := range l2ClientsToCheck { + _, err = WaitForTx(ctx, client, tx.Hash(), time.Second*100) + Require(t, err) + + l2balance, err := client.BalanceAt(ctx, l2info.GetAddress("User2"), nil) + Require(t, err) + + if l2balance.Cmp(expectedBalance) != 0 { + Fatal(t, "Unexpected balance:", l2balance) + } + + } +}