cmd/wnode, whisper: add whisper CLI tool and mail server (#3580)

This commit is contained in:
gluk256
2017-01-31 11:16:20 +01:00
committed by Felix Lange
parent 1c140f7382
commit 690f6ea1d7
8 changed files with 769 additions and 30 deletions

View File

@@ -83,5 +83,5 @@ func (e unknownVersionError) Error() string {
// in order to bypass the expiry checks.
type MailServer interface {
Archive(env *Envelope)
DeliverMail(whisperPeer *Peer, data []byte)
DeliverMail(whisperPeer *Peer, request *Envelope)
}

View File

@@ -22,6 +22,7 @@ import (
"testing"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
)
func copyFromBuf(dst []byte, src []byte, beg int) int {
@@ -311,3 +312,35 @@ func TestEncryptWithZeroKey(t *testing.T) {
t.Fatalf("wrapped with nil key, seed: %d.", seed)
}
}
func TestRlpEncode(t *testing.T) {
InitSingleTest()
params, err := generateMessageParams()
if err != nil {
t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
}
msg := NewSentMessage(params)
env, err := msg.Wrap(params)
if err != nil {
t.Fatalf("wrapped with zero key, seed: %d.", seed)
}
raw, err := rlp.EncodeToBytes(env)
if err != nil {
t.Fatalf("RLP encode failed: %s.", err)
}
var decoded Envelope
rlp.DecodeBytes(raw, &decoded)
if err != nil {
t.Fatalf("RLP decode failed: %s.", err)
}
he := env.Hash()
hd := decoded.Hash()
if he != hd {
t.Fatalf("Hashes are not equal: %x vs. %x", he, hd)
}
}

View File

@@ -175,3 +175,8 @@ func (p *Peer) broadcast() error {
glog.V(logger.Detail).Infoln(p.peer, "broadcasted", len(transmit), "message(s)")
return nil
}
func (p *Peer) ID() []byte {
id := p.peer.ID()
return id[:]
}

View File

@@ -31,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rlp"
"golang.org/x/crypto/pbkdf2"
set "gopkg.in/fatih/set.v0"
)
@@ -125,13 +124,13 @@ func (w *Whisper) MarkPeerTrusted(peerID []byte) error {
return nil
}
func (w *Whisper) RequestHistoricMessages(peerID []byte, data []byte) error {
func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error {
p, err := w.getPeer(peerID)
if err != nil {
return err
}
p.trusted = true
return p2p.Send(p.ws, p2pRequestCode, data)
return p2p.Send(p.ws, p2pRequestCode, envelope)
}
func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error {
@@ -142,6 +141,10 @@ func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error {
return p2p.Send(p.ws, p2pCode, envelope)
}
func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error {
return p2p.Send(peer.ws, p2pCode, envelope)
}
// NewIdentity generates a new cryptographic identity for the client, and injects
// it into the known identities for message decryption.
func (w *Whisper) NewIdentity() *ecdsa.PrivateKey {
@@ -347,9 +350,6 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
return fmt.Errorf("invalid envelope")
}
p.mark(envelope)
if wh.mailServer != nil {
wh.mailServer.Archive(envelope)
}
}
case p2pCode:
// peer-to-peer message, sent directly to peer bypassing PoW checks, etc.
@@ -357,25 +357,22 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
// therefore might not satisfy the PoW, expiry and other requirements.
// these messages are only accepted from the trusted peer.
if p.trusted {
var envelopes []*Envelope
if err := packet.Decode(&envelopes); err != nil {
var envelope Envelope
if err := packet.Decode(&envelope); err != nil {
glog.V(logger.Warn).Infof("%v: failed to decode direct message: [%v], peer will be disconnected", p.peer, err)
return fmt.Errorf("garbage received (directMessage)")
}
for _, envelope := range envelopes {
wh.postEvent(envelope, true)
}
wh.postEvent(&envelope, true)
}
case p2pRequestCode:
// Must be processed if mail server is implemented. Otherwise ignore.
if wh.mailServer != nil {
s := rlp.NewStream(packet.Payload, uint64(packet.Size))
data, err := s.Bytes()
if err == nil {
wh.mailServer.DeliverMail(p, data)
} else {
glog.V(logger.Error).Infof("%v: bad requestHistoricMessages received: [%v]", p.peer, err)
var request Envelope
if err := packet.Decode(&request); err != nil {
glog.V(logger.Warn).Infof("%v: failed to decode p2p request message: [%v], peer will be disconnected", p.peer, err)
return fmt.Errorf("garbage received (p2p request)")
}
wh.mailServer.DeliverMail(p, &request)
}
default:
// New message types might be implemented in the future versions of Whisper.
@@ -454,6 +451,9 @@ func (wh *Whisper) add(envelope *Envelope) error {
} else {
glog.V(logger.Detail).Infof("cached whisper envelope [%x]: %v\n", envelope.Hash(), envelope)
wh.postEvent(envelope, false) // notify the local node about the new message
if wh.mailServer != nil {
wh.mailServer.Archive(envelope)
}
}
return nil
}

View File

@@ -57,12 +57,6 @@ func TestWhisperBasic(t *testing.T) {
if err := w.MarkPeerTrusted(peerID); err == nil {
t.Fatalf("failed MarkPeerTrusted.")
}
if err := w.RequestHistoricMessages(peerID, peerID); err == nil {
t.Fatalf("failed RequestHistoricMessages.")
}
if err := w.SendP2PMessage(peerID, nil); err == nil {
t.Fatalf("failed SendP2PMessage.")
}
exist := w.HasSymKey("non-existing")
if exist {
t.Fatalf("failed HasSymKey.")