fix contract filter test. rename *Logs methods to *Events, to reflect the fact that these are specific to solidity events.

This commit is contained in:
Jared Wasinger 2024-12-02 12:57:09 +07:00 committed by Felix Lange
parent 1f25c68ec4
commit d3d6926683
3 changed files with 28 additions and 24 deletions

View File

@ -153,8 +153,6 @@ func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend Co
}
func DeployContractRaw(opts *TransactOpts, bytecode []byte, backend ContractBackend, packedParams []byte) (common.Address, *types.Transaction, *BoundContract, error) {
// TODO: it's weird to instantiate a bound contract (implies existence of contract) in order to deploy a contract
// that doesn't yet exist
c := NewBoundContract(common.Address{}, abi.ABI{}, backend, backend, backend)
tx, err := c.transact(opts, nil, append(bytecode, packedParams...))
@ -463,6 +461,12 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
return signedTx, nil
}
// 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) {
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) {

View File

@ -222,22 +222,24 @@ func LinkAndDeploy(auth *bind.TransactOpts, backend bind.ContractBackend, deploy
return res, nil
}
// TODO: adding docs soon (jwasinger)
func FilterLogs[T any](instance *ContractInstance, opts *bind.FilterOpts, eventID common.Hash, unpack func(*types.Log) (*T, error), topics ...[]any) (*EventIterator[T], error) {
// 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.FilterLogs(opts, eventID.String(), topics...)
logs, sub, err := c.FilterLogsByID(opts, eventID, topics...)
if err != nil {
return nil, err
}
return &EventIterator[T]{unpack: unpack, logs: logs, sub: sub}, nil
}
// WatchLogs causes logs emitted with a given event id from a specified
// contract to be intercepted, unpacked, and forwarded to sink. If
// unpack returns an error, the returned subscription is closed with the
// error.
func WatchLogs(instance *ContractInstance, abi abi.ABI, opts *bind.WatchOpts, eventID common.Hash, onLog func(*types.Log) error, topics ...[]any) (event.Subscription, error) {
// 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...)
@ -262,7 +264,7 @@ func WatchLogs(instance *ContractInstance, abi abi.ABI, opts *bind.WatchOpts, ev
}), nil
}
// EventIterator is returned from FilterLogs and is used to iterate over the raw logs and unpacked data for events.
// 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

View File

@ -375,7 +375,6 @@ func TestEvents(t *testing.T) {
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,
@ -387,7 +386,7 @@ func TestEvents(t *testing.T) {
Start: nil,
Context: context.Background(),
}
sub1, err := WatchLogs(&boundContract, *abi, watchOpts, events.CBasic1EventID(), func(raw *types.Log) error {
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),
@ -395,7 +394,7 @@ func TestEvents(t *testing.T) {
newCBasic1Ch <- event
return nil
})
sub2, err := WatchLogs(&boundContract, *abi, watchOpts, events.CBasic2EventID(), func(raw *types.Log) error {
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),
@ -448,7 +447,7 @@ done:
t.Fatalf("expected event type 2 count to be 1. got %d", e2Count)
}
// now, test that we can filter those events that were just caught through the subscription
// now, test that we can filter those same logs after they were included in the chain
filterOpts := &bind.FilterOpts{
Start: 0,
@ -466,12 +465,11 @@ done:
Data: (new(big.Int)).SetBytes(raw.Data),
}, nil
}
// TODO: test that returning error from unpack prevents event from being received by sink.
it, err := FilterLogs[events.CBasic1](crtctInstance, filterOpts, events.CBasic1EventID(), unpackBasic)
it, err := FilterEvents[events.CBasic1](crtctInstance, filterOpts, events.CBasic1EventID(), unpackBasic)
if err != nil {
t.Fatalf("error filtering logs %v\n", err)
}
it2, err := FilterLogs[events.CBasic2](crtctInstance, filterOpts, events.CBasic1EventID(), unpackBasic2)
it2, err := FilterEvents[events.CBasic2](crtctInstance, filterOpts, events.CBasic2EventID(), unpackBasic2)
if err != nil {
t.Fatalf("error filtering logs %v\n", err)
}
@ -483,11 +481,11 @@ done:
for it2.Next() {
e2Count++
}
if e2Count != 1 {
t.Fatalf("bad")
if e1Count != 2 {
t.Fatalf("expected e1Count of 2 from filter call. got %d", e1Count)
}
if e1Count != 1 {
t.Fatalf("bad")
if e2Count != 1 {
t.Fatalf("expected e2Count of 1 from filter call. got %d", e1Count)
}
}
@ -549,8 +547,8 @@ func TestEventsUnpackFailure(t *testing.T) {
Start: nil,
Context: context.Background(),
}
sub1, err := WatchLogs(&boundContract, *abi, watchOpts, events.CBasic1EventID(), unpackBasic)
sub2, err := WatchLogs(&boundContract, *abi, watchOpts, events.CBasic2EventID(), unpackBasic2)
sub1, err := WatchEvents(&boundContract, *abi, watchOpts, events.CBasic1EventID(), unpackBasic)
sub2, err := WatchEvents(&boundContract, *abi, watchOpts, events.CBasic2EventID(), unpackBasic2)
defer sub1.Unsubscribe()
defer sub2.Unsubscribe()