From edd21dead7ee9d089d181156a39c2268722579bc Mon Sep 17 00:00:00 2001 From: Ino Murko Date: Fri, 27 Jan 2023 18:21:27 +0100 Subject: [PATCH] Release/v0.4.1 (#544) * feat: deploy entrypoint (#508) * feat: deploy entrypoint * update depl * register on AM * deploy bundler helper * fix: src/runop * fix: integ tests * use dockerfile packages * add solc * move aa_deployer to docker-compose side * add paymaster deploy scripts (cherry picked from commit 9be4fc0145aa8e539d63fa6faa4d75f7a72fbf8d) * patch proxyd validId (#543) * patch proxyd validId * patch proxyd validId patch proxyd validId (cherry picked from commit aa4a7fd1bd1766cd3a1f7bfc0cbd5824d2bd7d0e) --------- Co-authored-by: Souradeep Das --- .circleci/config.yml | 4 +- .../integration_tests/validation_test.go | 208 +++++++++--------- go/proxyd/rpc.go | 7 +- ops/docker-compose-side.yml | 30 +++ ops/docker-compose.yml | 2 +- ops/docker/Dockerfile.aa_deployer | 38 ++++ ops/docker/Dockerfile.packages | 13 ++ .../boba/account-abstraction/.env.example | 6 + .../boba/account-abstraction/bin/deploy.ts | 72 ++++++ .../contracts/bundler/BundlerHelper.sol | 31 +++ .../deploy/1-deploy-helper.ts | 82 +++++++ .../deploy/2-deploy_entrypoint.ts | 38 ++++ .../deploy/3-deploy-deposit-paymaster.ts | 26 +++ .../deploy/4-deploy-verifying-paymaster.ts | 32 +++ .../deploy/5-dump-addresses.ts | 35 +++ .../deploy/deploy_entrypoint.ts | 38 ---- .../account-abstraction/hardhat.config.ts | 68 +++--- .../boba/account-abstraction/package.json | 8 +- .../account-abstraction/scripts/deployer.sh | 22 ++ .../scripts/wait-for-l1-and-l2.sh | 77 +++++++ .../boba/account-abstraction/src/runop.ts | 16 +- .../boba/account-abstraction/tasks/deploy.ts | 17 ++ .../boba/account-abstraction/tsconfig.json | 34 +-- .../src/services/main/service.ts | 38 ++++ yarn.lock | 22 +- 25 files changed, 738 insertions(+), 226 deletions(-) create mode 100644 ops/docker/Dockerfile.aa_deployer create mode 100644 packages/boba/account-abstraction/.env.example create mode 100644 packages/boba/account-abstraction/bin/deploy.ts create mode 100644 packages/boba/account-abstraction/contracts/bundler/BundlerHelper.sol create mode 100644 packages/boba/account-abstraction/deploy/1-deploy-helper.ts create mode 100644 packages/boba/account-abstraction/deploy/2-deploy_entrypoint.ts create mode 100644 packages/boba/account-abstraction/deploy/3-deploy-deposit-paymaster.ts create mode 100644 packages/boba/account-abstraction/deploy/4-deploy-verifying-paymaster.ts create mode 100644 packages/boba/account-abstraction/deploy/5-dump-addresses.ts delete mode 100644 packages/boba/account-abstraction/deploy/deploy_entrypoint.ts create mode 100644 packages/boba/account-abstraction/scripts/deployer.sh create mode 100644 packages/boba/account-abstraction/scripts/wait-for-l1-and-l2.sh create mode 100644 packages/boba/account-abstraction/tasks/deploy.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index 9802b1da60..8a4ac0d23f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -193,7 +193,7 @@ jobs: name: Build everything command: | docker-compose build --progress=plain - docker-compose -f docker-compose.yml -f docker-compose-side.yml build bobalink + docker-compose -f docker-compose.yml -f docker-compose-side.yml build bobalink aa_deployer working_directory: ops - run: name: Bring up the stack @@ -204,7 +204,7 @@ jobs: - run: name: Bring up services command: | - docker-compose -f docker-compose.yml -f docker-compose-side.yml up -d bobalink + docker-compose -f docker-compose.yml -f docker-compose-side.yml up -d bobalink aa_deployer working_directory: ops - run: name: Start background logging diff --git a/go/proxyd/integration_tests/validation_test.go b/go/proxyd/integration_tests/validation_test.go index 6f0653df2c..442ecaab9c 100644 --- a/go/proxyd/integration_tests/validation_test.go +++ b/go/proxyd/integration_tests/validation_test.go @@ -13,94 +13,94 @@ const ( notWhitelistedResponse = `{"jsonrpc":"2.0","error":{"code":-32001,"message":"rpc method is not whitelisted custom message"},"id":999}` parseErrResponse = `{"jsonrpc":"2.0","error":{"code":-32700,"message":"parse error"},"id":null}` invalidJSONRPCVersionResponse = `{"error":{"code":-32601,"message":"invalid JSON-RPC version"},"id":null,"jsonrpc":"2.0"}` - invalidIDResponse = `{"error":{"code":-32601,"message":"invalid ID"},"id":null,"jsonrpc":"2.0"}` - invalidMethodResponse = `{"error":{"code":-32601,"message":"no method specified"},"id":null,"jsonrpc":"2.0"}` - invalidBatchLenResponse = `{"error":{"code":-32601,"message":"must specify at least one batch call"},"id":null,"jsonrpc":"2.0"}` + //invalidIDResponse = `{"error":{"code":-32601,"message":"invalid ID"},"id":null,"jsonrpc":"2.0"}` + invalidMethodResponse = `{"error":{"code":-32601,"message":"no method specified"},"id":null,"jsonrpc":"2.0"}` + invalidBatchLenResponse = `{"error":{"code":-32601,"message":"must specify at least one batch call"},"id":null,"jsonrpc":"2.0"}` ) -func TestSingleRPCValidation(t *testing.T) { - goodBackend := NewMockBackend(BatchedResponseHandler(200, goodResponse)) - defer goodBackend.Close() +// func TestSingleRPCValidation(t *testing.T) { +// goodBackend := NewMockBackend(BatchedResponseHandler(200, goodResponse)) +// defer goodBackend.Close() - require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", goodBackend.URL())) +// require.NoError(t, os.Setenv("GOOD_BACKEND_RPC_URL", goodBackend.URL())) - config := ReadConfig("whitelist") - client := NewProxydClient("http://127.0.0.1:8545") - shutdown, err := proxyd.Start(config) - require.NoError(t, err) - defer shutdown() +// config := ReadConfig("whitelist") +// client := NewProxydClient("http://127.0.0.1:8545") +// shutdown, err := proxyd.Start(config) +// require.NoError(t, err) +// defer shutdown() - tests := []struct { - name string - body string - res string - code int - }{ - { - "body not JSON", - "this ain't an RPC call", - parseErrResponse, - 400, - }, - { - "body not RPC", - "{\"not\": \"rpc\"}", - invalidJSONRPCVersionResponse, - 400, - }, - { - "body missing RPC ID", - "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23]}", - invalidIDResponse, - 400, - }, - { - "body has array ID", - "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": []}", - invalidIDResponse, - 400, - }, - { - "body has object ID", - "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": {}}", - invalidIDResponse, - 400, - }, - { - "bad method", - "{\"jsonrpc\": \"2.0\", \"method\": 7, \"params\": [42, 23], \"id\": 1}", - parseErrResponse, - 400, - }, - { - "bad JSON-RPC", - "{\"jsonrpc\": \"1.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": 1}", - invalidJSONRPCVersionResponse, - 400, - }, - { - "omitted method", - "{\"jsonrpc\": \"2.0\", \"params\": [42, 23], \"id\": 1}", - invalidMethodResponse, - 400, - }, - { - "not whitelisted method", - "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": 999}", - notWhitelistedResponse, - 403, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - res, code, err := client.SendRequest([]byte(tt.body)) - require.NoError(t, err) - RequireEqualJSON(t, []byte(tt.res), res) - require.Equal(t, tt.code, code) - require.Equal(t, 0, len(goodBackend.Requests())) - }) - } -} +// tests := []struct { +// name string +// body string +// res string +// code int +// }{ +// { +// "body not JSON", +// "this ain't an RPC call", +// parseErrResponse, +// 400, +// }, +// { +// "body not RPC", +// "{\"not\": \"rpc\"}", +// invalidJSONRPCVersionResponse, +// 400, +// }, +// // { +// // "body missing RPC ID", +// // "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23]}", +// // invalidIDResponse, +// // 400, +// // }, +// { +// "body has array ID", +// "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": []}", +// invalidIDResponse, +// 400, +// }, +// { +// "body has object ID", +// "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": {}}", +// invalidIDResponse, +// 400, +// }, +// { +// "bad method", +// "{\"jsonrpc\": \"2.0\", \"method\": 7, \"params\": [42, 23], \"id\": 1}", +// parseErrResponse, +// 400, +// }, +// { +// "bad JSON-RPC", +// "{\"jsonrpc\": \"1.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": 1}", +// invalidJSONRPCVersionResponse, +// 400, +// }, +// { +// "omitted method", +// "{\"jsonrpc\": \"2.0\", \"params\": [42, 23], \"id\": 1}", +// invalidMethodResponse, +// 400, +// }, +// { +// "not whitelisted method", +// "{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": 999}", +// notWhitelistedResponse, +// 403, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// res, code, err := client.SendRequest([]byte(tt.body)) +// require.NoError(t, err) +// RequireEqualJSON(t, []byte(tt.res), res) +// require.Equal(t, tt.code, code) +// require.Equal(t, 0, len(goodBackend.Requests())) +// }) +// } +// } func TestBatchRPCValidation(t *testing.T) { goodBackend := NewMockBackend(BatchedResponseHandler(200, goodResponse)) @@ -149,27 +149,27 @@ func TestBatchRPCValidation(t *testing.T) { 200, 0, }, - { - "body missing RPC ID", - "[{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23]}]", - asArray(invalidIDResponse), - 200, - 0, - }, - { - "body has array ID", - "[{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": []}]", - asArray(invalidIDResponse), - 200, - 0, - }, - { - "body has object ID", - "[{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": {}}]", - asArray(invalidIDResponse), - 200, - 0, - }, + // { + // "body missing RPC ID", + // "[{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23]}]", + // asArray(invalidIDResponse), + // 200, + // 0, + // }, + // { + // "body has array ID", + // "[{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": []}]", + // asArray(invalidIDResponse), + // 200, + // 0, + // }, + // { + // "body has object ID", + // "[{\"jsonrpc\": \"2.0\", \"method\": \"subtract\", \"params\": [42, 23], \"id\": {}}]", + // asArray(invalidIDResponse), + // 200, + // 0, + // }, // this happens because we can't deserialize the method into a non // string value, and it blows up the parsing for the whole request. { diff --git a/go/proxyd/rpc.go b/go/proxyd/rpc.go index 0c30d6439d..e8cee18d60 100644 --- a/go/proxyd/rpc.go +++ b/go/proxyd/rpc.go @@ -125,9 +125,10 @@ func ValidateRPCReq(req *RPCReq) error { return ErrInvalidRequest("no method specified") } - if !IsValidID(req.ID) { - return ErrInvalidRequest("invalid ID") - } + // cosmic universe + // if !IsValidID(req.ID) { + // return ErrInvalidRequest("invalid ID") + // } return nil } diff --git a/ops/docker-compose-side.yml b/ops/docker-compose-side.yml index 581ed274a8..18160bfe5a 100644 --- a/ops/docker-compose-side.yml +++ b/ops/docker-compose-side.yml @@ -1,5 +1,9 @@ version: "3" +# Account #0 +x-deployer_pk: &deployer_pk + DEPLOYER_PRIVATE_KEY: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' + # Account #6 - bobalink test x-bobalink_pk: &bobalink_pk BOBALINK_REPORTER_KEY: '0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e' @@ -85,6 +89,32 @@ services: BOBA_URL: http://dtl:8081/boba-addr.json POLLING_INTERVAL: 1000 + # deploys account abstraction contracts and serves contract addresses + aa_deployer: + depends_on: + - l1_chain + - dtl + - l2geth + - boba_deployer + image: bobanetwork/aa_deployer:latest + build: + context: .. + dockerfile: ./ops/docker/Dockerfile.packages + target: aa_deployer + environment: + L1_NODE_WEB3_URL: http://l1_chain:8545 + L2_NODE_WEB3_URL: http://l2geth:8545 + ADDRESS_MANAGER_ADDRESS: "0x5FbDB2315678afecb367f032d93F642f64180aa3" + URL: http://dtl:8081/addresses.json + BOBA_URL: http://dtl:8081/boba-addr.json + # DO NOT use in production + << : *deployer_pk + RETRIES: 200 + DTL_REGISTRY_URL: http://dtl:8081/aa-addr.json + # skip compilation when run in docker-compose, since the contracts + # were already compiled in the builder step + NO_COMPILE: 1 + proxyd: image: bobanetwork/proxyd:latest build: diff --git a/ops/docker-compose.yml b/ops/docker-compose.yml index 22b176de7b..210285278b 100644 --- a/ops/docker-compose.yml +++ b/ops/docker-compose.yml @@ -439,4 +439,4 @@ services: source: ./seed.yaml target: /init/seed.yaml ports: - - 8888:8888 + - 8888:8888 \ No newline at end of file diff --git a/ops/docker/Dockerfile.aa_deployer b/ops/docker/Dockerfile.aa_deployer new file mode 100644 index 0000000000..ddb8ce4ac7 --- /dev/null +++ b/ops/docker/Dockerfile.aa_deployer @@ -0,0 +1,38 @@ +FROM bobanetwork/builder AS builder +FROM node:14-alpine + +RUN apk add --no-cache git curl bash jq +WORKDIR /opt/optimism/ + +COPY --from=builder /optimism/*.json /optimism/yarn.lock ./ +COPY --from=builder /optimism/node_modules ./node_modules + +WORKDIR /opt/optimism/packages/contracts +COPY --from=builder /optimism/packages/contracts/dist ./dist +COPY --from=builder /optimism/packages/contracts/*.json ./ +COPY --from=builder /optimism/packages/contracts/node_modules ./node_modules +COPY --from=builder /optimism/packages/contracts/artifacts ./artifacts +COPY --from=builder /optimism/packages/contracts/deployments ./deployments + +# get the built artifacts +WORKDIR /opt/optimism/packages/boba/account-abstraction +COPY --from=builder /optimism/packages/boba/account-abstraction/tsconfig.json ./tsconfig.json +COPY --from=builder /optimism/packages/boba/account-abstraction/package.json ./package.json +COPY --from=builder /optimism/packages/boba/account-abstraction/node_modules ./node_modules +COPY --from=builder /optimism/packages/boba/account-abstraction/artifacts ./artifacts + +# Copy solc compilers + +# get static artifacts from the host +COPY packages/boba/account-abstraction/bin ./bin +COPY packages/boba/account-abstraction/contracts ./contracts +COPY packages/boba/account-abstraction/hardhat.config.ts ./ +COPY packages/boba/account-abstraction/deploy ./deploy +COPY packages/boba/account-abstraction/scripts ./scripts +COPY packages/boba/account-abstraction/tasks ./tasks + + +RUN chmod +x ./scripts/wait-for-l1-and-l2.sh +RUN chmod +x ./scripts/deployer.sh + +ENTRYPOINT ["./scripts/wait-for-l1-and-l2.sh", "./scripts/deployer.sh"] \ No newline at end of file diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index 9179946ab8..2f8cb7c869 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -13,6 +13,8 @@ ADD ${SOLC_PREFIX}solc-linux-amd64-v0.5.17+commit.d19bba13 ./solc-v0.5.17+commit ADD ${SOLC_PREFIX}solc-linux-amd64-v0.6.6+commit.6c089d02 ./solc-v0.6.6+commit.6c089d02 ADD ${SOLC_PREFIX}solc-linux-amd64-v0.8.9+commit.e5eed63a ./solc-v0.8.9+commit.e5eed63a ADD ${SOLC_PREFIX}solc-linux-amd64-v0.8.11+commit.d7f03943 ./solc-v0.8.11+commit.d7f03943 +ADD ${SOLC_PREFIX}solc-linux-amd64-v0.8.15+commit.e14f2714 ./solc-v0.8.15+commit.e14f2714 +ADD ${SOLC_PREFIX}solc-linux-amd64-v0.8.17+commit.8df45f5f ./solc-v0.8.17+commit.8df45f5f FROM node:16-buster-slim as base @@ -56,6 +58,7 @@ COPY packages/boba/turing/package.json ./packages/boba/turing/package.json COPY packages/boba/ve-boba/package.json ./packages/boba/ve-boba/package.json COPY packages/boba/bobalink/package.json ./packages/boba/bobalink/package.json COPY packages/boba/teleportation/package.json ./packages/boba/teleportation/package.json +COPY packages/boba/account-abstraction/package.json ./packages/boba/account-abstraction/package.json FROM base as builder WORKDIR /opt/optimism @@ -76,6 +79,8 @@ COPY --from=downloader solc-v0.5.17+commit.d19bba13 /root/.cache/hardhat-nodejs/ COPY --from=downloader solc-v0.6.6+commit.6c089d02 /root/.cache/hardhat-nodejs/compilers-v2/linux-amd64/solc-linux-amd64-v0.6.6+commit.6c089d02 COPY --from=downloader solc-v0.8.9+commit.e5eed63a /root/.cache/hardhat-nodejs/compilers-v2/linux-amd64/solc-linux-amd64-v0.8.9+commit.e5eed63a COPY --from=downloader solc-v0.8.11+commit.d7f03943 /root/.cache/hardhat-nodejs/compilers-v2/linux-amd64/solc-linux-amd64-v0.8.11+commit.d7f03943 +COPY --from=downloader solc-v0.8.15+commit.e14f2714 /root/.cache/hardhat-nodejs/compilers-v2/linux-amd64/solc-linux-amd64-v0.8.15+commit.e14f2714 +COPY --from=downloader solc-v0.8.17+commit.8df45f5f /root/.cache/hardhat-nodejs/compilers-v2/linux-amd64/solc-linux-amd64-v0.8.17+commit.8df45f5f RUN chmod +x /root/.cache/hardhat-nodejs/compilers-v2/linux-amd64/* @@ -155,3 +160,11 @@ WORKDIR /opt/optimism/packages/boba COPY --from=builder /opt/optimism/packages/boba/teleportation ./teleportation WORKDIR /opt/optimism/packages/boba/teleportation CMD ["npm", "run", "start"] + +FROM packages as aa_deployer +WORKDIR /opt/optimism/packages/boba +COPY --from=builder /opt/optimism/packages/boba/account-abstraction ./account-abstraction +WORKDIR /opt/optimism/packages/boba/account-abstraction +RUN chmod +x ./scripts/wait-for-l1-and-l2.sh +RUN chmod +x ./scripts/deployer.sh +ENTRYPOINT ["./scripts/wait-for-l1-and-l2.sh", "./scripts/deployer.sh"] diff --git a/packages/boba/account-abstraction/.env.example b/packages/boba/account-abstraction/.env.example new file mode 100644 index 0000000000..73f061d31c --- /dev/null +++ b/packages/boba/account-abstraction/.env.example @@ -0,0 +1,6 @@ +L1_NODE_WEB3_URL=http://localhost:9545 +L2_NODE_WEB3_URL=http://localhost:8545 +ADDRESS_MANAGER_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 +DEPLOYER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +URL=http://localhost:8080 +BOBA_URL=http://localhost:8078/addresses.json \ No newline at end of file diff --git a/packages/boba/account-abstraction/bin/deploy.ts b/packages/boba/account-abstraction/bin/deploy.ts new file mode 100644 index 0000000000..4b57636826 --- /dev/null +++ b/packages/boba/account-abstraction/bin/deploy.ts @@ -0,0 +1,72 @@ +import { Wallet, providers } from 'ethers' +import { getContractFactory } from '@eth-optimism/contracts' + +/* eslint-disable */ +require('dotenv').config() + +import hre from 'hardhat' + +const main = async () => { + console.log('Starting BOBA AA contracts deployment...') + + const network = process.env.NETWORK || 'local' + + const l1Provider = new providers.JsonRpcProvider(process.env.L1_NODE_WEB3_URL) + const l2Provider = new providers.JsonRpcProvider(process.env.L2_NODE_WEB3_URL) + + const deployer_l1 = new Wallet(process.env.DEPLOYER_PRIVATE_KEY, l1Provider) + const deployer_l2 = new Wallet(process.env.DEPLOYER_PRIVATE_KEY, l2Provider) + + const getAddressManager = (provider: any, addressManagerAddress: any) => { + return getContractFactory('Lib_AddressManager') + .connect(provider) + .attach(addressManagerAddress) as any + } + + console.log( + `ADDRESS_MANAGER_ADDRESS was set to ${process.env.ADDRESS_MANAGER_ADDRESS}` + ) + const addressManager = getAddressManager( + deployer_l1, + process.env.ADDRESS_MANAGER_ADDRESS + ) + + const l1MessengerAddress = await addressManager.getAddress( + 'Proxy__L1CrossDomainMessenger' + ) + const l2MessengerAddress = await addressManager.getAddress( + 'L2CrossDomainMessenger' + ) + + const L1StandardBridgeAddress = await addressManager.getAddress( + 'Proxy__L1StandardBridge' + ) + const L1StandardBridge = getContractFactory('L1StandardBridge') + .connect(deployer_l1) + .attach(L1StandardBridgeAddress) + + const L2StandardBridgeAddress = await L1StandardBridge.l2TokenBridge() + + await hre.run('deploy', { + l1MessengerAddress, + l2MessengerAddress, + L1StandardBridgeAddress, + L2StandardBridgeAddress, + l1Provider, + l2Provider, + deployer_l1, + deployer_l2, + addressManager, + network, + noCompile: process.env.NO_COMPILE ? true : false, + }) +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.log( + JSON.stringify({ error: error.message, stack: error.stack }, null, 2) + ) + process.exit(1) + }) diff --git a/packages/boba/account-abstraction/contracts/bundler/BundlerHelper.sol b/packages/boba/account-abstraction/contracts/bundler/BundlerHelper.sol new file mode 100644 index 0000000000..b6f9fb59e2 --- /dev/null +++ b/packages/boba/account-abstraction/contracts/bundler/BundlerHelper.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.15; + +import "../core/EntryPoint.sol"; +import "solidity-string-utils/StringUtils.sol"; + +contract BundlerHelper { + using StringUtils for *; + + /** + * run handleop. require to get refund for the used gas. + */ + function handleOps(uint expectedPaymentGas, EntryPoint ep, UserOperation[] calldata ops, address payable beneficiary) + public returns (uint paid, uint gasPrice, bytes memory errorReason){ + gasPrice = tx.gasprice; + uint expectedPayment = expectedPaymentGas * gasPrice; + uint preBalance = beneficiary.balance; + try ep.handleOps(ops, beneficiary) { + } catch (bytes memory err) { + errorReason = err; + } + paid = beneficiary.balance - preBalance; + if (paid < expectedPayment) { + revert(string.concat( + "didn't pay enough: paid ", paid.toString(), + " expected ", expectedPayment.toString(), + " gasPrice ", gasPrice.toString() + )); + } + } +} diff --git a/packages/boba/account-abstraction/deploy/1-deploy-helper.ts b/packages/boba/account-abstraction/deploy/1-deploy-helper.ts new file mode 100644 index 0000000000..8030d0fa80 --- /dev/null +++ b/packages/boba/account-abstraction/deploy/1-deploy-helper.ts @@ -0,0 +1,82 @@ +import { DeployFunction } from 'hardhat-deploy/types' +import { ethers } from 'hardhat' + +const sleep = async (ms: number): Promise => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(null) + }, ms) + }) + } + + const hexStringEquals = (stringA: string, stringB: string): boolean => { + if (!ethers.utils.isHexString(stringA)) { + throw new Error(`input is not a hex string: ${stringA}`) + } + + if (!ethers.utils.isHexString(stringB)) { + throw new Error(`input is not a hex string: ${stringB}`) + } + + return stringA.toLowerCase() === stringB.toLowerCase() + } + + const waitUntilTrue = async ( + check: () => Promise, + opts: { + retries?: number + delay?: number + } = {} + ) => { + opts.retries = opts.retries || 100 + opts.delay = opts.delay || 5000 + + let retries = 0 + while (!(await check())) { + if (retries > opts.retries) { + throw new Error(`check failed after ${opts.retries} attempts`) + } + retries++ + await sleep(opts.delay) + } + } + + export const registerBobaAddress = async ( + addressManager: any, + name: string, + address: string + ): Promise => { + + console.log("AddressManager address:",addressManager.address) + + const currentAddress = await addressManager.getAddress(name) + if (address === currentAddress) { + console.log( + `✓ Not registering address for ${name} because it's already been correctly registered` + ) + return + } + + console.log(`Registering address for ${name} to ${address}...`) + await addressManager.setAddress(name, address) + + console.log(`Waiting for registration to reflect on-chain...`) + await waitUntilTrue(async () => { + return hexStringEquals(await addressManager.getAddress(name), address) + }) + + console.log(`✓ Registered address for ${name}`) + } + +const deployFn: DeployFunction = async (hre) => { + const BundlerHelper = await hre.deployments.deploy('BundlerHelper', { + from: (hre as any).deployConfig.deployer_l2.address, + args: [], + log: true, + deterministicDeployment: true + }) + await registerBobaAddress( (hre as any).deployConfig.addressManager, 'Boba_BundlerHelper', BundlerHelper.address ) +} + +export default deployFn +deployFn.tags = ['BundlerHelper'] diff --git a/packages/boba/account-abstraction/deploy/2-deploy_entrypoint.ts b/packages/boba/account-abstraction/deploy/2-deploy_entrypoint.ts new file mode 100644 index 0000000000..b99793f075 --- /dev/null +++ b/packages/boba/account-abstraction/deploy/2-deploy_entrypoint.ts @@ -0,0 +1,38 @@ +import { DeployFunction } from 'hardhat-deploy/types' +import { ethers } from 'hardhat' +import { registerBobaAddress } from './1-deploy-helper' + +// const UNSTAKE_DELAY_SEC = 100 +// const PAYMASTER_STAKE = ethers.utils.parseEther('1') + +// deploy entrypoint - but only on debug network.. +const deployFn: DeployFunction = async (hre) => { + // first verify if already deployed: + try { + await hre.deployments.deploy( + 'EntryPoint', { + from: ethers.constants.AddressZero, + args: [], + deterministicDeployment: true, + log: true + }) + + // already deployed. do nothing. + return + } catch (e) { + } + + const EntryPoint = await hre.deployments.deploy( + 'EntryPoint', { + from: (hre as any).deployConfig.deployer_l2.address, + args: [], + gasLimit: 4e6, + deterministicDeployment: true, + log: true + }) + + await registerBobaAddress( (hre as any).deployConfig.addressManager, 'Boba_EntryPoint', EntryPoint.address ) +} + +export default deployFn +deployFn.tags = ['EntryPoint'] diff --git a/packages/boba/account-abstraction/deploy/3-deploy-deposit-paymaster.ts b/packages/boba/account-abstraction/deploy/3-deploy-deposit-paymaster.ts new file mode 100644 index 0000000000..1bc24e67b5 --- /dev/null +++ b/packages/boba/account-abstraction/deploy/3-deploy-deposit-paymaster.ts @@ -0,0 +1,26 @@ +import { DeployFunction } from 'hardhat-deploy/types' +import { ethers } from 'hardhat' +import { registerBobaAddress } from './1-deploy-helper' + +const deployFn: DeployFunction = async (hre) => { + const entryPoint = await hre.deployments.getOrNull('EntryPoint') + console.log(`EntryPoint is located at: ${entryPoint.address}`) + const ethPriceOracle = await (hre as any).deployConfig.addressManager.getAddress('FeedRegistry') + console.log(`Eth Price Oracle is located at: ${ethPriceOracle}`) + const entryPointFromAM = await (hre as any).deployConfig.addressManager.getAddress('Boba_EntryPoint') + if (entryPoint.address == entryPointFromAM) { + const BobaDepositPaymaster = await hre.deployments.deploy( + 'BobaDepositPaymaster', { + from: (hre as any).deployConfig.deployer_l2.address, + args: [entryPoint.address, ethPriceOracle], + gasLimit: 4e6, + deterministicDeployment: false, + log: true + }) + + await registerBobaAddress( (hre as any).deployConfig.addressManager, 'BobaDepositPaymaster', BobaDepositPaymaster.address ) + } +} + +export default deployFn +deployFn.tags = ['BobaDepositPaymaster'] diff --git a/packages/boba/account-abstraction/deploy/4-deploy-verifying-paymaster.ts b/packages/boba/account-abstraction/deploy/4-deploy-verifying-paymaster.ts new file mode 100644 index 0000000000..e0454af337 --- /dev/null +++ b/packages/boba/account-abstraction/deploy/4-deploy-verifying-paymaster.ts @@ -0,0 +1,32 @@ +import { DeployFunction } from 'hardhat-deploy/types' +import { ethers } from 'hardhat' +import { registerBobaAddress } from './1-deploy-helper' + +const deployFn: DeployFunction = async (hre) => { + // use the sig verifying address + const verifyingSignerAddress = (hre as any).deployConfig.deployer_l2.address + console.log(`Verifying Signer is: ${verifyingSignerAddress}`) + + const entryPoint = await hre.deployments.getOrNull('EntryPoint') + console.log(`EntryPoint is located at: ${entryPoint.address}`) + const bobaDepositPaymaster = await hre.deployments.getOrNull('BobaDepositPaymaster') + console.log(`BobaDepositPaymaster is located at: ${bobaDepositPaymaster.address}`) + const bobaToken = await (hre as any).deployConfig.addressManager.getAddress('TK_L2BOBA') + console.log(`Boba is located at: ${bobaToken}`) + const entryPointFromAM = await (hre as any).deployConfig.addressManager.getAddress('Boba_EntryPoint') + if (entryPoint.address == entryPointFromAM) { + const BobaVerifyingPaymaster = await hre.deployments.deploy( + 'BobaVerifyingPaymaster', { + from: (hre as any).deployConfig.deployer_l2.address, + args: [entryPoint.address, verifyingSignerAddress, bobaDepositPaymaster.address, bobaToken], + gasLimit: 4e6, + deterministicDeployment: false, + log: true + }) + + await registerBobaAddress( (hre as any).deployConfig.addressManager, 'BobaVerifyingPaymaster', BobaVerifyingPaymaster.address ) + } +} + +export default deployFn +deployFn.tags = ['BobaVerifyingPaymaster'] diff --git a/packages/boba/account-abstraction/deploy/5-dump-addresses.ts b/packages/boba/account-abstraction/deploy/5-dump-addresses.ts new file mode 100644 index 0000000000..6e9395cb02 --- /dev/null +++ b/packages/boba/account-abstraction/deploy/5-dump-addresses.ts @@ -0,0 +1,35 @@ +/* Imports: External */ +import { DeployFunction } from 'hardhat-deploy/types' +import path from 'path' +import fs from 'fs' + +const deployFn: DeployFunction = async (hre) => { + const contracts = {} + const deployments = await hre.deployments.all() + + for (const key in deployments) { + if (deployments.hasOwnProperty(key)) { + if (key == 'EntryPoint' || key == 'BundlerHelper') { + contracts['BOBA_'+key] = deployments[key].address + } else { + contracts[key] = deployments[key].address + } + } + } + + const addresses = JSON.stringify(contracts, null, 2) + + console.log(addresses) + + const dumpsPath = path.resolve(__dirname, '../dist/dumps') + + if (!fs.existsSync(dumpsPath)) { + fs.mkdirSync(dumpsPath, { recursive: true }) + } + const addrsPath = path.resolve(dumpsPath, 'addresses.json') + fs.writeFileSync(addrsPath, addresses) +} + +deployFn.tags = ['Log', 'required'] + +export default deployFn diff --git a/packages/boba/account-abstraction/deploy/deploy_entrypoint.ts b/packages/boba/account-abstraction/deploy/deploy_entrypoint.ts deleted file mode 100644 index 4a1c21766b..0000000000 --- a/packages/boba/account-abstraction/deploy/deploy_entrypoint.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { DeployFunction } from 'hardhat-deploy/types' -import { Create2Factory } from '../src/Create2Factory' -import { ethers } from 'hardhat' - -const deployEntryPoint: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const provider = ethers.provider - const from = await provider.getSigner().getAddress() - await new Create2Factory(ethers.provider).deployFactory() - - const ret = await hre.deployments.deploy( - 'EntryPoint', { - from, - args: [], - gasLimit: 6e6, - deterministicDeployment: true - }) - console.log('==entrypoint addr=', ret.address) - const entryPointAddress = ret.address - - const w = await hre.deployments.deploy( - 'SimpleWallet', { - from, - args: [entryPointAddress, from], - gasLimit: 2e6, - deterministicDeployment: true - }) - - console.log('== wallet=', w.address) - - const t = await hre.deployments.deploy('TestCounter', { - from, - deterministicDeployment: true - }) - console.log('==testCounter=', t.address) -} - -export default deployEntryPoint diff --git a/packages/boba/account-abstraction/hardhat.config.ts b/packages/boba/account-abstraction/hardhat.config.ts index f30eae3b09..db7fbc1489 100644 --- a/packages/boba/account-abstraction/hardhat.config.ts +++ b/packages/boba/account-abstraction/hardhat.config.ts @@ -3,31 +3,22 @@ import '@typechain/hardhat' import { HardhatUserConfig } from 'hardhat/config' import 'hardhat-deploy' import '@nomiclabs/hardhat-etherscan' - +import './tasks/deploy' import 'solidity-coverage' -import * as fs from 'fs' - -const mnemonicFileName = process.env.MNEMONIC_FILE ?? `${process.env.HOME}/.secret/testnet-mnemonic.txt` -let mnemonic = 'test '.repeat(11) + 'junk' -if (fs.existsSync(mnemonicFileName)) { mnemonic = fs.readFileSync(mnemonicFileName, 'ascii') } +import * as dotenv from 'dotenv' -function getNetwork1 (url: string): { url: string, accounts: { mnemonic: string } } { - return { - url, - accounts: { mnemonic } - } -} +// Load environment variables from .env +dotenv.config() -function getNetwork (name: string): { url: string, accounts: { mnemonic: string } } { - return getNetwork1(`https://${name}.infura.io/v3/${process.env.INFURA_ID}`) - // return getNetwork1(`wss://${name}.infura.io/ws/v3/${process.env.INFURA_ID}`) +if (!process.env.L1_NODE_WEB3_URL) { + process.env.L1_NODE_WEB3_URL = 'http://localhost:9545' } const optimizedComilerSettings = { version: '0.8.17', settings: { - optimizer: { enabled: true, runs: 1000000 }, + optimizer: { enabled: true, runs: 10_000 }, viaIR: true } } @@ -44,7 +35,7 @@ const config: HardhatUserConfig = { compilers: [{ version: '0.8.15', settings: { - optimizer: { enabled: true, runs: 1000000 } + optimizer: { enabled: true, runs: 10_000 } } }], overrides: { @@ -53,25 +44,40 @@ const config: HardhatUserConfig = { } }, networks: { - dev: { url: 'http://localhost:8545' }, - // github action starts localgeth service, for gas calculations - localgeth: { url: 'http://localgeth:8545' }, - goerli: getNetwork('goerli'), - proxy: getNetwork1('http://localhost:8545'), - //testnets - bobagoerli: getNetwork('bobagoerli'), - bobabase: getNetwork('bobabase'), - bobafantom: getNetwork('bobafantom'), - bobafuji: getNetwork('bobafuji'), - bobabnb: getNetwork('bobabnb') + boba: { + url: 'http://localhost:8545', + saveDeployments: false, + }, + localhost: { + url: 'http://localhost:9545', + allowUnlimitedContractSize: true, + timeout: 1800000, + accounts: [ + '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', + ], + }, + mainnet: { + url: process.env.L1_NODE_WEB3_URL, + }, + 'boba-mainnet': { + url: 'https://mainnet.boba.network', + }, + goerli: { + url: process.env.L1_NODE_WEB3_URL || '', + }, }, mocha: { - timeout: 10000 + timeout: 300000 }, + namedAccounts: { + deployer: { + default: 0, + }, + }, etherscan: { - apiKey: process.env.ETHERSCAN_API_KEY - } + apiKey: process.env.ETHERSCAN_KEY, + }, } diff --git a/packages/boba/account-abstraction/package.json b/packages/boba/account-abstraction/package.json index 67836f5633..1f1287bf08 100644 --- a/packages/boba/account-abstraction/package.json +++ b/packages/boba/account-abstraction/package.json @@ -15,7 +15,7 @@ "mocha-gascalc": "TS_NODE_TRANSPILE_ONLY=1 npx ts-mocha --bail gascalc/*", "test": "yarn run ci", "coverage": "COVERAGE=1 hardhat coverage", - "deploy": "./scripts/hh-wrapper deploy", + "deploy": "ts-node \"./bin/deploy.ts\"", "test-dev": "hardhat test --network dev", "ci": "yarn compile && hardhat test && yarn run runop", "ci-gas-calc": "yarn gas-calc && yarn check-gas-reports", @@ -26,6 +26,7 @@ }, "license": "ISC", "devDependencies": { + "@eth-optimism/contracts": "^0.5.11", "@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-waffle": "^2.0.1", "@typechain/ethers-v5": "^10.1.0", @@ -52,7 +53,7 @@ }, "dependencies": { "@gnosis.pm/safe-contracts": "^1.3.0", - "@nomiclabs/hardhat-etherscan": "^2.1.6", + "@nomiclabs/hardhat-etherscan": "^3.1.0", "@openzeppelin/contracts": "^4.2.0", "@openzeppelin/contracts-upgradeable": "4.3.2", "@thehubbleproject/bls": "^0.5.1", @@ -60,9 +61,10 @@ "@types/mocha": "^9.0.0", "ethereumjs-util": "^7.1.0", "ethereumjs-wallet": "^1.0.1", - "hardhat-deploy": "^0.9.3", + "hardhat-deploy": "^0.11.12", "hardhat-deploy-ethers": "^0.3.0-beta.11", "solidity-coverage": "^0.7.18", + "solidity-string-utils": "^0.0.8-0", "source-map-support": "^0.5.19", "table": "^6.8.0", "typescript": "^4.3.5" diff --git a/packages/boba/account-abstraction/scripts/deployer.sh b/packages/boba/account-abstraction/scripts/deployer.sh new file mode 100644 index 0000000000..f95f5d3735 --- /dev/null +++ b/packages/boba/account-abstraction/scripts/deployer.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e + +# This is what deploys all the right BOBA contracts +yarn run deploy + +# Register the deployed addresses with DTL +if [ -n "$DTL_REGISTRY_URL" ] ; then + echo "Will upload addresses.json to $DTL_REGISTRY_URL" + curl \ + --fail \ + --show-error \ + --silent \ + -H "Content-Type: application/json" \ + --retry-connrefused \ + --retry $RETRIES \ + --retry-delay 5 \ + -T dist/dumps/addresses.json \ + "$DTL_REGISTRY_URL" + echo + echo "Upload done." +fi \ No newline at end of file diff --git a/packages/boba/account-abstraction/scripts/wait-for-l1-and-l2.sh b/packages/boba/account-abstraction/scripts/wait-for-l1-and-l2.sh new file mode 100644 index 0000000000..a46f31e8a4 --- /dev/null +++ b/packages/boba/account-abstraction/scripts/wait-for-l1-and-l2.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# Copyright Optimism PBC 2020 +# MIT License +# github.com/ethereum-optimism + +cmd="$@" +JSON='{"jsonrpc":"2.0","id":0,"method":"net_version","params":[]}' + +RETRIES=${RETRIES:-50} +until $(curl --silent --fail \ + --output /dev/null \ + -H "Content-Type: application/json" \ + --data "$JSON" "$L1_NODE_WEB3_URL"); do + sleep 1 + echo "Will wait $((RETRIES--)) more times for $L1_NODE_WEB3_URL to be up..." + + if [ "$RETRIES" -lt 0 ]; then + echo "Timeout waiting for layer one node at $L1_NODE_WEB3_URL" + exit 1 + fi +done +echo "Connected to L1 Node at $L1_NODE_WEB3_URL" + +RETRIES=${RETRIES:-50} #BUG BUG BUG - if the above takes a lot of retires, then this loop will run out of retries +until $(curl --silent --fail \ + --output /dev/null \ + -H "Content-Type: application/json" \ + --data "$JSON" "$L2_NODE_WEB3_URL"); do + sleep 2 + echo "Will wait $((RETRIES--)) more times for $L2_NODE_WEB3_URL to be up..." + + if [ "$RETRIES" -lt 0 ]; then + echo "Timeout waiting for layer two node at $L2_NODE_WEB3_URL" + exit 1 + fi +done +echo "Connected to L2 Node at $L2_NODE_WEB3_URL" + +if [ ! -z "$URL" ]; then + RETRIES=${RETRIES:-50} + until $(curl --silent --fail \ + --output /dev/null \ + "$URL"); do + sleep 1 + echo "Will wait $((RETRIES--)) more times for $URL to be up..." + + if [ "$RETRIES" -lt 0 ]; then + echo "Timeout waiting for contract deployment" + exit 1 + fi + done + echo "Rollup contracts are deployed" + + if [ ! -z "$BOBA_URL" ]; then + RETRIES=${RETRIES:-50} + until $(curl --fail \ + --output /dev/null \ + "$BOBA_URL"); do + sleep 10 + echo "Will wait $((RETRIES--)) more times for $BOBA_URL to be up..." + + if [ "$RETRIES" -lt 0 ]; then + echo "Timeout waiting for boba deployment" + exit 1 + fi + done + echo "Boba contracts are deployed" + fi + + ADDRESS_MANAGER_ADDRESS=$(curl --silent $URL | jq -r .AddressManager) + exec env \ + ADDRESS_MANAGER_ADDRESS=$ADDRESS_MANAGER_ADDRESS \ + $cmd +else + exec $cmd +fi diff --git a/packages/boba/account-abstraction/src/runop.ts b/packages/boba/account-abstraction/src/runop.ts index 401bdf1475..94ced74ff7 100644 --- a/packages/boba/account-abstraction/src/runop.ts +++ b/packages/boba/account-abstraction/src/runop.ts @@ -9,6 +9,7 @@ import '../test/aa.init' import { parseEther } from 'ethers/lib/utils' import { providers } from 'ethers' import { TransactionReceipt } from '@ethersproject/abstract-provider/src.ts/index'; +import { Create2Factory } from './Create2Factory' // eslint-disable-next-line @typescript-eslint/no-floating-promises (async () => { @@ -17,7 +18,20 @@ import { TransactionReceipt } from '@ethersproject/abstract-provider/src.ts/inde // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (aa_url == null && !process.env.FORCE_DEPLOY) { - await hre.run('deploy') + // await hre.run('deploy') + const from = await ethers.provider.getSigner().getAddress() + await new Create2Factory(ethers.provider).deployFactory() + const ret = await hre.deployments.deploy( + 'EntryPoint', { + from, + args: [], + gasLimit: 6e6, + deterministicDeployment: true + }) + const t = await hre.deployments.deploy('TestCounter', { + from, + deterministicDeployment: true + }) const chainId = await hre.getChainId() if (chainId.match(/1337/) == null) { console.log('chainid=', chainId) diff --git a/packages/boba/account-abstraction/tasks/deploy.ts b/packages/boba/account-abstraction/tasks/deploy.ts new file mode 100644 index 0000000000..dbeaf27bab --- /dev/null +++ b/packages/boba/account-abstraction/tasks/deploy.ts @@ -0,0 +1,17 @@ +/* Imports: External */ +import { task } from 'hardhat/config' +import * as types from 'hardhat/internal/core/params/argumentTypes' + +const DEFAULT_EM_CHAIN_ID = 28 + +task('deploy', 'Deploy contracts to L1 and L2') + .addOptionalParam( + 'emOvmChainId', + 'Chain ID for the L2 network.', + DEFAULT_EM_CHAIN_ID, + types.int + ) + .setAction(async (args, hre: any, runSuper) => { + hre.deployConfig = args + return runSuper(args) + }) diff --git a/packages/boba/account-abstraction/tsconfig.json b/packages/boba/account-abstraction/tsconfig.json index 63d3dd8dfa..304071bc8e 100644 --- a/packages/boba/account-abstraction/tsconfig.json +++ b/packages/boba/account-abstraction/tsconfig.json @@ -1,31 +1,9 @@ { - "exclude": [ - ".eslintrc.js" - ], + "extends": "../../../tsconfig.json", "compilerOptions": { - "target": "es2020", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - "strictPropertyInitialization": false, - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noFallthroughCasesInSwitch": true, - "module": "commonjs", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "outDir": "dist", - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "jsx": "react-jsx" - } + "outDir": "./dist", + "resolveJsonModule": true + }, + "include": ["./hardhat.config.ts", "./scripts", "./bin", "./deploy", "./test"], + "files": ["./hardhat.config.ts"] } diff --git a/packages/data-transport-layer/src/services/main/service.ts b/packages/data-transport-layer/src/services/main/service.ts index 34c13a5f28..55c5a07c51 100644 --- a/packages/data-transport-layer/src/services/main/service.ts +++ b/packages/data-transport-layer/src/services/main/service.ts @@ -230,6 +230,25 @@ export class L1DataTransportService extends BaseService { + try { + let aList + try { + aList = JSON.parse(await this.state.db.get("aa-addr")) + } catch(e) { + if (e.notFound) { + this.logger.warn("Address Registry is not yet ready to serve AA addresses (db notFound)") + return res.status(503).json({error: "Address Registry is not yet populated"}) + } else { throw e } + } + + return res.json(aList) + } catch (e) { + return res.status(500).json({ + error: e.toString(), + }) + } + }) this.state.addressRegistry['put']("/addresses.json", async (req, res) => { try { const rb = req.body @@ -285,6 +304,25 @@ export class L1DataTransportService extends BaseService { + try { + const rb = req.body + + this.logger.info("addressRegistry PUT request for BOBA addresses", {rb}) + + // As with the base list, we could add future restrictions on changing + // certain critical addresses. For now we allow anything. + + this.logger.info("Will store new aa-addr.json", rb) + await this.state.db.put("aa-addr", JSON.stringify(rb)) + this.logger.info("Stored aa-addr.json") + return res.sendStatus(201).end() + } catch (e) { + return res.status(500).json({ + error: e.toString(), + }) + } + }) this.state.addressRegistry['get']("/state-dump.latest.json", async (req, res) => { try { diff --git a/yarn.lock b/yarn.lock index 5d4aab8d79..1305f9c5bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4395,19 +4395,6 @@ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.2.1.tgz#8057b43566a0e41abeb8142064a3c0d3f23dca86" integrity sha512-RHWYwnxryWR8hzRmU4Jm/q4gzvXpetUOJ4OPlwH2YARcDB+j79+yAYCwO0lN1SUOb4++oOTJEe6AWLEc42LIvg== -"@nomiclabs/hardhat-etherscan@^2.1.6": - version "2.1.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz#e206275e96962cd15e5ba9148b44388bc922d8c2" - integrity sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^5.0.2" - debug "^4.1.1" - fs-extra "^7.0.1" - node-fetch "^2.6.0" - semver "^6.3.0" - "@nomiclabs/hardhat-etherscan@^3.1.0": version "3.1.4" resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.4.tgz#970e57fabc6060489c93b3f646ca790db36ffee0" @@ -9203,7 +9190,7 @@ catering@^2.1.0, catering@^2.1.1: resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== -cbor@^5.0.2, cbor@^5.2.0: +cbor@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== @@ -19548,7 +19535,7 @@ node-fetch@2.6.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== -node-fetch@2.6.7, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7: +node-fetch@2.6.7, node-fetch@^2.6.1, node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== @@ -24492,6 +24479,11 @@ solidity-coverage@^0.7.17, solidity-coverage@^0.7.18: shelljs "^0.8.3" web3-utils "^1.3.0" +solidity-string-utils@^0.0.8-0: + version "0.0.8-0" + resolved "https://registry.yarnpkg.com/solidity-string-utils/-/solidity-string-utils-0.0.8-0.tgz#17d9c4ec9297615e17de61e8bc587042727ee55d" + integrity sha512-AHyYRuySlm71vk/rzat5YkP/H+xr5g3a0THHljH2DFSilMnsbLNusSUXVfbU1A3IZrfnaocAx1FSM01/mtchzg== + sonic-boom@^1.0.2: version "1.4.1" resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e"