Whisper API fixed (#3687)
* whisper: wnode updated for tests with geth * whisper: updated processing of incoming messages * whisper: symmetric encryption updated * whisper: filter id type changed to enhance security * whisper: allow filter without topic for asymmetric encryption * whisper: POW updated * whisper: logging updated * whisper: spellchecker update * whisper: error handling changed * whisper: JSON field names fixed
This commit is contained in:
@ -123,7 +123,7 @@ func (api *PublicWhisperAPI) GenerateSymKey(name string) error {
|
||||
}
|
||||
|
||||
// AddSymKey stores the key under the 'name' id.
|
||||
func (api *PublicWhisperAPI) AddSymKey(name string, key []byte) error {
|
||||
func (api *PublicWhisperAPI) AddSymKey(name string, key hexutil.Bytes) error {
|
||||
if api.whisper == nil {
|
||||
return whisperOffLineErr
|
||||
}
|
||||
@ -151,9 +151,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) (uint32, error) {
|
||||
func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (string, error) {
|
||||
if api.whisper == nil {
|
||||
return 0, whisperOffLineErr
|
||||
return "", whisperOffLineErr
|
||||
}
|
||||
|
||||
filter := Filter{
|
||||
@ -168,28 +168,28 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) {
|
||||
}
|
||||
filter.Topics = append(filter.Topics, args.Topics...)
|
||||
|
||||
if len(args.Topics) == 0 {
|
||||
if len(args.Topics) == 0 && len(args.KeyName) != 0 {
|
||||
info := "NewFilter: at least one topic must be specified"
|
||||
glog.V(logger.Error).Infof(info)
|
||||
return 0, errors.New(info)
|
||||
return "", 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 0, errors.New(info)
|
||||
return "", 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 0, errors.New(info)
|
||||
return "", 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 0, errors.New(info)
|
||||
return "", errors.New(info)
|
||||
}
|
||||
|
||||
if len(args.To) > 0 {
|
||||
@ -197,13 +197,13 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) {
|
||||
if !ValidatePublicKey(dst) {
|
||||
info := "NewFilter: Invalid 'To' address"
|
||||
glog.V(logger.Error).Infof(info)
|
||||
return 0, errors.New(info)
|
||||
return "", 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 0, errors.New(info)
|
||||
return "", errors.New(info)
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,21 +211,20 @@ func (api *PublicWhisperAPI) NewFilter(args WhisperFilterArgs) (uint32, error) {
|
||||
if !ValidatePublicKey(filter.Src) {
|
||||
info := "NewFilter: Invalid 'From' address"
|
||||
glog.V(logger.Error).Infof(info)
|
||||
return 0, errors.New(info)
|
||||
return "", errors.New(info)
|
||||
}
|
||||
}
|
||||
|
||||
id := api.whisper.Watch(&filter)
|
||||
return id, nil
|
||||
return api.whisper.Watch(&filter)
|
||||
}
|
||||
|
||||
// UninstallFilter disables and removes an existing filter.
|
||||
func (api *PublicWhisperAPI) UninstallFilter(filterId uint32) {
|
||||
func (api *PublicWhisperAPI) UninstallFilter(filterId string) {
|
||||
api.whisper.Unwatch(filterId)
|
||||
}
|
||||
|
||||
// GetFilterChanges retrieves all the new messages matched by a filter since the last retrieval.
|
||||
func (api *PublicWhisperAPI) GetFilterChanges(filterId uint32) []WhisperMessage {
|
||||
func (api *PublicWhisperAPI) GetFilterChanges(filterId string) []*WhisperMessage {
|
||||
f := api.whisper.GetFilter(filterId)
|
||||
if f != nil {
|
||||
newMail := f.Retrieve()
|
||||
@ -235,14 +234,14 @@ func (api *PublicWhisperAPI) GetFilterChanges(filterId uint32) []WhisperMessage
|
||||
}
|
||||
|
||||
// GetMessages retrieves all the known messages that match a specific filter.
|
||||
func (api *PublicWhisperAPI) GetMessages(filterId uint32) []WhisperMessage {
|
||||
func (api *PublicWhisperAPI) GetMessages(filterId string) []*WhisperMessage {
|
||||
all := api.whisper.Messages(filterId)
|
||||
return toWhisperMessages(all)
|
||||
}
|
||||
|
||||
// toWhisperMessages converts a Whisper message to a RPC whisper message.
|
||||
func toWhisperMessages(messages []*ReceivedMessage) []WhisperMessage {
|
||||
msgs := make([]WhisperMessage, len(messages))
|
||||
func toWhisperMessages(messages []*ReceivedMessage) []*WhisperMessage {
|
||||
msgs := make([]*WhisperMessage, len(messages))
|
||||
for i, msg := range messages {
|
||||
msgs[i] = NewWhisperMessage(msg)
|
||||
}
|
||||
@ -282,8 +281,8 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
|
||||
}
|
||||
|
||||
filter := api.whisper.GetFilter(args.FilterID)
|
||||
if filter == nil && args.FilterID > 0 {
|
||||
info := fmt.Sprintf("Post: wrong filter id %d", args.FilterID)
|
||||
if filter == nil && len(args.FilterID) > 0 {
|
||||
info := fmt.Sprintf("Post: wrong filter id %s", args.FilterID)
|
||||
glog.V(logger.Error).Infof(info)
|
||||
return errors.New(info)
|
||||
}
|
||||
@ -299,7 +298,7 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
|
||||
if (params.Topic == TopicType{}) {
|
||||
sz := len(filter.Topics)
|
||||
if sz < 1 {
|
||||
info := fmt.Sprintf("Post: no topics in filter # %d", args.FilterID)
|
||||
info := fmt.Sprintf("Post: no topics in filter # %s", args.FilterID)
|
||||
glog.V(logger.Error).Infof(info)
|
||||
return errors.New(info)
|
||||
} else if sz == 1 {
|
||||
@ -374,17 +373,17 @@ type PostArgs struct {
|
||||
Payload hexutil.Bytes `json:"payload"`
|
||||
WorkTime uint32 `json:"worktime"`
|
||||
PoW float64 `json:"pow"`
|
||||
FilterID uint32 `json:"filterID"`
|
||||
FilterID string `json:"filterID"`
|
||||
PeerID hexutil.Bytes `json:"peerID"`
|
||||
}
|
||||
|
||||
type WhisperFilterArgs struct {
|
||||
To string
|
||||
From string
|
||||
KeyName string
|
||||
PoW float64
|
||||
Topics []TopicType
|
||||
AcceptP2P bool
|
||||
To string `json:"to"`
|
||||
From string `json:"from"`
|
||||
KeyName string `json:"keyname"`
|
||||
PoW float64 `json:"pow"`
|
||||
Topics []TopicType `json:"topics"`
|
||||
AcceptP2P bool `json:"p2p"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a
|
||||
@ -397,7 +396,7 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
KeyName string `json:"keyname"`
|
||||
PoW float64 `json:"pow"`
|
||||
Topics []interface{} `json:"topics"`
|
||||
AcceptP2P bool `json:"acceptP2P"`
|
||||
AcceptP2P bool `json:"p2p"`
|
||||
}
|
||||
if err := json.Unmarshal(b, &obj); err != nil {
|
||||
return err
|
||||
@ -438,6 +437,7 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
|
||||
// WhisperMessage is the RPC representation of a whisper message.
|
||||
type WhisperMessage struct {
|
||||
Topic string `json:"topic"`
|
||||
Payload string `json:"payload"`
|
||||
Padding string `json:"padding"`
|
||||
From string `json:"from"`
|
||||
@ -449,15 +449,22 @@ type WhisperMessage struct {
|
||||
}
|
||||
|
||||
// NewWhisperMessage converts an internal message into an API version.
|
||||
func NewWhisperMessage(message *ReceivedMessage) WhisperMessage {
|
||||
return WhisperMessage{
|
||||
func NewWhisperMessage(message *ReceivedMessage) *WhisperMessage {
|
||||
msg := WhisperMessage{
|
||||
Topic: common.ToHex(message.Topic[:]),
|
||||
Payload: common.ToHex(message.Payload),
|
||||
Padding: common.ToHex(message.Padding),
|
||||
From: common.ToHex(crypto.FromECDSAPub(message.SigToPubKey())),
|
||||
To: common.ToHex(crypto.FromECDSAPub(message.Dst)),
|
||||
Sent: message.Sent,
|
||||
TTL: message.TTL,
|
||||
PoW: message.PoW,
|
||||
Hash: common.ToHex(message.EnvelopeHash.Bytes()),
|
||||
}
|
||||
|
||||
if message.Dst != nil {
|
||||
msg.To = common.ToHex(crypto.FromECDSAPub(message.Dst))
|
||||
}
|
||||
if isMessageSigned(message.Raw[0]) {
|
||||
msg.From = common.ToHex(crypto.FromECDSAPub(message.SigToPubKey()))
|
||||
}
|
||||
return &msg
|
||||
}
|
||||
|
Reference in New Issue
Block a user