mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
whisper: refactored message processing
This commit is contained in:
parent
2dcf75a722
commit
e47820d164
5 changed files with 74 additions and 12 deletions
|
|
@ -55,6 +55,22 @@ func APIs() []rpc.API {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start starts the Whisper worker threads.
|
||||||
|
func (api *PublicWhisperAPI) Start() error {
|
||||||
|
if api.whisper == nil {
|
||||||
|
return whisperOffLineErr
|
||||||
|
}
|
||||||
|
return api.whisper.Start(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop stops the Whisper worker threads.
|
||||||
|
func (api *PublicWhisperAPI) Stop() error {
|
||||||
|
if api.whisper == nil {
|
||||||
|
return whisperOffLineErr
|
||||||
|
}
|
||||||
|
return api.whisper.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
// Version returns the Whisper version this node offers.
|
// Version returns the Whisper version this node offers.
|
||||||
func (api *PublicWhisperAPI) Version() (*rpc.HexNumber, error) {
|
func (api *PublicWhisperAPI) Version() (*rpc.HexNumber, error) {
|
||||||
if api.whisper == nil {
|
if api.whisper == nil {
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,9 @@ func TestIntegrationAsym(t *testing.T) {
|
||||||
t.Fatalf("failed to create API.")
|
t.Fatalf("failed to create API.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.Start()
|
||||||
|
defer api.Stop()
|
||||||
|
|
||||||
sig, err := api.NewIdentity()
|
sig, err := api.NewIdentity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed NewIdentity: %s.", err)
|
t.Fatalf("failed NewIdentity: %s.", err)
|
||||||
|
|
@ -375,6 +378,9 @@ func TestIntegrationSym(t *testing.T) {
|
||||||
t.Fatalf("failed to create API.")
|
t.Fatalf("failed to create API.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.Start()
|
||||||
|
defer api.Stop()
|
||||||
|
|
||||||
keyname := "schluessel"
|
keyname := "schluessel"
|
||||||
err := api.GenerateSymKey(keyname)
|
err := api.GenerateSymKey(keyname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -471,6 +477,9 @@ func TestIntegrationSymWithFilter(t *testing.T) {
|
||||||
t.Fatalf("failed to create API.")
|
t.Fatalf("failed to create API.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api.Start()
|
||||||
|
defer api.Stop()
|
||||||
|
|
||||||
keyname := "schluessel"
|
keyname := "schluessel"
|
||||||
err := api.GenerateSymKey(keyname)
|
err := api.GenerateSymKey(keyname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,10 @@ func (fs *Filters) Get(i uint32) *Filter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *Filters) NotifyWatchers(env *Envelope, messageCode uint64) {
|
func (fs *Filters) NotifyWatchers(env *Envelope, messageCode uint64) {
|
||||||
|
if env == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
fs.mutex.RLock()
|
fs.mutex.RLock()
|
||||||
var msg *ReceivedMessage
|
var msg *ReceivedMessage
|
||||||
for _, watcher := range fs.watchers {
|
for _, watcher := range fs.watchers {
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@ func initialize(t *testing.T) {
|
||||||
var node TestNode
|
var node TestNode
|
||||||
node.shh = NewWhisper(nil)
|
node.shh = NewWhisper(nil)
|
||||||
node.shh.test = true
|
node.shh.test = true
|
||||||
|
node.shh.Start(nil)
|
||||||
topics := make([]TopicType, 0)
|
topics := make([]TopicType, 0)
|
||||||
topics = append(topics, sharedTopic)
|
topics = append(topics, sharedTopic)
|
||||||
f := Filter{KeySym: sharedKey, Topics: topics}
|
f := Filter{KeySym: sharedKey, Topics: topics}
|
||||||
|
|
@ -166,6 +167,7 @@ func stopServers() {
|
||||||
n := nodes[i]
|
n := nodes[i]
|
||||||
if n != nil {
|
if n != nil {
|
||||||
n.shh.Unwatch(n.filerId)
|
n.shh.Unwatch(n.filerId)
|
||||||
|
n.shh.Stop()
|
||||||
n.server.Stop()
|
n.server.Stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import (
|
||||||
crand "crypto/rand"
|
crand "crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -35,6 +36,11 @@ import (
|
||||||
set "gopkg.in/fatih/set.v0"
|
set "gopkg.in/fatih/set.v0"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type QueueItem struct {
|
||||||
|
hash common.Hash
|
||||||
|
code uint64
|
||||||
|
}
|
||||||
|
|
||||||
// Whisper represents a dark communication interface through the Ethereum
|
// Whisper represents a dark communication interface through the Ethereum
|
||||||
// network, using its very own P2P communication layer.
|
// network, using its very own P2P communication layer.
|
||||||
type Whisper struct {
|
type Whisper struct {
|
||||||
|
|
@ -55,7 +61,9 @@ type Whisper struct {
|
||||||
|
|
||||||
mailServer MailServer
|
mailServer MailServer
|
||||||
|
|
||||||
quit chan struct{}
|
messageQueue chan QueueItem
|
||||||
|
quit chan struct{}
|
||||||
|
|
||||||
test bool
|
test bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,14 +71,15 @@ type Whisper struct {
|
||||||
// Param s should be passed if you want to implement mail server, otherwise nil.
|
// Param s should be passed if you want to implement mail server, otherwise nil.
|
||||||
func NewWhisper(server MailServer) *Whisper {
|
func NewWhisper(server MailServer) *Whisper {
|
||||||
whisper := &Whisper{
|
whisper := &Whisper{
|
||||||
privateKeys: make(map[string]*ecdsa.PrivateKey),
|
privateKeys: make(map[string]*ecdsa.PrivateKey),
|
||||||
symKeys: make(map[string][]byte),
|
symKeys: make(map[string][]byte),
|
||||||
envelopes: make(map[common.Hash]*Envelope),
|
envelopes: make(map[common.Hash]*Envelope),
|
||||||
messages: make(map[common.Hash]*ReceivedMessage),
|
messages: make(map[common.Hash]*ReceivedMessage),
|
||||||
expirations: make(map[uint32]*set.SetNonTS),
|
expirations: make(map[uint32]*set.SetNonTS),
|
||||||
peers: make(map[*Peer]struct{}),
|
peers: make(map[*Peer]struct{}),
|
||||||
mailServer: server,
|
mailServer: server,
|
||||||
quit: make(chan struct{}),
|
messageQueue: make(chan QueueItem, 1024),
|
||||||
|
quit: make(chan struct{}),
|
||||||
}
|
}
|
||||||
whisper.filters = NewFilters(whisper)
|
whisper.filters = NewFilters(whisper)
|
||||||
|
|
||||||
|
|
@ -270,6 +279,12 @@ func (w *Whisper) Send(envelope *Envelope) error {
|
||||||
func (w *Whisper) Start(*p2p.Server) error {
|
func (w *Whisper) Start(*p2p.Server) error {
|
||||||
glog.V(logger.Info).Infoln("Whisper started")
|
glog.V(logger.Info).Infoln("Whisper started")
|
||||||
go w.update()
|
go w.update()
|
||||||
|
|
||||||
|
numCPU := runtime.NumCPU()
|
||||||
|
for i := 0; i < numCPU; i++ {
|
||||||
|
go w.processQueue()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -444,14 +459,30 @@ func (wh *Whisper) add(envelope *Envelope) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// postEvent delivers the message to the watchers.
|
// postEvent queues the message for further processing.
|
||||||
func (w *Whisper) postEvent(envelope *Envelope, messageCode uint64) {
|
func (w *Whisper) postEvent(envelope *Envelope, messageCode uint64) {
|
||||||
// if the version of incoming message is higher than
|
// if the version of incoming message is higher than
|
||||||
// currently supported version, we can not decrypt it,
|
// currently supported version, we can not decrypt it,
|
||||||
// and therefore just ignore this message
|
// and therefore just ignore this message
|
||||||
if envelope.Ver() <= EnvelopeVersion {
|
if envelope.Ver() <= EnvelopeVersion {
|
||||||
// todo: review if you need an additional thread here
|
i := QueueItem{hash: envelope.Hash(), code: messageCode}
|
||||||
go w.filters.NotifyWatchers(envelope, messageCode)
|
w.messageQueue <- i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// processQueue delivers the messages to the watchers during the lifetime of the whisper node.
|
||||||
|
func (w *Whisper) processQueue() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-w.quit:
|
||||||
|
return
|
||||||
|
|
||||||
|
case i := <-w.messageQueue:
|
||||||
|
w.poolMu.Lock()
|
||||||
|
e := w.envelopes[i.hash]
|
||||||
|
w.poolMu.Unlock()
|
||||||
|
w.filters.NotifyWatchers(e, i.code)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue