From 6b5967afd8f069510972c4cdb43e834a38b9d16b Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Mon, 2 Dec 2024 14:43:32 +0700 Subject: [PATCH] delete unused test data. remove useless v2 helper methods. update tests --- accounts/abi/bind/base.go | 17 +- accounts/abi/bind/lib.go | 5 - accounts/abi/bind/testdata/v2/bindings.go | 0 .../testdata/v2/return_structs/bindings.go | 84 ------ .../v2/return_structs/combined-abi.json | 1 - .../testdata/v2/return_structs/contract.sol | 8 - .../abi/bind/testdata/v2/simple/contract.sol | 6 - accounts/abi/bind/v2/lib.go | 141 ----------- accounts/abi/bind/v2/lib_test.go | 239 ++++-------------- 9 files changed, 57 insertions(+), 444 deletions(-) delete mode 100644 accounts/abi/bind/testdata/v2/bindings.go delete mode 100644 accounts/abi/bind/testdata/v2/return_structs/bindings.go delete mode 100644 accounts/abi/bind/testdata/v2/return_structs/combined-abi.json delete mode 100644 accounts/abi/bind/testdata/v2/return_structs/contract.sol delete mode 100644 accounts/abi/bind/testdata/v2/simple/contract.sol diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index a0c4dc3d08..690766f7b5 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -152,6 +152,9 @@ func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend Co return c.address, tx, c, nil } +// DeployContractRaw deploys a contract onto the Ethereum blockchain and binds the +// deployment address with a Go wrapper. It expects its parameters to be abi-encoded +// bytes. func DeployContractRaw(opts *TransactOpts, bytecode []byte, backend ContractBackend, packedParams []byte) (common.Address, *types.Transaction, *BoundContract, error) { c := NewBoundContract(common.Address{}, abi.ABI{}, backend, backend, backend) @@ -402,7 +405,7 @@ func (c *BoundContract) estimateGasLimit(opts *TransactOpts, contract *common.Ad } res, err := c.transactor.EstimateGas(ensureContext(opts.Context), msg) if err != nil { - panic(err) + return 0, err } return res, nil } @@ -463,17 +466,17 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i // FilterLogsByID filters contract logs for past blocks, returning the necessary // channels to construct a strongly typed bound iterator on top of them. -func (c *BoundContract) FilterLogsByID(opts *FilterOpts, eventID common.Hash, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) FilterLogsByID(opts *FilterOpts, eventID common.Hash, query ...[]interface{}) (<-chan types.Log, event.Subscription, error) { return c.filterLogs(opts, eventID, query...) } // FilterLogs filters contract logs for past blocks, returning the necessary // channels to construct a strongly typed bound iterator on top of them. -func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]interface{}) (<-chan types.Log, event.Subscription, error) { return c.filterLogs(opts, c.abi.Events[name].ID, query...) } -func (c *BoundContract) filterLogs(opts *FilterOpts, eventID common.Hash, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) filterLogs(opts *FilterOpts, eventID common.Hash, query ...[]interface{}) (<-chan types.Log, event.Subscription, error) { // Don't crash on a lazy user if opts == nil { opts = new(FilterOpts) @@ -518,17 +521,17 @@ func (c *BoundContract) filterLogs(opts *FilterOpts, eventID common.Hash, query // WatchLogs filters subscribes to contract logs for future blocks, returning a // subscription object that can be used to tear down the watcher. -func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]interface{}) (<-chan types.Log, event.Subscription, error) { return c.watchLogs(opts, c.abi.Events[name].ID, query...) } // WatchLogsForId filters subscribes to contract logs for future blocks, returning a // subscription object that can be used to tear down the watcher. -func (c *BoundContract) WatchLogsForId(opts *WatchOpts, id common.Hash, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) WatchLogsForId(opts *WatchOpts, id common.Hash, query ...[]interface{}) (<-chan types.Log, event.Subscription, error) { return c.watchLogs(opts, id, query...) } -func (c *BoundContract) watchLogs(opts *WatchOpts, eventID common.Hash, query ...[]interface{}) (chan types.Log, event.Subscription, error) { +func (c *BoundContract) watchLogs(opts *WatchOpts, eventID common.Hash, query ...[]interface{}) (<-chan types.Log, event.Subscription, error) { // Don't crash on a lazy user if opts == nil { opts = new(WatchOpts) diff --git a/accounts/abi/bind/lib.go b/accounts/abi/bind/lib.go index 3ab6a8aee6..2ffb0dec51 100644 --- a/accounts/abi/bind/lib.go +++ b/accounts/abi/bind/lib.go @@ -26,8 +26,3 @@ type ContractInstance interface { Address() common.Address Backend() ContractBackend } - -type ContractInstanceV2 interface { - Address() common.Address - Backend() ContractBackend -} diff --git a/accounts/abi/bind/testdata/v2/bindings.go b/accounts/abi/bind/testdata/v2/bindings.go deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accounts/abi/bind/testdata/v2/return_structs/bindings.go b/accounts/abi/bind/testdata/v2/return_structs/bindings.go deleted file mode 100644 index 959da73e96..0000000000 --- a/accounts/abi/bind/testdata/v2/return_structs/bindings.go +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated via abigen V2 - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package return_structs - -import ( - "errors" - "math/big" - - "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/core/types" -) - -// Reference imports to suppress solc_errors if they are not otherwise used. -var ( - _ = errors.New - _ = big.NewInt - _ = bind.Bind - _ = common.Big1 - _ = types.BloomLookup - _ = abi.ConvertType -) - -var CLibraryDeps = []*bind.MetaData{} - -// TODO: convert this type to value type after everything works. -// CMetaData contains all meta data concerning the C contract. -var CMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"DoSomethingWithManyArgs\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]", - Pattern: "55ef3c19a0ab1c1845f9e347540c1e51f5", - Bin: "0x6080604052348015600e575f80fd5b5060fc8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80636fd8b96814602a575b5f80fd5b60306047565b604051603e9493929190608b565b60405180910390f35b5f805f805f805f80935093509350935090919293565b5f819050919050565b606d81605d565b82525050565b5f8115159050919050565b6085816073565b82525050565b5f608082019050609c5f8301876066565b60a760208301866066565b60b260408301856066565b60bd6060830184607e565b9594505050505056fea2646970667358221220ca49ad4f133bcee385e1656fc277c9fd6546763a73df384f7d5d0fdd3c4808a564736f6c634300081a0033", -} - -// C is an auto generated Go binding around an Ethereum contract. -type C struct { - abi abi.ABI -} - -// NewC creates a new instance of C. -func NewC() (*C, error) { - parsed, err := CMetaData.GetAbi() - if err != nil { - return nil, err - } - return &C{abi: *parsed}, nil -} - -func (_C *C) PackConstructor() ([]byte, error) { - return _C.abi.Pack("") -} - -// DoSomethingWithManyArgs is a free data retrieval call binding the contract method 0x6fd8b968. -// -// Solidity: function DoSomethingWithManyArgs() pure returns(uint256, uint256, uint256, bool) -func (_C *C) PackDoSomethingWithManyArgs() ([]byte, error) { - return _C.abi.Pack("DoSomethingWithManyArgs") -} - -type DoSomethingWithManyArgsOutput struct { - Arg *big.Int - Arg0 *big.Int - Arg1 *big.Int - Arg2 bool -} - -func (_C *C) UnpackDoSomethingWithManyArgs(data []byte) (DoSomethingWithManyArgsOutput, error) { - out, err := _C.abi.Unpack("DoSomethingWithManyArgs", data) - - outstruct := new(DoSomethingWithManyArgsOutput) - if err != nil { - return *outstruct, err - } - - outstruct.Arg = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Arg0 = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.Arg1 = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.Arg2 = *abi.ConvertType(out[3], new(bool)).(*bool) - - return *outstruct, err - -} - diff --git a/accounts/abi/bind/testdata/v2/return_structs/combined-abi.json b/accounts/abi/bind/testdata/v2/return_structs/combined-abi.json deleted file mode 100644 index 8c27f43d42..0000000000 --- a/accounts/abi/bind/testdata/v2/return_structs/combined-abi.json +++ /dev/null @@ -1 +0,0 @@ -{"contracts":{"contract.sol:C":{"abi":[{"inputs":[],"name":"DoSomethingWithManyArgs","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"bin":"6080604052348015600e575f80fd5b5060fc8061001b5f395ff3fe6080604052348015600e575f80fd5b50600436106026575f3560e01c80636fd8b96814602a575b5f80fd5b60306047565b604051603e9493929190608b565b60405180910390f35b5f805f805f805f80935093509350935090919293565b5f819050919050565b606d81605d565b82525050565b5f8115159050919050565b6085816073565b82525050565b5f608082019050609c5f8301876066565b60a760208301866066565b60b260408301856066565b60bd6060830184607e565b9594505050505056fea2646970667358221220ca49ad4f133bcee385e1656fc277c9fd6546763a73df384f7d5d0fdd3c4808a564736f6c634300081a0033"}},"version":"0.8.26+commit.8a97fa7a.Darwin.appleclang"} diff --git a/accounts/abi/bind/testdata/v2/return_structs/contract.sol b/accounts/abi/bind/testdata/v2/return_structs/contract.sol deleted file mode 100644 index 85c517bce0..0000000000 --- a/accounts/abi/bind/testdata/v2/return_structs/contract.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; - -contract C { - function DoSomethingWithManyArgs() public pure returns (uint256, uint256, uint256, bool) { - return(uint256(0), uint256(0), uint256(0), false); - } -} \ No newline at end of file diff --git a/accounts/abi/bind/testdata/v2/simple/contract.sol b/accounts/abi/bind/testdata/v2/simple/contract.sol deleted file mode 100644 index 1e26c0e04d..0000000000 --- a/accounts/abi/bind/testdata/v2/simple/contract.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; - -contract C { - -} \ No newline at end of file diff --git a/accounts/abi/bind/v2/lib.go b/accounts/abi/bind/v2/lib.go index caa6469637..e2658c2357 100644 --- a/accounts/abi/bind/v2/lib.go +++ b/accounts/abi/bind/v2/lib.go @@ -19,22 +19,13 @@ package v2 import ( "encoding/hex" "fmt" - "github.com/ethereum/go-ethereum" - "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/core/types" - "github.com/ethereum/go-ethereum/event" "regexp" "strings" ) -// TODO: it's weird to have a mirror interface of this in the bind package... -type ContractInstance struct { - Address common.Address - Backend bind.ContractBackend -} - // deployContract deploys a hex-encoded contract with the given constructor // input. It returns the deployment transaction, address on success. func deployContract(backend bind.ContractBackend, auth *bind.TransactOpts, constructor []byte, contract string) (deploymentTx *types.Transaction, deploymentAddr common.Address, err error) { @@ -221,135 +212,3 @@ func LinkAndDeploy(auth *bind.TransactOpts, backend bind.ContractBackend, deploy return res, nil } - -// FilterEvents returns an iterator for filtering events that match the query -// parameters (filter range, eventID, topics). If unpack returns an error, -// the iterator value is not updated, and the iterator is stopped with the -// returned error. -func FilterEvents[T any](instance *ContractInstance, opts *bind.FilterOpts, eventID common.Hash, unpack func(*types.Log) (*T, error), topics ...[]any) (*EventIterator[T], error) { - backend := instance.Backend - c := bind.NewBoundContract(instance.Address, abi.ABI{}, backend, backend, backend) - logs, sub, err := c.FilterLogsByID(opts, eventID, topics...) - if err != nil { - return nil, err - } - return &EventIterator[T]{unpack: unpack, logs: logs, sub: sub}, nil -} - -// WatchEvents causes events emitted from a specified contract to be forwarded to -// onLog if they match the query parameters (matching eventID and topics). If -// onLog returns an error, the returned subscription is cancelled with that error. -func WatchEvents(instance *ContractInstance, abi abi.ABI, opts *bind.WatchOpts, eventID common.Hash, onLog func(*types.Log) error, topics ...[]any) (event.Subscription, error) { - backend := instance.Backend - c := bind.NewBoundContract(instance.Address, abi, backend, backend, backend) - logs, sub, err := c.WatchLogsForId(opts, eventID, topics...) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - err := onLog(&log) - if err != nil { - return err - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// EventIterator is returned from FilterEvents and is used to iterate over the raw logs and unpacked data for events. -type EventIterator[T any] struct { - event *T // event containing the contract specifics and raw log - - unpack func(*types.Log) (*T, error) // Unpack function for the event - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for solc_errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Value returns the current value of the iterator, or nil if there isn't one. -func (it *EventIterator[T]) Value() *T { - return it.event -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *EventIterator[T]) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - res, err := it.unpack(&log) - if err != nil { - it.fail = err - return false - } - it.event = res - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - res, err := it.unpack(&log) - if err != nil { - it.fail = err - return false - } - it.event = res - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *EventIterator[T]) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *EventIterator[T]) Close() error { - it.sub.Unsubscribe() - return nil -} - -// Transact creates and submits a transaction to the bound contract instance -// using the provided abi-encoded input (or nil). -func Transact(instance *ContractInstance, opts *bind.TransactOpts, input []byte) (*types.Transaction, error) { - var ( - addr = instance.Address - backend = instance.Backend - ) - c := bind.NewBoundContract(addr, abi.ABI{}, backend, backend, backend) - return c.RawTransact(opts, input) -} - -// Call performs an eth_call on the given bound contract instance, using the -// provided abi-encoded input (or nil). -func Call(instance *ContractInstance, opts *bind.CallOpts, input []byte) ([]byte, error) { - backend := instance.Backend - c := bind.NewBoundContract(instance.Address, abi.ABI{}, backend, backend, backend) - return c.CallRaw(opts, input) -} diff --git a/accounts/abi/bind/v2/lib_test.go b/accounts/abi/bind/v2/lib_test.go index 1424727c61..3b78062f5d 100644 --- a/accounts/abi/bind/v2/lib_test.go +++ b/accounts/abi/bind/v2/lib_test.go @@ -25,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/accounts/abi/bind/testdata/v2/events" "github.com/ethereum/go-ethereum/accounts/abi/bind/testdata/v2/nested_libraries" - "github.com/ethereum/go-ethereum/accounts/abi/bind/testdata/v2/solc_errors" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -98,6 +97,7 @@ func testSetup() (*bind.TransactOpts, *backends.SimulatedBackend, error) { return opts, &bindBackend, nil } +/* // test deployment and interaction for a basic contract with no library deps func TestErrors(t *testing.T) { opts, bindBackend, err := testSetup() @@ -137,26 +137,20 @@ func TestErrors(t *testing.T) { t.Fatalf("pack function input err: %v\n", doInput) } - cABI, err := nested_libraries.C1MetaData.GetAbi() - if err != nil { - t.Fatalf("error getting abi object: %v", err) - } contractAddr := res.Addrs[solc_errors.CMetaData.Pattern] - boundC := bind.NewBoundContract(contractAddr, *cABI, bindBackend, bindBackend, bindBackend) - callOpts := &bind.CallOpts{ - From: common.Address{}, - Context: context.Background(), + contractInstance := &ContractInstance{ + Address: contractAddr, + Backend: bindBackend, } - callRes, err := boundC.CallRaw(callOpts, doInput) + _, err = Transact(contractInstance, opts, doInput) if err != nil { - fmt.Println(callRes) - t.Fatalf("err calling contract: %v", err) + t.Fatalf("err submitting tx: %v", err) } - _ = callRes } +*/ // test that deploying a contract with library dependencies works, -// verifying by calling the deployed contract. +// verifying by calling method on the deployed contract. func TestDeploymentLibraries(t *testing.T) { opts, bindBackend, err := testSetup() if err != nil { @@ -230,6 +224,8 @@ func TestDeploymentLibraries(t *testing.T) { } } +// Same as TestDeployment. However, stagger the deployments with overrides: +// first deploy the library deps and then the contract. func TestDeploymentWithOverrides(t *testing.T) { opts, bindBackend, err := testSetup() if err != nil { @@ -309,12 +305,12 @@ func TestDeploymentWithOverrides(t *testing.T) { t.Fatalf("error getting abi object: %v", err) } contractAddr := res.Addrs[nested_libraries.C1MetaData.Pattern] - boundC := bind.NewBoundContract(contractAddr, *cABI, bindBackend, bindBackend, bindBackend) + boundContract := bind.NewBoundContract(contractAddr, *cABI, bindBackend, bindBackend, bindBackend) callOpts := &bind.CallOpts{ From: common.Address{}, Context: context.Background(), } - callRes, err := boundC.CallRaw(callOpts, doInput) + callRes, err := boundContract.CallRaw(callOpts, doInput) if err != nil { t.Fatalf("err calling contract: %v", err) } @@ -327,19 +323,6 @@ func TestDeploymentWithOverrides(t *testing.T) { } } -/* - * - */ -/* - func TestDeploymentWithOverrides(t *testing.T) { - // more deployment test case ideas: - // 1) deploy libraries, then deploy contract first with libraries as overrides - // 2) deploy contract without library dependencies. - } -*/ - -// note to self: see how to filter logs in eth_call. - func TestEvents(t *testing.T) { // test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.) txAuth, backend, err := testSetup() @@ -375,48 +358,31 @@ func TestEvents(t *testing.T) { t.Fatalf("error getting contract abi: %v", err) } - boundContract := ContractInstance{ - res.Addrs[events.CMetaData.Pattern], - backend, - } + boundContract := bind.NewBoundContract(res.Addrs[events.CMetaData.Pattern], *abi, backend, backend, backend) - newCBasic1Ch := make(chan *events.CBasic1) - newCBasic2Ch := make(chan *events.CBasic2) watchOpts := &bind.WatchOpts{ Start: nil, Context: context.Background(), } - sub1, err := WatchEvents(&boundContract, *abi, watchOpts, events.CBasic1EventID(), func(raw *types.Log) error { - event := &events.CBasic1{ - Id: (new(big.Int)).SetBytes(raw.Topics[0].Bytes()), - Data: (new(big.Int)).SetBytes(raw.Data), - } - newCBasic1Ch <- event - return nil - }) - sub2, err := WatchEvents(&boundContract, *abi, watchOpts, events.CBasic2EventID(), func(raw *types.Log) error { - event := &events.CBasic2{ - Flag: false, // TODO: how to unpack different types to go types? this should be exposed via abi package. - Data: (new(big.Int)).SetBytes(raw.Data), - } - newCBasic2Ch <- event - return nil - }) + chE1, sub1, err := boundContract.WatchLogsForId(watchOpts, events.CBasic1EventID(), nil) + if err != nil { + t.Fatalf("WatchLogsForId with event type 1 failed: %v", err) + } defer sub1.Unsubscribe() + + chE2, sub2, err := boundContract.WatchLogsForId(watchOpts, events.CBasic2EventID(), nil) + if err != nil { + t.Fatalf("WatchLogsForId with event type 2 failed: %v", err) + } defer sub2.Unsubscribe() - crtctInstance := &ContractInstance{ - Address: res.Addrs[events.CMetaData.Pattern], - Backend: backend, - } - _ = ctrct - packedCall, err := ctrct.PackEmitMulti() + packedCallData, err := ctrct.PackEmitMulti() if err != nil { t.Fatalf("failed to pack EmitMulti arguments") } - tx, err := Transact(crtctInstance, txAuth, packedCall) + tx, err := boundContract.RawTransact(txAuth, packedCallData) if err != nil { - t.Fatalf("failed to send transaction...") + t.Fatalf("failed to submit transaction: %v", err) } backend.Commit() if _, err := bind.WaitMined(context.Background(), backend, tx); err != nil { @@ -428,15 +394,16 @@ func TestEvents(t *testing.T) { e2Count := 0 for { select { - case _ = <-newCBasic1Ch: - e1Count++ - case _ = <-newCBasic2Ch: - e2Count++ - case _ = <-timeout.C: + case <-timeout.C: goto done - } - if e1Count == 2 && e2Count == 1 { - break + case err := <-sub1.Err(): + t.Fatalf("received err from sub1: %v", err) + case err := <-sub2.Err(): + t.Fatalf("received err from sub2: %v", err) + case <-chE1: + e1Count++ + case <-chE2: + e2Count++ } } done: @@ -453,144 +420,32 @@ done: Start: 0, Context: context.Background(), } - unpackBasic := func(raw *types.Log) (*events.CBasic1, error) { - return &events.CBasic1{ - Id: (new(big.Int)).SetBytes(raw.Topics[0].Bytes()), - Data: (new(big.Int)).SetBytes(raw.Data), - }, nil - } - unpackBasic2 := func(raw *types.Log) (*events.CBasic2, error) { - return &events.CBasic2{ - Flag: false, // TODO: how to unpack different types to go types? this should be exposed via abi package. - Data: (new(big.Int)).SetBytes(raw.Data), - }, nil - } - it, err := FilterEvents[events.CBasic1](crtctInstance, filterOpts, events.CBasic1EventID(), unpackBasic) + chE1, sub1, err = boundContract.FilterLogsByID(filterOpts, events.CBasic1EventID(), nil) if err != nil { - t.Fatalf("error filtering logs %v\n", err) + t.Fatalf("failed to filter logs for event type 1: %v", err) } - it2, err := FilterEvents[events.CBasic2](crtctInstance, filterOpts, events.CBasic2EventID(), unpackBasic2) + chE2, sub2, err = boundContract.FilterLogsByID(filterOpts, events.CBasic2EventID(), nil) if err != nil { - t.Fatalf("error filtering logs %v\n", err) + t.Fatalf("failed to filter logs for event type 2: %v", err) } + timeout.Reset(2 * time.Second) e1Count = 0 e2Count = 0 - for it.Next() { - e1Count++ - } - for it2.Next() { - e2Count++ - } - if e1Count != 2 { - t.Fatalf("expected e1Count of 2 from filter call. got %d", e1Count) - } - if e2Count != 1 { - t.Fatalf("expected e2Count of 1 from filter call. got %d", e1Count) - } -} - -func TestEventsUnpackFailure(t *testing.T) { - // test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.) - txAuth, backend, err := testSetup() - if err != nil { - t.Fatalf("error setting up testing env: %v", err) - } - - deploymentParams := DeploymentParams{ - Contracts: []ContractDeployParams{ - { - Meta: events.CMetaData, - }, - }, - } - - res, err := LinkAndDeploy(txAuth, backend, deploymentParams) - if err != nil { - t.Fatalf("error deploying contract for testing: %v", err) - } - - backend.Commit() - if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[events.CMetaData.Pattern]); err != nil { - t.Fatalf("WaitDeployed failed %v", err) - } - - ctrct, err := events.NewC() - if err != nil { - t.Fatalf("error instantiating contract instance: %v", err) - } - - abi, err := events.CMetaData.GetAbi() - if err != nil { - t.Fatalf("error getting contract abi: %v", err) - } - - // TODO: why did I introduce separate type, and not just use bound contract? - boundContract := ContractInstance{ - res.Addrs[events.CMetaData.Pattern], - backend, - } - - newCBasic1Ch := make(chan *events.CBasic1) - newCBasic2Ch := make(chan *events.CBasic2) - unpackBasic := func(raw *types.Log) error { - return fmt.Errorf("this error should stop the filter that uses this unpack.") - } - unpackBasic2 := func(raw *types.Log) error { - newCBasic2Ch <- &events.CBasic2{ - Flag: false, // TODO: how to unpack different types to go types? this should be exposed via abi package. - Data: (new(big.Int)).SetBytes(raw.Data), - } - return nil - } - - watchOpts := &bind.WatchOpts{ - Start: nil, - Context: context.Background(), - } - sub1, err := WatchEvents(&boundContract, *abi, watchOpts, events.CBasic1EventID(), unpackBasic) - sub2, err := WatchEvents(&boundContract, *abi, watchOpts, events.CBasic2EventID(), unpackBasic2) - defer sub1.Unsubscribe() - defer sub2.Unsubscribe() - - crtctInstance := &ContractInstance{ - Address: res.Addrs[events.CMetaData.Pattern], - Backend: backend, - } - _ = ctrct - packedCall, err := ctrct.PackEmitMulti() - if err != nil { - t.Fatalf("failed to pack EmitMulti arguments") - } - tx, err := Transact(crtctInstance, txAuth, packedCall) - if err != nil { - t.Fatalf("failed to send transaction...") - } - backend.Commit() - if _, err := bind.WaitMined(context.Background(), backend, tx); err != nil { - t.Fatalf("error waiting for tx to be mined: %v", err) - } - - timeout := time.NewTimer(2 * time.Second) - e1Count := 0 - e2Count := 0 for { select { - case _ = <-newCBasic1Ch: + case <-timeout.C: + goto done2 + case <-chE1: e1Count++ - case _ = <-newCBasic2Ch: + case <-chE2: e2Count++ - case _ = <-timeout.C: - goto done - } - if e1Count == 2 && e2Count == 1 { - break } } -done: - if e1Count != 0 { - t.Fatalf("expected event type 1 count to be 0. got %d", e1Count) +done2: + if e1Count != 2 { + t.Fatalf("incorrect results from filter logs: expected event type 1 count to be 2. got %d", e1Count) } if e2Count != 1 { - t.Fatalf("expected event type 2 count to be 1. got %d", e2Count) + t.Fatalf("incorrect results from filter logs: expected event type 2 count to be 1. got %d", e2Count) } }