Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

op-e2e: Test Granite EVM rules in op-program #11391

Merged
merged 1 commit into from
Aug 12, 2024
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
79 changes: 79 additions & 0 deletions op-e2e/faultproofs/precompile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import (
"encoding/json"
"fmt"
"math"
"math/big"
"path/filepath"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -134,6 +137,82 @@ func TestPrecompiles(t *testing.T) {
}
}

func TestGranitePrecompiles(t *testing.T) {
op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background()
genesisTime := hexutil.Uint64(0)
cfg := op_e2e.GraniteSystemConfig(t, &genesisTime)
// We don't need a verifier - just the sequencer is enough
delete(cfg.Nodes, "verifier")
// Use a small sequencer window size to avoid test timeout while waiting for empty blocks
// But not too small to ensure that our claim and subsequent state change is published
cfg.DeployConfig.SequencerWindowSize = 16

sys, err := cfg.Start(t)
require.Nil(t, err, "Error starting up system")
defer sys.Close()

log := testlog.Logger(t, log.LevelInfo)
log.Info("genesis", "l2", sys.RollupConfig.Genesis.L2, "l1", sys.RollupConfig.Genesis.L1, "l2_time", sys.RollupConfig.Genesis.L2Time)

l1Client := sys.Clients["l1"]
l2Seq := sys.Clients["sequencer"]
rollupRPCClient, err := rpc.DialContext(context.Background(), sys.RollupNodes["sequencer"].HTTPEndpoint())
require.Nil(t, err)
rollupClient := sources.NewRollupClient(client.NewBaseRPCClient(rollupRPCClient))

aliceKey := cfg.Secrets.Alice

t.Log("Capture current L2 head as agreed starting point")
latestBlock, err := l2Seq.BlockByNumber(ctx, nil)
require.NoError(t, err)
agreedL2Output, err := rollupClient.OutputAtBlock(ctx, latestBlock.NumberU64())
require.NoError(t, err, "could not retrieve l2 agreed block")
l2Head := agreedL2Output.BlockRef.Hash
l2OutputRoot := agreedL2Output.OutputRoot

precompile := common.BytesToAddress([]byte{0x08})
input := make([]byte, 113_000)
tx := types.MustSignNewTx(aliceKey, types.LatestSignerForChainID(cfg.L2ChainIDBig()), &types.DynamicFeeTx{
ChainID: cfg.L2ChainIDBig(),
Nonce: 0,
GasTipCap: big.NewInt(1 * params.GWei),
GasFeeCap: big.NewInt(10 * params.GWei),
Gas: 25_000_000,
To: &precompile,
Value: big.NewInt(0),
Data: input,
})
err = l2Seq.SendTransaction(ctx, tx)
require.NoError(t, err, "Should send bn256Pairing transaction")
// Expect a successful receipt to retrieve the EVM call trace so we can inspect the revert reason
receipt, err := wait.ForReceiptMaybe(ctx, l2Seq, tx.Hash(), types.ReceiptStatusSuccessful, false)
require.NotNil(t, err)
require.Contains(t, err.Error(), "bad elliptic curve pairing input size")

t.Logf("Transaction hash %v", tx.Hash())
t.Log("Determine L2 claim")
l2ClaimBlockNumber := receipt.BlockNumber
l2Output, err := rollupClient.OutputAtBlock(ctx, l2ClaimBlockNumber.Uint64())
require.NoError(t, err, "could not get expected output")
l2Claim := l2Output.OutputRoot

t.Log("Determine L1 head that includes all batches required for L2 claim block")
require.NoError(t, wait.ForSafeBlock(ctx, rollupClient, l2ClaimBlockNumber.Uint64()))
l1HeadBlock, err := l1Client.BlockByNumber(ctx, nil)
require.NoError(t, err, "get l1 head block")
l1Head := l1HeadBlock.Hash()

inputs := utils.LocalGameInputs{
L1Head: l1Head,
L2Head: l2Head,
L2Claim: common.Hash(l2Claim),
L2OutputRoot: common.Hash(l2OutputRoot),
L2BlockNumber: l2ClaimBlockNumber,
}
runCannon(t, ctx, sys, inputs, "sequencer")
}

func runCannon(t *testing.T, ctx context.Context, sys *op_e2e.System, inputs utils.LocalGameInputs, l2Node string, extraVmArgs ...string) {
l1Endpoint := sys.NodeEndpoint("l1")
l1Beacon := sys.L1BeaconEndpoint()
Expand Down
1 change: 1 addition & 0 deletions op-e2e/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ func FjordSystemConfig(t *testing.T, fjordTimeOffset *hexutil.Uint64) SystemConf
func GraniteSystemConfig(t *testing.T, graniteTimeOffset *hexutil.Uint64) SystemConfig {
cfg := FjordSystemConfig(t, &genesisTime)
cfg.DeployConfig.L2GenesisGraniteTimeOffset = graniteTimeOffset
cfg.DeployConfig.ChannelTimeoutGranite = 20
return cfg
}

Expand Down