add coverage for event filtering

This commit is contained in:
Jared Wasinger 2024-11-27 23:10:15 +07:00
parent 00b4f31f36
commit ff9946cd48
2 changed files with 41 additions and 15 deletions

View File

@ -233,7 +233,10 @@ func FilterLogs[T any](instance *ContractInstance, opts *bind.FilterOpts, eventI
return &EventIterator[T]{unpack: unpack, logs: logs, sub: sub}, nil
}
// TODO: adding docs soon (jwasinger)
// 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[T any](instance *ContractInstance, abi abi.ABI, opts *bind.WatchOpts, eventID common.Hash, unpack func(*types.Log) (*T, error), sink chan<- *T, topics ...[]any) (event.Subscription, error) {
backend := instance.Backend
c := bind.NewBoundContract(instance.Address, abi, backend, backend, backend)
@ -270,7 +273,7 @@ func WatchLogs[T any](instance *ContractInstance, abi abi.ABI, opts *bind.WatchO
// EventIterator is returned from FilterLogs 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
event *T // event containing the contract specifics and raw log
unpack func(*types.Log) (*T, error) // Unpack function for the event
@ -280,6 +283,11 @@ type EventIterator[T any] struct {
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.
@ -297,7 +305,7 @@ func (it *EventIterator[T]) Next() bool {
it.fail = err
return false
}
it.Event = res
it.event = res
return true
default:
@ -312,7 +320,7 @@ func (it *EventIterator[T]) Next() bool {
it.fail = err
return false
}
it.Event = res
it.event = res
return true
case err := <-it.sub.Err():

View File

@ -350,11 +350,6 @@ func TestEvents(t *testing.T) {
sub2, err := WatchLogs[events.CBasic2](&boundContract, *abi, watchOpts, events.CBasic2EventID(), unpackBasic2, newCBasic2Ch)
defer sub1.Unsubscribe()
defer sub2.Unsubscribe()
fmt.Printf("watching for event with id %x\n", events.CBasic1EventID())
fmt.Printf("watching for event with id %x\n", events.CBasic2EventID())
//wtf do I do with this subscriptions??
_ = sub1
_ = sub2
crtctInstance := &ContractInstance{
Address: res.Addrs[events.CMetaData.Pattern],
@ -397,10 +392,36 @@ done:
if e2Count != 1 {
t.Fatalf("expected event type 2 count to be 1. got %d", e2Count)
}
// commit a few blocks...
// now filter for the previously-emitted events.
// now, test that we can filter those events that were just caught through the subscription
filterOpts := &bind.FilterOpts{
Start: 0,
Context: context.Background(),
}
// TODO: test that returning error from unpack prevents event from being received by sink.
it, err := FilterLogs[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)
if err != nil {
t.Fatalf("error filtering logs %v\n", err)
}
e1Count = 0
e2Count = 0
for it.Next() {
e1Count++
}
for it2.Next() {
e2Count++
}
if e2Count != 1 {
t.Fatalf("bad")
}
if e1Count != 1 {
t.Fatalf("bad")
}
}
func TestEventsUnpackFailure(t *testing.T) {
@ -445,7 +466,7 @@ func TestEventsUnpackFailure(t *testing.T) {
}
unpackBasic := func(raw *types.Log) (*events.CBasic1, error) {
return nil, fmt.Errorf("could not unpack event")
return nil, fmt.Errorf("this error should stop the filter that uses this unpack.")
}
unpackBasic2 := func(raw *types.Log) (*events.CBasic2, error) {
return &events.CBasic2{
@ -463,9 +484,6 @@ func TestEventsUnpackFailure(t *testing.T) {
sub2, err := WatchLogs[events.CBasic2](&boundContract, *abi, watchOpts, events.CBasic2EventID(), unpackBasic2, newCBasic2Ch)
defer sub1.Unsubscribe()
defer sub2.Unsubscribe()
//wtf do I do with this subscriptions??
_ = sub1
_ = sub2
crtctInstance := &ContractInstance{
Address: res.Addrs[events.CMetaData.Pattern],