diff --git a/whisper/shhapi/api.go b/whisper/shhapi/api.go index a660f35d12..6ed3e17c24 100644 --- a/whisper/shhapi/api.go +++ b/whisper/shhapi/api.go @@ -149,9 +149,9 @@ func (api *PublicWhisperAPI) DeleteSymKey(name string) error { // NewWhisperFilter creates and registers a new message filter to watch for inbound whisper messages. // Returns the ID of the newly created Filter. -func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (*rpc.HexNumber, error) { +func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) { if api.whisper == nil { - return nil, whisperOffLineErr + return 0, whisperOffLineErr } filter := whisperv5.Filter{ @@ -173,25 +173,25 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (*rpc.HexNumber, if len(args.Topics) == 0 { info := "NewFilter: at least one topic must be specified" glog.V(logger.Error).Infof(info) - return nil, errors.New(info) + return 0, errors.New(info) } if len(args.KeyName) != 0 && len(filter.KeySym) == 0 { info := "NewFilter: key was not found by name: " + args.KeyName glog.V(logger.Error).Infof(info) - return nil, errors.New(info) + return 0, errors.New(info) } if len(args.To) == 0 && len(filter.KeySym) == 0 { info := "NewFilter: filter must contain either symmetric or asymmetric key" glog.V(logger.Error).Infof(info) - return nil, errors.New(info) + return 0, errors.New(info) } if len(args.To) != 0 && len(filter.KeySym) != 0 { info := "NewFilter: filter must not contain both symmetric and asymmetric key" glog.V(logger.Error).Infof(info) - return nil, errors.New(info) + return 0, errors.New(info) } if len(args.To) > 0 { @@ -199,13 +199,13 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (*rpc.HexNumber, if !whisperv5.ValidatePublicKey(dst) { info := "NewFilter: Invalid 'To' address" glog.V(logger.Error).Infof(info) - return nil, errors.New(info) + return 0, errors.New(info) } filter.KeyAsym = api.whisper.GetIdentity(string(args.To)) if filter.KeyAsym == nil { info := "NewFilter: non-existent identity provided" glog.V(logger.Error).Infof(info) - return nil, errors.New(info) + return 0, errors.New(info) } } @@ -213,22 +213,22 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (*rpc.HexNumber, if !whisperv5.ValidatePublicKey(filter.Src) { info := "NewFilter: Invalid 'From' address" glog.V(logger.Error).Infof(info) - return nil, errors.New(info) + return 0, errors.New(info) } } id := api.whisper.Watch(&filter) - return rpc.NewHexNumber(id), nil + return id, nil } // UninstallFilter disables and removes an existing filter. -func (api *PublicWhisperAPI) UninstallFilter(filterId rpc.HexNumber) { - api.whisper.Unwatch(filterId.Int()) +func (api *PublicWhisperAPI) UninstallFilter(filterId uint32) { + api.whisper.Unwatch(filterId) } // GetFilterChanges retrieves all the new messages matched by a filter since the last retrieval. -func (api *PublicWhisperAPI) GetFilterChanges(filterId rpc.HexNumber) []WhisperMessage { - f := api.whisper.GetFilter(filterId.Int()) +func (api *PublicWhisperAPI) GetFilterChanges(filterId uint32) []WhisperMessage { + f := api.whisper.GetFilter(filterId) if f != nil { newMail := f.Retrieve() return toWhisperMessages(newMail) @@ -237,8 +237,8 @@ func (api *PublicWhisperAPI) GetFilterChanges(filterId rpc.HexNumber) []WhisperM } // GetMessages retrieves all the known messages that match a specific filter. -func (api *PublicWhisperAPI) GetMessages(filterId rpc.HexNumber) []WhisperMessage { - all := api.whisper.Messages(filterId.Int()) +func (api *PublicWhisperAPI) GetMessages(filterId uint32) []WhisperMessage { + all := api.whisper.Messages(filterId) return toWhisperMessages(all) } @@ -284,7 +284,7 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { } filter := api.whisper.GetFilter(args.FilterID) - if filter == nil && args.FilterID > -1 { + if filter == nil && args.FilterID > 0 { info := fmt.Sprintf("Post: wrong filter id %d", args.FilterID) glog.V(logger.Error).Infof(info) return errors.New(info) @@ -367,56 +367,17 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { } type PostArgs struct { - TTL uint32 - From string - To string - KeyName string - Topic whisperv5.TopicType - Padding rpc.HexBytes - Payload rpc.HexBytes - WorkTime uint32 - PoW float64 - FilterID int - PeerID rpc.HexBytes -} - -func (args *PostArgs) UnmarshalJSON(data []byte) (err error) { - var obj struct { - TTL uint32 `json:"ttl"` - From string `json:"from"` - To string `json:"to"` - KeyName string `json:"keyname"` - Topic whisperv5.TopicType `json:"topic"` - Payload rpc.HexBytes `json:"payload"` - Padding rpc.HexBytes `json:"padding"` - WorkTime uint32 `json:"worktime"` - PoW float64 `json:"pow"` - FilterID rpc.HexBytes `json:"filterID"` - PeerID rpc.HexBytes `json:"peerID"` - } - - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - args.TTL = obj.TTL - args.From = obj.From - args.To = obj.To - args.KeyName = obj.KeyName - args.Topic = obj.Topic - args.Payload = obj.Payload - args.Padding = obj.Padding - args.WorkTime = obj.WorkTime - args.PoW = obj.PoW - args.FilterID = -1 - args.PeerID = obj.PeerID - - if obj.FilterID != nil { - x := whisperv5.BytesToIntBigEndian(obj.FilterID) - args.FilterID = int(x) - } - - return nil + TTL uint32 `json:"ttl"` + From string `json:"from"` + To string `json:"to"` + KeyName string `json:"keyname"` + Topic whisperv5.TopicType `json:"topic"` + Padding rpc.HexBytes `json:"padding"` + Payload rpc.HexBytes `json:"payload"` + WorkTime uint32 `json:"worktime"` + PoW float64 `json:"pow"` + FilterID uint32 `json:"filterID"` + PeerID rpc.HexBytes `json:"peerID"` } type WhisperFilterArgs struct { diff --git a/whisper/shhapi/api_test.go b/whisper/shhapi/api_test.go index 820d4f01d8..8287b471a2 100644 --- a/whisper/shhapi/api_test.go +++ b/whisper/shhapi/api_test.go @@ -21,8 +21,9 @@ import ( "testing" "time" + "encoding/json" + "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/whisper/whisperv5" ) @@ -42,10 +43,9 @@ func TestBasic(x *testing.T) { x.Fatalf("wrong version: %d.", ver.Uint64()) } - var hexnum rpc.HexNumber - mail := api.GetFilterChanges(hexnum) + mail := api.GetFilterChanges(1) if len(mail) != 0 { - x.Fatalf("failed GetFilterChanges") + x.Fatalf("failed GetFilterChanges: premature result") } exist, err := api.HasIdentity(id) @@ -213,12 +213,12 @@ func TestUnmarshalPostArgs(x *testing.T) { "payload":"0x7061796C6F61642073686F756C642062652070736575646F72616E646F6D", "worktime":777, "pow":3.1416, - "filterID":"0x40", + "filterID":64, "peerID":"0xf26e7779" }`) var a PostArgs - err := a.UnmarshalJSON(s) + err := json.Unmarshal(s, &a) if err != nil { x.Fatalf("failed UnmarshalJSON: %s.", err) } @@ -258,9 +258,9 @@ func TestUnmarshalPostArgs(x *testing.T) { } } -func waitForMessage(api *PublicWhisperAPI, id *rpc.HexNumber, target int) bool { +func waitForMessage(api *PublicWhisperAPI, id uint32, target int) bool { for i := 0; i < 64; i++ { - all := api.GetMessages(*id) + all := api.GetMessages(id) if len(all) >= target { return true } @@ -336,7 +336,7 @@ func TestIntegrationAsym(x *testing.T) { x.Fatalf("failed to receive first message: timeout.") } - mail := api.GetFilterChanges(*id) + mail := api.GetFilterChanges(id) if len(mail) != 1 { x.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) } @@ -358,7 +358,7 @@ func TestIntegrationAsym(x *testing.T) { x.Fatalf("failed to receive second message: timeout.") } - mail = api.GetFilterChanges(*id) + mail = api.GetFilterChanges(id) if len(mail) != 1 { x.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) } @@ -432,7 +432,7 @@ func TestIntegrationSym(x *testing.T) { x.Fatalf("failed test case 33 (receive first message: timeout).") } - mail := api.GetFilterChanges(*id) + mail := api.GetFilterChanges(id) if len(mail) != 1 { x.Fatalf("failed test case 34 (GetFilterChanges: got %d messages).", len(mail)) } @@ -454,7 +454,7 @@ func TestIntegrationSym(x *testing.T) { x.Fatalf("failed test case 43 (receive second message: timeout).") } - mail = api.GetFilterChanges(*id) + mail = api.GetFilterChanges(id) if len(mail) != 1 { x.Fatalf("failed test case 44 (GetFilterChanges: got %d messages).", len(mail)) } @@ -510,7 +510,7 @@ func TestIntegrationSymWithFilter(x *testing.T) { var p PostArgs p.TTL = 1 - p.FilterID = id.Int() + p.FilterID = id p.From = sig p.Padding = []byte("test string") p.Payload = []byte("extended test string") @@ -528,7 +528,7 @@ func TestIntegrationSymWithFilter(x *testing.T) { x.Fatalf("failed to receive first message: timeout.") } - mail := api.GetFilterChanges(*id) + mail := api.GetFilterChanges(id) if len(mail) != 1 { x.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) } @@ -550,7 +550,7 @@ func TestIntegrationSymWithFilter(x *testing.T) { x.Fatalf("failed to receive second message: timeout.") } - mail = api.GetFilterChanges(*id) + mail = api.GetFilterChanges(id) if len(mail) != 1 { x.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail)) } diff --git a/whisper/whisperv5/doc.go b/whisper/whisperv5/doc.go index 6bce5a59e5..c37bcb9263 100644 --- a/whisper/whisperv5/doc.go +++ b/whisper/whisperv5/doc.go @@ -46,7 +46,7 @@ const ( messagesCode = 1 p2pCode = 2 mailRequestCode = 3 - NumberOfMessageCodes = 10 + NumberOfMessageCodes = 32 paddingMask = byte(3) signatureFlag = byte(4) diff --git a/whisper/whisperv5/envelope.go b/whisper/whisperv5/envelope.go index 57d454a08b..cb8fc89d19 100644 --- a/whisper/whisperv5/envelope.go +++ b/whisper/whisperv5/envelope.go @@ -131,7 +131,7 @@ func (e *Envelope) calculatePoW(diff uint32) { h = crypto.Keccak256(buf) firstBit := common.FirstBitSet(common.BigD(h)) x := math.Pow(2, float64(firstBit)) - x /= float64(len(e.Data)) + x /= float64(len(e.Data) + len(e.Salt) + len(e.AESNonce)) x /= float64(e.TTL + diff) e.pow = x } diff --git a/whisper/whisperv5/filter.go b/whisper/whisperv5/filter.go index 2c61bde99f..fd5f5083f6 100644 --- a/whisper/whisperv5/filter.go +++ b/whisper/whisperv5/filter.go @@ -37,20 +37,20 @@ type Filter struct { } type Filters struct { - id int - watchers map[int]*Filter + id uint32 // can contain any value except zero + watchers map[uint32]*Filter whisper *Whisper mutex sync.RWMutex } func NewFilters(w *Whisper) *Filters { return &Filters{ - watchers: make(map[int]*Filter), + watchers: make(map[uint32]*Filter), whisper: w, } } -func (fs *Filters) Install(watcher *Filter) int { +func (fs *Filters) Install(watcher *Filter) uint32 { if watcher.Messages == nil { watcher.Messages = make(map[common.Hash]*ReceivedMessage) } @@ -58,19 +58,18 @@ func (fs *Filters) Install(watcher *Filter) int { fs.mutex.Lock() defer fs.mutex.Unlock() - fs.watchers[fs.id] = watcher - ret := fs.id fs.id++ - return ret + fs.watchers[fs.id] = watcher + return fs.id } -func (fs *Filters) Uninstall(id int) { +func (fs *Filters) Uninstall(id uint32) { fs.mutex.Lock() defer fs.mutex.Unlock() delete(fs.watchers, id) } -func (fs *Filters) Get(i int) *Filter { +func (fs *Filters) Get(i uint32) *Filter { fs.mutex.RLock() defer fs.mutex.RUnlock() return fs.watchers[i] diff --git a/whisper/whisperv5/filter_test.go b/whisper/whisperv5/filter_test.go index 8406d813a0..c5a9f59fb0 100644 --- a/whisper/whisperv5/filter_test.go +++ b/whisper/whisperv5/filter_test.go @@ -43,7 +43,7 @@ func InitDebugTest(i int64) { type FilterTestCase struct { f *Filter - id int + id uint32 alive bool msgCnt int } @@ -100,7 +100,7 @@ func TestInstallFilters(x *testing.T) { filters := NewFilters(w) tst := generateTestCases(x, SizeTestFilters) - var j int + var j uint32 for i := 0; i < SizeTestFilters; i++ { j = filters.Install(tst[i].f) tst[i].id = j @@ -516,7 +516,8 @@ func TestWatchers(x *testing.T) { const NumFilters = 16 const NumMessages = 256 - var i, j int + var i int + var j uint32 var e *Envelope w := NewWhisper(nil) @@ -532,7 +533,7 @@ func TestWatchers(x *testing.T) { var envelopes [NumMessages]*Envelope for i = 0; i < NumMessages; i++ { - j = rand.Int() % NumFilters + j = rand.Uint32() % NumFilters e = generateCompatibeEnvelope(x, tst[j].f) envelopes[i] = e tst[j].msgCnt++ @@ -585,7 +586,7 @@ func TestWatchers(x *testing.T) { envelopes[0] = e tst[0].msgCnt++ for i = 1; i < NumMessages; i++ { - j = rand.Int() % NumFilters + j = rand.Uint32() % NumFilters e = generateCompatibeEnvelope(x, tst[j].f) envelopes[i] = e tst[j].msgCnt++ @@ -639,7 +640,10 @@ func TestWatchers(x *testing.T) { x.Fatalf("failed test case 9 with seed %d.", seed) } - f := filters.Get(0) + f := filters.Get(1) + if f == nil { + x.Fatalf("failed to get the filter with seed %d.", seed) + } f.AcceptP2P = true total = 0 filters.NotifyWatchers(envelopes[0], p2pCode) diff --git a/whisper/whisperv5/peer_test.go b/whisper/whisperv5/peer_test.go index d4893bacd7..8a38f2a1bc 100644 --- a/whisper/whisperv5/peer_test.go +++ b/whisper/whisperv5/peer_test.go @@ -79,7 +79,7 @@ type TestNode struct { shh *Whisper id *ecdsa.PrivateKey server *p2p.Server - filerId int + filerId uint32 } var result TestData diff --git a/whisper/whisperv5/whisper.go b/whisper/whisperv5/whisper.go index 8368108244..049079ba8a 100644 --- a/whisper/whisperv5/whisper.go +++ b/whisper/whisperv5/whisper.go @@ -245,16 +245,16 @@ func (w *Whisper) GetSymKey(name string) []byte { // Watch installs a new message handler to run in case a matching packet arrives // from the whisper network. -func (w *Whisper) Watch(f *Filter) int { +func (w *Whisper) Watch(f *Filter) uint32 { return w.filters.Install(f) } -func (w *Whisper) GetFilter(id int) *Filter { +func (w *Whisper) GetFilter(id uint32) *Filter { return w.filters.Get(id) } // Unwatch removes an installed message handler. -func (w *Whisper) Unwatch(id int) { +func (w *Whisper) Unwatch(id uint32) { w.filters.Uninstall(id) } @@ -507,7 +507,7 @@ func (w *Whisper) Envelopes() []*Envelope { } // Messages retrieves all the decrypted messages matching a filter id. -func (w *Whisper) Messages(id int) []*ReceivedMessage { +func (w *Whisper) Messages(id uint32) []*ReceivedMessage { result := make([]*ReceivedMessage, 0) w.poolMu.RLock() defer w.poolMu.RUnlock()