Skip to content

Commit

Permalink
Merge pull request #59 from bluele/fix/event-search
Browse files Browse the repository at this point in the history
Fix event-search command to returns correctly the number of matched txs
  • Loading branch information
bluele authored Sep 16, 2019
2 parents 35f7ccc + efc1d74 commit 70bf576
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 13 deletions.
28 changes: 24 additions & 4 deletions pkg/client/cmd/contract/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/bluele/hypermint/pkg/client"
"github.com/bluele/hypermint/pkg/contract/event"
"github.com/bluele/hypermint/pkg/util"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/common"
Expand Down Expand Up @@ -102,8 +103,9 @@ func EventCMD() *cobra.Command {
if err != nil {
return err
}
contractAddr := ethcmn.HexToAddress(viper.GetString(flagContractAddress))
q, err := event.MakeEventSearchQuery(
viper.GetString(flagContractAddress),
contractAddr,
viper.GetString(flagEventName),
viper.GetString(flagEventValue),
)
Expand All @@ -114,9 +116,27 @@ func EventCMD() *cobra.Command {
if err != nil {
return err
}

if viper.GetBool(flagCount) {
fmt.Print(len(res.Txs))
var count int
for _, tx := range res.Txs {
events, err := event.GetEventsByContractAddr(contractAddr, tx)
if err != nil {
return err
}
if len(events) == 0 {
continue
}
events, err = event.FilterEvents(
events,
viper.GetString(flagEventName),
viper.GetString(flagEventValue),
)
if err != nil {
return err
}
count += len(events)
}
fmt.Print(count)
return nil
} else {
for _, tx := range res.Txs {
Expand All @@ -130,7 +150,7 @@ func EventCMD() *cobra.Command {
searchCmd.Flags().String(flagContractAddress, "", "contract address for subscription")
searchCmd.Flags().String(flagEventName, "", "event name")
searchCmd.Flags().String(flagEventValue, "", "event value as hex string")
searchCmd.Flags().Bool(flagCount, false, "if true, only print count of txs")
searchCmd.Flags().Bool(flagCount, false, "if true, only print count of matched txs")
util.CheckRequiredFlag(searchCmd, flagContractAddress, flagEventName)
eventCmd.AddCommand(searchCmd)

Expand Down
64 changes: 61 additions & 3 deletions pkg/contract/event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package event
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"strings"

"github.com/bluele/hypermint/pkg/abci/types"
"github.com/ethereum/go-ethereum/common"
tmcmn "github.com/tendermint/tendermint/libs/common"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)

type Event struct {
Expand Down Expand Up @@ -143,10 +145,9 @@ func MakeEntryBytes(name, value string) ([]byte, error) {
// contractAddr: target contract address
// eventName: event name
// eventValue: value corresponding to event name. NOTE: if value has a prefix "0x", value will be decoded into []byte
func MakeEventSearchQuery(contractAddr string, eventName, eventValue string) (string, error) {
func MakeEventSearchQuery(contractAddr common.Address, eventName, eventValue string) (string, error) {
var parts []string

parts = append(parts, fmt.Sprintf("contract.address='%v'", contractAddr))
parts = append(parts, fmt.Sprintf("contract.address='%v'", contractAddr.Hex()))
parts = append(parts, fmt.Sprintf("contract.event.name='%v'", eventName))
if len(eventValue) > 0 {
ev, err := MakeEntryBytes(eventName, eventValue)
Expand All @@ -157,3 +158,60 @@ func MakeEventSearchQuery(contractAddr string, eventName, eventValue string) (st
}
return strings.Join(parts, " AND "), nil
}

// GetEventsByContractAddr returns events that matches a given contract address from ResultTx.
func GetEventsByContractAddr(contractAddr common.Address, result *ctypes.ResultTx) ([]types.Event, error) {
if !result.TxResult.IsOK() {
return nil, errors.New("result has an error")
}

var events []types.Event
L:
for _, ev := range result.TxResult.GetEvents() {
for _, attr := range ev.GetAttributes() {
if bytes.Equal([]byte("address"), attr.GetKey()) {
if bytes.Equal([]byte(contractAddr.Hex()), attr.GetValue()) {
events = append(events, types.Event(ev))
}
continue L
}
}
}
return events, nil
}

// FilterEvents returns events that includes a given event name and value. (value is optional)
func FilterEvents(events []types.Event, eventName, eventValue string) ([]types.Event, error) {
var value []byte
var checkValue bool
if len(eventValue) == 0 {
checkValue = false
} else {
checkValue = true
v, err := MakeEntryBytes(eventName, eventValue)
if err != nil {
return nil, err
}
value = v
}

var rets []types.Event
for _, ev := range events {
for _, attr := range ev.Attributes {
if !checkValue {
if bytes.Equal([]byte("event.name"), attr.GetKey()) {
if bytes.Equal([]byte(eventName), attr.GetValue()) {
rets = append(rets, ev)
}
}
} else {
if bytes.Equal([]byte("event.data"), attr.GetKey()) {
if bytes.Equal(value, attr.GetValue()) {
rets = append(rets, ev)
}
}
}
}
}
return rets, nil
}
11 changes: 5 additions & 6 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,12 +159,11 @@ func (ts *E2ETestSuite) TestContract() {
ts.NoError(err)
ts.Equal(1, count)
}
// WARNING: currently this test case will be failed.
// {
// count, err := ts.SearchEvent(ctx, c, "test-ext-event-name", "second")
// ts.NoError(err)
// ts.Equal(0, count)
// }
{
count, err := ts.SearchEvent(ctx, c, "test-ext-event-name", "second")
ts.NoError(err)
ts.Equal(0, count)
}
})
}

Expand Down

0 comments on commit 70bf576

Please sign in to comment.