|
|
@@ -3,10 +3,8 @@ package core
|
|
|
import (
|
|
|
"bytes"
|
|
|
"math"
|
|
|
- "math/big"
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
|
- "github.com/ethereum/go-ethereum/ethutil"
|
|
|
"github.com/ethereum/go-ethereum/state"
|
|
|
)
|
|
|
|
|
|
@@ -20,13 +18,12 @@ type Filter struct {
|
|
|
earliest int64
|
|
|
latest int64
|
|
|
skip int
|
|
|
- from, to [][]byte
|
|
|
+ address []byte
|
|
|
max int
|
|
|
+ topics [][]byte
|
|
|
|
|
|
- Altered []AccountChange
|
|
|
-
|
|
|
- BlockCallback func(*types.Block)
|
|
|
- MessageCallback func(state.Messages)
|
|
|
+ BlockCallback func(*types.Block)
|
|
|
+ LogsCallback func(state.Logs)
|
|
|
}
|
|
|
|
|
|
// Create a new filter which uses a bloom filter on blocks to figure out whether a particular block
|
|
|
@@ -35,10 +32,6 @@ func NewFilter(eth EthManager) *Filter {
|
|
|
return &Filter{eth: eth}
|
|
|
}
|
|
|
|
|
|
-func (self *Filter) AddAltered(address, stateAddress []byte) {
|
|
|
- self.Altered = append(self.Altered, AccountChange{address, stateAddress})
|
|
|
-}
|
|
|
-
|
|
|
// Set the earliest and latest block for filtering.
|
|
|
// -1 = latest block (i.e., the current block)
|
|
|
// hash = particular hash from-to
|
|
|
@@ -50,20 +43,12 @@ func (self *Filter) SetLatestBlock(latest int64) {
|
|
|
self.latest = latest
|
|
|
}
|
|
|
|
|
|
-func (self *Filter) SetFrom(addr [][]byte) {
|
|
|
- self.from = addr
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Filter) AddFrom(addr []byte) {
|
|
|
- self.from = append(self.from, addr)
|
|
|
-}
|
|
|
-
|
|
|
-func (self *Filter) SetTo(addr [][]byte) {
|
|
|
- self.to = addr
|
|
|
+func (self *Filter) SetAddress(addr []byte) {
|
|
|
+ self.address = addr
|
|
|
}
|
|
|
|
|
|
-func (self *Filter) AddTo(addr []byte) {
|
|
|
- self.to = append(self.to, addr)
|
|
|
+func (self *Filter) SetTopics(topics [][]byte) {
|
|
|
+ self.topics = topics
|
|
|
}
|
|
|
|
|
|
func (self *Filter) SetMax(max int) {
|
|
|
@@ -74,8 +59,8 @@ func (self *Filter) SetSkip(skip int) {
|
|
|
self.skip = skip
|
|
|
}
|
|
|
|
|
|
-// Run filters messages with the current parameters set
|
|
|
-func (self *Filter) Find() []*state.Message {
|
|
|
+// Run filters logs with the current parameters set
|
|
|
+func (self *Filter) Find() state.Logs {
|
|
|
earliestBlock := self.eth.ChainManager().CurrentBlock()
|
|
|
var earliestBlockNo uint64 = uint64(self.earliest)
|
|
|
if self.earliest == -1 {
|
|
|
@@ -87,39 +72,39 @@ func (self *Filter) Find() []*state.Message {
|
|
|
}
|
|
|
|
|
|
var (
|
|
|
- messages []*state.Message
|
|
|
- block = self.eth.ChainManager().GetBlockByNumber(latestBlockNo)
|
|
|
- quit bool
|
|
|
+ logs state.Logs
|
|
|
+ block = self.eth.ChainManager().GetBlockByNumber(latestBlockNo)
|
|
|
+ quit bool
|
|
|
)
|
|
|
for i := 0; !quit && block != nil; i++ {
|
|
|
// Quit on latest
|
|
|
switch {
|
|
|
case block.NumberU64() == earliestBlockNo, block.NumberU64() == 0:
|
|
|
quit = true
|
|
|
- case self.max <= len(messages):
|
|
|
+ case self.max <= len(logs):
|
|
|
break
|
|
|
}
|
|
|
|
|
|
// Use bloom filtering to see if this block is interesting given the
|
|
|
// current parameters
|
|
|
if self.bloomFilter(block) {
|
|
|
- // Get the messages of the block
|
|
|
- msgs, err := self.eth.BlockProcessor().GetMessages(block)
|
|
|
+ // Get the logs of the block
|
|
|
+ logs, err := self.eth.BlockProcessor().GetLogs(block)
|
|
|
if err != nil {
|
|
|
- chainlogger.Warnln("err: filter get messages ", err)
|
|
|
+ chainlogger.Warnln("err: filter get logs ", err)
|
|
|
|
|
|
break
|
|
|
}
|
|
|
|
|
|
- messages = append(messages, self.FilterMessages(msgs)...)
|
|
|
+ logs = append(logs, self.FilterLogs(logs)...)
|
|
|
}
|
|
|
|
|
|
block = self.eth.ChainManager().GetBlock(block.ParentHash())
|
|
|
}
|
|
|
|
|
|
- skip := int(math.Min(float64(len(messages)), float64(self.skip)))
|
|
|
+ skip := int(math.Min(float64(len(logs)), float64(self.skip)))
|
|
|
|
|
|
- return messages[skip:]
|
|
|
+ return logs[skip:]
|
|
|
}
|
|
|
|
|
|
func includes(addresses [][]byte, a []byte) (found bool) {
|
|
|
@@ -132,70 +117,37 @@ func includes(addresses [][]byte, a []byte) (found bool) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-func (self *Filter) FilterMessages(msgs []*state.Message) []*state.Message {
|
|
|
- var messages []*state.Message
|
|
|
+func (self *Filter) FilterLogs(logs state.Logs) state.Logs {
|
|
|
+ var ret state.Logs
|
|
|
|
|
|
- // Filter the messages for interesting stuff
|
|
|
- for _, message := range msgs {
|
|
|
- if len(self.to) > 0 && !includes(self.to, message.To) {
|
|
|
+ // Filter the logs for interesting stuff
|
|
|
+ for _, log := range logs {
|
|
|
+ if len(self.address) > 0 && !bytes.Equal(self.address, log.Address()) {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
- if len(self.from) > 0 && !includes(self.from, message.From) {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- var match bool
|
|
|
- if len(self.Altered) == 0 {
|
|
|
- match = true
|
|
|
- }
|
|
|
-
|
|
|
- for _, accountChange := range self.Altered {
|
|
|
- if len(accountChange.Address) > 0 && bytes.Compare(message.To, accountChange.Address) != 0 {
|
|
|
+ for _, topic := range self.topics {
|
|
|
+ if !includes(log.Topics(), topic) {
|
|
|
continue
|
|
|
}
|
|
|
-
|
|
|
- if len(accountChange.StateAddress) > 0 && !includes(message.ChangedAddresses, accountChange.StateAddress) {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- match = true
|
|
|
- break
|
|
|
- }
|
|
|
-
|
|
|
- if !match {
|
|
|
- continue
|
|
|
}
|
|
|
|
|
|
- messages = append(messages, message)
|
|
|
+ ret = append(ret, log)
|
|
|
}
|
|
|
|
|
|
- return messages
|
|
|
+ return ret
|
|
|
}
|
|
|
|
|
|
func (self *Filter) bloomFilter(block *types.Block) bool {
|
|
|
- var fromIncluded, toIncluded bool
|
|
|
- if len(self.from) > 0 {
|
|
|
- for _, from := range self.from {
|
|
|
- if types.BloomLookup(block.Bloom(), from) || bytes.Equal(block.Coinbase(), from) {
|
|
|
- fromIncluded = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- fromIncluded = true
|
|
|
+ if len(self.address) > 0 && !types.BloomLookup(block.Bloom(), self.address) {
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
- if len(self.to) > 0 {
|
|
|
- for _, to := range self.to {
|
|
|
- if types.BloomLookup(block.Bloom(), ethutil.U256(new(big.Int).Add(ethutil.Big1, ethutil.BigD(to))).Bytes()) || bytes.Equal(block.Coinbase(), to) {
|
|
|
- toIncluded = true
|
|
|
- break
|
|
|
- }
|
|
|
+ for _, topic := range self.topics {
|
|
|
+ if !types.BloomLookup(block.Bloom(), topic) {
|
|
|
+ return false
|
|
|
}
|
|
|
- } else {
|
|
|
- toIncluded = true
|
|
|
}
|
|
|
|
|
|
- return fromIncluded && toIncluded
|
|
|
+ return true
|
|
|
}
|