diff options
Diffstat (limited to 'whisper')
-rw-r--r-- | whisper/doc.go | 16 | ||||
-rw-r--r-- | whisper/envelope.go | 12 | ||||
-rw-r--r-- | whisper/main.go | 14 | ||||
-rw-r--r-- | whisper/util.go | 11 | ||||
-rw-r--r-- | whisper/whisper.go | 29 |
5 files changed, 51 insertions, 31 deletions
diff --git a/whisper/doc.go b/whisper/doc.go new file mode 100644 index 000000000..986df8fb9 --- /dev/null +++ b/whisper/doc.go @@ -0,0 +1,16 @@ +/* +Package whisper implements the Whisper PoC-1. + +(https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec) + +Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP). +As such it may be likened and compared to both, not dissimilar to the +matter/energy duality (apologies to physicists for the blatant abuse of a +fundamental and beautiful natural principle). + +Whisper is a pure identity-based messaging system. Whisper provides a low-level +(non-application-specific) but easily-accessible API without being based upon +or prejudiced by the low-level hardware attributes and characteristics, +particularly the notion of singular endpoints. +*/ +package whisper diff --git a/whisper/envelope.go b/whisper/envelope.go index 683e88128..066e20f6a 100644 --- a/whisper/envelope.go +++ b/whisper/envelope.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/rlp" + "github.com/obscuren/ecies" ) const ( @@ -73,10 +74,15 @@ func (self *Envelope) Open(prv *ecdsa.PrivateKey) (msg *Message, err error) { message.Flags = data[0] message.Signature = data[1:66] } - message.Payload = data[dataStart:] + + payload := data[dataStart:] if prv != nil { - message.Payload, err = crypto.Decrypt(prv, message.Payload) - if err != nil { + message.Payload, err = crypto.Decrypt(prv, payload) + switch err { + case ecies.ErrInvalidPublicKey: // Payload isn't encrypted + message.Payload = payload + return &message, err + default: return nil, fmt.Errorf("unable to open envelope. Decrypt failed: %v", err) } } diff --git a/whisper/main.go b/whisper/main.go index 2ee2f3ff1..edd5f7004 100644 --- a/whisper/main.go +++ b/whisper/main.go @@ -5,10 +5,8 @@ package main import ( "fmt" "log" - "net" "os" - "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/whisper" @@ -20,12 +18,12 @@ func main() { pub, _ := secp256k1.GenerateKeyPair() - whisper := whisper.New(&event.TypeMux{}) + whisper := whisper.New() srv := p2p.Server{ MaxPeers: 10, Identity: p2p.NewSimpleClientIdentity("whisper-go", "1.0", "", string(pub)), - ListenAddr: ":30303", + ListenAddr: ":30300", NAT: p2p.UPNP(), Protocols: []p2p.Protocol{whisper.Protocol()}, @@ -35,13 +33,5 @@ func main() { os.Exit(1) } - // add seed peers - seed, err := net.ResolveTCPAddr("tcp", "poc-7.ethdev.com:30300") - if err != nil { - fmt.Println("couldn't resolve:", err) - os.Exit(1) - } - srv.SuggestPeer(seed.IP, seed.Port, nil) - select {} } diff --git a/whisper/util.go b/whisper/util.go index abef1d667..7a222395f 100644 --- a/whisper/util.go +++ b/whisper/util.go @@ -18,10 +18,19 @@ func Topics(data [][]byte) [][]byte { return d } -func TopicsFromString(data []string) [][]byte { +func TopicsFromString(data ...string) [][]byte { d := make([][]byte, len(data)) for i, str := range data { d[i] = hashTopic([]byte(str)) } return d } + +func bytesToMap(s [][]byte) map[string]struct{} { + m := make(map[string]struct{}) + for _, topic := range s { + m[string(topic)] = struct{}{} + } + + return m +} diff --git a/whisper/whisper.go b/whisper/whisper.go index 356debd1c..ffcdd7d40 100644 --- a/whisper/whisper.go +++ b/whisper/whisper.go @@ -4,13 +4,14 @@ import ( "bytes" "crypto/ecdsa" "errors" - "fmt" "sync" "time" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event/filter" + "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/p2p" + "github.com/obscuren/ecies" "gopkg.in/fatih/set.v0" ) @@ -47,6 +48,8 @@ type MessageEvent struct { const DefaultTtl = 50 * time.Second +var wlogger = logger.NewLogger("SHH") + type Whisper struct { protocol p2p.Protocol filters *filter.Filters @@ -68,17 +71,6 @@ func New() *Whisper { quit: make(chan struct{}), } whisper.filters.Start() - go whisper.update() - - // XXX TODO REMOVE TESTING CODE - msg := NewMessage([]byte(fmt.Sprintf("Hello world. This is whisper-go. Incase you're wondering; the time is %v", time.Now()))) - envelope, _ := msg.Seal(DefaultPow, Opts{ - Ttl: DefaultTtl, - }) - if err := whisper.Send(envelope); err != nil { - fmt.Println(err) - } - // XXX TODO REMOVE TESTING CODE // p2p whisper sub protocol handler whisper.protocol = p2p.Protocol{ @@ -91,6 +83,11 @@ func New() *Whisper { return whisper } +func (self *Whisper) Start() { + wlogger.Infoln("Whisper started") + go self.update() +} + func (self *Whisper) Stop() { close(self.quit) } @@ -122,6 +119,7 @@ func (self *Whisper) Watch(opts Filter) int { return self.filters.Install(filter.Generic{ Str1: string(crypto.FromECDSA(opts.To)), Str2: string(crypto.FromECDSAPub(opts.From)), + Data: bytesToMap(opts.Topics), Fn: func(data interface{}) { opts.Fn(data.(*Message)) }, @@ -177,7 +175,7 @@ func (self *Whisper) add(envelope *Envelope) error { if !self.expiry[envelope.Expiry].Has(hash) { self.expiry[envelope.Expiry].Add(hash) - self.postEvent(envelope) + go self.postEvent(envelope) } return nil @@ -230,13 +228,14 @@ func (self *Whisper) envelopes() (envelopes []*Envelope) { func (self *Whisper) postEvent(envelope *Envelope) { for _, key := range self.keys { - if message, err := envelope.Open(key); err == nil { + if message, err := envelope.Open(key); err == nil || (err != nil && err == ecies.ErrInvalidPublicKey) { // Create a custom filter? self.filters.Notify(filter.Generic{ Str1: string(crypto.FromECDSA(key)), Str2: string(crypto.FromECDSAPub(message.Recover())), + Data: bytesToMap(envelope.Topics), }, message) } else { - fmt.Println(err) + wlogger.Infoln(err) } } } |