diff --git a/src/library.go b/src/library.go index 4053035b1..cb91d4c3c 100644 --- a/src/library.go +++ b/src/library.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "os" + "github.com/ethereum/go-ethereum/whisper" ) var emptyError = "" @@ -116,3 +117,42 @@ func addPeer(url *C.char) *C.char { return C.CString(string(outBytes)) } + +//export addWhisperFilter +func addWhisperFilter(filterJson *C.char) *C.char { + + var id int + var filter whisper.NewFilterArgs + + err := json.Unmarshal([]byte(C.GoString(filterJson)), &filter) + if err == nil { + id = doAddWhisperFilter(filter) + } + + errString := emptyError + if err != nil { + fmt.Fprintln(os.Stderr, err) + errString = err.Error() + } + + out := AddWhisperFilterResult{ + Id: id, + Error: errString, + } + outBytes, _ := json.Marshal(&out) + + return C.CString(string(outBytes)) + +} + +//export removeWhisperFilter +func removeWhisperFilter(idFilter int) { + + doRemoveWhisperFilter(idFilter) +} + +//export clearWhisperFilters +func clearWhisperFilters() { + + doClearWhisperFilters() +} \ No newline at end of file diff --git a/src/main.go b/src/main.go index ebf407b5b..944d31d11 100644 --- a/src/main.go +++ b/src/main.go @@ -14,6 +14,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/release" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/whisper" "gopkg.in/urfave/cli.v1" ) @@ -34,6 +35,7 @@ var ( c *cli.Context // the CLI context used to start the geth node accountSync *[]node.Service // the object used to sync accounts between geth services accountManager *accounts.Manager // the account manager attached to the currentNode + whisperService *whisper.Whisper // whisper service datadir string // data directory for geth ) @@ -86,7 +88,10 @@ func RunNode(nodeIn *node.Node) { if err := nodeIn.Service(&accountManager); err != nil { glog.V(logger.Warn).Infoln("cannot get account manager:", err) - } + } + if err := nodeIn.Service(&whisperService); err != nil { + glog.V(logger.Warn).Infoln("cannot get whisper service:", err) + } nodeIn.Wait() } diff --git a/src/types.go b/src/types.go index 1b043337b..d3e0636d0 100644 --- a/src/types.go +++ b/src/types.go @@ -14,3 +14,22 @@ type AddPeerResult struct { Success bool `json:"success"` Error string `json:"error"` } + +type AddWhisperFilterResult struct { + Id int `json:"id"` + Error string `json:"error"` +} + +type WhisperMessageEvent struct { + Payload string `json:"payload"` + To string `json:"to"` + From string `json:"from"` + Sent int64 `json:"sent"` + TTL int64 `json:"ttl"` + Hash string `json:"hash"` +} + +type GethEvent struct { + Type string `json:"type"` + Event interface{} `json:"event"` +} \ No newline at end of file diff --git a/src/whisper.go b/src/whisper.go new file mode 100644 index 000000000..bfbd8e9cb --- /dev/null +++ b/src/whisper.go @@ -0,0 +1,63 @@ +package main + +/* +#include +#include +#include +extern bool GethServiceSignalEvent( const char *jsonEvent ); +*/ +import "C" +import ( + "encoding/json" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/whisper" +) + +var( + whisperFilters []int +) + + +func onWhisperMessage(message *whisper.Message) { + event := GethEvent{ + Type: "whisper", + Event: WhisperMessageEvent{ + Payload: string(message.Payload), + From: common.ToHex(crypto.FromECDSAPub(message.Recover())), + To: common.ToHex(crypto.FromECDSAPub(message.To)), + Sent: message.Sent.Unix(), + TTL: int64(message.TTL / time.Second), + Hash: common.ToHex(message.Hash.Bytes()), + }, + } + body, _ := json.Marshal(&event) + C.GethServiceSignalEvent(C.CString(string(body))) +} + +func doAddWhisperFilter(args whisper.NewFilterArgs) int { + var id int + filter := whisper.Filter{ + To: crypto.ToECDSAPub(common.FromHex(args.To)), + From: crypto.ToECDSAPub(common.FromHex(args.From)), + Topics: whisper.NewFilterTopics(args.Topics...), + Fn: onWhisperMessage, + } + + id = whisperService.Watch(filter) + whisperFilters = append(whisperFilters, id) + return id +} + +func doRemoveWhisperFilter(idFilter int) { + whisperService.Unwatch(idFilter) +} + +func doClearWhisperFilters() { + for _, idFilter := range whisperFilters { + doRemoveWhisperFilter(idFilter) + } + whisperFilters = nil +} \ No newline at end of file