Skip to content
Closed
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
24 changes: 17 additions & 7 deletions simulators/optimism/devnet/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,30 @@ func genesisBlockByNumberTest(t *TestEnv) {
}
}

// CodeAtTest tests the code for the deployed contract.
func CodeAtTest(t *TestEnv) {
code, err := t.Eth.CodeAt(t.Ctx(), t.Config.DeployedContractAddr, nil)
if err != nil {
t.Fatalf("Could not fetch code for deployed contract: %v", err)
}
if bytes.Compare(runtimeCode, code) != 0 {
t.Fatalf("Unexpected code, want %x, got %x", runtimeCode, code)
}
}

// deployContractTest deploys `contractSrc` and tests if the code and state
// on the contract address contain the expected values (as set in the ctor).
func deployContractTest(t *TestEnv) {
var (
address = t.Vault.createAccount(t, big.NewInt(params.Ether))
address = t.Config.Vault.createAccount(t, big.NewInt(params.Ether))
nonce = uint64(0)

expectedContractAddress = crypto.CreateAddress(address, nonce)
gasLimit = uint64(1200000)
)

rawTx := types.NewContractCreation(nonce, big0, gasLimit, gasPrice, deployCode)
deployTx, err := t.Vault.signTransaction(address, rawTx)
deployTx, err := t.Config.Vault.signTransaction(address, rawTx)
if err != nil {
t.Fatalf("Unable to sign deploy tx: %v", err)
}
Expand Down Expand Up @@ -162,7 +172,7 @@ func deployContractTest(t *TestEnv) {
// the contract address.
func deployContractOutOfGasTest(t *TestEnv) {
var (
address = t.Vault.createAccount(t, big.NewInt(params.Ether))
address = t.Config.Vault.createAccount(t, big.NewInt(params.Ether))
nonce = uint64(0)
contractAddress = crypto.CreateAddress(address, nonce)
gasLimit = uint64(240000) // insufficient gas
Expand All @@ -171,7 +181,7 @@ func deployContractOutOfGasTest(t *TestEnv) {

// Deploy the contract.
rawTx := types.NewContractCreation(nonce, big0, gasLimit, gasPrice, deployCode)
deployTx, err := t.Vault.signTransaction(address, rawTx)
deployTx, err := t.Config.Vault.signTransaction(address, rawTx)
if err != nil {
t.Fatalf("unable to sign deploy tx: %v", err)
}
Expand Down Expand Up @@ -249,9 +259,9 @@ func newHeadSubscriptionTest(t *TestEnv) {
// address are updated correct.
func balanceAndNonceAtTest(t *TestEnv) {
var (
sourceAddr = t.Vault.createAccount(t, big.NewInt(params.Ether))
sourceAddr = t.Config.Vault.createAccount(t, big.NewInt(params.Ether))
sourceNonce = uint64(0)
targetAddr = t.Vault.createAccount(t, nil)
targetAddr = t.Config.Vault.createAccount(t, nil)
)

// Get current balance
Expand Down Expand Up @@ -279,7 +289,7 @@ func balanceAndNonceAtTest(t *TestEnv) {
gasLimit = uint64(50000)
)
rawTx := types.NewTransaction(sourceNonce, targetAddr, amount, gasLimit, gasPrice, nil)
valueTx, err := t.Vault.signTransaction(sourceAddr, rawTx)
valueTx, err := t.Config.Vault.signTransaction(sourceAddr, rawTx)
if err != nil {
t.Fatalf("Unable to sign value tx: %v", err)
}
Expand Down
40 changes: 21 additions & 19 deletions simulators/optimism/devnet/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ import (
// default timeout for RPC calls
var rpcTimeout = 10 * time.Second

type TestConfig struct {
Vault *vault
L1GenesisBlock []byte
DeployedContractAddr common.Address
}

// TestClient is the environment of a single test.
type TestEnv struct {
*hivesim.T
RPC *rpc.Client
Eth *ethclient.Client
Vault *vault

genesis []byte
RPC *rpc.Client
Eth *ethclient.Client
Config *TestConfig

// This holds most recent context created by the Ctx method.
// Every time Ctx is called, it creates a new context with the default
Expand All @@ -39,7 +43,7 @@ type TestEnv struct {
}

// runHTTP runs the given test function using the HTTP RPC client.
func runHTTP(t *hivesim.T, c *hivesim.Client, v *vault, g []byte, fn func(*TestEnv)) {
func runHTTP(t *hivesim.T, c *hivesim.Client, config *TestConfig, fn func(*TestEnv)) {
// This sets up debug logging of the requests and responses.
client := &http.Client{
Transport: &loggingRoundTrip{
Expand All @@ -51,11 +55,10 @@ func runHTTP(t *hivesim.T, c *hivesim.Client, v *vault, g []byte, fn func(*TestE
rpcClient, _ := rpc.DialHTTPWithClient(fmt.Sprintf("http://%v:9545/", c.IP), client)
defer rpcClient.Close()
env := &TestEnv{
T: t,
RPC: rpcClient,
Eth: ethclient.NewClient(rpcClient),
Vault: v,
genesis: g,
T: t,
RPC: rpcClient,
Eth: ethclient.NewClient(rpcClient),
Config: config,
}
fn(env)
if env.lastCtx != nil {
Expand All @@ -64,7 +67,7 @@ func runHTTP(t *hivesim.T, c *hivesim.Client, v *vault, g []byte, fn func(*TestE
}

// runWS runs the given test function using the WebSocket RPC client.
func runWS(t *hivesim.T, c *hivesim.Client, v *vault, g []byte, fn func(*TestEnv)) {
func runWS(t *hivesim.T, c *hivesim.Client, config *TestConfig, fn func(*TestEnv)) {
ctx, done := context.WithTimeout(context.Background(), 5*time.Second)
rpcClient, err := rpc.DialWebsocket(ctx, fmt.Sprintf("ws://%v:9546/", c.IP), "")
done()
Expand All @@ -74,11 +77,10 @@ func runWS(t *hivesim.T, c *hivesim.Client, v *vault, g []byte, fn func(*TestEnv
defer rpcClient.Close()

env := &TestEnv{
T: t,
RPC: rpcClient,
Eth: ethclient.NewClient(rpcClient),
Vault: v,
genesis: g,
T: t,
RPC: rpcClient,
Eth: ethclient.NewClient(rpcClient),
Config: config,
}
fn(env)
if env.lastCtx != nil {
Expand All @@ -93,10 +95,10 @@ func (t *TestEnv) CallContext(ctx context.Context, result interface{}, method st
return t.RPC.CallContext(ctx, result, method, args...)
}

// LoadGenesis returns the genesis block.
// LoadGenesis returns the L1 genesis block.
func (t *TestEnv) LoadGenesis() *types.Block {
var genesis core.Genesis
if err := json.Unmarshal(t.genesis, &genesis); err != nil {
if err := json.Unmarshal(t.Config.L1GenesisBlock, &genesis); err != nil {
panic(fmt.Errorf("can't parse genesis JSON: %v", err))
}
return genesis.ToBlock(nil)
Expand Down
53 changes: 49 additions & 4 deletions simulators/optimism/devnet/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package main

import (
"context"
"math/big"
"time"

"fmt"
"strings"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/hive/hivesim"
)

Expand All @@ -16,9 +20,46 @@ type testSpec struct {
Run func(*TestEnv)
}

func setup(t *TestEnv) {
var (
address = t.Config.Vault.createAccount(t, big.NewInt(params.Ether))
nonce = uint64(0)

expectedContractAddress = crypto.CreateAddress(address, nonce)
gasLimit = uint64(1200000)
)

rawTx := types.NewContractCreation(nonce, big0, gasLimit, gasPrice, deployCode)
deployTx, err := t.Config.Vault.signTransaction(address, rawTx)
if err != nil {
t.Fatalf("Unable to sign deploy tx: %v", err)
}

// deploy contract
if err := t.Eth.SendTransaction(t.Ctx(), deployTx); err != nil {
t.Fatalf("Unable to send transaction: %v", err)
}

t.Logf("Deploy transaction: 0x%x", deployTx.Hash())

// fetch transaction receipt for contract address
receipt, err := waitForTxConfirmations(t, deployTx.Hash(), 5)
if err != nil {
t.Fatalf("Unable to retrieve receipt: %v", err)
}

// ensure receipt has the expected address
if expectedContractAddress != receipt.ContractAddress {
t.Fatalf("Contract deploy on different address, expected %x, got %x", expectedContractAddress, receipt.ContractAddress)
}

t.Config.DeployedContractAddr = receipt.ContractAddress
}

var tests = []testSpec{
// HTTP RPC tests.
{Name: "http/BalanceAndNonceAt", Run: balanceAndNonceAtTest},
{Name: "http/CodeAt", Run: CodeAtTest},
{Name: "http/ContractDeployment", Run: deployContractTest},
{Name: "http/ContractDeploymentOutOfGas", Run: deployContractOutOfGasTest},
{Name: "http/GenesisBlockByHash", Run: genesisBlockByHashTest},
Expand Down Expand Up @@ -82,8 +123,12 @@ func runAllTests(t *hivesim.T) {

c := d.l2.Client

vault := newVault()
genesis := []byte(d.l2Genesis)
// Setup deployed contract
config := &TestConfig{
Vault: newVault(),
L1GenesisBlock: []byte(d.l2Genesis),
}
runHTTP(t, c, config, setup)

s := newSemaphore(16)
for _, test := range tests {
Expand All @@ -97,9 +142,9 @@ func runAllTests(t *hivesim.T) {
Run: func(t *hivesim.T) {
switch test.Name[:strings.IndexByte(test.Name, '/')] {
case "http":
runHTTP(t, c, vault, genesis, test.Run)
runHTTP(t, c, config, test.Run)
case "ws":
runWS(t, c, vault, genesis, test.Run)
runWS(t, c, config, test.Run)
default:
panic("bad test prefix in name " + test.Name)
}
Expand Down