Filter accepts multiple topics per entry. Fixes #403
This commit is contained in:
		
							parent
							
								
									ac88ae86a3
								
							
						
					
					
						commit
						6e50a1e9f5
					
				| @ -17,7 +17,7 @@ type FilterOptions struct { | |||||||
| 	Latest   int64 | 	Latest   int64 | ||||||
| 
 | 
 | ||||||
| 	Address [][]byte | 	Address [][]byte | ||||||
| 	Topics  [][]byte | 	Topics  [][][]byte | ||||||
| 
 | 
 | ||||||
| 	Skip int | 	Skip int | ||||||
| 	Max  int | 	Max  int | ||||||
| @ -31,7 +31,7 @@ type Filter struct { | |||||||
| 	skip     int | 	skip     int | ||||||
| 	address  [][]byte | 	address  [][]byte | ||||||
| 	max      int | 	max      int | ||||||
| 	topics   [][]byte | 	topics   [][][]byte | ||||||
| 
 | 
 | ||||||
| 	BlockCallback   func(*types.Block) | 	BlockCallback   func(*types.Block) | ||||||
| 	PendingCallback func(*types.Block) | 	PendingCallback func(*types.Block) | ||||||
| @ -44,6 +44,8 @@ func NewFilter(eth Backend) *Filter { | |||||||
| 	return &Filter{eth: eth} | 	return &Filter{eth: eth} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // SetOptions copies the filter options to the filter it self. The reason for this "silly" copy
 | ||||||
|  | // is simply because named arguments in this case is extremely nice and readable.
 | ||||||
| func (self *Filter) SetOptions(options FilterOptions) { | func (self *Filter) SetOptions(options FilterOptions) { | ||||||
| 	self.earliest = options.Earliest | 	self.earliest = options.Earliest | ||||||
| 	self.latest = options.Latest | 	self.latest = options.Latest | ||||||
| @ -69,7 +71,7 @@ func (self *Filter) SetAddress(addr [][]byte) { | |||||||
| 	self.address = addr | 	self.address = addr | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (self *Filter) SetTopics(topics [][]byte) { | func (self *Filter) SetTopics(topics [][][]byte) { | ||||||
| 	self.topics = topics | 	self.topics = topics | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -149,10 +151,18 @@ Logs: | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		max := int(math.Min(float64(len(self.topics)), float64(len(log.Topics())))) | 		logTopics := make([][]byte, len(self.topics)) | ||||||
| 		for i := 0; i < max; i++ { | 		copy(logTopics, log.Topics()) | ||||||
| 			if !bytes.Equal(log.Topics()[i], self.topics[i]) { | 
 | ||||||
| 				continue Logs | 		for i, topics := range self.topics { | ||||||
|  | 			for _, topic := range topics { | ||||||
|  | 				var match bool | ||||||
|  | 				if bytes.Equal(log.Topics()[i], topic) { | ||||||
|  | 					match = true | ||||||
|  | 				} | ||||||
|  | 				if !match { | ||||||
|  | 					continue Logs | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -177,8 +187,15 @@ func (self *Filter) bloomFilter(block *types.Block) bool { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for _, topic := range self.topics { | 	for _, sub := range self.topics { | ||||||
| 		if !types.BloomLookup(block.Bloom(), topic) { | 		var included bool | ||||||
|  | 		for _, topic := range sub { | ||||||
|  | 			if types.BloomLookup(block.Bloom(), topic) { | ||||||
|  | 				included = true | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if !included { | ||||||
| 			return false | 			return false | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -6,7 +6,6 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/eth" | 	"github.com/ethereum/go-ethereum/eth" | ||||||
| 	"github.com/ethereum/go-ethereum/ethutil" | 	"github.com/ethereum/go-ethereum/ethutil" | ||||||
| 	"github.com/ethereum/go-ethereum/state" | 	"github.com/ethereum/go-ethereum/state" | ||||||
| 	"github.com/ethereum/go-ethereum/ui" |  | ||||||
| 	"github.com/ethereum/go-ethereum/xeth" | 	"github.com/ethereum/go-ethereum/xeth" | ||||||
| 	"github.com/obscuren/otto" | 	"github.com/obscuren/otto" | ||||||
| ) | ) | ||||||
| @ -96,17 +95,3 @@ func (self *JSEthereum) toVal(v interface{}) otto.Value { | |||||||
| 
 | 
 | ||||||
| 	return result | 	return result | ||||||
| } | } | ||||||
| 
 |  | ||||||
| func (self *JSEthereum) Messages(object map[string]interface{}) otto.Value { |  | ||||||
| 	filter := ui.NewFilterFromMap(object, self.ethereum) |  | ||||||
| 
 |  | ||||||
| 	logs := filter.Find() |  | ||||||
| 	var jslogs []JSLog |  | ||||||
| 	for _, m := range logs { |  | ||||||
| 		jslogs = append(jslogs, NewJSLog(m)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	v, _ := self.vm.ToValue(jslogs) |  | ||||||
| 
 |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								rpc/args.go
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								rpc/args.go
									
									
									
									
									
								
							| @ -197,7 +197,7 @@ type FilterOptions struct { | |||||||
| 	Earliest int64 | 	Earliest int64 | ||||||
| 	Latest   int64 | 	Latest   int64 | ||||||
| 	Address  interface{} | 	Address  interface{} | ||||||
| 	Topic    []string | 	Topic    []interface{} | ||||||
| 	Skip     int | 	Skip     int | ||||||
| 	Max      int | 	Max      int | ||||||
| } | } | ||||||
| @ -220,10 +220,20 @@ func toFilterOptions(options *FilterOptions) core.FilterOptions { | |||||||
| 
 | 
 | ||||||
| 	opts.Earliest = options.Earliest | 	opts.Earliest = options.Earliest | ||||||
| 	opts.Latest = options.Latest | 	opts.Latest = options.Latest | ||||||
| 	opts.Topics = make([][]byte, len(options.Topic)) | 
 | ||||||
| 	for i, topic := range options.Topic { | 	topics := make([][][]byte, len(options.Topic)) | ||||||
| 		opts.Topics[i] = fromHex(topic) | 	for i, topicDat := range options.Topic { | ||||||
|  | 		if slice, ok := topicDat.([]interface{}); ok { | ||||||
|  | 			topics[i] = make([][]byte, len(slice)) | ||||||
|  | 			for j, topic := range slice { | ||||||
|  | 				topics[i][j] = fromHex(topic.(string)) | ||||||
|  | 			} | ||||||
|  | 		} else if str, ok := topicDat.(string); ok { | ||||||
|  | 			topics[i] = make([][]byte, 1) | ||||||
|  | 			topics[i][0] = fromHex(str) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  | 	opts.Topics = topics | ||||||
| 
 | 
 | ||||||
| 	return opts | 	return opts | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										76
									
								
								ui/filter.go
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								ui/filter.go
									
									
									
									
									
								
							| @ -1,77 +1 @@ | |||||||
| package ui | package ui | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"github.com/ethereum/go-ethereum/core" |  | ||||||
| 	"github.com/ethereum/go-ethereum/ethutil" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| func fromHex(s string) []byte { |  | ||||||
| 	if len(s) > 1 { |  | ||||||
| 		if s[0:2] == "0x" { |  | ||||||
| 			s = s[2:] |  | ||||||
| 		} |  | ||||||
| 		return ethutil.Hex2Bytes(s) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewFilterFromMap(object map[string]interface{}, eth core.Backend) *core.Filter { |  | ||||||
| 	filter := core.NewFilter(eth) |  | ||||||
| 
 |  | ||||||
| 	if object["earliest"] != nil { |  | ||||||
| 		val := ethutil.NewValue(object["earliest"]) |  | ||||||
| 		filter.SetEarliestBlock(val.Int()) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if object["latest"] != nil { |  | ||||||
| 		val := ethutil.NewValue(object["latest"]) |  | ||||||
| 		filter.SetLatestBlock(val.Int()) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if object["address"] != nil { |  | ||||||
| 		//val := ethutil.NewValue(object["address"])
 |  | ||||||
| 		//filter.SetAddress(fromHex(val.Str()))
 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if object["max"] != nil { |  | ||||||
| 		val := ethutil.NewValue(object["max"]) |  | ||||||
| 		filter.SetMax(int(val.Uint())) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if object["skip"] != nil { |  | ||||||
| 		val := ethutil.NewValue(object["skip"]) |  | ||||||
| 		filter.SetSkip(int(val.Uint())) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if object["topics"] != nil { |  | ||||||
| 		filter.SetTopics(MakeTopics(object["topics"])) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return filter |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Conversion methodn
 |  | ||||||
| func mapToAccountChange(m map[string]interface{}) (d core.AccountChange) { |  | ||||||
| 	if str, ok := m["id"].(string); ok { |  | ||||||
| 		d.Address = fromHex(str) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if str, ok := m["at"].(string); ok { |  | ||||||
| 		d.StateAddress = fromHex(str) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // data can come in in the following formats:
 |  | ||||||
| // ["aabbccdd", {id: "ccddee", at: "11223344"}], "aabbcc", {id: "ccddee", at: "1122"}
 |  | ||||||
| func MakeTopics(v interface{}) (d [][]byte) { |  | ||||||
| 	if str, ok := v.(string); ok { |  | ||||||
| 		d = append(d, fromHex(str)) |  | ||||||
| 	} else if slice, ok := v.([]string); ok { |  | ||||||
| 		for _, item := range slice { |  | ||||||
| 			d = append(d, fromHex(item)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user