Commit 48ad2f56 authored by Andreas Bigger's avatar Andreas Bigger

Add logic for parsing output proposed logs.

parent daaf917b
......@@ -5,6 +5,8 @@ import (
"errors"
"math/big"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum-optimism/optimism/op-node/eth"
)
......@@ -15,8 +17,21 @@ var (
ErrInvalidBlockNumber = errors.New("invalid block number")
// ErrUnsupportedL2OOVersion is returned when the output version is not supported.
ErrUnsupportedL2OOVersion = errors.New("unsupported l2oo version")
// ErrInvalidOutputLogTopic is returned when the output log topic is invalid.
ErrInvalidOutputLogTopic = errors.New("invalid output log topic")
)
// ParseOutputLog parses a log from the L2OutputOracle contract.
func (c *Challenger) ParseOutputLog(log *types.Log) (*big.Int, eth.Bytes32, error) {
// Validate the first topic is the output log topic
if log.Topics[0] != c.l2ooABI.Events["OutputProposed"].ID {
return nil, eth.Bytes32{}, ErrInvalidOutputLogTopic
}
l2BlockNumber := new(big.Int).SetBytes(log.Topics[3][:])
expected := log.Topics[1]
return l2BlockNumber, eth.Bytes32(expected), nil
}
// ValidateOutput checks that a given output is expected via a trusted rollup node rpc.
// It returns: if the output is correct, the fetched output, error
func (c *Challenger) ValidateOutput(ctx context.Context, l2BlockNumber *big.Int, expected eth.Bytes32) (bool, *eth.Bytes32, error) {
......
......@@ -10,13 +10,49 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/testlog"
)
func TestParseOutputLog_Succeeds(t *testing.T) {
challenger := newTestChallenger(t, eth.OutputResponse{}, true)
expectedBlockNumber := big.NewInt(0x04)
expectedOutputRoot := eth.Bytes32{0x02}
logTopic := challenger.l2ooABI.Events["OutputProposed"].ID
log := types.Log{
Topics: []common.Hash{logTopic, common.Hash(expectedOutputRoot), {0x03}, common.BigToHash(expectedBlockNumber)},
}
parsedBlockNumber, parsedOutputRoot, err := challenger.ParseOutputLog(&log)
require.NoError(t, err)
require.Equal(t, expectedBlockNumber, parsedBlockNumber)
require.Equal(t, expectedOutputRoot, parsedOutputRoot)
}
func TestParseOutputLog_WrongLogTopic_Errors(t *testing.T) {
challenger := newTestChallenger(t, eth.OutputResponse{}, true)
_, _, err := challenger.ParseOutputLog(&types.Log{
Topics: []common.Hash{{0x01}, {0x02}, {0x03}, {0x04}},
})
require.ErrorIs(t, err, ErrInvalidOutputLogTopic)
}
func TestParseOutputLog_BadLog_Panics(t *testing.T) {
challenger := newTestChallenger(t, eth.OutputResponse{}, true)
logTopic := challenger.l2ooABI.Events["OutputProposed"].ID
require.Panics(t, func() {
log := types.Log{
Topics: []common.Hash{logTopic, {0x02}, {0x03}},
}
_, _, _ = challenger.ParseOutputLog(&log)
})
}
func TestChallenger_ValidateOutput_RollupClientErrors(t *testing.T) {
output := eth.OutputResponse{
Version: supportedL2OutputVersion,
......@@ -127,11 +163,14 @@ func newTestChallenger(t *testing.T, output eth.OutputResponse, errors bool) *Ch
outputApi := newMockOutputApi(output, errors)
log := testlog.Logger(t, log.LvlError)
metr := metrics.NewMetrics("test")
parsedL2oo, err := bindings.L2OutputOracleMetaData.GetAbi()
require.NoError(t, err)
challenger := Challenger{
rollupClient: outputApi,
log: log,
metr: metr,
networkTimeout: time.Duration(5) * time.Second,
l2ooABI: parsedL2oo,
}
return &challenger
}
......
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