-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
op-program: encapsulate ValidateClaim (#10960)
- Loading branch information
1 parent
ea4d1fd
commit 258a480
Showing
6 changed files
with
160 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package claim | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/ethereum/go-ethereum/log" | ||
|
||
"github.com/ethereum-optimism/optimism/op-service/eth" | ||
) | ||
|
||
var ErrClaimNotValid = errors.New("invalid claim") | ||
|
||
type L2Source interface { | ||
L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) | ||
L2OutputRoot(uint64) (eth.Bytes32, error) | ||
} | ||
|
||
func ValidateClaim(log log.Logger, l2ClaimBlockNum uint64, claimedOutputRoot eth.Bytes32, src L2Source) error { | ||
l2Head, err := src.L2BlockRefByLabel(context.Background(), eth.Safe) | ||
if err != nil { | ||
return fmt.Errorf("cannot retrieve safe head: %w", err) | ||
} | ||
outputRoot, err := src.L2OutputRoot(min(l2ClaimBlockNum, l2Head.Number)) | ||
if err != nil { | ||
return fmt.Errorf("calculate L2 output root: %w", err) | ||
} | ||
log.Info("Validating claim", "head", l2Head, "output", outputRoot, "claim", claimedOutputRoot) | ||
if claimedOutputRoot != outputRoot { | ||
return fmt.Errorf("%w: claim: %v actual: %v", ErrClaimNotValid, claimedOutputRoot, outputRoot) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package claim | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/ethereum/go-ethereum/log" | ||
|
||
"github.com/ethereum-optimism/optimism/op-service/eth" | ||
"github.com/ethereum-optimism/optimism/op-service/testlog" | ||
) | ||
|
||
type mockL2 struct { | ||
safeL2 eth.L2BlockRef | ||
safeL2Err error | ||
|
||
outputRoot eth.Bytes32 | ||
outputRootErr error | ||
|
||
requestedOutputRoot uint64 | ||
} | ||
|
||
func (m *mockL2) L2BlockRefByLabel(ctx context.Context, label eth.BlockLabel) (eth.L2BlockRef, error) { | ||
if label != eth.Safe { | ||
panic("unexpected usage") | ||
} | ||
if m.safeL2Err != nil { | ||
return eth.L2BlockRef{}, m.safeL2Err | ||
} | ||
return m.safeL2, nil | ||
} | ||
|
||
func (m *mockL2) L2OutputRoot(u uint64) (eth.Bytes32, error) { | ||
m.requestedOutputRoot = u | ||
if m.outputRootErr != nil { | ||
return eth.Bytes32{}, m.outputRootErr | ||
} | ||
return m.outputRoot, nil | ||
} | ||
|
||
var _ L2Source = (*mockL2)(nil) | ||
|
||
func TestValidateClaim(t *testing.T) { | ||
t.Run("Valid", func(t *testing.T) { | ||
expected := eth.Bytes32{0x11} | ||
l2 := &mockL2{ | ||
outputRoot: expected, | ||
} | ||
logger := testlog.Logger(t, log.LevelError) | ||
err := ValidateClaim(logger, uint64(0), expected, l2) | ||
require.NoError(t, err) | ||
}) | ||
|
||
t.Run("Valid-PriorToSafeHead", func(t *testing.T) { | ||
expected := eth.Bytes32{0x11} | ||
l2 := &mockL2{ | ||
outputRoot: expected, | ||
safeL2: eth.L2BlockRef{ | ||
Number: 10, | ||
}, | ||
} | ||
logger := testlog.Logger(t, log.LevelError) | ||
err := ValidateClaim(logger, uint64(20), expected, l2) | ||
require.NoError(t, err) | ||
require.Equal(t, uint64(10), l2.requestedOutputRoot) | ||
}) | ||
|
||
t.Run("Invalid", func(t *testing.T) { | ||
l2 := &mockL2{ | ||
outputRoot: eth.Bytes32{0x22}, | ||
} | ||
logger := testlog.Logger(t, log.LevelError) | ||
err := ValidateClaim(logger, uint64(0), eth.Bytes32{0x11}, l2) | ||
require.ErrorIs(t, err, ErrClaimNotValid) | ||
}) | ||
|
||
t.Run("Invalid-PriorToSafeHead", func(t *testing.T) { | ||
l2 := &mockL2{ | ||
outputRoot: eth.Bytes32{0x22}, | ||
safeL2: eth.L2BlockRef{Number: 10}, | ||
} | ||
logger := testlog.Logger(t, log.LevelError) | ||
err := ValidateClaim(logger, uint64(20), eth.Bytes32{0x55}, l2) | ||
require.ErrorIs(t, err, ErrClaimNotValid) | ||
require.Equal(t, uint64(10), l2.requestedOutputRoot) | ||
}) | ||
|
||
t.Run("Error-safe-head", func(t *testing.T) { | ||
expectedErr := errors.New("boom") | ||
l2 := &mockL2{ | ||
outputRoot: eth.Bytes32{0x11}, | ||
safeL2: eth.L2BlockRef{Number: 10}, | ||
safeL2Err: expectedErr, | ||
} | ||
logger := testlog.Logger(t, log.LevelError) | ||
err := ValidateClaim(logger, uint64(0), eth.Bytes32{0x11}, l2) | ||
require.ErrorIs(t, err, expectedErr) | ||
}) | ||
t.Run("Error-output-root", func(t *testing.T) { | ||
expectedErr := errors.New("boom") | ||
l2 := &mockL2{ | ||
outputRoot: eth.Bytes32{0x11}, | ||
outputRootErr: expectedErr, | ||
safeL2: eth.L2BlockRef{Number: 10}, | ||
} | ||
logger := testlog.Logger(t, log.LevelError) | ||
err := ValidateClaim(logger, uint64(0), eth.Bytes32{0x11}, l2) | ||
require.ErrorIs(t, err, expectedErr) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters