diff options
Diffstat (limited to 'ethchain')
-rw-r--r-- | ethchain/filter.go | 101 | ||||
-rw-r--r-- | ethchain/state_manager.go | 14 | ||||
-rw-r--r-- | ethchain/state_transition.go | 8 |
3 files changed, 107 insertions, 16 deletions
diff --git a/ethchain/filter.go b/ethchain/filter.go index 4f3160b90..c4c403cf7 100644 --- a/ethchain/filter.go +++ b/ethchain/filter.go @@ -6,8 +6,13 @@ import ( "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethutil" + "gopkg.in/qml.v1" ) +type data struct { + id, address []byte +} + // Filtering interface type Filter struct { eth EthManager @@ -16,6 +21,8 @@ type Filter struct { skip int from, to [][]byte max int + + altered []data } // Create a new filter which uses a bloom filter on blocks to figure out whether a particular block @@ -61,9 +68,19 @@ func NewFilterFromMap(object map[string]interface{}, eth EthManager) *Filter { filter.SetSkip(object["skip"].(int)) } + if object["altered"] != nil { + filter.altered = makeAltered(object["altered"]) + } + + fmt.Println("ALTERED", filter.altered) + return filter } +func (self *Filter) AddAltered(id, address []byte) { + self.altered = append(self.altered, data{id, address}) +} + // Set the earliest and latest block for filtering. // -1 = latest block (i.e., the current block) // hash = particular hash from-to @@ -158,17 +175,19 @@ func (self *Filter) Find() []*ethstate.Message { return messages } +func includes(addresses [][]byte, a []byte) (found bool) { + for _, addr := range addresses { + if bytes.Compare(addr, a) == 0 { + return true + } + } + + return +} + func (self *Filter) FilterMessages(msgs []*ethstate.Message) []*ethstate.Message { var messages []*ethstate.Message - includes := func(addresses [][]byte, a []byte) (found bool) { - for _, addr := range addresses { - if bytes.Compare(addr, a) == 0 { - return true - } - } - return - } // Filter the messages for interesting stuff for _, message := range msgs { if len(self.to) > 0 && !includes(self.to, message.To) { @@ -179,6 +198,28 @@ func (self *Filter) FilterMessages(msgs []*ethstate.Message) []*ethstate.Message continue } + var match bool + if len(self.altered) == 0 { + match = true + } + + for _, item := range self.altered { + if len(item.id) > 0 && bytes.Compare(message.To, item.id) != 0 { + continue + } + + if len(item.address) > 0 && !includes(message.ChangedAddresses, item.address) { + continue + } + + match = true + break + } + + if !match { + continue + } + messages = append(messages, message) } @@ -219,3 +260,47 @@ func (self *Filter) bloomFilter(block *Block) bool { return fromIncluded && toIncluded } + +// Conversion methodn +func mapToData(m map[string]interface{}) (d data) { + if str, ok := m["id"].(string); ok { + d.id = ethutil.Hex2Bytes(str) + } + + if str, ok := m["at"].(string); ok { + d.address = ethutil.Hex2Bytes(str) + } + + return +} + +// data can come in in the following formats: +// ["aabbccdd", {id: "ccddee", at: "11223344"}], "aabbcc", {id: "ccddee", at: "1122"} +func makeAltered(v interface{}) (d []data) { + if str, ok := v.(string); ok { + d = append(d, data{ethutil.Hex2Bytes(str), nil}) + } else if obj, ok := v.(map[string]interface{}); ok { + d = append(d, mapToData(obj)) + } else if slice, ok := v.([]interface{}); ok { + for _, item := range slice { + d = append(d, makeAltered(item)...) + } + } else if qList, ok := v.(*qml.List); ok { + var s []interface{} + qList.Convert(&s) + + fmt.Println(s) + + d = makeAltered(s) + } else if qMap, ok := v.(*qml.Map); ok { + var m map[string]interface{} + qMap.Convert(&m) + fmt.Println(m) + + d = makeAltered(m) + } else { + panic(fmt.Sprintf("makeAltered err (unknown conversion): %T\n", v)) + } + + return +} diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index 1f47a2e0b..08bd22d29 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -373,11 +373,17 @@ func (sm *StateManager) Stop() { func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter { bloomf := NewBloomFilter(nil) - for addr, stateObject := range state.Manifest().ObjectChanges { - // Set the bloom filter's bin - bloomf.Set([]byte(addr)) + /* + for addr, stateObject := range state.Manifest().ObjectChanges { + // Set the bloom filter's bin + bloomf.Set([]byte(addr)) - sm.Ethereum.Reactor().Post("object:"+addr, stateObject) + sm.Ethereum.Reactor().Post("object:"+addr, stateObject) + } + */ + for _, msg := range state.Manifest().Messages { + bloomf.Set(msg.To) + bloomf.Set(msg.From) } sm.Ethereum.Reactor().Post("messages", state.Manifest().Messages) diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go index 489ff2b6a..f8452cdb3 100644 --- a/ethchain/state_transition.go +++ b/ethchain/state_transition.go @@ -225,7 +225,7 @@ func (self *StateTransition) TransitionState() (err error) { // script section for the state object. self.data = nil - code, err := self.Eval(receiver.Init(), receiver, "init") + code, err := self.Eval(msg, receiver.Init(), receiver, "init") if err != nil { self.state.Set(snapshot) @@ -236,7 +236,7 @@ func (self *StateTransition) TransitionState() (err error) { msg.Output = code } else { if len(receiver.Code) > 0 { - ret, err := self.Eval(receiver.Code, receiver, "code") + ret, err := self.Eval(msg, receiver.Code, receiver, "code") if err != nil { self.state.Set(snapshot) @@ -263,12 +263,12 @@ func (self *StateTransition) transferValue(sender, receiver *ethstate.StateObjec return nil } -func (self *StateTransition) Eval(script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { +func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context *ethstate.StateObject, typ string) (ret []byte, err error) { var ( transactor = self.Sender() state = self.state env = NewEnv(state, self.tx, self.block) - callerClosure = ethvm.NewClosure(transactor, context, script, self.gas, self.gasPrice) + callerClosure = ethvm.NewClosure(msg, transactor, context, script, self.gas, self.gasPrice) ) vm := ethvm.New(env) |