Commit 59132e13 authored by Adrian Sutton's avatar Adrian Sutton

Merge branch 'develop' into aj/deploy-dispute-game-e2e

parents 9b93ae25 677bff37
......@@ -3,7 +3,7 @@
"changelog": ["@changesets/changelog-github", { "repo": "ethereum-optimism/optimism" }],
"commit": false,
"fixed": [],
"linked": [["contracts-bedrock", "contracts-ts"]],
"linked": [["@eth-optimism/contracts-bedrock", "@eth-optimism/contracts-ts"]],
"access": "public",
"baseBranch": "develop",
"updateInternalDependencies": "patch",
......
---
'@eth-optimism/sdk': minor
---
Added to and from block filters to several methods in CrossChainMessenger
......@@ -197,7 +197,7 @@ jobs:
fi
IMAGE_BASE="<<parameters.registry>>/<<parameters.repo>>/<<parameters.docker_name>>"
DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
docker build \
docker build --progress plain \
$(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
-f <<parameters.docker_file>> \
<<parameters.docker_context>>
......@@ -266,7 +266,7 @@ jobs:
DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
docker context create buildx-build
docker buildx create --use buildx-build
docker buildx build --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
docker buildx build --progress plain --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
$(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
-f <<parameters.docker_file>> \
<<parameters.docker_context>>
......@@ -321,7 +321,7 @@ jobs:
DOCKER_TAGS=$(echo -ne <<parameters.docker_tags>> | sed "s/,/\n/g" | sed "s/[^a-zA-Z0-9\n]/-/g" | sed -e "s|^|-t ${IMAGE_BASE}:|")
docker context create buildx-build
docker buildx create --use buildx-build
docker buildx build --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
docker buildx build --progress plain --platform=<<parameters.platforms>> --target "<<parameters.docker_target>>" --push \
$(echo -ne $DOCKER_TAGS | tr '\n' ' ') \
-f <<parameters.docker_file>> \
<<parameters.docker_context>>
......@@ -1745,6 +1745,21 @@ workflows:
- oplabs-gcr-release
requires:
- hold
- docker-release:
name: op-ufm-docker-release
filters:
tags:
only: /^op-ufm\/v.*/
branches:
ignore: /.*/
docker_file: op-ufm/Dockerfile
docker_name: op-ufm
docker_tags: <<pipeline.git.revision>>,<<pipeline.git.branch>>
docker_context: .
context:
- oplabs-gcr-release
requires:
- hold
- docker-release:
name: proxyd-docker-release
filters:
......
......@@ -18,13 +18,14 @@ on:
required: true
type: choice
options:
- ci-builder
- fault-detector
- indexer
- op-node
- op-batcher
- op-proposer
- op-ufm
- proxyd
- indexer
- fault-detector
- ci-builder
prerelease:
description: Increment major/minor/patch as prerelease?
required: false
......
---
title: Using the SDK with OP Stack
title: Using the OP Stack Client SDK
lang: en-US
---
When building applications for use with your OP Stack, you can continue to use [the Optimism JavaScript SDK](https://sdk.optimism.io/).
The main difference is you need to provide some contract addresses to the `CrossDomainMessenger` because they aren't preconfigured.
## Natively supported chains
## Contract addresses
[The OP Stack Client SDK](https://sdk.optimism.io/) natively supports multiple OP Chains: OP, Base, etc.
To see whether a specific OP Chain is supported directly, [see the documentation](https://sdk.optimism.io/enums/l2chainid).
### L1 contract addresses
## Not natively supported chains
The contract addresses are in `.../optimism/packages/contracts-bedrock/deployments/getting-started`, which you created when you deployed the L1 contracts.
If you are using a chain that is *not* natively supported, for example an OP Stack chain [you just created](./getting-started.md), you can continue to use [the OP Stack Client SDK](https://sdk.optimism.io/).
You just need to provide some contract addresses to the `CrossDomainMessenger` because they aren't preconfigured.
### Getting contract addresses
#### L1 contract addresses
If you followed the directions in [Getting Started](./getting-started.md), the contract addresses are in `.../optimism/packages/contracts-bedrock/deployments/getting-started`, which you created when you deployed the L1 contracts.
| Contract name when creating `CrossDomainMessenger` | File with address |
| - | - |
......@@ -22,9 +29,9 @@ The contract addresses are in `.../optimism/packages/contracts-bedrock/deploymen
| `L2OutputOracle` | `L2OutputOracleProxy.json`
### Unneeded contract addresses
#### Unneeded contract addresses
Some contracts are required by the SDK, but not actually used.
Some contracts are required by the SDK as a sanity check, but are not actually used.
For these contracts you can just specify the zero address:
- `StateCommitmentChain`
......@@ -33,7 +40,7 @@ For these contracts you can just specify the zero address:
In JavaScript you can create the zero address using the expression `"0x".padEnd(42, "0")`.
## The CrossChainMessenger object
### The CrossChainMessenger object
These directions assume you are inside the [Hardhat console](https://hardhat.org/hardhat-runner/docs/guides/hardhat-console).
They further assume that your project already includes the Optimism SDK [`@eth-optimism/sdk`](https://www.npmjs.com/package/@eth-optimism/sdk).
......@@ -113,7 +120,7 @@ They further assume that your project already includes the Optimism SDK [`@eth-o
})
```
## Verify SDK functionality
### Verify SDK functionality
To verify the SDK's functionality, transfer some ETH from L1 to L2.
......
......@@ -49,7 +49,7 @@ func (ap *AlphabetProvider) Get(i uint64) (common.Hash, error) {
func (ap *AlphabetProvider) AbsolutePreState() []byte {
out := make([]byte, 32)
out[31] = 140 // ascii character 140 is "`"
out[31] = 96 // ascii character 96 is "`"
return out
}
......
......@@ -10,6 +10,7 @@ import (
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
......@@ -40,6 +41,10 @@ func (m *mockTxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (
), nil
}
func (m *mockTxManager) Call(_ context.Context, _ ethereum.CallMsg, _ *big.Int) ([]byte, error) {
panic("unimplemented")
}
func (m *mockTxManager) BlockNumber(ctx context.Context) (uint64, error) {
panic("not implemented")
}
......
......@@ -44,6 +44,9 @@ type fakeTxMgr struct {
func (f fakeTxMgr) From() common.Address {
return f.from
}
func (f fakeTxMgr) Call(_ context.Context, _ ethereum.CallMsg, _ *big.Int) ([]byte, error) {
panic("unimplemented")
}
func (f fakeTxMgr) BlockNumber(_ context.Context) (uint64, error) {
panic("unimplemented")
}
......
......@@ -4,9 +4,12 @@ package mocks
import (
context "context"
big "math/big"
common "github.com/ethereum/go-ethereum/common"
ethereum "github.com/ethereum/go-ethereum"
mock "github.com/stretchr/testify/mock"
txmgr "github.com/ethereum-optimism/optimism/op-service/txmgr"
......@@ -43,6 +46,32 @@ func (_m *TxManager) BlockNumber(ctx context.Context) (uint64, error) {
return r0, r1
}
// Call provides a mock function with given fields: ctx, msg, blockNumber
func (_m *TxManager) Call(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
ret := _m.Called(ctx, msg, blockNumber)
var r0 []byte
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) ([]byte, error)); ok {
return rf(ctx, msg, blockNumber)
}
if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg, *big.Int) []byte); ok {
r0 = rf(ctx, msg, blockNumber)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]byte)
}
}
if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg, *big.Int) error); ok {
r1 = rf(ctx, msg, blockNumber)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// From provides a mock function with given fields:
func (_m *TxManager) From() common.Address {
ret := _m.Called()
......
......@@ -45,6 +45,10 @@ type TxManager interface {
// NOTE: Send can be called concurrently, the nonce will be managed internally.
Send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error)
// Call is used to call a contract.
// Internally, it uses the [ethclient.Client.CallContract] method.
Call(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
// From returns the sending address associated with the instance of the transaction manager.
// It is static for a single instance of a TxManager.
From() common.Address
......@@ -59,6 +63,9 @@ type ETHBackend interface {
// BlockNumber returns the most recent block number.
BlockNumber(ctx context.Context) (uint64, error)
// CallContract executes an eth_call against the provided contract.
CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
// TransactionReceipt queries the backend for a receipt associated with
// txHash. If lookup does not fail, but the transaction is not found,
// nil should be returned for both values.
......@@ -155,6 +162,12 @@ func (m *SimpleTxManager) Send(ctx context.Context, candidate TxCandidate) (*typ
return receipt, err
}
// Call is used to call a contract.
// Internally, it uses the [ethclient.Client.CallContract] method.
func (m *SimpleTxManager) Call(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
return m.backend.CallContract(ctx, msg, blockNumber)
}
// send performs the actual transaction creation and sending.
func (m *SimpleTxManager) send(ctx context.Context, candidate TxCandidate) (*types.Receipt, error) {
if m.cfg.TxSendTimeout != 0 {
......
......@@ -194,6 +194,11 @@ func (b *mockBackend) BlockNumber(ctx context.Context) (uint64, error) {
return b.blockHeight, nil
}
// Call mocks a call to the EVM.
func (b *mockBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
return nil, nil
}
func (b *mockBackend) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
return &types.Header{
BaseFee: b.g.basefee(),
......@@ -649,6 +654,10 @@ func (b *failingBackend) HeaderByNumber(_ context.Context, _ *big.Int) (*types.H
}, nil
}
func (b *failingBackend) CallContract(_ context.Context, _ ethereum.CallMsg, _ *big.Int) ([]byte, error) {
return nil, errors.New("unimplemented")
}
func (b *failingBackend) SendTransaction(_ context.Context, _ *types.Transaction) error {
return errors.New("unimplemented")
}
......
......@@ -44,7 +44,7 @@
"l1GenesisBlockTimestamp": "0x64935846",
"l1StartingBlockTag": "earliest",
"l2GenesisRegolithTimeOffset": "0x0",
"faultGameAbsolutePrestate": 140,
"faultGameAbsolutePrestate": 96,
"faultGameMaxDepth": 4,
"faultGameMaxDuration": 604800
}
}
\ No newline at end of file
// public rpcs are heavily throttled/rate limited so replace these with rpcs with apikeys. These are meant to be testnet rpcs
// in future these will get renamed to VITE_E2E_RPC_URL_GOERLI etc.
VITE_E2E_RPC_URL_L1=https://ethereum-goerli.publicnode.com
VITE_E2E_RPC_URL_L2=https://goerli.optimism.io
\ No newline at end of file
This diff is collapsed.
......@@ -2,3 +2,4 @@
- The new tests for the next version of sdk will use vitest
- The vitest tests are kept here seperated from mocha tests for now
- Can find values needed in a `.env` file in `example.env`
......@@ -11,22 +11,40 @@ const crossChainMessenger = new CrossChainMessenger({
bedrock: true,
})
describe('prove message', () => {
describe('getMessageStatus', () => {
it(`should be able to correctly find a finalized withdrawal`, async () => {
/**
* Tx hash of legacy withdrawal that was claimed
* Tx hash of a withdrawal
*
* @see https://goerli-optimism.etherscan.io/tx/0xda9e9c8dfc7718bc1499e1e64d8df6cddbabc46e819475a6c755db286a41b9fa
* @see https://goerli-optimism.etherscan.io/tx/0x8fb235a61079f3fa87da66e78c9da075281bc4ba5f1af4b95197dd9480e03bb5
*/
const txWithdrawalHash =
'0xda9e9c8dfc7718bc1499e1e64d8df6cddbabc46e819475a6c755db286a41b9fa'
'0x8fb235a61079f3fa87da66e78c9da075281bc4ba5f1af4b95197dd9480e03bb5'
const txReceipt = await l2Provider.getTransactionReceipt(txWithdrawalHash)
expect(txReceipt).toBeDefined()
expect(await crossChainMessenger.getMessageStatus(txWithdrawalHash)).toBe(
MessageStatus.RELAYED
)
expect(
await crossChainMessenger.getMessageStatus(
txWithdrawalHash,
0,
9370789 - 1000,
9370789
)
).toBe(MessageStatus.RELAYED)
}, 20_000)
it(`should return READY_FOR_RELAY if not in block range`, async () => {
const txWithdrawalHash =
'0x8fb235a61079f3fa87da66e78c9da075281bc4ba5f1af4b95197dd9480e03bb5'
const txReceipt = await l2Provider.getTransactionReceipt(txWithdrawalHash)
expect(txReceipt).toBeDefined()
expect(
await crossChainMessenger.getMessageStatus(txWithdrawalHash, 0, 0, 0)
).toBe(MessageStatus.READY_FOR_RELAY)
}, 20_000)
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment