Skip to content

Commit be74662

Browse files
committed
eth/filters: simplify query object decoding
1 parent ec5f531 commit be74662

File tree

1 file changed

+44
-47
lines changed

1 file changed

+44
-47
lines changed

eth/filters/api.go

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package filters
1818

1919
import (
20-
"encoding/hex"
2120
"encoding/json"
2221
"errors"
2322
"fmt"
@@ -28,6 +27,7 @@ import (
2827
"golang.org/x/net/context"
2928

3029
"github.com/ethereum/go-ethereum/common"
30+
"github.com/ethereum/go-ethereum/common/hexutil"
3131
"github.com/ethereum/go-ethereum/core/types"
3232
"github.com/ethereum/go-ethereum/ethdb"
3333
"github.com/ethereum/go-ethereum/event"
@@ -459,73 +459,54 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error {
459459

460460
if raw.Addresses != nil {
461461
// raw.Address can contain a single address or an array of addresses
462-
var addresses []common.Address
463-
if strAddrs, ok := raw.Addresses.([]interface{}); ok {
464-
for i, addr := range strAddrs {
462+
switch rawAddr := raw.Addresses.(type) {
463+
case []interface{}:
464+
for i, addr := range rawAddr {
465465
if strAddr, ok := addr.(string); ok {
466-
if len(strAddr) >= 2 && strAddr[0] == '0' && (strAddr[1] == 'x' || strAddr[1] == 'X') {
467-
strAddr = strAddr[2:]
468-
}
469-
if decAddr, err := hex.DecodeString(strAddr); err == nil {
470-
addresses = append(addresses, common.BytesToAddress(decAddr))
471-
} else {
472-
return fmt.Errorf("invalid address given")
466+
addr, err := decodeAddress(strAddr)
467+
if err != nil {
468+
return fmt.Errorf("invalid address at index %d: %v", i, err)
473469
}
470+
args.Addresses = append(args.Addresses, addr)
474471
} else {
475-
return fmt.Errorf("invalid address on index %d", i)
472+
return fmt.Errorf("non-string address at index %d", i)
476473
}
477474
}
478-
} else if singleAddr, ok := raw.Addresses.(string); ok {
479-
if len(singleAddr) >= 2 && singleAddr[0] == '0' && (singleAddr[1] == 'x' || singleAddr[1] == 'X') {
480-
singleAddr = singleAddr[2:]
481-
}
482-
if decAddr, err := hex.DecodeString(singleAddr); err == nil {
483-
addresses = append(addresses, common.BytesToAddress(decAddr))
484-
} else {
485-
return fmt.Errorf("invalid address given")
475+
case string:
476+
addr, err := decodeAddress(rawAddr)
477+
if err != nil {
478+
return fmt.Errorf("invalid address: %v", err)
486479
}
487-
} else {
488-
return errors.New("invalid address(es) given")
489-
}
490-
args.Addresses = addresses
491-
}
492-
493-
// helper function which parses a string to a topic hash
494-
topicConverter := func(raw string) (common.Hash, error) {
495-
if len(raw) == 0 {
496-
return common.Hash{}, nil
497-
}
498-
if len(raw) >= 2 && raw[0] == '0' && (raw[1] == 'x' || raw[1] == 'X') {
499-
raw = raw[2:]
500-
}
501-
if len(raw) != 2*common.HashLength {
502-
return common.Hash{}, errors.New("invalid topic(s)")
503-
}
504-
if decAddr, err := hex.DecodeString(raw); err == nil {
505-
return common.BytesToHash(decAddr), nil
480+
args.Addresses = []common.Address{addr}
481+
default:
482+
return errors.New("invalid addresses in query")
506483
}
507-
return common.Hash{}, errors.New("invalid topic(s)")
508484
}
509485

510486
// topics is an array consisting of strings and/or arrays of strings.
511487
// JSON null values are converted to common.Hash{} and ignored by the filter manager.
512488
if len(raw.Topics) > 0 {
513489
args.Topics = make([][]common.Hash, len(raw.Topics))
514490
for i, t := range raw.Topics {
515-
if t == nil { // ignore topic when matching logs
491+
switch topic := t.(type) {
492+
case nil:
493+
// ignore topic when matching logs
516494
args.Topics[i] = []common.Hash{common.Hash{}}
517-
} else if topic, ok := t.(string); ok { // match specific topic
518-
top, err := topicConverter(topic)
495+
496+
case string:
497+
// match specific topic
498+
top, err := decodeTopic(topic)
519499
if err != nil {
520500
return err
521501
}
522502
args.Topics[i] = []common.Hash{top}
523-
} else if topics, ok := t.([]interface{}); ok { // or case e.g. [null, "topic0", "topic1"]
524-
for _, rawTopic := range topics {
503+
case []interface{}:
504+
// or case e.g. [null, "topic0", "topic1"]
505+
for _, rawTopic := range topic {
525506
if rawTopic == nil {
526507
args.Topics[i] = append(args.Topics[i], common.Hash{})
527508
} else if topic, ok := rawTopic.(string); ok {
528-
parsed, err := topicConverter(topic)
509+
parsed, err := decodeTopic(topic)
529510
if err != nil {
530511
return err
531512
}
@@ -534,11 +515,27 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error {
534515
return fmt.Errorf("invalid topic(s)")
535516
}
536517
}
537-
} else {
518+
default:
538519
return fmt.Errorf("invalid topic(s)")
539520
}
540521
}
541522
}
542523

543524
return nil
544525
}
526+
527+
func decodeAddress(s string) (common.Address, error) {
528+
b, err := hexutil.Decode(s)
529+
if err == nil && len(b) != common.AddressLength {
530+
err = fmt.Errorf("hex has invalid length %d after decoding", len(b))
531+
}
532+
return common.BytesToAddress(b), err
533+
}
534+
535+
func decodeTopic(s string) (common.Hash, error) {
536+
b, err := hexutil.Decode(s)
537+
if err == nil && len(b) != common.HashLength {
538+
err = fmt.Errorf("hex has invalid length %d after decoding", len(b))
539+
}
540+
return common.BytesToHash(b), err
541+
}

0 commit comments

Comments
 (0)