diff --git a/op-challenger/game/fault/contracts/faultdisputegame.go b/op-challenger/game/fault/contracts/faultdisputegame.go index a1300e225075..e44380f2daff 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame.go +++ b/op-challenger/game/fault/contracts/faultdisputegame.go @@ -13,7 +13,6 @@ import ( "github.com/ethereum-optimism/optimism/op-challenger/game/fault/contracts/metrics" "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" gameTypes "github.com/ethereum-optimism/optimism/op-challenger/game/types" - "github.com/ethereum-optimism/optimism/op-e2e/bindings" "github.com/ethereum-optimism/optimism/op-service/sources/batching" "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum-optimism/optimism/op-service/txmgr" @@ -444,57 +443,6 @@ func (f *FaultDisputeGameContractLatest) GetAllClaims(ctx context.Context, block return claims, nil } -func (f *FaultDisputeGameContractLatest) GetSubClaims(ctx context.Context, block rpcblock.Block, aggClaim *types.Claim) ([]common.Hash, error) { - defer f.metrics.StartContractRequest("GetAllSubClaims")() - - filter, err := bindings.NewFaultDisputeGameFilterer(f.contract.Addr(), f.multiCaller) - if err != nil { - return nil, err - } - - parentIndex := [...]*big.Int{big.NewInt(int64(aggClaim.ParentContractIndex))} - claim := [...][32]byte{aggClaim.ClaimData.ValueBytes()} - claimant := [...]common.Address{aggClaim.Claimant} - moveIter, err := filter.FilterMove(nil, parentIndex[:], claim[:], claimant[:]) - if err != nil { - return nil, fmt.Errorf("failed to filter move event log: %w", err) - } - ok := moveIter.Next() - if !ok { - return nil, fmt.Errorf("failed to get move event log: %w", moveIter.Error()) - } - txHash := moveIter.Event.Raw.TxHash - - // todo: replace hardcoded method name - txCall := batching.NewTxGetByHash(f.contract.Abi(), txHash, "move") - result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, txCall) - if err != nil { - return nil, fmt.Errorf("failed to load claim calldata: %w", err) - } - - txn, err := txCall.DecodeToTx(result) - if err != nil { - return nil, fmt.Errorf("failed to decode tx: %w", err) - } - - var subValues []common.Hash - - if len(txn.BlobHashes()) > 0 { - // todo: fetch Blobs and unpack it into subValues - return nil, fmt.Errorf("blob tx hasn't been supported") - } else { - inputMap, err := txCall.UnpackCallData(txn) - if err != nil { - return nil, fmt.Errorf("failed to unpack tx resp: %w", err) - } - // todo: replace claim with nary-subValues - claim := *abi.ConvertType(inputMap[subClaimField], new([32]byte)).(*[32]byte) - subValues = append(subValues, claim) - } - - return subValues, nil -} - func (f *FaultDisputeGameContractLatest) IsResolved(ctx context.Context, block rpcblock.Block, claims ...types.Claim) ([]bool, error) { defer f.metrics.StartContractRequest("IsResolved")() calls := make([]batching.Call, 0, len(claims)) @@ -677,5 +625,5 @@ type FaultDisputeGameContract interface { ResolveClaimTx(claimIdx uint64) (txmgr.TxCandidate, error) CallResolve(ctx context.Context) (gameTypes.GameStatus, error) ResolveTx() (txmgr.TxCandidate, error) - GetSubClaims(ctx context.Context, block rpcblock.Block, aggClaim *types.Claim) ([]common.Hash, error) + GetSubValues(ctx context.Context, block rpcblock.Block, aggClaim *types.Claim) ([]common.Hash, error) } diff --git a/op-challenger/game/fault/contracts/faultdisputegame2.go b/op-challenger/game/fault/contracts/faultdisputegame2.go new file mode 100644 index 000000000000..921fdace6bae --- /dev/null +++ b/op-challenger/game/fault/contracts/faultdisputegame2.go @@ -0,0 +1,87 @@ +package contracts + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum-optimism/optimism/op-challenger/game/fault/types" + "github.com/ethereum-optimism/optimism/op-e2e/bindings" + "github.com/ethereum-optimism/optimism/op-service/sources/batching" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" +) + +func (f *FaultDisputeGameContractLatest) GetAllClaimsWithSubValues(ctx context.Context, block rpcblock.Block) ([]types.Claim, error) { + defer f.metrics.StartContractRequest("GetAllClaims")() + results, err := batching.ReadArray(ctx, f.multiCaller, block, f.contract.Call(methodClaimCount), func(i *big.Int) *batching.ContractCall { + return f.contract.Call(methodClaim, i) + }) + if err != nil { + return nil, fmt.Errorf("failed to load claims: %w", err) + } + + var claims []types.Claim + for idx, result := range results { + claim := f.decodeClaim(result, idx) + subValues, err := f.GetSubValues(ctx, block, &claim) + if err != nil { + return nil, fmt.Errorf("failed to load subValues for claim %s: %w", claim, err) + } + claim.SetSubValues(&subValues) + claims = append(claims, claim) + } + return claims, nil +} + +func (f *FaultDisputeGameContractLatest) GetSubValues(ctx context.Context, block rpcblock.Block, aggClaim *types.Claim) ([]common.Hash, error) { + defer f.metrics.StartContractRequest("GetAllSubValues")() + + filter, err := bindings.NewFaultDisputeGameFilterer(f.contract.Addr(), f.multiCaller) + if err != nil { + return nil, err + } + + parentIndex := [...]*big.Int{big.NewInt(int64(aggClaim.ParentContractIndex))} + claim := [...][32]byte{aggClaim.ClaimData.ValueBytes()} + claimant := [...]common.Address{aggClaim.Claimant} + moveIter, err := filter.FilterMove(nil, parentIndex[:], claim[:], claimant[:]) + if err != nil { + return nil, fmt.Errorf("failed to filter move event log: %w", err) + } + ok := moveIter.Next() + if !ok { + return nil, fmt.Errorf("failed to get move event log: %w", moveIter.Error()) + } + txHash := moveIter.Event.Raw.TxHash + + // todo: replace hardcoded method name + txCall := batching.NewTxGetByHash(f.contract.Abi(), txHash, "move") + result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, txCall) + if err != nil { + return nil, fmt.Errorf("failed to load claim calldata: %w", err) + } + + txn, err := txCall.DecodeToTx(result) + if err != nil { + return nil, fmt.Errorf("failed to decode tx: %w", err) + } + + var subValues []common.Hash + + if len(txn.BlobHashes()) > 0 { + // todo: fetch Blobs and unpack it into subValues + return nil, fmt.Errorf("blob tx hasn't been supported") + } else { + inputMap, err := txCall.UnpackCallData(txn) + if err != nil { + return nil, fmt.Errorf("failed to unpack tx resp: %w", err) + } + // todo: replace claim with nary-subValues + claim := *abi.ConvertType(inputMap[subClaimField], new([32]byte)).(*[32]byte) + subValues = append(subValues, claim) + } + + return subValues, nil +} diff --git a/op-challenger/game/fault/contracts/faultdisputegame_test.go b/op-challenger/game/fault/contracts/faultdisputegame_test.go index 387b34b84175..e5d99b6ba1ff 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame_test.go +++ b/op-challenger/game/fault/contracts/faultdisputegame_test.go @@ -390,7 +390,7 @@ func TestGetSubClaims(t *testing.T) { require.NoError(t, err) stubRpc.SetTxResponse(txHash, packed) - claims, err := game.GetSubClaims(context.Background(), block, &claim0) + claims, err := game.GetSubValues(context.Background(), block, &claim0) require.NoError(t, err) require.Equal(t, 1, len(claims)) require.Equal(t, claim0.ClaimData.Value, claims[0]) diff --git a/op-challenger/game/fault/solver/solver2.go b/op-challenger/game/fault/solver/solver2.go index 603531cb88d3..c71bceda62cf 100644 --- a/op-challenger/game/fault/solver/solver2.go +++ b/op-challenger/game/fault/solver/solver2.go @@ -52,6 +52,3 @@ func (s *claimSolver) AttemptStep2(ctx context.Context, game types.Game, claim t OracleData: oracleData, }, nil } - - -func findPrestateItem() \ No newline at end of file