Skip to content

Commit

Permalink
op-challenger: implement NewSplitProviderSelector2 for pre/post outpu…
Browse files Browse the repository at this point in the history
…tRoot and findAncestorProofAtDepth2 for stepProof
  • Loading branch information
dajuguan committed Oct 29, 2024
1 parent 4784022 commit 23e1ba6
Show file tree
Hide file tree
Showing 9 changed files with 742 additions and 135 deletions.
10 changes: 9 additions & 1 deletion op-challenger/game/fault/test/claim_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type claimCfg struct {
parentIdx int
clockTimestamp time.Time
clockDuration time.Duration
branch uint64
}

func newClaimCfg(opts ...ClaimOpt) *claimCfg {
Expand Down Expand Up @@ -75,6 +76,12 @@ func WithClock(timestamp time.Time, duration time.Duration) ClaimOpt {
})
}

func WithBranch(branch uint64) ClaimOpt {
return claimOptFn(func(cfg *claimCfg) {
cfg.branch = branch
})
}

// ClaimBuilder is a test utility to enable creating claims in a wide range of situations
type ClaimBuilder struct {
require *require.Assertions
Expand Down Expand Up @@ -141,6 +148,7 @@ func (c *ClaimBuilder) claim(pos types.Position, opts ...ClaimOpt) types.Claim {
Duration: cfg.clockDuration,
Timestamp: cfg.clockTimestamp,
},
AttackBranch: cfg.branch,
}
if cfg.claimant != (common.Address{}) {
claim.Claimant = cfg.claimant
Expand Down Expand Up @@ -197,5 +205,5 @@ func GetClaimsHash(values []common.Hash) common.Hash {
func (c *ClaimBuilder) AttackClaim2(claim types.Claim, subClaims []common.Hash, nbits uint64, branch uint64, opts ...ClaimOpt) types.Claim {
pos := claim.Position.Attack2(nbits, branch)
topClaim := GetClaimsHash(subClaims)
return c.claim(pos, append([]ClaimOpt{WithParent(claim), WithValue(topClaim)}, opts...)...)
return c.claim(pos, append([]ClaimOpt{WithParent(claim), WithValue(topClaim), WithBranch(branch)}, opts...)...)
}
8 changes: 5 additions & 3 deletions op-challenger/game/fault/test/game_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ func (c *ClaimBuilder) GameBuilder(rootOpts ...ClaimOpt) *GameBuilder {
}
}

func (c *ClaimBuilder) GameBuilder2(nary int64, rootOpts ...ClaimOpt) *GameBuilder {
func (c *ClaimBuilder) GameBuilder2(nary int64, splitDepth types.Depth, rootOpts ...ClaimOpt) *GameBuilder {
return &GameBuilder{
builder: c,
Game: types.NewGameState2([]types.Claim{c.CreateRootClaim(rootOpts...)}, c.maxDepth, nary, make(map[types.ClaimID][]common.Hash)),
Game: types.NewGameState2([]types.Claim{c.CreateRootClaim(rootOpts...)}, c.maxDepth, splitDepth, nary, make(map[types.ClaimID][]common.Hash)),
}
}

Expand Down Expand Up @@ -82,7 +82,9 @@ func (s *GameBuilderSeq) addClaimAndSubClaimsToGame(claim *types.Claim, subClaim
claims := append(s.gameBuilder.Game.Claims(), *claim)
allSubClaims := s.gameBuilder.Game.SubClaims()
allSubClaims[claim.ID()] = subClaims
s.gameBuilder.Game = types.NewGameState2(claims, s.builder.maxDepth, s.gameBuilder.Game.Nary().Int64(), allSubClaims)
splitDepth := s.gameBuilder.Game.SplitDepth()
nary := s.gameBuilder.Game.Nary().Int64()
s.gameBuilder.Game = types.NewGameState2(claims, s.builder.maxDepth, splitDepth, nary, allSubClaims)
}

func (s *GameBuilderSeq) Attack(opts ...ClaimOpt) *GameBuilderSeq {
Expand Down
124 changes: 122 additions & 2 deletions op-challenger/game/fault/trace/access2.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,138 @@ package trace

import (
"context"
"fmt"
"math/big"

"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
)

// Get the traceIdx's accestor claims hash and its merkel proof in subclaims. traceIdx can be ref's traceIdx ±1.
// Params:
// - relativeTraceIdx: the trace index relative to splitDepth
func findAncestorProofAtDepth2(ctx context.Context, provider types.TraceProvider, game types.Game, ref types.Claim, relativeTraceIdx *big.Int) (types.DAItem, error) {
maxTraceDepth := game.MaxDepth() - game.SplitDepth()
// Find the ancestor claim at the (splitDepth + 1) level.
splitLeaf, err := FindAncestorAtDepth(game, ref, types.Depth(game.SplitDepth()+game.NBits()))
if err != nil {
return types.DAItem{}, err
}
// If traceIdx equals -1, the absolute prestate is returned.
if relativeTraceIdx.Cmp(big.NewInt(-1)) == 0 {
absolutePresate, err := provider.AbsolutePreStateCommitment(ctx)
if err != nil {
return types.DAItem{}, fmt.Errorf("failed to get absolutePrestate: %w", err)
}
return types.DAItem{
DaType: types.CallDataType,
DataHash: absolutePresate.Bytes(),
Proof: []byte{},
}, nil
}

// If traceIdx is the right most branch, the root Claim is returned.
if new(big.Int).Add(relativeTraceIdx, big.NewInt(1)).Cmp(new(big.Int).Lsh(big.NewInt(1), uint(maxTraceDepth-game.NBits()))) == 0 {
return types.DAItem{
DaType: types.CallDataType,
DataHash: splitLeaf.Value.Bytes(),
Proof: []byte{},
}, nil
}

ancestor := ref
relativeAncestorPos, err := ancestor.RelativeToAncestorAtDepth(game.SplitDepth())
if err != nil {
return types.DAItem{}, err
}
minTraceIndex := relativeAncestorPos.TraceIndex(maxTraceDepth)
offset := new(big.Int).Lsh(big.NewInt(int64(game.MaxAttackBranch())-1), uint(maxTraceDepth-relativeAncestorPos.Depth()))
maxTraceIndex := new(big.Int).Add(minTraceIndex, offset)
// If Ancestor's left most branch traceIdx <= traceId <= Ancestor's rightmost branch traceIdx, we do nothing;
// otherwise, we should trace the correct ancestor
for minTraceIndex.Cmp(relativeTraceIdx) == 1 || maxTraceIndex.Cmp(relativeTraceIdx) == -1 {
parent, err := game.GetParent(ancestor)
if err != nil {
return types.DAItem{}, fmt.Errorf("failed to get ancestor of claim %v: %w", ancestor.ContractIndex, err)
}

ancestor = parent
relativeAncestorPos, err = ancestor.RelativeToAncestorAtDepth(game.SplitDepth())
if err != nil {
return types.DAItem{}, err
}
minTraceIndex = relativeAncestorPos.TraceIndex(maxTraceDepth)
offset = new(big.Int).Lsh(big.NewInt(int64(game.MaxAttackBranch())-1), uint(maxTraceDepth-relativeAncestorPos.Depth()))
maxTraceIndex = new(big.Int).Add(minTraceIndex, offset)
}

branch := new(big.Int).Div(new(big.Int).Sub(relativeTraceIdx, minTraceIndex), new(big.Int).Lsh(big.NewInt(1), uint(maxTraceDepth-relativeAncestorPos.Depth()))).Int64()
subclaims, err := game.GetSubClaims(ancestor)
if err != nil {
return types.DAItem{}, fmt.Errorf("failed to get subclaims of claim %v: %w", ref.ContractIndex, err)
}

ancestorClaim := subclaims[branch]
merkleProof := make([]byte, 0)
for i := int64(0); i < branch; i++ {
merkleProof = append(merkleProof, subclaims[i].Bytes()...)
}

for i := branch + 1; i < int64(game.MaxAttackBranch()); i++ {
merkleProof = append(merkleProof, subclaims[i].Bytes()...)
}

return types.DAItem{
DaType: types.CallDataType,
DataHash: ancestorClaim.Bytes(),
Proof: merkleProof,
}, nil
}

// Params:
// - ref: the attacked claim
// - pos: next attacking position (global) for the ref claim.
func (t *Accessor) GetStepData2(ctx context.Context, game types.Game, ref types.Claim, pos types.Position) (prestate []byte, proofData []byte, preimageData *types.PreimageOracleData, err error) {
// Get oracle data
// prestate, proofData, preimageData, err = t.GetStepData(ctx, game, ref, pos)
provider, err := t.selector(ctx, game, ref, pos)
if err != nil {
return nil, nil, nil, err
}
parentPos, err := game.GetParent(ref)
prestate, proofData, preimageData, err = provider.GetStepData2(ctx, pos, pos)
if err != nil {
return nil, nil, nil, err
}
return provider.GetStepData2(ctx, pos, parentPos.Position)
// Get stepProof for stepV2
relativePos, err := pos.RelativeToAncestorAtDepth(game.SplitDepth())
if err != nil {
return nil, nil, nil, err
}
postTraceIdx := relativePos.TraceIndex(game.MaxDepth())
preTraceIdx := new(big.Int).Sub(postTraceIdx, big.NewInt(1))
preStateDaItem, err := findAncestorProofAtDepth2(ctx, provider, game, ref, preTraceIdx)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to get postStateDaItem at trace index %v: %w", preTraceIdx, err)
}
postStateDaItem, err := findAncestorProofAtDepth2(ctx, provider, game, ref, postTraceIdx)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to get postStateDaItem at trace index %v: %w", postTraceIdx, err)
}
StepProof := types.StepProofData{
Prestate: preStateDaItem,
PostState: postStateDaItem,
}

preimageData.StepProof = StepProof
return prestate, proofData, preimageData, nil
}

func FindAncestorAtDepth(game types.Game, claim types.Claim, depth types.Depth) (types.Claim, error) {
for claim.Depth() > depth {
parent, err := game.GetParent(claim)
if err != nil {
return types.Claim{}, fmt.Errorf("failed to find ancestor at depth %v: %w", depth, err)
}
claim = parent
}
return claim, nil
}
Loading

0 comments on commit 23e1ba6

Please sign in to comment.