diff --git a/op-challenger/game/fault/contracts/faultdisputegame2.go b/op-challenger/game/fault/contracts/faultdisputegame2.go index bad905dd24d6..e447eba9e615 100644 --- a/op-challenger/game/fault/contracts/faultdisputegame2.go +++ b/op-challenger/game/fault/contracts/faultdisputegame2.go @@ -10,7 +10,9 @@ import ( "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/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" ) func (f *FaultDisputeGameContractLatest) GetSubClaims(ctx context.Context, block rpcblock.Block, aggClaim *types.Claim) ([]common.Hash, error) { @@ -24,7 +26,18 @@ func (f *FaultDisputeGameContractLatest) GetSubClaims(ctx context.Context, block 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[:]) + var end *uint64 + if block.ArgValue() == rpcblock.Latest { + end = nil + } else { + blockNumber, ok := block.ArgValue().(rpc.BlockNumber) + if !ok { + return nil, fmt.Errorf("block number is not lastest or int64") + } + blockNumberU64 := uint64(blockNumber) + end = &blockNumberU64 + } + moveIter, err := filter.FilterMove(&bind.FilterOpts{End: end, Context: ctx}, parentIndex[:], claim[:], claimant[:]) if err != nil { return nil, fmt.Errorf("failed to filter move event log: %w", err) } @@ -36,15 +49,12 @@ func (f *FaultDisputeGameContractLatest) GetSubClaims(ctx context.Context, block // todo: replace hardcoded method name txCall := batching.NewTxGetByHash(f.contract.Abi(), txHash, "move") - result, err := f.multiCaller.SingleCall(ctx, rpcblock.Latest, txCall) + result, err := f.multiCaller.SingleCall(ctx, block, 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) - } + txn := result.GetTx() var subClaims []common.Hash @@ -52,7 +62,7 @@ func (f *FaultDisputeGameContractLatest) GetSubClaims(ctx context.Context, block // todo: fetch Blobs and unpack it into subClaims return nil, fmt.Errorf("blob tx hasn't been supported") } else { - inputMap, err := txCall.UnpackCallData(txn) + inputMap, err := txCall.UnpackCallData(&txn) if err != nil { return nil, fmt.Errorf("failed to unpack tx resp: %w", err) } diff --git a/op-service/sources/batching/call.go b/op-service/sources/batching/call.go index db4563b64258..6784d8ba04cb 100644 --- a/op-service/sources/batching/call.go +++ b/op-service/sources/batching/call.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" ) @@ -67,3 +68,7 @@ func (c *CallResult) GetBytes32Slice(i int) [][32]byte { func (c *CallResult) GetString(i int) string { return *abi.ConvertType(c.out[i], new(string)).(*string) } + +func (c *CallResult) GetTx() types.Transaction { + return *abi.ConvertType(c.out[0], new(types.Transaction)).(*types.Transaction) +} diff --git a/op-service/sources/batching/test/event_stub.go b/op-service/sources/batching/test/event_stub.go index 4c08284dba2b..6b46d385f819 100644 --- a/op-service/sources/batching/test/event_stub.go +++ b/op-service/sources/batching/test/event_stub.go @@ -25,7 +25,10 @@ func (c *expectedFilterLogsCall) Matches(rpcMethod string, args ...interface{}) return fmt.Errorf("expected rpcMethod eth_getFilterLogs but was %v", rpcMethod) } - topics := args[0].([][]common.Hash) + topics, ok := args[0].([][]common.Hash) + if !ok { + return fmt.Errorf("arg 0 is not [][]common.Hash") + } if !reflect.DeepEqual(topics, c.topics) { return fmt.Errorf("expected topics %v but was %v", c.topics, topics) diff --git a/op-service/sources/batching/test/tx_stub.go b/op-service/sources/batching/test/tx_stub.go index a513a215e68f..4b14a7592781 100644 --- a/op-service/sources/batching/test/tx_stub.go +++ b/op-service/sources/batching/test/tx_stub.go @@ -21,7 +21,10 @@ func (c *expectedGetTxByHashCall) Matches(rpcMethod string, args ...interface{}) return fmt.Errorf("expected rpcMethod eth_getTransactionByHash but was %v", rpcMethod) } - txhash := args[0].(common.Hash) + txhash, ok := args[0].(common.Hash) + if !ok { + return fmt.Errorf("arg 0 is not common.Hash") + } if txhash != c.txHash { return fmt.Errorf("expected txHash %v but was %v", c.txHash, txhash) diff --git a/op-service/sources/batching/tx_call.go b/op-service/sources/batching/tx_call.go index 9f5487a68f4e..de3d223e2e5d 100644 --- a/op-service/sources/batching/tx_call.go +++ b/op-service/sources/batching/tx_call.go @@ -1,6 +1,8 @@ package batching import ( + "fmt" + "github.com/ethereum-optimism/optimism/op-service/sources/batching/rpcblock" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -35,11 +37,21 @@ func (b *TxGetByHashCall) ToBatchElemCreator() (BatchElementCreator, error) { } func (c *TxGetByHashCall) HandleResult(result interface{}) (*CallResult, error) { - res := result.(*hexutil.Bytes) - return &CallResult{out: []interface{}{*res}}, nil + res, ok := result.(*hexutil.Bytes) + if !ok { + return nil, fmt.Errorf("result is not hexutil.Bytes") + } + + txn := new(types.Transaction) + err := txn.UnmarshalBinary(*res) + if err != nil { + return nil, err + } + return &CallResult{out: []interface{}{txn}}, nil } -func (c *TxGetByHashCall) DecodeTxParams(data []byte) (map[string]interface{}, error) { +func (c *TxGetByHashCall) UnpackCallData(txn *types.Transaction) (map[string]interface{}, error) { + data := txn.Data() m, err := c.Abi.MethodById(data[:4]) v := map[string]interface{}{} if err != nil { @@ -50,18 +62,3 @@ func (c *TxGetByHashCall) DecodeTxParams(data []byte) (map[string]interface{}, e } return v, nil } - -func (c *TxGetByHashCall) DecodeToTx(res *CallResult) (*types.Transaction, error) { - txn := new(types.Transaction) - hex := res.out[0].(hexutil.Bytes) - err := txn.UnmarshalBinary(hex) - if err != nil { - return nil, err - } - return txn, nil -} - -func (c *TxGetByHashCall) UnpackCallData(txn *types.Transaction) (map[string]interface{}, error) { - input := txn.Data() - return c.DecodeTxParams(input) -} diff --git a/op-service/sources/batching/tx_call_test.go b/op-service/sources/batching/tx_call_test.go index 2b4440df33e4..7dfdefb88335 100644 --- a/op-service/sources/batching/tx_call_test.go +++ b/op-service/sources/batching/tx_call_test.go @@ -12,23 +12,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestDecodeTxGetByHash(t *testing.T) { - addr := common.Address{0xbd} - testAbi, err := test.ERC20MetaData.GetAbi() - require.NoError(t, err) - call := NewTxGetByHash(testAbi, common.Hash{0xcc}, "approve") - expectedAmount := big.NewInt(1234444) - expectedSpender := common.Address{0xcc} - contractCall := NewContractCall(testAbi, addr, "approve", expectedSpender, expectedAmount) - packed, err := contractCall.Pack() - require.NoError(t, err) - - unpackedMap, err := call.DecodeTxParams(packed) - require.NoError(t, err) - require.Equal(t, expectedAmount, unpackedMap["amount"]) - require.Equal(t, expectedSpender, unpackedMap["spender"]) -} - func TestUnpackTxCalldata(t *testing.T) { expectedSpender := common.Address{0xcc} expectedAmount := big.NewInt(1234444) @@ -59,9 +42,8 @@ func TestUnpackTxCalldata(t *testing.T) { result, err := caller.SingleCall(context.Background(), rpcblock.Latest, txCall) require.NoError(t, err) - decodedTx, err := txCall.DecodeToTx(result) - require.NoError(t, err) - unpackedMap, err := txCall.UnpackCallData(decodedTx) + decodedTx := result.GetTx() + unpackedMap, err := txCall.UnpackCallData(&decodedTx) require.NoError(t, err) require.Equal(t, expectedSpender, unpackedMap["spender"]) require.Equal(t, expectedAmount, unpackedMap["amount"])