Commit f7c50027 authored by Adrian Sutton's avatar Adrian Sutton Committed by GitHub

cannon: Support stopping at specific types of preimages not just local or keccak (#9406)

parent 66943d0c
......@@ -66,7 +66,7 @@ var (
}
RunStopAtPreimageTypeFlag = &cli.StringFlag{
Name: "stop-at-preimage-type",
Usage: "stop at the first preimage request matching this type (must be either 'any', 'local' or 'global')",
Usage: "stop at the first preimage request matching this type",
Required: false,
}
RunStopAtPreimageLargerThanFlag = &cli.StringFlag{
......@@ -243,9 +243,23 @@ func Run(ctx *cli.Context) error {
outLog := &mipsevm.LoggingWriter{Name: "program std-out", Log: l}
errLog := &mipsevm.LoggingWriter{Name: "program std-err", Log: l}
stopAtPreimageType := ctx.String(RunStopAtPreimageTypeFlag.Name)
if stopAtPreimageType != "" && stopAtPreimageType != "any" && stopAtPreimageType != "local" && stopAtPreimageType != "global" {
return fmt.Errorf("invalid preimage type %q, must be either 'any', 'local' or 'global'", stopAtPreimageType)
stopAtAnyPreimage := false
var stopAtPreimageTypeByte preimage.KeyType
switch ctx.String(RunStopAtPreimageTypeFlag.Name) {
case "local":
stopAtPreimageTypeByte = preimage.LocalKeyType
case "keccak":
stopAtPreimageTypeByte = preimage.Keccak256KeyType
case "sha256":
stopAtPreimageTypeByte = preimage.Sha256KeyType
case "blob":
stopAtPreimageTypeByte = preimage.BlobKeyType
case "any":
stopAtAnyPreimage = true
case "":
// 0 preimage type is forbidden so will not stop at any preimage
default:
return fmt.Errorf("invalid preimage type %q", ctx.String(RunStopAtPreimageTypeFlag.Name))
}
stopAtPreimageLargerThan := ctx.Int(RunStopAtPreimageLargerThanFlag.Name)
......@@ -380,17 +394,11 @@ func Run(ctx *cli.Context) error {
}
if preimageRead := state.PreimageOffset > prevPreimageOffset; preimageRead {
if stopAtPreimageType == "any" {
if stopAtAnyPreimage {
break
}
if stopAtPreimageType != "" {
keyType := byte(preimage.LocalKeyType)
if stopAtPreimageType == "global" {
keyType = byte(preimage.Keccak256KeyType)
}
if state.PreimageKey.Bytes()[0] == keyType {
break
}
if state.PreimageKey.Bytes()[0] == byte(stopAtPreimageTypeByte) {
break
}
if stopAtPreimageLargerThan != 0 && len(us.LastPreimage()) > stopAtPreimageLargerThan {
break
......
......@@ -252,12 +252,16 @@ type preimageOpts []string
type PreimageOpt func() preimageOpts
func FirstGlobalPreimageLoad() PreimageOpt {
func FirstPreimageLoadOfType(preimageType string) PreimageOpt {
return func() preimageOpts {
return []string{"--stop-at-preimage-type", "global"}
return []string{"--stop-at-preimage-type", preimageType}
}
}
func FirstKeccakPreimageLoad() PreimageOpt {
return FirstPreimageLoadOfType("keccak")
}
func PreimageLargerThan(size int) PreimageOpt {
return func() preimageOpts {
return []string{"--stop-at-preimage-larger-than", strconv.Itoa(size)}
......
......@@ -209,6 +209,7 @@ func (g *OutputCannonGameHelper) ChallengeToPreimageLoad(ctx context.Context, ou
// Now the preimage is available wait for the step call to succeed.
leafClaim.WaitForCountered(ctx)
g.LogGameData(ctx)
}
func (g *OutputCannonGameHelper) createCannonTraceProvider(ctx context.Context, l2Node string, outputRootClaim *ClaimHelper, options ...challenger.Option) *cannon.CannonTraceProviderForTest {
......
......@@ -254,11 +254,11 @@ func TestOutputCannonStepWithLargePreimage(t *testing.T) {
}
func TestOutputCannonStepWithPreimage(t *testing.T) {
testPreimageStep := func(t *testing.T, preloadPreimage bool) {
testPreimageStep := func(t *testing.T, preimageType cannon.PreimageOpt, preloadPreimage bool) {
op_e2e.InitParallel(t, op_e2e.UsesCannon)
ctx := context.Background()
sys, l1Client := startFaultDisputeSystem(t)
sys, _ := startFaultDisputeSystem(t)
t.Cleanup(sys.Close)
disputeGameFactory := disputegame.NewFactoryHelper(t, ctx, sys)
......@@ -276,20 +276,16 @@ func TestOutputCannonStepWithPreimage(t *testing.T) {
// Now the honest challenger is positioned as the defender of the execution game
// We then move to challenge it to induce a preimage load
preimageLoadCheck := game.CreateStepPreimageLoadCheck(ctx)
game.ChallengeToPreimageLoad(ctx, outputRootClaim, sys.Cfg.Secrets.Alice, cannon.FirstGlobalPreimageLoad(), preimageLoadCheck, preloadPreimage)
sys.TimeTravelClock.AdvanceTime(game.GameDuration(ctx))
require.NoError(t, wait.ForNextBlock(ctx, l1Client))
game.WaitForInactivity(ctx, 10, true)
game.LogGameData(ctx)
require.EqualValues(t, disputegame.StatusChallengerWins, game.Status(ctx))
game.ChallengeToPreimageLoad(ctx, outputRootClaim, sys.Cfg.Secrets.Alice, preimageType, preimageLoadCheck, preloadPreimage)
// The above method already verified the image was uploaded and step called successfully
// So we don't waste time resolving the game - that's tested elsewhere.
}
t.Run("non-existing preimage", func(t *testing.T) {
testPreimageStep(t, false)
testPreimageStep(t, cannon.FirstKeccakPreimageLoad(), false)
})
t.Run("preimage already exists", func(t *testing.T) {
testPreimageStep(t, true)
testPreimageStep(t, cannon.FirstKeccakPreimageLoad(), true)
})
}
......
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