shh.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of go-ethereum.
  3. //
  4. // go-ethereum is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // go-ethereum is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
  16. package api
  17. import (
  18. "math/big"
  19. "github.com/ethereum/go-ethereum/eth"
  20. "github.com/ethereum/go-ethereum/rpc/codec"
  21. "github.com/ethereum/go-ethereum/rpc/shared"
  22. "github.com/ethereum/go-ethereum/xeth"
  23. )
  24. const (
  25. ShhApiVersion = "1.0"
  26. )
  27. var (
  28. // mapping between methods and handlers
  29. shhMapping = map[string]shhhandler{
  30. "shh_version": (*shhApi).Version,
  31. "shh_post": (*shhApi).Post,
  32. "shh_hasIdentity": (*shhApi).HasIdentity,
  33. "shh_newIdentity": (*shhApi).NewIdentity,
  34. "shh_newFilter": (*shhApi).NewFilter,
  35. "shh_uninstallFilter": (*shhApi).UninstallFilter,
  36. "shh_getFilterChanges": (*shhApi).GetFilterChanges,
  37. }
  38. )
  39. func newWhisperOfflineError(method string) error {
  40. return shared.NewNotAvailableError(method, "whisper offline")
  41. }
  42. // net callback handler
  43. type shhhandler func(*shhApi, *shared.Request) (interface{}, error)
  44. // shh api provider
  45. type shhApi struct {
  46. xeth *xeth.XEth
  47. ethereum *eth.Ethereum
  48. methods map[string]shhhandler
  49. codec codec.ApiCoder
  50. }
  51. // create a new whisper api instance
  52. func NewShhApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *shhApi {
  53. return &shhApi{
  54. xeth: xeth,
  55. ethereum: eth,
  56. methods: shhMapping,
  57. codec: coder.New(nil),
  58. }
  59. }
  60. // collection with supported methods
  61. func (self *shhApi) Methods() []string {
  62. methods := make([]string, len(self.methods))
  63. i := 0
  64. for k := range self.methods {
  65. methods[i] = k
  66. i++
  67. }
  68. return methods
  69. }
  70. // Execute given request
  71. func (self *shhApi) Execute(req *shared.Request) (interface{}, error) {
  72. if callback, ok := self.methods[req.Method]; ok {
  73. return callback(self, req)
  74. }
  75. return nil, shared.NewNotImplementedError(req.Method)
  76. }
  77. func (self *shhApi) Name() string {
  78. return shared.ShhApiName
  79. }
  80. func (self *shhApi) ApiVersion() string {
  81. return ShhApiVersion
  82. }
  83. func (self *shhApi) Version(req *shared.Request) (interface{}, error) {
  84. w := self.xeth.Whisper()
  85. if w == nil {
  86. return nil, newWhisperOfflineError(req.Method)
  87. }
  88. return w.Version(), nil
  89. }
  90. func (self *shhApi) Post(req *shared.Request) (interface{}, error) {
  91. w := self.xeth.Whisper()
  92. if w == nil {
  93. return nil, newWhisperOfflineError(req.Method)
  94. }
  95. args := new(WhisperMessageArgs)
  96. if err := self.codec.Decode(req.Params, &args); err != nil {
  97. return nil, err
  98. }
  99. err := w.Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl)
  100. if err != nil {
  101. return false, err
  102. }
  103. return true, nil
  104. }
  105. func (self *shhApi) HasIdentity(req *shared.Request) (interface{}, error) {
  106. w := self.xeth.Whisper()
  107. if w == nil {
  108. return nil, newWhisperOfflineError(req.Method)
  109. }
  110. args := new(WhisperIdentityArgs)
  111. if err := self.codec.Decode(req.Params, &args); err != nil {
  112. return nil, err
  113. }
  114. return w.HasIdentity(args.Identity), nil
  115. }
  116. func (self *shhApi) NewIdentity(req *shared.Request) (interface{}, error) {
  117. w := self.xeth.Whisper()
  118. if w == nil {
  119. return nil, newWhisperOfflineError(req.Method)
  120. }
  121. return w.NewIdentity(), nil
  122. }
  123. func (self *shhApi) NewFilter(req *shared.Request) (interface{}, error) {
  124. args := new(WhisperFilterArgs)
  125. if err := self.codec.Decode(req.Params, &args); err != nil {
  126. return nil, err
  127. }
  128. id := self.xeth.NewWhisperFilter(args.To, args.From, args.Topics)
  129. return newHexNum(big.NewInt(int64(id)).Bytes()), nil
  130. }
  131. func (self *shhApi) UninstallFilter(req *shared.Request) (interface{}, error) {
  132. args := new(FilterIdArgs)
  133. if err := self.codec.Decode(req.Params, &args); err != nil {
  134. return nil, err
  135. }
  136. return self.xeth.UninstallWhisperFilter(args.Id), nil
  137. }
  138. func (self *shhApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
  139. w := self.xeth.Whisper()
  140. if w == nil {
  141. return nil, newWhisperOfflineError(req.Method)
  142. }
  143. // Retrieve all the new messages arrived since the last request
  144. args := new(FilterIdArgs)
  145. if err := self.codec.Decode(req.Params, &args); err != nil {
  146. return nil, err
  147. }
  148. return self.xeth.WhisperMessagesChanged(args.Id), nil
  149. }
  150. func (self *shhApi) GetMessages(req *shared.Request) (interface{}, error) {
  151. w := self.xeth.Whisper()
  152. if w == nil {
  153. return nil, newWhisperOfflineError(req.Method)
  154. }
  155. // Retrieve all the cached messages matching a specific, existing filter
  156. args := new(FilterIdArgs)
  157. if err := self.codec.Decode(req.Params, &args); err != nil {
  158. return nil, err
  159. }
  160. return self.xeth.WhisperMessages(args.Id), nil
  161. }