Commit a737ef99 authored by Mark Tyneway's avatar Mark Tyneway

op-chain-ops: add test for message passer functionality

Ensures the message passer will revert when called with
malformed calldata.
parent 00345067
package crossdomain package crossdomain
import ( import (
"context"
"math/big"
"testing" "testing"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
...@@ -105,3 +115,82 @@ func TestDecodeWitnessCallData(t *testing.T) { ...@@ -105,3 +115,82 @@ func TestDecodeWitnessCallData(t *testing.T) {
}) })
} }
} }
// TestMessagePasserSafety ensures that the LegacyMessagePasser contract reverts when it is called
// with incorrect calldata. The function signature is correct but the calldata is not abi encoded
// correctly. It is expected the solidity reverts when it cannot abi decode the calldata correctly.
// Only a call to `passMessageToL1` with abi encoded `bytes` will result in the `successfulMessages`
// mapping being updated.
func TestMessagePasserSafety(t *testing.T) {
testKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
opts, err := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337))
require.NoError(t, err)
backend := backends.NewSimulatedBackend(
core.GenesisAlloc{testAddr: {Balance: big.NewInt(10000000000000000)}},
30_000_000,
)
defer backend.Close()
// deploy the LegacyMessagePasser contract
addr, tx, contract, err := bindings.DeployLegacyMessagePasser(opts, backend)
require.NoError(t, err)
backend.Commit()
_, err = bind.WaitMined(context.Background(), backend, tx)
require.NoError(t, err)
// ensure that it deployed
code, err := backend.CodeAt(context.Background(), addr, nil)
require.NoError(t, err)
require.True(t, len(code) > 0)
// dummy message
msg := []byte{0x00, 0x01, 0x02, 0x03}
// call `passMessageToL1`
msgTx, err := contract.PassMessageToL1(opts, msg)
require.NoError(t, err)
// ensure that the receipt is successful
backend.Commit()
msgReceipt, err := bind.WaitMined(context.Background(), backend, msgTx)
require.NoError(t, err)
require.Equal(t, msgReceipt.Status, types.ReceiptStatusSuccessful)
// check for the data in the `successfulMessages` mapping
data := make([]byte, len(msg)+len(testAddr))
copy(data[:], msg)
copy(data[len(msg):], testAddr.Bytes())
digest := crypto.Keccak256Hash(data)
contains, err := contract.SentMessages(&bind.CallOpts{}, digest)
require.NoError(t, err)
require.True(t, contains)
// build a transaction with improperly formatted calldata
nonce, err := backend.NonceAt(context.Background(), testAddr, nil)
require.NoError(t, err)
// append msg without abi encoding it
selector := crypto.Keccak256([]byte("passMessageToL1(bytes)"))[0:4]
require.Equal(t, selector, hexutil.MustDecode("0xcafa81dc"))
calldata := append(selector, msg...)
transaction, err := opts.Signer(testAddr, types.NewTx(&types.DynamicFeeTx{
ChainID: big.NewInt(1337),
Nonce: nonce,
GasTipCap: msgTx.GasTipCap(),
GasFeeCap: msgTx.GasFeeCap(),
Gas: msgTx.Gas() * 2,
To: msgTx.To(),
Data: calldata,
}))
require.NoError(t, err)
err = backend.SendTransaction(context.Background(), transaction)
require.NoError(t, err)
backend.Commit()
badReceipt, err := bind.WaitMined(context.Background(), backend, transaction)
require.NoError(t, err)
require.Equal(t, badReceipt.Status, types.ReceiptStatusFailed)
}
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