Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/espresso-devnet-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ jobs:
- name: Run Key Rotation test
run: go test -timeout 30m -p 1 -count 1 -run 'TestKeyRotation' -v ./espresso/devnet-tests/...

# - name: Run Change Batch Inbox Owner test
# run: go test -timeout 30m -p 1 -count 1 -run 'TestChangeBatchInboxOwner -v ./espresso/devnet-tests/...
- name: Run Change Batch Inbox Owner test
run: go test -timeout 30m -p 1 -count 1 -run 'TestChangeBatchInboxOwner' -v ./espresso/devnet-tests/...

- name: Save Nix cache
uses: nix-community/cache-nix-action/save@v6
Expand Down
6 changes: 6 additions & 0 deletions espresso/.env
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ OPERATOR_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf
# cast wallet address --private-key $OPERATOR_PRIVATE_KEY
OPERATOR_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266

# BatchAuthenticator owner address for contract ownership (index 3 from mnemonic)
# cast wallet address --mnemonic "test test ... junk" --hd-path "m/44'/60'/0'/0/3"
BATCH_AUTHENTICATOR_OWNER_ADDRESS=0x90F79bf6EB2c4f870365E785982E1f101E93b906
# cast wallet private-key --mnemonic "test test ... junk" --hd-path "m/44'/60'/0'/0/3"
BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY=0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6

# cast wallet address --mnemonic "test test ... junk" --hd-path "m/44'/60'/0'/0/1"
PROPOSER_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8

Expand Down
14 changes: 14 additions & 0 deletions espresso/devnet-tests/devnet_tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"math/big"
"os"
"os/exec"
"path/filepath"
"reflect"
"strconv"
"strings"
Expand All @@ -27,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/joho/godotenv"

env "github.com/ethereum-optimism/optimism/espresso/environment"
"github.com/ethereum-optimism/optimism/op-e2e/config/secrets"
Expand All @@ -44,6 +46,18 @@ type Devnet struct {
L2VerifRollup *sources.RollupClient
}

// LoadEnvFile loads environment variables from a .env file
func LoadEnvFile(filename string) error {
return godotenv.Load(filename)
}

// LoadDevnetEnv loads the espresso/.env file for devnet tests
func LoadDevnetEnv() error {
// Get the path to the espresso/.env file relative to the test directory
envPath := filepath.Join("..", ".env")
return LoadEnvFile(envPath)
}

func NewDevnet(ctx context.Context, t *testing.T) *Devnet {

if testing.Short() {
Expand Down
43 changes: 39 additions & 4 deletions espresso/devnet-tests/key_rotation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ package devnet_tests

import (
"context"
"os"
"strings"
"testing"

"github.com/ethereum-optimism/optimism/op-batcher/bindings"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
)

func TestRotateBatcherKey(t *testing.T) {

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand Down Expand Up @@ -52,6 +57,10 @@ func TestRotateBatcherKey(t *testing.T) {
}

func TestChangeBatchInboxOwner(t *testing.T) {
// Load environment variables from .env file
err := LoadDevnetEnv()
require.NoError(t, err, "Failed to load .env file")

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand All @@ -68,18 +77,44 @@ func TestChangeBatchInboxOwner(t *testing.T) {
config, err := d.RollupConfig(ctx)
require.NoError(t, err)

// Change the BatchAuthenticator's owner
batchAuthenticator, err := bindings.NewBatchAuthenticator(config.BatchAuthenticatorAddress, d.L1)
require.NoError(t, err)
tx, err := batchAuthenticator.TransferOwnership(&bind.TransactOpts{}, d.secrets.Addresses().Bob)

// Get L1 chain ID for transaction signing
l1ChainID, err := d.L1.ChainID(ctx)
require.NoError(t, err)
_, err = d.SendL1Tx(ctx, tx)

// Check current owner first
currentOwner, err := batchAuthenticator.Owner(&bind.CallOpts{})
require.NoError(t, err)

// Check that the new owner is different from the current one
bobAddress := d.secrets.Addresses().Bob
require.NotEqual(t, currentOwner, bobAddress)

// Use batch authenticator owner key to sign the transaction
batchAuthenticatorPrivateKeyHex := os.Getenv("BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY")
require.NotEmpty(t, batchAuthenticatorPrivateKeyHex, "BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY must be set")
t.Logf("Using BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY from environment: %s...", batchAuthenticatorPrivateKeyHex[:10])

batchAuthenticatorKey, err := crypto.HexToECDSA(strings.TrimPrefix(batchAuthenticatorPrivateKeyHex, "0x"))
require.NoError(t, err)

batchAuthenticatorOwnerOpts, err := bind.NewKeyedTransactorWithChainID(batchAuthenticatorKey, l1ChainID)
require.NoError(t, err)

// Call TransferOwnership
tx, err := batchAuthenticator.TransferOwnership(batchAuthenticatorOwnerOpts, bobAddress)
require.NoError(t, err)

// Wait for transaction receipt and check if it succeeded
_, err = wait.ForReceiptOK(ctx, d.L1, tx.Hash())
require.NoError(t, err)

// Ensure the owner has been changed
newOwner, err := batchAuthenticator.Owner(&bind.CallOpts{})
require.NoError(t, err)
require.Equal(t, newOwner, d.secrets.Addresses().Bob)
require.Equal(t, newOwner, bobAddress)

// Check that everything still functions
require.NoError(t, d.RunSimpleL2Burn())
Expand Down
2 changes: 1 addition & 1 deletion espresso/scripts/prepare-allocs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.proposer -v "${P
# contract addresses are deterministic.
dasel put -f "${DEPLOYER_DIR}/state.json" -s create2Salt -v "0xaecea4f57fadb2097ccd56594f2f22715ac52f92971c5913b70a7f1134b68feb"

op-deployer apply --l1-rpc-url "${ANVIL_URL}" \
BATCH_AUTHENTICATOR_OWNER_ADDRESS="${BATCH_AUTHENTICATOR_OWNER_ADDRESS}" op-deployer apply --l1-rpc-url "${ANVIL_URL}" \
--workdir "${DEPLOYER_DIR}" \
--private-key="${OPERATOR_PRIVATE_KEY}"

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ require (
gopkg.in/yaml.v3 v3.0.1
)

require github.com/joho/godotenv v1.5.1

require (
codeberg.org/go-fonts/liberation v0.5.0 // indirect
codeberg.org/go-latex/latex v0.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
Expand Down
5 changes: 3 additions & 2 deletions op-deployer/pkg/deployer/opcm/espresso.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type DeployEspressoOutput struct {
}

type DeployEspressoScript struct {
Run func(input, output common.Address) error
Run func(input, output, deployerAddress common.Address) error
}

type DeployAWSNitroVerifierScript struct {
Expand Down Expand Up @@ -72,6 +72,7 @@ func DeployAWSNitroVerifier(
func DeployEspresso(
host *script.Host,
input DeployEspressoInput,
deployerAddress common.Address,
) (DeployEspressoOutput, error) {
var output DeployEspressoOutput
inputAddr := host.NewScriptAddress()
Expand All @@ -97,7 +98,7 @@ func DeployEspresso(
}
defer cleanupDeploy()

if err := deployScript.Run(inputAddr, outputAddr); err != nil {
if err := deployScript.Run(inputAddr, outputAddr, deployerAddress); err != nil {
return output, fmt.Errorf("failed to run %s script: %w", implContract, err)
}

Expand Down
13 changes: 12 additions & 1 deletion op-deployer/pkg/deployer/pipeline/espresso.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pipeline

import (
"fmt"
"os"

"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm"
"github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state"
Expand Down Expand Up @@ -36,11 +37,21 @@ func DeployEspresso(env *Env, intent *state.Intent, st *state.State, chainID com
}

var eo opcm.DeployEspressoOutput
// Read batch authenticator owner address from environment variable, fallback to env.Deployer
var batchAuthenticatorOwnwerAddress common.Address
if batchAuthenticatorOwnerEnv := os.Getenv("BATCH_AUTHENTICATOR_OWNER_ADDRESS"); batchAuthenticatorOwnerEnv != "" {
batchAuthenticatorOwnwerAddress = common.HexToAddress(batchAuthenticatorOwnerEnv)
lgr.Info("Using batch authenticator owner address from BATCH_AUTHENTICATOR_OWNER_ADDRESS env var", "address", batchAuthenticatorOwnwerAddress.Hex())
} else {
batchAuthenticatorOwnwerAddress = env.Deployer
lgr.Info("Using deployer address from env.Deployer", "address", batchAuthenticatorOwnwerAddress.Hex())
}

eo, err = opcm.DeployEspresso(env.L1ScriptHost, opcm.DeployEspressoInput{
Salt: st.Create2Salt,
PreApprovedBatcherKey: chainIntent.PreApprovedBatcherKey,
NitroTEEVerifier: nvo.NitroTEEVerifierAddress,
})
}, batchAuthenticatorOwnwerAddress)
if err != nil {
return fmt.Errorf("failed to deploy espresso contracts: %w", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface IBatchAuthenticator {

function __constructor__(
address _espressoTEEVerifier,
address _preApprovedBatcher
address _preApprovedBatcher,
address _owner
) external;
}
12 changes: 8 additions & 4 deletions packages/contracts-bedrock/scripts/deploy/DeployEspresso.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,18 @@ contract DeployEspressoOutput is BaseDeployIO {
}

contract DeployEspresso is Script {
function run(DeployEspressoInput input, DeployEspressoOutput output) public {
function run(DeployEspressoInput input, DeployEspressoOutput output, address deployerAddress) public {
IEspressoTEEVerifier teeVerifier = deployTEEVerifier(input);
IBatchAuthenticator batchAuthenticator = deployBatchAuthenticator(input, output, teeVerifier);
IBatchAuthenticator batchAuthenticator = deployBatchAuthenticator(input, output, teeVerifier, deployerAddress);
deployBatchInbox(input, output, batchAuthenticator);
checkOutput(output);
}

function deployBatchAuthenticator(
DeployEspressoInput input,
DeployEspressoOutput output,
IEspressoTEEVerifier teeVerifier
IEspressoTEEVerifier teeVerifier,
address owner
)
public
returns (IBatchAuthenticator)
Expand All @@ -96,11 +97,14 @@ contract DeployEspresso is Script {
_name: "BatchAuthenticator",
_salt: salt,
_args: DeployUtils.encodeConstructor(
abi.encodeCall(IBatchAuthenticator.__constructor__, (address(teeVerifier), preApprovedBatcherKey))
abi.encodeCall(
IBatchAuthenticator.__constructor__, (address(teeVerifier), preApprovedBatcherKey, owner)
)
)
})
);
vm.label(address(impl), "BatchAuthenticatorImpl");

output.set(output.batchAuthenticatorAddress.selector, address(impl));
return impl;
}
Expand Down
7 changes: 4 additions & 3 deletions packages/contracts-bedrock/src/L1/BatchAuthenticator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.0;

import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ISemver } from "interfaces/universal/ISemver.sol";
import { EspressoTEEVerifier } from "@espresso-tee-contracts/EspressoTEEVerifier.sol";
import { IEspressoTEEVerifier } from "@espresso-tee-contracts/interface/IEspressoTEEVerifier.sol";
Expand All @@ -14,7 +14,7 @@ interface INitroValidator {
returns (bytes memory attestationTbs, bytes memory signature);
}

contract BatchAuthenticator is ISemver, OwnableUpgradeable {
contract BatchAuthenticator is ISemver, Ownable {
/// @notice Semantic version.
/// @custom:semver 1.0.0
string public constant version = "1.0.0";
Expand All @@ -27,10 +27,11 @@ contract BatchAuthenticator is ISemver, OwnableUpgradeable {
EspressoTEEVerifier public immutable espressoTEEVerifier;
INitroValidator public immutable nitroValidator;

constructor(EspressoTEEVerifier _espressoTEEVerifier, address _preApprovedBatcher) OwnableUpgradeable() {
constructor(EspressoTEEVerifier _espressoTEEVerifier, address _preApprovedBatcher, address _owner) Ownable() {
espressoTEEVerifier = _espressoTEEVerifier;
preApprovedBatcher = _preApprovedBatcher;
nitroValidator = INitroValidator(address(espressoTEEVerifier.espressoNitroTEEVerifier()));
_transferOwnership(_owner);
}

function decodeAttestationTbs(bytes memory attestation) external view returns (bytes memory, bytes memory) {
Expand Down
Loading